
/*
 | The following structure defines a few application-specific configuration desires.
 | It provides application defaults for things that can also be set by other means.
 | Assigning a non-zero value indicates a custom application desire.
 | Items with a zero value will default to the decisions made when the PCRE CONFIG.H was defined.
 */

typedef struct pcre_app_cfg {
  unsigned long int match_limit;  /* Maximum number of calls to match() */
  unsigned long int match_limit_recursion; /* Max recursive calls to match() */
  int something_else;      /* not yet useful */
  int another_thing;       /* not yet useful */
} pcre_app_cfg;


/*
 | The following can retrieve the default configuration values for the application.
 | These defaults were decided upon when the PCRE CONFIG.H was defined.
 */
PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
pcre_get_app_defaults (pcre_app_cfg * app_cfg)
{
  if (app_cfg == NULL)
    return;

  app_cfg->match_limit = MATCH_LIMIT;
  app_cfg->match_limit_recursion = MATCH_LIMIT_RECURSION;
  app_cfg->something_else = 0;
  app_cfg->another_thing = 0;

} /* end of pcre_get_app_cfg */


/*
 | The following function is similar to pcre_exec(), with the exception that the
 | first parameter is new, and may optionally contain application-specific
 | configuration defaults.
 */

PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_exec_app (const pcre_app_cfg * app_cfg,
  const pcre *argument_re, const pcre_extra *extra_data,
  PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,
  int offsetcount)
{
pcre_extra app_extra;

/* the application should have provided its configuration desires */
if (app_cfg != NULL)
  {
  /* we assign a pcre_extra if the caller has not provided one */
  if (extra_data == NULL)
    {
    memset (&app_extra, 0, sizeof(app_extra));
    }
  else
    {
    /* the caller's extra_data is CONST, any mods are to our own copy of it */
    /* its origin may have come from a call to pcre_study() */
    memcpy (&app_extra, extra_data, sizeof(*extra_data));
    }
  /* apply application desires into our own copy of the pcre_extra */
  extra_data = &app_extra;
  if ((app_cfg->match_limit > 0) &&
      ((app_extra.flags & PCRE_EXTRA_MATCH_LIMIT) != 0))
    {
    app_extra.flags |= PCRE_EXTRA_MATCH_LIMIT;
     app_extra.match_limit = app_cfg->match_limit;
    }
  if ((app_cfg->match_limit > 0) &&
      ((app_extra.flags & PCRE_EXTRA_MATCH_LIMIT) != 0))
    {
    app_extra.flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
    app_extra.match_limit_recursion = app_cfg->match_limit_recursion;
    }
  }

/* having assigned the application's config desires, invoke exec() as normal */
return pcre_exec(argument_re, extra_data, subject, length, start_offset, options, offsets, offsetcount);
} /* end of pcre_exec_app() */


