Blame locale/strings2po.c

Packit 2fc92b
/*
Packit 2fc92b
 * Convert Apple .strings file (UTF-16 BE text file) to GNU gettext .po files.
Packit 2fc92b
 *
Packit 2fc92b
 * Copyright 2007-2014 by Apple Inc.
Packit 2fc92b
 *
Packit 2fc92b
 * These coded instructions, statements, and computer programs are the
Packit 2fc92b
 * property of Apple Inc. and are protected by Federal copyright
Packit 2fc92b
 * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
Packit 2fc92b
 * which should have been included with this file.  If this file is
Packit 2fc92b
 * missing or damaged, see the license at "http://www.cups.org/".
Packit 2fc92b
 *
Packit 2fc92b
 * Usage:
Packit 2fc92b
 *
Packit 2fc92b
 *   strings2po filename.strings filename.po
Packit 2fc92b
 *
Packit 2fc92b
 * Compile with:
Packit 2fc92b
 *
Packit 2fc92b
 *   gcc -o strings2po strings2po.c
Packit 2fc92b
 */
Packit 2fc92b
Packit 2fc92b
#include <stdio.h>
Packit 2fc92b
#include <stdlib.h>
Packit 2fc92b
Packit 2fc92b
Packit 2fc92b
/*
Packit 2fc92b
 * The .strings file format is simple:
Packit 2fc92b
 *
Packit 2fc92b
 * // comment
Packit 2fc92b
 * "id" = "str";
Packit 2fc92b
 *
Packit 2fc92b
 * Both the id and str strings use standard C quoting for special characters
Packit 2fc92b
 * like newline and the double quote character.
Packit 2fc92b
 */
Packit 2fc92b
Packit 2fc92b
/*
Packit 2fc92b
 * Local functions...
Packit 2fc92b
 */
Packit 2fc92b
Packit 2fc92b
static int	read_strings(FILE *strings, char *buffer, size_t bufsize,
Packit 2fc92b
		             char **id, char **str);
Packit 2fc92b
static void	write_po(FILE *po, const char *what, const char *s);
Packit 2fc92b
Packit 2fc92b
Packit 2fc92b
/*
Packit 2fc92b
 *   main() - Convert .strings file to .po.
Packit 2fc92b
 */
Packit 2fc92b
Packit 2fc92b
int					/* O - Exit code */
Packit 2fc92b
main(int  argc,				/* I - Number of command-line args */
Packit 2fc92b
     char *argv[])			/* I - Command-line arguments */
Packit 2fc92b
{
Packit 2fc92b
  FILE	*strings,			/* .strings file */
Packit 2fc92b
	*po;				/* .po file */
Packit 2fc92b
  char	iconv[1024],			/* iconv command */
Packit 2fc92b
	buffer[8192],			/* Line buffer */
Packit 2fc92b
	*id,				/* ID string */
Packit 2fc92b
	*str;				/* Translation string */
Packit 2fc92b
  int	count;				/* Number of messages converted */
Packit 2fc92b
Packit 2fc92b
Packit 2fc92b
  if (argc != 3)
Packit 2fc92b
  {
Packit 2fc92b
    puts("Usage: strings2po filename.strings filename.po");
Packit 2fc92b
    return (1);
Packit 2fc92b
  }
Packit 2fc92b
Packit 2fc92b
 /*
Packit 2fc92b
  * Cheat by using iconv to convert the .strings file from UTF-16 to UTF-8
Packit 2fc92b
  * which is what we need for the .po file (and it makes things a lot
Packit 2fc92b
  * simpler...)
Packit 2fc92b
  */
Packit 2fc92b
Packit 2fc92b
  snprintf(iconv, sizeof(iconv), "iconv -f utf-16 -t utf-8 '%s'", argv[1]);
Packit 2fc92b
  if ((strings = popen(iconv, "r")) == NULL)
Packit 2fc92b
  {
Packit 2fc92b
    perror(argv[1]);
Packit 2fc92b
    return (1);
Packit 2fc92b
  }
Packit 2fc92b
Packit 2fc92b
  if ((po = fopen(argv[2], "w")) == NULL)
Packit 2fc92b
  {
Packit 2fc92b
    perror(argv[2]);
Packit 2fc92b
    pclose(strings);
Packit 2fc92b
    return (1);
Packit 2fc92b
  }
Packit 2fc92b
Packit 2fc92b
  count = 0;
Packit 2fc92b
Packit 2fc92b
  while (read_strings(strings, buffer, sizeof(buffer), &id, &str))
Packit 2fc92b
  {
Packit 2fc92b
    count ++;
Packit 2fc92b
    write_po(po, "msgid", id);
Packit 2fc92b
    write_po(po, "msgstr", str);
Packit 2fc92b
  }
Packit 2fc92b
Packit 2fc92b
  pclose(strings);
Packit 2fc92b
  fclose(po);
Packit 2fc92b
Packit 2fc92b
  printf("%s: %d messages.\n", argv[2], count);
Packit 2fc92b
Packit 2fc92b
  return (0);
Packit 2fc92b
}
Packit 2fc92b
Packit 2fc92b
Packit 2fc92b
/*
Packit 2fc92b
 * 'read_strings()' - Read a line from a .strings file.
Packit 2fc92b
 */
Packit 2fc92b
Packit 2fc92b
static int				/* O - 1 on success, 0 on failure */
Packit 2fc92b
read_strings(FILE   *strings,		/* I - .strings file */
Packit 2fc92b
             char   *buffer,		/* I - Line buffer */
Packit 2fc92b
	     size_t bufsize,		/* I - Size of line buffer */
Packit 2fc92b
             char   **id,		/* O - Pointer to ID string */
Packit 2fc92b
	     char   **str)		/* O - Pointer to translation string */
Packit 2fc92b
{
Packit 2fc92b
  char	*bufptr;			/* Pointer into buffer */
Packit 2fc92b
Packit 2fc92b
Packit 2fc92b
  while (fgets(buffer, (int)bufsize, strings))
Packit 2fc92b
  {
Packit 2fc92b
    if (buffer[0] != '\"')
Packit 2fc92b
      continue;
Packit 2fc92b
Packit 2fc92b
    *id = buffer + 1;
Packit 2fc92b
Packit 2fc92b
    for (bufptr = buffer + 1; *bufptr && *bufptr != '\"'; bufptr ++)
Packit 2fc92b
      if (*bufptr == '\\')
Packit 2fc92b
        bufptr ++;
Packit 2fc92b
Packit 2fc92b
    if (*bufptr != '\"')
Packit 2fc92b
      continue;
Packit 2fc92b
Packit 2fc92b
    *bufptr++ = '\0';
Packit 2fc92b
Packit 2fc92b
    while (*bufptr && *bufptr != '\"')
Packit 2fc92b
      bufptr ++;
Packit 2fc92b
Packit 2fc92b
    if (!*bufptr)
Packit 2fc92b
      continue;
Packit 2fc92b
Packit 2fc92b
    bufptr ++;
Packit 2fc92b
    *str = bufptr;
Packit 2fc92b
Packit 2fc92b
    for (; *bufptr && *bufptr != '\"'; bufptr ++)
Packit 2fc92b
      if (*bufptr == '\\')
Packit 2fc92b
        bufptr ++;
Packit 2fc92b
Packit 2fc92b
    if (*bufptr != '\"')
Packit 2fc92b
      continue;
Packit 2fc92b
Packit 2fc92b
    *bufptr = '\0';
Packit 2fc92b
Packit 2fc92b
    return (1);
Packit 2fc92b
  }
Packit 2fc92b
Packit 2fc92b
  return (0);
Packit 2fc92b
}
Packit 2fc92b
Packit 2fc92b
Packit 2fc92b
/*
Packit 2fc92b
 * 'write_po()' - Write a line to the .po file.
Packit 2fc92b
 */
Packit 2fc92b
Packit 2fc92b
static void
Packit 2fc92b
write_po(FILE       *po,		/* I - .po file */
Packit 2fc92b
         const char *what,		/* I - Type of string */
Packit 2fc92b
	 const char *s)			/* I - String to write */
Packit 2fc92b
{
Packit 2fc92b
  fprintf(po, "%s \"%s\"\n", what, s);
Packit 2fc92b
}