kxgettext.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  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. #include <stdlib.h>
  7. #include <string.h>
  8. #define LKC_DIRECT_LINK
  9. #include "lkc.h"
  10. static char *escape(const char* text, char *bf, int len)
  11. {
  12. char *bfp = bf;
  13. int multiline = strchr(text, '\n') != NULL;
  14. *bfp++ = '"';
  15. --len;
  16. if (multiline) {
  17. *bfp++ = '"';
  18. *bfp++ = '\n';
  19. *bfp++ = '"';
  20. len -= 3;
  21. }
  22. while (*text != '\0' && len > 1) {
  23. if (*text == '"')
  24. *bfp++ = '\\';
  25. else if (*text == '\n') {
  26. *bfp++ = '\\';
  27. *bfp++ = 'n';
  28. *bfp++ = '"';
  29. *bfp++ = '\n';
  30. *bfp++ = '"';
  31. len -= 5;
  32. ++text;
  33. goto next;
  34. }
  35. *bfp++ = *text++;
  36. next:
  37. --len;
  38. }
  39. if (multiline)
  40. bfp -= 3;
  41. *bfp++ = '"';
  42. *bfp = '\0';
  43. return bf;
  44. }
  45. struct file_line {
  46. struct file_line *next;
  47. char* file;
  48. int lineno;
  49. };
  50. static struct file_line *file_line__new(char *file, int lineno)
  51. {
  52. struct file_line *self = malloc(sizeof(*self));
  53. if (self == NULL)
  54. goto out;
  55. self->file = file;
  56. self->lineno = lineno;
  57. self->next = NULL;
  58. out:
  59. return self;
  60. }
  61. struct message {
  62. const char *msg;
  63. const char *option;
  64. struct message *next;
  65. struct file_line *files;
  66. };
  67. static struct message *message__list;
  68. static struct message *message__new(const char *msg, char *option, char *file, int lineno)
  69. {
  70. struct message *self = malloc(sizeof(*self));
  71. if (self == NULL)
  72. goto out;
  73. self->files = file_line__new(file, lineno);
  74. if (self->files == NULL)
  75. goto out_fail;
  76. self->msg = strdup(msg);
  77. if (self->msg == NULL)
  78. goto out_fail_msg;
  79. self->option = option;
  80. self->next = NULL;
  81. out:
  82. return self;
  83. out_fail_msg:
  84. free(self->files);
  85. out_fail:
  86. free(self);
  87. self = NULL;
  88. goto out;
  89. }
  90. static struct message *mesage__find(const char *msg)
  91. {
  92. struct message *m = message__list;
  93. while (m != NULL) {
  94. if (strcmp(m->msg, msg) == 0)
  95. break;
  96. m = m->next;
  97. }
  98. return m;
  99. }
  100. static int message__add_file_line(struct message *self, char *file, int lineno)
  101. {
  102. int rc = -1;
  103. struct file_line *fl = file_line__new(file, lineno);
  104. if (fl == NULL)
  105. goto out;
  106. fl->next = self->files;
  107. self->files = fl;
  108. rc = 0;
  109. out:
  110. return rc;
  111. }
  112. static int message__add(const char *msg, char *option, char *file, int lineno)
  113. {
  114. int rc = 0;
  115. char bf[16384];
  116. char *escaped = escape(msg, bf, sizeof(bf));
  117. struct message *m = mesage__find(escaped);
  118. if (m != NULL)
  119. rc = message__add_file_line(m, file, lineno);
  120. else {
  121. m = message__new(escaped, option, file, lineno);
  122. if (m != NULL) {
  123. m->next = message__list;
  124. message__list = m;
  125. } else
  126. rc = -1;
  127. }
  128. return rc;
  129. }
  130. void menu_build_message_list(struct menu *menu)
  131. {
  132. struct menu *child;
  133. message__add(menu_get_prompt(menu), NULL,
  134. menu->file == NULL ? "Root Menu" : menu->file->name,
  135. menu->lineno);
  136. if (menu->sym != NULL && menu->sym->help != NULL)
  137. message__add(menu->sym->help, menu->sym->name,
  138. menu->file == NULL ? "Root Menu" : menu->file->name,
  139. menu->lineno);
  140. for (child = menu->list; child != NULL; child = child->next)
  141. if (child->prompt != NULL)
  142. menu_build_message_list(child);
  143. }
  144. static void message__print_file_lineno(struct message *self)
  145. {
  146. struct file_line *fl = self->files;
  147. printf("\n#: %s:%d", fl->file, fl->lineno);
  148. fl = fl->next;
  149. while (fl != NULL) {
  150. printf(", %s:%d", fl->file, fl->lineno);
  151. fl = fl->next;
  152. }
  153. if (self->option != NULL)
  154. printf(", %s:00000", self->option);
  155. putchar('\n');
  156. }
  157. static void message__print_gettext_msgid_msgstr(struct message *self)
  158. {
  159. message__print_file_lineno(self);
  160. printf("msgid %s\n"
  161. "msgstr \"\"\n", self->msg);
  162. }
  163. void menu__xgettext(void)
  164. {
  165. struct message *m = message__list;
  166. while (m != NULL) {
  167. message__print_gettext_msgid_msgstr(m);
  168. m = m->next;
  169. }
  170. }
  171. int main(int ac, char **av)
  172. {
  173. conf_parse(av[1]);
  174. menu_build_message_list(menu_get_root_menu(NULL));
  175. menu__xgettext();
  176. return 0;
  177. }