• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500-V1.0.1.40_1.0.68/ap/gpl/timemachine/gettext-0.17/gettext-tools/src/
1/* Message list test for equality.
2   Copyright (C) 2001-2002, 2005-2006 Free Software Foundation, Inc.
3   Written by Bruno Haible <haible@clisp.cons.org>, 2001.
4
5   This program is free software: you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 3 of the License, or
8   (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18
19#ifdef HAVE_CONFIG_H
20# include "config.h"
21#endif
22
23/* Specification.  */
24#include "msgl-equal.h"
25
26#include <stddef.h>
27#include <string.h>
28
29
30static inline bool
31msgstr_equal (const char *msgstr1, size_t msgstr1_len,
32	      const char *msgstr2, size_t msgstr2_len)
33{
34  return (msgstr1_len == msgstr2_len
35	  && memcmp (msgstr1, msgstr2, msgstr1_len) == 0);
36}
37
38static bool
39msgstr_equal_ignoring_potcdate (const char *msgstr1, size_t msgstr1_len,
40				const char *msgstr2, size_t msgstr2_len)
41{
42  const char *msgstr1_end = msgstr1 + msgstr1_len;
43  const char *msgstr2_end = msgstr2 + msgstr2_len;
44  const char *ptr1;
45  const char *ptr2;
46  const char *const field = "POT-Creation-Date:";
47  const ptrdiff_t fieldlen = sizeof ("POT-Creation-Date:") - 1;
48
49  /* Search for the occurrence of field in msgstr1.  */
50  for (ptr1 = msgstr1;;)
51    {
52      if (msgstr1_end - ptr1 < fieldlen)
53	{
54	  ptr1 = NULL;
55	  break;
56	}
57      if (memcmp (ptr1, field, fieldlen) == 0)
58	break;
59      ptr1 = (const char *) memchr (ptr1, '\n', msgstr1_end - ptr1);
60      if (ptr1 == NULL)
61	break;
62      ptr1++;
63    }
64
65  /* Search for the occurrence of field in msgstr2.  */
66  for (ptr2 = msgstr2;;)
67    {
68      if (msgstr2_end - ptr2 < fieldlen)
69	{
70	  ptr2 = NULL;
71	  break;
72	}
73      if (memcmp (ptr2, field, fieldlen) == 0)
74	break;
75      ptr2 = (const char *) memchr (ptr2, '\n', msgstr2_end - ptr2);
76      if (ptr2 == NULL)
77	break;
78      ptr2++;
79    }
80
81  if (ptr1 == NULL)
82    {
83      if (ptr2 == NULL)
84	return msgstr_equal (msgstr1, msgstr1_len, msgstr2, msgstr2_len);
85    }
86  else
87    {
88      if (ptr2 != NULL)
89	{
90	  /* Compare, ignoring the lines starting at ptr1 and ptr2.  */
91	  if (msgstr_equal (msgstr1, ptr1 - msgstr1, msgstr2, ptr2 - msgstr2))
92	    {
93	      ptr1 = (const char *) memchr (ptr1, '\n', msgstr1_end - ptr1);
94	      if (ptr1 == NULL)
95		ptr1 = msgstr1_end;
96
97	      ptr2 = (const char *) memchr (ptr2, '\n', msgstr2_end - ptr2);
98	      if (ptr2 == NULL)
99		ptr2 = msgstr2_end;
100
101	      return msgstr_equal (ptr1, msgstr1_end - ptr1,
102				   ptr2, msgstr2_end - ptr2);
103	    }
104	}
105    }
106  return false;
107}
108
109static inline bool
110pos_equal (const lex_pos_ty *pos1, const lex_pos_ty *pos2)
111{
112  return ((pos1->file_name == pos2->file_name
113	   || strcmp (pos1->file_name, pos2->file_name) == 0)
114	  && pos1->line_number == pos2->line_number);
115}
116
117bool
118string_list_equal (const string_list_ty *slp1, const string_list_ty *slp2)
119{
120  size_t i, i1, i2;
121
122  i1 = (slp1 != NULL ? slp1->nitems : 0);
123  i2 = (slp2 != NULL ? slp2->nitems : 0);
124  if (i1 != i2)
125    return false;
126  for (i = 0; i < i1; i++)
127    if (strcmp (slp1->item[i], slp2->item[i]) != 0)
128      return false;
129  return true;
130}
131
132bool
133message_equal (const message_ty *mp1, const message_ty *mp2,
134	       bool ignore_potcdate)
135{
136  size_t i, i1, i2;
137
138  if (!(mp1->msgctxt != NULL
139	? mp2->msgctxt != NULL && strcmp (mp1->msgctxt, mp2->msgctxt) == 0
140	: mp2->msgctxt == NULL))
141    return false;
142
143  if (strcmp (mp1->msgid, mp2->msgid) != 0)
144    return false;
145
146  if (!(mp1->msgid_plural != NULL
147	? mp2->msgid_plural != NULL
148	  && strcmp (mp1->msgid_plural, mp2->msgid_plural) == 0
149	: mp2->msgid_plural == NULL))
150    return false;
151
152  if (is_header (mp1) && ignore_potcdate
153      ? !msgstr_equal_ignoring_potcdate (mp1->msgstr, mp1->msgstr_len,
154					 mp2->msgstr, mp2->msgstr_len)
155      : !msgstr_equal (mp1->msgstr, mp1->msgstr_len,
156		       mp2->msgstr, mp2->msgstr_len))
157    return false;
158
159  if (!pos_equal (&mp1->pos, &mp2->pos))
160    return false;
161
162  if (!string_list_equal (mp1->comment, mp2->comment))
163    return false;
164
165  if (!string_list_equal (mp1->comment_dot, mp2->comment_dot))
166    return false;
167
168  i1 = mp1->filepos_count;
169  i2 = mp2->filepos_count;
170  if (i1 != i2)
171    return false;
172  for (i = 0; i < i1; i++)
173    if (!pos_equal (&mp1->filepos[i], &mp2->filepos[i]))
174      return false;
175
176  if (mp1->is_fuzzy != mp2->is_fuzzy)
177    return false;
178
179  for (i = 0; i < NFORMATS; i++)
180    if (mp1->is_format[i] != mp2->is_format[i])
181      return false;
182
183  if (!(mp1->prev_msgctxt != NULL
184	? mp2->prev_msgctxt != NULL
185	  && strcmp (mp1->prev_msgctxt, mp2->prev_msgctxt) == 0
186	: mp2->prev_msgctxt == NULL))
187    return false;
188
189  if (!(mp1->prev_msgid != NULL
190	? mp2->prev_msgid != NULL
191	  && strcmp (mp1->prev_msgid, mp2->prev_msgid) == 0
192	: mp2->prev_msgid == NULL))
193    return false;
194
195  if (!(mp1->prev_msgid_plural != NULL
196	? mp2->prev_msgid_plural != NULL
197	  && strcmp (mp1->prev_msgid_plural, mp2->prev_msgid_plural) == 0
198	: mp2->prev_msgid_plural == NULL))
199    return false;
200
201  if (mp1->obsolete != mp2->obsolete)
202    return false;
203
204  return true;
205}
206
207bool
208message_list_equal (const message_list_ty *mlp1, const message_list_ty *mlp2,
209		    bool ignore_potcdate)
210{
211  size_t i, i1, i2;
212
213  i1 = mlp1->nitems;
214  i2 = mlp2->nitems;
215  if (i1 != i2)
216    return false;
217  for (i = 0; i < i1; i++)
218    if (!message_equal (mlp1->item[i], mlp2->item[i], ignore_potcdate))
219      return false;
220  return true;
221}
222
223static inline bool
224msgdomain_equal (const msgdomain_ty *mdp1, const msgdomain_ty *mdp2,
225		 bool ignore_potcdate)
226{
227  return (strcmp (mdp1->domain, mdp2->domain) == 0
228	  && message_list_equal (mdp1->messages, mdp2->messages,
229				 ignore_potcdate));
230}
231
232bool
233msgdomain_list_equal (const msgdomain_list_ty *mdlp1,
234		      const msgdomain_list_ty *mdlp2,
235		      bool ignore_potcdate)
236{
237  size_t i, i1, i2;
238
239  i1 = mdlp1->nitems;
240  i2 = mdlp2->nitems;
241  if (i1 != i2)
242    return false;
243  for (i = 0; i < i1; i++)
244    if (!msgdomain_equal (mdlp1->item[i], mdlp2->item[i], ignore_potcdate))
245      return false;
246  return true;
247}
248