Linux Audio

Check our new training course

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