]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - locale/po2strings.c
Changelog
[thirdparty/cups.git] / locale / po2strings.c
index ce89266e0780c3a976ab9ad319d1c4caf035d30b..e8732407cf27aeff1b60cb2f9eb675133e65150d 100644 (file)
@@ -1,15 +1,9 @@
 /*
- * "$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-2010 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>
@@ -53,6 +43,9 @@
  * 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.
  */
@@ -70,8 +63,9 @@ main(int  argc,                               /* I - Number of command-line args */
                        *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? */
 
 
@@ -130,21 +124,36 @@ main(int  argc,                           /* I - Number of command-line args */
 
   while (cupsFileGets(po, s, sizeof(s)) != NULL)
   {
-    if ((s[0] == '#' && s[0] != '.') || !s[0])
+    if (s[0] == '#' && s[1] == '.')
     {
      /*
-      * Skip blank and file comment lines...
+      * Copy comment string...
       */
 
-      continue;
+      if (msgid && msgstr)
+      {
+       /*
+        * First output the last localization string...
+       */
+
+       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] == '#')
+    else if (s[0] == '#' || !s[0])
     {
      /*
-      * Copy comment string...
+      * Skip blank and file comment lines...
       */
 
-      cupsFilePrintf(strings, "//%s\n", s + 2);
+      continue;
     }
     else
     {
@@ -160,7 +169,7 @@ main(int  argc,                             /* I - Number of command-line args */
      /*
       * Find start of value...
       */
-      
+
       if ((ptr = strchr(s, '\"')) == NULL)
        continue;
 
@@ -179,27 +188,34 @@ main(int  argc,                           /* I - Number of command-line args */
         if (msgid && msgstr)
        {
          if (*msgid)
-            cupsFilePrintf(strings, "\"%s\" = \"%s\";\n\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)
          free(msgid);
+
+       if (msgstr)
          free(msgstr);
-       }
 
         msgid  = strdup(ptr);
        msgstr = NULL;
       }
-      else if (s[0] == '\"' )
+      else if (s[0] == '\"' && (msgid || msgstr))
       {
        /*
        * 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)
+           free(msgstr);
          perror("Unable to allocate string");
          return (1);
        }
@@ -214,7 +230,7 @@ main(int  argc,                             /* I - Number of command-line args */
 
          msgstr = temp;
 
-         strcpy(msgstr + length, ptr);
+         memcpy(msgstr + length, ptr, ptrlen + 1);
        }
        else
        {
@@ -226,7 +242,7 @@ main(int  argc,                             /* I - Number of command-line args */
 
          msgid = temp;
 
-         strcpy(msgid + length, ptr);
+         memcpy(msgid + length, ptr, ptrlen + 1);
        }
       }
       else if (!strncmp(s, "msgstr", 6) && msgid)
@@ -235,8 +251,12 @@ main(int  argc,                            /* I - Number of command-line args */
        * Set the string...
        */
 
+        if (msgstr)
+          free(msgstr);
+
        if ((msgstr = strdup(ptr)) == NULL)
        {
+         free(msgid);
          perror("Unable to allocate msgstr");
          return (1);
        }
@@ -247,12 +267,14 @@ main(int  argc,                           /* I - Number of command-line args */
   if (msgid && msgstr)
   {
     if (*msgid)
-      cupsFilePrintf(strings, "\"%s\" = \"%s\";\n\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)
     free(msgid);
+
+  if (msgstr)
     free(msgstr);
-  }
 
   cupsFileClose(po);
   cupsFileClose(strings);
@@ -262,5 +284,111 @@ main(int  argc,                           /* I - Number of command-line args */
 
 
 /*
- * 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);
+}