diff options
author | Bruno Haible <bruno@clisp.org> | 2002-10-04 11:36:54 +0000 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2009-06-23 12:08:46 +0200 |
commit | 37b1870c1979c42adbca49825ee14cbe9bd33ca1 (patch) | |
tree | 724547f811bd2f15bc74f838e870dfbd1daa5cff | |
parent | 0ebb4fc90b909227965fbacbdd974f682472adfc (diff) | |
download | external_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/ChangeLog | 10 | ||||
-rw-r--r-- | po/Makefile.in.in | 28 | ||||
-rw-r--r-- | src/ChangeLog | 11 | ||||
-rw-r--r-- | src/msgl-equal.c | 126 | ||||
-rw-r--r-- | src/msgl-equal.h | 11 | ||||
-rw-r--r-- | src/msgmerge.c | 7 |
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; |