00001 /** 00002 * @file op_regex.h 00003 * This file contains various definitions and interface for a 00004 * lightweight wrapper around libc regex, providing match 00005 * and replace facility. 00006 * 00007 * @remark Copyright 2003 OProfile authors 00008 * @remark Read the file COPYING 00009 * @remark Idea comes from TextFilt project <http://textfilt.sourceforge.net> 00010 * 00011 * @author Philippe Elie 00012 */ 00013 00014 #ifndef OP_REGEX_H 00015 #define OP_REGEX_H 00016 00017 // required by posix before including regex.h 00018 #include <sys/types.h> 00019 #include <regex.h> 00020 00021 #include <string> 00022 #include <vector> 00023 #include <map> 00024 00025 #include "op_exception.h" 00026 00027 /** 00028 * ill formed regular expression or expression throw such exception 00029 */ 00030 struct bad_regex : op_exception { 00031 bad_regex(std::string const & pattern); 00032 }; 00033 00034 /** 00035 * lightweight encapsulation of regex lib search and replace 00036 * 00037 * See stl.pat for further details and examples of used syntax. 00038 */ 00039 class regular_expression_replace { 00040 public: 00041 /** 00042 * @param limit limit on number of search and replace done 00043 * @param limit_defs_expansion limit on number of expansion done 00044 * during replacement of regular definition name by their expansion 00045 * 00046 * build an object holding regular defintion and regular expression 00047 * & replace, preparing it for substitution ala sed 00048 */ 00049 regular_expression_replace(size_t limit = 100, 00050 size_t limit_defs_expansion = 100); 00051 ~regular_expression_replace(); 00052 00053 /** 00054 * @param name a regular definition name 00055 * @param replace the string to subsitute in other regular definition 00056 * or regular exepression when this regular defintion name is 00057 * encoutered. 00058 */ 00059 void add_definition(std::string const & name, 00060 std::string const & replace); 00061 /** 00062 * @param pattern a regular expression pattern, POSIX extended notation 00063 * @param replace the replace string to use when this regular 00064 * expression is matched 00065 * 00066 * You can imbed regular definition in pattern but not in replace. 00067 */ 00068 void add_pattern(std::string const & pattern, 00069 std::string const & replace); 00070 00071 /** 00072 * @param str the input/output string where we search pattern and 00073 * replace them. 00074 * 00075 * Execute loop at max limit time on the set of regular expression 00076 * 00077 * Return true if too many match occur and replacing has been stopped 00078 * due to reach limit_defs_expansion. You can test if some pattern has 00079 * been matched by saving the input string and comparing it to the new 00080 * value. There is no way to detect s/a/a because the output string 00081 * will be identical to the input string. 00082 */ 00083 bool execute(std::string & str) const; 00084 private: 00085 struct replace_t { 00086 // when this regexp is matched 00087 regex_t regexp; 00088 // replace the matched part with this string 00089 std::string replace; 00090 }; 00091 00092 // helper to execute 00093 bool do_execute(std::string & str, replace_t const & regexp) const; 00094 void do_replace(std::string & str, std::string const & replace, 00095 regmatch_t const * match) const; 00096 00097 // helper to add_definition() and add_pattern() 00098 std::string expand_string(std::string const & input); 00099 00100 // helper to add_pattern 00101 std::string substitute_definition(std::string const & pattern); 00102 00103 // return the match of throw if idx is invalid 00104 regmatch_t const & get_match(regmatch_t const * match, char idx) const; 00105 00106 // don't increase too, it have direct impact on performance. This limit 00107 // the number of grouping expression allowed in a regular expression 00108 // Note than you can use grouping match operator > 9 only in the 00109 // replace rule not in match regular expression since POSIX don't allow 00110 // more than \9 in matching sequence. 00111 static const size_t max_match = 16; 00112 00113 size_t limit; 00114 size_t limit_defs_expansion; 00115 std::vector<replace_t> regex_replace; 00116 /// dictionary of regular definition 00117 typedef std::map<std::string, std::string> defs_dict; 00118 defs_dict defs; 00119 }; 00120 00121 /** 00122 * @param regex the regular_expression_replace to fill 00123 * @param filename the filename from where the deifnition and pattern are read 00124 * 00125 * add to regex pattern and regular definition read from the given file 00126 */ 00127 void setup_regex(regular_expression_replace& regex, 00128 std::string const & filename); 00129 00130 #endif /* !OP_REGEX_H */
1.6.1