From 67bd0be1a4ed817954c9dcededf9bd9cb8c2f431 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Sun, 11 Oct 2020 02:59:54 -0500 Subject: toysh: more variable/wildcard plumbing and tests. --- lib/dirtree.c | 13 ++++++++----- lib/lib.c | 19 +++++++++++++++++++ lib/lib.h | 5 +++-- 3 files changed, 30 insertions(+), 7 deletions(-) (limited to 'lib') 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); diff --git a/lib/lib.c b/lib/lib.c index 752fd0a1..c4e70dfe 100644 --- a/lib/lib.c +++ b/lib/lib.c @@ -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) diff --git a/lib/lib.h b/lib/lib.h index db851631..6851c4aa 100644 --- a/lib/lib.h +++ b/lib/lib.h @@ -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); -- cgit v1.2.3