]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Message list header manipulation.
authorBruno Haible <bruno@clisp.org>
Wed, 26 Dec 2007 16:01:30 +0000 (16:01 +0000)
committerBruno Haible <bruno@clisp.org>
Tue, 23 Jun 2009 10:15:35 +0000 (12:15 +0200)
gettext-tools/src/msgl-header.c [new file with mode: 0644]
gettext-tools/src/msgl-header.h [new file with mode: 0644]

diff --git a/gettext-tools/src/msgl-header.c b/gettext-tools/src/msgl-header.c
new file mode 100644 (file)
index 0000000..0e1ba9b
--- /dev/null
@@ -0,0 +1,170 @@
+/* Message list header manipulation.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno@clisp.org>, 2007.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+/* Specification.  */
+#include "msgl-header.h"
+
+#include <string.h>
+
+#include "xalloc.h"
+
+#define SIZEOF(a) (sizeof(a) / sizeof(a[0]))
+
+
+void
+msgdomain_list_set_header_field (msgdomain_list_ty *mdlp,
+                                const char *field, const char *value)
+{
+  /* The known fields in their usual order.  */
+  static const struct
+    {
+      const char *name;
+      size_t len;
+    }
+  known_fields[] =
+    {
+      { "Project-Id-Version:", sizeof ("Project-Id-Version:") - 1 },
+      { "Report-Msgid-Bugs-To:", sizeof ("Report-Msgid-Bugs-To:") - 1 },
+      { "POT-Creation-Date:", sizeof ("POT-Creation-Date:") - 1 },
+      { "PO-Revision-Date:", sizeof ("PO-Revision-Date:") - 1 },
+      { "Last-Translator:", sizeof ("Last-Translator:") - 1 },
+      { "Language-Team:", sizeof ("Language-Team:") - 1 },
+      { "Language:", sizeof ("Language:") - 1 },
+      { "MIME-Version:", sizeof ("MIME-Version:") - 1 },
+      { "Content-Type:", sizeof ("Content-Type:") - 1 },
+      { "Content-Transfer-Encoding:",
+       sizeof ("Content-Transfer-Encoding:") - 1 }
+    };
+  size_t field_len;
+  int field_index;
+  size_t k, i;
+
+  field_len = strlen (field);
+
+  /* Search the field in known_fields[].  */
+  field_index = -1;
+  for (k = 0; k < SIZEOF (known_fields); k++)
+    if (strcmp (known_fields[k].name, field) == 0)
+      {
+       field_index = k;
+       break;
+      }
+
+  for (i = 0; i < mdlp->nitems; i++)
+    {
+      message_list_ty *mlp = mdlp->item[i]->messages;
+      size_t j;
+
+      /* Search the header entry.  */
+      for (j = 0; j < mlp->nitems; j++)
+       if (is_header (mlp->item[j]) && !mlp->item[j]->obsolete)
+         {
+           message_ty *mp = mlp->item[j];
+
+           /* Modify the header entry.  */
+           const char *header = mp->msgstr;
+           char *new_header =
+             XNMALLOC (strlen (header) + 1
+                       + strlen (field) + 1 + strlen (value) + 1 + 1,
+                       char);
+
+           /* Test whether the field already occurs in the header entry.  */
+           const char *h;
+
+           for (h = header; *h != '\0'; )
+             {
+               if (strncmp (h, field, field_len) == 0)
+                 break;
+               h = strchr (h, '\n');
+               if (h == NULL)
+                 break;
+               h++;
+             }
+           if (h != NULL && *h != '\0')
+             {
+               /* Replace the field.  */
+               char *p = new_header;
+               memcpy (p, header, h - header);
+               p += h - header;
+               p = stpcpy (p, field);
+               p = stpcpy (stpcpy (stpcpy (p, " "), value), "\n");
+               h = strchr (h, '\n');
+               if (h != NULL)
+                 {
+                   h++;
+                   stpcpy (p, h);
+                 }
+             }
+           else if (field_index < 0)
+             {
+               /* An unknown field.  Append it at the end.  */
+               char *p = new_header;
+               p = stpcpy (p, header);
+               if (p > new_header && p[-1] != '\n')
+                 *p++ = '\n';
+               p = stpcpy (p, field);
+               stpcpy (stpcpy (stpcpy (p, " "), value), "\n");
+             }
+           else
+             {
+               /* Find the appropriate position for inserting the field.  */
+               for (h = header; *h != '\0'; )
+                 {
+                   /* Test whether h starts with a field name whose index is
+                      > field_index.  */
+                   for (k = field_index + 1; k < SIZEOF (known_fields); k++)
+                     if (strncmp (h, known_fields[k].name, known_fields[k].len)
+                         == 0)
+                       break;
+                   if (k < SIZEOF (known_fields))
+                     break;
+                   h = strchr (h, '\n');
+                   if (h == NULL)
+                     break;
+                   h++;
+                 }
+               if (h != NULL && *h != '\0')
+                 {
+                   /* Insert the field at position h.  */
+                   char *p = new_header;
+                   memcpy (p, header, h - header);
+                   p += h - header;
+                   p = stpcpy (p, field);
+                   p = stpcpy (stpcpy (stpcpy (p, " "), value), "\n");
+                   stpcpy (p, h);
+                 }
+               else
+                 {
+                   /* Append it at the end.  */
+                   char *p = new_header;
+                   p = stpcpy (p, header);
+                   if (p > new_header && p[-1] != '\n')
+                     *p++ = '\n';
+                   p = stpcpy (p, field);
+                   stpcpy (stpcpy (stpcpy (p, " "), value), "\n");
+                 }
+             }
+
+           mp->msgstr = new_header;
+         }
+    }
+}
diff --git a/gettext-tools/src/msgl-header.h b/gettext-tools/src/msgl-header.h
new file mode 100644 (file)
index 0000000..9fb501a
--- /dev/null
@@ -0,0 +1,43 @@
+/* Message list header manipulation.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno@clisp.org>, 2007.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _MSGL_HEADER_H
+#define _MSGL_HEADER_H
+
+#include "message.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Set the given field to the given value.
+   The FIELD name ends in a colon.
+   The VALUE will have a space prepended and a newline appended by this
+   function.  */
+extern void
+       msgdomain_list_set_header_field (msgdomain_list_ty *mdlp,
+                                       const char *field, const char *value);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _MSGL_HEADER_H */