Replaced fnmatch() with patmatch()
authorClifford Wolf <clifford@clifford.at>
Fri, 10 Oct 2014 16:02:17 +0000 (18:02 +0200)
committerClifford Wolf <clifford@clifford.at>
Fri, 10 Oct 2014 16:02:17 +0000 (18:02 +0200)
kernel/patmatch.h [new file with mode: 0644]
passes/cmds/cover.cc
passes/cmds/select.cc
passes/hierarchy/hierarchy.cc

diff --git a/kernel/patmatch.h b/kernel/patmatch.h
new file mode 100644 (file)
index 0000000..611c8d8
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ *  yosys -- Yosys Open SYnthesis Suite
+ *
+ *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
+ *  
+ *  Permission to use, copy, modify, and/or distribute this software for any
+ *  purpose with or without fee is hereby granted, provided that the above
+ *  copyright notice and this permission notice appear in all copies.
+ *  
+ *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#ifndef PATMATCH_H
+#define PATMATCH_H
+
+#include "kernel/yosys.h"
+
+YOSYS_NAMESPACE_BEGIN
+
+// this is very similar to fnmatch(). the exact rules used by this
+// function are:
+//
+//    ?        matches any character except
+//    *        matches any sequence of characters
+//    [...]    matches any of the characters in the list
+//    [!..]    matches any of the characters not in the list
+//
+// a backslash may be used to escape the next characters in the
+// pattern. each special character can also simply match itself.
+//
+static bool patmatch(const char *pattern, const char *string)
+{
+       if (*pattern == 0)
+               return *string == 0;
+
+       if (*pattern == '\\') {
+               if (pattern[1] == string[0] && patmatch(pattern+2, string+1))
+                       return true;
+       }
+
+       if (*pattern == '?') {
+               if (*string == 0)
+                       return false;
+               return patmatch(pattern+1, string+1);
+       }
+
+       if (*pattern == '*') {
+               while (*string) {
+                       if (patmatch(pattern+1, string++))
+                               return true;
+               }
+               return pattern[1] == 0;
+       }
+
+       if (*pattern == '[') {
+               bool found_match = false;
+               bool inverted_list = pattern[1] == '!';
+               const char *p = pattern + (inverted_list ? 1 : 0);
+
+               while (*++p) {
+                       if (*p == ']') {
+                               if (found_match != inverted_list && patmatch(p+1, string+1))
+                                       return true;
+                               break;
+                       }
+
+                       if (*p == '\\') {
+                               if (*++p == *string)
+                                       found_match = true;
+                       } else
+                       if (*p == *string)
+                               found_match = true;
+               }
+       }
+
+       if (*pattern == *string)
+               return patmatch(pattern+1, string+1);
+
+       return false;
+}
+
+YOSYS_NAMESPACE_END
+
+#endif
index 057f3121741bdc5c2b249e5da7785cf13538af6b..64f7acf50fd2d54bb9a4697495282bb2dec6b7d4 100644 (file)
 
 #include <sys/types.h>
 #include <unistd.h>
-#include <fnmatch.h>
 
-#include "kernel/register.h"
-#include "kernel/rtlil.h"
-#include "kernel/log.h"
+#include "kernel/yosys.h"
+#include "kernel/patmatch.h"
 
 USING_YOSYS_NAMESPACE
 PRIVATE_NAMESPACE_BEGIN
@@ -123,7 +121,7 @@ struct CoverPass : public Pass {
                for (auto &it : get_coverage_data()) {
                        if (!patterns.empty()) {
                                for (auto &p : patterns)
-                                       if (!fnmatch(p.c_str(), it.first.c_str(), 0))
+                                       if (patmatch(p.c_str(), it.first.c_str()))
                                                goto pattern_match;
                                continue;
                        }
index 363687f25ef1e7a3c76a0f9a5df51e540046598f..893f897d20804834e0b09c7e5be2f3e27201fe58 100644 (file)
  *
  */
 
-#include "kernel/register.h"
+#include "kernel/yosys.h"
 #include "kernel/celltypes.h"
 #include "kernel/sigtools.h"
-#include "kernel/log.h"
+#include "kernel/patmatch.h"
 #include <string.h>
-#include <fnmatch.h>
 #include <errno.h>
 
 USING_YOSYS_NAMESPACE
@@ -38,9 +37,9 @@ static bool match_ids(RTLIL::IdString id, std::string pattern)
                return true;
        if (id.size() > 0 && id[0] == '\\' && id.substr(1) == pattern)
                return true;
-       if (!fnmatch(pattern.c_str(), id.c_str(), 0))
+       if (patmatch(pattern.c_str(), id.c_str()))
                return true;
-       if (id.size() > 0 && id[0] == '\\' && !fnmatch(pattern.c_str(), id.substr(1).c_str(), 0))
+       if (id.size() > 0 && id[0] == '\\' && patmatch(pattern.c_str(), id.substr(1).c_str()))
                return true;
        if (id.size() > 0 && id[0] == '$' && pattern.size() > 0 && pattern[0] == '$') {
                const char *p = id.c_str();
@@ -83,7 +82,7 @@ static bool match_attr_val(const RTLIL::Const &value, std::string pattern, char
                std::string value_str = value.decode_string();
 
                if (match_op == '=')
-                       if (!fnmatch(pattern.c_str(), value.decode_string().c_str(), FNM_NOESCAPE))
+                       if (patmatch(pattern.c_str(), value.decode_string().c_str()))
                                return true;
 
                if (match_op == '=')
@@ -107,9 +106,9 @@ static bool match_attr(const std::map<RTLIL::IdString, RTLIL::Const> &attributes
 {
        if (name_pat.find('*') != std::string::npos || name_pat.find('?') != std::string::npos || name_pat.find('[') != std::string::npos) {
                for (auto &it : attributes) {
-                       if (!fnmatch(name_pat.c_str(), it.first.c_str(), FNM_NOESCAPE) && match_attr_val(it.second, value_pat, match_op))
+                       if (patmatch(name_pat.c_str(), it.first.c_str()) && match_attr_val(it.second, value_pat, match_op))
                                return true;
-                       if (it.first.size() > 0 && it.first[0] == '\\' && !fnmatch(name_pat.c_str(), it.first.substr(1).c_str(), FNM_NOESCAPE) && match_attr_val(it.second, value_pat, match_op))
+                       if (it.first.size() > 0 && it.first[0] == '\\' && patmatch(name_pat.c_str(), it.first.substr(1).c_str()) && match_attr_val(it.second, value_pat, match_op))
                                return true;
                }
        } else {
index 960fc19292767f97770b74dcba0229e414125199..68317a60a507199a28428a00f012f7de9bc252d5 100644 (file)
  *
  */
 
-#include "kernel/register.h"
-#include "kernel/log.h"
+#include "kernel/yosys.h"
+#include "kernel/patmatch.h"
 #include <stdlib.h>
 #include <stdio.h>
-#include <fnmatch.h>
 #include <set>
 #include <unistd.h>
 
@@ -47,7 +46,7 @@ void generate(RTLIL::Design *design, const std::vector<std::string> &celltypes,
                if (cell->type.substr(0, 1) == "$" && cell->type.substr(0, 3) != "$__")
                        continue;
                for (auto &pattern : celltypes)
-                       if (!fnmatch(pattern.c_str(), RTLIL::unescape_id(cell->type).c_str(), FNM_NOESCAPE))
+                       if (patmatch(pattern.c_str(), RTLIL::unescape_id(cell->type).c_str()))
                                found_celltypes.insert(cell->type);
        }
 
@@ -97,7 +96,7 @@ void generate(RTLIL::Design *design, const std::vector<std::string> &celltypes,
                while (portnames.size() > 0) {
                        RTLIL::IdString portname = *portnames.begin();
                        for (auto &decl : portdecls)
-                               if (decl.index == 0 && !fnmatch(decl.portname.c_str(), RTLIL::unescape_id(portname).c_str(), FNM_NOESCAPE)) {
+                               if (decl.index == 0 && patmatch(decl.portname.c_str(), RTLIL::unescape_id(portname).c_str())) {
                                        generate_port_decl_t d = decl;
                                        d.portname = portname;
                                        d.index = *indices.begin();