On 17-Sep-04, at 4:55 PM, Stas Bekman wrote:
I'd rather not add new directives, but have:
On reflection, I think I agree. It is possible to achieve virtually the same effect with
PerlSetVar foo ""
So I trimmed a few lines out of the patch, ran the tests again, and this time I will cut and paste it into the message:
--------------------------------------------------------
Index: modperl-2.0/src/modules/perl/mod_perl.h
===================================================================
RCS file: /home/cvspublic/modperl-2.0/src/modules/perl/mod_perl.h,v
retrieving revision 1.68
diff -u -r1.68 mod_perl.h
--- modperl-2.0/src/modules/perl/mod_perl.h 10 Jul 2004 00:36:19 -0000 1.68
+++ modperl-2.0/src/modules/perl/mod_perl.h 18 Sep 2004 00:16:21 -0000
@@ -129,9 +129,10 @@
#define MgTypeExt(mg) (mg->mg_type == '~')
-typedef void MP_FUNC_T(modperl_table_modify_t) (apr_table_t *, - const char *, - const char *); +typedef void MP_FUNC_T(modperl_var_modify_t) (apr_table_t *, + apr_table_t *, + const char *, + const char *);
/* we need to hook a few internal things before APR_HOOK_REALLY_FIRST */
#define MODPERL_HOOK_REALLY_REALLY_FIRST (-20)
Index: modperl-2.0/src/modules/perl/modperl_cmd.c
===================================================================
RCS file: /home/cvspublic/modperl-2.0/src/modules/perl/modperl_cmd.c,v
retrieving revision 1.65
diff -u -r1.65 modperl_cmd.c
--- modperl-2.0/src/modules/perl/modperl_cmd.c 9 Sep 2004 22:16:37 -0000 1.65
+++ modperl-2.0/src/modules/perl/modperl_cmd.c 18 Sep 2004 00:16:22 -0000
@@ -266,64 +266,50 @@
}
}
-static MP_CMD_SRV_DECLARE2(handle_vars)
+static void modperl_cmd_addvar_func(apr_table_t *configvars,
+ apr_table_t *setvars,
+ const char *key, const char *val)
{
- MP_dSCFG(parms->server);
- modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig;
- const char *name = parms->cmd->name;
-
- /* PerlSetVar and PerlAddVar logic. here's the deal...
- *
- * cfg->configvars holds the final PerlSetVar/PerlAddVar configuration
- * for a given server or directory. however, getting to that point
- * is kind of tricky, due to the add-style nature of PerlAddVar.
- *
- * the solution is to use cfg->setvars to hold PerlSetVar entries
- * and cfg->addvars to hold PerlAddVar entries, each serving as a
- * placeholder for when we need to know what's what in the merge routines.
- *
- * however, for the initial pass, apr_table_setn and apr_table_addn
- * will properly build the configvars table, which will be visible to
- * startup scripts trying to access per-server configurations.
- *
- * the end result is that we need to populate all three tables in order
- * to keep things straight later on see merge_table_config_vars in
- * modperl_config.c
- */
- modperl_table_modify_t func =
- strEQ(name, "PerlSetVar") ? apr_table_setn : apr_table_addn;
+ apr_table_addn(configvars, key, val);
+}
- apr_table_t *table =
- strEQ(name, "PerlSetVar") ? dcfg->setvars : dcfg->addvars;
+/* Conceptually, setvar is { unsetvar; addvar; } */- func(table, arg1, arg2);
- func(dcfg->configvars, arg1, arg2);
+static void modperl_cmd_setvar_func(apr_table_t *configvars,
+ apr_table_t *setvars,
+ const char * key, const char *val)
+{
+ apr_table_setn(setvars, key, val);
+ apr_table_setn(configvars, key, val);
+}+static const char *modperl_cmd_modvar(modperl_var_modify_t varfunc,
+ cmd_parms *parms,
+ modperl_config_dir_t *dcfg,
+ const char *arg1, const char *arg2)
+{
+ varfunc(dcfg->configvars, dcfg->setvars, arg1, arg2);
MP_TRACE_d(MP_FUNC, "%s DIR: arg1 = %s, arg2 = %s\n",
- name, arg1, arg2);
-
- /* make available via Apache->server->dir_config */
+ parms->cmd->name, arg1, arg2);
if (!parms->path) {
- table = strEQ(name, "PerlSetVar") ? scfg->setvars : scfg->addvars;
-
- func(table, arg1, arg2);
- func(scfg->configvars, arg1, arg2);
-
+ MP_dSCFG(parms->server);
+ varfunc(scfg->configvars, scfg->setvars, arg1, arg2);
MP_TRACE_d(MP_FUNC, "%s SRV: arg1 = %s, arg2 = %s\n",
- name, arg1, arg2);
+ parms->cmd->name, arg1, arg2);
}
-
return NULL;
}
-MP_CMD_SRV_DECLARE2(set_var)
+MP_CMD_SRV_DECLARE2(add_var)
{
- return modperl_cmd_handle_vars(parms, mconfig, arg1, arg2);
+ modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig;
+ return modperl_cmd_modvar(modperl_cmd_addvar_func, parms, dcfg, arg1, arg2);
}
-MP_CMD_SRV_DECLARE2(add_var)
+MP_CMD_SRV_DECLARE2(set_var)
{
- return modperl_cmd_handle_vars(parms, mconfig, arg1, arg2);
+ modperl_config_dir_t *dcfg = (modperl_config_dir_t *)mconfig;
+ return modperl_cmd_modvar(modperl_cmd_setvar_func, parms, dcfg, arg1, arg2);
}
MP_CMD_SRV_DECLARE2(set_env)
Index: modperl-2.0/src/modules/perl/modperl_config.c
===================================================================
RCS file: /home/cvspublic/modperl-2.0/src/modules/perl/modperl_config.c,v
retrieving revision 1.81
diff -u -r1.81 modperl_config.c
--- modperl-2.0/src/modules/perl/modperl_config.c 9 Sep 2004 22:39:11 -0000 1.81
+++ modperl-2.0/src/modules/perl/modperl_config.c 18 Sep 2004 00:16:24 -0000
@@ -43,6 +43,11 @@
* note that this is equivalent to apr_table_overlap except a new
* table is generated, which is required (otherwise we would clobber
* the existing parent or child configurations)
+ *
+ * note that this is *not* equivalent to apr_table_overlap, although
+ * I think it should be, because apr_table_overlap seems to clear
+ * its first argument when the tables have different pools. I think
+ * this is wrong -- rici
*/
apr_table_t *merge = apr_table_overlay(p, base, add);
@@ -59,54 +64,27 @@
#define merge_table_overlap_item(item) \
mrg->item = modperl_table_overlap(p, base->item, add->item)-static apr_table_t *merge_table_config_vars(apr_pool_t *p,
- apr_table_t *configvars,
- apr_table_t *set,
- apr_table_t *add)
+static apr_table_t *merge_config_add_vars(apr_pool_t *p,
+ const apr_table_t *base,
+ const apr_table_t *unset,
+ const apr_table_t *add)
{
- apr_table_t *base = apr_table_copy(p, configvars);
- apr_table_t *merged_config_vars;
+ apr_table_t *temp = apr_table_copy(p, base); const apr_array_header_t *arr;
apr_table_entry_t *entries;
int i;- /* configvars already contains a properly merged PerlSetVar/PerlAddVar
- * configuration for the base (parent), so all we need to do is merge
- * the add (child) configuration into it properly.
- *
- * any PerlSetVar settings in the add (child) config need to reset
- * existing entries in the base (parent) config, or generate a
- * new entry where none existed previously. PerlAddVar settings
- * are merged into that.
- *
- * unfortunately, there is no set of apr functions to do this for us -
- * apr_compress_table would be ok, except it always merges mulit-valued
- * keys into one, regardless of the APR_OVERLAP_TABLES flag. that is,
- * regardless of whether newer entries are set or merged into existing
- * entries, the entire table is _always_ compressed. this is no good -
- * we need separate entries for existing keys, not a single (compressed)
- * entry.
- *
- * fortunately, the logic here is simple. first, (re)set the base (parent)
- * table where a PerlSetVar entry exists in the add (child) configuration.
- * then, just overlay the PerlAddVar configuration into it.
- */
-
- arr = apr_table_elts(set);
+ /* for each key in unset do apr_table_unset(temp, key); */
+ arr = apr_table_elts(unset);
entries = (apr_table_entry_t *)arr->elts;
/* hopefully this is faster than using apr_table_do */
for (i = 0; i < arr->nelts; i++) {
- apr_table_setn(base, entries[i].key, entries[i].val);
+ if (entries[i].key) apr_table_unset(temp, entries[i].key);
}
-
- /* at this point, all the PerlSetVar merging has happened. add in the
- * add (child) PerlAddVar entries and we're done
- */
- merged_config_vars = apr_table_overlay(p, base, add);
-
- return merged_config_vars;
+
+ return apr_table_overlay(p, temp, add);
}
#define merge_handlers(merge_flag, array) \
@@ -141,18 +119,10 @@
merge_table_overlap_item(SetEnv);/* this is where we merge PerlSetVar and PerlAddVar together */
- mrg->configvars = merge_table_config_vars(p,
- base->configvars,
- add->setvars, add->addvars);
-
- /* note we don't care about merging dcfg->setvars or dcfg->addvars
- * specifically - what is important to merge is dfcg->configvars.
- * but we need to keep track of the entries for this config, so
- * the merged values are simply the values for the add (current)
- * configuration.
- */
- mrg->setvars = add->setvars;
- mrg->addvars = add->addvars;
+ mrg->configvars = merge_config_add_vars(p,
+ base->configvars,
+ add->setvars, add->configvars);
+ merge_table_overlap_item(setvars);
/* XXX: check if Perl*Handler is disabled */
for (i=0; i < MP_HANDLER_NUM_PER_DIR; i++) {
@@ -187,7 +157,6 @@
scfg->argv = apr_array_make(p, 2, sizeof(char *)); scfg->setvars = apr_table_make(p, 2);
- scfg->addvars = apr_table_make(p, 2);
scfg->configvars = apr_table_make(p, 2); scfg->PassEnv = apr_table_make(p, 2);
@@ -223,7 +192,6 @@
dcfg->flags = modperl_options_new(p, MpDirType); dcfg->setvars = apr_table_make(p, 2);
- dcfg->addvars = apr_table_make(p, 2);
dcfg->configvars = apr_table_make(p, 2); dcfg->SetEnv = apr_table_make(p, 2);
@@ -322,18 +290,10 @@
merge_table_overlap_item(PassEnv);/* this is where we merge PerlSetVar and PerlAddVar together */
- mrg->configvars = merge_table_config_vars(p,
- base->configvars,
- add->setvars, add->addvars);
-
- /* note we don't care about merging dcfg->setvars or dcfg->addvars
- * specifically - what is important to merge is dfcg->configvars.
- * but we need to keep track of the entries for this config, so
- * the merged values are simply the values for the add (current)
- * configuration.
- */
- mrg->setvars = add->setvars;
- mrg->addvars = add->addvars;
+ mrg->configvars = merge_config_add_vars(p,
+ base->configvars,
+ add->setvars, add->configvars);
+ merge_table_overlap_item(setvars);
merge_item(threaded_mpm);
merge_item(server);
Index: modperl-2.0/src/modules/perl/modperl_types.h
===================================================================
RCS file: /home/cvspublic/modperl-2.0/src/modules/perl/modperl_types.h,v
retrieving revision 1.76
diff -u -r1.76 modperl_types.h
--- modperl-2.0/src/modules/perl/modperl_types.h 18 Aug 2004 22:05:16 -0000 1.76
+++ modperl-2.0/src/modules/perl/modperl_types.h 18 Sep 2004 00:16:25 -0000
@@ -127,7 +127,6 @@
typedef struct {
MpHV *setvars;
- MpHV *addvars;
MpHV *configvars;
MpHV *SetEnv;
MpHV *PassEnv;
@@ -160,7 +159,6 @@
MpAV *handlers_per_dir[MP_HANDLER_NUM_PER_DIR];
MpHV *SetEnv;
MpHV *setvars;
- MpHV *addvars;
MpHV *configvars;
modperl_options_t *flags;
#ifdef USE_ITHREADS
Index: modperl-2.0/t/response/TestModperl/merge.pm
===================================================================
RCS file: /home/cvspublic/modperl-2.0/t/response/TestModperl/merge.pm,v
retrieving revision 1.7
diff -u -r1.7 merge.pm
--- modperl-2.0/t/response/TestModperl/merge.pm 9 Jul 2004 18:53:01 -0000 1.7
+++ modperl-2.0/t/response/TestModperl/merge.pm 18 Sep 2004 00:16:27 -0000
@@ -90,7 +90,7 @@
$hash = $1;
# skip .htaccess merges for now - they are still broken
- plan tests => 10, under_construction;
+ # plan tests => 10, under_construction;
} elsif ($uri =~ m/(merge2)/) {
$hash = $1;
} else {
-- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html
