From c1d6a946fbdb5eff8571675cece333e87a9b9d07 Mon Sep 17 00:00:00 2001 From: dshaligram Date: Sun, 24 Jun 2007 09:20:43 +0000 Subject: Allow glob patterns in KFEAT lines. For instance: KFEAT: A = gate * Abyss git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1633 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/direct.cc | 2 +- crawl-ref/source/direct.h | 2 +- crawl-ref/source/initfile.cc | 3 ++- crawl-ref/source/libutil.cc | 62 ++++++++++++++++++++++++++++---------------- crawl-ref/source/libutil.h | 42 +++++++++++++++++++++--------- crawl-ref/source/mapdef.cc | 6 ++--- 6 files changed, 76 insertions(+), 41 deletions(-) (limited to 'crawl-ref') diff --git a/crawl-ref/source/direct.cc b/crawl-ref/source/direct.cc index e6da1565ff..56b2a41963 100644 --- a/crawl-ref/source/direct.cc +++ b/crawl-ref/source/direct.cc @@ -1199,7 +1199,7 @@ static void describe_feature(int mx, int my, bool oos) } // Returns a vector of features matching the given pattern. -std::vector features_by_desc(const text_pattern &pattern) +std::vector features_by_desc(const base_pattern &pattern) { std::vector features; diff --git a/crawl-ref/source/direct.h b/crawl-ref/source/direct.h index 54b7a4821d..7b14bb3e00 100644 --- a/crawl-ref/source/direct.h +++ b/crawl-ref/source/direct.h @@ -43,7 +43,7 @@ std::string feature_description(int mx, int my); std::string feature_description(dungeon_feature_type grid, trap_type tr = NUM_TRAPS); -std::vector features_by_desc(const text_pattern &pattern); +std::vector features_by_desc(const base_pattern &pattern); inline int view2gridX(int vx) { diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc index 78636690a8..142048120e 100644 --- a/crawl-ref/source/initfile.cc +++ b/crawl-ref/source/initfile.cc @@ -855,7 +855,8 @@ void game_options::add_feature_override(const std::string &text) iprops.resize(5); trim_string(fname); - std::vector feats = features_by_desc(fname); + std::vector feats = + features_by_desc(text_pattern(fname)); if (feats.empty()) return; diff --git a/crawl-ref/source/libutil.cc b/crawl-ref/source/libutil.cc index 98dd7f598f..042615ee64 100644 --- a/crawl-ref/source/libutil.cc +++ b/crawl-ref/source/libutil.cc @@ -381,6 +381,40 @@ static bool glob_match( const char *pattern, const char *text, bool icase ) } } +//////////////////////////////////////////////////////////////////// +// Basic glob (always available) + +struct glob_info +{ + std::string s; + bool ignore_case; +}; + +void *compile_glob_pattern(const char *pattern, bool icase) +{ + // If we're using simple globs, we need to box the pattern with '*' + std::string s = std::string("*") + pattern + "*"; + glob_info *gi = new glob_info; + if (gi) + { + gi->s = s; + gi->ignore_case = icase; + } + return gi; +} + +void free_compiled_glob_pattern(void *compiled_pattern) +{ + delete static_cast( compiled_pattern ); +} + +bool glob_pattern_match(void *compiled_pattern, const char *text, int length) +{ + glob_info *gi = static_cast( compiled_pattern ); + return glob_match(gi->s.c_str(), text, gi->ignore_case); +} +//////////////////////////////////////////////////////////////////// + #if defined(REGEX_PCRE) //////////////////////////////////////////////////////////////////// // Perl Compatible Regular Expressions @@ -459,38 +493,20 @@ bool pattern_match(void *compiled_pattern, const char *text, int length) //////////////////////////////////////////////////////////////////// #else -//////////////////////////////////////////////////////////////////// -// Basic glob -struct glob_info -{ - std::string s; - bool ignore_case; -}; - -void *compile_pattern(const char *pattern, bool icase) +void *compile_pattern(const char *pattern, bool icase) { - // If we're using simple globs, we need to box the pattern with '*' - std::string s = std::string("*") + pattern + "*"; - glob_info *gi = new glob_info; - if (gi) - { - gi->s = s; - gi->ignore_case = icase; - } - return gi; + return compile_glob_pattern(pattern, icase); } -void free_compiled_pattern(void *compiled_pattern) +void free_compiled_pattern(void *cp) { - delete static_cast( compiled_pattern ); + free_compiled_glob_pattern(cp); } bool pattern_match(void *compiled_pattern, const char *text, int length) { - glob_info *gi = static_cast( compiled_pattern ); - return glob_match(gi->s.c_str(), text, gi->ignore_case); + return glob_pattern_match(compiled_pattern, text, length); } -//////////////////////////////////////////////////////////////////// #endif diff --git a/crawl-ref/source/libutil.h b/crawl-ref/source/libutil.h index b359bfb304..1191ca6312 100644 --- a/crawl-ref/source/libutil.h +++ b/crawl-ref/source/libutil.h @@ -55,6 +55,15 @@ void *compile_pattern(const char *pattern, bool ignore_case = false); void free_compiled_pattern(void *cp); bool pattern_match(void *compiled_pattern, const char *text, int length); +// Globs are always available. +void *compile_glob_pattern(const char *pattern, bool ignore_case = false); +void free_compiled_glob_pattern(void *cp); +bool glob_pattern_match(void *compiled_pattern, const char *text, int length); + +typedef void *(*p_compile)(const char *pattern, bool ignore_case); +typedef void (*p_free)(void *cp); +typedef bool (*p_match)(void *compiled_pattern, const char *text, int length); + std::string & trim_string( std::string &str ); std::string trimmed_string( std::string s ); @@ -133,22 +142,23 @@ public: virtual bool matches(const std::string &s) const = 0; }; -class text_pattern : public base_pattern +template +class basic_text_pattern : public base_pattern { public: - text_pattern(const std::string &s, bool icase = false) + basic_text_pattern(const std::string &s, bool icase = false) : pattern(s), compiled_pattern(NULL), isvalid(true), ignore_case(icase) { } - text_pattern() + basic_text_pattern() : pattern(), compiled_pattern(NULL), isvalid(false), ignore_case(false) { } - text_pattern(const text_pattern &tp) + basic_text_pattern(const basic_text_pattern &tp) : base_pattern(tp), pattern(tp.pattern), compiled_pattern(NULL), @@ -157,19 +167,19 @@ public: { } - ~text_pattern() + ~basic_text_pattern() { if (compiled_pattern) - free_compiled_pattern(compiled_pattern); + pfree(compiled_pattern); } - const text_pattern &operator= (const text_pattern &tp) + const basic_text_pattern &operator= (const basic_text_pattern &tp) { if (this == &tp) return tp; if (compiled_pattern) - free_compiled_pattern(compiled_pattern); + pfree(compiled_pattern); pattern = tp.pattern; compiled_pattern = NULL; isvalid = tp.isvalid; @@ -177,13 +187,13 @@ public: return *this; } - const text_pattern &operator= (const std::string &spattern) + const basic_text_pattern &operator= (const std::string &spattern) { if (pattern == spattern) return *this; if (compiled_pattern) - free_compiled_pattern(compiled_pattern); + pfree(compiled_pattern); pattern = spattern; compiled_pattern = NULL; isvalid = true; @@ -194,7 +204,7 @@ public: bool compile() const { return !empty()? - !!(compiled_pattern = compile_pattern(pattern.c_str(), ignore_case)) + !!(compiled_pattern = pcomp(pattern.c_str(), ignore_case)) : false; } @@ -211,7 +221,7 @@ public: bool matches(const char *s, int length) const { - return valid() && pattern_match(compiled_pattern, s, length); + return valid() && pmatch(compiled_pattern, s, length); } bool matches(const char *s) const @@ -236,5 +246,13 @@ private: bool ignore_case; }; +typedef +basic_text_pattern text_pattern; + +typedef +basic_text_pattern glob_pattern; #endif diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc index 65f7e322f2..5e4cf0c5e2 100644 --- a/crawl-ref/source/mapdef.cc +++ b/crawl-ref/source/mapdef.cc @@ -1931,9 +1931,9 @@ feature_spec_list keyed_mapspec::parse_feature(const std::string &str) } std::vector feats = - features_by_desc( text_pattern(s, true) ); - for (int i = 0, size = feats.size(); i < size; ++i) - list.push_back( feature_spec(feats[i], weight) ); + features_by_desc( glob_pattern(s, true) ); + if (!feats.empty()) + list.push_back( feature_spec(feats[0], weight) ); if (feats.empty()) err = make_stringf("no features matching \"%s\"", -- cgit v1.2.3-54-g00ecf