From 7ad83c80b8512bed383fe27c60e5dffd1255ae8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Mon, 2 May 2011 05:03:48 +0200 Subject: [PATCH] added modified getopt (c++-ized) with BSD license, vegetation flags clarified, prospector lists trees and plants separately, prospector pretty-prints --- CMakeLists.txt | 1 + LICENSE | 35 ++- library/depends/xgetopt/xgetopt.h | 249 ++++++++++++++++++++ library/include/dfhack/modules/Vegetation.h | 20 +- tools/supported/prospector.cpp | 39 ++- 5 files changed, 331 insertions(+), 13 deletions(-) create mode 100644 library/depends/xgetopt/xgetopt.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ac924f41..29e68e480 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -148,6 +148,7 @@ OPTION(BUILD_DFHACK_PLAYGROUND "Build tools from the playground folder" OFF) include_directories (${dfhack_SOURCE_DIR}/library/include/) include_directories (${dfhack_SOURCE_DIR}/library/shm/) include_directories (${dfhack_SOURCE_DIR}/library/depends/argstream/) +include_directories (${dfhack_SOURCE_DIR}/library/depends/xgetopt/) # macro to save on typing in the tool subdirs # builds a tool, links it to the dfhack lib and makes sure the dependency diff --git a/LICENSE b/LICENSE index 4cfc6a66d..d9943bf5a 100644 --- a/LICENSE +++ b/LICENSE @@ -137,4 +137,37 @@ would be appreciated but is not required. must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source -distribution. \ No newline at end of file +distribution. +------------------------------------------------------------------ +Free Getopt +Copyright (c)2002-2003 Mark K. Kim +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the original author of this software nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. diff --git a/library/depends/xgetopt/xgetopt.h b/library/depends/xgetopt/xgetopt.h new file mode 100644 index 000000000..f7aed5980 --- /dev/null +++ b/library/depends/xgetopt/xgetopt.h @@ -0,0 +1,249 @@ +/***************************************************************************** +* getopt.c - competent and free getopt library. +* $Header: /cvsroot/freegetopt/freegetopt/getopt.c,v 1.2 2003/10/26 03:10:20 vindaci Exp $ +* +* Copyright (c)2002-2003 Mark K. Kim +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* +* * Neither the original author of this software nor the names of its +* contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +* DAMAGE. +*/ +#include +#include +#include + +class xgetopt +{ +public: + xgetopt(int argc_, char** argv_, const char* optstr_) + { + optarg = NULL; + optind = 0; + opterr = 1; + optopt = '?'; + argv_index = 1; + argv_index2 = 1; + opt_offset = 1; + dashdash = 0; + nonopt = 0; + argc = argc_; + argv = argv_; + optstr = optstr_; + prev_argv = argv; + prev_argc = argc; + } + int optind; + int opterr; + int optopt; + + int operator()() + { + int c = 0; + /* Jump point in case we want to ignore the current argv_index */ + getopt_top: + + /* Misc. initializations */ + optarg = NULL; + + /* Dash-dash check */ + if(argv[argv_index] && !strcmp(argv[argv_index], "--")) + { + dashdash = 1; + increment_index(); + } + + /* If we're at the end of argv, that's it. */ + if(argv[argv_index] == NULL) + { + c = -1; + } + /* Are we looking at a string? Single dash is also a string */ + else if(dashdash || argv[argv_index][0] != '-' || !strcmp(argv[argv_index], "-")) + { + /* If we want a string... */ + if(optstr[0] == '-') + { + c = 1; + optarg = argv[argv_index]; + increment_index(); + } + /* If we really don't want it (we're in POSIX mode), we're done */ + else if(optstr[0] == '+' || getenv("POSIXLY_CORRECT")) + { + c = -1; + + /* Everything else is a non-opt argument */ + nonopt = argc - argv_index; + } + /* If we mildly don't want it, then move it back */ + else + { + if(!permute_argv_once()) goto getopt_top; + else c = -1; + } + } + /* Otherwise we're looking at an option */ + else + { + const char* opt_ptr = NULL; + + /* Grab the option */ + c = argv[argv_index][opt_offset++]; + + /* Is the option in the optstr? */ + if(optstr[0] == '-') opt_ptr = strchr(optstr+1, c); + else opt_ptr = strchr(optstr, c); + /* Invalid argument */ + if(!opt_ptr) + { + if(opterr) + { + fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c); + } + + optopt = c; + c = '?'; + + /* Move onto the next option */ + increment_index(); + } + /* Option takes argument */ + else if(opt_ptr[1] == ':') + { + /* ie, -oARGUMENT, -xxxoARGUMENT, etc. */ + if(argv[argv_index][opt_offset] != '\0') + { + optarg = &argv[argv_index][opt_offset]; + increment_index(); + } + /* ie, -o ARGUMENT (only if it's a required argument) */ + else if(opt_ptr[2] != ':') + { + /* One of those "you're not expected to understand this" moment */ + if(argv_index2 < argv_index) argv_index2 = argv_index; + while(argv[++argv_index2] && argv[argv_index2][0] == '-'); + optarg = argv[argv_index2]; + + /* Don't cross into the non-option argument list */ + if(argv_index2 + nonopt >= prev_argc) optarg = NULL; + + /* Move onto the next option */ + increment_index(); + } + else + { + /* Move onto the next option */ + increment_index(); + } + + /* In case we got no argument for an option with required argument */ + if(optarg == NULL && opt_ptr[2] != ':') + { + optopt = c; + c = '?'; + + if(opterr) + { + fprintf(stderr,"%s: option requires an argument -- %c\n", + argv[0], optopt); + } + } + } + /* Option does not take argument */ + else + { + /* Next argv_index */ + if(argv[argv_index][opt_offset] == '\0') + { + increment_index(); + } + } + } + + /* Calculate optind */ + if(c == -1) + { + optind = argc - nonopt; + } + else + { + optind = argv_index; + } + + return c; + } + +private: + char** prev_argv; /* Keep a copy of argv and argc to */ + int prev_argc; /* tell if getopt params change */ + int argv_index; /* Option we're checking */ + int argv_index2; /* Option argument we're checking */ + int opt_offset; /* Index into compounded "-option" */ + int dashdash; /* True if "--" option reached */ + int nonopt; /* How many nonopts we've found */ + int argc; + char ** argv; + const char * optstr; + char* optarg; + + void increment_index() + { + /* Move onto the next option */ + if(argv_index < argv_index2) + { + while(prev_argv[++argv_index] && prev_argv[argv_index][0] != '-' + && argv_index < argv_index2+1); + } + else argv_index++; + opt_offset = 1; + } + + /* + * Permutes argv[] so that the argument currently being processed is moved + * to the end. + */ + int permute_argv_once() + { + /* Movability check */ + if(argv_index + nonopt >= prev_argc) return 1; + /* Move the current option to the end, bring the others to front */ + else + { + char* tmp = prev_argv[argv_index]; + + /* Move the data */ + memmove(&prev_argv[argv_index], &prev_argv[argv_index+1], + sizeof(char**) * (prev_argc - argv_index - 1)); + prev_argv[prev_argc - 1] = tmp; + + nonopt++; + return 0; + } + } +}; diff --git a/library/include/dfhack/modules/Vegetation.h b/library/include/dfhack/modules/Vegetation.h index 77285bde4..128294e52 100644 --- a/library/include/dfhack/modules/Vegetation.h +++ b/library/include/dfhack/modules/Vegetation.h @@ -16,13 +16,19 @@ namespace DFHack */ struct t_tree { - /** - 0: sapling?, dead sapling?, grown maple tree - 1: willow sapling? - 2: shrub - 3: shrub near water! - */ - uint16_t type; // +0x6C + // +0x6C + #pragma pack(push, 1) + union + { + uint16_t type; + struct + { + unsigned int watery : 1; + unsigned int is_shrub : 1; + unsigned int unknown : 14; + }; + }; + #pragma pack(pop) uint16_t material; // +0x6E uint16_t x; // +0x70 uint16_t y; // +0x72 diff --git a/tools/supported/prospector.cpp b/tools/supported/prospector.cpp index e2ad5833e..9b0f06ca6 100644 --- a/tools/supported/prospector.cpp +++ b/tools/supported/prospector.cpp @@ -7,14 +7,18 @@ #include #include +#include #include +#include #include using namespace std; #include #include +#include typedef std::map MatMap; +typedef std::vector< pair > MatSorter; typedef std::vector FeatureList; typedef std::vector FeatureListPointer; @@ -26,8 +30,9 @@ bool parseOptions(int argc, char **argv, bool &showHidden, bool &showPlants, { char c; opterr = 0; - - while ((c = getopt(argc, argv, "apst")) != -1) + + xgetopt opt(argc, argv, "apsr"); + while ((c = opt()) != -1) { switch (c) { @@ -62,15 +67,33 @@ bool parseOptions(int argc, char **argv, bool &showHidden, bool &showPlants, } } +template