Exemple #1
0
/*********************************************************************************
 *                                                                               *
 * Function: regexp_sub                                                          *
 *                                                                               *
 * Purpose: Test if a string matches the specified regular expression. If yes    *
 *          then create a return value by substituting '\<n>' sequences in       *
 *          output template with the captured groups.                            *
 *                                                                               *
 * Parameters: string          - [IN] the string to parse                        *
 *             pattern         - [IN] the regular expression                     *
 *             output_template - [IN] the output string template. The output     *
 *                                    string is constructed from template by     *
 *                                    replacing \<n> sequences with the captured *
 *                                    regexp group.                              *
 *                                    If output template is NULL or contains     *
 *                                    empty string then the whole input string   *
 *                                    is used as output value.                   *
 *            flags            - [IN] the regcomp() function flags.              *
 *                                    See regcomp() manual.                      *
 *                                                                               *
 * Return value: Allocated string containing output value if the input           *
 *               string matches the specified regular expression or NULL         *
 *               otherwise.                                                      *
 *                                                                               *
 *********************************************************************************/
static char	*regexp_sub(const char *string, const char *pattern, const char *output_template, int flags)
{
	ZBX_THREAD_LOCAL static char	*old_pattern = NULL;
	ZBX_THREAD_LOCAL static int	old_flags;
	ZBX_THREAD_LOCAL static regex_t	re;

	regmatch_t			match[10];	/* up to 10 capture groups in regexp */
	char				*ptr = NULL;

	if (NULL == string)
		return NULL;

	if (NULL == output_template || '\0' == *output_template)
		flags |= REG_NOSUB;

	/* performance optimization: if possible then reuse the last compiled regexp */

	if (NULL == old_pattern)
		goto compile;

	if (0 != strcmp(old_pattern, pattern) || old_flags != flags)
		regfree(&re);
	else
		goto execute;
compile:
	if (0 == regcomp(&re, pattern, flags))
	{
		old_pattern = zbx_strdup(old_pattern, pattern);
		old_flags = flags;
	}
	else
	{
#ifdef _WINDOWS
		/* the Windows gnuregex implementation does not correctly clean up */
		/* allocated memory after regcomp() failure                        */
		regfree(&re);
#endif
		zbx_free(old_pattern);
		return NULL;
	}
execute:
	if (0 == regexec(&re, string, ARRSIZE(match), match, 0))
		ptr = regexp_sub_replace(string, output_template, match, ARRSIZE(match));

	return ptr;
}
/*********************************************************************************
 *                                                                               *
 * Function: regexp_sub                                                          *
 *                                                                               *
 * Purpose: Test if a string matches the specified regular expression. If yes    *
 *          then create a return value by substituting '\<n>' sequences in       *
 *          output template with the captured groups.                            *
 *                                                                               *
 * Parameters: string          - [IN] the string to parse                        *
 *             pattern         - [IN] the regular expression                     *
 *             output_template - [IN] the output string template. The output     *
 *                                    string is constructed from template by     *
 *                                    replacing \<n> sequences with the captured *
 *                                    regexp group.                              *
 *                                    If output template is NULL or contains     *
 *                                    empty string then the whole input string   *
 *                                    is used as output value.                   *
 *            flags            - [IN] the regcomp() function flags.              *
 *                                    See regcomp() manual.                      *
 *                                                                               *
 * Return value: Allocated string containing output value if the input           *
 *               string matches the specified regular expression or NULL         *
 *               otherwise.                                                      *
 *                                                                               *
 *********************************************************************************/
static char	*regexp_sub(const char *string, const char *pattern, const char *output_template, int flags)
{
	regex_t		re;
	regmatch_t	match[10];
	char		*ptr = NULL;

	if (NULL == string)
		return NULL;

	if (NULL == output_template || '\0' == *output_template)
		flags |= REG_NOSUB;

	if (0 != regcomp(&re, pattern, flags))
		return NULL;

	if (0 == regexec(&re, string, ARRSIZE(match), match, 0))
		ptr = regexp_sub_replace(string, output_template, match, ARRSIZE(match));

	regfree(&re);

	return ptr;
}