aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@users.noreply.github.com>2021-05-16 21:06:48 -0400
committerGitHub <noreply@github.com>2021-05-16 21:06:48 -0400
commitbc3013fc68746265db78bf92623f7e6e3e469264 (patch)
treefadf9d7fb0febde598dbc4a7b5ec27eea62020cc
parent25493db89f8e23d2e78e1ee16b3748173ef60188 (diff)
downloadcleanpath-bc3013fc68746265db78bf92623f7e6e3e469264.tar.gz
Add default path (#6)
* Add default path * Improve support/implementation logic * Fix braces in tests * Enable warnings * Emit more generalized form of windows path * Change initialization order * Add --default/-D to documentation * Fix platform detection
-rw-r--r--CMakeLists.txt9
-rw-r--r--README.md1
-rw-r--r--config.h.in2
-rw-r--r--docs/man/cleanpath.17
-rw-r--r--include/cleanpath/cleanpath.h14
-rw-r--r--src/main.c46
-rw-r--r--tests/CMakeLists.txt2
-rw-r--r--tests/test_errors.c6
-rw-r--r--tests/test_modes_filter_all.c12
-rw-r--r--tests/test_modes_filter_general.c12
10 files changed, 86 insertions, 25 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 604534b..823cddf 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.0)
project(cleanpath)
include(CheckIncludeFile)
+include(CheckSymbolExists)
include(CTest)
set(CMAKE_C_STANDARD 99)
@@ -9,12 +10,20 @@ set(LIB_SOURCES lib/cleanpath.c)
set(MAIN_SOURCES src/main.c)
set(LIB_INCLUDES include/cleanpath/cleanpath.h)
+check_symbol_exists(confstr "unistd.h" HAVE_CONFSTR)
+
configure_file ("${PROJECT_SOURCE_DIR}/config.h.in"
"${PROJECT_BINARY_DIR}/include/config.h")
include_directories(${PROJECT_BINARY_DIR}/include)
include_directories(${CMAKE_SOURCE_DIR}/include)
+if(MSVC)
+ add_compile_options(/W4)
+else()
+ add_compile_options(-Wall -Wextra)
+endif()
+
enable_testing()
add_subdirectory(tests)
diff --git a/README.md b/README.md
index 9cdb00f..838a1bc 100644
--- a/README.md
+++ b/README.md
@@ -21,6 +21,7 @@ $ make install
usage: cleanpath [-hVelrsE] [pattern ...]
--help -h Displays this help message
--version -V Displays the program's version
+ --default -D Displays default operating system PATH
--list Format output as a list
--exact -e Filter when pattern is an exact match (default)
--loose -l Filter when any part of the pattern matches
diff --git a/config.h.in b/config.h.in
index 777f43c..f1292c7 100644
--- a/config.h.in
+++ b/config.h.in
@@ -1,6 +1,6 @@
#ifndef CLEAN_PATH_CONFIG_H
#define CLEAN_PATH_CONFIG_H
-// Reserved for later use
+#cmakedefine HAVE_CONFSTR @HAVE_CONFSTR@
#endif \ No newline at end of file
diff --git a/docs/man/cleanpath.1 b/docs/man/cleanpath.1
index ba3db63..6b3aa84 100644
--- a/docs/man/cleanpath.1
+++ b/docs/man/cleanpath.1
@@ -23,6 +23,13 @@ Prints brief usage information.
\f[B]-V\f[R], \f[B]--version\f[R]
Prints the current version number.
.TP
+\f[B]-D\f[R], \f[B]--default\f[R]
+Prints the default operating system PATH
+.RS
+.PP
+No other arguments are honored and no filtering will occur.
+.RE
+.TP
\f[B]--list\f[R]
Format output as a list
.TP
diff --git a/include/cleanpath/cleanpath.h b/include/cleanpath/cleanpath.h
index afee624..dfb0b5f 100644
--- a/include/cleanpath/cleanpath.h
+++ b/include/cleanpath/cleanpath.h
@@ -38,13 +38,21 @@
#define CLEANPATH_PART_MAX 1024
#define CLEANPATH_VAR "PATH"
#define CLEANPATH_SEP ":"
-#define CLEANPATH_MSG_NOAVAIL ""
+#define CLEANPATH_MSG_NOT_IMPLEMENTED "[not implemented]"
+#define CLEANPATH_MSG_NOT_SUPPORTED "[not supported]"
+#define CLEANPATH_MSG_NO_REGEX ""
+#define CLEANPATH_MSG_NO_DEFAULT_PATH ""
#if OS_WINDOWS
#undef CLEANPATH_SEP
#define CLEANPATH_SEP ";"
-#undef CLEANPATH_MSG_NOAVAIL
-#define CLEANPATH_MSG_NOAVAIL " [not implemented] "
+#undef CLEANPATH_MSG_NO_REGEX
+#define CLEANPATH_MSG_NO_REGEX CLEANPATH_MSG_NOT_IMPLEMENTED
+#endif
+
+#if !OS_SUPPORTED
+#undef CLEANPATH_MSG_NO_DEFAULT_PATH
+#define CLEANPATH_MSG_NO_DEFAULT_PATH CLEANPATH_MSG_NOT_SUPPORTED
#endif
struct CleanPath {
diff --git a/src/main.c b/src/main.c
index 7b60bbe..71cc6fd 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2,8 +2,13 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
+#include "config.h"
#include "cleanpath/cleanpath.h"
+#if !OS_WINDOWS
+#include <unistd.h>
+#endif
+
// Make argument parsing less wordy
#define ARGM(X) strcmp(argv[i], X) == 0
@@ -51,6 +56,25 @@ void show_listing(struct CleanPath *path) {
}
}
+static int show_default_path() {
+ char buf[CLEANPATH_PART_MAX];
+#if OS_WINDOWS
+ // I could not find anything in MSDN about dumping default path information.
+ // The internet agrees "this" is "it" (XP/Vista/8/10):
+ strncpy(buf, "%SystemRoot%\\system32;%SystemRoot%;%SystemRoot%\\System32\\Wbem;", sizeof(buf));
+#elif HAVE_CONFSTR // POSIX
+ size_t cf_status;
+ cf_status = confstr(_CS_PATH, buf, sizeof(buf));
+ if (cf_status < 1) { // 0 and -1 are possible error codes for linux and darwin
+ return 1;
+ }
+#else
+ *buf = '\0';
+#endif
+ puts(buf);
+ return 0;
+}
+
void show_path(struct CleanPath *path) {
char *result;
@@ -71,13 +95,14 @@ static void show_usage() {
char *bname;
bname = strrchr(program, '/');
- printf("usage: %s [-hVelrsv] [pattern ...]\n", bname ? bname + 1 : program);
+ printf("usage: %s [-hVDelrsv] [pattern ...]\n", bname ? bname + 1 : program);
printf(" --help -h Displays this help message\n");
printf(" --version -V Displays the program's version\n");
+ printf(" --default -D Displays default operating system PATH " CLEANPATH_MSG_NO_DEFAULT_PATH "\n");
printf(" --list Format output as a list\n");
printf(" --exact -e Filter when pattern is an exact match (default)\n");
printf(" --loose -l Filter when any part of the pattern matches\n");
- printf(" --regex -r Filter matches with (Extended) Regular Expressions " CLEANPATH_MSG_NOAVAIL "\n");
+ printf(" --regex -r Filter matches with (Extended) Regular Expressions " CLEANPATH_MSG_NO_REGEX "\n");
printf(" --sep [str] -s Use custom path separator (default: ':')\n");
printf(" --env [str] -E Use custom environment variable (default: PATH)\n");
}
@@ -86,27 +111,28 @@ int main(int argc, char *argv[]) {
struct CleanPath *path;
char *sep;
char *sys_var;
- char *result;
- size_t pattern_nelem;
int do_listing;
+ int do_default_path;
int filter_mode;
int args_invalid;
+ size_t pattern_nelem;
char *pattern[CLEANPATH_PART_MAX];
program = argv[0];
- result = NULL;
sys_var = NULL;
sep = CLEANPATH_SEP;
do_listing = 0;
+ do_default_path = 0;
filter_mode = CLEANPATH_FILTER_NONE;
- memset(pattern, 0, sizeof(pattern) / sizeof(char *));
pattern_nelem = 0;
+ memset(pattern, 0, (sizeof(pattern) / sizeof(char *)) * sizeof(char *));
args_invalid = 0;
char *args_valid[] = {
"--help", "-h",
"--version", "-V",
"--list",
+ "--default", "-D",
"--exact", "-e",
"--loose", "-l",
"--regex", "-r",
@@ -135,6 +161,9 @@ int main(int argc, char *argv[]) {
if (ARGM("--list")) {
do_listing = 1;
}
+ if (ARGM("--default") || ARGM("-D")) {
+ do_default_path = 1;
+ }
if (ARGM("--exact") || ARGM("-e")) {
filter_mode = CLEANPATH_FILTER_EXACT;
continue;
@@ -173,6 +202,11 @@ int main(int argc, char *argv[]) {
pattern_nelem++;
}
+ // Show default system path, and exit
+ if (do_default_path) {
+ exit(show_default_path());
+ }
+
// Use default environment variable when not set by --var
if (sys_var == NULL) {
sys_var = getenv_ex(CLEANPATH_VAR);
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 7a56301..7a7d3db 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -27,7 +27,7 @@ endforeach()
# processes.
set(TEST_SETUP -E TESTVAR)
-if(${CMAKE_SYSTEM_NAME} EQUAL WINDOWS)
+if(WIN32)
set(TEST_SETUP ${TEST_SETUP}_WIN)
set(exec ${CMAKE_BINARY_DIR}/cleanpath.exe)
diff --git a/tests/test_errors.c b/tests/test_errors.c
index 82241ed..18c444e 100644
--- a/tests/test_errors.c
+++ b/tests/test_errors.c
@@ -6,6 +6,8 @@ int main() {
path = NULL;
//intentionally bad
- myassert(cleanpath_init("good", NULL) == NULL, "cleanpath_init() returned non-NULL on NULL sep\n");
- myassert(cleanpath_init(NULL, "good") == NULL, "cleanpath_init() returned non-NULL on NULL path\n");
+ myassert((path = cleanpath_init("good", NULL)) == NULL, "cleanpath_init() returned non-NULL on NULL sep\n");
+ if (path) cleanpath_free(path);
+ myassert((path = cleanpath_init(NULL, "good")) == NULL, "cleanpath_init() returned non-NULL on NULL path\n");
+ if (path) cleanpath_free(path);
}
diff --git a/tests/test_modes_filter_all.c b/tests/test_modes_filter_all.c
index d57b418..3893be0 100644
--- a/tests/test_modes_filter_all.c
+++ b/tests/test_modes_filter_all.c
@@ -30,7 +30,7 @@ char *modes_str[MAX_MODE] = {
const char *inputs[MAX_MODE][MAX_PART][MAX_RECORD] = {
{ // Filter exact
- "/opt/local/bin",
+ {"/opt/local/bin",
"/opt/local/sbin",
"/usr/local/bin",
"/usr/bin",
@@ -39,16 +39,16 @@ const char *inputs[MAX_MODE][MAX_PART][MAX_RECORD] = {
"/sbin",
"/opt/X11/bin",
"/Library/Apple/usr/bin",
- NULL
+ NULL}
},
{ // Filter loose
- "bin",
- NULL
+ {"bin",
+ NULL}
},
#if !OS_WINDOWS
{ // Filter regex
- ".*",
- NULL
+ {".*",
+ NULL}
},
#endif
};
diff --git a/tests/test_modes_filter_general.c b/tests/test_modes_filter_general.c
index 45206a4..d33ebb9 100644
--- a/tests/test_modes_filter_general.c
+++ b/tests/test_modes_filter_general.c
@@ -29,22 +29,22 @@ char *modes_str[MAX_MODE] = {
const char *inputs[MAX_MODE][MAX_PART][MAX_RECORD] = {
{ // Filter exact
- "/opt/local/bin",
+ {"/opt/local/bin",
"/opt/local/sbin",
"intentionally bad", // test non-existent pattern in string
- NULL
+ NULL}
},
{ // Filter loose
- "/opt/local",
+ {"/opt/local",
"intentionally bad", // test non-existent pattern in string
- NULL
+ NULL}
},
#if !OS_WINDOWS
{ // Filter regex
- "^/opt/local/.*",
+ {"^/opt/local/.*",
"intentionally bad", // test non-existent pattern in string
"intentionally worse (", // cause total regex failure with unmatched parenthesis
- NULL
+ NULL}
},
#endif
};