diff --git a/app/utils/dirs_to_json.c b/app/utils/dirs_to_json.c index 12a04854..f14bc246 100644 --- a/app/utils/dirs_to_json.c +++ b/app/utils/dirs_to_json.c @@ -8,63 +8,63 @@ struct zsv_dir_foreach_to_json_ctx { }; static int zsv_dir_foreach_to_json(struct zsv_foreach_dirent_handle *h, size_t depth) { - if(!h->is_dir) { - struct zsv_dir_foreach_to_json_ctx *ctx = h->ctx; - h->ctx = ctx->zsv_dir_filter.ctx; - if(ctx->zsv_dir_filter.filter(h, depth) && !ctx->err) { - char suffix = 0; - if(strlen(h->parent_and_entry) > 5 && !zsv_stricmp((const unsigned char *)h->parent_and_entry + strlen(h->parent_and_entry) - 5, (const unsigned char *)".json")) - suffix = 'j'; // json - else if(strlen(h->parent_and_entry) > 4 && !zsv_stricmp((const unsigned char *)h->parent_and_entry + strlen(h->parent_and_entry) - 4, (const unsigned char *)".txt")) - suffix = 't'; // text - if(suffix) { - // for now, only handle json or txt - FILE *f = fopen(h->parent_and_entry, "rb"); - if(!f) - perror(h->parent_and_entry); - else { - // create an entry for this file. the map key is the file name; its value is the file contents - unsigned char *js = zsv_json_from_str((const unsigned char *)h->parent_and_entry + strlen((const char *)ctx->parent_dir) + 1); - if(!js) - errno = ENOMEM, perror(NULL); - else if(*js) { - if(ctx->count > 0) - if(zsv_jq_parse(ctx->zjq, ",", 1)) - ctx->err = 1; - if(!ctx->err) { - ctx->count++; - if(zsv_jq_parse(ctx->zjq, js, strlen((const char *)js)) || zsv_jq_parse(ctx->zjq, ":", 1)) - ctx->err = 1; - else { - switch(suffix) { - case 'j': // json - if(zsv_jq_parse_file(ctx->zjq, f)) - ctx->err = 1; - break; - case 't': // txt - // for now we are going to limit txt file values to 4096 chars and JSON-stringify it - { - unsigned char buff[4096]; - size_t n = fread(buff, 1, sizeof(buff), f); - unsigned char *txt_js = NULL; - if(n) { - txt_js = zsv_json_from_str_n(buff, n); - if(zsv_jq_parse(ctx->zjq, txt_js ? txt_js : (const unsigned char *)"null", txt_js ? strlen((const char *)txt_js) : 4)) - ctx->err = 1; - } + struct zsv_dir_foreach_to_json_ctx *ctx = h->ctx; + h->ctx = ctx->zsv_dir_filter.ctx; + if(!ctx->zsv_dir_filter.filter(h, depth)) + h->no_recurse = 1; // skip this node (only matters if node is dir) + else if(!h->is_dir) { // process this file + char suffix = 0; + if(strlen(h->parent_and_entry) > 5 && !zsv_stricmp((const unsigned char *)h->parent_and_entry + strlen(h->parent_and_entry) - 5, (const unsigned char *)".json")) + suffix = 'j'; // json + else if(strlen(h->parent_and_entry) > 4 && !zsv_stricmp((const unsigned char *)h->parent_and_entry + strlen(h->parent_and_entry) - 4, (const unsigned char *)".txt")) + suffix = 't'; // text + if(suffix) { + // for now, only handle json or txt + FILE *f = fopen(h->parent_and_entry, "rb"); + if(!f) + perror(h->parent_and_entry); + else { + // create an entry for this file. the map key is the file name; its value is the file contents + unsigned char *js = zsv_json_from_str((const unsigned char *)h->parent_and_entry + strlen((const char *)ctx->parent_dir) + 1); + if(!js) + errno = ENOMEM, perror(NULL); + else if(*js) { + if(ctx->count > 0) + if(zsv_jq_parse(ctx->zjq, ",", 1)) + ctx->err = 1; + if(!ctx->err) { + ctx->count++; + if(zsv_jq_parse(ctx->zjq, js, strlen((const char *)js)) || zsv_jq_parse(ctx->zjq, ":", 1)) + ctx->err = 1; + else { + switch(suffix) { + case 'j': // json + if(zsv_jq_parse_file(ctx->zjq, f)) + ctx->err = 1; + break; + case 't': // txt + // for now we are going to limit txt file values to 4096 chars and JSON-stringify it + { + unsigned char buff[4096]; + size_t n = fread(buff, 1, sizeof(buff), f); + unsigned char *txt_js = NULL; + if(n) { + txt_js = zsv_json_from_str_n(buff, n); + if(zsv_jq_parse(ctx->zjq, txt_js ? txt_js : (const unsigned char *)"null", txt_js ? strlen((const char *)txt_js) : 4)) + ctx->err = 1; } - break; } + break; } } } - free(js); - fclose(f); } + free(js); + fclose(f); } } - h->ctx = ctx; } + h->ctx = ctx; return 0; } diff --git a/include/zsv/utils/dirs.h b/include/zsv/utils/dirs.h index 7627e83f..5fa746df 100644 --- a/include/zsv/utils/dirs.h +++ b/include/zsv/utils/dirs.h @@ -92,7 +92,7 @@ int zsv_foreach_dirent(const char *dir_path, ); struct zsv_dir_filter { - zsv_foreach_dirent_handler filter; /* filter function; return 1 to process this node */ + zsv_foreach_dirent_handler filter; /* filter function; return 1 to process this node. if node is dir, return 0 to skip entirely */ size_t max_depth; /* max depth to recurse */ void *ctx; /* pointer to pass to filter function */ };