/** Internal prototypes **/
-char *_OS_Regex(char *pattern, char *str, char **prts_closure,
- char **prts_str, int flags);
+static const char *_OS_Regex(const char *pattern, const char *str, const char **prts_closure,
+ const char **prts_str, int flags) __attribute__((nonnull(1,2)));
* Returns the end of the string on success or NULL on error.
* The error code is set on reg->error.
*/
-char *OSRegex_Execute(char *str, OSRegex *reg)
+const char *OSRegex_Execute(const char *str, OSRegex *reg)
{
- char *ret;
+ const char *ret;
int i = 0;
-
+
/* The string can't be NULL */
if(str == NULL)
{
/* If we need the sub strings */
if(reg->prts_closure)
{
- int j = 0, k = 0, str_char = 0;
+ int k = 0;
/* Looping on all sub patterns */
while(reg->patterns[i])
{
/* Cleaning the prts_str */
+ int j = 0;
while(reg->prts_closure[i][j])
{
reg->prts_str[i][j] = NULL;
/* We must always have the open and the close */
while(reg->prts_str[i][j] && reg->prts_str[i][j+1])
{
- str_char = reg->prts_str[i][j+1][0];
-
- reg->prts_str[i][j+1][0] = '\0';
-
- reg->sub_strings[k] = strdup(reg->prts_str[i][j]);
+ size_t length = (size_t) (reg->prts_str[i][j+1] - reg->prts_str[i][j]);
+ reg->sub_strings[k] = (char *) malloc((length + 1) * sizeof(char));
if(!reg->sub_strings[k])
{
OSRegex_FreeSubStrings(reg);
return(NULL);
}
-
+ strncpy(reg->sub_strings[k], reg->prts_str[i][j], length);
+ reg->sub_strings[k][length] = '\0';
+
/* Set the next one to null */
- reg->prts_str[i][j+1][0] = str_char;
k++;
reg->sub_strings[k] = NULL;
return(0);
}
-
+
/* If we don't need the sub strings */
-
+
/* Looping on all sub patterns */
while(reg->patterns[i])
{
- if((ret = _OS_Regex(reg->patterns[i], str, NULL, NULL, reg->flags[i])))
+ if((ret = _OS_Regex(reg->patterns[i], str, NULL, NULL, reg->flags[i])))
{
return(ret);
}
}
return(NULL);
-}
+}
#define PRTS(x) ((prts(*x) && x++) || 1)
#define ENDOFFILE(x) ( PRTS(x) && (*x == '\0'))
* Returns 1 on success and 0 on failure.
* If prts_closure is set, the parenthesis locations will be
* written on prts_str (which must not be NULL)
- */
-char *_OS_Regex(char *pattern, char *str, char **prts_closure,
- char **prts_str, int flags)
+ */
+static const char *_OS_Regex(const char *pattern, const char *str, const char **prts_closure,
+ const char **prts_str, int flags)
{
- char *r_code = NULL;
-
+ const char *r_code = NULL;
+
int ok_here;
int _regex_matched = 0;
-
+
int prts_int;
- char *st = str;
- char *st_error = NULL;
-
- char *pt = pattern;
- char *next_pt;
+ const char *st = str;
+ const char *st_error = NULL;
+
+ const char *pt = pattern;
+ const char *next_pt;
+
+ const char *pt_error[4] = {NULL, NULL, NULL, NULL};
+ const char *pt_error_str[4] = {NULL, NULL, NULL, NULL};
- char *pt_error[4] = {NULL, NULL, NULL, NULL};
- char *pt_error_str[4];
-
/* Will loop the whole string, trying to find a match */
do
switch(*pt)
{
case '\0':
- if(!(flags & END_SET) || (flags & END_SET && (*st == '\0')))
+ if(!(flags & END_SET) || ((flags & END_SET) && (*st == '\0')))
return(r_code);
break;
pt++;
if(*pt == '\0')
{
- if(!(flags & END_SET) || (flags & END_SET && (*st == '\0')))
+ if(!(flags & END_SET) || ((flags & END_SET) && (*st == '\0')))
return(r_code);
}
break;
+ default:
+ break; /* do nothing */
}
/* If it starts on Backslash (future regex) */
if(Regex((uchar)*(pt+1), (uchar)*st))
{
next_pt = pt+2;
-
+
/* If we don't have a '+' or '*', we should skip
* searching using this pattern.
*/
r_code = st;
continue;
}
-
+
/* If it is a '*', we need to set the _regex_matched
* for the first pattern even.
*/
/* If our regex matches and we have a "+" set, we will
- * try the next one to see if it matches. If yes, we
+ * try the next one to see if it matches. If yes, we
* can jump to it, but saving our currently location
* in case of error.
* _regex_matched will set set to true after the first
{
next_pt++;
}
-
+
if(*next_pt == '\0')
{
ok_here = 1;
{
if(*(st+1) == '\0')
prts_str[prts_int] = st+1;
- else
+ else
prts_str[prts_int] = st;
break;
}
continue;
}
-
+
/* Each "if" will increment the amount
* necessary for the next pattern in ok_here
*/
- if(ok_here)
+ if(ok_here)
next_pt+=ok_here;
-
-
+
+
if(!pt_error[0])
{
pt_error[0] = pt;
_regex_matched = 1;
}
-
+
r_code = st;
continue;
}
-
+
else if((*(pt+3) == '\0') && (_regex_matched == 1)&&(r_code))
{
r_code = st;
- if(!(flags & END_SET) || (flags & END_SET && (*st == '\0')))
+ if(!(flags & END_SET) || ((flags & END_SET) && (*st == '\0')))
return(r_code);
}
-
+
/* If we didn't match regex, but _regex_matched == 1, jump
* to the next available pattern
*/
}
pt = pattern;
r_code = NULL;
-
+
}while(*(++st) != '\0');
if(*pt == BACKSLASH && *(pt+2) == '*')
pt+=3;
else
- break;
+ break;
}
-
+
if(prts(*pt))
{
prts_int = 0;
}
/* Cleaning up */
- if(ENDOFFILE(pt) ||
- (*pt == BACKSLASH &&
- _regex_matched &&
- (pt+=2) &&
- isPlus(*pt) &&
+ if(ENDOFFILE(pt) ||
+ (*pt == BACKSLASH &&
+ _regex_matched &&
+ (pt+=2) &&
+ isPlus(*pt) &&
+ (pt++) &&
+ ((ENDOFFILE(pt)) ||
+ ((*pt == BACKSLASH) &&
+ (pt+=2) &&
+ (*pt == '*') &&
(pt++) &&
- ((ENDOFFILE(pt)) ||
- ((*pt == BACKSLASH) &&
- (pt+=2) &&
- (*pt == '*') &&
- (pt++) &&
(ENDOFFILE(pt)) ))) ||
(*pt == BACKSLASH &&
(pt+=2) &&
(*pt == '*') &&
(pt++) &&
ENDOFFILE(pt))
- )
+ )
{
return(r_code);
}
-
+
return(NULL);
}