diff options
author | Jim Blandy <jimb@red-bean.com> | 1999-09-06 05:56:10 +0000 |
---|---|---|
committer | Jim Blandy <jimb@red-bean.com> | 1999-09-06 05:56:10 +0000 |
commit | 5083e79d95b1bbae9a6cccee48890dd80305593b (patch) | |
tree | ffd66b1662e8ef8e98c34267a1cd8ef01133dc3c | |
parent | 9b5a0fb7e80ae667e535fbf642c50db2c6fb8f16 (diff) | |
download | guile-5083e79d95b1bbae9a6cccee48890dd80305593b.tar.gz |
* mbconv.c: New file.
* init.c: #include "mbconv.h".
(scm_boot_guile_1): call scm_init_mbconv.
* mbconv.h: Add extern declaration for scm_init_mbconv.
* Makefile.am (libguile_la_SOURCES, BUILT_SOURCES,
modinclude_HEADERS): Include the `mbconv' files in the lists.
* Makefile.in: Regenerated.
* scmconfig.h.in: Regenerated (see configure.in changes).
-rw-r--r-- | libguile/Makefile.am | 40 | ||||
-rw-r--r-- | libguile/Makefile.in | 27 | ||||
-rw-r--r-- | libguile/init.c | 4 | ||||
-rw-r--r-- | libguile/mbconv.c | 366 | ||||
-rw-r--r-- | libguile/scmconfig.h.in | 3 |
5 files changed, 406 insertions, 34 deletions
diff --git a/libguile/Makefile.am b/libguile/Makefile.am index dda9508d6..fdef34945 100644 --- a/libguile/Makefile.am +++ b/libguile/Makefile.am @@ -41,12 +41,12 @@ libguile_la_SOURCES = \ gh_data.c gh_eval.c gh_funcs.c gh_init.c gh_io.c gh_list.c \ gh_predicates.c gsubr.c guardians.c hash.c hashtab.c init.c \ ioext.c keywords.c lang.c list.c load.c macros.c mallocs.c mb.c \ - modules.c net_db.c numbers.c objects.c objprop.c options.c pairs.c \ - ports.c posix.c print.c procprop.c procs.c ramap.c random.c read.c \ - root.c scmsigs.c script.c simpos.c smob.c socket.c sort.c \ - srcprop.c stackchk.c stacks.c stime.c strings.c strop.c strorder.c \ - strports.c struct.c symbols.c tag.c throw.c unif.c variable.c \ - vectors.c version.c vports.c weaks.c + mbconv.c modules.c net_db.c numbers.c objects.c objprop.c \ + options.c pairs.c ports.c posix.c print.c procprop.c procs.c \ + ramap.c random.c read.c root.c scmsigs.c script.c simpos.c smob.c \ + socket.c sort.c srcprop.c stackchk.c stacks.c stime.c strings.c \ + strop.c strorder.c strports.c struct.c symbols.c tag.c throw.c \ + unif.c variable.c vectors.c version.c vports.c weaks.c BUILT_SOURCES = \ cpp_err_symbols.c cpp_sig_symbols.c libpath.h alist.x arbiters.x \ @@ -54,13 +54,13 @@ BUILT_SOURCES = \ dynl.x dynwind.x eq.x error.x eval.x evalext.x feature.x filesys.x \ fluids.x fports.x gc.x gsubr.x guardians.x hash.x hashtab.x init.x \ ioext.x iselect.x keywords.x lang.x list.x load.x macros.x \ - mallocs.x mb.x modules.x net_db.x numbers.x objects.x objprop.x \ - options.x pairs.x ports.x posix.x print.x procprop.x procs.x \ - random.x ramap.x read.x regex-posix.x root.x scmsigs.x script.x \ - simpos.x smob.x socket.x sort.x srcprop.x stackchk.x stacks.x \ - stime.x strings.x strop.x strorder.x strports.x struct.x symbols.x \ - tag.x threads.x throw.x unif.x variable.x vectors.x version.x \ - vports.x weaks.x + mallocs.x mb.x mbconv.x modules.x net_db.x numbers.x objects.x \ + objprop.x options.x pairs.x ports.x posix.x print.x procprop.x \ + procs.x random.x ramap.x read.x regex-posix.x root.x scmsigs.x \ + script.x simpos.x smob.x socket.x sort.x srcprop.x stackchk.x \ + stacks.x stime.x strings.x strop.x strorder.x strports.x struct.x \ + symbols.x tag.x threads.x throw.x unif.x variable.x vectors.x \ + version.x vports.x weaks.x EXTRA_libguile_la_SOURCES = _scm.h \ strerror.c inet_aton.c putenv.c \ @@ -90,13 +90,13 @@ modinclude_HEADERS = \ evalext.h feature.h filesys.h fports.h gc.h gdb_interface.h \ gdbint.h genio.h gsubr.h guardians.h hash.h hashtab.h init.h \ ioext.h keywords.h kw.h lang.h list.h load.h macros.h mallocs.h \ - mb.h modules.h net_db.h numbers.h objects.h objprop.h options.h \ - pairs.h ports.h posix.h regex-posix.h print.h procprop.h procs.h \ - random.h ramap.h read.h root.h scmsigs.h script.h simpos.h smob.h \ - socket.h sort.h srcprop.h stackchk.h stacks.h stime.h strings.h \ - strop.h strorder.h strports.h struct.h symbols.h tag.h tags.h \ - throw.h unif.h variable.h vectors.h version.h vports.h weaks.h \ - snarf.h threads.h coop-defs.h fluids.h iselect.h + mb.h mbconv.h modules.h net_db.h numbers.h objects.h objprop.h \ + options.h pairs.h ports.h posix.h regex-posix.h print.h procprop.h \ + procs.h random.h ramap.h read.h root.h scmsigs.h script.h simpos.h \ + smob.h socket.h sort.h srcprop.h stackchk.h stacks.h stime.h \ + strings.h strop.h strorder.h strports.h struct.h symbols.h tag.h \ + tags.h throw.h unif.h variable.h vectors.h version.h vports.h \ + weaks.h snarf.h threads.h coop-defs.h fluids.h iselect.h ## This file is generated at configure time. That is why it is DATA ## and not a header -- headers are included in the distribution. diff --git a/libguile/Makefile.in b/libguile/Makefile.in index a2e42006f..2e4c47289 100644 --- a/libguile/Makefile.in +++ b/libguile/Makefile.in @@ -103,10 +103,10 @@ bin_PROGRAMS = guile guile_SOURCES = guile.c guile_LDADD = libguile.la ${THREAD_LIBS_LOCAL} -libguile_la_SOURCES = alist.c arbiters.c async.c backtrace.c boolean.c chars.c continuations.c debug.c dynl.c dynwind.c eq.c error.c eval.c evalext.c feature.c filesys.c fluids.c fports.c gc.c gdbint.c gh_data.c gh_eval.c gh_funcs.c gh_init.c gh_io.c gh_list.c gh_predicates.c gsubr.c guardians.c hash.c hashtab.c init.c ioext.c keywords.c lang.c list.c load.c macros.c mallocs.c mb.c modules.c net_db.c numbers.c objects.c objprop.c options.c pairs.c ports.c posix.c print.c procprop.c procs.c ramap.c random.c read.c root.c scmsigs.c script.c simpos.c smob.c socket.c sort.c srcprop.c stackchk.c stacks.c stime.c strings.c strop.c strorder.c strports.c struct.c symbols.c tag.c throw.c unif.c variable.c vectors.c version.c vports.c weaks.c +libguile_la_SOURCES = alist.c arbiters.c async.c backtrace.c boolean.c chars.c continuations.c debug.c dynl.c dynwind.c eq.c error.c eval.c evalext.c feature.c filesys.c fluids.c fports.c gc.c gdbint.c gh_data.c gh_eval.c gh_funcs.c gh_init.c gh_io.c gh_list.c gh_predicates.c gsubr.c guardians.c hash.c hashtab.c init.c ioext.c keywords.c lang.c list.c load.c macros.c mallocs.c mb.c mbconv.c modules.c net_db.c numbers.c objects.c objprop.c options.c pairs.c ports.c posix.c print.c procprop.c procs.c ramap.c random.c read.c root.c scmsigs.c script.c simpos.c smob.c socket.c sort.c srcprop.c stackchk.c stacks.c stime.c strings.c strop.c strorder.c strports.c struct.c symbols.c tag.c throw.c unif.c variable.c vectors.c version.c vports.c weaks.c -BUILT_SOURCES = cpp_err_symbols.c cpp_sig_symbols.c libpath.h alist.x arbiters.x async.x backtrace.x boolean.x chars.x continuations.x debug.x dynl.x dynwind.x eq.x error.x eval.x evalext.x feature.x filesys.x fluids.x fports.x gc.x gsubr.x guardians.x hash.x hashtab.x init.x ioext.x iselect.x keywords.x lang.x list.x load.x macros.x mallocs.x mb.x modules.x net_db.x numbers.x objects.x objprop.x options.x pairs.x ports.x posix.x print.x procprop.x procs.x random.x ramap.x read.x regex-posix.x root.x scmsigs.x script.x simpos.x smob.x socket.x sort.x srcprop.x stackchk.x stacks.x stime.x strings.x strop.x strorder.x strports.x struct.x symbols.x tag.x threads.x throw.x unif.x variable.x vectors.x version.x vports.x weaks.x +BUILT_SOURCES = cpp_err_symbols.c cpp_sig_symbols.c libpath.h alist.x arbiters.x async.x backtrace.x boolean.x chars.x continuations.x debug.x dynl.x dynwind.x eq.x error.x eval.x evalext.x feature.x filesys.x fluids.x fports.x gc.x gsubr.x guardians.x hash.x hashtab.x init.x ioext.x iselect.x keywords.x lang.x list.x load.x macros.x mallocs.x mb.x mbconv.x modules.x net_db.x numbers.x objects.x objprop.x options.x pairs.x ports.x posix.x print.x procprop.x procs.x random.x ramap.x read.x regex-posix.x root.x scmsigs.x script.x simpos.x smob.x socket.x sort.x srcprop.x stackchk.x stacks.x stime.x strings.x strop.x strorder.x strports.x struct.x symbols.x tag.x threads.x throw.x unif.x variable.x vectors.x version.x vports.x weaks.x EXTRA_libguile_la_SOURCES = _scm.h strerror.c inet_aton.c putenv.c threads.c alloca.c regex-posix.c iselect.c @@ -125,7 +125,7 @@ pkginclude_HEADERS = gh.h # These are headers visible as <libguile/mumble.h>. modincludedir = $(includedir)/libguile -modinclude_HEADERS = __scm.h alist.h arbiters.h async.h backtrace.h boolean.h chars.h continuations.h debug.h dynl.h dynwind.h eq.h error.h eval.h evalext.h feature.h filesys.h fports.h gc.h gdb_interface.h gdbint.h genio.h gsubr.h guardians.h hash.h hashtab.h init.h ioext.h keywords.h kw.h lang.h list.h load.h macros.h mallocs.h mb.h modules.h net_db.h numbers.h objects.h objprop.h options.h pairs.h ports.h posix.h regex-posix.h print.h procprop.h procs.h random.h ramap.h read.h root.h scmsigs.h script.h simpos.h smob.h socket.h sort.h srcprop.h stackchk.h stacks.h stime.h strings.h strop.h strorder.h strports.h struct.h symbols.h tag.h tags.h throw.h unif.h variable.h vectors.h version.h vports.h weaks.h snarf.h threads.h coop-defs.h fluids.h iselect.h +modinclude_HEADERS = __scm.h alist.h arbiters.h async.h backtrace.h boolean.h chars.h continuations.h debug.h dynl.h dynwind.h eq.h error.h eval.h evalext.h feature.h filesys.h fports.h gc.h gdb_interface.h gdbint.h genio.h gsubr.h guardians.h hash.h hashtab.h init.h ioext.h keywords.h kw.h lang.h list.h load.h macros.h mallocs.h mb.h mbconv.h modules.h net_db.h numbers.h objects.h objprop.h options.h pairs.h ports.h posix.h regex-posix.h print.h procprop.h procs.h random.h ramap.h read.h root.h scmsigs.h script.h simpos.h smob.h socket.h sort.h srcprop.h stackchk.h stacks.h stime.h strings.h strop.h strorder.h strports.h struct.h symbols.h tag.h tags.h throw.h unif.h variable.h vectors.h version.h vports.h weaks.h snarf.h threads.h coop-defs.h fluids.h iselect.h modinclude_DATA = scmconfig.h @@ -170,12 +170,13 @@ error.lo eval.lo evalext.lo feature.lo filesys.lo fluids.lo fports.lo \ gc.lo gdbint.lo gh_data.lo gh_eval.lo gh_funcs.lo gh_init.lo gh_io.lo \ gh_list.lo gh_predicates.lo gsubr.lo guardians.lo hash.lo hashtab.lo \ init.lo ioext.lo keywords.lo lang.lo list.lo load.lo macros.lo \ -mallocs.lo mb.lo modules.lo net_db.lo numbers.lo objects.lo objprop.lo \ -options.lo pairs.lo ports.lo posix.lo print.lo procprop.lo procs.lo \ -ramap.lo random.lo read.lo root.lo scmsigs.lo script.lo simpos.lo \ -smob.lo socket.lo sort.lo srcprop.lo stackchk.lo stacks.lo stime.lo \ -strings.lo strop.lo strorder.lo strports.lo struct.lo symbols.lo tag.lo \ -throw.lo unif.lo variable.lo vectors.lo version.lo vports.lo weaks.lo +mallocs.lo mb.lo mbconv.lo modules.lo net_db.lo numbers.lo objects.lo \ +objprop.lo options.lo pairs.lo ports.lo posix.lo print.lo procprop.lo \ +procs.lo ramap.lo random.lo read.lo root.lo scmsigs.lo script.lo \ +simpos.lo smob.lo socket.lo sort.lo srcprop.lo stackchk.lo stacks.lo \ +stime.lo strings.lo strop.lo strorder.lo strports.lo struct.lo \ +symbols.lo tag.lo throw.lo unif.lo variable.lo vectors.lo version.lo \ +vports.lo weaks.lo PROGRAMS = $(bin_PROGRAMS) guile_OBJECTS = guile.o @@ -222,10 +223,10 @@ DEP_FILES = .deps/alist.P .deps/alloca.P .deps/arbiters.P .deps/async.P \ .deps/hash.P .deps/hashtab.P .deps/inet_aton.P .deps/init.P \ .deps/ioext.P .deps/iselect.P .deps/keywords.P .deps/lang.P \ .deps/list.P .deps/load.P .deps/macros.P .deps/mallocs.P .deps/mb.P \ -.deps/modules.P .deps/net_db.P .deps/numbers.P .deps/objects.P \ -.deps/objprop.P .deps/options.P .deps/pairs.P .deps/ports.P \ -.deps/posix.P .deps/print.P .deps/procprop.P .deps/procs.P \ -.deps/putenv.P .deps/ramap.P .deps/random.P .deps/read.P \ +.deps/mbconv.P .deps/modules.P .deps/net_db.P .deps/numbers.P \ +.deps/objects.P .deps/objprop.P .deps/options.P .deps/pairs.P \ +.deps/ports.P .deps/posix.P .deps/print.P .deps/procprop.P \ +.deps/procs.P .deps/putenv.P .deps/ramap.P .deps/random.P .deps/read.P \ .deps/regex-posix.P .deps/root.P .deps/scmsigs.P .deps/script.P \ .deps/simpos.P .deps/smob.P .deps/socket.P .deps/sort.P .deps/srcprop.P \ .deps/stackchk.P .deps/stacks.P .deps/stime.P .deps/strerror.P \ diff --git a/libguile/init.c b/libguile/init.c index d9a8b2dca..527403074 100644 --- a/libguile/init.c +++ b/libguile/init.c @@ -46,7 +46,6 @@ #include "_scm.h" /* Everybody has an init function. */ -#include "mb.h" #include "alist.h" #include "arbiters.h" #include "async.h" @@ -82,6 +81,8 @@ #include "load.h" #include "macros.h" #include "mallocs.h" +#include "mb.h" +#include "mbconv.h" #include "modules.h" #include "net_db.h" #include "numbers.h" @@ -449,6 +450,7 @@ scm_boot_guile_1 (base, closure) #endif start_stack (base); scm_init_mb (); + scm_init_mbconv (); scm_init_gsubr (); scm_init_feature (); scm_init_alist (); diff --git a/libguile/mbconv.c b/libguile/mbconv.c new file mode 100644 index 000000000..e3a256aa0 --- /dev/null +++ b/libguile/mbconv.c @@ -0,0 +1,366 @@ +/* Copyright (C) 1999 Free Software Foundation, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * As a special exception, the Free Software Foundation gives permission + * for additional uses of the text contained in its release of GUILE. + * + * The exception is that, if you link the GUILE library with other files + * to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the GUILE library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the + * Free Software Foundation under the name GUILE. If you copy + * code from other Free Software Foundation releases into a copy of + * GUILE, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for GUILE, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ + +/* Much code here is borrowed from Tom Tromey's libunicode --- thanks, + Tom! Unfortunately, I can't simply use libunicode itself at the + moment, since our canonical internal encoding is different. When + Emacs and Guile switch to UTF-8, hopefully that will change. */ + + +/* Headers. */ + +#include "_scm.h" + +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +#include "mbconv.h" + +#ifdef HAVE_ICONV +# include <iconv.h> +#else +/* This is harmless as it is completely ignored by the code when the + above condition is false. */ +typedef void *iconv_t; +#endif + + +/* Exceptions. */ + +SCM_GLOBAL_SYMBOL (scm_text_unknown_encoding, "text:unknown-encoding"); +static const char text_unknown_encoding_msg[] = + "unable to convert from encoding `%s' to encoding `%s'"; + + +/* The implementation of the conversion context object. */ + +struct scm_mb_iconv_ours +{ + /* Converter from source character set to Guile character set. */ + struct scm_mb_encoding *from; + + /* Converter private data. */ + void *from_data; + + /* Converter from Guile character set to destination character set. */ + struct scm_mb_encoding *to; + + /* Converter private data. */ + void *to_data; + + /* Buffer used to store intermediate results. */ + scm_char_t *buffer; + + /* Number of valid characters in buffer. */ + size_t valid; + + /* Total number of character slots in buffer. */ + size_t size; +}; + +struct scm_mb_iconv +{ + /* Type of converter. */ + enum { + scm_mb_iconv_type_native, + scm_mb_iconv_type_ours + } type; + + union + { + iconv_t native; /* Used in `native' case. */ + struct scm_mb_iconv_ours ours; /* Used in `our' case. */ + } u; +}; + + +/* The registry of all encodings. */ + +/* Linked list of all character sets. */ +static struct scm_mb_encoding *encodings; + +void +scm_mb_register_encoding (struct scm_mb_encoding *vec) +{ + vec->next = encodings; + encodings = vec; +} + +static struct scm_mb_encoding * +find_encoding (const char *name) +{ + struct scm_mb_encoding *cs; + + for (cs = encodings; cs; cs = cs->next) + { + int i; + for (i = 0; cs->names[i]; ++i) + { + if (! strcasecmp (cs->names[i], name)) + return cs; + } + } + + return cs; +} + + +/* Creating and destroying conversion contexts. */ + +static void +no_memory_for_open (struct scm_mb_iconv *r) +{ + if (r) + { + if (r->u.ours.buffer) free (r->u.ours.buffer); + free (r); + } + + scm_memory_error ("scm_mb_iconv_open"); +} + +struct scm_mb_iconv * +scm_mb_iconv_open (const char *tocode, const char *fromcode) +{ + struct scm_mb_iconv *r = (struct scm_mb_iconv *) malloc (sizeof (*r)); + + if (! r) + no_memory_for_open (r); + + r->u.ours.buffer = 0; + + /* Try our encodings first. */ + r->u.ours.from = find_encoding (fromcode); + if (r->u.ours.from) + r->u.ours.to = find_encoding (tocode); + if (r->u.ours.from && r->u.ours.to) + { + r->type = scm_mb_iconv_type_ours; + + /* FIXME: how to pick the size? */ + r->u.ours.size = 1024; + r->u.ours.buffer = (scm_char_t *) malloc (r->u.ours.size + * sizeof (scm_char_t)); + if (! r->u.ours.buffer) + no_memory_for_open (r); + + r->u.ours.valid = 0; + + if (r->u.ours.from->init + && ! r->u.ours.from->init (&r->u.ours.from_data)) + no_memory_for_open (r); + + if (r->u.ours.to->init && ! r->u.ours.to->init (&r->u.ours.to_data)) + { + if (r->u.ours.from->destroy) + r->u.ours.from->destroy (&r->u.ours.from_data); + no_memory_for_open (r); + } + + return r; + } + +#ifdef HAVE_ICONV + /* We don't have the conversions the user requested. Try the + system's iconv library. */ + r->u.native = iconv_open (tocode, fromcode); + if (r->u.native != (iconv_t) -1) + { + r->type = scm_mb_iconv_type_native; + return r; + } +#endif + + free (r); + + { + SCM args = SCM_LIST2 (scm_makfrom0str (fromcode), + scm_makfrom0str (tocode)); + + scm_error (scm_text_unknown_encoding, "scm_mb_iconv_open", + text_unknown_encoding_msg, args, args); + } + + return 0; +} + +void +scm_mb_iconv_close (struct scm_mb_iconv *cd) +{ + switch (cd->type) + { + case scm_mb_iconv_type_native: +#ifdef HAVE_ICONV + if (iconv_close (cd->u.native) < 0) + scm_syserror ("scm_mb_iconv_close"); + break; +#else + abort (); +#endif + + case scm_mb_iconv_type_ours: + if (cd->u.ours.to->destroy) + cd->u.ours.to->destroy (&cd->u.ours.to_data); + if (cd->u.ours.from->destroy) + cd->u.ours.from->destroy (&cd->u.ours.from_data); + free (cd->u.ours.buffer); + break; + } + + free (cd); +} + + +/* Actually converting text. */ + +size_t +scm_mb_iconv (struct scm_mb_iconv *context, + const char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft) +{ + struct scm_mb_iconv_ours *ours; + +#ifdef HAVE_ICONV + if (context->type == scm_mb_iconv_type_native) + { + size_t result = iconv (context->u.native, + inbuf, inbytesleft, + outbuf, outbytesleft); + if (result == (size_t) -1) + switch (errno) + { + case EILSEQ: return scm_mb_iconv_bad_encoding; + case E2BIG: return scm_mb_iconv_more_room; + case EINVAL: return scm_mb_iconv_incomplete_encoding; + default: + scm_syserror ("scm_mb_iconv"); + } + else + return result; + } +#endif /* HAVE_ICONV */ + + ours = &context->u.ours; + + /* If inbuf or *inbuf is zero, then we need to reset the conversion + states. */ + if (! inbuf || ! *inbuf) + { + int result; + + /* Try to reset the output conversion first; if it fails, we need to + leave the input conversion state untouched. */ + result = ours->to->reset (ours->to_data, outbuf, outbytesleft); + if (result < 0) + return result; + + /* Reset the input context. */ + return ours->from->reset (ours->from_data, 0, 0); + } + + if (! outbuf || *outbytesleft <= 0) + return scm_mb_iconv_more_room; + + /* Oh! We actually have some *TEXT* to convert! Not bureaucracy!!! */ + while (*inbytesleft > 0) + { + /* Convert as many characters as possible from the input buffer + into the intermediate scm_char_t buffer. */ + { + scm_char_t *buf = ours->buffer + ours->valid; + size_t buf_left = ours->size - ours->valid; + enum scm_mb_read_result read_result + = ours->from->read (ours->from_data, inbuf, inbytesleft, + &buf, &buf_left); + ours->valid = ours->size - buf_left; + + if (*inbytesleft < 0) + abort (); + + switch (read_result) + { + case scm_mb_read_ok: + break; + case scm_mb_read_incomplete: + return scm_mb_iconv_incomplete_encoding; + case scm_mb_read_error: + return scm_mb_iconv_bad_encoding; + default: + abort (); + } + } + + /* Convert as many characters as possible from the intermediate + scm_char_t buffer to the output buffer. */ + { + scm_char_t *buf = ours->buffer; + size_t buf_left = ours->valid; + enum scm_mb_write_result write_result + = ours->to->write (ours->to_data, &buf, &buf_left, + outbuf, outbytesleft); + if (buf_left > 0) + memmove (ours->buffer, buf, buf_left * sizeof (scm_char_t)); + ours->valid = buf_left; + switch (write_result) + { + case scm_mb_write_ok: + break; + case scm_mb_write_more_room: + return scm_mb_iconv_more_room; + default: + abort (); + } + } + } + + return 0; +} + + +/* Initialization. */ + +void +scm_init_mbconv () +{ +#include "mbconv.x" +} diff --git a/libguile/scmconfig.h.in b/libguile/scmconfig.h.in index 4412efdd8..3ffd8fc34 100644 --- a/libguile/scmconfig.h.in +++ b/libguile/scmconfig.h.in @@ -236,6 +236,9 @@ /* Define if you have the gettimeofday function. */ #undef HAVE_GETTIMEOFDAY +/* Define if you have the iconv function. */ +#undef HAVE_ICONV + /* Define if you have the inet_aton function. */ #undef HAVE_INET_ATON |