Update.
authorUlrich Drepper <drepper@redhat.com>
Wed, 1 Apr 1998 16:15:20 +0000 (16:15 +0000)
committerUlrich Drepper <drepper@redhat.com>
Wed, 1 Apr 1998 16:15:20 +0000 (16:15 +0000)
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.

ChangeLog
iconv/iconv_prog.c
libc.map
libio/fileops.c
libio/libioP.h

index f1fe222..3cf2563 100644 (file)
--- a/ChangeLog
+++ b/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.
index 719f20d..6b34d34 100644 (file)
    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 ("");
+}
index e4a289d..0135d57 100644 (file)
--- a/libc.map
+++ b/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;
index d184916..c75accd 100644 (file)
@@ -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 (;;)
+
+  want = n;
+
+  while (want > 0)
     {
-      /* Data available. */
-      _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr;
-      if (count > 0)
+      have = fp->_IO_read_end - fp->_IO_read_ptr;
+      if (want <= have)
        {
-         if (count > more)
-           count = more;
-         if (count > 20)
+         memcpy (s, fp->_IO_read_ptr, want);
+         fp->_IO_read_ptr += want;
+         want = 0;
+       }
+      else
+       {
+         if (have > 0)
            {
-#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;
+             memcpy (s, fp->_IO_read_ptr, have);
+             want -= have;
+             s += have;
+             fp->_IO_read_ptr += have;
            }
-         else if (count <= 0)
-           count = 0;
-         else
+
+         /* Check for backup and repeat */
+         if (_IO_in_backup (fp))
            {
-             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);
+             _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),
index 785bfee..0452c77 100644 (file)
@@ -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 *));