2 Copyright (C) 2003-2004 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2003.
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)
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. */
31 #define _(str) gettext (str)
33 /* Qt format strings are processed by QString::arg and are documented in
34 qt-3.0.5/doc/html/qstring.html.
35 A directive starts with '%' and is followed by a digit ('0' to '9').
36 Each %n must occur only once in the given string.
37 The first .arg() invocation replaces the %n with the lowest numbered n,
38 the next .arg() invocation then replaces the %n with the second-lowest
39 numbered n, and so on.
40 (This is inherently buggy because a '%' in the first replacement confuses
41 the second .arg() invocation.)
42 Although %0 is supported, usually %1 denotes the first argument, %2 the
43 second argument etc. */
47 unsigned int directives
;
48 unsigned int arg_count
;
54 format_parse (const char *format
, bool translated
, char **invalid_reason
)
62 for (; *format
!= '\0';)
64 if (*format
>= '0' && *format
<= '9')
71 number
= *format
- '0';
73 while (spec
.arg_count
<= number
)
74 spec
.args_used
[spec
.arg_count
++] = false;
75 if (spec
.args_used
[number
])
78 xasprintf (_("Multiple references to %%%c."), *format
);
81 spec
.args_used
[number
] = true;
86 result
= (struct spec
*) xmalloc (sizeof (struct spec
));
95 format_free (void *descr
)
97 struct spec
*spec
= (struct spec
*) descr
;
103 format_get_number_of_directives (void *descr
)
105 struct spec
*spec
= (struct spec
*) descr
;
107 return spec
->directives
;
111 format_check (void *msgid_descr
, void *msgstr_descr
, bool equality
,
112 formatstring_error_logger_t error_logger
,
113 const char *pretty_msgstr
)
115 struct spec
*spec1
= (struct spec
*) msgid_descr
;
116 struct spec
*spec2
= (struct spec
*) msgstr_descr
;
120 for (i
= 0; i
< spec1
->arg_count
|| i
< spec2
->arg_count
; i
++)
122 bool arg_used1
= (i
< spec1
->arg_count
&& spec1
->args_used
[i
]);
123 bool arg_used2
= (i
< spec2
->arg_count
&& spec2
->args_used
[i
]);
125 /* The translator cannot omit a %n from the msgstr because that would
126 yield a "Argument missing" warning at runtime. */
127 if (arg_used1
!= arg_used2
)
130 error_logger (arg_used1
131 ? _("a format specification for argument %u doesn't exist in '%s'")
132 : _("a format specification for argument %u, as in '%s', doesn't exist in 'msgid'"),
143 struct formatstring_parser formatstring_qt
=
147 format_get_number_of_directives
,
154 /* Test program: Print the argument list specification returned by
155 format_parse for strings read from standard input. */
161 format_print (void *descr
)
163 struct spec
*spec
= (struct spec
*) descr
;
173 for (i
= 0; i
< spec
->arg_count
; i
++)
177 if (spec
->args_used
[i
])
191 size_t line_size
= 0;
193 char *invalid_reason
;
196 line_len
= getline (&line
, &line_size
, stdin
);
199 if (line_len
> 0 && line
[line_len
- 1] == '\n')
200 line
[--line_len
] = '\0';
202 invalid_reason
= NULL
;
203 descr
= format_parse (line
, false, &invalid_reason
);
205 format_print (descr
);
208 printf ("%s\n", invalid_reason
);
210 free (invalid_reason
);
218 * For Emacs M-x compile
220 * compile-command: "/bin/sh ../libtool --mode=link gcc -o a.out -static -O -g -Wall -I.. -I../lib -I../intl -DHAVE_CONFIG_H -DTEST format-qt.c ../lib/libgettextlib.la"