/*
- * "$Id: po2strings.c 6921 2007-09-06 13:38:37Z mike $"
+ * Convert a GNU gettext .po file to an Apple .strings file.
*
- * Convert a GNU gettext .po file to an Apple .strings file.
+ * Copyright 2007-2017 by Apple Inc.
*
- * Copyright 2007-2012 by Apple Inc.
- *
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
+ * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
*
* Usage:
*
* Compile with:
*
* gcc -o po2strings po2strings.c `cups-config --libs`
- *
- * Contents:
- *
- * main() - Convert .po file to .strings.
*/
#include <cups/cups-private.h>
* characters like newline and the double quote character.
*/
+static char *normalize_string(const char *idstr, char *buffer, size_t bufsize);
+
+
/*
* main() - Convert .po file to .strings.
*/
*ptr, /* Pointer into buffer */
*temp, /* New string */
*msgid, /* msgid string */
- *msgstr; /* msgstr string */
- int length; /* Length of combined strings */
+ *msgstr, /* msgstr string */
+ normalized[8192];/* Normalized msgid string */
+ size_t length; /* Length of combined strings */
int use_msgid; /* Use msgid strings for msgstr? */
if (msgid && msgstr)
{
if (*msgid)
- cupsFilePrintf(strings, "\"%s\" = \"%s\";\n", msgid,
- (use_msgid || !*msgstr) ? msgid : msgstr);
+ cupsFilePrintf(strings, "\"%s\" = \"%s\";\n", msgid, normalize_string((use_msgid || !*msgstr) ? msgid : msgstr, normalized, sizeof(normalized)));
}
if (msgid)
* Append to current string...
*/
- length = (int)strlen(msgstr ? msgstr : msgid);
+ size_t ptrlen = strlen(ptr); /* Length of string */
+
+ length = strlen(msgstr ? msgstr : msgid);
if ((temp = realloc(msgstr ? msgstr : msgid,
- length + strlen(ptr) + 1)) == NULL)
+ length + ptrlen + 1)) == NULL)
{
free(msgid);
if (msgstr)
msgstr = temp;
- strcpy(msgstr + length, ptr);
+ memcpy(msgstr + length, ptr, ptrlen + 1);
}
else
{
msgid = temp;
- strcpy(msgid + length, ptr);
+ memcpy(msgid + length, ptr, ptrlen + 1);
}
}
else if (!strncmp(s, "msgstr", 6) && msgid)
if (msgid && msgstr)
{
if (*msgid)
- cupsFilePrintf(strings, "\"%s\" = \"%s\";\n", msgid,
- (use_msgid || !*msgstr) ? msgid : msgstr);
+ cupsFilePrintf(strings, "\"%s\" = \"%s\";\n", msgid, normalize_string((use_msgid || !*msgstr) ? msgid : msgstr, normalized, sizeof(normalized)));
}
if (msgid)
/*
- * End of "$Id: po2strings.c 6921 2007-09-06 13:38:37Z mike $".
+ * 'normalize_string()' - Normalize a msgid string.
+ *
+ * This function converts ASCII ellipsis and double quotes to their Unicode
+ * counterparts.
*/
+
+static char * /* O - Normalized string */
+normalize_string(const char *idstr, /* I - msgid string */
+ char *buffer, /* I - Normalized string buffer */
+ size_t bufsize) /* I - Size of string buffer */
+{
+ char *bufptr = buffer, /* Pointer into buffer */
+ *bufend = buffer + bufsize - 3; /* End of buffer */
+ int quote = 0, /* Quote direction */
+ html = 0; /* HTML text */
+
+
+ while (*idstr && bufptr < bufend)
+ {
+ if (!strncmp(idstr, "<A ", 3))
+ html = 1;
+ else if (html && *idstr == '>')
+ html = 0;
+
+ if (*idstr == '.' && idstr[1] == '.' && idstr[2] == '.')
+ {
+ /*
+ * Convert ... to Unicode ellipsis...
+ */
+
+ *bufptr++ = (char)0xE2;
+ *bufptr++ = (char)0x80;
+ *bufptr++ = (char)0xA6;
+ idstr += 2;
+ }
+ else if (!html && *idstr == '\\' && idstr[1] == '\"')
+ {
+ if (quote)
+ {
+ /*
+ * Convert second \" to Unicode right (curley) double quote.
+ */
+
+ *bufptr++ = (char)0xE2;
+ *bufptr++ = (char)0x80;
+ *bufptr++ = (char)0x9D;
+ quote = 0;
+ }
+ else if (strchr(idstr + 2, '\"') != NULL)
+ {
+ /*
+ * Convert first \" to Unicode left (curley) double quote.
+ */
+
+ *bufptr++ = (char)0xE2;
+ *bufptr++ = (char)0x80;
+ *bufptr++ = (char)0x9C;
+ quote = 1;
+ }
+ else
+ {
+ /*
+ * Convert lone \" to Unicode double prime.
+ */
+
+ *bufptr++ = (char)0xE2;
+ *bufptr++ = (char)0x80;
+ *bufptr++ = (char)0xB3;
+ }
+
+ idstr ++;
+ }
+ else if (*idstr == '\'')
+ {
+ if (strchr(idstr + 1, '\'') == NULL || quote)
+ {
+ /*
+ * Convert second ' (or ' used for a contraction) to Unicode right
+ * (curley) single quote.
+ */
+
+ *bufptr++ = (char)0xE2;
+ *bufptr++ = (char)0x80;
+ *bufptr++ = (char)0x99;
+ quote = 0;
+ }
+ else
+ {
+ /*
+ * Convert first ' to Unicode left (curley) single quote.
+ */
+
+ *bufptr++ = (char)0xE2;
+ *bufptr++ = (char)0x80;
+ *bufptr++ = (char)0x98;
+ quote = 1;
+ }
+ }
+ else
+ *bufptr++ = *idstr;
+
+ idstr ++;
+ }
+
+ *bufptr = '\0';
+
+ return (buffer);
+}