No empty .Rs/.Re
[netbsd-mini2440.git] / gnu / dist / gettext / gettext-tools / src / msgl-equal.c
blobb1ab7b7fa2ea55f253a7475d042ad5668e717d83
1 /* Message list test for equality.
2 Copyright (C) 2001-2002 Free Software Foundation, Inc.
3 Written by Bruno Haible <haible@clisp.cons.org>, 2001.
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 2, or (at your option)
8 any later version.
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.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software Foundation,
17 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20 #ifdef HAVE_CONFIG_H
21 # include "config.h"
22 #endif
24 /* Specification. */
25 #include "msgl-equal.h"
27 #include <stddef.h>
28 #include <string.h>
31 static inline bool
32 msgstr_equal (const char *msgstr1, size_t msgstr1_len,
33 const char *msgstr2, size_t msgstr2_len)
35 return (msgstr1_len == msgstr2_len
36 && memcmp (msgstr1, msgstr2, msgstr1_len) == 0);
39 static bool
40 msgstr_equal_ignoring_potcdate (const char *msgstr1, size_t msgstr1_len,
41 const char *msgstr2, size_t msgstr2_len)
43 const char *msgstr1_end = msgstr1 + msgstr1_len;
44 const char *msgstr2_end = msgstr2 + msgstr2_len;
45 const char *ptr1;
46 const char *ptr2;
47 const char *const field = "POT-Creation-Date:";
48 const ptrdiff_t fieldlen = sizeof ("POT-Creation-Date:") - 1;
50 /* Search for the occurrence of field in msgstr1. */
51 for (ptr1 = msgstr1;;)
53 if (msgstr1_end - ptr1 < fieldlen)
55 ptr1 = NULL;
56 break;
58 if (memcmp (ptr1, field, fieldlen) == 0)
59 break;
60 ptr1 = memchr (ptr1, '\n', msgstr1_end - ptr1);
61 if (ptr1 == NULL)
62 break;
63 ptr1++;
66 /* Search for the occurrence of field in msgstr2. */
67 for (ptr2 = msgstr2;;)
69 if (msgstr2_end - ptr2 < fieldlen)
71 ptr2 = NULL;
72 break;
74 if (memcmp (ptr2, field, fieldlen) == 0)
75 break;
76 ptr2 = memchr (ptr2, '\n', msgstr2_end - ptr2);
77 if (ptr2 == NULL)
78 break;
79 ptr2++;
82 if (ptr1 == NULL)
84 if (ptr2 == NULL)
85 return msgstr_equal (msgstr1, msgstr1_len, msgstr2, msgstr2_len);
87 else
89 if (ptr2 != NULL)
91 /* Compare, ignoring the lines starting at ptr1 and ptr2. */
92 if (msgstr_equal (msgstr1, ptr1 - msgstr1, msgstr2, ptr2 - msgstr2))
94 ptr1 = memchr (ptr1, '\n', msgstr1_end - ptr1);
95 if (ptr1 == NULL)
96 ptr1 = msgstr1_end;
98 ptr2 = memchr (ptr2, '\n', msgstr2_end - ptr2);
99 if (ptr2 == NULL)
100 ptr2 = msgstr2_end;
102 return msgstr_equal (ptr1, msgstr1_end - ptr1,
103 ptr2, msgstr2_end - ptr2);
107 return false;
110 static inline bool
111 pos_equal (const lex_pos_ty *pos1, const lex_pos_ty *pos2)
113 return ((pos1->file_name == pos2->file_name
114 || strcmp (pos1->file_name, pos2->file_name) == 0)
115 && pos1->line_number == pos2->line_number);
118 bool
119 string_list_equal (const string_list_ty *slp1, const string_list_ty *slp2)
121 size_t i, i1, i2;
123 i1 = (slp1 != NULL ? slp1->nitems : 0);
124 i2 = (slp2 != NULL ? slp2->nitems : 0);
125 if (i1 != i2)
126 return false;
127 for (i = 0; i < i1; i++)
128 if (strcmp (slp1->item[i], slp2->item[i]) != 0)
129 return false;
130 return true;
133 bool
134 message_equal (const message_ty *mp1, const message_ty *mp2,
135 bool ignore_potcdate)
137 size_t i, i1, i2;
139 if (strcmp (mp1->msgid, mp2->msgid) != 0)
140 return false;
142 if (!(mp1->msgid_plural != NULL
143 ? mp2->msgid_plural != NULL
144 && strcmp (mp1->msgid_plural, mp2->msgid_plural) == 0
145 : mp2->msgid_plural == NULL))
146 return false;
148 if (mp1->msgid[0] == '\0' && ignore_potcdate
149 ? !msgstr_equal_ignoring_potcdate (mp1->msgstr, mp1->msgstr_len,
150 mp2->msgstr, mp2->msgstr_len)
151 : !msgstr_equal (mp1->msgstr, mp1->msgstr_len,
152 mp2->msgstr, mp2->msgstr_len))
153 return false;
155 if (!pos_equal (&mp1->pos, &mp2->pos))
156 return false;
158 if (!string_list_equal (mp1->comment, mp2->comment))
159 return false;
161 if (!string_list_equal (mp1->comment_dot, mp2->comment_dot))
162 return false;
164 i1 = mp1->filepos_count;
165 i2 = mp2->filepos_count;
166 if (i1 != i2)
167 return false;
168 for (i = 0; i < i1; i++)
169 if (!pos_equal (&mp1->filepos[i], &mp2->filepos[i]))
170 return false;
172 if (mp1->is_fuzzy != mp2->is_fuzzy)
173 return false;
175 for (i = 0; i < NFORMATS; i++)
176 if (mp1->is_format[i] != mp2->is_format[i])
177 return false;
179 if (mp1->obsolete != mp2->obsolete)
180 return false;
182 return true;
185 bool
186 message_list_equal (const message_list_ty *mlp1, const message_list_ty *mlp2,
187 bool ignore_potcdate)
189 size_t i, i1, i2;
191 i1 = mlp1->nitems;
192 i2 = mlp2->nitems;
193 if (i1 != i2)
194 return false;
195 for (i = 0; i < i1; i++)
196 if (!message_equal (mlp1->item[i], mlp2->item[i], ignore_potcdate))
197 return false;
198 return true;
201 static inline bool
202 msgdomain_equal (const msgdomain_ty *mdp1, const msgdomain_ty *mdp2,
203 bool ignore_potcdate)
205 return (strcmp (mdp1->domain, mdp2->domain) == 0
206 && message_list_equal (mdp1->messages, mdp2->messages,
207 ignore_potcdate));
210 bool
211 msgdomain_list_equal (const msgdomain_list_ty *mdlp1,
212 const msgdomain_list_ty *mdlp2,
213 bool ignore_potcdate)
215 size_t i, i1, i2;
217 i1 = mdlp1->nitems;
218 i2 = mdlp2->nitems;
219 if (i1 != i2)
220 return false;
221 for (i = 0; i < i1; i++)
222 if (!msgdomain_equal (mdlp1->item[i], mdlp2->item[i], ignore_potcdate))
223 return false;
224 return true;