Hi, The patch enables building apr-iconv with the selected set of prelinked modules. If the requested module is not found as prelinked, then the existing mechanism (apr_dso_*) is used.
Right now the selected module list is static, so the next step would be to make that customizable. The prelinked modules are: _tbl_simple, cp437, cp850, cp851, cp852, iso-8859-1, iso-8859-2, iso-8859-5, windows-1250, windows-1251, windows-1252 which might, or might not be the ones that are relevant, cause for EBCDIC machines the ebcdic-* modules should be prelinked. MT.
cvs server: Diffing ccs Index: ccs/cp437.c =================================================================== RCS file: /home/cvspublic/apr-iconv/ccs/cp437.c,v retrieving revision 1.2 diff -u -3 -r1.2 cp437.c --- ccs/cp437.c 2 Dec 2002 22:47:48 -0000 1.2 +++ ccs/cp437.c 10 Mar 2003 10:39:06 -0000 @@ -339,7 +339,7 @@ convert_from_ucs, convert_to_ucs, }; -struct iconv_module_desc iconv_module = { +ICONV_MOD_DECLARE(cp437) = { ICMOD_UC_CCS, apr_iconv_mod_noevent, NULL, Index: ccs/cp850.c =================================================================== RCS file: /home/cvspublic/apr-iconv/ccs/cp850.c,v retrieving revision 1.2 diff -u -3 -r1.2 cp850.c --- ccs/cp850.c 2 Dec 2002 22:47:48 -0000 1.2 +++ ccs/cp850.c 10 Mar 2003 10:39:06 -0000 @@ -234,7 +234,7 @@ convert_from_ucs, convert_to_ucs, }; -struct iconv_module_desc iconv_module = { +ICONV_MOD_DECLARE(cp850) = { ICMOD_UC_CCS, apr_iconv_mod_noevent, NULL, Index: ccs/cp851.c =================================================================== RCS file: /home/cvspublic/apr-iconv/ccs/cp851.c,v retrieving revision 1.2 diff -u -3 -r1.2 cp851.c --- ccs/cp851.c 2 Dec 2002 22:47:48 -0000 1.2 +++ ccs/cp851.c 10 Mar 2003 10:39:07 -0000 @@ -234,7 +234,7 @@ convert_from_ucs, convert_to_ucs, }; -struct iconv_module_desc iconv_module = { +ICONV_MOD_DECLARE(cp851) = { ICMOD_UC_CCS, apr_iconv_mod_noevent, NULL, Index: ccs/cp852.c =================================================================== RCS file: /home/cvspublic/apr-iconv/ccs/cp852.c,v retrieving revision 1.2 diff -u -3 -r1.2 cp852.c --- ccs/cp852.c 2 Dec 2002 22:47:48 -0000 1.2 +++ ccs/cp852.c 10 Mar 2003 10:39:08 -0000 @@ -234,7 +234,7 @@ convert_from_ucs, convert_to_ucs, }; -struct iconv_module_desc iconv_module = { +ICONV_MOD_DECLARE(cp852) = { ICMOD_UC_CCS, apr_iconv_mod_noevent, NULL, Index: ccs/iso-8859-1.c =================================================================== RCS file: /home/cvspublic/apr-iconv/ccs/iso-8859-1.c,v retrieving revision 1.2 diff -u -3 -r1.2 iso-8859-1.c --- ccs/iso-8859-1.c 2 Dec 2002 22:47:48 -0000 1.2 +++ ccs/iso-8859-1.c 10 Mar 2003 10:39:09 -0000 @@ -129,7 +129,7 @@ convert_from_ucs, convert_to_ucs, }; -struct iconv_module_desc iconv_module = { +ICONV_MOD_DECLARE(iso_8859_1) = { ICMOD_UC_CCS, apr_iconv_mod_noevent, NULL, Index: ccs/iso-8859-2.c =================================================================== RCS file: /home/cvspublic/apr-iconv/ccs/iso-8859-2.c,v retrieving revision 1.2 diff -u -3 -r1.2 iso-8859-2.c --- ccs/iso-8859-2.c 2 Dec 2002 22:47:48 -0000 1.2 +++ ccs/iso-8859-2.c 10 Mar 2003 10:39:09 -0000 @@ -199,7 +199,7 @@ convert_from_ucs, convert_to_ucs, }; -struct iconv_module_desc iconv_module = { +ICONV_MOD_DECLARE(iso_8859_2) = { ICMOD_UC_CCS, apr_iconv_mod_noevent, NULL, Index: ccs/iso-8859-5.c =================================================================== RCS file: /home/cvspublic/apr-iconv/ccs/iso-8859-5.c,v retrieving revision 1.2 diff -u -3 -r1.2 iso-8859-5.c --- ccs/iso-8859-5.c 2 Dec 2002 22:47:48 -0000 1.2 +++ ccs/iso-8859-5.c 10 Mar 2003 10:39:10 -0000 @@ -199,7 +199,7 @@ convert_from_ucs, convert_to_ucs, }; -struct iconv_module_desc iconv_module = { +ICONV_MOD_DECLARE(iso_8859_5) = { ICMOD_UC_CCS, apr_iconv_mod_noevent, NULL, Index: ccs/windows-1250.c =================================================================== RCS file: /home/cvspublic/apr-iconv/ccs/windows-1250.c,v retrieving revision 1.2 diff -u -3 -r1.2 windows-1250.c --- ccs/windows-1250.c 2 Dec 2002 22:47:50 -0000 1.2 +++ ccs/windows-1250.c 10 Mar 2003 10:39:11 -0000 @@ -269,7 +269,7 @@ convert_from_ucs, convert_to_ucs, }; -struct iconv_module_desc iconv_module = { +ICONV_MOD_DECLARE(windows_1250) = { ICMOD_UC_CCS, apr_iconv_mod_noevent, NULL, Index: ccs/windows-1251.c =================================================================== RCS file: /home/cvspublic/apr-iconv/ccs/windows-1251.c,v retrieving revision 1.2 diff -u -3 -r1.2 windows-1251.c --- ccs/windows-1251.c 2 Dec 2002 22:47:50 -0000 1.2 +++ ccs/windows-1251.c 10 Mar 2003 10:39:12 -0000 @@ -234,7 +234,7 @@ convert_from_ucs, convert_to_ucs, }; -struct iconv_module_desc iconv_module = { +ICONV_MOD_DECLARE(windows_1251) = { ICMOD_UC_CCS, apr_iconv_mod_noevent, NULL, Index: ccs/windows-1252.c =================================================================== RCS file: /home/cvspublic/apr-iconv/ccs/windows-1252.c,v retrieving revision 1.2 diff -u -3 -r1.2 windows-1252.c --- ccs/windows-1252.c 2 Dec 2002 22:47:50 -0000 1.2 +++ ccs/windows-1252.c 10 Mar 2003 10:39:13 -0000 @@ -269,7 +269,7 @@ convert_from_ucs, convert_to_ucs, }; -struct iconv_module_desc iconv_module = { +ICONV_MOD_DECLARE(windows_1252) = { ICMOD_UC_CCS, apr_iconv_mod_noevent, NULL, cvs server: Diffing ces cvs server: Diffing include cvs server: Diffing lib Index: lib/iconv.h =================================================================== RCS file: /home/cvspublic/apr-iconv/lib/iconv.h,v retrieving revision 1.16 diff -u -3 -r1.16 iconv.h --- lib/iconv.h 12 Feb 2003 20:36:11 -0000 1.16 +++ lib/iconv.h 10 Mar 2003 10:39:14 -0000 @@ -1,6 +1,6 @@ /*- * Copyright (c) 1999,2000 - * Konstantin Chuguev. All rights reserved. + * Konstantin Chuguev. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -12,8 +12,8 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by Konstantin Chuguev - * and its contributors. + * This product includes software developed by Konstantin Chuguev + * and its contributors. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -49,28 +49,28 @@ /* * iconv module types */ -#define ICMOD_ANY 0 -#define ICMOD_LIB 1 -#define ICMOD_UC_CCS 0x100 /* UC - CCS for CES */ -#define ICMOD_UC_CES 0x101 /* UC - CES */ +#define ICMOD_ANY 0 +#define ICMOD_LIB 1 +#define ICMOD_UC_CCS 0x100 /* UC - CCS for CES */ +#define ICMOD_UC_CES 0x101 /* UC - CES */ /* * iconv module flags */ -#define ICMODF_LOADED 0x8000 +#define ICMODF_LOADED 0x8000 /* * iconv module handler events */ -#define ICMODEV_LOAD 1 /* module load. after dependencies resolved */ -#define ICMODEV_UNLOAD 2 /* module unload */ +#define ICMODEV_LOAD 1 /* module load. after dependencies resolved */ +#define ICMODEV_UNLOAD 2 /* module unload */ #define ICMODEV_DYN_LOAD 3 /* load dynamic dependencies */ #define ICMODEV_DYN_UNLOAD 4 /* unload dynamic dependencies */ struct iconv_module_depend { - int md_type; - const char * md_name; - const void * md_data; + int md_type; + const char * md_name; + const void * md_data; }; struct iconv_module; @@ -80,38 +80,38 @@ typedef int iconv_mod_event_t(struct iconv_module *, int, apr_pool_t *ctx); struct iconv_module_desc { - int imd_type; - iconv_mod_event_t *imd_event; - const struct iconv_module_depend *imd_depend; - const void * imd_data; + int imd_type; + iconv_mod_event_t *imd_event; + const struct iconv_module_depend *imd_depend; + const void * imd_data; }; #define END_ICONV_MODULE_DEPEND {0, NULL, NULL} -#define ICONV_MODULE(type,data) struct iconv_module_desc iconv_module \ - {(type), (data)} +#define ICONV_MODULE(type,data) struct iconv_module_desc iconv_module \ + {(type), (data)} struct iconv_module { - int im_flags; - void * im_handle; - struct iconv_module_desc *im_desc; - struct iconv_module *im_next; - struct iconv_module *im_deplist; - int im_depcnt; - const void * im_methods; - void * im_data; - const void * im_depdata; /* data if module loaded from dependency */ - const void * im_args; + int im_flags; + void * im_handle; + struct iconv_module_desc *im_desc; + struct iconv_module *im_next; + struct iconv_module *im_deplist; + int im_depcnt; + const void * im_methods; + void * im_data; + const void * im_depdata; /* data if module loaded from dependency */ + const void * im_args; /* This is module-private data. Nothing outside the module itself may touch it. */ void *im_private; }; -#define ICONV_MOD_LOAD(mod,ctx) (mod)->im_desc->imd_event(mod, ICMODEV_LOAD,ctx) -#define ICONV_MOD_UNLOAD(mod,ctx) (mod)->im_desc->imd_event(mod, ICMODEV_UNLOAD,ctx) -#define ICONV_MOD_DYN_LOAD(mod,ctx) (mod)->im_desc->imd_event(mod, ICMODEV_DYN_LOAD,ctx) -#define ICONV_MOD_DYN_UNLOAD(mod,ctx) (mod)->im_desc->imd_event(mod, ICMODEV_DYN_UNLOAD,ctx) +#define ICONV_MOD_LOAD(mod,ctx) (mod)->im_desc->imd_event(mod, ICMODEV_LOAD,ctx) +#define ICONV_MOD_UNLOAD(mod,ctx) (mod)->im_desc->imd_event(mod, ICMODEV_UNLOAD,ctx) +#define ICONV_MOD_DYN_LOAD(mod,ctx) (mod)->im_desc->imd_event(mod, ICMODEV_DYN_LOAD,ctx) +#define ICONV_MOD_DYN_UNLOAD(mod,ctx) (mod)->im_desc->imd_event(mod, ICMODEV_DYN_UNLOAD,ctx) /* * iconv converter definitions. @@ -119,17 +119,17 @@ typedef int iconv_open_t(const char *, const char *, void **, apr_pool_t *); typedef int iconv_close_t(void *, apr_pool_t *); typedef apr_status_t iconv_conv_t(void *, const unsigned char **, apr_size_t *, - unsigned char **, apr_size_t *, apr_size_t *); + unsigned char **, apr_size_t *, apr_size_t *); struct iconv_converter_desc { - iconv_open_t * icd_open; - iconv_close_t * icd_close; - iconv_conv_t * icd_conv; + iconv_open_t * icd_open; + iconv_close_t * icd_close; + iconv_conv_t * icd_conv; }; struct iconv_converter { - struct iconv_converter_desc *ic_desc; - void * ic_data; + struct iconv_converter_desc *ic_desc; + void * ic_data; }; /* @@ -137,44 +137,44 @@ */ #define UCS_CHAR_ZERO_WIDTH_NBSP 0xFEFF -#define UCS_CHAR_INVALID 0xFFFE -#define UCS_CHAR_NONE 0xFFFF +#define UCS_CHAR_INVALID 0xFFFE +#define UCS_CHAR_NONE 0xFFFF -typedef apr_uint16_t ucs2_t; /* Unicode character [D5] */ -typedef apr_uint32_t ucs4_t; /* Unicode scalar character [D28] */ +typedef apr_uint16_t ucs2_t; /* Unicode character [D5] */ +typedef apr_uint32_t ucs4_t; /* Unicode scalar character [D28] */ #define ucs_t ucs4_t /* * one-level coded character set conversion tables */ typedef struct { - apr_uint16_t data[128]; -} iconv_ccs_convtable_7bit; /* 7-bit charset to Unicode */ + apr_uint16_t data[128]; +} iconv_ccs_convtable_7bit; /* 7-bit charset to Unicode */ typedef struct { - apr_uint16_t data[256]; -} iconv_ccs_convtable_8bit; /* 8-bit charset to Unicode */ + apr_uint16_t data[256]; +} iconv_ccs_convtable_8bit; /* 8-bit charset to Unicode */ /* * two-level coded character set conversion tables */ typedef struct { - const iconv_ccs_convtable_7bit *data[128]; -} iconv_ccs_convtable_14bit; /* 14-bit charset to Unicode */ + const iconv_ccs_convtable_7bit *data[128]; +} iconv_ccs_convtable_14bit; /* 14-bit charset to Unicode */ typedef struct { - const iconv_ccs_convtable_8bit *data[256]; -} iconv_ccs_convtable_16bit; /* 16-bit charset to Unicode; - * Unicode to any charset */ + const iconv_ccs_convtable_8bit *data[256]; +} iconv_ccs_convtable_16bit; /* 16-bit charset to Unicode; + * Unicode to any charset */ /* * abstract coded character set conversion table */ typedef union { - iconv_ccs_convtable_7bit _7bit; - iconv_ccs_convtable_8bit _8bit; - iconv_ccs_convtable_14bit _14bit; - iconv_ccs_convtable_16bit _16bit; + iconv_ccs_convtable_7bit _7bit; + iconv_ccs_convtable_8bit _8bit; + iconv_ccs_convtable_14bit _14bit; + iconv_ccs_convtable_16bit _16bit; } iconv_ccs_convtable; /* @@ -186,12 +186,12 @@ * charset conversion module descriptor */ struct iconv_ccs_desc { - const char * const * names; - int nbits; - const iconv_ccs_convtable * from_ucs; - const iconv_ccs_convtable * to_ucs; - iconv_ccs_converter_t * convert_from_ucs; - iconv_ccs_converter_t * convert_to_ucs; + const char * const * names; + int nbits; + const iconv_ccs_convtable * from_ucs; + const iconv_ccs_convtable * to_ucs; + iconv_ccs_converter_t * convert_from_ucs; + iconv_ccs_converter_t * convert_to_ucs; }; /* @@ -200,31 +200,31 @@ static APR_INLINE ucs2_t iconv_ccs_convert_7bit(const iconv_ccs_convtable *table, ucs2_t ch) { - return ch & 0x80 ? UCS_CHAR_INVALID : table->_7bit.data[ch]; + return ch & 0x80 ? UCS_CHAR_INVALID : table->_7bit.data[ch]; } static APR_INLINE ucs2_t iconv_ccs_convert_8bit(const iconv_ccs_convtable *table, ucs2_t ch) { - return table->_8bit.data[ch]; + return table->_8bit.data[ch]; } static APR_INLINE ucs2_t iconv_ccs_convert_14bit(const iconv_ccs_convtable *table, ucs2_t ch) { - const iconv_ccs_convtable_7bit *sub_table; + const iconv_ccs_convtable_7bit *sub_table; - sub_table = ch & 0x8080 ? NULL : table->_14bit.data[ch >> 8]; - return sub_table ? sub_table->data[ch & 0x7F] : UCS_CHAR_INVALID; + sub_table = ch & 0x8080 ? NULL : table->_14bit.data[ch >> 8]; + return sub_table ? sub_table->data[ch & 0x7F] : UCS_CHAR_INVALID; } static APR_INLINE ucs2_t iconv_ccs_convert_16bit(const iconv_ccs_convtable *table, ucs2_t ch) { - const iconv_ccs_convtable_8bit *sub_table; + const iconv_ccs_convtable_8bit *sub_table; - sub_table = table->_16bit.data[ch >> 8]; - return sub_table ? sub_table->data[ch & 0xFF] : UCS_CHAR_INVALID; + sub_table = table->_16bit.data[ch >> 8]; + return sub_table ? sub_table->data[ch & 0xFF] : UCS_CHAR_INVALID; } #define ICONV_CCS_CONVERT_FROM_UCS(ccsd, ch) \ @@ -238,11 +238,11 @@ struct iconv_ces; typedef int iconv_ces_open_t(struct iconv_ces *, apr_pool_t *); -typedef int iconv_ces_close_t(struct iconv_ces *); -typedef void iconv_ces_reset_t(struct iconv_ces *); -typedef const char * const *iconv_ces_names_t(struct iconv_ces *); -typedef int iconv_ces_nbits_t(struct iconv_ces *); -typedef int iconv_ces_nbytes_t(struct iconv_ces *); +typedef int iconv_ces_close_t(struct iconv_ces *); +typedef void iconv_ces_reset_t(struct iconv_ces *); +typedef const char * const *iconv_ces_names_t(struct iconv_ces *); +typedef int iconv_ces_nbits_t(struct iconv_ces *); +typedef int iconv_ces_nbytes_t(struct iconv_ces *); typedef apr_ssize_t iconv_ces_convert_from_ucs_t (struct iconv_ces *data, ucs_t in, @@ -253,21 +253,21 @@ const unsigned char **inbuf, apr_size_t *inbytesleft); struct iconv_ces_desc { - iconv_ces_open_t * open; - iconv_ces_close_t * close; - iconv_ces_reset_t * reset; - iconv_ces_names_t * names; - iconv_ces_nbits_t * nbits; - iconv_ces_nbytes_t * nbytes; - iconv_ces_convert_from_ucs_t * convert_from_ucs; - iconv_ces_convert_to_ucs_t * convert_to_ucs; - const void *data; + iconv_ces_open_t * open; + iconv_ces_close_t * close; + iconv_ces_reset_t * reset; + iconv_ces_names_t * names; + iconv_ces_nbits_t * nbits; + iconv_ces_nbytes_t * nbytes; + iconv_ces_convert_from_ucs_t * convert_from_ucs; + iconv_ces_convert_to_ucs_t * convert_to_ucs; + const void *data; }; struct iconv_ces { - struct iconv_ces_desc * desc; - void * data; - struct iconv_module * mod; + struct iconv_ces_desc * desc; + void * data; + struct iconv_module * mod; }; API_DECLARE_NONSTD(int) apr_iconv_ces_open(const char *ces_name, struct iconv_ces **cespp, apr_pool_t *ctx); @@ -285,23 +285,23 @@ */ #define apr_iconv_ces_open_zero (iconv_ces_open_t*)apr_iconv_ces_zero -#define iconv_char32bit(ch) ((ch) & 0xFFFF0000) +#define iconv_char32bit(ch) ((ch) & 0xFFFF0000) -#define ICONV_CES_OPEN(ces,ctx) (ces)->desc->open(ces,ctx) -#define ICONV_CES_CLOSE(ces) (ces)->desc->close(ces) -#define ICONV_CES_RESET(ces) (ces)->desc->reset(ces) +#define ICONV_CES_OPEN(ces,ctx) (ces)->desc->open(ces,ctx) +#define ICONV_CES_CLOSE(ces) (ces)->desc->close(ces) +#define ICONV_CES_RESET(ces) (ces)->desc->reset(ces) #define ICONV_CES_CONVERT_FROM_UCS(cesd, in, outbuf, outbytes) \ - ((cesd)->desc->convert_from_ucs((cesd), (in), (outbuf), (outbytes))) + ((cesd)->desc->convert_from_ucs((cesd), (in), (outbuf), (outbytes))) #define ICONV_CES_CONVERT_TO_UCS(cesd, inbuf, inbytes) \ - ((cesd)->desc->convert_to_ucs((cesd), (inbuf), (inbytes))) + ((cesd)->desc->convert_to_ucs((cesd), (inbuf), (inbytes))) #define ICONV_CES_DRIVER_DECL(name) \ - iconv_ces_open_t iconv_##name##_open; \ - iconv_ces_close_t iconv_##name##_close; \ - iconv_ces_reset_t iconv_##name##_reset; \ - iconv_ces_nbits_t iconv_##name##_nbits; \ - iconv_ces_convert_from_ucs_t iconv_##name##_convert_from_ucs; \ - iconv_ces_convert_to_ucs_t iconv_##name##_convert_to_ucs + iconv_ces_open_t iconv_##name##_open; \ + iconv_ces_close_t iconv_##name##_close; \ + iconv_ces_reset_t iconv_##name##_reset; \ + iconv_ces_nbits_t iconv_##name##_nbits; \ + iconv_ces_convert_from_ucs_t iconv_##name##_convert_from_ucs; \ + iconv_ces_convert_to_ucs_t iconv_##name##_convert_to_ucs /* ************************************************ @@ -310,8 +310,8 @@ */ typedef struct iconv_ces_euc_ccs { - const char *prefix; - apr_size_t prefixlen; + const char *prefix; + apr_size_t prefixlen; } iconv_ces_euc_ccs_t; ICONV_CES_DRIVER_DECL(euc); @@ -322,19 +322,28 @@ enum { ICONV_SHIFT_SI = 0, ICONV_SHIFT_SO, ICONV_SHIFT_SS2, ICONV_SHIFT_SS3 }; typedef struct iconv_ces_iso2022_ccs { - int shift; - const char * designator; - apr_size_t designatorlen; + int shift; + const char * designator; + apr_size_t designatorlen; } iconv_ces_iso2022_ccs_t; typedef struct { - const int * shift_tab; - int nccs; - const struct iconv_ces_iso2022_ccs *ccs; + const int * shift_tab; + int nccs; + const struct iconv_ces_iso2022_ccs *ccs; } iconv_ces_iso2022_data; ICONV_CES_DRIVER_DECL(iso2022); +/* + * preloaded modules name confilct resolving + */ +#ifdef ICONV_MOD_STATIC +#define ICONV_MOD_DECLARE(name) struct iconv_module_desc iconv_##name##_module +#define ICONV_MOD_PRELINK(name, mod) {name, &iconv_##mod##_module} +#else +#define ICONV_MOD_DECLARE(name) struct iconv_module_desc iconv_module +#endif API_DECLARE_NONSTD(int) apr_iconv_mod_load(const char *, int, const void *, struct iconv_module **, apr_pool_t *); API_DECLARE_NONSTD(int) apr_iconv_mod_unload(struct iconv_module *,apr_pool_t *ctx); @@ -348,7 +357,7 @@ API_DECLARE_NONSTD(apr_status_t) apr_iconv_euc_open(struct iconv_ces *ces, apr_pool_t *ctx); API_DECLARE_NONSTD(apr_status_t) apr_iconv_euc_close(struct iconv_ces *ces); -API_DECLARE_NONSTD(apr_ssize_t) apr_iconv_euc_convert_from_ucs(struct iconv_ces *ces, ucs_t in, unsigned char **outbuf, apr_size_t *outbytesleft); +API_DECLARE_NONSTD(apr_ssize_t) apr_iconv_euc_convert_from_ucs(struct iconv_ces *ces, ucs_t in, unsigned char **outbuf, apr_size_t *outbytesleft); API_DECLARE_NONSTD(ucs_t) apr_iconv_euc_convert_to_ucs(struct iconv_ces *ces, const unsigned char **inbuf, apr_size_t *inbytesleft); API_DECLARE_NONSTD(apr_status_t) apr_iconv_iso2022_open(struct iconv_ces *ces, apr_pool_t *ctx); Index: lib/iconv_module.c =================================================================== RCS file: /home/cvspublic/apr-iconv/lib/iconv_module.c,v retrieving revision 1.14 diff -u -3 -r1.14 iconv_module.c --- lib/iconv_module.c 17 Feb 2003 03:49:35 -0000 1.14 +++ lib/iconv_module.c 10 Mar 2003 10:39:15 -0000 @@ -11,8 +11,8 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by Boris Popov - * and its contributors. + * This product includes software developed by Boris Popov + * and its contributors. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -49,13 +49,56 @@ #include "charset_alias.h" #endif +extern ICONV_MOD_DECLARE(_tbl_simple); +extern ICONV_MOD_DECLARE(cp437); +extern ICONV_MOD_DECLARE(cp850); +extern ICONV_MOD_DECLARE(cp851); +extern ICONV_MOD_DECLARE(cp852); +extern ICONV_MOD_DECLARE(iso_8859_1); +extern ICONV_MOD_DECLARE(iso_8859_2); +extern ICONV_MOD_DECLARE(iso_8859_5); +extern ICONV_MOD_DECLARE(windows_1250); +extern ICONV_MOD_DECLARE(windows_1251); +extern ICONV_MOD_DECLARE(windows_1252); + +static struct { + const char *name; + struct iconv_module_desc *mdesc; +} prelinked_modules[] = { + ICONV_MOD_PRELINK("_tbl_simple", _tbl_simple), + ICONV_MOD_PRELINK("cp437", cp437), + ICONV_MOD_PRELINK("cp850", cp850), + ICONV_MOD_PRELINK("cp851", cp851), + ICONV_MOD_PRELINK("cp852", cp852), + ICONV_MOD_PRELINK("iso-8859-1", iso_8859_1), + ICONV_MOD_PRELINK("iso-8859-2", iso_8859_2), + ICONV_MOD_PRELINK("iso-8859-5", iso_8859_5), + ICONV_MOD_PRELINK("windows-1250", windows_1250), + ICONV_MOD_PRELINK("windows-1251", windows_1251), + ICONV_MOD_PRELINK("windows-1252", windows_1252), + {NULL, NULL} +}; + +static int +iconv_plopen(const char *name, struct iconv_module_desc **mdesc) +{ + int i; + for (i = 0; prelinked_modules[i].name; i++) + if (!strcmp(name, prelinked_modules[i].name)) { + *mdesc = prelinked_modules[i].mdesc; + return 0; + } + + return -1; +} + static apr_status_t iconv_getpathname(char *buffer, const char *dir, const char *name, apr_pool_t *ctx) { apr_status_t rv; - apr_finfo_t sb; + apr_finfo_t sb; - apr_snprintf(buffer, APR_PATH_MAX, "%s/%s.so", dir, name); + apr_snprintf(buffer, APR_PATH_MAX, "%s/%s.so", dir, name); rv = apr_stat(&sb, buffer, APR_FINFO_TYPE, ctx); #ifdef API_HAVE_CHARSET_ALIAS_TABLE /* If we didn't find the file, try again after looking in @@ -77,18 +120,18 @@ static apr_status_t iconv_getpath(char *buf, const char *name, apr_pool_t *ctx) { - char buffer[APR_PATH_MAX]; + char buffer[APR_PATH_MAX]; apr_array_header_t *pathelts; apr_pool_t *subpool; apr_status_t status; - char *ptr; + char *ptr; status = apr_pool_create(&subpool, ctx); if (status) return status; - if (apr_tolower(name[0]) == 'x' && name[1] == '-') - name += 2; + if (apr_tolower(name[0]) == 'x' && name[1] == '-') + name += 2; ptr = buffer; while (0 != (*ptr++ = apr_tolower(*name++))) ; @@ -116,120 +159,122 @@ static int iconv_dlopen(const char *name, const char *symbol, void **hpp, void **dpp, apr_pool_t *ctx) { - apr_dso_handle_t *handle; - void *data; + apr_dso_handle_t *handle; + void *data; - /* dlopen */ - if (apr_dso_load(&handle, name, ctx) != APR_SUCCESS) { - return EINVAL; - } - /* dlsym */ - if ( apr_dso_sym(&data, handle, symbol) == APR_SUCCESS) { - *hpp = handle; - *dpp = data; - return 0; - } - apr_dso_unload(handle); - return EINVAL; + /* dlopen */ + if (apr_dso_load(&handle, name, ctx) != APR_SUCCESS) { + return EINVAL; + } + /* dlsym */ + if ( apr_dso_sym(&data, handle, symbol) == APR_SUCCESS) { + *hpp = handle; + *dpp = data; + return 0; + } + apr_dso_unload(handle); + return EINVAL; } API_DECLARE_NONSTD(int) apr_iconv_mod_load(const char *modname, int modtype, const void *args, - struct iconv_module **modpp, apr_pool_t *ctx) + struct iconv_module **modpp, apr_pool_t *ctx) { - struct iconv_module_desc *mdesc; - struct iconv_module *mod, *depmod; - const struct iconv_module_depend *depend; - char buffer[APR_PATH_MAX]; - void *handle; - int error; - - if (iconv_getpath(buffer, modname, ctx) != 0) - return EINVAL; - - error = iconv_dlopen(buffer, "iconv_module", &handle, (void**)&mdesc, ctx); - if (error) - return error; - if (modtype != ICMOD_ANY && mdesc->imd_type != modtype) { - apr_dso_unload(handle); - return APR_EFTYPE; - } - mod = malloc(sizeof(*mod)); - if (mod == NULL) { - apr_dso_unload(handle); - return ENOMEM; - } - memset(mod, 0, sizeof(*mod)); - mod->im_handle = handle; - mod->im_desc = mdesc; - mod->im_args = args; - depend = mdesc->imd_depend; - if (depend) { - while (depend->md_name) { - error = apr_iconv_mod_load(depend->md_name, - depend->md_type, NULL, &depmod, ctx); - if (error) - goto bad; - depmod->im_depdata = depend->md_data; - depmod->im_next = mod->im_deplist; - mod->im_deplist = depmod; - depend++; - } - } - error = ICONV_MOD_DYN_LOAD(mod,ctx); - if (error) - goto bad; - depmod = mod->im_deplist; - while (depmod) { - mod->im_depcnt++; - depmod = depmod->im_next; - } - error = ICONV_MOD_LOAD(mod,ctx); - if (error) - goto bad; - mod->im_flags |= ICMODF_LOADED; - *modpp = mod; - return 0; + struct iconv_module_desc *mdesc; + struct iconv_module *mod, *depmod; + const struct iconv_module_depend *depend; + char buffer[APR_PATH_MAX]; + void *handle = NULL; + int error; + + if (iconv_plopen(modname, &mdesc)) { + if (iconv_getpath(buffer, modname, ctx) != 0) + return EINVAL; + + error = iconv_dlopen(buffer, "iconv_module", &handle, (void**)&mdesc, ctx); + if (error) + return error; + } + if (modtype != ICMOD_ANY && mdesc->imd_type != modtype) { + if (handle) apr_dso_unload(handle); + return APR_EFTYPE; + } + mod = malloc(sizeof(*mod)); + if (mod == NULL) { + if (handle) apr_dso_unload(handle); + return ENOMEM; + } + memset(mod, 0, sizeof(*mod)); + mod->im_handle = handle; + mod->im_desc = mdesc; + mod->im_args = args; + depend = mdesc->imd_depend; + if (depend) { + while (depend->md_name) { + error = apr_iconv_mod_load(depend->md_name, + depend->md_type, NULL, &depmod, ctx); + if (error) + goto bad; + depmod->im_depdata = depend->md_data; + depmod->im_next = mod->im_deplist; + mod->im_deplist = depmod; + depend++; + } + } + error = ICONV_MOD_DYN_LOAD(mod,ctx); + if (error) + goto bad; + depmod = mod->im_deplist; + while (depmod) { + mod->im_depcnt++; + depmod = depmod->im_next; + } + error = ICONV_MOD_LOAD(mod,ctx); + if (error) + goto bad; + mod->im_flags |= ICMODF_LOADED; + *modpp = mod; + return 0; bad: - apr_iconv_mod_unload(mod,ctx); - return error; + apr_iconv_mod_unload(mod,ctx); + return error; } API_DECLARE_NONSTD(int) apr_iconv_mod_unload(struct iconv_module *mod, apr_pool_t *ctx) { - struct iconv_module *deplist, *tmp; - int error = 0; + struct iconv_module *deplist, *tmp; + int error = 0; - if (mod == NULL) - return -1; - if (mod->im_flags & ICMODF_LOADED) - error = ICONV_MOD_UNLOAD(mod,ctx); - error = ICONV_MOD_DYN_UNLOAD(mod,ctx); - deplist = mod->im_deplist; - while (deplist) { - tmp = deplist->im_next; - apr_iconv_mod_unload(deplist,ctx); - deplist = tmp; - } - if (mod->im_handle != NULL) - if (apr_dso_unload(mod->im_handle) != APR_SUCCESS) - error = APR_EINVAL; - free(mod); - return error; + if (mod == NULL) + return -1; + if (mod->im_flags & ICMODF_LOADED) + error = ICONV_MOD_UNLOAD(mod,ctx); + error = ICONV_MOD_DYN_UNLOAD(mod,ctx); + deplist = mod->im_deplist; + while (deplist) { + tmp = deplist->im_next; + apr_iconv_mod_unload(deplist,ctx); + deplist = tmp; + } + if (mod->im_handle != NULL) + if (apr_dso_unload(mod->im_handle) != APR_SUCCESS) + error = APR_EINVAL; + free(mod); + return error; } API_DECLARE_NONSTD(int) apr_iconv_mod_noevent(struct iconv_module *mod, int event, apr_pool_t *ctx) { - switch (event) { - case ICMODEV_LOAD: - case ICMODEV_UNLOAD: - case ICMODEV_DYN_LOAD: - case ICMODEV_DYN_UNLOAD: - break; - default: - return APR_EINVAL; - } - return 0; + switch (event) { + case ICMODEV_LOAD: + case ICMODEV_UNLOAD: + case ICMODEV_DYN_LOAD: + case ICMODEV_DYN_UNLOAD: + break; + default: + return APR_EINVAL; + } + return 0; }