summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2002-10-04 11:36:54 +0000
committerBruno Haible <bruno@clisp.org>2009-06-23 12:08:46 +0200
commit37b1870c1979c42adbca49825ee14cbe9bd33ca1 (patch)
tree724547f811bd2f15bc74f838e870dfbd1daa5cff
parent0ebb4fc90b909227965fbacbdd974f682472adfc (diff)
downloadexternal_gettext-37b1870c1979c42adbca49825ee14cbe9bd33ca1.zip
external_gettext-37b1870c1979c42adbca49825ee14cbe9bd33ca1.tar.gz
external_gettext-37b1870c1979c42adbca49825ee14cbe9bd33ca1.tar.bz2
Avoid modifying PO files if the POT file is the same except for a different
POT-Creation-Date.
-rw-r--r--po/ChangeLog10
-rw-r--r--po/Makefile.in.in28
-rw-r--r--src/ChangeLog11
-rw-r--r--src/msgl-equal.c126
-rw-r--r--src/msgl-equal.h11
-rw-r--r--src/msgmerge.c7
6 files changed, 172 insertions, 21 deletions
diff --git a/po/ChangeLog b/po/ChangeLog
index bb663f5..5b3a75e 100644
--- a/po/ChangeLog
+++ b/po/ChangeLog
@@ -1,3 +1,13 @@
+2002-10-03 Bruno Haible <bruno@clisp.org>
+
+ Avoid modifying PO files if the POT file is the same except for a
+ different POT-Creation-Date.
+ * Makefile.in.in (DISTFILES): Add stamp-po.
+ (all-yes): Depend on stamp-po, not directly on CATALOGS.
+ (stamp-po): New rule.
+ (mostlyclean): Also remove stamp-poT.
+ (maintainer-clean): Also remove stamp-po.
+
2002-09-19 Bruno Haible <bruno@clisp.org>
* be.po: Update from Ales Nyakhaychyk <i18n@infonet.by>.
diff --git a/po/Makefile.in.in b/po/Makefile.in.in
index b8eab2b..165e896 100644
--- a/po/Makefile.in.in
+++ b/po/Makefile.in.in
@@ -44,7 +44,7 @@ UPDATEPOFILES = @UPDATEPOFILES@
DUMMYPOFILES = @DUMMYPOFILES@
DISTFILES.common = Makefile.in.in Makevars remove-potcdate.sin \
$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3)
-DISTFILES = $(DISTFILES.common) POTFILES.in $(DOMAIN).pot \
+DISTFILES = $(DISTFILES.common) POTFILES.in $(DOMAIN).pot stamp-po \
$(POFILES) $(GMOFILES) \
$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3)
@@ -74,13 +74,29 @@ CATALOGS = @CATALOGS@
all: all-@USE_NLS@
-all-yes: $(CATALOGS)
+all-yes: stamp-po
all-no:
+# stamp-po is a timestamp denoting the last time at which the CATALOGS have
+# been loosely updated. Its purpose is that when a developer or translator
+# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS,
+# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent
+# invocations of "make" will do nothing. This timestamp would not be necessary
+# if updating the $(CATALOGS) would always touch them; however, the rule for
+# $(POFILES) has been designed to not touch files that don't need to be
+# changed.
+stamp-po: $(srcdir)/$(DOMAIN).pot
+ $(MAKE) $(CATALOGS)
+ @echo "touch stamp-po"
+ @echo timestamp > stamp-poT
+ @mv stamp-poT stamp-po
+
# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update',
# otherwise packages like GCC can not be built if only parts of the source
# have been downloaded.
+# This target rebuilds $(DOMAIN).pot; it is an expensive operation.
+# Note that $(DOMAIN).pot is not touched if it doesn't need to be changed.
$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed
$(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \
--add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) \
@@ -101,9 +117,14 @@ $(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed
fi; \
}
+# This rule has no dependencies: we don't need to update $(DOMAIN).pot at
+# every "make" invocation, only create it when it is missing.
+# Only "make $(DOMAIN).pot-update" or "make dist" will force an update.
$(srcdir)/$(DOMAIN).pot:
$(MAKE) $(DOMAIN).pot-update
+# This target rebuilds a PO file if $(DOMAIN).pot has changed.
+# Note that a PO file is not touched if it doesn't need to be changed.
$(POFILES): $(srcdir)/$(DOMAIN).pot
@lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \
test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
@@ -239,6 +260,7 @@ dvi info tags TAGS ID:
mostlyclean:
rm -f remove-potcdate.sed
+ rm -f stamp-poT
rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po
rm -fr *.o
@@ -250,7 +272,7 @@ distclean: clean
maintainer-clean: distclean
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
- rm -f $(GMOFILES)
+ rm -f stamp-po $(GMOFILES)
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
dist distdir:
diff --git a/src/ChangeLog b/src/ChangeLog
index d5a0d8e..9ec1210 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,14 @@
+2002-10-03 Bruno Haible <bruno@clisp.org>
+
+ * msgl-equal.h (message_equal, message_list_equal,
+ msgdomain_list_equal): Add 'ignore_potcdate' argument.
+ * msgl-equal-c (msgstr_equal, msgstr_equal_ignoring_potcdate): New
+ functions.
+ (message_equal, message_list_equal, msgdomain_equal,
+ msgdomain_list_equal): Add 'ignore_potcdate' argument.
+ * msgmerge.c (main): Call msgdomain_list_equal with ignore_potcdate =
+ true.
+
2002-09-09 Bruno Haible <bruno@clisp.org>
* x-smalltalk.h: New file.
diff --git a/src/msgl-equal.c b/src/msgl-equal.c
index 0c97630..1252af9 100644
--- a/src/msgl-equal.c
+++ b/src/msgl-equal.c
@@ -1,5 +1,5 @@
/* Message list test for equality.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001-2002 Free Software Foundation, Inc.
Written by Bruno Haible <haible@clisp.cons.org>, 2001.
This program is free software; you can redistribute it and/or modify
@@ -24,18 +24,113 @@
/* Specification. */
#include "msgl-equal.h"
+#include <stddef.h>
#include <string.h>
/* Prototypes for local functions. Needed to ensure compiler checking of
function argument counts despite of K&R C function definition syntax. */
+static inline bool msgstr_equal PARAMS ((const char *msgstr1,
+ size_t msgstr1_len,
+ const char *msgstr2,
+ size_t msgstr2_len));
+static inline bool msgstr_equal_ignoring_potcdate PARAMS ((const char *msgstr1,
+ size_t msgstr1_len,
+ const char *msgstr2,
+ size_t msgstr2_len));
static inline bool pos_equal PARAMS ((const lex_pos_ty *pos1,
const lex_pos_ty *pos2));
static inline bool msgdomain_equal PARAMS ((const msgdomain_ty *mdp1,
- const msgdomain_ty *mdp2));
+ const msgdomain_ty *mdp2,
+ bool ignore_potcdate));
static inline bool
+msgstr_equal (msgstr1, msgstr1_len, msgstr2, msgstr2_len)
+ const char *msgstr1;
+ size_t msgstr1_len;
+ const char *msgstr2;
+ size_t msgstr2_len;
+{
+ return (msgstr1_len == msgstr2_len
+ && memcmp (msgstr1, msgstr2, msgstr1_len) == 0);
+}
+
+static bool
+msgstr_equal_ignoring_potcdate (msgstr1, msgstr1_len, msgstr2, msgstr2_len)
+ const char *msgstr1;
+ size_t msgstr1_len;
+ const char *msgstr2;
+ size_t msgstr2_len;
+{
+ const char *msgstr1_end = msgstr1 + msgstr1_len;
+ const char *msgstr2_end = msgstr2 + msgstr2_len;
+ const char *ptr1;
+ const char *ptr2;
+ const char *const field = "POT-Creation-Date:";
+ const ptrdiff_t fieldlen = sizeof ("POT-Creation-Date:") - 1;
+
+ /* Search for the occurrence of field in msgstr1. */
+ for (ptr1 = msgstr1;;)
+ {
+ if (msgstr1_end - ptr1 < fieldlen)
+ {
+ ptr1 = NULL;
+ break;
+ }
+ if (memcmp (ptr1, field, fieldlen) == 0)
+ break;
+ ptr1 = memchr (ptr1, '\n', msgstr1_end - ptr1);
+ if (ptr1 == NULL)
+ break;
+ ptr1++;
+ }
+
+ /* Search for the occurrence of field in msgstr2. */
+ for (ptr2 = msgstr2;;)
+ {
+ if (msgstr2_end - ptr2 < fieldlen)
+ {
+ ptr2 = NULL;
+ break;
+ }
+ if (memcmp (ptr2, field, fieldlen) == 0)
+ break;
+ ptr2 = memchr (ptr2, '\n', msgstr2_end - ptr2);
+ if (ptr2 == NULL)
+ break;
+ ptr2++;
+ }
+
+ if (ptr1 == NULL)
+ {
+ if (ptr2 == NULL)
+ return msgstr_equal (msgstr1, msgstr1_len, msgstr2, msgstr2_len);
+ }
+ else
+ {
+ if (ptr2 != NULL)
+ {
+ /* Compare, ignoring the lines starting at ptr1 and ptr2. */
+ if (msgstr_equal (msgstr1, ptr1 - msgstr1, msgstr2, ptr2 - msgstr2))
+ {
+ ptr1 = memchr (ptr1, '\n', msgstr1_end - ptr1);
+ if (ptr1 == NULL)
+ ptr1 = msgstr1_end;
+
+ ptr2 = memchr (ptr2, '\n', msgstr2_end - ptr2);
+ if (ptr2 == NULL)
+ ptr2 = msgstr2_end;
+
+ return msgstr_equal (ptr1, msgstr1_end - ptr1,
+ ptr2, msgstr2_end - ptr2);
+ }
+ }
+ }
+ return false;
+}
+
+static inline bool
pos_equal (pos1, pos2)
const lex_pos_ty *pos1;
const lex_pos_ty *pos2;
@@ -63,9 +158,10 @@ string_list_equal (slp1, slp2)
}
bool
-message_equal (mp1, mp2)
+message_equal (mp1, mp2, ignore_potcdate)
const message_ty *mp1;
const message_ty *mp2;
+ bool ignore_potcdate;
{
size_t i, i1, i2;
@@ -78,9 +174,11 @@ message_equal (mp1, mp2)
: mp2->msgid_plural == NULL))
return false;
- if (mp1->msgstr_len != mp2->msgstr_len)
- return false;
- if (memcmp (mp1->msgstr, mp2->msgstr, mp1->msgstr_len) != 0)
+ if (mp1->msgid[0] == '\0' && ignore_potcdate
+ ? !msgstr_equal_ignoring_potcdate (mp1->msgstr, mp1->msgstr_len,
+ mp2->msgstr, mp2->msgstr_len)
+ : !msgstr_equal (mp1->msgstr, mp1->msgstr_len,
+ mp2->msgstr, mp2->msgstr_len))
return false;
if (!pos_equal (&mp1->pos, &mp2->pos))
@@ -114,9 +212,10 @@ message_equal (mp1, mp2)
}
bool
-message_list_equal (mlp1, mlp2)
+message_list_equal (mlp1, mlp2, ignore_potcdate)
const message_list_ty *mlp1;
const message_list_ty *mlp2;
+ bool ignore_potcdate;
{
size_t i, i1, i2;
@@ -125,24 +224,27 @@ message_list_equal (mlp1, mlp2)
if (i1 != i2)
return false;
for (i = 0; i < i1; i++)
- if (!message_equal (mlp1->item[i], mlp2->item[i]))
+ if (!message_equal (mlp1->item[i], mlp2->item[i], ignore_potcdate))
return false;
return true;
}
static inline bool
-msgdomain_equal (mdp1, mdp2)
+msgdomain_equal (mdp1, mdp2, ignore_potcdate)
const msgdomain_ty *mdp1;
const msgdomain_ty *mdp2;
+ bool ignore_potcdate;
{
return (strcmp (mdp1->domain, mdp2->domain) == 0
- && message_list_equal (mdp1->messages, mdp2->messages));
+ && message_list_equal (mdp1->messages, mdp2->messages,
+ ignore_potcdate));
}
bool
-msgdomain_list_equal (mdlp1, mdlp2)
+msgdomain_list_equal (mdlp1, mdlp2, ignore_potcdate)
const msgdomain_list_ty *mdlp1;
const msgdomain_list_ty *mdlp2;
+ bool ignore_potcdate;
{
size_t i, i1, i2;
@@ -151,7 +253,7 @@ msgdomain_list_equal (mdlp1, mdlp2)
if (i1 != i2)
return false;
for (i = 0; i < i1; i++)
- if (!msgdomain_equal (mdlp1->item[i], mdlp2->item[i]))
+ if (!msgdomain_equal (mdlp1->item[i], mdlp2->item[i], ignore_potcdate))
return false;
return true;
}
diff --git a/src/msgl-equal.h b/src/msgl-equal.h
index c707289..c131b2d 100644
--- a/src/msgl-equal.h
+++ b/src/msgl-equal.h
@@ -1,5 +1,5 @@
/* Message list test for equality.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001-2002 Free Software Foundation, Inc.
Written by Bruno Haible <haible@clisp.cons.org>, 2001.
This program is free software; you can redistribute it and/or modify
@@ -31,12 +31,15 @@ extern bool
would be the same. */
extern bool
- message_equal PARAMS ((const message_ty *mp1, const message_ty *mp2));
+ message_equal PARAMS ((const message_ty *mp1, const message_ty *mp2,
+ bool ignore_potcdate));
extern bool
message_list_equal PARAMS ((const message_list_ty *mlp1,
- const message_list_ty *mlp2));
+ const message_list_ty *mlp2,
+ bool ignore_potcdate));
extern bool
msgdomain_list_equal PARAMS ((const msgdomain_list_ty *mdlp1,
- const msgdomain_list_ty *mdlp2));
+ const msgdomain_list_ty *mdlp2,
+ bool ignore_potcdate));
#endif /* _MSGL_EQUAL_H */
diff --git a/src/msgmerge.c b/src/msgmerge.c
index bf45a2b..dc71eb3 100644
--- a/src/msgmerge.c
+++ b/src/msgmerge.c
@@ -336,8 +336,11 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
if (update_mode)
{
- /* Do nothing if the original file and the result are equal. */
- if (!msgdomain_list_equal (def, result))
+ /* Do nothing if the original file and the result are equal. Also do
+ nothing if the original file and the result differ only by the
+ POT-Creation-Date in the header entry; this is needed for projects
+ which don't put the .pot file under CVS. */
+ if (!msgdomain_list_equal (def, result, true))
{
/* Back up def.po. */
enum backup_type backup_type;