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