URL
https://opencores.org/ocsvn/uart2bus_testbench/uart2bus_testbench/trunk
Subversion Repositories uart2bus_testbench
[/] [uart2bus_testbench/] [trunk/] [tb/] [uvm_src/] [dpi/] [uvm_regex.cc] - Rev 16
Compare with Previous | Blame | View Log
//---------------------------------------------------------------------- // Copyright 2007-2011 Mentor Graphics Corporation // Copyright 2011 Cadence Design Systems, Inc. // All Rights Reserved Worldwide // // Licensed under the Apache License, Version 2.0 (the // "License"); you may not use this file except in // compliance with the License. You may obtain a copy of // the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in // writing, software distributed under the License is // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See // the License for the specific language governing // permissions and limitations under the License. //---------------------------------------------------------------------- #include "uvm_dpi.h" #include <sys/types.h> const char uvm_re_bracket_char = '/'; #define UVM_REGEX_MAX_LENGTH 2048 static char uvm_re[UVM_REGEX_MAX_LENGTH+4]; //-------------------------------------------------------------------- // uvm_re_match // // Match a string to a regular expression. The regex is first lookup // up in the regex cache to see if it has already been compiled. If // so, the compile version is retrieved from the cache. Otherwise, it // is compiled and cached for future use. After compilation the // matching is done using regexec(). //-------------------------------------------------------------------- int uvm_re_match(const char * re, const char *str) { regex_t *rexp; int err; // safety check. Args should never be ~null~ since this is called // from DPI. But we'll check anyway. if(re == NULL) return 1; if(str == NULL) return 1; int len = strlen(re); char * rex = &uvm_re[0]; if (len > UVM_REGEX_MAX_LENGTH) { const char* err_str = "uvm_re_match : regular expression greater than max %0d: |%s|"; char buffer[strlen(err_str) + int_str_max(10) + strlen(re)]; sprintf(buffer, err_str, UVM_REGEX_MAX_LENGTH, re); m_uvm_report_dpi(M_UVM_ERROR, (char*) "UVM/DPI/REGEX_MAX", &buffer[0], M_UVM_NONE, (char*)__FILE__, __LINE__); return 1; } // we copy the regexp because we need to remove any brackets around it strncpy(&uvm_re[0],re,UVM_REGEX_MAX_LENGTH); if (len>1 && (re[0] == uvm_re_bracket_char) && re[len-1] == uvm_re_bracket_char) { uvm_re[len-1] = '\0'; rex++; } rexp = (regex_t*)malloc(sizeof(regex_t)); if (rexp == NULL) { m_uvm_report_dpi(M_UVM_ERROR, (char*) "UVM/DPI/REGEX_ALLOC", (char*) "uvm_re_match: internal memory allocation error", M_UVM_NONE, (char*)__FILE__, __LINE__); return 1; } err = regcomp(rexp, rex, REG_EXTENDED); if (err != 0) { regerror(err,rexp,uvm_re,UVM_REGEX_MAX_LENGTH-1); const char * err_str = "uvm_re_match : invalid glob or regular expression: |%s||%s|"; char buffer[strlen(err_str) + strlen(re) + strlen(uvm_re)]; sprintf(buffer, err_str, re, uvm_re); m_uvm_report_dpi(M_UVM_ERROR, (char*) "UVM/DPI/REGEX_INV", &buffer[0], M_UVM_NONE, (char*)__FILE__, __LINE__); regfree(rexp); free(rexp); return err; } err = regexec(rexp, str, 0, NULL, 0); //vpi_printf((PLI_BYTE8*) "UVM_INFO: uvm_re_match: re=%s str=%s ERR=%0d\n",rex,str,err); regfree(rexp); free(rexp); return err; } //-------------------------------------------------------------------- // uvm_glob_to_re // // Convert a glob expression to a normal regular expression. //-------------------------------------------------------------------- const char * uvm_glob_to_re(const char *glob) { const char *p; int len; // safety check. Glob should never be ~null~ since this is called // from DPI. But we'll check anyway. if(glob == NULL) return NULL; len = strlen(glob); if (len > 2040) { const char * err_str = "uvm_re_match : glob expression greater than max 2040: |%s|"; char buffer[strlen(err_str) + strlen(glob)]; sprintf(buffer, err_str, glob); m_uvm_report_dpi(M_UVM_ERROR, (char*) "UVM/DPI/REGEX_MAX", &buffer[0], M_UVM_NONE, (char*)__FILE__, __LINE__); return glob; } // If either of the following cases appear then return an empty string // // 1. The glob string is empty (it has zero characters) // 2. The glob string has a single character that is the // uvm_re_bracket_char (i.e. "/") if(len == 0 || (len == 1 && *glob == uvm_re_bracket_char)) { uvm_re[0] = '\0'; return &uvm_re[0]; // return an empty string } // If bracketed with the /glob/, then it's already a regex if(glob[0] == uvm_re_bracket_char && glob[len-1] == uvm_re_bracket_char) { strcpy(uvm_re,glob); return &uvm_re[0]; } else { // Convert the glob to a true regular expression (Posix syntax) len = 0; uvm_re[len++] = uvm_re_bracket_char; // ^ goes at the beginning... if (*glob != '^') uvm_re[len++] = '^'; for(p = glob; *p; p++) { // Replace the glob metacharacters with corresponding regular // expression metacharacters. switch(*p) { case '*': uvm_re[len++] = '.'; uvm_re[len++] = '*'; break; case '+': uvm_re[len++] = '.'; uvm_re[len++] = '+'; break; case '.': uvm_re[len++] = '\\'; uvm_re[len++] = '.'; break; case '?': uvm_re[len++] = '.'; break; case '[': uvm_re[len++] = '\\'; uvm_re[len++] = '['; break; case ']': uvm_re[len++] = '\\'; uvm_re[len++] = ']'; break; case '(': uvm_re[len++] = '\\'; uvm_re[len++] = '('; break; case ')': uvm_re[len++] = '\\'; uvm_re[len++] = ')'; break; default: uvm_re[len++] = *p; break; } } } // Let's check to see if the regular expression is bounded by ^ at // the beginning and $ at the end. If not, add those characters in // the appropriate position. if (uvm_re[len-1] != '$') uvm_re[len++] = '$'; uvm_re[len++] = uvm_re_bracket_char; uvm_re[len++] = '\0'; return &uvm_re[0]; } //-------------------------------------------------------------------- // uvm_dump_re_cache // // Dumps the set of regular expressions stored in the cache //-------------------------------------------------------------------- void uvm_dump_re_cache() { m_uvm_report_dpi(M_UVM_INFO, (char*) "UVM/DPI/REGEX_MAX", (char*) "uvm_dump_re_cache: cache not implemented", M_UVM_LOW, (char*)__FILE__, __LINE__); }