|
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 |
}
|