home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6-686 / scripts / kconfig / kxgettext.c < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  3.9 KB  |  228 lines

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