Skip to content

Commit

Permalink
misc refactorings (#142)
Browse files Browse the repository at this point in the history
* move zsv_strencode.c to standalone file
change utils/dirs_from_json to accommodate backslash path separators
modify zsv_foreach_dirent to stop sooner if max_depth provided and to abort if subdir handler returns err
  • Loading branch information
liquidaty authored Nov 8, 2023
1 parent 134ba17 commit ab4b0b7
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 43 deletions.
10 changes: 7 additions & 3 deletions app/utils/dirs.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <zsv/utils/string.h>
#include <unistd.h> // unlink
#include <sys/stat.h>
#include <yajl_helper/yajl_helper.h>

#if defined(_WIN32)
#include <windows.h>
Expand Down Expand Up @@ -245,7 +246,7 @@ int zsv_foreach_dirent_aux(const char *dir_path,
if(!dir_path)
return 1;

if(max_depth > 0 && depth > max_depth)
if(max_depth > 0 && depth >= max_depth)
return 0;

DIR *dr;
Expand All @@ -269,11 +270,11 @@ int zsv_foreach_dirent_aux(const char *dir_path,
char is_dir = h.stat.st_mode & S_IFDIR ? 1 : 0;
h.is_dir = is_dir;
if(handler)
err = handler(&h, depth + 1);
handler(&h, depth + 1);

if(is_dir && !h.no_recurse)
// recurse!
zsv_foreach_dirent_aux(tmp, depth + 1, max_depth, handler, ctx, verbose);
err = zsv_foreach_dirent_aux(tmp, depth + 1, max_depth, handler, ctx, verbose);
free(tmp);
}
}
Expand Down Expand Up @@ -312,6 +313,9 @@ int zsv_remove_dir_recursive(const unsigned char *path) {
return err;
}

#ifndef ZSV_NO_JQ
#include "dirs_to_json.c"

#include "dirs_from_json.c"

#endif
4 changes: 4 additions & 0 deletions app/utils/dirs_from_json.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ static int zsv_dir_from_json_map_key(struct yajl_helper_parse_state *st,
asprintf(&fn, "%s%c%.*s", ctx->filepath_prefix, FILESLASH, (int)len, s);
else
asprintf(&fn, "%.*s", (int)len, s);

// if we have any backslashes, replace with fwd slash
if(fn)
for(int i = 0, j = strlen(fn); i < j; i++) if(fn[i] == '\\') fn[i] = '/';
if(!fn) {
errno = ENOMEM;
perror(NULL);
Expand Down
6 changes: 6 additions & 0 deletions app/utils/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
#include <zsv/utils/utf8.h>
#include <zsv/utils/string.h>

#ifdef ZSV_UTILS_STRING_STANDALONE
#include "../../src/zsv_strencode.c"
#endif

#ifndef NO_UTF8PROC
#include <utf8proc.h>

Expand Down Expand Up @@ -326,8 +330,10 @@ size_t zsv_strunescape_backslash(unsigned char *s, size_t len) {
return j;
}

#ifndef ZSV_STRING_LIB_ONLY
struct zsv_cell zsv_get_cell_trimmed(zsv_parser parser, size_t ix) {
struct zsv_cell c = zsv_get_cell(parser, ix);
c.str = (unsigned char *)zsv_strtrim(c.str, &c.len);
return c;
}
#endif
41 changes: 1 addition & 40 deletions src/zsv.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#endif

#include "zsv.h"
#include <zsv/utils/utf8.h>
#include <zsv/utils/compiler.h>
#ifdef ZSV_EXTRAS
#include <zsv/utils/arg.h>
Expand All @@ -30,45 +29,7 @@ const char *zsv_lib_version(void) {
return ZSV_VERSION;
}

/**
* Ensure valid UTF8 encoding by, if needed, replacing malformed bytes
*/
ZSV_EXPORT
size_t zsv_strencode(unsigned char *s, size_t n, unsigned char replace,
int (*malformed_handler)(void *, const unsigned char *s, size_t n, size_t offset), void *handler_ctx) {
size_t new_len = 0;
int clen;
for(size_t i2 = 0; i2 < n; i2 += (size_t)clen) {
clen = ZSV_UTF8_CHARLEN(s[i2]);
if(LIKELY(clen == 1))
s[new_len++] = s[i2];
else if(UNLIKELY(clen < 0) || UNLIKELY(i2 + clen >= n)) {
if(malformed_handler)
malformed_handler(handler_ctx, s, n, new_len);
if(replace)
s[new_len++] = replace;
clen = 1;
} else { /* might be valid multi-byte utf8; check */
unsigned char valid_n;
for(valid_n = 1; valid_n < clen; valid_n++)
if(!ZSV_UTF8_SUBSEQUENT_CHAR_OK(s[i2 + valid_n]))
break;
if(valid_n == clen) { /* valid_n utf8; copy it */
memmove(s + new_len, s + i2, clen);
new_len += clen;
} else { /* invalid; valid_n smaller than expected */
if(malformed_handler)
malformed_handler(handler_ctx, s, n, new_len);
if(replace) {
memset(s + new_len, replace, valid_n);
new_len += valid_n;
}
clen = valid_n;
}
}
}
return new_len; // new length
}
#include "zsv_strencode.c"

/**
* When we parse a chunk, if it was not the first parse call, we might have a partial
Expand Down
49 changes: 49 additions & 0 deletions src/zsv_strencode.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* zsv_strencode(): standalone file to allow zsv utilities that use this
* to be used on a standalone basis without the zsv parser
*
* This file is part of zsv/lib, distributed under the license defined at
* https://opensource.org/licenses/MIT
*/

#include <zsv/utils/utf8.h>
#include <zsv/utils/compiler.h>
/**
* Ensure valid UTF8 encoding by, if needed, replacing malformed bytes
*/
ZSV_EXPORT
size_t zsv_strencode(unsigned char *s, size_t n, unsigned char replace,
int (*malformed_handler)(void *, const unsigned char *s, size_t n, size_t offset), void *handler_ctx) {
size_t new_len = 0;
int clen;
for(size_t i2 = 0; i2 < n; i2 += (size_t)clen) {
clen = ZSV_UTF8_CHARLEN(s[i2]);
if(LIKELY(clen == 1))
s[new_len++] = s[i2];
else if(UNLIKELY(clen < 0) || UNLIKELY(i2 + clen >= n)) {
if(malformed_handler)
malformed_handler(handler_ctx, s, n, new_len);
if(replace)
s[new_len++] = replace;
clen = 1;
} else { /* might be valid multi-byte utf8; check */
unsigned char valid_n;
for(valid_n = 1; valid_n < clen; valid_n++)
if(!ZSV_UTF8_SUBSEQUENT_CHAR_OK(s[i2 + valid_n]))
break;
if(valid_n == clen) { /* valid_n utf8; copy it */
memmove(s + new_len, s + i2, clen);
new_len += clen;
} else { /* invalid; valid_n smaller than expected */
if(malformed_handler)
malformed_handler(handler_ctx, s, n, new_len);
if(replace) {
memset(s + new_len, replace, valid_n);
new_len += valid_n;
}
clen = valid_n;
}
}
}
return new_len; // new length
}

0 comments on commit ab4b0b7

Please sign in to comment.