diff options
| author | Jakob Kaivo <jkk@ung.org> | 2019-02-09 16:52:37 -0500 |
|---|---|---|
| committer | Jakob Kaivo <jkk@ung.org> | 2019-02-09 16:52:37 -0500 |
| commit | 0f7495e05b3367fa5863781bb3dcd3871405a73e (patch) | |
| tree | 42a46d559e9f9366c2d6727c366703ddd52d67ac /src | |
| parent | d4522efed407b6a1b82006f0d3a6d0f0ebed231c (diff) | |
merge POSIX.2 identifiers
Diffstat (limited to 'src')
| -rw-r--r-- | src/glob/GLOB_ABORTED.c | 6 | ||||
| -rw-r--r-- | src/glob/GLOB_APPEND.c | 6 | ||||
| -rw-r--r-- | src/glob/GLOB_DOOFFS.c | 6 | ||||
| -rw-r--r-- | src/glob/GLOB_ERR.c | 6 | ||||
| -rw-r--r-- | src/glob/GLOB_MARK.c | 6 | ||||
| -rw-r--r-- | src/glob/GLOB_NOCHECK.c | 6 | ||||
| -rw-r--r-- | src/glob/GLOB_NOESCAPE.c | 6 | ||||
| -rw-r--r-- | src/glob/GLOB_NOMATCH.c | 6 | ||||
| -rw-r--r-- | src/glob/GLOB_NOSORT.c | 6 | ||||
| -rw-r--r-- | src/glob/GLOB_NOSPACE.c | 6 | ||||
| -rw-r--r-- | src/glob/GLOB_NOSYS.c | 6 | ||||
| -rw-r--r-- | src/glob/glob.c | 114 | ||||
| -rw-r--r-- | src/glob/glob_t.c | 11 | ||||
| -rw-r--r-- | src/glob/globfree.c | 22 |
14 files changed, 213 insertions, 0 deletions
diff --git a/src/glob/GLOB_ABORTED.c b/src/glob/GLOB_ABORTED.c new file mode 100644 index 00000000..4fff433e --- /dev/null +++ b/src/glob/GLOB_ABORTED.c @@ -0,0 +1,6 @@ +#include <glob.h> +#define GLOB_ABORTED 1 +/* +POSIX(2) +*/ + diff --git a/src/glob/GLOB_APPEND.c b/src/glob/GLOB_APPEND.c new file mode 100644 index 00000000..e9cdddac --- /dev/null +++ b/src/glob/GLOB_APPEND.c @@ -0,0 +1,6 @@ +#include <glob.h> +#define GLOB_APPEND (1<<0) +/* +POSIX(2) +*/ + diff --git a/src/glob/GLOB_DOOFFS.c b/src/glob/GLOB_DOOFFS.c new file mode 100644 index 00000000..5c1615ec --- /dev/null +++ b/src/glob/GLOB_DOOFFS.c @@ -0,0 +1,6 @@ +#include <glob.h> +#define GLOB_DOOFFS (1<<1) +/* +POSIX(2) +*/ + diff --git a/src/glob/GLOB_ERR.c b/src/glob/GLOB_ERR.c new file mode 100644 index 00000000..1b28a495 --- /dev/null +++ b/src/glob/GLOB_ERR.c @@ -0,0 +1,6 @@ +#include <glob.h> +#define GLOB_ERR (1<<2) +/* +POSIX(2) +*/ + diff --git a/src/glob/GLOB_MARK.c b/src/glob/GLOB_MARK.c new file mode 100644 index 00000000..628b1e0d --- /dev/null +++ b/src/glob/GLOB_MARK.c @@ -0,0 +1,6 @@ +#include <glob.h> +#define GLOB_MARK (1<<3) +/* +POSIX(2) +*/ + diff --git a/src/glob/GLOB_NOCHECK.c b/src/glob/GLOB_NOCHECK.c new file mode 100644 index 00000000..323fdf40 --- /dev/null +++ b/src/glob/GLOB_NOCHECK.c @@ -0,0 +1,6 @@ +#include <glob.h> +#define GLOB_NOCHECK (1<<4) +/* +POSIX(2) +*/ + diff --git a/src/glob/GLOB_NOESCAPE.c b/src/glob/GLOB_NOESCAPE.c new file mode 100644 index 00000000..befaaaef --- /dev/null +++ b/src/glob/GLOB_NOESCAPE.c @@ -0,0 +1,6 @@ +#include <glob.h> +#define GLOB_NOESCAPE (1<<5) +/* +POSIX(2) +*/ + diff --git a/src/glob/GLOB_NOMATCH.c b/src/glob/GLOB_NOMATCH.c new file mode 100644 index 00000000..1d404a00 --- /dev/null +++ b/src/glob/GLOB_NOMATCH.c @@ -0,0 +1,6 @@ +#include <glob.h> +#define GLOB_NOMATCH 2 +/* +POSIX(2) +*/ + diff --git a/src/glob/GLOB_NOSORT.c b/src/glob/GLOB_NOSORT.c new file mode 100644 index 00000000..c17dcf28 --- /dev/null +++ b/src/glob/GLOB_NOSORT.c @@ -0,0 +1,6 @@ +#include <glob.h> +#define GLOB_NOSORT (1<<6) +/* +POSIX(2) +*/ + diff --git a/src/glob/GLOB_NOSPACE.c b/src/glob/GLOB_NOSPACE.c new file mode 100644 index 00000000..e57a197b --- /dev/null +++ b/src/glob/GLOB_NOSPACE.c @@ -0,0 +1,6 @@ +#include <glob.h> +#define GLOB_NOSPACE 3 +/* +POSIX(2) +*/ + diff --git a/src/glob/GLOB_NOSYS.c b/src/glob/GLOB_NOSYS.c new file mode 100644 index 00000000..4c0682c4 --- /dev/null +++ b/src/glob/GLOB_NOSYS.c @@ -0,0 +1,6 @@ +#include <glob.h> +#define GLOB_NOSYS (-2) +/* +POSIX(2) +*/ + diff --git a/src/glob/glob.c b/src/glob/glob.c new file mode 100644 index 00000000..15e30731 --- /dev/null +++ b/src/glob/glob.c @@ -0,0 +1,114 @@ +#include <glob.h> +#include "stdlib.h" +#include "string.h" +#include "dirent.h" +#include "fnmatch.h" +#include "errno.h" +#include "unistd.h" +#include "__nonstd.h" + +int glob(const char * restrict pattern, int flags, int (*errfunc) (const char * epath, int eerrno), glob_t * restrict pglob) +{ + __ASSERT_NONNULL(pattern); + __ASSERT_NONNULL(pglob); + + int fnmatch_flags = FNM_PATHNAME | FNM_PERIOD; + if (flags & GLOB_NOESCAPE) { + fnmatch_flags |= FNM_NOESCAPE; + } + + if (flags & GLOB_APPEND) { + if (pglob->gl_pathc == 0) { + /* no good */ + } + + if (pglob->gl_offs > 0 && !(flags & GLOB_DOOFFS)) { + /* nope */ + } + } else { + if (pglob->gl_pathc != 0) { + /* also no */ + } + } + + char *path = strdup(pattern); + int slashes = 0; + + for (size_t i = 0; path[i]; i++) { + if (path[i] == '/') { + slashes++; + path[i] = '\0'; + } + } + + if (path[0] == '\0') { + path[0] = '/'; + slashes--; + } + + /* TODO: check for trailing slash to match only directories */ + /* TODO: compress adjacent slashes */ + /* TODO: DOOFFS */ + + do { + const char *p = path + strlen(path) + 1; + struct dirent *de; + DIR *d = opendir(path); + if (d == NULL) { + if (errfunc != NULL) { + if (errfunc(path, errno) != 0) { + return GLOB_ABORTED; + } + } + + if (flags & GLOB_ERR) { + return GLOB_ABORTED; + } + } + + while ((de = readdir(d)) != NULL) { + if (fnmatch(de->d_name, p, fnmatch_flags) == 0) { + pglob->gl_pathc++; + char **tmp = realloc(pglob->gl_pathv, sizeof(char*) * pglob->gl_pathc); + if (tmp == NULL) { + pglob->gl_pathc--; + return GLOB_NOSPACE; + } + + pglob->gl_pathv = tmp; + /* FIXME: add path to front */ + pglob->gl_pathv[pglob->gl_pathc - 1] = strdup(de->d_name); + /* TODO: MARK */ + } + } + + closedir(d); + + path[strlen(path)] = '/'; + slashes--; + } while (slashes); + + if (pglob->gl_pathc == 0) { + if (flags & GLOB_NOCHECK) { + /* TODO: DOOFFS */ + pglob->gl_pathc = 1; + pglob->gl_pathv = malloc(sizeof(char*)); + pglob->gl_pathv[0] = strdup(pattern); + } else { + return GLOB_NOMATCH; + } + } + + if (!(flags & GLOB_NOSORT)) { + qsort(pglob->gl_pathv + pglob->gl_offs, pglob->gl_pathc, + sizeof(char*), + (int (*)(const void *, const void *))strcoll); + } + + return 0; +} + +/* +POSIX(2) +*/ + diff --git a/src/glob/glob_t.c b/src/glob/glob_t.c new file mode 100644 index 00000000..21fcf4f6 --- /dev/null +++ b/src/glob/glob_t.c @@ -0,0 +1,11 @@ +#include <glob.h> + +typedef struct { + size_t gl_pathc; + char ** gl_pathv; + size_t gl_offs; +} glob_t; +/* +POSIX(2) +*/ + diff --git a/src/glob/globfree.c b/src/glob/globfree.c new file mode 100644 index 00000000..f04708c4 --- /dev/null +++ b/src/glob/globfree.c @@ -0,0 +1,22 @@ +#include <glob.h> +#include "stdlib.h" + +void globfree(glob_t * pglob) +{ + if (pglob == NULL) { + return; + } + + for (size_t i = 0; i < pglob->gl_pathc; i++) { + if (pglob->gl_pathv[i] != NULL) { + free(pglob->gl_pathv[i]); + } + } + + free(pglob); +} + +/* +POSIX(2) +*/ + |
