diff options
| author | Petr Mrázek | 2011-05-02 05:03:48 +0200 |
|---|---|---|
| committer | Petr Mrázek | 2011-05-02 05:03:48 +0200 |
| commit | 7ad83c80b8512bed383fe27c60e5dffd1255ae8b (patch) | |
| tree | 442ad940c6dc502db0185600096051f19910b440 | |
| parent | a8fb188c094e7cf90973839f7f38efaa8d6a57fd (diff) | |
| download | dfhack-7ad83c80b8512bed383fe27c60e5dffd1255ae8b.tar.gz dfhack-7ad83c80b8512bed383fe27c60e5dffd1255ae8b.tar.bz2 dfhack-7ad83c80b8512bed383fe27c60e5dffd1255ae8b.tar.xz | |
added modified getopt (c++-ized) with BSD license, vegetation flags clarified, prospector lists trees and plants separately,
prospector pretty-prints
| -rw-r--r-- | CMakeLists.txt | 1 | ||||
| -rw-r--r-- | LICENSE | 35 | ||||
| -rw-r--r-- | library/depends/xgetopt/xgetopt.h | 249 | ||||
| -rw-r--r-- | library/include/dfhack/modules/Vegetation.h | 20 | ||||
| -rw-r--r-- | tools/supported/prospector.cpp | 39 |
5 files changed, 331 insertions, 13 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ac924f4..29e68e48 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 @@ -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 00000000..f7aed598 --- /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 <stdio.h> +#include <stdlib.h> +#include <string.h> + +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 77285bde..128294e5 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 e2ad5833..9b0f06ca 100644 --- a/tools/supported/prospector.cpp +++ b/tools/supported/prospector.cpp @@ -7,14 +7,18 @@ #include <cstdlib> #include <iostream> +#include <iomanip> #include <map> +#include <algorithm> #include <vector> using namespace std; #include <DFHack.h> #include <dfhack/extra/MapExtras.h> +#include <xgetopt.h> typedef std::map<int16_t, unsigned int> MatMap; +typedef std::vector< pair<int16_t, unsigned int> > MatSorter; typedef std::vector<DFHack::t_feature> FeatureList; typedef std::vector<DFHack::t_feature*> 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<template <typename> class P = std::greater > +struct compare_pair_second +{ + template<class T1, class T2> + bool operator()(const std::pair<T1, T2>& left, const std::pair<T1, T2>& right) + { + return P<T2>()(left.second, right.second); + } +}; + + void printMats(MatMap &mat, std::vector<DFHack::t_matgloss> &materials) { unsigned int total = 0; + MatSorter sorting_vector; for (MatMap::const_iterator it = mat.begin(); it != mat.end(); ++it) { + sorting_vector.push_back(*it); + } + std::sort(sorting_vector.begin(), sorting_vector.end(), compare_pair_second<>()); + for (MatSorter::const_iterator it = sorting_vector.begin(); it != sorting_vector.end(); ++it) + { DFHack::t_matgloss mat = materials[it->first]; - std::cout << mat.id << " : " << it->second << std::endl; + std::cout << std::setw(25) << mat.id << " : " << it->second << std::endl; total += it->second; } + std::cout << ">>> TOTAL = " << total << std::endl << std::endl; } @@ -140,6 +163,7 @@ int main(int argc, char *argv[]) MatMap layerMats; MatMap veinMats; MatMap plantMats; + MatMap treeMats; if (!(showSlade && maps->ReadGlobalFeatures(globalFeatures))) { @@ -297,7 +321,10 @@ int main(int argc, char *argv[]) loc = loc % 16; if (showHidden || !b->DesignationAt(loc).bits.hidden) { - plantMats[it->material]++; + if(plant.is_shrub) + plantMats[it->material]++; + else + treeMats[it->material]++; } } } @@ -326,8 +353,10 @@ int main(int argc, char *argv[]) if (showPlants) { - std::cout << "Plant materials:" << std::endl; + std::cout << "Shrubs:" << std::endl; printMats(plantMats, mats->organic); + std::cout << "Wood in trees:" << std::endl; + printMats(treeMats, mats->organic); } if (hasAquifer) |
