@@ -0,0 +1,139 @@
+#include <gettext-po.h>
+#include "cache.h"
+#include "strbuf.h"
+
+static void xerror(int severity,
+ po_message_t message,
+ const char *filename, size_t lineno, size_t column,
+ int multiline_p, const char *message_text)
+{
+ die("%s:%d:%d %s", filename, lineno, column, message_text);
+}
+
+static void xerror2(int severity,
+ po_message_t message1,
+ const char *filename1, size_t lineno1, size_t column1,
+ int multiline_p1, const char *message_text1,
+ po_message_t message2,
+ const char *filename2, size_t lineno2, size_t column2,
+ int multiline_p2, const char *message_text2)
+{
+ die("%s:%d:%d %s (%s:%d:%d %s)",
+ filename1, lineno1, column1, message_text1,
+ filename2, lineno2, column2, message_text2);
+}
+
+static void translate(const char *msg, struct strbuf *buf)
+{
+ const char *end = msg + strlen(msg);
+ const char *text = "* GETTEXT POISON *";
+ int text_len = strlen(text);
+ int t = 0;
+
+ strbuf_reset(buf);
+ /* preserve \n and printf format specifiers because msgfmt
+ barfs otherwise. */
+ while (msg < end) {
+ /* printf specifiers and shell variables, it's a quite
+ relax check */
+ if ((*msg == '%' || *msg == '$') && msg+1 < end) {
+ strbuf_addch(buf, *msg++);
+ do
+ strbuf_addch(buf, *msg);
+ while (msg < end && !isspace(*msg++));
+ } else if (*msg == '\n') {
+ /* we only need to preserve trailing newlines, doing
+ more does not really harm */
+ strbuf_addch(buf, '\n');
+ msg++;
+ } else {
+ strbuf_addch(buf, text[t]);
+ t = (t + 1) % text_len;
+ msg++;
+ }
+ }
+}
+
+int main(int argc, char **argv)
+{
+ const char *project_header = "Project-Id-Version: ";
+ const char *charset_header = "Content-Type: text/plain; charset=";
+ const char *plural_header = "Plural-Forms: nplurals=";
+ struct po_xerror_handler handler = { xerror, xerror2 };
+ po_file_t src;
+ const char *file = argv[1];
+ po_message_iterator_t iter;
+ po_message_t msg;
+ struct strbuf buf = STRBUF_INIT;
+
+ if (argc != 3)
+ die("usage: test-poisongen <pot file> <poison po file>");
+
+ src = po_file_read(file, &handler);
+ if (src == NULL)
+ die("could not open %s\n", file);
+
+ iter = po_message_iterator(src, "messages");
+ while ((msg = po_next_message(iter)) != NULL) {
+ /* msgid "" is the header, special handling */
+ if (po_message_msgid(msg)[0] == '\0') {
+ const char *p;
+
+ /* no fuzzy, msgfmt does not like it */
+ po_message_set_fuzzy(msg, 0);
+
+ strbuf_reset(&buf);
+ strbuf_addstr(&buf, po_message_msgstr(msg));
+
+ if (!prefixcmp(buf.buf, project_header) &&
+ !prefixcmp(buf.buf + strlen(project_header),
+ "PACKAGE VERSION\n")) {
+ strbuf_splice(&buf, strlen(project_header),
+ strlen("PACKAGE VERSION"),
+ "git poison",
+ strlen("git poison"));
+ }
+
+ /* Content-Type: text/plain; charset=UTF-8 */
+ if ((p = strstr(buf.buf, charset_header)) != NULL &&
+ !prefixcmp(p + strlen(charset_header), "CHARSET\n")) {
+ p += strlen(charset_header);
+ strbuf_splice(&buf, p - buf.buf, strlen("CHARSET"),
+ "UTF-8", strlen("UTF-8"));
+ }
+
+ /* Plural-Forms: nplurals=2; plural=1 */
+ if ((p = strstr(buf.buf, plural_header)) != NULL &&
+ !prefixcmp(p + strlen(plural_header), "INTEGER; plural=EXPRESSION")) {
+ int offset;
+ p += strlen(plural_header);
+ offset = p - buf.buf;
+ strbuf_splice(&buf, offset, strlen("INTEGER"), "2", 1);
+ offset += 1;
+ assert(!prefixcmp(buf.buf + offset, "; plural=EXPRESSION"));
+ offset += strlen("; plural=");
+ strbuf_splice(&buf, offset, strlen("EXPRESSION"), "1", 1);
+ }
+
+ po_message_set_msgstr(msg, buf.buf);
+ continue;
+ }
+ if (po_message_msgid_plural(msg)) {
+ int index = 0;
+
+ translate(po_message_msgid(msg), &buf);
+ po_message_set_msgstr_plural(msg, index++, buf.buf);
+
+ while (po_message_msgstr_plural(msg, index)) {
+ translate(po_message_msgid_plural(msg), &buf);
+ po_message_set_msgstr_plural(msg, index++, buf.buf);
+ }
+ } else {
+ translate(po_message_msgid(msg), &buf);
+ po_message_set_msgstr(msg, buf.buf);
+ }
+ }
+
+ po_file_write(src, argv[2], &handler);
+ return 0;
+}