diff options
author | Steve Bennett <steveb@workware.net.au> | 2010-01-24 10:53:36 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2010-10-15 11:02:39 +1000 |
commit | 6ef810ae664dccd457fe1ed750f7d509b6f60878 (patch) | |
tree | 13f3ab69416d1fc7f5d10db06c1bf83aa0153e4f /jim-regexp.c | |
parent | a0017cc44c22a83df8f92600317ad8ccd635e2a1 (diff) | |
download | jimtcl-6ef810ae664dccd457fe1ed750f7d509b6f60878.zip jimtcl-6ef810ae664dccd457fe1ed750f7d509b6f60878.tar.gz jimtcl-6ef810ae664dccd457fe1ed750f7d509b6f60878.tar.bz2 |
Bugs, features and tests
source fails with zero length file
unknown can't be called recursively
*: This can be useful when using unknown to dynamically load code,
which may in turn want to dynamically load code
*: Limit it to 50 recursions though
Allow string greater/less comparison
*: Comparing two strings for order did not work
Implement file join
*: It's not to hard and is handy when working with the current dir, ""
Don't omit [unknown] completely from stack trace
*: Since we lose valuable informtion, just omit the name
Fix return from case
Turn regexp patterns into real objects
*: Thus caching the compiled regexps
Allow error to rethrow an error
Replace bcopy() with more standard memcpy()
Fixes to parray, improve errorInfo
*: errorInfo takes an optional stack trace
Add tests for rethrowing errors via errorInfo
Fix ndelay
*: Was looking at wrong param
*: Also fix usage/help for aio.socket
Package should be able to call exit
*: Currently any return from a package is changed to JIM_ERR
Line counting is incorrect for backlash newline
Diffstat (limited to 'jim-regexp.c')
-rw-r--r-- | jim-regexp.c | 72 |
1 files changed, 51 insertions, 21 deletions
diff --git a/jim-regexp.c b/jim-regexp.c index 736813d..b8a7585 100644 --- a/jim-regexp.c +++ b/jim-regexp.c @@ -53,25 +53,59 @@ #define JIM_EXTENSION #include "jim.h" -/** - * REVISIT: Should cache a number of compiled regexps for performance reasons. - */ -static regex_t * -compile_regexp(Jim_Interp *interp, const char *pattern, int flags) +void FreeRegexpInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) +{ + regfree(objPtr->internalRep.regexpValue.compre); + Jim_Free(objPtr->internalRep.regexpValue.compre); +} + +static Jim_ObjType regexpObjType = { + "regexp", + FreeRegexpInternalRep, + NULL, + NULL, + JIM_TYPE_NONE +}; + +static regex_t *SetRegexpFromAny(Jim_Interp *interp, Jim_Obj *objPtr, unsigned flags) { + regex_t *compre; + const char *pattern; int ret; - regex_t *result = (regex_t *)Jim_Alloc(sizeof(*result)); + /* Check if the object is already an uptodate variable */ + if (objPtr->typePtr == ®expObjType && + objPtr->internalRep.regexpValue.compre && + objPtr->internalRep.regexpValue.flags == flags) { + /* nothing to do */ + return objPtr->internalRep.regexpValue.compre; + } + + /* Not a regexp or the flags do not match */ + if (objPtr->typePtr == ®expObjType) { + FreeRegexpInternalRep(interp, objPtr); + objPtr->typePtr = NULL; + } - if ((ret = regcomp(result, pattern, REG_EXTENDED | flags)) != 0) { + /* Get the string representation */ + pattern = Jim_GetString(objPtr, NULL); + compre = Jim_Alloc(sizeof(regex_t)); + + if ((ret = regcomp(compre, pattern, REG_EXTENDED | flags)) != 0) { char buf[100]; - regerror(ret, result, buf, sizeof(buf)); + regerror(ret, compre, buf, sizeof(buf)); Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); Jim_AppendStrings(interp, Jim_GetResult(interp), "couldn't compile regular expression pattern: ", buf, NULL); - Jim_Free(result); + regfree(compre); + Jim_Free(compre); return NULL; } - return result; + + objPtr->typePtr = ®expObjType; + objPtr->internalRep.regexpValue.flags = flags; + objPtr->internalRep.regexpValue.compre = compre; + + return compre; } int Jim_RegexpCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) @@ -139,12 +173,12 @@ int Jim_RegexpCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) goto wrongNumArgs; } - pattern = Jim_GetString(argv[i], NULL); - regex = compile_regexp(interp, pattern, regcomp_flags); - if (regex == NULL) { + regex = SetRegexpFromAny(interp, argv[i], regcomp_flags); + if (!regex) { return JIM_ERR; } + pattern = Jim_GetString(argv[i], NULL); source_str = Jim_GetString(argv[i + 1], &source_len); num_vars = argc - i - 2; @@ -271,12 +305,10 @@ int Jim_RegexpCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } Jim_Free(pmatch); - regfree(regex); - Jim_Free(regex); return result; } -#define MAX_SUB_MATCHES 10 +#define MAX_SUB_MATCHES 50 int Jim_RegsubCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { @@ -338,11 +370,11 @@ int Jim_RegsubCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) goto wrongNumArgs; } - pattern = Jim_GetString(argv[i], NULL); - regex = compile_regexp(interp, pattern, regcomp_flags); - if (regex == NULL) { + regex = SetRegexpFromAny(interp, argv[i], regcomp_flags); + if (!regex) { return JIM_ERR; } + pattern = Jim_GetString(argv[i], NULL); source_str = Jim_GetString(argv[i + 1], &source_len); replace_str = Jim_GetString(argv[i + 2], NULL); @@ -459,8 +491,6 @@ int Jim_RegsubCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } done: - regfree(regex); - Jim_Free(regex); return result; } |