Hi,
[ Just lurking on d-i for a while, to get up to speed on the design
before contributing].
Why do you use DEBCONF_LANG rather than LANG or LC_ALL ?
Similarly, in some parts of the installer, there is a need to find the
Country. Shouldn't that be found from LC_ALL as well?
Regards,
Alastair McKinstry
On Sat, 2002-11-09 at 03:05, Denis Barbier wrote:
> 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);
--
Alastair McKinstry <mckinstry@debian.org>
GPG Key fingerprint = 9E64 E714 8E08 81F9 F3DC 1020 FA8E 3790 9051 38F4
He that would make his own liberty secure must guard even his enemy from
oppression; for if he violates this duty he establishes a precedent that
will reach to himself.
- --Thomas Paine
Attachment:
signature.asc
Description: This is a digitally signed message part