Group :: Sistema/Base
RPM: glibc
Main Changelog Spec Patches Sources Download Gear Bugs e FR Repocop
Patch: glibc-2.5-alt-iconv_prog-replace.patch
Download
Download
# Add "--replace" option to iconv utility.
--- glibc-2.5.orig/iconv/iconv_prog.c
+++ glibc-2.5/iconv/iconv_prog.c
@@ -63,6 +63,7 @@ static const struct argp_option options[
{ "list", 'l', NULL, 0, N_("list all known coded character sets") },
{ NULL, 0, NULL, 0, N_("Output control:") },
{ NULL, 'c', NULL, 0, N_("omit invalid characters from output") },
+ { "replace", 'r', "SYMBOL", OPTION_ARG_OPTIONAL, N_("replace invalid characters with specified symbol") },
{ "output", 'o', "FILE", 0, N_("output file") },
{ "silent", 's', NULL, 0, N_("suppress warnings") },
{ "verbose", OPT_VERBOSE, NULL, 0, N_("print progress information") },
@@ -106,6 +107,9 @@ static int list;
/* If nonzero omit invalid character from output. */
int omit_invalid;
+/* If nonzero replace invalid character. */
+static char replace_invalid;
+
/* Prototypes for the functions doing the actual work. */
static int process_block (iconv_t cd, char *addr, size_t len, FILE *output);
static int process_fd (iconv_t cd, int fd, FILE *output);
@@ -304,7 +308,7 @@ #endif
#ifdef _POSIX_MAPPED_FILES
/* We have possibilities for reading the input file. First try
to mmap() it since this will provide the fastest solution. */
- if (fstat (fd, &st) == 0
+ if (!replace_invalid && fstat (fd, &st) == 0
&& ((addr = mmap (NULL, st.st_size, PROT_READ, MAP_PRIVATE,
fd, 0)) != MAP_FAILED))
{
@@ -387,6 +391,10 @@ parse_opt (int key, char *arg, struct ar
/* Omit invalid characters from output. */
omit_invalid = 1;
break;
+ case 'r':
+ /* Replace invalid characters. */
+ replace_invalid = (arg && *arg) ? *arg : '?';
+ break;
case OPT_VERBOSE:
verbose = 1;
break;
@@ -430,6 +438,23 @@ warranty; not even for MERCHANTABILITY o
fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
}
+static int
+write_invalid( iconv_t cd, char **addr, size_t *len, FILE *output )
+{
+ int errno_save = errno;
+ int needed_from = ((__gconv_t) cd)->__steps->__min_needed_from;
+ if ( fwrite( &replace_invalid, 1, 1, output ) < 1 || ferror( output ) )
+ {
+ /* Error occurred while printing replace symbol. */
+ error (0, 0, _("conversion stopped due to problem in writing the output"));
+ return -1;
+ }
+
+ errno = errno_save;
+ *addr += needed_from;
+ *len -= needed_from;
+ return 0;
+}
static int
process_block (iconv_t cd, char *addr, size_t len, FILE *output)
@@ -517,12 +542,27 @@ conversion stopped due to problem in wri
switch (errno)
{
case EILSEQ:
+ if (replace_invalid)
+ {
+ if (write_invalid (cd, &addr, &len, output))
+ return -1;
+ else
+ continue;
+ }
if (! omit_invalid)
error (0, 0, _("illegal input sequence at position %ld"),
(long int) (addr - start));
break;
case EINVAL:
- error (0, 0, _("\
+ if (replace_invalid)
+ {
+ if (write_invalid (cd, &addr, &len, output))
+ return -1;
+ else
+ continue;
+ }
+ if (! omit_invalid)
+ error (0, 0, _("\
incomplete character or shift sequence at end of buffer"));
break;
case EBADF: