summaryrefslogtreecommitdiff
path: root/src/glob
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2019-02-09 16:52:37 -0500
committerJakob Kaivo <jkk@ung.org>2019-02-09 16:52:37 -0500
commit0f7495e05b3367fa5863781bb3dcd3871405a73e (patch)
tree42a46d559e9f9366c2d6727c366703ddd52d67ac /src/glob
parentd4522efed407b6a1b82006f0d3a6d0f0ebed231c (diff)
merge POSIX.2 identifiers
Diffstat (limited to 'src/glob')
-rw-r--r--src/glob/GLOB_ABORTED.c6
-rw-r--r--src/glob/GLOB_APPEND.c6
-rw-r--r--src/glob/GLOB_DOOFFS.c6
-rw-r--r--src/glob/GLOB_ERR.c6
-rw-r--r--src/glob/GLOB_MARK.c6
-rw-r--r--src/glob/GLOB_NOCHECK.c6
-rw-r--r--src/glob/GLOB_NOESCAPE.c6
-rw-r--r--src/glob/GLOB_NOMATCH.c6
-rw-r--r--src/glob/GLOB_NOSORT.c6
-rw-r--r--src/glob/GLOB_NOSPACE.c6
-rw-r--r--src/glob/GLOB_NOSYS.c6
-rw-r--r--src/glob/glob.c114
-rw-r--r--src/glob/glob_t.c11
-rw-r--r--src/glob/globfree.c22
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)
+*/
+