1 /*
2     myregex.* - regex() wrapper class
3     Copyright (C) 1999-2000,2002-2004  Matthew Mueller <donut AT dakotacom.net>
4 
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 #ifndef _MYREGEX_H_
20 #define _MYREGEX_H_
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #include <sys/types.h>
26 
27 #ifdef HAVE_PKG_pcre
28 #include <pcreposix.h>
29 #else
30 #include <regex.h>
31 #endif
32 
33 #ifndef REG_EXTENDED
34 #define REG_EXTENDED (0)
35 #endif
36 #ifndef REG_NOSUB
37 #define REG_NOSUB (0)
38 #endif
39 
40 #include <assert.h>
41 //#include "mystring.h"
42 #include <string>
43 #include <stdio.h>
44 
45 #include "log.h"
46 DEFINE_EX_SUBCLASS(RegexEx, ApplicationExFatal, true);
47 
48 const string& regex_match_word_beginning(void);//may contain grouping
49 const string& regex_match_word_beginning_safe(void);//won't contain any grouping
50 const string& regex_match_word_end(void);//may contain grouping
51 void regex_escape_string(const string &s, string &buf);
52 
53 //  use strerror for a textual description of problem.  same as regerror(), but without the first arg(s).
54 
55 //throws a RegexEx if there is an error during the constructor
56 class c_regex_base{
57 	protected:
58 //icky, but pcreposix doesn't have regexec's args as const.  Blah.
59 #ifdef HAVE_PKG_pcre
60 		mutable
61 #endif
62 			regex_t regex;
63 	public:
64 		c_regex_base(const char * pattern,int cflags);
65 		~c_regex_base();
strerror(int re_err,char * buf,size_t bufsize)66 		size_t strerror(int re_err,char *buf,size_t bufsize){return regerror(re_err,&regex,buf,bufsize);}
67 };
68 
69 //thread safe
70 class c_regex_nosub : public c_regex_base{
71   public:
match(const char * str)72 	int match(const char *str)const{return regexec(&regex,str,0,NULL,0);}
match(const string & str)73 	int match(const string &str)const{return regexec(&regex,str.c_str(),0,NULL,0);}
74 	c_regex_nosub(const char * pattern,int cflags=REG_EXTENDED);
75 //	~c_regex_nosub();
76 };
77 inline bool operator == (const string &a,const c_regex_nosub &r){return r.match(a)==0;}
78 inline bool operator == (const string &a,const c_regex_nosub *r){return r->match(a)==0;}
79 inline bool operator != (const string &a,const c_regex_nosub &r){return r.match(a)!=0;}
80 inline bool operator != (const string &a,const c_regex_nosub *r){return r->match(a)!=0;}
81 inline bool operator == (const char *a,const c_regex_nosub &r){return r.match(a)==0;}
82 
83 //thread safe version
84 class c_regex_subs {
85 	private:
86 		regmatch_t *regmatch;
87 		int rnsub;
88 		//string **rsub;
89 		string *rsub;
90 		int nregmatch;
91 	public:
92 		void setnregmatch(int num);
93 		int doregex(regex_t *regex,const char *str);
94 		int re_err;
95 		void freesub(void);
nsub(void)96 		int nsub(void) const {return rnsub;}
97 		const string &operator [](int i) const {return rsub[i];}
sub(int i)98 		const string &sub(int i) const {return rsub[i];}
subs(int i)99 		const char * subs(int i) const {return rsub[i].c_str();}
sublen(int i)100 		const int sublen(int i) const {return regmatch[i].rm_eo-regmatch[i].rm_so;}
subeo(int i)101 		const int subeo(int i) const {return regmatch[i].rm_eo;}
102 		c_regex_subs(int nregmatch=0);
103 		~c_regex_subs();
104 };
105 class c_regex_r : public c_regex_base{
106 	protected:
107 		int nregmatch;
108 	public:
109 		int match(const char *str,c_regex_subs* subs);
match(const string & str,c_regex_subs * subs)110 		int match(const string &str,c_regex_subs* subs) {return match(str.c_str(), subs);}
111 		c_regex_subs* match(const char *str);
match(const string & str)112 		c_regex_subs* match(const string &str) {return match(str.c_str());}
113 		c_regex_r(const char * pattern,int cflags=REG_EXTENDED);
114 	//	~c_regex_r();
115 };
116 
117 //non thread safe (obviously, if two threads did a match at the same time, your subs would be screwed)
118 class c_regex : protected c_regex_r, public c_regex_subs{
119 	public:
match(const char * str)120 		int match(const char *str){return c_regex_r::match(str,this);}
match(const string & str)121 		int match(const string &str){return c_regex_r::match(str,this);}
c_regex_r(pattern,cflags)122 		c_regex(const char * pattern,int cflags=REG_EXTENDED):c_regex_r(pattern,cflags){setnregmatch(c_regex_r::nregmatch);}
123 //		~c_regex();
124 };
125 inline bool operator == (const string &a,c_regex &r){return !r.match(a.c_str());}
126 inline bool operator == (const string &a,c_regex *r){return !r->match(a.c_str());}
127 inline bool operator != (const string &a,c_regex *r){return r->match(a.c_str());}
128 inline bool operator == (const char *a,c_regex &r){return !r.match(a);}
129 
130 #endif
131