1b99bc125d897c0712377c4fb4d23ff9f6cbca9f angie Fri Feb 25 11:43:27 2011 -0800 New src/inc/regexHelper.h module replaces the regex conveniencefunctions that were previously down in hg/lib/hgFindSpecCustom.c. The primary motivation for this is so I can use regex functions in the new src/lib/vcf.c for Feature #2821 (VCF parser), but I hope this will make it easier in general to use regexes in any new code. diff --git src/lib/regexHelper.c src/lib/regexHelper.c new file mode 100644 index 0000000..9b42886 --- /dev/null +++ src/lib/regexHelper.c @@ -0,0 +1,80 @@ +/* regexHelper: easy wrappers on POSIX Extended Regular Expressions (man 7 regex, man 3 regex) */ + +#include "regexHelper.h" +#include "hash.h" + +const regex_t *regexCompile(const char *exp, const char *description, int compileFlags) +/* Compile exp (or die with an informative-as-possible error message). + * Cache pre-compiled regex's internally (so don't free result after use). */ +{ +static struct hash *reHash = NULL; +struct hashEl *hel = NULL; +char key[512]; +safef(key, sizeof(key), "%d.%s", compileFlags, exp); + +if (reHash == NULL) + reHash = newHash(10); +hel = hashLookup(reHash, key); +if (hel != NULL) + return((regex_t *)hel->val); +else + { + regex_t *compiledExp = NULL; + int errNum = 0; + AllocVar(compiledExp); + errNum = regcomp(compiledExp, exp, compileFlags); + if (errNum != 0) + { + char errBuf[512]; + regerror(errNum, compiledExp, errBuf, sizeof(errBuf)); + errAbort("%s \"%s\" got regular expression compilation error %d:\n%s\n", + description, exp, errNum, errBuf); + } + hashAdd(reHash, key, compiledExp); + return(compiledExp); + } +} + +static boolean regexMatchSubstrMaybeCase(const char *string, const char *exp, + regmatch_t substrArr[], size_t substrArrSize, + boolean isCaseInsensitive) +/* Return TRUE if string matches regular expression exp; + * regexec fills in substrArr with substring offsets. */ +{ +int compileFlags = REG_EXTENDED; +if (isCaseInsensitive) + compileFlags |= REG_ICASE; +if (substrArr == NULL) + compileFlags |= REG_NOSUB; +const regex_t *compiledExp = regexCompile(exp, "Regular expression w/substrings", compileFlags); +return(regexec(compiledExp, string, substrArrSize, substrArr, 0) == 0); +} + +boolean regexMatch(const char *string, const char *exp) +/* Return TRUE if string matches regular expression exp (case sensitive). */ +{ +return regexMatchSubstrMaybeCase(string, exp, NULL, 0, FALSE); +} + +boolean regexMatchNoCase(const char *string, const char *exp) +/* Return TRUE if string matches regular expression exp (case insensitive). */ +{ +return regexMatchSubstrMaybeCase(string, exp, NULL, 0, TRUE); +} + +boolean regexMatchSubstr(const char *string, const char *exp, + regmatch_t substrArr[], size_t substrArrSize) +/* Return TRUE if string matches regular expression exp (case sensitive); + * regexec fills in substrArr with substring offsets. */ +{ +return regexMatchSubstrMaybeCase(string, exp, substrArr, substrArrSize, FALSE); +} + +boolean regexMatchSubstrNoCase(const char *string, const char *exp, + regmatch_t substrArr[], size_t substrArrSize) +/* Return TRUE if string matches regular expression exp (case insensitive); + * regexec fills in substrArr with substring offsets. */ +{ +return regexMatchSubstrMaybeCase(string, exp, substrArr, substrArrSize, TRUE); +} +