oprofile 0.9.6

Copy in the rest of the oprofile 0.9.6 tree so we have a source
copy to match the prebuilt binaries that are checked into
external/.

Change-Id: Iaac327571d5d583594a4194973bf256569061048
diff --git a/libregex/op_regex.h b/libregex/op_regex.h
new file mode 100644
index 0000000..423b980
--- /dev/null
+++ b/libregex/op_regex.h
@@ -0,0 +1,130 @@
+/**
+ * @file op_regex.h
+ * This file contains various definitions and interface for a
+ * lightweight wrapper around libc regex, providing match
+ * and replace facility.
+ *
+ * @remark Copyright 2003 OProfile authors
+ * @remark Read the file COPYING
+ * @remark Idea comes from TextFilt project <http://textfilt.sourceforge.net>
+ *
+ * @author Philippe Elie
+ */
+
+#ifndef OP_REGEX_H
+#define OP_REGEX_H
+
+// required by posix before including regex.h
+#include <sys/types.h>
+#include <regex.h>
+
+#include <string>
+#include <vector>
+#include <map>
+
+#include "op_exception.h"
+
+/**
+ * ill formed regular expression or expression throw such exception
+ */
+struct bad_regex : op_exception {
+	bad_regex(std::string const & pattern);
+};
+
+/**
+ * lightweight encapsulation of regex lib search and replace
+ *
+ * See stl.pat for further details and examples of used syntax.
+ */
+class regular_expression_replace {
+public:
+	/**
+	 * @param limit limit on number of search and replace done
+	 * @param limit_defs_expansion limit on number of expansion done
+	 *  during replacement of regular definition name by their expansion
+	 *
+	 * build an object holding regular defintion and regular expression
+	 * & replace, preparing it for substitution ala sed
+	 */
+	regular_expression_replace(size_t limit = 100,
+				   size_t limit_defs_expansion = 100);
+	~regular_expression_replace();
+
+	/**
+	 * @param name a regular definition name
+	 * @param replace the string to subsitute in other regular definition
+	 * or regular exepression when this regular defintion name is
+	 * encoutered.
+	 */
+	void add_definition(std::string const & name,
+			    std::string const & replace);
+	/**
+	 * @param pattern a regular expression pattern, POSIX extended notation
+	 * @param replace the replace string to use when this regular
+	 *  expression is matched
+	 *
+	 * You can imbed regular definition in pattern but not in replace.
+	 */
+	void add_pattern(std::string const & pattern,
+			 std::string const & replace);
+
+	/**
+	 * @param str the input/output string where we search pattern and
+	 * replace them.
+	 *
+	 * Execute loop at max limit time on the set of regular expression
+	 *
+	 * Return true if too many match occur and replacing has been stopped
+	 * due to reach limit_defs_expansion. You can test if some pattern has
+	 * been matched by saving the input string and comparing it to the new
+	 * value. There is no way to detect s/a/a because the output string
+	 * will be identical to the input string.
+	 */
+	bool execute(std::string & str) const;
+private:
+	struct replace_t {
+		// when this regexp is matched
+		regex_t regexp;
+		// replace the matched part with this string
+		std::string replace;
+	};
+
+	// helper to execute
+	bool do_execute(std::string & str, replace_t const & regexp) const;
+	void do_replace(std::string & str, std::string const & replace,
+			regmatch_t const * match) const;
+
+	// helper to add_definition() and add_pattern()
+	std::string expand_string(std::string const & input);
+
+	// helper to add_pattern
+	std::string substitute_definition(std::string const & pattern);
+
+	// return the match of throw if idx is invalid
+	regmatch_t const & get_match(regmatch_t const * match, char idx) const;
+
+	// don't increase too, it have direct impact on performance. This limit
+	// the number of grouping expression allowed in a regular expression
+	// Note than you can use grouping match operator > 9 only in the
+	// replace rule not in match regular expression since POSIX don't allow
+	// more than \9 in matching sequence.
+	static const size_t max_match = 16;
+
+	size_t limit;
+	size_t limit_defs_expansion;
+	std::vector<replace_t> regex_replace;
+	/// dictionary of regular definition
+	typedef std::map<std::string, std::string> defs_dict;
+	defs_dict defs;
+};
+
+/**
+ * @param regex the regular_expression_replace to fill
+ * @param filename the filename from where the deifnition and pattern are read
+ *
+ * add to regex pattern and regular definition read from the given file
+ */
+void setup_regex(regular_expression_replace& regex,
+		 std::string const & filename);
+
+#endif /* !OP_REGEX_H */