source: MondoRescue/branches/2.2.5/mindi-busybox/scripts/kconfig/kxgettext.c @ 1765

Last change on this file since 1765 was 1765, checked in by Bruno Cornec, 12 years ago

Update to busybox 1.7.2

  • Property svn:eol-style set to native
File size: 3.9 KB
Line 
1/*
2 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 2005
3 *
4 * Released under the terms of the GNU GPL v2.0
5 */
6
7#include <stdlib.h>
8#include <string.h>
9
10#define LKC_DIRECT_LINK
11#include "lkc.h"
12
13static char *escape(const char* text, char *bf, int len)
14{
15    char *bfp = bf;
16    int multiline = strchr(text, '\n') != NULL;
17    int eol = 0;
18    int textlen = strlen(text);
19
20    if ((textlen > 0) && (text[textlen-1] == '\n'))
21        eol = 1;
22
23    *bfp++ = '"';
24    --len;
25
26    if (multiline) {
27        *bfp++ = '"';
28        *bfp++ = '\n';
29        *bfp++ = '"';
30        len -= 3;
31    }
32
33    while (*text != '\0' && len > 1) {
34        if (*text == '"')
35            *bfp++ = '\\';
36        else if (*text == '\n') {
37            *bfp++ = '\\';
38            *bfp++ = 'n';
39            *bfp++ = '"';
40            *bfp++ = '\n';
41            *bfp++ = '"';
42            len -= 5;
43            ++text;
44            goto next;
45        }
46        *bfp++ = *text++;
47next:
48        --len;
49    }
50
51    if (multiline && eol)
52        bfp -= 3;
53
54    *bfp++ = '"';
55    *bfp = '\0';
56
57    return bf;
58}
59
60struct file_line {
61    struct file_line *next;
62    char*        file;
63    int      lineno;
64};
65
66static struct file_line *file_line__new(char *file, int lineno)
67{
68    struct file_line *self = malloc(sizeof(*self));
69
70    if (self == NULL)
71        goto out;
72
73    self->file   = file;
74    self->lineno = lineno;
75    self->next   = NULL;
76out:
77    return self;
78}
79
80struct message {
81    const char   *msg;
82    const char   *option;
83    struct message   *next;
84    struct file_line *files;
85};
86
87static struct message *message__list;
88
89static struct message *message__new(const char *msg, char *option, char *file, int lineno)
90{
91    struct message *self = malloc(sizeof(*self));
92
93    if (self == NULL)
94        goto out;
95
96    self->files = file_line__new(file, lineno);
97    if (self->files == NULL)
98        goto out_fail;
99
100    self->msg = strdup(msg);
101    if (self->msg == NULL)
102        goto out_fail_msg;
103
104    self->option = option;
105    self->next = NULL;
106out:
107    return self;
108out_fail_msg:
109    free(self->files);
110out_fail:
111    free(self);
112    self = NULL;
113    goto out;
114}
115
116static struct message *mesage__find(const char *msg)
117{
118    struct message *m = message__list;
119
120    while (m != NULL) {
121        if (strcmp(m->msg, msg) == 0)
122            break;
123        m = m->next;
124    }
125
126    return m;
127}
128
129static int message__add_file_line(struct message *self, char *file, int lineno)
130{
131    int rc = -1;
132    struct file_line *fl = file_line__new(file, lineno);
133
134    if (fl == NULL)
135        goto out;
136
137    fl->next    = self->files;
138    self->files = fl;
139    rc = 0;
140out:
141    return rc;
142}
143
144static int message__add(const char *msg, char *option, char *file, int lineno)
145{
146    int rc = 0;
147    char bf[16384];
148    char *escaped = escape(msg, bf, sizeof(bf));
149    struct message *m = mesage__find(escaped);
150
151    if (m != NULL)
152        rc = message__add_file_line(m, file, lineno);
153    else {
154        m = message__new(escaped, option, file, lineno);
155
156        if (m != NULL) {
157            m->next       = message__list;
158            message__list = m;
159        } else
160            rc = -1;
161    }
162    return rc;
163}
164
165void menu_build_message_list(struct menu *menu)
166{
167    struct menu *child;
168
169    message__add(menu_get_prompt(menu), NULL,
170             menu->file == NULL ? "Root Menu" : menu->file->name,
171             menu->lineno);
172
173    if (menu->sym != NULL && menu->sym->help != NULL)
174        message__add(menu->sym->help, menu->sym->name,
175                 menu->file == NULL ? "Root Menu" : menu->file->name,
176                 menu->lineno);
177
178    for (child = menu->list; child != NULL; child = child->next)
179        if (child->prompt != NULL)
180            menu_build_message_list(child);
181}
182
183static void message__print_file_lineno(struct message *self)
184{
185    struct file_line *fl = self->files;
186
187    putchar('\n');
188    if (self->option != NULL)
189        printf("# %s:00000\n", self->option);
190
191    printf("#: %s:%d", fl->file, fl->lineno);
192    fl = fl->next;
193
194    while (fl != NULL) {
195        printf(", %s:%d", fl->file, fl->lineno);
196        fl = fl->next;
197    }
198
199    putchar('\n');
200}
201
202static void message__print_gettext_msgid_msgstr(struct message *self)
203{
204    message__print_file_lineno(self);
205
206    printf("msgid %s\n"
207           "msgstr \"\"\n", self->msg);
208}
209
210void menu__xgettext(void)
211{
212    struct message *m = message__list;
213
214    while (m != NULL) {
215        message__print_gettext_msgid_msgstr(m);
216        m = m->next;
217    }
218}
219
220int main(int ac, char **av)
221{
222    conf_parse(av[1]);
223
224    menu_build_message_list(menu_get_root_menu(NULL));
225    menu__xgettext();
226    return 0;
227}
Note: See TracBrowser for help on using the repository browser.