111
111
for (; *format != '\0';)
112
112
if (*format++ == '%')
115
enum format_arg_type type;
117
FDI_SET (format - 1, FMTDIR_START);
120
if (isdigit (*format))
122
const char *f = format;
127
m = 10 * m + (*f - '0');
130
while (isdigit (*f));
132
if (*f == '$' && m > 0)
140
while (*format == ' ' || *format == '+' || *format == '-'
141
|| *format == '#' || *format == '0')
149
if (spec.allocated == spec.numbered_arg_count)
151
spec.allocated = 2 * spec.allocated + 1;
152
spec.numbered = (struct numbered_arg *) xrealloc (spec.numbered, spec.allocated * sizeof (struct numbered_arg));
154
spec.numbered[spec.numbered_arg_count].number = number;
155
spec.numbered[spec.numbered_arg_count].type = FAT_INTEGER;
156
spec.numbered_arg_count++;
160
else if (isdigit (*format))
162
do format++; while (isdigit (*format));
165
/* Parse precision. */
174
if (spec.allocated == spec.numbered_arg_count)
176
spec.allocated = 2 * spec.allocated + 1;
177
spec.numbered = (struct numbered_arg *) xrealloc (spec.numbered, spec.allocated * sizeof (struct numbered_arg));
179
spec.numbered[spec.numbered_arg_count].number = number;
180
spec.numbered[spec.numbered_arg_count].type = FAT_INTEGER;
181
spec.numbered_arg_count++;
185
else if (isdigit (*format))
187
do format++; while (isdigit (*format));
197
type = FAT_CHARACTER;
199
case 'd': case 'i': case 'x': case 'X': case 'o':
202
case 'e': case 'E': case 'f': case 'g': case 'G':
206
type = FAT_OBJECT_PRETTY;
214
*invalid_reason = INVALID_UNTERMINATED_DIRECTIVE ();
215
FDI_SET (format - 1, FMTDIR_ERROR);
220
INVALID_CONVERSION_SPECIFIER (spec.directives, *format);
221
FDI_SET (format, FMTDIR_ERROR);
226
if (type != FAT_NONE)
228
if (spec.allocated == spec.numbered_arg_count)
230
spec.allocated = 2 * spec.allocated + 1;
231
spec.numbered = (struct numbered_arg *) xrealloc (spec.numbered, spec.allocated * sizeof (struct numbered_arg));
233
spec.numbered[spec.numbered_arg_count].number = number;
234
spec.numbered[spec.numbered_arg_count].type = type;
235
spec.numbered_arg_count++;
240
FDI_SET (format, FMTDIR_END);
115
enum format_arg_type type;
117
FDI_SET (format - 1, FMTDIR_START);
120
if (isdigit (*format))
122
const char *f = format;
127
m = 10 * m + (*f - '0');
130
while (isdigit (*f));
132
if (*f == '$' && m > 0)
140
while (*format == ' ' || *format == '+' || *format == '-'
141
|| *format == '#' || *format == '0')
149
if (spec.allocated == spec.numbered_arg_count)
151
spec.allocated = 2 * spec.allocated + 1;
152
spec.numbered = (struct numbered_arg *) xrealloc (spec.numbered, spec.allocated * sizeof (struct numbered_arg));
154
spec.numbered[spec.numbered_arg_count].number = number;
155
spec.numbered[spec.numbered_arg_count].type = FAT_INTEGER;
156
spec.numbered_arg_count++;
160
else if (isdigit (*format))
162
do format++; while (isdigit (*format));
165
/* Parse precision. */
174
if (spec.allocated == spec.numbered_arg_count)
176
spec.allocated = 2 * spec.allocated + 1;
177
spec.numbered = (struct numbered_arg *) xrealloc (spec.numbered, spec.allocated * sizeof (struct numbered_arg));
179
spec.numbered[spec.numbered_arg_count].number = number;
180
spec.numbered[spec.numbered_arg_count].type = FAT_INTEGER;
181
spec.numbered_arg_count++;
185
else if (isdigit (*format))
187
do format++; while (isdigit (*format));
197
type = FAT_CHARACTER;
199
case 'd': case 'i': case 'x': case 'X': case 'o':
202
case 'e': case 'E': case 'f': case 'g': case 'G':
206
type = FAT_OBJECT_PRETTY;
214
*invalid_reason = INVALID_UNTERMINATED_DIRECTIVE ();
215
FDI_SET (format - 1, FMTDIR_ERROR);
220
INVALID_CONVERSION_SPECIFIER (spec.directives, *format);
221
FDI_SET (format, FMTDIR_ERROR);
226
if (type != FAT_NONE)
228
if (spec.allocated == spec.numbered_arg_count)
230
spec.allocated = 2 * spec.allocated + 1;
231
spec.numbered = (struct numbered_arg *) xrealloc (spec.numbered, spec.allocated * sizeof (struct numbered_arg));
233
spec.numbered[spec.numbered_arg_count].number = number;
234
spec.numbered[spec.numbered_arg_count].type = type;
235
spec.numbered_arg_count++;
240
FDI_SET (format, FMTDIR_END);
245
245
/* Sort the numbered argument array, and eliminate duplicates. */
251
251
qsort (spec.numbered, spec.numbered_arg_count,
252
sizeof (struct numbered_arg), numbered_arg_compare);
252
sizeof (struct numbered_arg), numbered_arg_compare);
254
254
/* Remove duplicates: Copy from i to j, keeping 0 <= j <= i. */
256
256
for (i = j = 0; i < spec.numbered_arg_count; i++)
257
if (j > 0 && spec.numbered[i].number == spec.numbered[j-1].number)
259
enum format_arg_type type1 = spec.numbered[i].type;
260
enum format_arg_type type2 = spec.numbered[j-1].type;
261
enum format_arg_type type_both;
267
/* Incompatible types. */
268
type_both = FAT_NONE;
271
INVALID_INCOMPATIBLE_ARG_TYPES (spec.numbered[i].number);
275
spec.numbered[j-1].type = type_both;
281
spec.numbered[j].number = spec.numbered[i].number;
282
spec.numbered[j].type = spec.numbered[i].type;
257
if (j > 0 && spec.numbered[i].number == spec.numbered[j-1].number)
259
enum format_arg_type type1 = spec.numbered[i].type;
260
enum format_arg_type type2 = spec.numbered[j-1].type;
261
enum format_arg_type type_both;
267
/* Incompatible types. */
268
type_both = FAT_NONE;
271
INVALID_INCOMPATIBLE_ARG_TYPES (spec.numbered[i].number);
275
spec.numbered[j-1].type = type_both;
281
spec.numbered[j].number = spec.numbered[i].number;
282
spec.numbered[j].type = spec.numbered[i].type;
286
286
spec.numbered_arg_count = j;
288
/* *invalid_reason has already been set above. */
288
/* *invalid_reason has already been set above. */
292
292
result = XMALLOC (struct spec);
333
333
unsigned int n2 = spec2->numbered_arg_count;
335
335
/* Check the argument names are the same.
336
Both arrays are sorted. We search for the first difference. */
336
Both arrays are sorted. We search for the first difference. */
337
337
for (i = 0, j = 0; i < n1 || j < n2; )
339
int cmp = (i >= n1 ? 1 :
341
spec1->numbered[i].number > spec2->numbered[j].number ? 1 :
342
spec1->numbered[i].number < spec2->numbered[j].number ? -1 :
339
int cmp = (i >= n1 ? 1 :
341
spec1->numbered[i].number > spec2->numbered[j].number ? 1 :
342
spec1->numbered[i].number < spec2->numbered[j].number ? -1 :
348
error_logger (_("a format specification for argument %u, as in '%s', doesn't exist in 'msgid'"),
349
spec2->numbered[j].number, pretty_msgstr);
358
error_logger (_("a format specification for argument %u doesn't exist in '%s'"),
359
spec1->numbered[i].number, pretty_msgstr);
348
error_logger (_("a format specification for argument %u, as in '%s', doesn't exist in '%s'"),
349
spec2->numbered[j].number, pretty_msgstr,
359
error_logger (_("a format specification for argument %u doesn't exist in '%s'"),
360
spec1->numbered[i].number, pretty_msgstr);
369
370
/* Check the argument types are the same. */
371
for (i = 0, j = 0; j < n2; )
373
if (spec1->numbered[i].number == spec2->numbered[j].number)
375
if (spec1->numbered[i].type != spec2->numbered[j].type)
378
error_logger (_("format specifications in 'msgid' and '%s' for argument %u are not the same"),
379
pretty_msgstr, spec2->numbered[j].number);
372
for (i = 0, j = 0; j < n2; )
374
if (spec1->numbered[i].number == spec2->numbered[j].number)
376
if (spec1->numbered[i].type != spec2->numbered[j].type)
379
error_logger (_("format specifications in '%s' and '%s' for argument %u are not the same"),
380
pretty_msgid, pretty_msgstr,
381
spec2->numbered[j].number);