[patch] cdebconf and i18n
Here is an improved patch, it has been tested and looks fine.
Currently language choice is performed by a DEBCONF_LANG environment
variable.
In src/modules/db/textdb/textdb.c, the textdb_template_get_real needs
more work.
Denis
Index: debian/changelog
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/debian/changelog,v
retrieving revision 1.40
diff -u -r1.40 changelog
--- debian/changelog 6 Nov 2002 10:11:37 -0000 1.40
+++ debian/changelog 9 Nov 2002 01:21:18 -0000
@@ -29,6 +29,13 @@
- fix confmodule.c and commands.c to not use fixed-size
buffers. (closes: #167312)
* Denis Barbier:
+ - change internal template structure in src/template.h in order
+ to help managing localized fields, and fix doc/modules.txt
+ accordingly
+ - define accessors to get and set template values, should be used
+ everywhere instead of direct access to structure members
+ - partially handle localized fields, only UTF-8 templates files
+ are considered
- convert to po-debconf, set Build-Depends: debhelper (>= 4.1.13)
to ensure that generated templates are right, and set output encoding
to UTF-8.
Index: doc/modules.txt
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/doc/modules.txt,v
retrieving revision 1.7
diff -u -r1.7 modules.txt
--- doc/modules.txt 1 Jul 2002 06:58:37 -0000 1.7
+++ doc/modules.txt 9 Nov 2002 01:21:18 -0000
@@ -36,20 +36,37 @@
A template has the following publically accessible fields:
- char *tag: the template's tag
-- char *type: the template's type XXX can be one of ...
-- char *defaultval: the template's default value, as a string
-- char *choices: if the template's type is choices based, here the choices
- are listed in a single string, seperated by commas XXX right?
-- char *description: a description of the template XXX must be under ... chars?
-- char *extended_description: a longer description
-- struct language_description *localized descriptions - has following fields:
- - struct language_description *next: NULL or another localized description
- - char *language: ISO tag for language XXX right?
- - char *choices, char *description, char *extended_description: as above,
- only in specified language
-
+- char *type: the template's type, can be one of select, multiselect,
+ string, boolean, note, text and password
+- struct template_l10n_fields *fields - has following fields:
+ - struct template_l10n_fields *next: NULL or another localized field
+ structure
+ - char *language: ISO code for language (ll or ll_LL)
+ - char *defaultval: the template's default value, as a string
+ - char *choices: if the template's type is choices based, here the choices
+ are listed in a single string, seperated by commas
+ - char *description: a description of the template XXX must be under ... chars?
+ - char *extended_description: a longer description
+
+The first template_l10n_fields structure must always be in English, and
+its ISO code is set to C.
+
XXX not covering "next", I assume it is private
XXX not covering memory management or deletion
+
+Publically accessible methods:
+
+const char *lget(struct template *, const char *lang, const char *field):
+ Return a string value for given field in a language, or NULL if not found
+
+void lset(struct template *, const char *lang, const char *field, const char *value):
+ Save string value at field for a given language
+
+const char *get(struct template *, const char *field):
+ Return a string value for given field in English
+
+void set(struct template *, const char *field, const char *value):
+ Save string value at English field
question API
~~~~~~~~~~~~
Index: src/commands.c
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/src/commands.c,v
retrieving revision 1.24
diff -u -r1.24 commands.c
--- src/commands.c 5 Nov 2002 02:55:13 -0000 1.24
+++ src/commands.c 9 Nov 2002 01:21:18 -0000
@@ -614,14 +614,14 @@
if (strcmp(field, "value") == 0)
snprintf(out, outsize, "%u %s", CMDSTATUS_SUCCESS, q->value);
else if (strcmp(field, "description") == 0)
- snprintf(out, outsize, "%u %s", CMDSTATUS_SUCCESS, question_description(q));
+ snprintf(out, outsize, "%u %s", CMDSTATUS_SUCCESS, question_get_translated_field(q, field));
else if (strcmp(field, "extended_description") == 0)
/* NOTE: this probably is wrong, because the extended
* description is likely multiline
*/
- snprintf(out, outsize, "%u %s", CMDSTATUS_SUCCESS, question_extended_description(q));
+ snprintf(out, outsize, "%u %s", CMDSTATUS_SUCCESS, question_get_translated_field(q, field));
else if (strcmp(field, "choices") == 0)
- snprintf(out, outsize, "%u %s", CMDSTATUS_SUCCESS, question_choices(q));
+ snprintf(out, outsize, "%u %s", CMDSTATUS_SUCCESS, question_get_translated_field(q, field));
else
snprintf(out, outsize, "%u %s does not exist", CMDSTATUS_BADPARAM, field);
}
Index: src/question.c
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/src/question.c,v
retrieving revision 1.12
diff -u -r1.12 question.c
--- src/question.c 7 Aug 2002 16:34:01 -0000 1.12
+++ src/question.c 9 Nov 2002 01:21:18 -0000
@@ -43,6 +43,8 @@
#include "configuration.h"
#include "database.h"
+static char cur_lang[6] = {0};
+
struct question *question_new(const char *tag)
{
struct question *q;
@@ -228,126 +230,44 @@
return DC_OK;
}
-/*
- * Function: getlanguage
- * Input: none
- * Output: const char* (size == 3) the language code of the currently
- * selected language
- * Description: find the currently selected language
- * Assumptions: config_new and database_new succeeds,
- * debian-installer/language exists
- */
-
-const char *getlanguage()
-{
-#if 0 /* FIXME */
- static struct database *db = NULL;
- static struct configuration *config = NULL;
- static char language[3];
- /* We need to directly access the configuration, since I couldn't
- get debconfclient to work from in here. */
- struct question *q2 = NULL;
- memset(language,'\0',3);
-
- if (! config) /* Then db isn't set either.. */
- {
- config = config_new();
- if (config == 0)
- DIE("Error initializing configuration item (%s %d)", __FILE__,__LINE__);
- if (config->read(config, DEBCONFCONFIG) == 0)
- DIE("Error reading configuration information");
- if ((db = database_new(config)) == 0)
- DIE("Cannot initialize DebConf database");
- db->load(db);
- }
- q2 = db->question_get(db, "debian-installer/language");
- if (q2 != NULL) {
- if (q2->value != NULL)
- snprintf(language,3,"%.2s",q2->value);
- question_deref(q2);
- }
- return language;
-#else
- return "";
-#endif
-}
-
-const char *question_description(struct question *q)
-{
- static char buf[4096] = {0};
- struct language_description *langdesc;
-
- langdesc = q->template->localized_descriptions;
- while (langdesc)
- {
- if (strcmp(langdesc->language,getlanguage()) == 0)
- {
- question_expand_vars(q, langdesc->description, buf, sizeof(buf));
- return buf;
- }
- langdesc = langdesc->next;
- }
- question_expand_vars(q, q->template->description, buf, sizeof(buf));
- return buf;
-}
-
-const char *question_extended_description(struct question *q)
-{
- static char buf[4096] = {0};
- question_expand_vars(q, q->template->extended_description, buf, sizeof(buf));
- return buf;
-}
-
-const char *question_extended_description_translated(struct question *q)
+const char *getlanguage(void)
{
- static char buf[4096] = {0};
- struct language_description *langdesc;
-
- langdesc = q->template->localized_descriptions;
- while (langdesc)
+ if (cur_lang[0] == 0)
{
- if (strcmp(langdesc->language,getlanguage()) == 0 && langdesc->description != NULL)
- {
- question_expand_vars(q, langdesc->extended_description, buf, sizeof(buf));
- return buf;
- }
- langdesc = langdesc->next;
+ if (getenv("DEBCONF_LANG"))
+ strncpy(cur_lang, getenv("DEBCONF_LANG"), 5);
+ else
+ strcpy(cur_lang, "C");
}
- question_expand_vars(q, q->template->extended_description, buf, sizeof(buf));
- return buf;
+ return cur_lang;
}
-const char *question_choices_translated(struct question *q)
+const char *question_get_field(struct question *q, const char *field)
{
static char buf[4096] = {0};
- struct language_description *langdesc;
-
- langdesc = q->template->localized_descriptions;
- while (langdesc)
- {
- if (strcmp(langdesc->language,getlanguage()) == 0 && langdesc->choices != NULL)
- {
- question_expand_vars(q, langdesc->choices, buf, sizeof(buf));
- return buf;
- }
- langdesc = langdesc->next;
- }
- question_expand_vars(q, q->template->choices, buf, sizeof(buf));
+ if (strcmp(field, "default") == 0) {
+ if (q->value != 0 && *q->value != 0)
+ return q->value;
+ else
+ return q->template->get(q->template, field);
+ }
+ question_expand_vars(q,
+ q->template->get(q->template, field),
+ buf, sizeof(buf));
return buf;
}
-const char *question_choices(struct question *q)
+const char *question_get_translated_field(struct question *q, const char *field)
{
static char buf[4096] = {0};
- question_expand_vars(q, q->template->choices, buf, sizeof(buf));
+ if (strcmp(field, "default") == 0) {
+ if (q->value != 0 && *q->value != 0)
+ return q->value;
+ else
+ return q->template->lget(q->template, getlanguage(), field);
+ }
+ question_expand_vars(q,
+ q->template->lget(q->template, getlanguage(), field),
+ buf, sizeof(buf));
return buf;
}
-
-const char *question_defaultval(struct question *q)
-{
- if (q->value != 0 && *q->value != 0)
- return q->value;
- else
- return q->template->defaultval;
-}
-
Index: src/question.h
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/src/question.h,v
retrieving revision 1.9
diff -u -r1.9 question.h
--- src/question.h 12 Aug 2002 13:38:34 -0000 1.9
+++ src/question.h 9 Nov 2002 01:21:18 -0000
@@ -45,10 +45,7 @@
const char *value);
void question_owner_add(struct question *q, const char *owner);
void question_owner_delete(struct question *q, const char *owner);
-const char *question_description(struct question *q);
-const char *question_extended_description(struct question *q);
-const char *question_choices_translated(struct question *q);
-const char *question_choices(struct question *q);
-const char *question_defaultval(struct question *q);
+const char *question_get_field(struct question *q, const char *field);
+const char *question_get_translated_field(struct question *q, const char *field);
#endif
Index: src/template.c
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/src/template.c,v
retrieving revision 1.8
diff -u -r1.8 template.c
--- src/template.c 1 Jul 2002 06:58:37 -0000 1.8
+++ src/template.c 9 Nov 2002 01:21:19 -0000
@@ -42,11 +42,31 @@
#include <stdio.h>
+static const char *template_lget(struct template *t, const char *lang,
+ const char *field);
+static const char *template_get(struct template *t, const char *field);
+static void template_lset(struct template *t, const char *lang,
+ const char *field, const char *value);
+static void template_set(struct template *t, const char *field,
+ const char *value);
+static const char *template_next_lang(struct template *t, const char *l);
+
+const char *template_fields_list[] = {
+ "tag",
+ "type",
+ "default",
+ "choices",
+ "description",
+ "extended_description",
+ NULL
+};
+
/*
* Function: template_new
* Input: a tag, describing which template this is. Can be null.
* Output: a blank template struct. Tag is strdup-ed, so the original
string may change without harm.
+ The fields structure is also allocated to store English fields
* Description: allocate a new, empty struct template.
* Assumptions: NEW succeeds
* Todo:
@@ -54,22 +74,40 @@
struct template *template_new(const char *tag)
{
+ struct template_l10n_fields *f = NEW(struct template_l10n_fields);
struct template *t = NEW(struct template);
+ memset(f, 0, sizeof(struct template_l10n_fields));
+ f->language = STRDUP("C");
memset(t, 0, sizeof(struct template));
t->ref = 1;
t->tag = STRDUP(tag);
+ t->get = template_get;
+ t->set = template_set;
+ t->lget = template_lget;
+ t->lset = template_lset;
+ t->next_lang = template_next_lang;
+ t->fields = f;
return t;
}
void template_delete(struct template *t)
{
+ struct template_l10n_fields *p, *q;
+
DELETE(t->tag);
DELETE(t->type);
- DELETE(t->defaultval);
- DELETE(t->choices);
- DELETE(t->description);
- DELETE(t->extended_description);
+ p = t->fields;
DELETE(t);
+ while (p != NULL)
+ {
+ q = p->next;
+ DELETE(p->defaultval);
+ DELETE(p->choices);
+ DELETE(p->description);
+ DELETE(p->extended_description);
+ DELETE(p);
+ p = q;
+ }
}
void template_ref(struct template *t)
@@ -89,23 +127,251 @@
* Output: a copy of the template passed as input
* Description: duplicate a template
* Assumptions: template_new succeeds, STRDUP succeeds.
- * Todo: Handle localization
*/
struct template *template_dup(struct template *t)
{
struct template *ret = template_new(t->tag);
+ struct template_l10n_fields *from, *to;
+
ret->type = STRDUP(t->type);
- ret->defaultval = STRDUP(t->defaultval);
- ret->choices = STRDUP(t->choices);
- ret->description = STRDUP(t->description);
- ret->extended_description = STRDUP(t->extended_description);
+ if (t->fields == NULL)
+ return ret;
+
+ ret->fields = NEW(struct template_l10n_fields);
+
+ from = t->fields;
+ to = ret->fields;
+ /* Iterate over available languages */
+ while (1)
+ {
+ to->defaultval = STRDUP(from->defaultval);
+ to->choices = STRDUP(from->choices);
+ to->description = STRDUP(from->description);
+ to->extended_description = STRDUP(from->extended_description);
+
+ if (from->next == NULL)
+ {
+ to->next = NULL;
+ break;
+ }
+ to->next = NEW(struct template_l10n_fields);
+ from = from->next;
+ to = to->next;
+ }
+ return ret;
+}
+
+static const char *template_field_get(struct template_l10n_fields *p,
+ const char *field)
+{
+ if (strcasecmp(field, "default") == 0)
+ return p->defaultval;
+ else if (strcasecmp(field, "choices") == 0)
+ return p->choices;
+ else if (strcasecmp(field, "description") == 0)
+ return p->description;
+ else if (strcasecmp(field, "extended_description") == 0)
+ return p->extended_description;
+ return NULL;
+}
+
+static void template_field_set(struct template_l10n_fields *p,
+ const char *field, const char *value)
+{
+ if (strcasecmp(field, "default") == 0)
+ {
+ DELETE(p->defaultval);
+ p->defaultval = STRDUP(value);
+ }
+ else if (strcasecmp(field, "choices") == 0)
+ {
+ DELETE(p->choices);
+ p->choices = STRDUP(value);
+ }
+ else if (strcasecmp(field, "description") == 0)
+ {
+ DELETE(p->description);
+ p->description = STRDUP(value);
+ }
+ else if (strcasecmp(field, "extended_description") == 0)
+ {
+ DELETE(p->extended_description);
+ p->extended_description = STRDUP(value);
+ }
+}
+
+/*
+ * Function: template_get
+ * Input: a template
+ * Input: a language name
+ * Input: a field name
+ * Output: the value of the given field in the given language, field
+ * name may be any of type, default, choices, description and
+ * extended_description
+ * Description: get field value
+ * Assumptions:
+ */
+
+static const char *template_lget(struct template *t, const char *lang,
+ const char *field)
+{
+ struct template_l10n_fields *p;
+ const char *ret = NULL, *altret = NULL;
+
+ if (strcmp(lang, "C") == 0 && strcasecmp(field, "tag") == 0)
+ return t->tag;
+ else if (strcmp(lang, "C") == 0 && strcasecmp(field, "type") == 0)
+ return t->type;
+
+ p = t->fields;
+ while (p != NULL)
+ {
+ /* Exact match */
+ if (strcmp(p->language, lang) == 0)
+ return template_field_get(p, field);
+
+ /* Language is xx_XX and a xx field is found */
+ if (strlen(p->language) == 2 && strncmp(lang, p->language, 2) == 0)
+ altret = template_field_get(p, field);
+
+ p = p->next;
+ }
+ if (altret != NULL)
+ return altret;
+ if (ret)
return ret;
+ /* Default value */
+ return template_field_get(t->fields, field);
+}
+
+static const char *template_get(struct template *t, const char *field)
+{
+ char *orig_field;
+ char *lang;
+ char *p;
+ const char *ret = NULL;
+
+ p = strchr(field, '-');
+ if (p == NULL)
+ return template_lget(t, "C", field);
+
+ orig_field = strdup(field);
+ lang = strchr(orig_field, '-');
+ *lang = 0;
+ lang++;
+ if (strstr(lang, ".UTF-8") == lang + 2)
+ {
+ *(lang+2) = 0;
+ ret = template_lget(t, lang, orig_field);
+ }
+ else if (strstr(lang, ".UTF-8") == lang + 5)
+ {
+ *(lang+5) = 0;
+ ret = template_lget(t, lang, orig_field);
+ }
+#ifndef NODEBUG
+ else
+ fprintf(stderr, "Unknown localized field:\n%s\n", p);
+#endif
+ free(orig_field);
+ return ret;
+}
+
+static void template_lset(struct template *t, const char *lang,
+ const char *field, const char *value)
+{
+ struct template_l10n_fields *p, *last;
+
+ if (strcmp(lang, "C") == 0 && strcasecmp(field, "tag") == 0)
+ {
+ t->tag = STRDUP(value);
+ return;
+ }
+ else if (strcmp(lang, "C") == 0 && strcasecmp(field, "type") == 0)
+ {
+ t->type = STRDUP(value);
+ return;
+ }
+
+ p = t->fields;
+ last = p;
+ while (p != NULL)
+ {
+ if (strcmp(p->language, lang) == 0)
+ {
+ template_field_set(p, field, value);
+ return;
+ }
+ last = p;
+ p = p->next;
+ }
+ p = NEW(struct template_l10n_fields);
+ memset(p, 0, sizeof(struct template_l10n_fields));
+ p->language = STRDUP(lang);
+ last->next = p;
+ template_field_set(p, field, value);
+}
+
+static void template_set(struct template *t, const char *field,
+ const char *value)
+{
+ char *orig_field;
+ char *lang;
+ char *p;
+
+ p = strchr(field, '-');
+ if (p == NULL)
+ template_lset(t, "C", field, value);
+ else
+ {
+ orig_field = strdup(field);
+ lang = strchr(orig_field, '-');
+ *lang = 0;
+ lang++;
+ if (strstr(lang, ".UTF-8") == lang + 2)
+ {
+ *(lang+2) = 0;
+ template_lset(t, lang, orig_field, value);
+ }
+ else if (strstr(lang, ".UTF-8") == lang + 5)
+ {
+ *(lang+5) = 0;
+ template_lset(t, lang, orig_field, value);
+ }
+#ifndef NODEBUG
+ else
+ fprintf(stderr, "Unknown localized field:\n%s\n", p);
+#endif
+ free(orig_field);
+ }
+}
+
+static const char *template_next_lang(struct template *t, const char *lang)
+{
+ struct template_l10n_fields *p;
+
+ if (lang == NULL)
+ return NULL;
+
+ p = t->fields;
+ while (p != NULL)
+ {
+ if (strcmp(p->language, lang) == 0)
+ {
+ if (p->next == NULL)
+ return NULL;
+ return p->next->language;
+ }
+ p = p->next;
+ }
+ return NULL;
}
struct template *template_load(const char *filename)
{
char buf[2048], extdesc[8192];
+ char lang[6];
char *p, *bufp;
FILE *fp;
struct template *tlist = NULL, *t = 0;
@@ -130,55 +396,36 @@
t = template_new(p+10);
}
else if (strstr(p, "Type: ") == p && t != 0)
- t->type = strdup(p+6);
+ template_set(t, "type", p+6);
else if (strstr(p, "Default: ") == p && t != 0)
- t->defaultval = strdup(p+9);
+ template_set(t, "default", p+9);
else if (strstr(p, "Choices: ") == p && t != 0)
- t->choices = strdup(p+9);
+ template_set(t, "choices", p+9);
else if (strstr(p, "Choices-") == p && t != 0)
{
- struct language_description *langdesc = malloc(sizeof(struct language_description));
- struct language_description *lng_tmp = 0;
- memset(langdesc,0,sizeof(struct language_description));
- /* We assume that the language codes are
- always 2 characters long, */
-
- langdesc->language = malloc(3);
- snprintf(langdesc->language,3,"%.2s",p+8);
-
- langdesc->choices = strdup(p+11);
-
- if (t->localized_descriptions == NULL)
+ if (strstr(p, ".UTF-8: ") == p + 10)
+ {
+ strncpy(lang, p+8, 2);
+ lang[2] = 0;
+ template_lset(t, lang, "choices", p+18);
+ }
+ else if (strstr(p, ".UTF-8: ") == p + 13)
{
- t->localized_descriptions = langdesc;
+ strncpy(lang, p+8, 5);
+ lang[5] = 0;
+ template_lset(t, lang, "choices", p+21);
}
else
{
- lng_tmp = t->localized_descriptions;
- while (lng_tmp != NULL)
- {
- if (strcmp(lng_tmp->language,langdesc->language) == 0)
- {
- if (lng_tmp->choices)
- free(lng_tmp->choices);
- lng_tmp->choices = langdesc->choices;
- free(langdesc->language);
- free(langdesc);
- langdesc = NULL;
- break;
- }
- lng_tmp = lng_tmp->next;
- }
- if (langdesc != NULL)
- {
- langdesc->next = t->localized_descriptions;
- t->localized_descriptions = langdesc;
- }
+#ifndef NODEBUG
+ fprintf(stderr, "Unknown localized field:\n%s\n", p);
+#endif
+ continue;
}
}
else if (strstr(p, "Description: ") == p && t != 0)
{
- t->description = strdup(p+13);
+ template_set(t, "description", p+13);
extdesc[0] = 0;
i = fgetc(fp);
/* Don't use fgets unless you _need_ to, a
@@ -219,22 +466,31 @@
*bufp = ' ';
}
- t->extended_description = strdup(extdesc);
+ template_set(t, "extended_description", extdesc);
}
}
else if (strstr(p, "Description-") == p && t != 0)
{
- struct language_description *langdesc = malloc(sizeof(struct language_description));
- struct language_description *lng_tmp = 0;
- memset(langdesc,0,sizeof(struct language_description));
-
- /* We assume that the language codes are
- always 2 characters long, */
-
- langdesc->language = malloc(3);
- snprintf(langdesc->language,3,"%.2s",p+12);
- langdesc->description = strdup(p+16);
-
+ if (strstr(p, ".UTF-8: ") == p + 14)
+ {
+ strncpy(lang, p+12, 2);
+ lang[2] = 0;
+ template_lset(t, lang, "description", p+22);
+ }
+ else if (strstr(p, ".UTF-8: ") == p + 17)
+ {
+ strncpy(lang, p+12, 5);
+ lang[5] = 0;
+ template_lset(t, lang, "description", p+25);
+ }
+ else
+ {
+#ifndef NODEBUG
+ fprintf(stderr, "Unknown localized field:\n%s\n", p);
+#endif
+ /* Skip extended description */
+ lang[0] = 0;
+ }
extdesc[0] = 0;
i = fgetc(fp);
/* Don't use fgets unless you _need_ to, a
@@ -273,37 +529,8 @@
*bufp = ' ';
}
- langdesc->extended_description = strdup(extdesc);
- }
- if (t->localized_descriptions == NULL)
- {
- t->localized_descriptions = langdesc;
- }
- else
- {
- lng_tmp = t->localized_descriptions;
- while (lng_tmp != NULL)
- {
- if (strcmp(lng_tmp->language,langdesc->language) == 0)
- {
- if (lng_tmp->description != NULL)
- free(lng_tmp->description);
- if (lng_tmp->extended_description != NULL)
- free(lng_tmp->extended_description);
- lng_tmp->description = langdesc->description;
- lng_tmp->extended_description = langdesc->extended_description;
- free(langdesc->language);
- free(langdesc);
- langdesc = NULL;
- break;
- }
- lng_tmp = lng_tmp->next;
- }
- if (langdesc != NULL)
- {
- langdesc->next = t->localized_descriptions;
- t->localized_descriptions = langdesc;
- }
+ if (lang[0] != 0)
+ template_lset(t, lang, "extended_description", extdesc);
}
}
}
Index: src/template.h
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/src/template.h,v
retrieving revision 1.3
diff -u -r1.3 template.h
--- src/template.h 12 Aug 2002 13:38:34 -0000 1.3
+++ src/template.h 9 Nov 2002 01:21:19 -0000
@@ -1,13 +1,14 @@
#ifndef _TEMPLATE_H_
#define _TEMPLATE_H_
-struct language_description
+struct template_l10n_fields
{
char *language;
+ char *defaultval;
+ char *choices;
char *description;
char *extended_description;
- char *choices;
- struct language_description *next;
+ struct template_l10n_fields *next;
};
struct template
@@ -15,13 +16,17 @@
char *tag;
unsigned int ref;
char *type;
- char *defaultval;
- char *choices;
- char *description;
- char *extended_description;
- struct language_description *localized_descriptions;
+ struct template_l10n_fields *fields;
struct template *next;
+ const char *(*lget)(struct template *, const char *l, const char *f);
+ const char *(*get)(struct template *, const char *f);
+ void (*lset)(struct template *, const char *l, const char *f,
+ const char *v);
+ void (*set)(struct template *, const char *f, const char *v);
+ const char *(*next_lang)(struct template *, const char *l);
};
+
+extern const char *template_fields_list[];
struct template *template_new(const char *tag);
void template_delete(struct template *t);
Index: src/modules/db/rfc822db/rfc822db.c
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/src/modules/db/rfc822db/rfc822db.c,v
retrieving revision 1.9
diff -u -r1.9 rfc822db.c
--- src/modules/db/rfc822db/rfc822db.c 3 Nov 2002 14:58:19 -0000 1.9
+++ src/modules/db/rfc822db/rfc822db.c 9 Nov 2002 01:21:19 -0000
@@ -239,7 +239,6 @@
* Output: DC_OK/DC_NOTOK
* Description: parse a template db file and put it into the cache
* Assumptions: the file is in valid rfc822 format
- * TODO: handle localized templates
*/
static int rfc822db_template_load(struct template_db *db)
{
@@ -262,8 +261,7 @@
{
struct template *tmp;
const char *name;
- char tbuf[1024];
- memset(&tbuf,0,1024);
+ struct rfc822_header *h;
name = rfc822db_header_lookup(header, "name");
if (name == NULL)
@@ -274,13 +272,10 @@
}
tmp = template_new(name);
+ for (h = header; h != NULL; h = h->next)
+ if (strcmp(h->header, "Name") != 0)
+ tmp->set(tmp, h->header, h->value);
- tmp->type = rfc822db_header_lookup(header, "type");
- tmp->defaultval = rfc822db_header_lookup(header, "default");
- tmp->choices = rfc822db_header_lookup(header, "choices");
- tmp->description = rfc822db_header_lookup(header, "description");
- tmp->extended_description = rfc822db_header_lookup(header, "extended_description");
-/* struct language_description *localized_descriptions; */
tmp->next = NULL;
tsearch(tmp, &dbdata->root, nodetemplatecomp);
}
@@ -292,52 +287,54 @@
void rfc822db_template_dump(const void *node, const VISIT which, const int depth)
{
- struct language_description *langdesc;
- const struct template *t = (*(struct template **) node);
- switch (which) {
- case preorder:
- break;
- case endorder:
- break;
- case postorder:
- case leaf:
- INFO(INFO_VERBOSE, "dumping template %s\n", (t)->tag);
-
- fprintf(outf, "Name: %s\n", escapestr((t)->tag));
- fprintf(outf, "Type: %s\n", escapestr((t)->type));
- if ((t)->defaultval != NULL)
- fprintf(outf, "Default: %s\n", escapestr((t)->defaultval));
- if ((t)->choices != NULL)
- fprintf(outf, "Choices: %s\n", escapestr((t)->choices));
- if ((t)->description != NULL)
- fprintf(outf, "Description: %s\n", escapestr((t)->description));
- if ((t)->extended_description != NULL)
- fprintf(outf, "Extended_description: %s\n", escapestr((t)->extended_description));
-
- langdesc = (t)->localized_descriptions;
- while (langdesc)
+ const char *p, *lang;
+ const char **field;
+ const struct template *t = (*(struct template **) node);
+
+ switch (which) {
+ case preorder:
+ break;
+ case endorder:
+ break;
+ case postorder:
+ case leaf:
+ p = t->get((struct template *) t, "tag");
+ INFO(INFO_VERBOSE, "dumping template %s\n", p);
+
+ for (field = template_fields_list; *field != NULL; field++)
{
- if (langdesc->description != NULL)
- fprintf(outf, "Description-%s: %s\n",
- langdesc->language,
- escapestr(langdesc->description));
-
- if (langdesc->extended_description != NULL)
- fprintf(outf, "Extended_description-%s: %s\n",
- langdesc->language,
- escapestr(langdesc->extended_description));
-
- if (langdesc->choices != NULL)
- fprintf(outf, "Choices-%s: %s\n",
- langdesc->language,
- escapestr(langdesc->choices));
-
- langdesc = langdesc->next;
+ p = t->get((struct template *) t, *field);
+ if (p != NULL)
+ {
+ if (strcmp(*field, "tag") == 0)
+ fprintf(outf, "Name: %s\n", escapestr(p));
+ else
+ fprintf(outf, "%c%s: %s\n",
+ toupper((*field)[0]),
+ (*field)+1, escapestr(p));
+ }
+ }
+
+ lang = t->next_lang((struct template *) t, "C");
+ while (lang)
+ {
+ for (field = template_fields_list; *field != NULL; field++)
+ {
+ p = t->lget((struct template *) t, lang, *field);
+ if (p != NULL)
+ {
+ if (strcmp(*field, "tag") != 0)
+ fprintf(outf, "%c%s-%s.UTF-8: %s\n",
+ toupper((*field)[0]), (*field)+1,
+ lang, escapestr(p));
+ }
+ }
+ lang = t->next_lang((struct template *) t, lang);
}
fprintf(outf, "\n");
- }
-
+ }
}
+
static int rfc822db_template_save(struct template_db *db)
{
struct template_db_cache *dbdata = db->data;
@@ -596,7 +593,7 @@
struct question *q, q2;
memset(&q2, 0, sizeof (struct question));
- q2.tag = ltag;
+ q2.tag = (char *) ltag;
q = tfind(&q2, &dbdata->root, nodequestioncomp);
if (q != NULL)
{
Index: src/modules/db/textdb/textdb.c
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/src/modules/db/textdb/textdb.c,v
retrieving revision 1.5
diff -u -r1.5 textdb.c
--- src/modules/db/textdb/textdb.c 30 Jul 2002 05:55:27 -0000 1.5
+++ src/modules/db/textdb/textdb.c 9 Nov 2002 01:21:19 -0000
@@ -135,38 +135,35 @@
{
FILE *outf;
char *filename;
- struct language_description *langdesc;
+ const char *p, *lang;
+ const char **field;
- if (t->tag == NULL) return DC_NOTOK;
- filename = template_filename(db, t->tag);
+ if (t->get(t, "tag") == NULL) return DC_NOTOK;
+ filename = template_filename(db, t->get(t, "tag"));
if ((outf = fopen(filename, "w")) == NULL)
return DC_NOTOK;
fprintf(outf, "template {\n");
- fprintf(outf, "\ttag \"%s\";\n", escapestr(t->tag));
- fprintf(outf, "\ttype \"%s\";\n", escapestr(t->type));
- if (t->defaultval != NULL)
- fprintf(outf, "\tdefault \"%s\";\n", escapestr(t->defaultval));
- if (t->choices != NULL)
- fprintf(outf, "\tchoices \"%s\";\n", escapestr(t->choices));
- if (t->description != NULL)
- fprintf(outf, "\tdescription \"%s\";\n", escapestr(t->description));
- if (t->extended_description != NULL)
- fprintf(outf, "\textended_description \"%s\";\n", escapestr(t->extended_description));
-
- langdesc = t->localized_descriptions;
- while (langdesc)
+ for (field = template_fields_list; *field != NULL; field++)
{
- if (langdesc->description != NULL)
- fprintf(outf, "\tdescription-%s \"%s\";\n", langdesc->language, escapestr(langdesc->description));
- if (langdesc->extended_description != NULL)
- fprintf(outf, "\textended_description-%s \"%s\";\n", langdesc->language, escapestr(langdesc->extended_description));
- if (langdesc->choices != NULL)
- fprintf(outf, "\tchoices-%s \"%s\";\n", langdesc->language, escapestr(langdesc->choices));
+ p = t->get(t, *field);
+ if (p != NULL)
+ fprintf(outf, "\t%s \"%s\";\n", *field, escapestr(p));
+ }
- langdesc = langdesc->next;
+ lang = t->next_lang(t, "C");
+ while (lang)
+ {
+ for (field = template_fields_list; *field != NULL; field++)
+ {
+ p = t->lget(t, lang, *field);
+ if (p != NULL)
+ fprintf(outf, "\t%s-%s \"%s\";\n", *field,
+ lang, escapestr(p));
+ }
+ lang = t->next_lang(t, lang);
}
fprintf(outf, "};\n");
@@ -204,16 +201,17 @@
}
else
{
- t->type = STRDUP(unescapestr(rec->get(rec, "template::type", "string")));
- t->defaultval = STRDUP(unescapestr(rec->get(rec, "template::default", 0)));
- t->choices = STRDUP(unescapestr(rec->get(rec, "template::choices", 0)));
- t->description = STRDUP(unescapestr(rec->get(rec, "template::description", 0)));
- t->extended_description = STRDUP(unescapestr(rec->get(rec, "template::extended_description", 0)));
+ t->set(t, "type", STRDUP(unescapestr(rec->get(rec, "template::type", "string"))));
+ t->set(t, "default", STRDUP(unescapestr(rec->get(rec, "template::default", 0))));
+ t->set(t, "choices", STRDUP(unescapestr(rec->get(rec, "template::choices", 0))));
+ t->set(t, "description", STRDUP(unescapestr(rec->get(rec, "template::description", 0))));
+ t->set(t, "extended_description", STRDUP(unescapestr(rec->get(rec, "template::extended_description", 0))));
/* We can't ask for all the localized descriptions so we need to
* brute-force this.
* This is stupid and ugly and should be fixed, FIXME
*/
+#if 0
for (a = 'a'; a <= 'z'; a++)
for (b = 'a'; b <= 'z'; b++)
{
@@ -239,6 +237,7 @@
t->localized_descriptions = langdesc;
}
}
+#endif
}
Index: src/modules/frontend/bogl/bogl.c
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/src/modules/frontend/bogl/bogl.c,v
retrieving revision 1.4
diff -u -r1.4 bogl.c
--- src/modules/frontend/bogl/bogl.c 2 Jul 2002 06:53:47 -0000 1.4
+++ src/modules/frontend/bogl/bogl.c 9 Nov 2002 01:21:19 -0000
@@ -58,12 +58,12 @@
static void drawdesctop(struct frontend *ui, struct question *q)
{
bowl_title(ui->title);
- bowl_new_text(question_description(q));
+ bowl_new_text(question_get_translated_field(q, "description"));
}
static void drawdescbot(struct frontend *ui, struct question *q)
{
- bowl_new_text(question_extended_description(q));
+ bowl_new_text(question_get_translated_field(q, "extended_description"));
}
/* boolean requires a new widget, the radio button :( */
@@ -71,7 +71,7 @@
int bogl_handler_boolean(struct frontend *ui, struct question *q)
{
/* Should just make bowl_new_checkbox be properly const-qualified. */
- char *desc = strdup(question_description(q));
+ char *desc = strdup(question_get_translated_field(q, "description"));
int ret;
#if 0
@@ -120,40 +120,50 @@
int bogl_handler_multiselect(struct frontend *ui, struct question *q)
{
- int nchoices, ndefs, ret, i, j;
+ char **choices, **choices_translated, **defaults, *selected;
+ int i, j, count, dcount, ret;
const char *p;
- char **choices, **defaults, *selected;
-
- nchoices = 1;
- for(p = question_choices(q); *p; p++)
- if(*p == ',')
- nchoices++;
- choices = malloc(sizeof(char *) * nchoices);
- nchoices = strchoicesplit(question_choices(q), choices, nchoices);
- selected = malloc(sizeof(char) * nchoices);
- memset(selected, ' ', nchoices);
- ndefs = 1;
- for(p = question_defaultval(q); *p; p++)
+ count = 0;
+ p = question_get_field(q, "choices");
+ if (*p)
+ {
+ count++;
+ for(; *p; p++)
+ if(*p == ',')
+ count++;
+ }
+
+ if (count <= 0) return DC_NOTOK;
+
+ choices = malloc(sizeof(char *) * count);
+ strchoicesplit(question_get_field(q, "choices"), choices, count);
+ choices_translated = malloc(sizeof(char *) * count);
+ strchoicesplit(question_get_field(q, "choices"), choices_translated, count);
+ selected = malloc(sizeof(char) * count);
+ memset(selected, ' ', count);
+
+ dcount = 1;
+ for(p = question_get_field(q, "default"); *p; p++)
if(*p == ',')
- ndefs++;
- defaults = malloc(sizeof(char *) * ndefs);
- ndefs = strchoicesplit(question_defaultval(q), defaults, ndefs);
- for(i = 0; i < ndefs; i++)
+ dcount++;
+ defaults = malloc(sizeof(char *) * dcount);
+ dcount = strchoicesplit(question_get_field(q, "default"), defaults, dcount);
+ for(j = 0; j < dcount; j++)
{
- for(j = 0; j < nchoices; j++)
- if(strcmp(choices[j], defaults[i]) == 0)
+ for(i = 0; i < count; i++)
+ if(strcmp(choices[i], defaults[j]) == 0)
{
- selected[j] = '*';
+ selected[i] = '*';
break;
}
- free(defaults[i]);
+ free(defaults[j]);
}
free(defaults);
bowl_flush();
drawdesctop(ui, q);
- bowl_new_checkbox(choices, selected, nchoices, (nchoices > 15) ? 15 : nchoices);
+ bowl_new_checkbox(choices, selected, count, (count > 15) ? 15 : count);
drawnavbuttons(ui, q);
drawdescbot(ui, q);
@@ -163,19 +173,19 @@
if(ret == DC_OK)
{
/* Be safe - allow for commas and spaces. */
- char *answer = malloc(strlen(question_choices(q)) + 1 + nchoices);
+ char *answer = malloc(strlen(question_get_translated_field(q, "choices")) + 1 + count);
answer[0] = 0;
- for(i = 0; i < nchoices; i++)
+ for(i = 0; i < count; i++)
if (selected[i] == '*')
{
if(answer[0] != 0)
strcat(answer, ", ");
- strcat(answer, choices[i]);
+ strcat(answer, choices_translated[i]);
}
question_setvalue(q, answer);
}
- for(i = 0; i < nchoices; i++)
+ for(i = 0; i < count; i++)
free(choices[i]);
free(choices);
@@ -189,7 +199,7 @@
bowl_flush();
drawdesctop(ui, q);
- bowl_new_input(&s, question_defaultval(q));
+ bowl_new_input(&s, question_get_field(q, "default"));
drawnavbuttons(ui, q);
drawdescbot(ui, q);
bowl_layout();
Index: src/modules/frontend/ncurses/ncurses.c
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/src/modules/frontend/ncurses/ncurses.c,v
retrieving revision 1.9
diff -u -r1.9 ncurses.c
--- src/modules/frontend/ncurses/ncurses.c 9 Jul 2002 05:25:04 -0000 1.9
+++ src/modules/frontend/ncurses/ncurses.c 9 Nov 2002 01:21:19 -0000
@@ -223,8 +223,8 @@
WINDOW *descwin = UIDATA(ui)->descwin;
drawframe(ui, WIN_QUERY, ui->title);
- wrapprint(qrywin, question_description(q), 0, COLS-2);
- wrapprint(descwin, question_extended_description(q), 0, COLS-2);
+ wrapprint(qrywin, question_get_translated_field(q, "description"), 0, COLS-2);
+ wrapprint(descwin, question_get_translated_field(q, "extended_description"), 0, COLS-2);
wclrtobot(qrywin);
wclrtobot(descwin);
wrefresh(stdscr);
@@ -237,12 +237,17 @@
char *value = "true";
int ret = 0, ans, pos = 2;
int ybut = UIDATA(ui)->qrylines - 6;
+ char *dft;
WINDOW *win = UIDATA(ui)->qrywin;
if (q->value != 0 && *q->value != 0)
value = q->value;
- else if (q->template->defaultval != 0 && *q->template->defaultval != 0)
- value = q->template->defaultval;
+ else
+ {
+ dft = (char *) q->template->get(q->template, "default");
+ if (dft != 0 && *dft != 0)
+ value = dft;
+ }
ans = (strcmp(value, "true") == 0);
@@ -351,29 +356,33 @@
static int nchandler_select(struct frontend *ui, struct question *q)
{
- char *value = NULL;
char *choices[100] = {0};
- int i, count, ret = 0, val = 0, pos = 2, xpos, ypos;
+ char *choices_translated[100] = {0};
+ char *defaults[100] = {0};
+ const char *defval = question_get_field(q, "default");
+
+ int i, count, dcount, ret = 0, def = -1, pos = 2, xpos, ypos;
int top, bottom, longest;
WINDOW *win = UIDATA(ui)->qrywin;
/* Parse out all the choices */
- count = strchoicesplit((char *)question_choices(q), choices, DIM(choices));
+ count = strchoicesplit(question_get_field(q, "choices"), choices, DIM(choices));
if (count <= 0) return DC_NOTOK;
+ strchoicesplit(question_get_translated_field(q, "choices"), choices_translated, DIM(choices_translated));
+ dcount = strchoicesplit(question_get_field(q, "default"), defaults, DIM(defaults));
+
/* See what the currently selected value should be -- either a
* previously selected value, or the default for the question
*/
- if ((q->value != 0 && *q->value != 0 && (value = q->value)) ||
- (q->template->defaultval != 0 && *q->template->defaultval != 0 &&
- (value = q->template->defaultval)))
+ if (defval != NULL)
{
for (i = 0; i < count; i++)
- if (strcmp(choices[i], value) == 0)
- val = i;
+ if (strcmp(choices[i], defval) == 0)
+ def = i + 1;
}
- longest = longestlen(choices, count);
+ longest = longestlen(choices_translated, count);
top = 0; bottom = MIN(count, UIDATA(ui)->qrylines-5);
xpos = (COLS-longest)/2-1;
@@ -382,11 +391,11 @@
ypos = 2;
for (i = top; i < bottom; i++)
{
- if (pos == 2 && i == val)
+ if (pos == 2 && i == def)
wstandout(win);
else
wstandend(win);
- mvwprintw(win, ypos++, xpos, " %-*s ", longest, choices[i]);
+ mvwprintw(win, ypos++, xpos, " %-*s ", longest, choices_translated[i]);
}
wstandend(win);
@@ -398,17 +407,17 @@
{
case KEY_LEFT:
case KEY_UP:
- val--;
- if (val < 0) val = count-1;
+ def--;
+ if (def < 0) def = count-1;
- /* check val against top/bottom */
+ /* check def against top/bottom */
break;
case KEY_RIGHT:
case KEY_DOWN:
- val++;
- if (val >= count) val = 0;
+ def++;
+ if (def >= count) def = 0;
- /* check val against top/bottom */
+ /* check def against top/bottom */
break;
case 9: /* TAB */
pos++;
@@ -432,7 +441,7 @@
}
}
if (ret == DC_OK)
- question_setvalue(q, choices[val]);
+ question_setvalue(q, choices[def]);
return ret;
}
Index: src/modules/frontend/slang/slang.c
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/src/modules/frontend/slang/slang.c,v
retrieving revision 1.11
diff -u -r1.11 slang.c
--- src/modules/frontend/slang/slang.c 9 Jul 2002 05:25:04 -0000 1.11
+++ src/modules/frontend/slang/slang.c 9 Nov 2002 01:21:20 -0000
@@ -197,8 +197,8 @@
slang_drawwin(&uid->qrywin);
slang_drawwin(&uid->descwin);
/* Draw in the descriptions */
- slang_wrapprint(&uid->qrywin, question_description(q), 0);
- slang_wrapprint(&uid->descwin, question_extended_description(q),
+ slang_wrapprint(&uid->qrywin, question_get_translated_field(q, "description"), 0);
+ slang_wrapprint(&uid->descwin, question_get_translated_field(q, "extended_description"),
uid->descstart);
/* caller should call slang_flush() ! */
@@ -319,7 +319,7 @@
const char *value = "true";
int ret = 0, ans, pos = 2;
- value = question_defaultval(q);
+ value = question_get_field(q, "default");
ans = (strcmp(value, "true") == 0);
@@ -373,6 +373,7 @@
static int slang_getselect(struct frontend *ui, struct question *q, int multi)
{
char *choices[100] = {0};
+ char *choices_translated[100] = {0};
char *defaults[100] = {0};
char selected[100] = {0};
char answer[1024] = {0};
@@ -382,8 +383,9 @@
struct slwindow *win = &uid->qrywin;
/* Parse out all the choices */
- count = strchoicesplit(question_choices(q), choices, DIM(choices));
- dcount = strchoicesplit(question_defaultval(q), defaults, DIM(defaults));
+ count = strchoicesplit(question_get_field(q, "choices"), choices, DIM(choices));
+ strchoicesplit(question_get_translated_field(q, "choices"), choices_translated, DIM(choices_translated));
+ dcount = strchoicesplit(question_get_field(q, "default"), defaults, DIM(defaults));
INFO(INFO_VERBOSE, "Parsed out %d choices, %d defaults\n", count, dcount);
if (count <= 0) return DC_NOTOK;
@@ -391,11 +393,9 @@
* previously selected value, or the default for the question
*/
for (j = 0; j < dcount; j++)
- {
for (i = 0; i < count; i++)
if (strcmp(choices[i], defaults[j]) == 0)
selected[i] = 1;
- }
longest = strlongest(choices, count);
top = 0;
@@ -414,10 +414,10 @@
slang_printf(ypos++, xpos, ((pos == 2 && i == val) ?
win->selectedcolor : win->drawcolor),
"(%c) %-*s ", (selected[i] ? '*' : ' '),
- longest, choices[i]);
+ longest, choices_translated[i]);
INFO(INFO_VERBOSE, "(%c) %-*s\n", (selected[i] ? '*' :
- ' '), longest, choices[i]);
+ ' '), longest, choices_translated[i]);
}
slang_navbuttons(ui, q, pos);
@@ -454,7 +454,7 @@
case 0: ret = DC_GOBACK; break;
case 1: ret = DC_OK; break;
default:
- if (multi == 0)
+ if (multi == 1)
{
memset(selected, 0, sizeof(selected));
selected[val] = 1;
@@ -477,10 +477,12 @@
strvacat(answer, sizeof(answer), choices[i], NULL);
}
free(choices[i]);
+ free(choices_translated[i]);
}
for (i = 0; i < dcount; i++)
free(defaults[i]);
question_setvalue(q, answer);
+
return DC_OK;
}
@@ -505,7 +507,7 @@
int cursor;
char *tmp;
- STRCPY(value, question_defaultval(q));
+ STRCPY(value, question_get_field(q, "default"));
cursor = strlen(value);
/* TODO: scrolling */
Index: src/modules/frontend/text/text.c
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/src/modules/frontend/text/text.c,v
retrieving revision 1.15
diff -u -r1.15 text.c
--- src/modules/frontend/text/text.c 5 Nov 2002 03:01:51 -0000 1.15
+++ src/modules/frontend/text/text.c 9 Nov 2002 01:21:20 -0000
@@ -119,8 +119,8 @@
*/
static void texthandler_displaydesc(struct frontend *obj, struct question *q)
{
- wrap_print(question_description(q));
- wrap_print(question_extended_description(q));
+ wrap_print(question_get_translated_field(q, "description"));
+ wrap_print(question_get_translated_field(q, "extended_description"));
}
/*
@@ -138,7 +138,7 @@
int def = -1;
const char *defval;
- defval = question_defaultval(q);
+ defval = question_get_field(q, "default");
if (defval)
{
if (strcmp(defval, "true") == 0)
@@ -180,25 +180,28 @@
static int texthandler_multiselect(struct frontend *obj, struct question *q)
{
char *choices[100] = {0};
+ char *choices_translated[100] = {0};
char *defaults[100] = {0};
char selected[100] = {0};
- char answer[1024];
+ char answer[1024] = {0};
int i, j, count, dcount, choice;
- count = strchoicesplit(question_choices(q), choices, DIM(choices));
- dcount = strchoicesplit(question_defaultval(q), defaults, DIM(defaults));
+ count = strchoicesplit(question_get_field(q, "choices"), choices, DIM(choices));
+ if (count <= 0) return DC_NOTOK;
+
+ strchoicesplit(question_get_translated_field(q, "choices"), choices_translated, DIM(choices_translated));
+ dcount = strchoicesplit(question_get_field(q, "default"), defaults, DIM(defaults));
- if (dcount > 0)
+ for (j = 0; j < dcount; j++)
for (i = 0; i < count; i++)
- for (j = 0; j < dcount; j++)
- if (strcmp(choices[i], defaults[j]) == 0)
- selected[i] = 1;
+ if (strcmp(choices[i], defaults[j]) == 0)
+ selected[i] = 1;
while(1)
{
for (i = 0; i < count; i++)
{
- printf("%3d. %s%s\n", i+1, choices[i],
+ printf("%3d. %s%s\n", i+1, choices_translated[i],
(selected[i] ? _(" (selected)") : ""));
}
@@ -217,7 +220,6 @@
}
}
- answer[0] = 0;
for (i = 0; i < count; i++)
{
if (selected[i])
@@ -227,6 +229,7 @@
strvacat(answer, sizeof(answer), choices[i], NULL);
}
free(choices[i]);
+ free(choices_translated[i]);
}
for (i = 0; i < dcount; i++)
free(defaults[i]);
@@ -301,34 +304,33 @@
char *choices_translated[100] = {0};
char answer[10];
int i, count, choice = 1, def = -1;
- const char *defval = question_defaultval(q);
+ const char *defval = question_get_field(q, "default");
+
+ count = strchoicesplit(question_get_field(q, "choices"), choices, DIM(choices));
+ if (count <= 0) return DC_NOTOK;
- count = strchoicesplit(question_choices(q), choices, DIM(choices));
- strchoicesplit(question_choices_translated(q), choices_translated, DIM(choices_translated));
+ strchoicesplit(question_get_translated_field(q, "choices"), choices_translated, DIM(choices_translated));
/* fprintf(stderr,"In texthandler_select, count is: %d\n", count);*/
- if (count > 1)
+ if (defval != NULL)
{
- if (defval != NULL)
- {
- for (i = 0; i < count; i++)
- if (strcmp(choices[i], defval) == 0)
- def = i + 1;
- }
-
- do
- {
- for (i = 0; i < count; i++)
- printf("%3d. %s%s\n", i+1, choices_translated[i],
- (def == i + 1 ? _(" (default)") : ""));
-
- printf(_("Prompt: 1 - %d> "), count);
- fgets(answer, sizeof(answer), stdin);
- if (answer[0] == '\n')
- choice = def;
- else
- choice = atoi(answer);
- } while (choice <= 0 || choice > count);
+ for (i = 0; i < count; i++)
+ if (strcmp(choices[i], defval) == 0)
+ def = i + 1;
}
+
+ do
+ {
+ for (i = 0; i < count; i++)
+ printf("%3d. %s%s\n", i+1, choices_translated[i],
+ (def == i + 1 ? _(" (default)") : ""));
+
+ printf(_("Prompt: 1 - %d> "), count);
+ fgets(answer, sizeof(answer), stdin);
+ if (answer[0] == '\n')
+ choice = def;
+ else
+ choice = atoi(answer);
+ } while (choice <= 0 || choice > count);
/* fprintf(stderr,"In %s, line: %d\n\tanswer: %s, choice[choice]: %s\n",
__FILE__,__LINE__,answer, choices[choice - 1]);*/
question_setvalue(q, choices[choice - 1]);
@@ -352,7 +354,7 @@
static int texthandler_string(struct frontend *obj, struct question *q)
{
char buf[1024] = {0};
- const char *defval = question_defaultval(q);
+ const char *defval = question_get_field(q, "default");
if (defval)
printf(_("[default = %s]"), defval);
printf("> "); fflush(stdout);
Reply to: