#include <cups/cups-private.h>
static char *normalize_string(const char *idstr, char *buffer, size_t bufsize);
int
main(int argc,
char *argv[])
{
int i;
const char *pofile,
*stringsfile;
cups_file_t *po,
*strings;
char s[4096],
*ptr,
*temp,
*msgid,
*msgstr,
normalized[8192];
size_t length;
int use_msgid;
pofile = NULL;
stringsfile = NULL;
use_msgid = 0;
for (i = 1; i < argc; i ++)
{
if (!strcmp(argv[i], "-m"))
use_msgid = 1;
else if (argv[i][0] == '-')
{
puts("Usage: po2strings [-m] filename.po filename.strings");
return (1);
}
else if (!pofile)
pofile = argv[i];
else if (!stringsfile)
stringsfile = argv[i];
else
{
puts("Usage: po2strings [-m] filename.po filename.strings");
return (1);
}
}
if (!pofile || !stringsfile)
{
puts("Usage: po2strings [-m] filename.po filename.strings");
return (1);
}
if ((po = cupsFileOpen(pofile, "r")) == NULL)
{
perror(pofile);
return (1);
}
if ((strings = cupsFileOpen(stringsfile, "w")) == NULL)
{
perror(stringsfile);
cupsFileClose(po);
return (1);
}
msgid = msgstr = NULL;
while (cupsFileGets(po, s, sizeof(s)) != NULL)
{
if (s[0] == '#' && s[1] == '.')
{
if (msgid && msgstr)
{
if (*msgid)
cupsFilePrintf(strings, "\"%s\" = \"%s\";\n", msgid,
(use_msgid || !*msgstr) ? msgid : msgstr);
free(msgid);
free(msgstr);
msgid = msgstr = NULL;
}
cupsFilePrintf(strings, "//%s\n", s + 2);
}
else if (s[0] == '#' || !s[0])
{
continue;
}
else
{
if ((ptr = strrchr(s, '\"')) == NULL)
continue;
*ptr = '\0';
if ((ptr = strchr(s, '\"')) == NULL)
continue;
ptr ++;
if (!strncmp(s, "msgid", 5))
{
if (msgid && msgstr)
{
if (*msgid)
cupsFilePrintf(strings, "\"%s\" = \"%s\";\n", msgid, normalize_string((use_msgid || !*msgstr) ? msgid : msgstr, normalized, sizeof(normalized)));
}
if (msgid)
free(msgid);
if (msgstr)
free(msgstr);
msgid = strdup(ptr);
msgstr = NULL;
}
else if (s[0] == '\"' && (msgid || msgstr))
{
size_t ptrlen = strlen(ptr);
length = strlen(msgstr ? msgstr : msgid);
if ((temp = realloc(msgstr ? msgstr : msgid,
length + ptrlen + 1)) == NULL)
{
free(msgid);
if (msgstr)
free(msgstr);
perror("Unable to allocate string");
return (1);
}
if (msgstr)
{
msgstr = temp;
memcpy(msgstr + length, ptr, ptrlen + 1);
}
else
{
msgid = temp;
memcpy(msgid + length, ptr, ptrlen + 1);
}
}
else if (!strncmp(s, "msgstr", 6) && msgid)
{
if (msgstr)
free(msgstr);
if ((msgstr = strdup(ptr)) == NULL)
{
free(msgid);
perror("Unable to allocate msgstr");
return (1);
}
}
}
}
if (msgid && msgstr)
{
if (*msgid)
cupsFilePrintf(strings, "\"%s\" = \"%s\";\n", msgid, normalize_string((use_msgid || !*msgstr) ? msgid : msgstr, normalized, sizeof(normalized)));
}
if (msgid)
free(msgid);
if (msgstr)
free(msgstr);
cupsFileClose(po);
cupsFileClose(strings);
return (0);
}
static char *
normalize_string(const char *idstr,
char *buffer,
size_t bufsize)
{
char *bufptr = buffer,
*bufend = buffer + bufsize - 3;
int quote = 0,
html = 0;
while (*idstr && bufptr < bufend)
{
if (!strncmp(idstr, "<A ", 3))
html = 1;
else if (html && *idstr == '>')
html = 0;
if (*idstr == '.' && idstr[1] == '.' && idstr[2] == '.')
{
*bufptr++ = (char)0xE2;
*bufptr++ = (char)0x80;
*bufptr++ = (char)0xA6;
idstr += 2;
}
else if (!html && *idstr == '\\' && idstr[1] == '\"' && (quote || strchr(idstr + 2, '\"') != NULL))
{
if (quote)
{
*bufptr++ = (char)0xE2;
*bufptr++ = (char)0x80;
*bufptr++ = (char)0x9D;
}
else
{
*bufptr++ = (char)0xE2;
*bufptr++ = (char)0x80;
*bufptr++ = (char)0x9C;
}
quote = !quote;
idstr ++;
}
else
*bufptr++ = *idstr;
idstr ++;
}
*bufptr = '\0';
return (buffer);
}