Update.
1998-04-01 16:10 Ulrich Drepper <drepper@cygnus.com> * libc.map: Add __gconv_alias_db, __gconv_nmodules, __gconv_modules_db. * iconv/iconv_prog.c: Implement --list option to print available coded character sets. 1998-04-01 18:10 Zack Weinberg <zack@rabi.phys.columbia.edu> Make fread() read large blocks straight to the user buffer. * libio/fileops.c (_IO_file_xsgetn): New function. (_IO_file_jumps): Use it. * libio/libioP.h: Prototype it.
This commit is contained in:
parent
5891046a86
commit
8fe0fd03e5
14
ChangeLog
14
ChangeLog
@ -1,3 +1,17 @@
|
||||
1998-04-01 16:10 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* libc.map: Add __gconv_alias_db, __gconv_nmodules, __gconv_modules_db.
|
||||
* iconv/iconv_prog.c: Implement --list option to print available
|
||||
coded character sets.
|
||||
|
||||
1998-04-01 18:10 Zack Weinberg <zack@rabi.phys.columbia.edu>
|
||||
|
||||
Make fread() read large blocks straight to the user buffer.
|
||||
|
||||
* libio/fileops.c (_IO_file_xsgetn): New function.
|
||||
(_IO_file_jumps): Use it.
|
||||
* libio/libioP.h: Prototype it.
|
||||
|
||||
1998-04-01 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* iconv/gconv_conf.c (builtin_aliases): New variable.
|
||||
|
@ -19,11 +19,14 @@
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <argp.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
#include <fcntl.h>
|
||||
#include <gconv.h>
|
||||
#include <iconv.h>
|
||||
#include <locale.h>
|
||||
#include <search.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -41,6 +44,7 @@ static void print_version (FILE *stream, struct argp_state *state);
|
||||
void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
|
||||
|
||||
#define OPT_VERBOSE 1000
|
||||
#define OPT_LIST 1001
|
||||
|
||||
/* Definitions of arguments for argp functions. */
|
||||
static const struct argp_option options[] =
|
||||
@ -48,6 +52,8 @@ static const struct argp_option options[] =
|
||||
{ NULL, 0, NULL, 0, N_("Input/Output format specification:") },
|
||||
{ "from-code", 'f', "NAME", 0, N_("encoding of original text") },
|
||||
{ "to-code", 't', "NAME", 0, N_("encoding for output") },
|
||||
{ NULL, 0, NULL, 0, N_("Information:") },
|
||||
{ "list", OPT_LIST, NULL, 0, N_("list all known coded character sets") },
|
||||
{ NULL, 0, NULL, 0, N_("Output control:") },
|
||||
{ "output", 'o', "FILE", 0, N_("output file") },
|
||||
{ "verbose", OPT_VERBOSE, NULL, 0, N_("print progress information") },
|
||||
@ -83,11 +89,15 @@ static const char *output_file;
|
||||
/* Nonzero if verbose ouput is wanted. */
|
||||
static int verbose;
|
||||
|
||||
/* Nonzero if list of all coded character sets is wanted. */
|
||||
static int list;
|
||||
|
||||
/* Prototypes for the functions doing the actual work. */
|
||||
static int process_block (iconv_t cd, const char *addr, size_t len,
|
||||
FILE *output);
|
||||
static int process_fd (iconv_t cd, int fd, FILE *output);
|
||||
static int process_file (iconv_t cd, FILE *input, FILE *output);
|
||||
static void print_known_names (void);
|
||||
|
||||
|
||||
int
|
||||
@ -107,6 +117,13 @@ main (int argc, char *argv[])
|
||||
/* Parse and process arguments. */
|
||||
argp_parse (&argp, argc, argv, 0, &remaining, NULL);
|
||||
|
||||
/* List all coded character sets if wanted. */
|
||||
if (list)
|
||||
{
|
||||
print_known_names ();
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/* If either the from- or to-code is not specified this is an error
|
||||
since we do not know what to do. */
|
||||
if (from_code == NULL && to_code == NULL)
|
||||
@ -237,6 +254,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
|
||||
case OPT_VERBOSE:
|
||||
verbose = 1;
|
||||
break;
|
||||
case OPT_LIST:
|
||||
list = 1;
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
@ -412,3 +432,106 @@ process_file (iconv_t cd, FILE *input, FILE *output)
|
||||
we haven't read anything so far. */
|
||||
return process_fd (cd, fileno (input), output);
|
||||
}
|
||||
|
||||
|
||||
/* Print all known character sets/encodings. */
|
||||
static void *printlist;
|
||||
static size_t column;
|
||||
static int not_first;
|
||||
|
||||
static void
|
||||
insert_print_list (const void *nodep, VISIT value, int level)
|
||||
{
|
||||
if (value == leaf || value == postorder)
|
||||
{
|
||||
const struct gconv_alias *s = *(const struct gconv_alias **) nodep;
|
||||
tsearch (s->fromname, &printlist, (__compar_fn_t) strcoll);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_print (const void *nodep, VISIT value, int level)
|
||||
{
|
||||
if (value == leaf || value == postorder)
|
||||
{
|
||||
const char *s = *(const char **) nodep;
|
||||
size_t len = strlen (s);
|
||||
size_t cnt;
|
||||
|
||||
while (len > 0 && s[len - 1] == '/')
|
||||
--len;
|
||||
|
||||
for (cnt = 0; cnt < len; ++cnt)
|
||||
if (isalnum (s[cnt]))
|
||||
break;
|
||||
if (cnt == len)
|
||||
return;
|
||||
|
||||
if (not_first)
|
||||
{
|
||||
putchar (',');
|
||||
++column;
|
||||
|
||||
if (column > 2 && column + len > 77)
|
||||
{
|
||||
fputs ("\n ", stdout);
|
||||
column = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
putchar (' ');
|
||||
++column;
|
||||
}
|
||||
}
|
||||
else
|
||||
not_first = 1;
|
||||
|
||||
fwrite (s, len, 1, stdout);
|
||||
column += len;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_known_names (void)
|
||||
{
|
||||
size_t cnt;
|
||||
iconv_t h;
|
||||
|
||||
/* We must initialize the internal databases first. */
|
||||
h = iconv_open ("L1", "L1");
|
||||
iconv_close (h);
|
||||
|
||||
/* First add the aliases. */
|
||||
twalk (__gconv_alias_db, insert_print_list);
|
||||
|
||||
/* Add the from- and to-names from the known modules. */
|
||||
for (cnt = 0; cnt < __gconv_nmodules; ++cnt)
|
||||
{
|
||||
if (__gconv_modules_db[cnt]->from_pattern == NULL)
|
||||
{
|
||||
tsearch (__gconv_modules_db[cnt]->from_constpfx, &printlist,
|
||||
(__compar_fn_t) strcoll);
|
||||
tsearch (__gconv_modules_db[cnt]->to_string, &printlist,
|
||||
(__compar_fn_t) strcoll);
|
||||
}
|
||||
else
|
||||
tsearch (__gconv_modules_db[cnt]->from_pattern, &printlist,
|
||||
(__compar_fn_t) strcoll);
|
||||
}
|
||||
|
||||
fputs (_("\
|
||||
The following list contain all the coded character sets known. This does\n\
|
||||
not necessarily mean that all combinations of these names can be used for\n\
|
||||
the FROM and TO command line parameters. One coded character set can be\n\
|
||||
listed with several different names (aliases).\n\
|
||||
Some of the names are no plain strings but instead regular expressions and\n\
|
||||
they match a variety of names which can be given as parameters to the\n\
|
||||
program.\n\n "), stdout);
|
||||
|
||||
/* Now print the collected names. */
|
||||
column = 2;
|
||||
twalk (printlist, do_print);
|
||||
|
||||
if (column != 0)
|
||||
puts ("");
|
||||
}
|
||||
|
1
libc.map
1
libc.map
@ -427,6 +427,7 @@ GLIBC_2.1 {
|
||||
global:
|
||||
# global variables
|
||||
_IO_2_1_stdin_; _IO_2_1_stdout_; _IO_2_1_stderr_;
|
||||
__gconv_alias_db; __gconv_nmodules; __gconv_modules_db;
|
||||
|
||||
# This is for ix86 only.
|
||||
_fp_hw;
|
||||
|
114
libio/fileops.c
114
libio/fileops.c
@ -775,80 +775,72 @@ _IO_file_xsputn (f, data, n)
|
||||
return n - to_do;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Work in progress */
|
||||
_IO_size_t
|
||||
_IO_file_xsgetn (fp, data, n)
|
||||
_IO_FILE *fp;
|
||||
void *data;
|
||||
_IO_size_t n;
|
||||
{
|
||||
register _IO_size_t more = n;
|
||||
register _IO_size_t want, have, count;
|
||||
register char *s = data;
|
||||
for (;;)
|
||||
{
|
||||
/* Data available. */
|
||||
_IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr;
|
||||
if (count > 0)
|
||||
{
|
||||
if (count > more)
|
||||
count = more;
|
||||
if (count > 20)
|
||||
{
|
||||
#ifdef _LIBC
|
||||
s = __mempcpy (s, fp->_IO_read_ptr, count);
|
||||
#else
|
||||
memcpy (s, fp->_IO_read_ptr, count);
|
||||
s += count;
|
||||
#endif
|
||||
fp->_IO_read_ptr += count;
|
||||
}
|
||||
else if (count <= 0)
|
||||
count = 0;
|
||||
else
|
||||
{
|
||||
register char *p = fp->_IO_read_ptr;
|
||||
register int i = (int) count;
|
||||
while (--i >= 0)
|
||||
*s++ = *p++;
|
||||
fp->_IO_read_ptr = p;
|
||||
}
|
||||
more -= count;
|
||||
}
|
||||
#if 0
|
||||
if (! _IO_in put_mode (fp)
|
||||
&& ! _IO_have_markers (fp) && ! IO_have_backup (fp))
|
||||
{
|
||||
/* This is an optimization of _IO_file_underflow */
|
||||
if (fp->_flags & _IO_NO_READS)
|
||||
break;
|
||||
/* If we're reading a lot of data, don't bother allocating
|
||||
a buffer. But if we're only reading a bit, perhaps we should ??*/
|
||||
if (count <= 512 && fp->_IO_buf_base == NULL)
|
||||
_IO_doallocbuf (fp);
|
||||
if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED))
|
||||
_IO_flush_all_linebuffered ();
|
||||
|
||||
_IO_switch_to_get_mode (fp); ???;
|
||||
count = _IO_SYSREAD (fp, s, more);
|
||||
want = n;
|
||||
|
||||
while (want > 0)
|
||||
{
|
||||
have = fp->_IO_read_end - fp->_IO_read_ptr;
|
||||
if (want <= have)
|
||||
{
|
||||
memcpy (s, fp->_IO_read_ptr, want);
|
||||
fp->_IO_read_ptr += want;
|
||||
want = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (have > 0)
|
||||
{
|
||||
memcpy (s, fp->_IO_read_ptr, have);
|
||||
want -= have;
|
||||
s += have;
|
||||
fp->_IO_read_ptr += have;
|
||||
}
|
||||
|
||||
/* Check for backup and repeat */
|
||||
if (_IO_in_backup (fp))
|
||||
{
|
||||
_IO_switch_to_main_get_area (fp);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If we now want less than a buffer, underflow and repeat
|
||||
the copy. Otherwise, _IO_SYSREAD directly to
|
||||
the user buffer. */
|
||||
if (fp->_IO_buf_base && want < fp->_IO_buf_end - fp->_IO_buf_base)
|
||||
{
|
||||
if (__underflow (fp) == EOF)
|
||||
break;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
count = _IO_SYSREAD (fp, s, want);
|
||||
if (count <= 0)
|
||||
{
|
||||
if (count == 0)
|
||||
fp->_flags |= _IO_EOF_SEEN;
|
||||
else
|
||||
fp->_flags |= _IO_ERR_SEEN, count = 0;
|
||||
}
|
||||
{
|
||||
if (count == 0)
|
||||
fp->_flags |= _IO_EOF_SEEN;
|
||||
else
|
||||
fp->_flags |= _IO_ERR_SEEN;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
s += count;
|
||||
more -= count;
|
||||
want -= count;
|
||||
}
|
||||
#endif
|
||||
if (more == 0 || __underflow (fp) == EOF)
|
||||
break;
|
||||
}
|
||||
return n - more;
|
||||
|
||||
return n - want;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct _IO_jump_t _IO_file_jumps =
|
||||
{
|
||||
@ -859,7 +851,7 @@ struct _IO_jump_t _IO_file_jumps =
|
||||
JUMP_INIT(uflow, _IO_default_uflow),
|
||||
JUMP_INIT(pbackfail, _IO_default_pbackfail),
|
||||
JUMP_INIT(xsputn, _IO_file_xsputn),
|
||||
JUMP_INIT(xsgetn, _IO_default_xsgetn),
|
||||
JUMP_INIT(xsgetn, _IO_file_xsgetn),
|
||||
JUMP_INIT(seekoff, _IO_file_seekoff),
|
||||
JUMP_INIT(seekpos, _IO_default_seekpos),
|
||||
JUMP_INIT(setbuf, _IO_file_setbuf),
|
||||
|
@ -368,6 +368,7 @@ extern int _IO_file_doallocate __P ((_IO_FILE *));
|
||||
extern _IO_FILE* _IO_file_setbuf __P ((_IO_FILE *, char *, _IO_ssize_t));
|
||||
extern _IO_fpos64_t _IO_file_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int));
|
||||
extern _IO_size_t _IO_file_xsputn __P ((_IO_FILE *, const void *, _IO_size_t));
|
||||
extern _IO_size_t _IO_file_xsgetn __P ((_IO_FILE *, void *, _IO_size_t));
|
||||
extern int _IO_file_stat __P ((_IO_FILE *, void *));
|
||||
extern int _IO_file_close __P ((_IO_FILE *));
|
||||
extern int _IO_file_underflow __P ((_IO_FILE *));
|
||||
|
Loading…
x
Reference in New Issue
Block a user