Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


imported SEABIOS source tree
[palacios.git] / bios / seabios / tools / 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         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                 else if (*text == '\\') {
47                         *bfp++ = '\\';
48                         len--;
49                 }
50                 *bfp++ = *text++;
51 next:
52                 --len;
53         }
54
55         if (multiline && eol)
56                 bfp -= 3;
57
58         *bfp++ = '"';
59         *bfp = '\0';
60
61         return bf;
62 }
63
64 struct file_line {
65         struct file_line *next;
66         const char *file;
67         int lineno;
68 };
69
70 static struct file_line *file_line__new(const char *file, int lineno)
71 {
72         struct file_line *self = malloc(sizeof(*self));
73
74         if (self == NULL)
75                 goto out;
76
77         self->file   = file;
78         self->lineno = lineno;
79         self->next   = NULL;
80 out:
81         return self;
82 }
83
84 struct message {
85         const char       *msg;
86         const char       *option;
87         struct message   *next;
88         struct file_line *files;
89 };
90
91 static struct message *message__list;
92
93 static struct message *message__new(const char *msg, char *option,
94                                     const char *file, int lineno)
95 {
96         struct message *self = malloc(sizeof(*self));
97
98         if (self == NULL)
99                 goto out;
100
101         self->files = file_line__new(file, lineno);
102         if (self->files == NULL)
103                 goto out_fail;
104
105         self->msg = strdup(msg);
106         if (self->msg == NULL)
107                 goto out_fail_msg;
108
109         self->option = option;
110         self->next = NULL;
111 out:
112         return self;
113 out_fail_msg:
114         free(self->files);
115 out_fail:
116         free(self);
117         self = NULL;
118         goto out;
119 }
120
121 static struct message *mesage__find(const char *msg)
122 {
123         struct message *m = message__list;
124
125         while (m != NULL) {
126                 if (strcmp(m->msg, msg) == 0)
127                         break;
128                 m = m->next;
129         }
130
131         return m;
132 }
133
134 static int message__add_file_line(struct message *self, const char *file,
135                                   int lineno)
136 {
137         int rc = -1;
138         struct file_line *fl = file_line__new(file, lineno);
139
140         if (fl == NULL)
141                 goto out;
142
143         fl->next    = self->files;
144         self->files = fl;
145         rc = 0;
146 out:
147         return rc;
148 }
149
150 static int message__add(const char *msg, char *option, const char *file,
151                         int lineno)
152 {
153         int rc = 0;
154         char bf[16384];
155         char *escaped = escape(msg, bf, sizeof(bf));
156         struct message *m = mesage__find(escaped);
157
158         if (m != NULL)
159                 rc = message__add_file_line(m, file, lineno);
160         else {
161                 m = message__new(escaped, option, file, lineno);
162
163                 if (m != NULL) {
164                         m->next       = message__list;
165                         message__list = m;
166                 } else
167                         rc = -1;
168         }
169         return rc;
170 }
171
172 static void menu_build_message_list(struct menu *menu)
173 {
174         struct menu *child;
175
176         message__add(menu_get_prompt(menu), NULL,
177                      menu->file == NULL ? "Root Menu" : menu->file->name,
178                      menu->lineno);
179
180         if (menu->sym != NULL && menu_has_help(menu))
181                 message__add(menu_get_help(menu), menu->sym->name,
182                              menu->file == NULL ? "Root Menu" : menu->file->name,
183                              menu->lineno);
184
185         for (child = menu->list; child != NULL; child = child->next)
186                 if (child->prompt != NULL)
187                         menu_build_message_list(child);
188 }
189
190 static void message__print_file_lineno(struct message *self)
191 {
192         struct file_line *fl = self->files;
193
194         putchar('\n');
195         if (self->option != NULL)
196                 printf("# %s:00000\n", self->option);
197
198         printf("#: %s:%d", fl->file, fl->lineno);
199         fl = fl->next;
200
201         while (fl != NULL) {
202                 printf(", %s:%d", fl->file, fl->lineno);
203                 fl = fl->next;
204         }
205
206         putchar('\n');
207 }
208
209 static void message__print_gettext_msgid_msgstr(struct message *self)
210 {
211         message__print_file_lineno(self);
212
213         printf("msgid %s\n"
214                "msgstr \"\"\n", self->msg);
215 }
216
217 static void menu__xgettext(void)
218 {
219         struct message *m = message__list;
220
221         while (m != NULL) {
222                 /* skip empty lines ("") */
223                 if (strlen(m->msg) > sizeof("\"\""))
224                         message__print_gettext_msgid_msgstr(m);
225                 m = m->next;
226         }
227 }
228
229 int main(int ac, char **av)
230 {
231         conf_parse(av[1]);
232
233         menu_build_message_list(menu_get_root_menu(NULL));
234         menu__xgettext();
235         return 0;
236 }