|
|
1.1 ! root 1: /* ! 2: * Arnaldo Carvalho de Melo <[email protected]>, 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.