52a142a631
The goal is to be able to use savedefconfig to generate minimal defconfig files. Four of our patches are removed since the modifications have been merged upstream. The new nconf configuration utility has appeared. Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
234 lines
4.1 KiB
C
234 lines
4.1 KiB
C
/*
|
|
* Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 2005
|
|
*
|
|
* Released under the terms of the GNU GPL v2.0
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#define LKC_DIRECT_LINK
|
|
#include "lkc.h"
|
|
|
|
static char *escape(const char* text, char *bf, int len)
|
|
{
|
|
char *bfp = bf;
|
|
int multiline = strchr(text, '\n') != NULL;
|
|
int eol = 0;
|
|
int textlen = strlen(text);
|
|
|
|
if ((textlen > 0) && (text[textlen-1] == '\n'))
|
|
eol = 1;
|
|
|
|
*bfp++ = '"';
|
|
--len;
|
|
|
|
if (multiline) {
|
|
*bfp++ = '"';
|
|
*bfp++ = '\n';
|
|
*bfp++ = '"';
|
|
len -= 3;
|
|
}
|
|
|
|
while (*text != '\0' && len > 1) {
|
|
if (*text == '"')
|
|
*bfp++ = '\\';
|
|
else if (*text == '\n') {
|
|
*bfp++ = '\\';
|
|
*bfp++ = 'n';
|
|
*bfp++ = '"';
|
|
*bfp++ = '\n';
|
|
*bfp++ = '"';
|
|
len -= 5;
|
|
++text;
|
|
goto next;
|
|
}
|
|
else if (*text == '\\') {
|
|
*bfp++ = '\\';
|
|
len--;
|
|
}
|
|
*bfp++ = *text++;
|
|
next:
|
|
--len;
|
|
}
|
|
|
|
if (multiline && eol)
|
|
bfp -= 3;
|
|
|
|
*bfp++ = '"';
|
|
*bfp = '\0';
|
|
|
|
return bf;
|
|
}
|
|
|
|
struct file_line {
|
|
struct file_line *next;
|
|
char* file;
|
|
int lineno;
|
|
};
|
|
|
|
static struct file_line *file_line__new(char *file, int lineno)
|
|
{
|
|
struct file_line *self = malloc(sizeof(*self));
|
|
|
|
if (self == NULL)
|
|
goto out;
|
|
|
|
self->file = file;
|
|
self->lineno = lineno;
|
|
self->next = NULL;
|
|
out:
|
|
return self;
|
|
}
|
|
|
|
struct message {
|
|
const char *msg;
|
|
const char *option;
|
|
struct message *next;
|
|
struct file_line *files;
|
|
};
|
|
|
|
static struct message *message__list;
|
|
|
|
static struct message *message__new(const char *msg, char *option, char *file, int lineno)
|
|
{
|
|
struct message *self = malloc(sizeof(*self));
|
|
|
|
if (self == NULL)
|
|
goto out;
|
|
|
|
self->files = file_line__new(file, lineno);
|
|
if (self->files == NULL)
|
|
goto out_fail;
|
|
|
|
self->msg = strdup(msg);
|
|
if (self->msg == NULL)
|
|
goto out_fail_msg;
|
|
|
|
self->option = option;
|
|
self->next = NULL;
|
|
out:
|
|
return self;
|
|
out_fail_msg:
|
|
free(self->files);
|
|
out_fail:
|
|
free(self);
|
|
self = NULL;
|
|
goto out;
|
|
}
|
|
|
|
static struct message *mesage__find(const char *msg)
|
|
{
|
|
struct message *m = message__list;
|
|
|
|
while (m != NULL) {
|
|
if (strcmp(m->msg, msg) == 0)
|
|
break;
|
|
m = m->next;
|
|
}
|
|
|
|
return m;
|
|
}
|
|
|
|
static int message__add_file_line(struct message *self, char *file, int lineno)
|
|
{
|
|
int rc = -1;
|
|
struct file_line *fl = file_line__new(file, lineno);
|
|
|
|
if (fl == NULL)
|
|
goto out;
|
|
|
|
fl->next = self->files;
|
|
self->files = fl;
|
|
rc = 0;
|
|
out:
|
|
return rc;
|
|
}
|
|
|
|
static int message__add(const char *msg, char *option, char *file, int lineno)
|
|
{
|
|
int rc = 0;
|
|
char bf[16384];
|
|
char *escaped = escape(msg, bf, sizeof(bf));
|
|
struct message *m = mesage__find(escaped);
|
|
|
|
if (m != NULL)
|
|
rc = message__add_file_line(m, file, lineno);
|
|
else {
|
|
m = message__new(escaped, option, file, lineno);
|
|
|
|
if (m != NULL) {
|
|
m->next = message__list;
|
|
message__list = m;
|
|
} else
|
|
rc = -1;
|
|
}
|
|
return rc;
|
|
}
|
|
|
|
static void menu_build_message_list(struct menu *menu)
|
|
{
|
|
struct menu *child;
|
|
|
|
message__add(menu_get_prompt(menu), NULL,
|
|
menu->file == NULL ? "Root Menu" : menu->file->name,
|
|
menu->lineno);
|
|
|
|
if (menu->sym != NULL && menu_has_help(menu))
|
|
message__add(menu_get_help(menu), menu->sym->name,
|
|
menu->file == NULL ? "Root Menu" : menu->file->name,
|
|
menu->lineno);
|
|
|
|
for (child = menu->list; child != NULL; child = child->next)
|
|
if (child->prompt != NULL)
|
|
menu_build_message_list(child);
|
|
}
|
|
|
|
static void message__print_file_lineno(struct message *self)
|
|
{
|
|
struct file_line *fl = self->files;
|
|
|
|
putchar('\n');
|
|
if (self->option != NULL)
|
|
printf("# %s:00000\n", self->option);
|
|
|
|
printf("#: %s:%d", fl->file, fl->lineno);
|
|
fl = fl->next;
|
|
|
|
while (fl != NULL) {
|
|
printf(", %s:%d", fl->file, fl->lineno);
|
|
fl = fl->next;
|
|
}
|
|
|
|
putchar('\n');
|
|
}
|
|
|
|
static void message__print_gettext_msgid_msgstr(struct message *self)
|
|
{
|
|
message__print_file_lineno(self);
|
|
|
|
printf("msgid %s\n"
|
|
"msgstr \"\"\n", self->msg);
|
|
}
|
|
|
|
static void menu__xgettext(void)
|
|
{
|
|
struct message *m = message__list;
|
|
|
|
while (m != NULL) {
|
|
/* skip empty lines ("") */
|
|
if (strlen(m->msg) > sizeof("\"\""))
|
|
message__print_gettext_msgid_msgstr(m);
|
|
m = m->next;
|
|
}
|
|
}
|
|
|
|
int main(int ac, char **av)
|
|
{
|
|
conf_parse(av[1]);
|
|
|
|
menu_build_message_list(menu_get_root_menu(NULL));
|
|
menu__xgettext();
|
|
return 0;
|
|
}
|