From 7724ca0d7c2018d62408bde10f9334743acebc39 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Wed, 15 Jun 2016 11:25:25 -0400 Subject: [PATCH] add Exists builtin. --- builtins.cpp | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++ builtins.h | 2 ++ command.cpp | 1 + 3 files changed, 83 insertions(+) diff --git a/builtins.cpp b/builtins.cpp index 5ee6c62..bc61657 100644 --- a/builtins.cpp +++ b/builtins.cpp @@ -11,6 +11,7 @@ #include #include +#include #include "cxx/string_splitter.h" #include "cxx/filesystem.h" @@ -404,6 +405,85 @@ int builtin_directory(Environment &env, const std::vector &tokens, return 0; } + +int builtin_exists(Environment &env, const std::vector &tokens, const fdmask &fds) { + + bool _a = false; // print if alias/symlink + bool _d = false; // print if directory + bool _f = false; // print if normal file + bool _n = false; // don't follow alias + bool _w = false; // print if normal file + writable + bool _q = false; // don't quote names + bool error = false; + + std::vector argv = getopt(tokens, [&](char c){ + switch(tolower(c)) + { + case 'a': + _a = true; + break; + case 'd': + _d = true; + break; + case 'f': + _f = true; + break; + case 'n': + _n = true; + break; + case 'q': + _q = true; + break; + case 'w': + _w = true; + break; + default: + fprintf(stderr, "### Exists - \"-%c\" is not an option.\n", c); + error = true; + break; + } + }); + + if (_w) _f = false; + + if (_a + _d + _f + _w > 1) { + fputs("### Exists - Conflicting options were specified.\n", stderr); + error = true; + } + + if (argv.size() < 1) { + fputs("### Exists - Not enough parameters were specified.\n", stderr); + error = true; + } + + + + if (error) { + fputs("# Usage - Exists [-a | -d | -f | -w] [-n] [-q] name...\n", stderr); + return 1; + } + + for (auto &s : argv) { + std::string path = ToolBox::MacToUnix(s); + std::error_code ec; + fs::file_status st = _n ? fs::symlink_status(path, ec) : fs::status(path, ec); + if (ec) continue; + + if (_d && !fs::is_directory(st)) continue; + if (_a && !fs::is_symlink(st)) continue; + if (_f && !fs::is_regular_file(st)) continue; + if (_w && !fs::is_regular_file(st)) continue; + if (_w && (access(path.c_str(), W_OK | F_OK) < 0)) continue; + + if (!_q) s = quote(std::move(s)); + fprintf(stdout, "%s\n", s.c_str()); + + } + + + return 0; +} + static bool is_assignment(int type) { switch(type) { diff --git a/builtins.h b/builtins.h index 54428a0..072ef98 100644 --- a/builtins.h +++ b/builtins.h @@ -19,6 +19,8 @@ int builtin_unexport(Environment &e, const std::vector &, const fdm int builtin_which(Environment &e, const std::vector &, const fdmask &); int builtin_aboutbox(Environment &e, const std::vector &, const fdmask &); +int builtin_exists(Environment &e, const std::vector &, const fdmask &); + int builtin_evaluate(Environment &e, std::vector &&, const fdmask &); #endif \ No newline at end of file diff --git a/command.cpp b/command.cpp index 64d120b..750a682 100644 --- a/command.cpp +++ b/command.cpp @@ -97,6 +97,7 @@ namespace { {"aboutbox", builtin_aboutbox}, {"directory", builtin_directory}, {"echo", builtin_echo}, + {"exists", builtin_exists}, {"export", builtin_export}, {"parameters", builtin_parameters}, {"quote", builtin_quote},