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