Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v3.0 236 lines 4.2 kB view raw
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 else if (*text == '\\') { 47 *bfp++ = '\\'; 48 len--; 49 } 50 *bfp++ = *text++; 51next: 52 --len; 53 } 54 55 if (multiline && eol) 56 bfp -= 3; 57 58 *bfp++ = '"'; 59 *bfp = '\0'; 60 61 return bf; 62} 63 64struct file_line { 65 struct file_line *next; 66 const char *file; 67 int lineno; 68}; 69 70static 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; 80out: 81 return self; 82} 83 84struct message { 85 const char *msg; 86 const char *option; 87 struct message *next; 88 struct file_line *files; 89}; 90 91static struct message *message__list; 92 93static 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; 111out: 112 return self; 113out_fail_msg: 114 free(self->files); 115out_fail: 116 free(self); 117 self = NULL; 118 goto out; 119} 120 121static 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 134static 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; 146out: 147 return rc; 148} 149 150static 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 172static 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 190static 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 209static 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 217static 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 229int 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}