Replaced fnmatch() with patmatch()

This commit is contained in:
Clifford Wolf 2014-10-10 18:02:17 +02:00
parent bbd808072b
commit 774933a0d8
4 changed files with 105 additions and 18 deletions

91
kernel/patmatch.h Normal file
View File

@ -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

View File

@ -19,11 +19,9 @@
#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;
}

View File

@ -17,12 +17,11 @@
*
*/
#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 {

View File

@ -17,11 +17,10 @@
*
*/
#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();