diff options
author | Rob Landley <rob@landley.net> | 2020-10-11 02:59:54 -0500 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2020-10-11 02:59:54 -0500 |
commit | 67bd0be1a4ed817954c9dcededf9bd9cb8c2f431 (patch) | |
tree | 4df0aa1044af467469e77c757bbf58dffe2f6178 /lib | |
parent | 0f2658c806586190be3aca21826e77fff9e50f1b (diff) | |
download | toybox-67bd0be1a4ed817954c9dcededf9bd9cb8c2f431.tar.gz |
toysh: more variable/wildcard plumbing and tests.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/dirtree.c | 13 | ||||
-rw-r--r-- | lib/lib.c | 19 | ||||
-rw-r--r-- | lib/lib.h | 5 |
3 files changed, 30 insertions, 7 deletions
diff --git a/lib/dirtree.c b/lib/dirtree.c index 2bd7c404..70b567d2 100644 --- a/lib/dirtree.c +++ b/lib/dirtree.c @@ -53,12 +53,13 @@ struct dirtree *dirtree_add_node(struct dirtree *parent, char *name, int flags) // Allocate/populate return structure dt = xmalloc((len = sizeof(struct dirtree)+len+1)+linklen); - memset(dt, 0, statless ? offsetof(struct dirtree, again) + memset(dt, 0, statless ? sizeof(struct dirtree)+1 : offsetof(struct dirtree, st)); dt->parent = parent; dt->again = statless ? 2 : 0; if (!statless) memcpy(&dt->st, &st, sizeof(struct stat)); - strcpy(dt->name, name ? name : ""); + if (name) strcpy(dt->name, name); + else dt->st.st_mode = S_IFDIR; if (linklen) dt->symlink = memcpy(len+(char *)dt, libbuf, linklen); return dt; @@ -142,10 +143,12 @@ int dirtree_recurse(struct dirtree *node, { struct dirtree *new, **ddt = &(node->child); struct dirent *entry; - DIR *dir; + DIR *dir = 0; - node->dirfd = dirfd; - if (node->dirfd == -1 || !(dir = fdopendir(node->dirfd))) { + // Why doesn't fdopendir() support AT_FDCWD? + if (AT_FDCWD == (node->dirfd = dirfd)) dir = opendir("."); + else if (node->dirfd != -1) dir = fdopendir(node->dirfd); + if (!dir) { if (!(flags & DIRTREE_SHUTUP)) { char *path = dirtree_path(node, 0); perror_msg_raw(path); @@ -346,6 +346,25 @@ int stridx(char *haystack, char needle) return off-haystack; } +// Convert wc to utf8, returning bytes written. Does not null terminate. +int wctoutf8(char *s, unsigned wc) +{ + int len = (wc>0x7ff)+(wc>0xffff), mask = 12+len+!!len; + + if (wc<128) { + *s = wc; + return 1; + } else { + do { + s[1+len] = 0x80+(wc&0x3f); + wc >>= 7; + } while (len--); + *s = wc|mask; + } + + return 2+len; +} + // Convert utf8 sequence to a unicode wide character // returns bytes consumed, or -1 if err, or -2 if need more data. int utf8towc(wchar_t *wc, char *str, unsigned len) @@ -74,11 +74,11 @@ void get_optflags(void); // Don't warn about failure to stat #define DIRTREE_SHUTUP 16 // Breadth first traversal, conserves filehandles at the expense of memory -#define DIRTREE_BREADTH 32 +#define DIRTREE_BREADTH 32 // TODO not implemented yet // skip non-numeric entries #define DIRTREE_PROC 64 // Return files we can't stat -#define DIRTREE_STATLESS 128 +#define DIRTREE_STATLESS 128 // Don't look at any more files in this directory. #define DIRTREE_ABORT 256 @@ -229,6 +229,7 @@ long long xstrtol(char *str, char **end, int base); long long atolx(char *c); long long atolx_range(char *numstr, long long low, long long high); int stridx(char *haystack, char needle); +int wctoutf8(char *s, unsigned wc); int utf8towc(wchar_t *wc, char *str, unsigned len); char *strlower(char *s); char *strafter(char *haystack, char *needle); |