From 5d33d165a2854f579140404c36ca5c0da21efe08 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Wed, 11 Dec 2019 20:57:23 -0500 Subject: [PATCH] cfspack: allow multiple patterns and multiple paths in args Also, always end the CFS chain with a stop block. fixes #55 #56 #57 --- tools/cfspack/README.md | 8 +++- tools/cfspack/cfspack.c | 86 +++++++++++++++++++++++++++++++---------- tools/zasm.sh | 6 +-- 3 files changed, 72 insertions(+), 28 deletions(-) diff --git a/tools/cfspack/README.md b/tools/cfspack/README.md index 5ddaf8a..20a9d6f 100644 --- a/tools/cfspack/README.md +++ b/tools/cfspack/README.md @@ -12,12 +12,16 @@ To pack a directory into a CFS blob, run: The blob is spit to stdout. If there are subdirectories, they will be prefixes to the filenames under it. -`cfspack` takes an optional second argument, a "fnmatch" pattern. If specified, -only files patching the pattern will be included. +`cfspack` takes optional -p pattern arguments. If specified, only files +matching at least one of the patterns ("fnmatch" style") will be included. If path is a file, a CFS with a single file will be spit and its name will exclude the directory part of that filename. +The chain being spitted is always ended with a "stop block" (a zero-allocation +block that stops the CFS chain). You can call `cfspack` with no argument to get +only a stop block. + The program errors out if a file name is too long (> 26 bytes) or too big (> 0x10000 - 0x20 bytes). diff --git a/tools/cfspack/cfspack.c b/tools/cfspack/cfspack.c index f222c79..5aafdb5 100644 --- a/tools/cfspack/cfspack.c +++ b/tools/cfspack/cfspack.c @@ -1,4 +1,6 @@ #include +#include +#include #include #include #include @@ -17,6 +19,16 @@ int is_regular_file(char *path) return S_ISREG(path_stat.st_mode); } +void spitempty() +{ + putchar('C'); + putchar('F'); + putchar('S'); + for (int i=0; i<0x20-3; i++) { + putchar(0); + } +} + int spitblock(char *fullpath, char *fn) { FILE *fp = fopen(fullpath, "r"); @@ -65,7 +77,7 @@ int spitblock(char *fullpath, char *fn) return 0; } -int spitdir(char *path, char *prefix, char *pattern) +int spitdir(char *path, char *prefix, char **patterns) { DIR *dp; struct dirent *ep; @@ -100,15 +112,23 @@ int spitdir(char *path, char *prefix, char *pattern) } strcat(newprefix, ep->d_name); if (ep->d_type == DT_DIR) { - int r = spitdir(fullpath, newprefix, pattern); + int r = spitdir(fullpath, newprefix, patterns); if (r != 0) { return r; } } else { - if (pattern) { - if (fnmatch(pattern, ep->d_name, 0) != 0) { - continue; + char **p = patterns; + // if we have no pattern, we match all + int matches = (*p) == NULL ? 1 : 0; + while (*p) { + if (fnmatch(*p, ep->d_name, 0) == 0) { + matches = 1; + break; } + p++; + } + if (!matches) { + continue; } int r = spitblock(fullpath, newprefix); @@ -121,22 +141,46 @@ int spitdir(char *path, char *prefix, char *pattern) return 0; } -int main(int argc, char *argv[]) +void usage() { - if ((argc > 3) || (argc < 2)) { - fprintf(stderr, "Usage: cfspack /path/to/dir [pattern] \n"); - return 1; - } - char *srcpath = argv[1]; - char *pattern = NULL; - if (argc == 3) { - pattern = argv[2]; - } - if (is_regular_file(srcpath)) { - // special case: just one file - return spitblock(srcpath, basename(srcpath)); - } else { - return spitdir(srcpath, "", pattern); - } + fprintf(stderr, "Usage: cfspack [-p pattern] [/path/to/dir...]\n"); +} + +int main(int argc, char *argv[]) +{ + int patterncount = 0; + char **patterns = malloc(sizeof(char**)); + patterns[0] = NULL; + while (1) { + int c = getopt(argc, argv, "p:"); + if (c < 0) { + break; + } + switch (c) { + case 'p': + patterns[patterncount] = optarg; + patterncount++; + patterns = realloc(patterns, sizeof(char**)*(patterncount+1)); + patterns[patterncount] = NULL; + break; + default: + usage(); + return 1; + } + } + int res = 0; + for (int i=optind; i> "${INCCFS}" - "${CFSPACK}" "${p}" "*.asm" >> "${INCCFS}" - "${CFSPACK}" "${p}" "*.bin" >> "${INCCFS}" -done +"${CFSPACK}" -p "*.h" -p "*.asm" -p "*.bin" "$@" > "${INCCFS}" "${ZASMBIN}" "${org}" "${INCCFS}" RES=$?