From 3adf3f51212c4330010bf04c63687b7593c29b6f Mon Sep 17 00:00:00 2001 From: Emanuel Guevel Date: Tue, 5 Mar 2013 00:45:25 +0100 Subject: [PATCH] Revive bsatool --- CMakeLists.txt | 13 ++- apps/bsatool/CMakeLists.txt | 26 ++++++ apps/bsatool/bsatool.cpp | 86 +++++++++++++++++ .../bsa/tests => apps/bsatool}/bsatool.ggo | 0 .../bsa/tests => apps/bsatool}/bsatool_cmd.c | 62 ++++++------- .../bsa/tests => apps/bsatool}/bsatool_cmd.h | 6 +- components/bsa/tests/Makefile | 9 +- components/bsa/tests/bsatool.cpp | 92 ------------------- 8 files changed, 159 insertions(+), 135 deletions(-) create mode 100644 apps/bsatool/CMakeLists.txt create mode 100644 apps/bsatool/bsatool.cpp rename {components/bsa/tests => apps/bsatool}/bsatool.ggo (100%) rename {components/bsa/tests => apps/bsatool}/bsatool_cmd.c (99%) rename {components/bsa/tests => apps/bsatool}/bsatool_cmd.h (98%) delete mode 100644 components/bsa/tests/bsatool.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 6498e723c2..3950274790 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,6 +29,7 @@ option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binarie option(BOOST_STATIC "Link static build of Boost into the binaries" FALSE) # Apps and tools +option(BUILD_BSATOOL "build BSA extractor" OFF) option(BUILD_ESMTOOL "build ESM inspector" ON) option(BUILD_LAUNCHER "build Launcher" ON) option(BUILD_MWINIIMPORTER "build MWiniImporter" ON) @@ -352,7 +353,7 @@ if(DPKG_PROGRAM) Data files from the original game is required to run it.") SET(CPACK_DEBIAN_PACKAGE_NAME "openmw") SET(CPACK_DEBIAN_PACKAGE_VERSION "${VERSION_STRING}") - SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW esmtool;Esmtool omwlauncher;OMWLauncher mwiniimporter;MWiniImporter") + SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW bsatool;Bsatool esmtool;Esmtool omwlauncher;OMWLauncher mwiniimporter;MWiniImporter") SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.11.2), libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libmpg123-0 (>= 1.12.1), libois-1.3.0 (>= 1.3.0), libopenal1 (>= 1:1.12.854), libsndfile1 (>= 1.0.23), libstdc++6 (>= 4.4.5), libuuid1 (>= 2.17.2), libqtgui4 (>= 4.7.0)") SET(CPACK_DEBIAN_PACKAGE_SECTION "Games") @@ -446,6 +447,10 @@ add_subdirectory (components) # Apps and tools add_subdirectory( apps/openmw ) +if (BUILD_BSATOOL) + add_subdirectory( apps/bsatool ) +endif() + if (BUILD_ESMTOOL) add_subdirectory( apps/esmtool ) endif() @@ -532,6 +537,9 @@ if (WIN32) set_target_properties(omwlauncher PROPERTIES COMPILE_FLAGS ${WARNINGS}) endif (BUILD_LAUNCHER) set_target_properties(openmw PROPERTIES COMPILE_FLAGS ${WARNINGS}) + if (BUILD_BSATOOL) + set_target_properties(bsatool PROPERTIES COMPILE_FLAGS ${WARNINGS}) + endif (BUILD_BSATOOL) if (BUILD_ESMTOOL) set_target_properties(esmtool PROPERTIES COMPILE_FLAGS ${WARNINGS}) endif (BUILD_ESMTOOL) @@ -656,6 +664,9 @@ if (NOT WIN32 AND NOT DPKG_PROGRAM AND NOT APPLE) IF(BUILD_LAUNCHER) INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/omwlauncher" DESTINATION "${BINDIR}" ) ENDIF(BUILD_LAUNCHER) + IF(BUILD_BSATOOL) + INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/bsatool" DESTINATION "${BINDIR}" ) + ENDIF(BUILD_BSATOOL) IF(BUILD_ESMTOOL) INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/esmtool" DESTINATION "${BINDIR}" ) ENDIF(BUILD_ESMTOOL) diff --git a/apps/bsatool/CMakeLists.txt b/apps/bsatool/CMakeLists.txt new file mode 100644 index 0000000000..8e33f0675c --- /dev/null +++ b/apps/bsatool/CMakeLists.txt @@ -0,0 +1,26 @@ +set(BSATOOL + bsatool.cpp + bsatool_cmd.c + bsatool_cmd.h +) +source_group(apps\\bsatool FILES ${BSATOOL}) + +# Main executable +add_executable(bsatool + ${BSATOOL} +) + +target_link_libraries(bsatool + ${Boost_LIBRARIES} + components +) + +#if (APPLE) +# find_library(CARBON_FRAMEWORK Carbon) +# target_link_libraries(openmw ${CARBON_FRAMEWORK}) +#endif (APPLE) + +if (BUILD_WITH_CODE_COVERAGE) + add_definitions (--coverage) + target_link_libraries(bsatool gcov) +endif() diff --git a/apps/bsatool/bsatool.cpp b/apps/bsatool/bsatool.cpp new file mode 100644 index 0000000000..2d15f8cf7c --- /dev/null +++ b/apps/bsatool/bsatool.cpp @@ -0,0 +1,86 @@ +#include + +#include "bsatool_cmd.h" + +#include +#include +#include +#include + +int main(int argc, char** argv) +{ + gengetopt_args_info info; + + if(cmdline_parser(argc, argv, &info) != 0) + return 1; + + if(info.inputs_num != 1) + { + if(info.inputs_num == 0) + std::cout << "ERROR: missing BSA file\n\n"; + else + std::cout << "ERROR: more than one BSA file specified\n\n"; + cmdline_parser_print_help(); + return 1; + } + + // Open file + Bsa::BSAFile bsa; + char *arcname = info.inputs[0]; + try { bsa.open(arcname); } + catch(std::exception &e) + { + std::cout << "ERROR reading BSA archive '" << arcname + << "'\nDetails:\n" << e.what() << std::endl; + return 2; + } + + if(info.extract_given) + { + char *file = info.extract_arg; + + if(!bsa.exists(file)) + { + std::cout << "ERROR: file '" << file << "' not found\n"; + std::cout << "In archive: " << arcname << std::endl; + return 3; + } + + // Find the base name of the file + int pos = strlen(file); + while(pos > 0 && file[pos] != '\\') pos--; + char *base = file+pos+1; + + // TODO: We might add full directory name extraction later. We + // could also allow automatic conversion from / to \ in + // parameter file names. + + // Load the file into a memory buffer + Ogre::DataStreamPtr data = bsa.getFile(file); + + // Write the file to disk + std::ofstream out(base, std::ios::binary); + out.write(data->getAsString().c_str(), data->size()); + out.close(); + + return 0; + } + + // List all files + const Bsa::BSAFile::FileList &files = bsa.getList(); + for(int i=0; i -#include +#include +#include #include #ifndef FIX_UNUSED @@ -71,7 +71,7 @@ void clear_args (struct gengetopt_args_info *args_info) FIX_UNUSED (args_info); args_info->extract_arg = NULL; args_info->extract_orig = NULL; - + } static @@ -83,7 +83,7 @@ void init_args_info(struct gengetopt_args_info *args_info) args_info->version_help = gengetopt_args_info_help[1] ; args_info->extract_help = gengetopt_args_info_help[2] ; args_info->long_help = gengetopt_args_info_help[3] ; - + } void @@ -133,7 +133,7 @@ void cmdline_parser_params_init(struct cmdline_parser_params *params) { if (params) - { + { params->override = 0; params->initialize = 1; params->check_required = 1; @@ -145,9 +145,9 @@ cmdline_parser_params_init(struct cmdline_parser_params *params) struct cmdline_parser_params * cmdline_parser_params_create(void) { - struct cmdline_parser_params *params = + struct cmdline_parser_params *params = (struct cmdline_parser_params *)malloc(sizeof(struct cmdline_parser_params)); - cmdline_parser_params_init(params); + cmdline_parser_params_init(params); return params; } @@ -168,8 +168,8 @@ cmdline_parser_release (struct gengetopt_args_info *args_info) unsigned int i; free_string_field (&(args_info->extract_arg)); free_string_field (&(args_info->extract_orig)); - - + + for (i = 0; i < args_info->inputs_num; ++i) free (args_info->inputs [i]); @@ -211,7 +211,7 @@ cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) write_into_file(outfile, "extract", args_info->extract_orig, 0); if (args_info->long_given) write_into_file(outfile, "long", 0, 0 ); - + i = EXIT_SUCCESS; return i; @@ -276,7 +276,7 @@ cmdline_parser_ext (int argc, char * const *argv, struct gengetopt_args_info *ar cmdline_parser_free (args_info); exit (EXIT_FAILURE); } - + return result; } @@ -285,7 +285,7 @@ cmdline_parser2 (int argc, char * const *argv, struct gengetopt_args_info *args_ { int result; struct cmdline_parser_params params; - + params.override = override; params.initialize = initialize; params.check_required = check_required; @@ -299,7 +299,7 @@ cmdline_parser2 (int argc, char * const *argv, struct gengetopt_args_info *args_ cmdline_parser_free (args_info); exit (EXIT_FAILURE); } - + return result; } @@ -324,7 +324,7 @@ cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog * */ -/* +/* * we must include anything we need since this file is not thought to be * inserted in a file already using getopt.h * @@ -859,7 +859,7 @@ static int getopt_internal_r(int argc, char *const *argv, const char *optstring, return -1; d->custom_optarg = NULL; - /* + /* * This is a big difference with GNU getopt, since optind == 0 * means initialization while here 1 means first call. */ @@ -926,7 +926,7 @@ static char *package_name = 0; */ static int update_arg(void *field, char **orig_field, - unsigned int *field_given, unsigned int *prev_given, + unsigned int *field_given, unsigned int *prev_given, char *value, const char *possible_values[], const char *default_value, cmdline_parser_arg_type arg_type, @@ -947,18 +947,18 @@ int update_arg(void *field, char **orig_field, if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given))) { if (short_opt != '-') - fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n", + fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n", package_name, long_opt, short_opt, (additional_error ? additional_error : "")); else - fprintf (stderr, "%s: `--%s' option given more than once%s\n", + fprintf (stderr, "%s: `--%s' option given more than once%s\n", package_name, long_opt, (additional_error ? additional_error : "")); return 1; /* failure */ } FIX_UNUSED (default_value); - + if (field_given && *field_given && ! override) return 0; if (prev_given) @@ -1011,7 +1011,7 @@ cmdline_parser_internal ( int error = 0; struct gengetopt_args_info local_args_info; - + int override; int initialize; int check_required; @@ -1021,9 +1021,9 @@ cmdline_parser_internal ( int optind; int opterr; int optopt; - + package_name = argv[0]; - + override = params->override; initialize = params->initialize; check_required = params->check_required; @@ -1078,28 +1078,28 @@ cmdline_parser_internal ( exit (EXIT_SUCCESS); case 'x': /* Extract file from archive. */ - - - if (update_arg( (void *)&(args_info->extract_arg), + + + if (update_arg( (void *)&(args_info->extract_arg), &(args_info->extract_orig), &(args_info->extract_given), &(local_args_info.extract_given), optarg, 0, 0, ARG_STRING, check_ambiguity, override, 0, 0, "extract", 'x', additional_error)) goto failure; - + break; case 'l': /* Include extra information in archive listing. */ - - - if (update_arg( 0 , + + + if (update_arg( 0 , 0 , &(args_info->long_given), &(local_args_info.long_given), optarg, 0, 0, ARG_NO, check_ambiguity, override, 0, 0, "long", 'l', additional_error)) goto failure; - + break; case 0: /* Long option with no short option */ @@ -1140,7 +1140,7 @@ cmdline_parser_internal ( return 0; failure: - + cmdline_parser_release (&local_args_info); return (EXIT_FAILURE); } diff --git a/components/bsa/tests/bsatool_cmd.h b/apps/bsatool/bsatool_cmd.h similarity index 98% rename from components/bsa/tests/bsatool_cmd.h rename to apps/bsatool/bsatool_cmd.h index 98fe2633fe..4d5f80ea27 100644 --- a/components/bsa/tests/bsatool_cmd.h +++ b/apps/bsatool/bsatool_cmd.h @@ -13,7 +13,7 @@ #include "config.h" #endif -#include /* for FILE */ +#include /* for FILE */ #ifdef __cplusplus extern "C" { @@ -43,7 +43,7 @@ struct gengetopt_args_info char * extract_orig; /**< @brief Extract file from archive original value given at command line. */ const char *extract_help; /**< @brief Extract file from archive help description. */ const char *long_help; /**< @brief Include extra information in archive listing help description. */ - + unsigned int help_given ; /**< @brief Whether help was given. */ unsigned int version_given ; /**< @brief Whether version was given. */ unsigned int extract_given ; /**< @brief Whether extract was given. */ @@ -136,7 +136,7 @@ void cmdline_parser_print_help(void); void cmdline_parser_print_version(void); /** - * Initializes all the fields a cmdline_parser_params structure + * Initializes all the fields a cmdline_parser_params structure * to their default values * @param params the structure to initialize */ diff --git a/components/bsa/tests/Makefile b/components/bsa/tests/Makefile index bc2bf4e50f..73e20d7b3a 100644 --- a/components/bsa/tests/Makefile +++ b/components/bsa/tests/Makefile @@ -1,6 +1,6 @@ GCC=g++ -all: bsa_file_test bsatool ogre_archive_test +all: bsa_file_test ogre_archive_test I_OGRE=$(shell pkg-config --cflags OGRE) L_OGRE=$(shell pkg-config --libs OGRE) @@ -11,12 +11,5 @@ bsa_file_test: bsa_file_test.cpp ../bsa_file.cpp ogre_archive_test: ogre_archive_test.cpp ../bsa_file.cpp ../bsa_archive.cpp $(GCC) $^ -o $@ $(I_OGRE) $(L_OGRE) -bsatool: bsatool.cpp ../bsa_file.cpp bsatool_cmd.c - $(GCC) $^ -o $@ - -bsatool_cmd.c: bsatool.ggo - gengetopt < bsatool.ggo - clean: rm *_test - rm bsatool diff --git a/components/bsa/tests/bsatool.cpp b/components/bsa/tests/bsatool.cpp deleted file mode 100644 index df37e3827c..0000000000 --- a/components/bsa/tests/bsatool.cpp +++ /dev/null @@ -1,92 +0,0 @@ -#include "../bsa_file.hpp" - -#include "bsatool_cmd.h" - -#include -#include -#include -#include - -#include "../../mangle/stream/filters/buffer_stream.hpp" - -using namespace std; -using namespace Mangle::Stream; -using namespace Bsa; - -int main(int argc, char** argv) -{ - gengetopt_args_info info; - - if(cmdline_parser(argc, argv, &info) != 0) - return 1; - - if(info.inputs_num != 1) - { - if(info.inputs_num == 0) - cout << "ERROR: missing BSA file\n\n"; - else - cout << "ERROR: more than one BSA file specified\n\n"; - cmdline_parser_print_help(); - return 1; - } - - // Open file - BSAFile bsa; - char *arcname = info.inputs[0]; - try { bsa.open(arcname); } - catch(exception &e) - { - cout << "ERROR reading BSA archive '" << arcname - << "'\nDetails:\n" << e.what() << endl; - return 2; - } - - if(info.extract_given) - { - char *file = info.extract_arg; - - if(!bsa.exists(file)) - { - cout << "ERROR: file '" << file << "' not found\n"; - cout << "In archive: " << arcname << endl; - return 3; - } - - // Find the base name of the file - int pos = strlen(file); - while(pos > 0 && file[pos] != '\\') pos--; - char *base = file+pos+1; - - // TODO: We might add full directory name extraction later. We - // could also allow automatic conversion from / to \ in - // parameter file names. - - // Load the file into a memory buffer - BufferStream data(bsa.getFile(file)); - - // Write the file to disk - ofstream out(base, ios::binary); - out.write((char*)data.getPtr(), data.size()); - out.close(); - - return 0; - } - - // List all files - const BSAFile::FileList &files = bsa.getList(); - for(int i=0; i