Index: Makefile ================================================================== --- Makefile +++ Makefile @@ -7,13 +7,17 @@ TCLSH := tclsh LIB_SUFFIX := $(shell . "${TCL_CONFIG_SH}"; echo "$${TCL_SHLIB_SUFFIX:-.so}") all: example-standalone$(LIB_SUFFIX) example-client$(LIB_SUFFIX) example-flexible$(LIB_SUFFIX) xvfs$(LIB_SUFFIX) -example.c: $(shell find example -type f) $(shell find lib -type f) lib/xvfs/xvfs.c.rvt xvfs-create Makefile - ./xvfs-create --directory example --name example > example.c.new - mv example.c.new example.c +example.c: $(shell find example -type f) $(shell find lib -type f) lib/xvfs/xvfs.c.rvt xvfs-create-c xvfs-create Makefile + rm -f example.c.new.1 example.c.new.2 + ./xvfs-create-c --directory example --name example > example.c.new.1 + ./xvfs-create --directory example --name example > example.c.new.2 + diff -u example.c.new.1 example.c.new.2 + rm -f example.c.new.2 + mv example.c.new.1 example.c example-standalone.o: example.c xvfs-core.h xvfs-core.c Makefile $(CC) $(CPPFLAGS) -DXVFS_MODE_STANDALONE $(CFLAGS) -o example-standalone.o -c example.c example-standalone$(LIB_SUFFIX): example-standalone.o Makefile @@ -43,10 +47,16 @@ rm -f xvfs-create-standalone.new xvfs-create-standalone ./xvfs-create --dump-tcl --remove-debug > xvfs-create-standalone.new chmod +x xvfs-create-standalone.new mv xvfs-create-standalone.new xvfs-create-standalone +xvfs-create-c: xvfs-create-c.o + $(CC) $(CFLAGS) $(LDFLAGS) -o xvfs-create-c xvfs-create-c.o $(LIBS) + +xvfs-create-c.o: xvfs-create-c.c + $(CC) $(CPPFLAGS) $(CFLAGS) -o xvfs-create-c.o -c xvfs-create-c.c + xvfs_random$(LIB_SUFFIX): $(shell find example -type f) $(shell find lib -type f) lib/xvfs/xvfs.c.rvt xvfs-create-random Makefile ./xvfs-create-random | $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -DXVFS_MODE_FLEXIBLE -x c - -shared -o xvfs_random$(LIB_SUFFIX) $(LIBS) xvfs_synthetic$(LIB_SUFFIX): $(shell find lib -type f) lib/xvfs/xvfs.c.rvt xvfs-create-synthetic Makefile ./xvfs-create-synthetic | $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -DXVFS_MODE_FLEXIBLE -x c - -shared -o xvfs_synthetic$(LIB_SUFFIX) $(LIBS) @@ -97,11 +107,12 @@ valgrind --tool=callgrind --callgrind-out-file=callgrind.out ./profile-bare 10 2 callgrind_annotate callgrind.out clean: rm -f xvfs-create-standalone.new xvfs-create-standalone - rm -f example.c example.c.new + rm -f xvfs-create-c.o xvfs-create-c + rm -f example.c example.c.new example.c.new.1 example.c.new.2 rm -f example-standalone$(LIB_SUFFIX) example-standalone.o rm -f example-client.o example-client$(LIB_SUFFIX) rm -f example-flexible.o example-flexible$(LIB_SUFFIX) rm -f xvfs.o xvfs$(LIB_SUFFIX) rm -f example-standalone.gcda example-standalone.gcno Index: lib/xvfs/xvfs.c.rvt ================================================================== --- lib/xvfs/xvfs.c.rvt +++ lib/xvfs/xvfs.c.rvt @@ -1,8 +1,15 @@ #include #include #include #include @@ -53,13 +60,12 @@ #endif + set ::xvfs::fileInfoStruct [xvfs::main $::xvfs::argv] +?> static long xvfs__nameToIndex(const char *path) { +#include +#include + +struct options { + char *name; + char *directory; +}; + +enum xvfs_minirivet_mode { + XVFS_MINIRIVET_MODE_COPY, + XVFS_MINIRIVET_MODE_TCL, + XVFS_MINIRIVET_MODE_TCL_PRINT +}; + +static int parse_options(int argc, char **argv, struct options *options) { + char *arg; + char **option; + int idx; + int retval; + + for (idx = 0; idx < argc; idx++) { + arg = argv[idx]; + + if (strcmp(arg, "--directory") == 0) { + option = &options->directory; + } else if (strcmp(arg, "--name") == 0) { + option = &options->name; + } else { + fprintf(stderr, "Invalid argument %s\n", arg); + + return(0); + } + + idx++; + arg = argv[idx]; + *option = arg; + } + + retval = 1; + if (!options->directory) { + fprintf(stderr, "error: --directory must be specified\n"); + retval = 0; + } + + if (!options->name) { + fprintf(stderr, "error: --name must be specified\n"); + retval = 0; + } + + return(retval); +} + +static void parse_xvfs_minirivet_directory(FILE *outfp, const char * const directory) { + fprintf(outfp, "\t...\n"); +} + +static int parse_xvfs_minirivet(FILE *outfp, const char * const file, const char * const name, const char * const directory) { + FILE *fp; + int ch, ch_buf[3]; + char tcl_buffer[8192], *tcl_buffer_p, *tcl_buffer_e; + enum xvfs_minirivet_mode mode; + + fp = fopen(file, "r"); + if (!fp) { + return(0); + } + +#define parse_xvfs_minirivet_getbyte(var) var = fgetc(fp); if (var == EOF) { break; } + + mode = XVFS_MINIRIVET_MODE_COPY; + while (1) { + parse_xvfs_minirivet_getbyte(ch); + + switch (mode) { + case XVFS_MINIRIVET_MODE_COPY: + if (ch == '<') { + parse_xvfs_minirivet_getbyte(ch_buf[0]); + if (ch_buf[0] != '?') { + fputc('<', outfp); + ch = ch_buf[0]; + + break; + } + + tcl_buffer_p = tcl_buffer; + parse_xvfs_minirivet_getbyte(ch_buf[0]); + if (ch_buf[0] == '=') { + mode = XVFS_MINIRIVET_MODE_TCL_PRINT; + } else { + mode = XVFS_MINIRIVET_MODE_TCL; + *tcl_buffer_p = ch_buf[0]; + tcl_buffer_p++; + } + *tcl_buffer_p = '\0'; + continue; + } + break; + case XVFS_MINIRIVET_MODE_TCL: + case XVFS_MINIRIVET_MODE_TCL_PRINT: + if (ch == '?') { + parse_xvfs_minirivet_getbyte(ch_buf[0]); + if (ch_buf[0] != '>') { + *tcl_buffer_p = ch; + tcl_buffer_p++; + + ch = ch_buf[0]; + + break; + } + + *tcl_buffer_p = '\0'; + + if (mode == XVFS_MINIRIVET_MODE_TCL_PRINT) { + tcl_buffer_p = tcl_buffer; + while (*tcl_buffer_p && isspace(*tcl_buffer_p)) { + tcl_buffer_p++; + } + tcl_buffer_e = tcl_buffer_p + strlen(tcl_buffer_p) - 1; + while (tcl_buffer_e >= tcl_buffer_p && isspace(*tcl_buffer_e)) { + *tcl_buffer_e = '\0'; + tcl_buffer_e--; + } + + if (strcmp(tcl_buffer_p, "$::xvfs::fsName") == 0) { + fprintf(outfp, name); + } else if (strcmp(tcl_buffer_p, "$::xvfs::fileInfoStruct") == 0) { + fprintf(outfp, "static const struct xvfs_file_data xvfs_"); + fprintf(outfp, name); + fprintf(outfp, "_data[] = {\n"); + parse_xvfs_minirivet_directory(outfp, directory); + fprintf(outfp, "};\n"); + } else if (strcmp(tcl_buffer_p, "[zlib adler32 $::xvfs::fsName]") == 0) { + fprintf(outfp, "0"); + } else { + fprintf(outfp, "@INVALID@%s@INVALID@", tcl_buffer_p); + } + } + + mode = XVFS_MINIRIVET_MODE_COPY; + continue; + } + break; + } + + switch (mode) { + case XVFS_MINIRIVET_MODE_COPY: + fputc(ch, outfp); + break; + case XVFS_MINIRIVET_MODE_TCL: + case XVFS_MINIRIVET_MODE_TCL_PRINT: + *tcl_buffer_p = ch; + tcl_buffer_p++; + break; + } + } + +#undef parse_xvfs_minirivet_getbyte + + return(1); +} + +static int xvfs_create(FILE *outfp, const char * const name, const char * const directory) { + return(parse_xvfs_minirivet(outfp, "lib/xvfs/xvfs.c.rvt", name, directory)); +} + +int main(int argc, char **argv) { + struct options options = {0}; + int parse_options_ret, xvfs_create_ret; + + argc--; + argv++; + + parse_options_ret = parse_options(argc, argv, &options); + if (!parse_options_ret) { + return(1); + } + + xvfs_create_ret = xvfs_create(stdout, options.name, options.directory); + if (!xvfs_create_ret) { + return(1); + } + + return(0); +}