| /* |
| * Convert Apple .strings file (UTF-16 BE text file) to GNU gettext .po files. |
| * |
| * Copyright 2007-2014 by Apple Inc. |
| * |
| * Licensed under Apache License v2.0. See the file "LICENSE" for more information. |
| * |
| * Usage: |
| * |
| * strings2po filename.strings filename.po |
| * |
| * Compile with: |
| * |
| * gcc -o strings2po strings2po.c |
| */ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| |
| |
| /* |
| * The .strings file format is simple: |
| * |
| * // comment |
| * "id" = "str"; |
| * |
| * Both the id and str strings use standard C quoting for special characters |
| * like newline and the double quote character. |
| */ |
| |
| /* |
| * Local functions... |
| */ |
| |
| static int read_strings(FILE *strings, char *buffer, size_t bufsize, |
| char **id, char **str); |
| static void write_po(FILE *po, const char *what, const char *s); |
| |
| |
| /* |
| * main() - Convert .strings file to .po. |
| */ |
| |
| int /* O - Exit code */ |
| main(int argc, /* I - Number of command-line args */ |
| char *argv[]) /* I - Command-line arguments */ |
| { |
| FILE *strings, /* .strings file */ |
| *po; /* .po file */ |
| char iconv[1024], /* iconv command */ |
| buffer[8192], /* Line buffer */ |
| *id, /* ID string */ |
| *str; /* Translation string */ |
| int count; /* Number of messages converted */ |
| |
| |
| if (argc != 3) |
| { |
| puts("Usage: strings2po filename.strings filename.po"); |
| return (1); |
| } |
| |
| /* |
| * Cheat by using iconv to convert the .strings file from UTF-16 to UTF-8 |
| * which is what we need for the .po file (and it makes things a lot |
| * simpler...) |
| */ |
| |
| snprintf(iconv, sizeof(iconv), "iconv -f utf-16 -t utf-8 '%s'", argv[1]); |
| if ((strings = popen(iconv, "r")) == NULL) |
| { |
| perror(argv[1]); |
| return (1); |
| } |
| |
| if ((po = fopen(argv[2], "w")) == NULL) |
| { |
| perror(argv[2]); |
| pclose(strings); |
| return (1); |
| } |
| |
| count = 0; |
| |
| while (read_strings(strings, buffer, sizeof(buffer), &id, &str)) |
| { |
| count ++; |
| write_po(po, "msgid", id); |
| write_po(po, "msgstr", str); |
| } |
| |
| pclose(strings); |
| fclose(po); |
| |
| printf("%s: %d messages.\n", argv[2], count); |
| |
| return (0); |
| } |
| |
| |
| /* |
| * 'read_strings()' - Read a line from a .strings file. |
| */ |
| |
| static int /* O - 1 on success, 0 on failure */ |
| read_strings(FILE *strings, /* I - .strings file */ |
| char *buffer, /* I - Line buffer */ |
| size_t bufsize, /* I - Size of line buffer */ |
| char **id, /* O - Pointer to ID string */ |
| char **str) /* O - Pointer to translation string */ |
| { |
| char *bufptr; /* Pointer into buffer */ |
| |
| |
| while (fgets(buffer, (int)bufsize, strings)) |
| { |
| if (buffer[0] != '\"') |
| continue; |
| |
| *id = buffer + 1; |
| |
| for (bufptr = buffer + 1; *bufptr && *bufptr != '\"'; bufptr ++) |
| if (*bufptr == '\\') |
| bufptr ++; |
| |
| if (*bufptr != '\"') |
| continue; |
| |
| *bufptr++ = '\0'; |
| |
| while (*bufptr && *bufptr != '\"') |
| bufptr ++; |
| |
| if (!*bufptr) |
| continue; |
| |
| bufptr ++; |
| *str = bufptr; |
| |
| for (; *bufptr && *bufptr != '\"'; bufptr ++) |
| if (*bufptr == '\\') |
| bufptr ++; |
| |
| if (*bufptr != '\"') |
| continue; |
| |
| *bufptr = '\0'; |
| |
| return (1); |
| } |
| |
| return (0); |
| } |
| |
| |
| /* |
| * 'write_po()' - Write a line to the .po file. |
| */ |
| |
| static void |
| write_po(FILE *po, /* I - .po file */ |
| const char *what, /* I - Type of string */ |
| const char *s) /* I - String to write */ |
| { |
| fprintf(po, "%s \"%s\"\n", what, s); |
| } |