string-regex.C

Go to the documentation of this file.
00001 /*
00002  * See the dyninst/COPYRIGHT file for copyright information.
00003  * 
00004  * We provide the Paradyn Tools (below described as "Paradyn")
00005  * on an AS IS basis, and do not warrant its validity or performance.
00006  * We reserve the right to update, modify, or discontinue this
00007  * software at any time.  We shall have no obligation to supply such
00008  * updates or modifications or any other form of support to you.
00009  * 
00010  * By your use of Paradyn, you understand and agree that we (or any
00011  * other person or entity with proprietary rights in Paradyn) are
00012  * under no obligation to provide either maintenance services,
00013  * update services, notices of latent defects, or correction of
00014  * defects for Paradyn.
00015  * 
00016  * This library is free software; you can redistribute it and/or
00017  * modify it under the terms of the GNU Lesser General Public
00018  * License as published by the Free Software Foundation; either
00019  * version 2.1 of the License, or (at your option) any later version.
00020  * 
00021  * This library is distributed in the hope that it will be useful,
00022  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00024  * Lesser General Public License for more details.
00025  * 
00026  * You should have received a copy of the GNU Lesser General Public
00027  * License along with this library; if not, write to the Free Software
00028  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00029  */
00030 
00031 
00032 // $Id: String.C,v 1.39 2008/07/01 19:26:47 legendre Exp $
00033 
00034 #include "common/h/headers.h"
00035 #include <assert.h>
00036 #if !defined (os_windows)
00037 #include <sys/types.h>
00038 #include <regex.h>
00039 #endif
00040 
00041 #include <boost/functional/hash.hpp>
00042 
00043 /* This doesn't actually belong here. */
00044 void dedemangle( char * demangled, char * result ) 
00045 {
00046    /* Lifted from Jeffrey Odom.  Code reformatted so
00047       I could figure out how to eliminate compiler warnings.
00048       Adjusted to handle spaces inside templates intelligently.
00049       We cut off everything after the first l-paren, so we don't
00050       need to worry about the space after the parameters but
00051       before the 'const'. */
00052    char * resultBegins = NULL;
00053    char * resultEnds = NULL;
00054    
00055    if ( demangled[0] == '(' &&
00056     strstr( demangled, "::" ) != NULL) 
00057    {
00058      int depth = 0, i = 0;
00059      for (;;)
00060      { 
00061        if (demangled[i] == '\0')
00062      break;
00063        if (demangled[i] == '(')
00064      depth++;
00065        if (demangled[i] == ')') {
00066      depth--;
00067      if (!depth)
00068        break;
00069        }
00070        i++;
00071      }
00072      if (demangled[i] != '\0') {
00073        resultBegins = demangled+i+1;
00074        if (resultBegins[0] == ':' && resultBegins[1] == ':')
00075      resultBegins += 2;
00076        resultEnds = const_cast<char *>(strrchr(resultBegins, ' '));
00077        if (resultEnds)
00078      resultEnds = '\0';
00079      }
00080      demangled = resultBegins;
00081    }
00082    if ( strrchr( demangled, '(' ) != NULL ) 
00083    {
00084       /* Strip off return types, if any.  Be careful not to
00085          pull off [template?/]class/namespace information.
00086 
00087          The only space that matters is the one that's _not_
00088          inside a template, so skip the templates and cut at the
00089          first space.  We can ignore 'operator[<[<]|>[>]]' because
00090          we'll stop before we reach it.
00091 
00092          Caveat: conversion operators (e.g., "operator bool") have
00093          spaces in the function name.  Right now we deal with this
00094          specifically (is the function "operator *"?).  Could be
00095          altered to after the last template but before the last
00096          left parenthesis.  (Instead of next, for "operator ()".)
00097       */
00098 
00099       resultBegins = demangled;
00100       int stack = 0; bool inTemplate = false;
00101       unsigned int offset, start_template_offset=0, stop_template_offset=0;
00102       int lastColon = 0;
00103       for ( offset = 0; offset < strlen( resultBegins ); offset++ ) 
00104       {
00105          if ( resultBegins[offset] == '<' ) 
00106          {
00107             stack++;
00108             inTemplate = true;
00109             if (stack == 1)
00110                start_template_offset = offset;
00111          }
00112          else if ( resultBegins[offset] == '>' ) 
00113          {
00114             stack--;
00115             if ( stack == 0 ) 
00116             { 
00117                inTemplate = false;
00118                stop_template_offset = offset;
00119             }
00120          }
00121          else if ( !inTemplate && resultBegins[offset] == '(' ) 
00122          {
00123             /* We've stumbled on something without a return value. */
00124 
00125             offset = 0;
00126             resultBegins = demangled;
00127             break;
00128          }
00129          else if ( !inTemplate && resultBegins[offset] == ' ' ) 
00130          {
00131             /* FIXME: verify that the space isn't in the function name,
00132                e.g., 'operator bool'.  If the first space we meet _is_
00133                a function name, it doesn't have a(n explicit) return type. */
00134             if ( strstr( &(resultBegins[ lastColon + 1 ]), "operator " ) == resultBegins + lastColon + 1 ) 
00135             {
00136                resultBegins = demangled;
00137                offset = 0;
00138             }
00139             else 
00140             {
00141                resultBegins = &(resultBegins[offset + 1]);
00142                offset++;
00143             }
00144 
00145             break;
00146          }
00147          else if ( !inTemplate && resultBegins[offset] == ':' ) 
00148          {
00149             lastColon = offset;
00150          }
00151       } /* end template elimination loop */
00152 
00153       /* Scan past the function name; the first left parenthesis
00154          not in in a template declaration starts the function arguments. */
00155       stack = 0; inTemplate = false;
00156       for ( ; offset < strlen( resultBegins ); offset++ ) 
00157       {
00158          if ( resultBegins[offset] == '<' ) 
00159          {
00160             stack++;
00161             inTemplate = true;
00162          }
00163          if ( resultBegins[offset] == '>' ) 
00164          {
00165             stack--;
00166             if ( stack == 0 ) { inTemplate = false; }
00167          }
00168          if ( !inTemplate && resultBegins[offset] == '(' ) 
00169          {
00170             resultEnds = const_cast<char *>(&(resultBegins[offset]));
00171             * resultEnds = '\0';
00172             break;
00173          } 
00174       } /* end template elimination loop */
00175    } /* end if a function prototype */
00176    else 
00177    {
00178       /* Assume demangle OK. */
00179       resultBegins = demangled;
00180    }
00181 
00182    strcpy( result, resultBegins );
00183 } /* end dedemangle */
00184 
00185 
00186 // Use POSIX regular expression pattern matching to check if string s matches
00187 // the pattern in this string
00188 bool regexEquiv(const char *str_,  const char *s, bool checkCase ) 
00189 {
00190 // Would this work under NT?  I don't know.
00191 #if !defined(os_windows)
00192     regex_t r;
00193     int err;
00194     bool match = false;
00195     int cflags = REG_NOSUB;
00196     if ( !checkCase )
00197         cflags |= REG_ICASE;
00198 
00199     // Regular expressions must be compiled first, see 'man regexec'
00200     err = regcomp( &r, str_, cflags );
00201 
00202     if ( err == 0 ) 
00203    {
00204         // Now we can check for a match
00205         err = regexec( &r, s, 0, NULL, 0 );
00206         if( err == 0 )
00207             match = true;
00208     }
00209 
00210     // Deal with errors
00211     if ( err != 0 && err != REG_NOMATCH ) 
00212    {
00213         char errbuf[80] = "";
00214         regerror( err, &r, errbuf, 80 );
00215         //cerr << "string_ll::regexEquiv -- " << errbuf << endl;
00216     }
00217 
00218     // Free the pattern buffer
00219     regfree( &r );
00220     return match;
00221 #else
00222     return false;
00223 #endif
00224 }
00225 
00226 bool prefixed_by(std::string &haystack, std::string &prefix)
00227 {
00228    if (!haystack.c_str()) 
00229       return false;
00230 
00231    const char *res = strstr(haystack.c_str(), prefix.c_str());
00232 
00233    if (res == haystack.c_str())
00234       return true;
00235 
00236    return false;
00237 }
00238 
00239 bool prefixed_by(std::string &haystack, const char *prefix)
00240 {
00241    std::string pref_str(prefix);
00242    return prefixed_by(haystack, pref_str);
00243 }
00244 
00245 
00246 bool suffixed_by(std::string &haystack, std::string &suffix)
00247 {
00248    if (!haystack.c_str()) 
00249       return false;
00250 
00251    int lastchar = haystack.length() - 1;
00252 
00253    int j = 0;
00254    for (int i = suffix.length() - 1; i >= 0; i--)
00255    {
00256       if (haystack[lastchar - i] != suffix[j])
00257          return false;
00258       j++;
00259    }
00260 
00261    return true;
00262 }
00263 
00264 bool suffixed_by(std::string &haystack, const char *suffix)
00265 {
00266    std::string suff_str(suffix);
00267    return suffixed_by(haystack, suff_str);
00268 }
00269 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1