Home | History | Annotate | Line # | Download | only in modules
citrus_mapper_std.c revision 1.10.38.1
      1  1.10.38.1  pgoyette /*	$NetBSD: citrus_mapper_std.c,v 1.10.38.1 2018/06/25 07:25:34 pgoyette Exp $	*/
      2        1.1  tshiozak 
      3        1.1  tshiozak /*-
      4        1.7   tnozaki  * Copyright (c)2003, 2006 Citrus Project,
      5        1.1  tshiozak  * All rights reserved.
      6        1.1  tshiozak  *
      7        1.1  tshiozak  * Redistribution and use in source and binary forms, with or without
      8        1.1  tshiozak  * modification, are permitted provided that the following conditions
      9        1.1  tshiozak  * are met:
     10        1.1  tshiozak  * 1. Redistributions of source code must retain the above copyright
     11        1.1  tshiozak  *    notice, this list of conditions and the following disclaimer.
     12        1.1  tshiozak  * 2. Redistributions in binary form must reproduce the above copyright
     13        1.1  tshiozak  *    notice, this list of conditions and the following disclaimer in the
     14        1.1  tshiozak  *    documentation and/or other materials provided with the distribution.
     15        1.1  tshiozak  *
     16        1.1  tshiozak  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     17        1.1  tshiozak  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18        1.1  tshiozak  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19        1.1  tshiozak  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     20        1.1  tshiozak  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21        1.1  tshiozak  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22        1.1  tshiozak  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23        1.1  tshiozak  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24        1.1  tshiozak  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25        1.1  tshiozak  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26        1.1  tshiozak  * SUCH DAMAGE.
     27        1.1  tshiozak  */
     28        1.1  tshiozak 
     29        1.1  tshiozak #include <sys/cdefs.h>
     30        1.1  tshiozak #if defined(LIBC_SCCS) && !defined(lint)
     31  1.10.38.1  pgoyette __RCSID("$NetBSD: citrus_mapper_std.c,v 1.10.38.1 2018/06/25 07:25:34 pgoyette Exp $");
     32        1.1  tshiozak #endif /* LIBC_SCCS and not lint */
     33        1.1  tshiozak 
     34        1.1  tshiozak #include <assert.h>
     35        1.1  tshiozak #include <errno.h>
     36        1.1  tshiozak #include <limits.h>
     37        1.1  tshiozak #include <stdio.h>
     38        1.1  tshiozak #include <stdlib.h>
     39        1.1  tshiozak #include <stdint.h>
     40        1.1  tshiozak #include <string.h>
     41        1.5    dogcow #include <machine/endian.h>
     42        1.2  tshiozak #include <sys/queue.h>
     43        1.1  tshiozak 
     44        1.1  tshiozak #include "citrus_namespace.h"
     45        1.1  tshiozak #include "citrus_types.h"
     46        1.1  tshiozak #include "citrus_bcs.h"
     47        1.1  tshiozak #include "citrus_region.h"
     48        1.1  tshiozak #include "citrus_mmap.h"
     49        1.1  tshiozak #include "citrus_module.h"
     50        1.1  tshiozak #include "citrus_hash.h"
     51        1.1  tshiozak #include "citrus_mapper.h"
     52        1.1  tshiozak #include "citrus_db.h"
     53        1.1  tshiozak #include "citrus_db_hash.h"
     54        1.1  tshiozak 
     55        1.1  tshiozak #include "citrus_mapper_std.h"
     56        1.1  tshiozak #include "citrus_mapper_std_file.h"
     57        1.1  tshiozak 
     58        1.1  tshiozak /* ---------------------------------------------------------------------- */
     59        1.1  tshiozak 
     60        1.1  tshiozak _CITRUS_MAPPER_DECLS(mapper_std);
     61        1.1  tshiozak _CITRUS_MAPPER_DEF_OPS(mapper_std);
     62        1.1  tshiozak 
     63        1.1  tshiozak 
     64        1.1  tshiozak /* ---------------------------------------------------------------------- */
     65        1.1  tshiozak 
     66        1.1  tshiozak int
     67        1.1  tshiozak _citrus_mapper_std_mapper_getops(struct _citrus_mapper_ops *ops, size_t lenops,
     68        1.1  tshiozak 				 u_int32_t expected_version)
     69        1.1  tshiozak {
     70        1.1  tshiozak 	if (expected_version<_CITRUS_MAPPER_ABI_VERSION || lenops<sizeof(*ops))
     71        1.1  tshiozak 		return (EINVAL);
     72        1.1  tshiozak 
     73        1.1  tshiozak 	memcpy(ops, &_citrus_mapper_std_mapper_ops,
     74        1.1  tshiozak 	       sizeof(_citrus_mapper_std_mapper_ops));
     75        1.1  tshiozak 
     76        1.1  tshiozak 	return (0);
     77        1.1  tshiozak }
     78        1.1  tshiozak 
     79        1.1  tshiozak /* ---------------------------------------------------------------------- */
     80        1.1  tshiozak 
     81        1.1  tshiozak static int
     82        1.1  tshiozak /*ARGSUSED*/
     83        1.1  tshiozak rowcol_convert(struct _citrus_mapper_std * __restrict ms,
     84        1.1  tshiozak 	       _index_t * __restrict dst, _index_t src,
     85        1.1  tshiozak 	       void * __restrict ps)
     86        1.1  tshiozak {
     87        1.7   tnozaki 	struct _citrus_mapper_std_rowcol *rc;
     88        1.7   tnozaki 	size_t i;
     89        1.7   tnozaki 	struct _citrus_mapper_std_linear_zone *lz;
     90        1.7   tnozaki 	_index_t n, idx = 0;
     91        1.1  tshiozak 	u_int32_t conv;
     92        1.1  tshiozak 
     93        1.7   tnozaki 	_DIAGASSERT(ms != NULL);
     94        1.8   tnozaki 	_DIAGASSERT(dst != NULL);
     95        1.7   tnozaki 	/* ps may be unused */
     96        1.7   tnozaki 	rc = &ms->ms_rowcol;
     97        1.7   tnozaki 
     98        1.7   tnozaki 	for (i = rc->rc_src_rowcol_len * rc->rc_src_rowcol_bits,
     99        1.7   tnozaki 	     lz = &rc->rc_src_rowcol[0]; i > 0; ++lz) {
    100        1.7   tnozaki 		i -= rc->rc_src_rowcol_bits;
    101        1.7   tnozaki 		n = (src >> i) & rc->rc_src_rowcol_mask;
    102        1.7   tnozaki 		if (n < lz->begin || n > lz->end) {
    103        1.7   tnozaki 			switch (rc->rc_oob_mode) {
    104        1.7   tnozaki 			case _CITRUS_MAPPER_STD_OOB_NONIDENTICAL:
    105        1.7   tnozaki 				*dst = rc->rc_dst_invalid;
    106        1.7   tnozaki 				return _MAPPER_CONVERT_NONIDENTICAL;
    107        1.7   tnozaki 			case _CITRUS_MAPPER_STD_OOB_ILSEQ:
    108        1.7   tnozaki 				return _MAPPER_CONVERT_ILSEQ;
    109        1.7   tnozaki 			default:
    110        1.7   tnozaki 				return _MAPPER_CONVERT_FATAL;
    111        1.7   tnozaki 			}
    112        1.3  tshiozak 		}
    113        1.7   tnozaki 		idx = idx * lz->width + n - lz->begin;
    114        1.1  tshiozak 	}
    115        1.1  tshiozak 	switch (rc->rc_dst_unit_bits) {
    116        1.1  tshiozak 	case 8:
    117        1.1  tshiozak 		conv = _region_peek8(&rc->rc_table, idx);
    118        1.1  tshiozak 		break;
    119        1.1  tshiozak 	case 16:
    120        1.1  tshiozak 		conv = be16toh(_region_peek16(&rc->rc_table, idx*2));
    121        1.1  tshiozak 		break;
    122        1.1  tshiozak 	case 32:
    123        1.1  tshiozak 		conv = be32toh(_region_peek32(&rc->rc_table, idx*4));
    124        1.1  tshiozak 		break;
    125        1.6  christos 	default:
    126        1.6  christos 		return _MAPPER_CONVERT_FATAL;
    127        1.1  tshiozak 	}
    128        1.1  tshiozak 
    129        1.1  tshiozak 	if (conv == rc->rc_dst_invalid) {
    130        1.1  tshiozak 		*dst = rc->rc_dst_invalid;
    131        1.3  tshiozak 		return _MAPPER_CONVERT_NONIDENTICAL;
    132        1.1  tshiozak 	}
    133        1.3  tshiozak 	if (conv == rc->rc_dst_ilseq)
    134        1.3  tshiozak 		return _MAPPER_CONVERT_ILSEQ;
    135        1.1  tshiozak 
    136        1.1  tshiozak 	*dst = conv;
    137        1.1  tshiozak 
    138        1.1  tshiozak 	return _MAPPER_CONVERT_SUCCESS;
    139        1.1  tshiozak }
    140        1.1  tshiozak 
    141        1.7   tnozaki static __inline int
    142        1.7   tnozaki set_linear_zone(struct _citrus_mapper_std_linear_zone *lz,
    143        1.7   tnozaki 	u_int32_t begin, u_int32_t end)
    144        1.7   tnozaki {
    145        1.7   tnozaki 	_DIAGASSERT(lz != NULL);
    146        1.7   tnozaki 
    147        1.7   tnozaki 	if (begin > end)
    148        1.7   tnozaki 		return EFTYPE;
    149        1.7   tnozaki 
    150        1.7   tnozaki 	lz->begin = begin;
    151        1.7   tnozaki 	lz->end = end;
    152        1.7   tnozaki 	lz->width= end - begin + 1;
    153        1.7   tnozaki 
    154        1.7   tnozaki 	return 0;
    155        1.7   tnozaki }
    156        1.7   tnozaki 
    157        1.7   tnozaki static __inline int
    158        1.7   tnozaki rowcol_parse_variable_compat(struct _citrus_mapper_std_rowcol *rc,
    159        1.7   tnozaki 	struct _region *r)
    160        1.7   tnozaki {
    161        1.7   tnozaki 	const struct _citrus_mapper_std_rowcol_info_compat_x *rcx;
    162        1.7   tnozaki 	struct _citrus_mapper_std_linear_zone *lz;
    163        1.7   tnozaki 	u_int32_t m, n;
    164        1.7   tnozaki 	int ret;
    165        1.7   tnozaki 
    166        1.7   tnozaki 	_DIAGASSERT(rc != NULL);
    167        1.7   tnozaki 	_DIAGASSERT(r != NULL && _region_size(r) == sizeof(*rcx));
    168        1.7   tnozaki 	rcx = _region_head(r);
    169        1.7   tnozaki 
    170        1.7   tnozaki 	rc->rc_dst_invalid = be32toh(rcx->rcx_dst_invalid);
    171        1.7   tnozaki 	rc->rc_dst_unit_bits = be32toh(rcx->rcx_dst_unit_bits);
    172        1.7   tnozaki 	m = be32toh(rcx->rcx_src_col_bits);
    173  1.10.38.1  pgoyette 	n = 1U << (m - 1);
    174        1.7   tnozaki 	n |= n - 1;
    175        1.7   tnozaki 	rc->rc_src_rowcol_bits = m;
    176        1.7   tnozaki 	rc->rc_src_rowcol_mask = n;
    177        1.7   tnozaki 
    178        1.7   tnozaki 	rc->rc_src_rowcol = malloc(2 *
    179        1.8   tnozaki 	    sizeof(*rc->rc_src_rowcol));
    180        1.7   tnozaki 	if (rc->rc_src_rowcol == NULL)
    181        1.7   tnozaki 		return ENOMEM;
    182        1.7   tnozaki 	lz = rc->rc_src_rowcol;
    183        1.7   tnozaki 	rc->rc_src_rowcol_len = 1;
    184        1.7   tnozaki 	m = be32toh(rcx->rcx_src_row_begin);
    185        1.7   tnozaki 	n = be32toh(rcx->rcx_src_row_end);
    186        1.7   tnozaki 	if (m + n > 0) {
    187        1.7   tnozaki 		ret = set_linear_zone(lz, m, n);
    188       1.10   tnozaki 		if (ret != 0) {
    189       1.10   tnozaki 			free(rc->rc_src_rowcol);
    190       1.10   tnozaki 			rc->rc_src_rowcol = NULL;
    191        1.7   tnozaki 			return ret;
    192       1.10   tnozaki 		}
    193        1.7   tnozaki 		++rc->rc_src_rowcol_len, ++lz;
    194        1.7   tnozaki 	}
    195        1.7   tnozaki 	m = be32toh(rcx->rcx_src_col_begin);
    196        1.7   tnozaki 	n = be32toh(rcx->rcx_src_col_end);
    197        1.7   tnozaki 
    198        1.7   tnozaki 	return set_linear_zone(lz, m, n);
    199        1.7   tnozaki }
    200        1.7   tnozaki 
    201        1.7   tnozaki static __inline int
    202        1.7   tnozaki rowcol_parse_variable(struct _citrus_mapper_std_rowcol *rc,
    203        1.7   tnozaki 	struct _region *r)
    204        1.7   tnozaki {
    205        1.7   tnozaki 	const struct _citrus_mapper_std_rowcol_info_x *rcx;
    206        1.7   tnozaki 	struct _citrus_mapper_std_linear_zone *lz;
    207        1.7   tnozaki 	u_int32_t m, n;
    208        1.7   tnozaki 	size_t i;
    209        1.7   tnozaki 	int ret;
    210        1.7   tnozaki 
    211        1.7   tnozaki 	_DIAGASSERT(rc != NULL);
    212        1.7   tnozaki 	_DIAGASSERT(r != NULL && _region_size(r) == sizeof(*rcx));
    213        1.7   tnozaki 	rcx = _region_head(r);
    214        1.7   tnozaki 
    215        1.7   tnozaki 	rc->rc_dst_invalid = be32toh(rcx->rcx_dst_invalid);
    216        1.7   tnozaki 	rc->rc_dst_unit_bits = be32toh(rcx->rcx_dst_unit_bits);
    217        1.7   tnozaki 
    218        1.7   tnozaki 	m = be32toh(rcx->rcx_src_rowcol_bits);
    219  1.10.38.1  pgoyette 	n = 1U << (m - 1);
    220        1.7   tnozaki 	n |= n - 1;
    221        1.7   tnozaki 	rc->rc_src_rowcol_bits = m;
    222        1.7   tnozaki 	rc->rc_src_rowcol_mask = n;
    223        1.7   tnozaki 
    224        1.7   tnozaki 	rc->rc_src_rowcol_len = be32toh(rcx->rcx_src_rowcol_len);
    225        1.7   tnozaki 	if (rc->rc_src_rowcol_len > _CITRUS_MAPPER_STD_ROWCOL_MAX)
    226        1.7   tnozaki 		return EFTYPE;
    227        1.7   tnozaki 	rc->rc_src_rowcol = malloc(rc->rc_src_rowcol_len *
    228        1.8   tnozaki 	    sizeof(*rc->rc_src_rowcol));
    229        1.7   tnozaki 	if (rc->rc_src_rowcol == NULL)
    230        1.7   tnozaki 		return ENOMEM;
    231        1.7   tnozaki 	for (i = 0, lz = rc->rc_src_rowcol;
    232        1.7   tnozaki 	     i < rc->rc_src_rowcol_len; ++i, ++lz) {
    233        1.7   tnozaki 		m = be32toh(rcx->rcx_src_rowcol[i].begin),
    234        1.7   tnozaki 		n = be32toh(rcx->rcx_src_rowcol[i].end);
    235        1.7   tnozaki 		ret = set_linear_zone(lz, m, n);
    236        1.7   tnozaki 		if (ret != 0) {
    237        1.7   tnozaki 			free(rc->rc_src_rowcol);
    238        1.7   tnozaki 			rc->rc_src_rowcol = NULL;
    239        1.7   tnozaki 			return ret;
    240        1.7   tnozaki 		}
    241        1.7   tnozaki 	}
    242        1.7   tnozaki 	return 0;
    243        1.7   tnozaki }
    244        1.7   tnozaki 
    245        1.7   tnozaki static void
    246        1.7   tnozaki rowcol_uninit(struct _citrus_mapper_std *ms)
    247        1.7   tnozaki {
    248        1.7   tnozaki 	struct _citrus_mapper_std_rowcol *rc;
    249        1.7   tnozaki 	_DIAGASSERT(ms != NULL);
    250        1.7   tnozaki 
    251        1.7   tnozaki 	rc = &ms->ms_rowcol;
    252        1.7   tnozaki 	free(rc->rc_src_rowcol);
    253        1.7   tnozaki }
    254        1.1  tshiozak 
    255        1.1  tshiozak static int
    256        1.1  tshiozak rowcol_init(struct _citrus_mapper_std *ms)
    257        1.1  tshiozak {
    258        1.1  tshiozak 	int ret;
    259        1.7   tnozaki 	struct _citrus_mapper_std_rowcol *rc;
    260        1.3  tshiozak 	const struct _citrus_mapper_std_rowcol_ext_ilseq_info_x *eix;
    261        1.1  tshiozak 	struct _region r;
    262        1.1  tshiozak 	u_int64_t table_size;
    263        1.7   tnozaki 	size_t i;
    264        1.7   tnozaki 	struct _citrus_mapper_std_linear_zone *lz;
    265        1.1  tshiozak 
    266        1.7   tnozaki 	_DIAGASSERT(ms != NULL);
    267        1.1  tshiozak 	ms->ms_convert = &rowcol_convert;
    268        1.7   tnozaki 	ms->ms_uninit = &rowcol_uninit;
    269        1.7   tnozaki 	rc = &ms->ms_rowcol;
    270        1.1  tshiozak 
    271        1.1  tshiozak 	/* get table region */
    272        1.1  tshiozak 	ret = _db_lookup_by_s(ms->ms_db, _CITRUS_MAPPER_STD_SYM_TABLE,
    273        1.1  tshiozak 			      &rc->rc_table, NULL);
    274        1.1  tshiozak 	if (ret) {
    275        1.1  tshiozak 		if (ret==ENOENT)
    276        1.1  tshiozak 			ret = EFTYPE;
    277        1.1  tshiozak 		return ret;
    278        1.1  tshiozak 	}
    279        1.1  tshiozak 
    280        1.1  tshiozak 	/* get table information */
    281        1.1  tshiozak 	ret = _db_lookup_by_s(ms->ms_db, _CITRUS_MAPPER_STD_SYM_INFO, &r, NULL);
    282        1.1  tshiozak 	if (ret) {
    283        1.1  tshiozak 		if (ret==ENOENT)
    284        1.3  tshiozak 			ret = EFTYPE;
    285        1.1  tshiozak 		return ret;
    286        1.1  tshiozak 	}
    287        1.7   tnozaki 	switch (_region_size(&r)) {
    288        1.7   tnozaki 	case _CITRUS_MAPPER_STD_ROWCOL_INFO_COMPAT_SIZE:
    289        1.7   tnozaki 		ret = rowcol_parse_variable_compat(rc, &r);
    290        1.7   tnozaki 		break;
    291        1.7   tnozaki 	case _CITRUS_MAPPER_STD_ROWCOL_INFO_SIZE:
    292        1.7   tnozaki 		ret = rowcol_parse_variable(rc, &r);
    293        1.7   tnozaki 		break;
    294        1.7   tnozaki 	default:
    295        1.7   tnozaki 		return EFTYPE;
    296        1.7   tnozaki 	}
    297        1.7   tnozaki 	if (ret != 0)
    298        1.7   tnozaki 		return ret;
    299        1.7   tnozaki 	/* sanity check */
    300        1.7   tnozaki 	switch (rc->rc_src_rowcol_bits) {
    301        1.7   tnozaki 	case 8: case 16: case 32:
    302        1.7   tnozaki 		if (rc->rc_src_rowcol_len <= 32 / rc->rc_src_rowcol_bits)
    303        1.7   tnozaki 			break;
    304        1.7   tnozaki 	/*FALLTHROUGH*/
    305        1.7   tnozaki 	default:
    306        1.1  tshiozak 		return EFTYPE;
    307        1.7   tnozaki 	}
    308        1.1  tshiozak 
    309        1.3  tshiozak 	/* ilseq extension */
    310        1.3  tshiozak 	rc->rc_oob_mode = _CITRUS_MAPPER_STD_OOB_NONIDENTICAL;
    311        1.3  tshiozak 	rc->rc_dst_ilseq = rc->rc_dst_invalid;
    312        1.3  tshiozak 	ret = _db_lookup_by_s(ms->ms_db,
    313        1.3  tshiozak 			      _CITRUS_MAPPER_STD_SYM_ROWCOL_EXT_ILSEQ,
    314        1.3  tshiozak 			      &r, NULL);
    315        1.3  tshiozak 	if (ret && ret != ENOENT)
    316        1.3  tshiozak 		return ret;
    317        1.3  tshiozak 	if (_region_size(&r) < sizeof(*eix))
    318        1.3  tshiozak 		return EFTYPE;
    319        1.3  tshiozak 	if (ret == 0) {
    320        1.3  tshiozak 		eix = _region_head(&r);
    321        1.3  tshiozak 		rc->rc_oob_mode = be32toh(eix->eix_oob_mode);
    322        1.3  tshiozak 		rc->rc_dst_ilseq = be32toh(eix->eix_dst_ilseq);
    323        1.3  tshiozak 	}
    324        1.1  tshiozak 
    325        1.1  tshiozak 	/* calcurate expected table size */
    326        1.7   tnozaki 	i = rc->rc_src_rowcol_len;
    327        1.7   tnozaki 	lz = &rc->rc_src_rowcol[--i];
    328        1.7   tnozaki 	table_size = lz->width;
    329        1.7   tnozaki 	while (i > 0) {
    330        1.7   tnozaki 		lz = &rc->rc_src_rowcol[--i];
    331        1.7   tnozaki 		table_size *= lz->width;
    332        1.7   tnozaki 	}
    333        1.1  tshiozak 	table_size *= rc->rc_dst_unit_bits/8;
    334        1.1  tshiozak 
    335        1.1  tshiozak 	if (table_size > UINT32_MAX ||
    336        1.1  tshiozak 	    _region_size(&rc->rc_table) < table_size)
    337        1.1  tshiozak 		return EFTYPE;
    338        1.1  tshiozak 
    339        1.1  tshiozak 	return 0;
    340        1.1  tshiozak }
    341        1.1  tshiozak 
    342        1.1  tshiozak typedef int (*initfunc_t)(struct _citrus_mapper_std *);
    343        1.4      yamt static const struct {
    344        1.1  tshiozak 	const char			*t_name;
    345        1.1  tshiozak 	initfunc_t			t_init;
    346        1.1  tshiozak } types[] = {
    347        1.1  tshiozak 	{ _CITRUS_MAPPER_STD_TYPE_ROWCOL, &rowcol_init },
    348        1.1  tshiozak };
    349        1.1  tshiozak #define NUM_OF_TYPES ((int)(sizeof(types)/sizeof(types[0])))
    350        1.1  tshiozak 
    351        1.1  tshiozak static int
    352        1.1  tshiozak /*ARGSUSED*/
    353        1.1  tshiozak _citrus_mapper_std_mapper_init(struct _citrus_mapper_area *__restrict ma,
    354        1.1  tshiozak 			       struct _citrus_mapper * __restrict cm,
    355        1.1  tshiozak 			       const char * __restrict curdir,
    356        1.1  tshiozak 			       const void * __restrict var, size_t lenvar,
    357        1.1  tshiozak 			       struct _citrus_mapper_traits * __restrict mt,
    358        1.1  tshiozak 			       size_t lenmt)
    359        1.1  tshiozak {
    360        1.1  tshiozak 	char path[PATH_MAX];
    361        1.1  tshiozak 	const char *type;
    362        1.1  tshiozak 	int ret, id;
    363        1.1  tshiozak 	struct _citrus_mapper_std *ms;
    364        1.1  tshiozak 
    365        1.1  tshiozak 	/* set traits */
    366        1.1  tshiozak 	if (lenmt<sizeof(*mt)) {
    367        1.1  tshiozak 		ret = EINVAL;
    368        1.1  tshiozak 		goto err0;
    369        1.1  tshiozak 	}
    370        1.1  tshiozak 	mt->mt_src_max = mt->mt_dst_max = 1;	/* 1:1 converter */
    371        1.1  tshiozak 	mt->mt_state_size = 0;			/* stateless */
    372        1.1  tshiozak 
    373        1.1  tshiozak 	/* alloc mapper std structure */
    374        1.1  tshiozak 	ms = malloc(sizeof(*ms));
    375        1.1  tshiozak 	if (ms==NULL) {
    376        1.1  tshiozak 		ret = errno;
    377        1.1  tshiozak 		goto err0;
    378        1.1  tshiozak 	}
    379        1.1  tshiozak 
    380        1.1  tshiozak 	/* open mapper file */
    381        1.1  tshiozak 	snprintf(path, sizeof(path),
    382        1.1  tshiozak 		 "%s/%.*s", curdir, (int)lenvar, (const char *)var);
    383        1.1  tshiozak 	ret = _map_file(&ms->ms_file, path);
    384        1.1  tshiozak 	if (ret)
    385        1.1  tshiozak 		goto err1;
    386        1.1  tshiozak 
    387        1.1  tshiozak 	ret = _db_open(&ms->ms_db, &ms->ms_file, _CITRUS_MAPPER_STD_MAGIC,
    388        1.1  tshiozak 		       &_db_hash_std, NULL);
    389        1.1  tshiozak 	if (ret)
    390        1.1  tshiozak 		goto err2;
    391        1.1  tshiozak 
    392        1.1  tshiozak 	/* get mapper type */
    393        1.1  tshiozak 	ret = _db_lookupstr_by_s(ms->ms_db, _CITRUS_MAPPER_STD_SYM_TYPE,
    394        1.1  tshiozak 				 &type, NULL);
    395        1.1  tshiozak 	if (ret) {
    396        1.1  tshiozak 		if (ret==ENOENT)
    397        1.1  tshiozak 			ret = EFTYPE;
    398        1.1  tshiozak 		goto err3;
    399        1.1  tshiozak 	}
    400        1.1  tshiozak 	for (id=0; id<NUM_OF_TYPES; id++)
    401        1.1  tshiozak 		if (_bcs_strcasecmp(type, types[id].t_name) == 0)
    402        1.1  tshiozak 			break;
    403        1.1  tshiozak 
    404        1.1  tshiozak 	if (id == NUM_OF_TYPES)
    405        1.1  tshiozak 		goto err3;
    406        1.1  tshiozak 
    407        1.1  tshiozak 	/* init the per-type structure */
    408        1.1  tshiozak 	ret = (*types[id].t_init)(ms);
    409        1.1  tshiozak 	if (ret)
    410        1.1  tshiozak 		goto err3;
    411        1.1  tshiozak 
    412        1.1  tshiozak 	cm->cm_closure = ms;
    413        1.1  tshiozak 
    414        1.1  tshiozak 	return 0;
    415        1.1  tshiozak 
    416        1.1  tshiozak err3:
    417        1.1  tshiozak 	_db_close(ms->ms_db);
    418        1.1  tshiozak err2:
    419        1.1  tshiozak 	_unmap_file(&ms->ms_file);
    420        1.1  tshiozak err1:
    421        1.1  tshiozak 	free(ms);
    422        1.1  tshiozak err0:
    423        1.1  tshiozak 	return ret;
    424        1.1  tshiozak }
    425        1.1  tshiozak 
    426        1.1  tshiozak static void
    427        1.1  tshiozak /*ARGSUSED*/
    428        1.1  tshiozak _citrus_mapper_std_mapper_uninit(struct _citrus_mapper *cm)
    429        1.1  tshiozak {
    430        1.1  tshiozak 	struct _citrus_mapper_std *ms;
    431        1.1  tshiozak 
    432        1.9       wiz 	_DIAGASSERT(cm!=NULL && cm->cm_closure!=NULL);
    433        1.1  tshiozak 
    434        1.1  tshiozak 	ms = cm->cm_closure;
    435        1.1  tshiozak 	if (ms->ms_uninit)
    436        1.1  tshiozak 		(*ms->ms_uninit)(ms);
    437        1.1  tshiozak 	_db_close(ms->ms_db);
    438        1.1  tshiozak 	_unmap_file(&ms->ms_file);
    439        1.1  tshiozak 	free(ms);
    440        1.1  tshiozak }
    441        1.1  tshiozak 
    442        1.1  tshiozak static void
    443        1.1  tshiozak /*ARGSUSED*/
    444        1.1  tshiozak _citrus_mapper_std_mapper_init_state(struct _citrus_mapper * __restrict cm,
    445        1.1  tshiozak 				     void * __restrict ps)
    446        1.1  tshiozak {
    447        1.1  tshiozak }
    448        1.1  tshiozak 
    449        1.1  tshiozak static int
    450        1.1  tshiozak /*ARGSUSED*/
    451        1.1  tshiozak _citrus_mapper_std_mapper_convert(struct _citrus_mapper * __restrict cm,
    452        1.1  tshiozak 				  _index_t * __restrict dst, _index_t src,
    453        1.1  tshiozak 				  void * __restrict ps)
    454        1.1  tshiozak {
    455        1.1  tshiozak 	struct _citrus_mapper_std *ms;
    456        1.1  tshiozak 
    457        1.1  tshiozak 	_DIAGASSERT(cm!=NULL && cm->cm_closure!=NULL);
    458        1.1  tshiozak 
    459        1.1  tshiozak 	ms = cm->cm_closure;
    460        1.1  tshiozak 
    461        1.1  tshiozak 	_DIAGASSERT(ms->ms_convert != NULL);
    462        1.1  tshiozak 
    463        1.1  tshiozak 	return (*ms->ms_convert)(ms, dst, src, ps);
    464        1.1  tshiozak }
    465