Attached patch seems to work (mirror works in auto mode), and the small test suite I added shows it does the right thing in all 4 cases. Could use some more testing, and my caveats about this being a hacky and suboptimal approach still apply. -- see shy jo
From 2e86f33f8439682894441139873cd917ede4736b Mon Sep 17 00:00:00 2001 From: Joey Hess <joey@kodama.kitenet.net> Date: Thu, 19 Jun 2008 18:40:13 -0400 Subject: [PATCH] noninteractive select handling * Add a separate queue for noninteractive questions, so that things can be done when these questions would be displayed. This is a bit hackish; debconf's method of letting questions determine if they are interactive or not is really better. But this doesn't need huge changes to cdebconf. * Handle the special case of a noninteractive select with no (or a bad) default the same as debconf does; when such a question is asked, set the value to the first item in the select list. Closes: #486892, #247744 --- packages/cdebconf/debian/changelog | 13 ++++ packages/cdebconf/src/commands.c | 3 + packages/cdebconf/src/frontend.c | 91 ++++++++++++++++++++++++++- packages/cdebconf/src/frontend.h | 5 ++ packages/cdebconf/src/test/select.config | 58 +++++++++++++++++ packages/cdebconf/src/test/select.templates | 22 +++++++ 6 files changed, 191 insertions(+), 1 deletions(-) create mode 100755 packages/cdebconf/src/test/select.config create mode 100644 packages/cdebconf/src/test/select.templates diff --git a/packages/cdebconf/debian/changelog b/packages/cdebconf/debian/changelog index c24225b..75ec1df 100644 --- a/packages/cdebconf/debian/changelog +++ b/packages/cdebconf/debian/changelog @@ -1,3 +1,16 @@ +cdebconf (0.132) UNRELEASED; urgency=low + + * Add a separate queue for noninteractive questions, so that things can + be done when these questions would be displayed. This is a bit hackish; + debconf's method of letting questions determine if they are interactive or + not is really better. But this doesn't need huge changes to cdebconf. + * Handle the special case of a noninteractive select with no (or a bad) + default the same as debconf does; when such a question is asked, + set the value to the first item in the select list. + Closes: #486892, #247744 + + -- Joey Hess <joeyh@debian.org> Thu, 19 Jun 2008 17:18:08 -0400 + cdebconf (0.131) unstable; urgency=low [ Frans Pop ] diff --git a/packages/cdebconf/src/commands.c b/packages/cdebconf/src/commands.c index 878e0b2..a5235c2 100644 --- a/packages/cdebconf/src/commands.c +++ b/packages/cdebconf/src/commands.c @@ -54,6 +54,8 @@ command_input(struct confmodule *mod, char *arg) if (visible) visible = mod->frontend->methods.add(mod->frontend, q); + else + mod->frontend->methods.add_noninteractive(mod->frontend, q); if (q->priority != NULL) free(q->priority); @@ -220,6 +222,7 @@ command_go(struct confmodule *mod, char *arg) mod->frontend->questions = q; } + mod->frontend->methods.go_noninteractive(mod->frontend); ret = mod->frontend->methods.go(mod->frontend); if (ret == CMDSTATUS_GOBACK || mod->backed_up != 0) { diff --git a/packages/cdebconf/src/frontend.c b/packages/cdebconf/src/frontend.c index 59d83fe..3a21bf9 100644 --- a/packages/cdebconf/src/frontend.c +++ b/packages/cdebconf/src/frontend.c @@ -4,6 +4,8 @@ #include "database.h" #include "frontend.h" #include "question.h" +#include "template.h" +#include "strutl.h" #include <dlfcn.h> #include <string.h> @@ -28,7 +30,7 @@ static int frontend_add(struct frontend *obj, struct question *q) qlast = qlast->next; } /* Question asked twice. debconf ignores the second question and - will we. */ + so will we. */ if (qlast == q) return DC_OK; qlast->next = q; @@ -40,11 +42,88 @@ static int frontend_add(struct frontend *obj, struct question *q) return DC_OK; } +static int frontend_add_noninteractive(struct frontend *obj, struct question *q) +{ + struct question *qlast; + ASSERT(q != NULL); + ASSERT(q->prev == NULL); + ASSERT(q->next == NULL); + + //INFO(INFO_DEBUG, "adding noninteractive question"); + + qlast = obj->questions_noninteractive; + if (qlast == NULL) + { + obj->questions_noninteractive = q; + } + else + { + while (qlast != q && qlast->next != NULL) + { + qlast = qlast->next; + } + qlast->next = q; + q->prev = qlast; + } + + question_ref(q); + + return DC_OK; +} + static int frontend_go(struct frontend *obj) { return DC_OK; } +static int frontend_go_noninteractive(struct frontend *obj) +{ + struct question *q = obj->questions_noninteractive; + + while (q != NULL) { + char *type = q->template->type; + + //INFO(INFO_DEBUG, "frontend_go_noninteractive; type %s", type); + + /* This is a hack to make noninteractive selects be set to + * the first item in the select list if their value is not + * set, or is set to something not in the list. This is for + * consistency with debconf. */ + if (strcmp(type, "select") == 0) { + int i, ok=0; + char **choices=NULL; + char *val = (char *) question_getvalue(q, ""); + int count = strgetargc(q_get_choices_vals(obj, q)); + if (count) { + choices = malloc(sizeof(char *) * count); + if (strchoicesplit(q_get_choices_vals(obj, q), choices, count) != count) + return DC_NOTOK; + + for (i = 0; i < count; i++) { + if (val && strcmp(val, choices[i]) == 0) { + ok=1; + break; + } + } + } + + if (! ok) { + if (count) + question_setvalue(q, choices[0]); + else + question_setvalue(q, ""); + } + + if (choices) + free(choices); + } + + q = q->next; + } + + return DC_OK; +} + static void frontend_clear(struct frontend *obj) { struct question *q; @@ -56,6 +135,14 @@ static void frontend_clear(struct frontend *obj) q->next = q->prev = NULL; question_deref(q); } + + while (obj->questions_noninteractive != NULL) + { + q = obj->questions_noninteractive; + obj->questions_noninteractive = obj->questions_noninteractive->next; + q->next = q->prev = NULL; + question_deref(q); + } } static int frontend_initialize(struct frontend *obj, struct configuration *cfg) @@ -227,6 +314,8 @@ struct frontend *frontend_new(struct configuration *cfg, struct template_db *tdb SETMETHOD(progress_step); SETMETHOD(progress_info); SETMETHOD(progress_stop); + SETMETHOD(add_noninteractive); + SETMETHOD(go_noninteractive); #undef SETMETHOD diff --git a/packages/cdebconf/src/frontend.h b/packages/cdebconf/src/frontend.h index 2f8e1aa..04a4dd7 100644 --- a/packages/cdebconf/src/frontend.h +++ b/packages/cdebconf/src/frontend.h @@ -43,6 +43,9 @@ struct frontend_module { int (*progress_step)(struct frontend *fe, int step); int (*progress_info)(struct frontend *fe, const char *info); void (*progress_stop)(struct frontend *fe); + + int (*go_noninteractive)(struct frontend *); + int (*add_noninteractive)(struct frontend *, struct question *q); }; struct frontend { @@ -75,6 +78,8 @@ struct frontend { struct frontend_module methods; /* path to plugins */ char *plugin_path; + /* separate list of noninteractive questions */ + struct question *questions_noninteractive; }; struct frontend *frontend_new(struct configuration *, struct template_db *, struct question_db *); diff --git a/packages/cdebconf/src/test/select.config b/packages/cdebconf/src/test/select.config new file mode 100755 index 0000000..ce443c1 --- /dev/null +++ b/packages/cdebconf/src/test/select.config @@ -0,0 +1,58 @@ +#!/bin/sh -e +# Testing #486892 +. ../client/confmodule + +debug() +{ + echo $* >&2 +} + +askquestion() +{ + question=$1 + priority=$2 + db_fset $question seen false + db_input $priority $question || true + db_go || true + db_get $question +} + +ok=1 + +askquestion test/select/withdefault low +if [ "$RET" = second ]; then + debug "ok withdefault" +else + debug "fail withdefault ($RET)" + ok=0 +fi + +askquestion test/select/nodefault low +if [ "$RET" = first ]; then + debug "ok nodefault" +else + debug "fail nodefault ($RET)" + ok=0 +fi + +askquestion test/select/strangedefault low +if [ "$RET" = first ]; then + debug "ok nodefault" +else + debug "fail nodefault ($RET)" + ok=0 +fi + +askquestion test/select/nochoices low +if [ "$RET" = "" ]; then + debug "ok nochoices" +else + debug "fail nochoices ($RET)" + ok=0 +fi + +if [ "$ok" ]; then + exit 0 +else + exit 1 +fi diff --git a/packages/cdebconf/src/test/select.templates b/packages/cdebconf/src/test/select.templates new file mode 100644 index 0000000..e2076a4 --- /dev/null +++ b/packages/cdebconf/src/test/select.templates @@ -0,0 +1,22 @@ +Template: test/select/withdefault +Type: select +Default: second +Choices: first, second, third +Description: select with a default value + +Template: test/select/nodefault +Type: select +Choices: first, second, third +Description: select with no default value + +Template: test/select/strangedefault +Type: select +Default: fourth +Choices: first, second, third +Description: select with a strange default value + +Template: test/select/nochoices +Type: select +Default: fourth +Choices: +Description: select with no choices -- 1.5.5.4
Attachment:
signature.asc
Description: Digital signature