[PATCH] Kconfig i18n support
[deliverable/linux.git] / scripts / kconfig / kxgettext.c
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
13 static char *escape(const char* text, char *bf, int len)
14 {
15 char *bfp = bf;
16 int multiline = strchr(text, '\n') != NULL;
17
18 *bfp++ = '"';
19 --len;
20
21 if (multiline) {
22 *bfp++ = '"';
23 *bfp++ = '\n';
24 *bfp++ = '"';
25 len -= 3;
26 }
27
28 while (*text != '\0' && len > 1) {
29 if (*text == '"')
30 *bfp++ = '\\';
31 else if (*text == '\n') {
32 *bfp++ = '\\';
33 *bfp++ = 'n';
34 *bfp++ = '"';
35 *bfp++ = '\n';
36 *bfp++ = '"';
37 len -= 5;
38 ++text;
39 goto next;
40 }
41 *bfp++ = *text++;
42 next:
43 --len;
44 }
45
46 if (multiline)
47 bfp -= 3;
48
49 *bfp++ = '"';
50 *bfp = '\0';
51
52 return bf;
53 }
54
55 struct file_line {
56 struct file_line *next;
57 char* file;
58 int lineno;
59 };
60
61 static struct file_line *file_line__new(char *file, int lineno)
62 {
63 struct file_line *self = malloc(sizeof(*self));
64
65 if (self == NULL)
66 goto out;
67
68 self->file = file;
69 self->lineno = lineno;
70 self->next = NULL;
71 out:
72 return self;
73 }
74
75 struct message {
76 const char *msg;
77 const char *option;
78 struct message *next;
79 struct file_line *files;
80 };
81
82 static struct message *message__list;
83
84 static struct message *message__new(const char *msg, char *option, char *file, int lineno)
85 {
86 struct message *self = malloc(sizeof(*self));
87
88 if (self == NULL)
89 goto out;
90
91 self->files = file_line__new(file, lineno);
92 if (self->files == NULL)
93 goto out_fail;
94
95 self->msg = strdup(msg);
96 if (self->msg == NULL)
97 goto out_fail_msg;
98
99 self->option = option;
100 self->next = NULL;
101 out:
102 return self;
103 out_fail_msg:
104 free(self->files);
105 out_fail:
106 free(self);
107 self = NULL;
108 goto out;
109 }
110
111 static struct message *mesage__find(const char *msg)
112 {
113 struct message *m = message__list;
114
115 while (m != NULL) {
116 if (strcmp(m->msg, msg) == 0)
117 break;
118 m = m->next;
119 }
120
121 return m;
122 }
123
124 static int message__add_file_line(struct message *self, char *file, int lineno)
125 {
126 int rc = -1;
127 struct file_line *fl = file_line__new(file, lineno);
128
129 if (fl == NULL)
130 goto out;
131
132 fl->next = self->files;
133 self->files = fl;
134 rc = 0;
135 out:
136 return rc;
137 }
138
139 static int message__add(const char *msg, char *option, char *file, int lineno)
140 {
141 int rc = 0;
142 char bf[16384];
143 char *escaped = escape(msg, bf, sizeof(bf));
144 struct message *m = mesage__find(escaped);
145
146 if (m != NULL)
147 rc = message__add_file_line(m, file, lineno);
148 else {
149 m = message__new(escaped, option, file, lineno);
150
151 if (m != NULL) {
152 m->next = message__list;
153 message__list = m;
154 } else
155 rc = -1;
156 }
157 return rc;
158 }
159
160 void menu_build_message_list(struct menu *menu)
161 {
162 struct menu *child;
163
164 message__add(menu_get_prompt(menu), NULL,
165 menu->file == NULL ? "Root Menu" : menu->file->name,
166 menu->lineno);
167
168 if (menu->sym != NULL && menu->sym->help != NULL)
169 message__add(menu->sym->help, menu->sym->name,
170 menu->file == NULL ? "Root Menu" : menu->file->name,
171 menu->lineno);
172
173 for (child = menu->list; child != NULL; child = child->next)
174 if (child->prompt != NULL)
175 menu_build_message_list(child);
176 }
177
178 static void message__print_file_lineno(struct message *self)
179 {
180 struct file_line *fl = self->files;
181
182 printf("\n#: %s:%d", fl->file, fl->lineno);
183 fl = fl->next;
184
185 while (fl != NULL) {
186 printf(", %s:%d", fl->file, fl->lineno);
187 fl = fl->next;
188 }
189
190 if (self->option != NULL)
191 printf(", %s:00000", self->option);
192
193 putchar('\n');
194 }
195
196 static void message__print_gettext_msgid_msgstr(struct message *self)
197 {
198 message__print_file_lineno(self);
199
200 printf("msgid %s\n"
201 "msgstr \"\"\n", self->msg);
202 }
203
204 void menu__xgettext(void)
205 {
206 struct message *m = message__list;
207
208 while (m != NULL) {
209 message__print_gettext_msgid_msgstr(m);
210 m = m->next;
211 }
212 }
213
214 int main(int ac, char **av)
215 {
216 conf_parse(av[1]);
217
218 menu_build_message_list(menu_get_root_menu(NULL));
219 menu__xgettext();
220 return 0;
221 }
This page took 0.087649 seconds and 5 git commands to generate.