Browse Source

cfspack: allow multiple patterns and multiple paths in args

Also, always end the CFS chain with a stop block.

fixes #55 #56 #57
pull/85/head
Virgil Dupras 4 years ago
parent
commit
5d33d165a2
3 changed files with 68 additions and 24 deletions
  1. +6
    -2
      tools/cfspack/README.md
  2. +61
    -17
      tools/cfspack/cfspack.c
  3. +1
    -5
      tools/zasm.sh

+ 6
- 2
tools/cfspack/README.md View File

@@ -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 The blob is spit to stdout. If there are subdirectories, they will be prefixes
to the filenames under it. 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 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. 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 The program errors out if a file name is too long (> 26 bytes) or too big
(> 0x10000 - 0x20 bytes). (> 0x10000 - 0x20 bytes).




+ 61
- 17
tools/cfspack/cfspack.c View File

@@ -1,4 +1,6 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h> #include <dirent.h>
#include <string.h> #include <string.h>
#include <fnmatch.h> #include <fnmatch.h>
@@ -17,6 +19,16 @@ int is_regular_file(char *path)
return S_ISREG(path_stat.st_mode); 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) int spitblock(char *fullpath, char *fn)
{ {
FILE *fp = fopen(fullpath, "r"); FILE *fp = fopen(fullpath, "r");
@@ -65,7 +77,7 @@ int spitblock(char *fullpath, char *fn)
return 0; return 0;
} }


int spitdir(char *path, char *prefix, char *pattern)
int spitdir(char *path, char *prefix, char **patterns)
{ {
DIR *dp; DIR *dp;
struct dirent *ep; struct dirent *ep;
@@ -100,15 +112,23 @@ int spitdir(char *path, char *prefix, char *pattern)
} }
strcat(newprefix, ep->d_name); strcat(newprefix, ep->d_name);
if (ep->d_type == DT_DIR) { if (ep->d_type == DT_DIR) {
int r = spitdir(fullpath, newprefix, pattern);
int r = spitdir(fullpath, newprefix, patterns);
if (r != 0) { if (r != 0) {
return r; return r;
} }
} else { } 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); int r = spitblock(fullpath, newprefix);
@@ -121,22 +141,46 @@ int spitdir(char *path, char *prefix, char *pattern)
return 0; return 0;
} }


void usage()
{
fprintf(stderr, "Usage: cfspack [-p pattern] [/path/to/dir...]\n");
}

int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
if ((argc > 3) || (argc < 2)) {
fprintf(stderr, "Usage: cfspack /path/to/dir [pattern] \n");
return 1;
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;
}
} }
char *srcpath = argv[1];
char *pattern = NULL;
if (argc == 3) {
pattern = argv[2];
int res = 0;
for (int i=optind; i<argc; i++) {
if (is_regular_file(argv[i])) {
// special case: just one file
res = spitblock(argv[i], basename(argv[i]));
} else {
res = spitdir(argv[i], "", patterns);
}
} }
if (is_regular_file(srcpath)) {
// special case: just one file
return spitblock(srcpath, basename(srcpath));
} else {
return spitdir(srcpath, "", pattern);
if (res == 0) {
spitempty();
} }
free(patterns);
return res;
} }



+ 1
- 5
tools/zasm.sh View File

@@ -31,11 +31,7 @@ ZASMBIN="${DIR}/emul/zasm/zasm"
CFSPACK="${DIR}/cfspack/cfspack" CFSPACK="${DIR}/cfspack/cfspack"
INCCFS=$(mktemp) INCCFS=$(mktemp)


for p in "$@"; do
"${CFSPACK}" "${p}" "*.h" >> "${INCCFS}"
"${CFSPACK}" "${p}" "*.asm" >> "${INCCFS}"
"${CFSPACK}" "${p}" "*.bin" >> "${INCCFS}"
done
"${CFSPACK}" -p "*.h" -p "*.asm" -p "*.bin" "$@" > "${INCCFS}"


"${ZASMBIN}" "${org}" "${INCCFS}" "${ZASMBIN}" "${org}" "${INCCFS}"
RES=$? RES=$?


Loading…
Cancel
Save