Logo Search packages:      
Sourcecode: undertaker version File versions  Download package

kxgettext.c

/*
 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 2005
 *
 * Released under the terms of the GNU GPL v2.0
 */

#include <stdlib.h>
#include <string.h>

#define LKC_DIRECT_LINK
#include "lkc.h"

static char *escape(const char* text, char *bf, int len)
{
      char *bfp = bf;
      int multiline = strchr(text, '\n') != NULL;
      int eol = 0;
      int textlen = strlen(text);

      if ((textlen > 0) && (text[textlen-1] == '\n'))
            eol = 1;

      *bfp++ = '"';
      --len;

      if (multiline) {
            *bfp++ = '"';
            *bfp++ = '\n';
            *bfp++ = '"';
            len -= 3;
      }

      while (*text != '\0' && len > 1) {
            if (*text == '"')
                  *bfp++ = '\\';
            else if (*text == '\n') {
                  *bfp++ = '\\';
                  *bfp++ = 'n';
                  *bfp++ = '"';
                  *bfp++ = '\n';
                  *bfp++ = '"';
                  len -= 5;
                  ++text;
                  goto next;
            }
            else if (*text == '\\') {
                  *bfp++ = '\\';
                  len--;
            }
            *bfp++ = *text++;
next:
            --len;
      }

      if (multiline && eol)
            bfp -= 3;

      *bfp++ = '"';
      *bfp = '\0';

      return bf;
}

00064 struct file_line {
      struct file_line *next;
      char*        file;
      int          lineno;
};

static struct file_line *file_line__new(char *file, int lineno)
{
      struct file_line *self = malloc(sizeof(*self));

      if (self == NULL)
            goto out;

      self->file   = file;
      self->lineno = lineno;
      self->next   = NULL;
out:
      return self;
}

00084 struct message {
      const char   *msg;
      const char   *option;
      struct message     *next;
      struct file_line *files;
};

static struct message *message__list;

static struct message *message__new(const char *msg, char *option, char *file, int lineno)
{
      struct message *self = malloc(sizeof(*self));

      if (self == NULL)
            goto out;

      self->files = file_line__new(file, lineno);
      if (self->files == NULL)
            goto out_fail;

      self->msg = strdup(msg);
      if (self->msg == NULL)
            goto out_fail_msg;

      self->option = option;
      self->next = NULL;
out:
      return self;
out_fail_msg:
      free(self->files);
out_fail:
      free(self);
      self = NULL;
      goto out;
}

static struct message *mesage__find(const char *msg)
{
      struct message *m = message__list;

      while (m != NULL) {
            if (strcmp(m->msg, msg) == 0)
                  break;
            m = m->next;
      }

      return m;
}

static int message__add_file_line(struct message *self, char *file, int lineno)
{
      int rc = -1;
      struct file_line *fl = file_line__new(file, lineno);

      if (fl == NULL)
            goto out;

      fl->next    = self->files;
      self->files = fl;
      rc = 0;
out:
      return rc;
}

static int message__add(const char *msg, char *option, char *file, int lineno)
{
      int rc = 0;
      char bf[16384];
      char *escaped = escape(msg, bf, sizeof(bf));
      struct message *m = mesage__find(escaped);

      if (m != NULL)
            rc = message__add_file_line(m, file, lineno);
      else {
            m = message__new(escaped, option, file, lineno);

            if (m != NULL) {
                  m->next           = message__list;
                  message__list = m;
            } else
                  rc = -1;
      }
      return rc;
}

static void menu_build_message_list(struct menu *menu)
{
      struct menu *child;

      message__add(menu_get_prompt(menu), NULL,
                 menu->file == NULL ? "Root Menu" : menu->file->name,
                 menu->lineno);

      if (menu->sym != NULL && menu_has_help(menu))
            message__add(menu_get_help(menu), menu->sym->name,
                       menu->file == NULL ? "Root Menu" : menu->file->name,
                       menu->lineno);

      for (child = menu->list; child != NULL; child = child->next)
            if (child->prompt != NULL)
                  menu_build_message_list(child);
}

static void message__print_file_lineno(struct message *self)
{
      struct file_line *fl = self->files;

      putchar('\n');
      if (self->option != NULL)
            printf("# %s:00000\n", self->option);

      printf("#: %s:%d", fl->file, fl->lineno);
      fl = fl->next;

      while (fl != NULL) {
            printf(", %s:%d", fl->file, fl->lineno);
            fl = fl->next;
      }

      putchar('\n');
}

static void message__print_gettext_msgid_msgstr(struct message *self)
{
      message__print_file_lineno(self);

      printf("msgid %s\n"
             "msgstr \"\"\n", self->msg);
}

static void menu__xgettext(void)
{
      struct message *m = message__list;

      while (m != NULL) {
            /* skip empty lines ("") */
            if (strlen(m->msg) > sizeof("\"\""))
                  message__print_gettext_msgid_msgstr(m);
            m = m->next;
      }
}

int main(int ac, char **av)
{
      conf_parse(av[1]);

      menu_build_message_list(menu_get_root_menu(NULL));
      menu__xgettext();
      return 0;
}

Generated by  Doxygen 1.6.0   Back to index