summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-06-24 09:20:43 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-06-24 09:20:43 +0000
commitc1d6a946fbdb5eff8571675cece333e87a9b9d07 (patch)
treeaf2e8a0a84bea0afb8c8c24ace6764091e9aa7f0 /crawl-ref/source
parentbc8d3fba7bf6518a07bcb2e5b1843bedd41ccf41 (diff)
downloadcrawl-ref-c1d6a946fbdb5eff8571675cece333e87a9b9d07.tar.gz
crawl-ref-c1d6a946fbdb5eff8571675cece333e87a9b9d07.zip
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
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/direct.cc2
-rw-r--r--crawl-ref/source/direct.h2
-rw-r--r--crawl-ref/source/initfile.cc3
-rw-r--r--crawl-ref/source/libutil.cc62
-rw-r--r--crawl-ref/source/libutil.h42
-rw-r--r--crawl-ref/source/mapdef.cc6
6 files changed, 76 insertions, 41 deletions
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<dungeon_feature_type> features_by_desc(const text_pattern &pattern)
+std::vector<dungeon_feature_type> features_by_desc(const base_pattern &pattern)
{
std::vector<dungeon_feature_type> 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<dungeon_feature_type> features_by_desc(const text_pattern &pattern);
+std::vector<dungeon_feature_type> 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<dungeon_feature_type> feats = features_by_desc(fname);
+ std::vector<dungeon_feature_type> 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<glob_info *>( compiled_pattern );
+}
+
+bool glob_pattern_match(void *compiled_pattern, const char *text, int length)
+{
+ glob_info *gi = static_cast<glob_info *>( 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<glob_info *>( compiled_pattern );
+ free_compiled_glob_pattern(cp);
}
bool pattern_match(void *compiled_pattern, const char *text, int length)
{
- glob_info *gi = static_cast<glob_info *>( 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 <p_compile pcomp, p_free pfree, p_match pmatch>
+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<compile_pattern,
+ free_compiled_pattern, pattern_match> text_pattern;
+
+typedef
+basic_text_pattern<compile_glob_pattern,
+ free_compiled_glob_pattern,
+ glob_pattern_match> 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<dungeon_feature_type> 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\"",