From: Thomas Perl Date: Sun, 28 Jul 2013 02:47:52 +0000 (+0200) Subject: Rewrite archive utility (command line parsing, C++) X-Git-Tag: tennix-1.2.1~9 X-Git-Url: https://repo.or.cz/w/tennix.git/commitdiff_plain/37def4d07d12eb77683db5e118211d8fb2b76985 Rewrite archive utility (command line parsing, C++) --- diff --git a/makefile b/makefile index 7d1891d..e478d6c 100644 --- a/makefile +++ b/makefile @@ -37,13 +37,10 @@ TENNIX_OBJ += src/tennix.o src/game.o src/graphics.o src/input.o TENNIX_OBJ += src/util.o src/sound.o src/animation.o src/archive.o TENNIX_OBJ += src/SDL_rotozoom.o src/network.o src/tennixpy.o -# Object files for "archive" -ARCHIVE_BIN := archive +# Object files for "tnxar" +ARCHIVE_BIN := tnxar ARCHIVE_OBJ += src/archivetool.o src/archive.o -# Target filename for "dump" -DUMP_BIN := dump - # Data files for tennix.tnx TENNIX_TNX := tennix.tnx TENNIX_TNX_DATA += $(wildcard data/*.ogg) @@ -63,7 +60,7 @@ TENNIX_PNG := data/tennix.png TENNIX_DESKTOP := data/tennix.desktop TENNIX_MAN := data/tennix.6 -all: $(TENNIX_BIN) $(ARCHIVE_BIN) $(DUMP_BIN) $(TENNIX_TNX) +all: $(TENNIX_BIN) $(ARCHIVE_BIN) $(TENNIX_TNX) %.o: %.cc $(SILENTMSG) " CXX $@" @@ -77,13 +74,9 @@ $(ARCHIVE_BIN): $(ARCHIVE_OBJ) $(SILENTMSG) " LD $@" $(SILENTCMD)$(CXX) -o $@ $^ -$(DUMP_BIN): $(ARCHIVE_BIN) - $(SILENTMSG) " SYMLINK $@" - $(SILENTCMD)$(LN) -s $< $@ - $(TENNIX_TNX): $(ARCHIVE_BIN) $(TENNIX_TNX_DATA) - $(SILENTMSG) " ARCHIVE $@" - $(SILENTCMD)./$(ARCHIVE_BIN) $@ $(TENNIX_TNX_DATA) + $(SILENTMSG) " TNXAR $@" + $(SILENTCMD)./$(ARCHIVE_BIN) -cf $@ $(TENNIX_TNX_DATA) install: $(TENNIX_BIN) $(TENNIX_TNX) $(TENNIX_PNG) $(TENNIX_DESKTOP) $(TENNIX_MAN) $(SILENTMSG) " INSTALL $(TENNIX_BIN)" @@ -106,7 +99,6 @@ clean: $(SILENTMSG) " CLEAN" $(SILENTCMD)$(RM) -f $(TENNIX_BIN) $(TENNIX_OBJ) $(SILENTCMD)$(RM) -f $(ARCHIVE_BIN) $(ARCHIVE_OBJ) - $(SILENTCMD)$(RM) -f $(DUMP_BIN) $(SILENTCMD)$(RM) -f $(TENNIX_TNX) distclean: clean diff --git a/src/archive.cc b/src/archive.cc index 962a950..921d1df 100644 --- a/src/archive.cc +++ b/src/archive.cc @@ -38,6 +38,15 @@ #include "archive.h" +static void +xormem(char* mem, uint32_t length, char key) +{ + char *i = mem, *end = mem+length; + for(; i != end; i++) { + *i ^= key; + } +} + TennixArchive::TennixArchive() : fp(NULL) , header() @@ -64,7 +73,11 @@ TennixArchive::TennixArchive(const char* filename, const char* fallback) if (fp == NULL && fallback != NULL) { fp = fopen(fallback, "rb"); } - tnx_assert(fp != NULL); + + if (fp == NULL) { + fprintf(stderr, "Cannot open archive: %s\n", filename); + exit(1); + } offset = sizeof(TennixArchiveHeader)*fread(&(header), sizeof(TennixArchiveHeader), 1, fp); tnx_assert(offset == sizeof(TennixArchiveHeader)); @@ -139,16 +152,6 @@ TennixArchive::getItemBytes() } void -TennixArchive::xormem(char* mem, uint32_t length, char key) -{ - char *i = mem, *end = mem+length; - - for(; i != end; i++) { - *i ^= key; - } -} - -void TennixArchive::appendItem(char* filename, char* data, uint32_t length) { TennixArchiveItem* item; diff --git a/src/archive.h b/src/archive.h index 6e44c47..331a649 100644 --- a/src/archive.h +++ b/src/archive.h @@ -76,8 +76,6 @@ class TennixArchive { int current_item; int building; - static void xormem(char* mem, uint32_t length, char key); - public: TennixArchive(); TennixArchive(const char* filename, const char* fallback=NULL); diff --git a/src/archivetool.cc b/src/archivetool.cc dissimilarity index 74% index 893c7b4..69b9a8e 100644 --- a/src/archivetool.cc +++ b/src/archivetool.cc @@ -1,125 +1,229 @@ - -/** - * - * Tennix Archive File Format - * Copyright (C) 2009-2010 Thomas Perl - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - * - **/ - -#include "tennix.h" - -#include -#include -#include -#include - -#include "archive.h" - -int main(int argc, char* argv[]) -{ - TennixArchive* tnxar; - char* data; - FILE *fp; - const char* filename; - char *bn = (char*)basename(argv[0]); - int len, i; - - if(strcmp(bn, "archive") == 0) { - if (argc < 2) { - fprintf(stderr, "Usage: %s archive.tnx file1 [....]\n", bn); - exit(EXIT_FAILURE); - } else if (argc == 2) { - fprintf(stderr, "Refusing to create an empty archive.\n"); - exit(EXIT_FAILURE); - } - - if (strcmp(".tnx", argv[1] + strlen(argv[1]) - 4) != 0) { - fprintf(stderr, "Wrong file extension: %s\n", argv[1]); - exit(EXIT_FAILURE); - } - - TennixArchive archive; - - //fprintf(stderr, "Creating %s with %d files\n", argv[1], argc-2); - for (i=2; i 3) { - fprintf(stderr, "Usage: %s archive.tnx [file]\n", bn); - exit(EXIT_FAILURE); - } - tnxar = new TennixArchive(argv[1]); - if (argc == 2) { - while (!tnxar->endOfFile()) { - filename = tnxar->getItemFilename(); - data = tnxar->getItemBytes(); - len = tnxar->getItemSize(); - fprintf(stderr, "Extracting: %s", filename); - fprintf(stderr, " (%d bytes)", len); - fp = fopen(filename, "wb"); - fputc('.', stderr); - tnx_assert(fwrite(data, len, 1, fp) == 1); - fputc('.', stderr); - fclose(fp); - fprintf(stderr, ".OK\n"); - free(data); - tnxar->next(); - } - } else if (argc == 3) { - filename = argv[2]; - if (tnxar->setItemFilename(filename) != 0) { - fprintf(stderr, "Extracting: %s", filename); - data = tnxar->getItemBytes(); - len = tnxar->getItemSize(); - fprintf(stderr, " (%d bytes)", len); - fp = fopen(filename, "wb"); - fputc('.', stderr); - tnx_assert(fwrite(data, len, 1, fp) == 1); - fputc('.', stderr); - fclose(fp); - fprintf(stderr, ".OK\n"); - free(data); - } else { - fprintf(stderr, "File not found in %s: %s\n", argv[1], filename); - delete tnxar; - exit(EXIT_FAILURE); - } - } - delete tnxar; - } - - return EXIT_SUCCESS; -} - + +/** + * + * Tennix Archive File Format + * Copyright (C) 2009-2010 Thomas Perl + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + **/ + +#include "tennix.h" + +#include +#include +#include +#include + +#include "archive.h" + +static int +extract_file(TennixArchive *tnxar, bool verbose) +{ + char *data = tnxar->getItemBytes(); + + if (verbose) { + printf("%s\n", tnxar->getItemFilename()); + } + + FILE *fp = fopen(tnxar->getItemFilename(), "wb"); + if (fp == NULL) { + return 1; + } + fwrite(data, tnxar->getItemSize(), 1, fp); + fclose(fp); + + free(data); + + return 0; +} + + +class ArchiveTool { + public: + ArchiveTool(int argc, char **argv); + + int run(); + + private: + int usage(); + + int create(bool verbose); + int test(bool verbose); + int extract(bool verbose); + + int argc; + char **argv; +}; + +ArchiveTool::ArchiveTool(int argc, char **argv) + : argc(argc) + , argv(argv) +{ +} + +int +ArchiveTool::run() +{ + bool do_create = false; + bool do_test = false; + bool do_extract = false; + bool verbose = false; + + if (argc < 2) { + return usage(); + } + + char *opts = argv[1]; + if (*opts == '-') opts++; + + while (*opts) { + switch (*opts) { + case 'c': + do_create = true; + break; + case 't': + do_test = true; + break; + case 'x': + do_extract = true; + break; + case 'v': + verbose = true; + break; + case 'f': + if (opts[1]) { + return usage(); + } + break; + default: + return usage(); + break; + } + opts++; + } + + if (do_create && !do_test && !do_extract && argc > 3) { + return create(verbose); + } else if (do_test && !do_create && !do_extract && argc > 2) { + return test(verbose); + } else if (do_extract && !do_create && !do_test && argc > 2) { + return extract(verbose); + } + + return usage(); +} + +int +ArchiveTool::create(bool verbose) +{ + if (argc < 4) { + fprintf(stderr, "Refusing to create an empty archive.\n"); + return 1; + } + + char *archive = argv[2]; + if (strcmp(".tnx", archive + strlen(archive) - 4) != 0) { + fprintf(stderr, "Wrong file extension: %s\n", archive); + return 1; + } + + TennixArchive tnxar; + for (int i=3; i file1 ...\n", argv[0]); + fprintf(stderr, " -c ... Create archive\n"); + fprintf(stderr, " -t ... Test archive (list contents)\n"); + fprintf(stderr, " -x ... Extract archive\n"); + fprintf(stderr, " -v ... Verbose output\n"); + fprintf(stderr, " -f ... Filename of archive (optional)\n"); + return 1; +} + +int +main(int argc, char **argv) +{ + ArchiveTool tool(argc, argv); + return tool.run(); +} +