geniconvtbl.c revision 85bb5f1d642e430b889478fb1200b511338085d7
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <synch.h>
#if defined(DEBUG)
#include <stdarg.h>
#endif /* !DEBUG */
#include "iconv_tm.h"
#include "hash.h"
/*
* Debug
*/
#if defined(DEBUG)
static void trace_init(void);
static void trace_message(char *, ...);
static char trace_option[128];
#else /* !DEBUG */
#define trace_init()
#define TRACE()
#define TRACE_MESSAGE(c, args)
#endif /* !DEBUG */
/*
* ITM reference information
*/
typedef struct _itm_ref {
char *name; /* ITM file name */
} itm_ref_t;
/*
* struct _icv_state; to keep status
*/
typedef struct _icv_state {
#if defined(OP_DEPTH_MAX)
int op_depth; /* depth of operation */
#endif /* OP_DEPTH_MAX */
} icv_state_t;
/*
* function prototype
*/
void * _icv_open(const char *);
void _icv_close(icv_state_t *);
const unsigned char **, size_t *,
unsigned char **, size_t *, long);
const unsigned char **, size_t *,
unsigned char **, size_t *, long);
const unsigned char **, size_t *,
unsigned char **, size_t *, long);
const unsigned char **, size_t *,
unsigned char **, size_t *, long);
const unsigned char **, size_t *,
size_t, itm_direc_t *);
const unsigned char **, size_t *,
unsigned char **, size_t *);
const unsigned char **, size_t *,
unsigned char **, size_t *);
static void itm_ref_free(int, void *, void *, void *, size_t);
static itm_ref_t *itm_ref_inc(const char *);
static void itm_ref_dec(itm_ref_t *);
static void op_init_default(icv_state_t *);
static void op_reset_default(icv_state_t *);
static void regs_init(icv_state_t *);
/*
* macro definition
*/
((itm_place2_t)(place2))))
((*inbytesleft) -= (c)))
*inbytesleft = ileft, \
*outbytesleft = oleft)
/*
* Open; called from iconv_open()
*/
void *
{
int r;
/*
* for debug
*/
trace_init();
/*
* _icv_open() primaty task
*/
return ((void *)(-1));
}
r = errno;
errno = r;
return (NULL);
}
#if defined(OP_DEPTH_MAX)
#endif /* OP_DEPTH_MAX */
/*
* brief sanity check
*/
return ((void *)(-1));
}
/* allocate register region */
} else {
r = errno;
errno = r;
return ((void *)(-1));
}
}
/* evaluate init operation */
} else {
}
return (ist);
}
/*
* Close; called from iconv_close
*/
void
{
return;
}
}
/*
* Actual conversion; called from iconv()
*/
const unsigned char **inbuf,
unsigned char **outbuf,
{
const unsigned char *ip;
return ((size_t)(-1));
}
}
if (NULL == inbytesleft) {
ileft = 0;
inbytesleft = &ileft;
}
retval = 0;
/*
* If (NULL == inbuf || NULL == *inbuf) then this conversion is
* placed into initial state.
*/
return (retval);
}
} else {
}
return ((size_t)(0));
}
char *map;
const unsigned char *ip;
unsigned char *op;
outbuf, outbytesleft, 0);
return (retval);
}
ileft = *inbytesleft;
oleft = *outbytesleft;
while (1 <= ileft) {
if (oleft < 1) {
UPDATE_ARGS();
errno));
return ((size_t)-1);
}
ileft--;
oleft--;
}
UPDATE_ARGS();
return (0);
outbuf, outbytesleft, 0);
return (retval);
outbuf, outbytesleft, 0);
return (retval);
outbuf, outbytesleft, 0);
return (retval);
outbuf, outbytesleft, 0);
return (retval);
}
#if defined(OP_DEPTH_MAX)
#endif /* OP_DEPTH_MAX */
/*
* Main loop; basically 1 loop per 1 output character
*/
while (0 < *inbytesleft) {
long i;
for (i = 0; /* NULL */; i++, direc++) {
TRACE_MESSAGE('e',
("_icv_iconv:error=%d\n", errno));
return ((size_t)(-1));
}
TRACE_MESSAGE('E',
("escape seq (default action=%6p, "
"type=%ld) executing\n",
continue;
return (retval);
goto retry_cond_eval;
}
} else {
}
TRACE_MESSAGE('a',
("inbytesleft=%ld; type=%ld:action=%p\n",
switch (ITM_TBL_MASK & type) {
case ITM_TBL_OP:
return (retval);
}
break;
case ITM_TBL_DIREC:
break;
case ITM_TBL_MAP:
switch (type) {
case ITM_TBL_MAP_INDEX_FIXED:
break;
case ITM_TBL_MAP_HASH:
break;
case ITM_TBL_MAP_DENSE_ENC:
break;
case ITM_TBL_MAP_LOOKUP:
break;
default:
TRACE_MESSAGE('e',
("_icv_iconv:error=%d\n", errno));
return ((size_t)(-1));
}
return (retval);
}
break;
default: /* never */
TRACE_MESSAGE('e',
("_icv_iconv:error=%d\n", errno));
return ((size_t)(-1));
}
break;
}
}
return (retval);
}
/*
* map-indexed-fixed
*/
static size_t
const unsigned char **inbuf,
unsigned char **outbuf,
long once)
{
long i;
unsigned char c;
unsigned long j;
const unsigned char *p;
do {
return ((size_t)(-1));
}
j = 0;
for (i = 0; i < map_hdr->source_len; i++) {
GET(c);
j = ((j << 8) | c);
}
(0 < map_hdr->default_error)) {
return ((size_t)(-1));
}
return ((size_t)(-1));
}
if (0 == map_hdr->default_error) {
p = (((unsigned char *)(map_hdr + 1)) +
for (i = 0; i < map_hdr->result_len; i++) {
PUT(*(p + i));
}
} else {
for (i = 0; i < map_hdr->source_len; i++) {
PUT(*(p + i));
}
}
} else {
char *map_error;
if (0 == map_hdr->default_error) {
map_error = (void *)
}
(0 != *(map_error))) {
(*inbuf) = (void *)
TRACE_MESSAGE('e',
("map_i_f:error=%d\n", errno));
return ((size_t)(-1));
}
p = (((unsigned char *)(map_hdr + 1)) +
(map_hdr->result_len *
for (i = 0; i < map_hdr->result_len; i++) {
PUT(*(p + i));
}
}
} while ((0 < *inbytesleft) && (0 == once));
return (size_t)(0);
}
/*
* map-lookup-fixed
*/
static size_t
const unsigned char **inbuf,
unsigned char **outbuf,
long once)
{
long i;
unsigned char *map;
const unsigned char *p;
long high;
long mid;
long low;
long result;
do {
return ((size_t)(-1));
}
i++, p++) {
if (*(unsigned char *)(*inbuf + i) < *p) {
result = -1;
break;
}
if (*p < *(unsigned char *)(*inbuf + i)) {
result = 1;
break;
}
}
if (result < 0) {
} else if (0 < result) {
} else { /* 0 == result */
break;
}
}
if (0 != result) {
if (map_hdr->default_error < 0) {
p = *inbuf;
} else if (0 == map_hdr->default_error) {
} else if (0 < map_hdr->default_error) {
errno));
return ((size_t)(-1));
}
} else {
if (0 != (*p)) {
errno));
return ((size_t)(-1));
}
p++;
}
return ((size_t)(-1));
}
for (i = 0; i < map_hdr->result_len; i++) {
PUT(*(p + i));
}
} while ((0 < *inbytesleft) && (0 == once));
return ((size_t)(0));
}
/*
* map-hash-lookup
*/
static size_t
const unsigned char **inbuf,
unsigned char **outbuf,
long once)
{
long i;
unsigned char *map_error;
unsigned char *map_hash;
unsigned char *map_of;
const unsigned char *p;
const unsigned char *q;
long high;
long mid;
long low;
long result;
do {
if (*inbytesleft < source_len) {
return ((size_t)(-1));
}
result = 1;
q = *inbuf;
for (i = 0, result = 0; i < source_len; i++) {
if (*(q + i) != *(p++)) {
result = -2;
break;
}
}
TRACE_MESSAGE('G',
("(h=%d): find pair without conflict\n",
hash_value));
} else if (0 == *(map_error + hash_value)) {
result = -3;
} else /* if (0 < *(map_error + hash_value)) */ {
for (i = 0, result = 0; i < source_len; i++) {
if (*(q + i) != *(p++)) {
result = 1;
break;
}
}
if (0 < result) {
for (i = 0, result = 0;
i < source_len;
i++, p++) {
if (*(q + i) < *p) {
result = -1;
break;
}
if (*p < *(q + i)) {
result = 1;
break;
}
}
if (result < 0) {
} else if (0 < result) {
} else { /* 0 == result */
"find data on out of "
"hashtable with CONFLICT\n",
hash_value));
break;
}
}
}
}
if (0 != result) {
if (map_hdr->default_error < 0) {
p = q;
} else if (0 == map_hdr->default_error) {
} else if (0 < map_hdr->default_error) {
hash_value));
TRACE_MESSAGE('e',
("map_h_l:error=%d\n", errno));
return ((size_t)(-1));
}
} else {
if (0 != (*p)) {
return ((size_t)(-1));
}
p++;
}
if (*outbytesleft < result_len) {
return ((size_t)(-1));
}
for (i = 0; i < result_len; i++) {
PUT(*(p + i));
}
} while ((0 < *inbytesleft) && (0 == once));
return ((size_t)(0));
}
/*
* map-dense_encoding-lookup
*/
static size_t
const unsigned char **inbuf,
unsigned char **outbuf,
long once)
{
long i;
itm_num_t j;
const unsigned char *p;
unsigned char *map_ptr;
unsigned char *map_error;
unsigned char *byte_seq_min;
unsigned char *byte_seq_max;
if (0 == map_hdr->default_error) {
}
do {
return ((size_t)(-1));
}
(0 < map_hdr->default_error)) {
return ((size_t)(-1));
}
return ((size_t)(-1));
}
if (0 == map_hdr->default_error) {
map_hdr->result_len));
for (i = 0; i < map_hdr->result_len; i++) {
PUT(*(p + i));
}
} else {
p = *inbuf;
for (i = 0; i < map_hdr->source_len; i++) {
PUT(*(p + i));
}
}
} else {
if (0 != *(map_error + j)) {
TRACE_MESSAGE('e',
("map_d_e_l:error=%d\n", errno));
return ((size_t)(-1));
}
}
for (i = 0; i < map_hdr->result_len; i++) {
PUT(*(p + i));
}
}
} while ((0 < *inbytesleft) && (0 == once));
return ((size_t)(0));
}
/*
* Evaluate condition table
*
*/
static size_t
const unsigned char **inbuf,
)
{
long i;
long j;
long k;
unsigned char *p;
itm_data_t *d;
const unsigned char *ip;
retval = 0;
ileft = *inbytesleft;
case ITM_COND_BETWEEN:
errno));
goto eval_cond_return;
}
p = (unsigned char *)(rtsh + 1);
retval = 0;
retval = 1;
if ((*(ip + k) < *(p + k)) ||
*(ip + k))) {
retval = 0;
break;
}
}
if (1 == retval) {
break;
}
}
if (0 == retval) {
TRACE_MESSAGE('b',
("out of between (%p) len= rtsh=%ld\n",
goto eval_cond_return;
}
break; /* continue */
case ITM_COND_ESCAPESEQ:
/*
* if escape sequence occur,
* change ist->default_action and return 2.
* never return 1.
*/
retval = 0;
TRACE_MESSAGE('E',
("escape seq (default action=%6p, "
"type=%ld) set\n",
}
retval = 0;
break;
}
j++, d++) {
if (*inbytesleft < d->size) {
continue;
}
TRACE_MESSAGE('E',
("escape seq: discard=%ld chars\n",
d->size));
TRACE_MESSAGE('E',
("escape seq (default "
"action=%6p, type=%ld) set\n",
((itm_tbl_hdr_t *)
retval = 2;
goto eval_cond_return;
}
}
if (0 == retval) {
goto eval_cond_return;
}
break; /* continue */
case ITM_COND_EXPR:
if (0 == retval) {
goto eval_cond_return;
} else {
retval = 1;
}
break; /* continue */
default:
goto eval_cond_return;
}
}
return (retval);
}
/*
* Evaluate operation table
*
*/
static size_t
const unsigned char **inbuf,
unsigned char **outbuf,
{
long i;
retval = 0;
#if defined(OP_DEPTH_MAX)
return (RETVALERR);
}
#endif /* OP_DEPTH_MAX */
if (((long)(retval)) < 0) {
#if defined(OP_DEPTH_MAX)
#endif /* OP_DEPTH_MAX */
switch (retval) {
case RETVALERR:
return (retval);
case RETVALRET:
return (RETVALRET);
} else {
return (0);
}
}
}
}
#if defined(OP_DEPTH_MAX)
#endif /* OP_DEPTH_MAX */
return (retval);
}
/*
* Evaluate single operation
*
*/
static size_t
const unsigned char **inbuf,
unsigned char **outbuf,
{
itm_num_t c;
itm_num_t i;
itm_size_t z;
unsigned char *p;
itm_tbl_hdr_t *h;
itm_type_t t;
#define EVAL_EXPR(n) \
retval = 0;
case ITM_OP_EXPR:
break;
case ITM_OP_ERROR:
break;
case ITM_OP_ERROR_D:
break;
case ITM_OP_OUT:
if ((*outbytesleft) == 0) {
return ((size_t)(-1));
}
retval = *inbytesleft;
break;
case ITM_OP_OUT_D:
if ((*outbytesleft) == 0) {
return ((size_t)(-1));
}
break;
case ITM_OP_OUT_S:
if ((*outbytesleft) == 0) {
return ((size_t)(-1));
}
if (*outbytesleft < z) {
return ((size_t)(-1));
}
for (; 0 < z; --z, p++) {
PUT(*p);
}
break;
case ITM_OP_OUT_R:
if ((*outbytesleft) == 0) {
return ((size_t)(-1));
}
break;
case ITM_OP_OUT_INVD:
if ((*outbytesleft) == 0) {
return ((size_t)(-1));
}
break;
case ITM_OP_DISCARD:
#if defined(EVAL_EXPR)
#else /* !defined(EVAL_EXPR) */
#endif /* defined(EVAL_EXPR) */
#if defined(DISCARD)
#else /* defined(DISCARD) */
GET(c);
}
#endif /* defined(DISCARD) */
break;
case ITM_OP_DISCARD_D:
#if defined(DISCARD)
#else /* defined(DISCARD) */
GET(c);
}
#endif /* defined(DISCARD) */
break;
case ITM_OP_IF:
if (c) {
}
break;
case ITM_OP_IF_ELSE:
if (c) {
} else {
}
break;
case ITM_OP_DIRECTION:
return ((size_t)(-2));
case ITM_OP_MAP:
i = 0;
#if defined(EVAL_EXPR)
i = EVAL_EXPR(1);
#else /* !defined(EVAL_EXPR) */
#endif /* defined(EVAL_EXPR) */
(*inbytesleft) -= i;
(*inbuf) += i;
}
/*
* Based on what is the maptype, we call the corresponding
* mapping function.
*/
t = h->type;
switch (t) {
case ITM_TBL_MAP_INDEX_FIXED:
break;
case ITM_TBL_MAP_HASH:
break;
case ITM_TBL_MAP_DENSE_ENC:
break;
case ITM_TBL_MAP_LOOKUP:
break;
default:
/*
* This should not be possible, but in case we
* have an incorrect maptype, don't fall back to
* map_i_f(). Instead, because it is an error, return
* an error. See CR 6622765.
*/
break;
}
(*outbytesleft) += i;
(*outbuf) -= i;
}
break;
case ITM_OP_OPERATION:
break;
case ITM_OP_INIT:
} else {
}
break;
case ITM_OP_RESET:
} else {
}
break;
case ITM_OP_BREAK:
return (RETVALBRK);
case ITM_OP_RETURN:
return (RETVALRET);
case ITM_OP_PRINTCHR:
*inbuf, *outbytesleft);
c, *inbytesleft));
break;
case ITM_OP_PRINTHD:
*inbuf, *outbytesleft);
c, *inbytesleft));
break;
case ITM_OP_PRINTINT:
*inbuf, *outbytesleft);
c, *inbytesleft));
break;
default: /* never */
return (size_t)(-1);
}
return (retval);
}
/*
* Evaluate expression
*/
static itm_num_t
const unsigned char *inbuf,
{
unsigned char *p;
long i;
#define EVAL_EXPR_INVD(n) \
((num0 ## n) < 0) ? \
(((num0 ## n) < inbytesleft) ? \
#define EVAL_EXPR(n) \
if (0 != num) { \
} else { \
return (0); \
}
case ITM_EXPR_NONE: /* not used */
return (0);
case ITM_EXPR_NOP: /* not used */
return (0);
case ITM_EXPR_NAME: /* not used */
return (0);
case ITM_EXPR_INT: /* integer */
case ITM_EXPR_SEQ: /* byte sequence */
} else {
}
}
return (num);
case ITM_EXPR_REG: /* register */
case ITM_EXPR_IN_VECTOR: /* in[expr] */
} else if ((-1) == num) {
return (inbytesleft);
} else {
return (0);
}
case ITM_EXPR_IN_VECTOR_D: /* in[DECIMAL] */
} else if ((-1) == num) {
return (inbytesleft);
} else {
return (0);
}
case ITM_EXPR_OUT: /* out */
return (outbytesleft);
case ITM_EXPR_TRUE: /* true */
return (1);
case ITM_EXPR_FALSE: /* false */
return (0);
case ITM_EXPR_UMINUS: /* unary minus */
return ((-1) * EVAL_EXPR(0));
#define PLUS_FOR_CSTYLE_CLEAN +
#define MINUS_FOR_CSTYLE_CLEAN -
#define MUL_FOR_CSTYLE_CLEAN *
#define DIV_FOR_CSTYLE_CLEAN /
#define MOD_FOR_CSTYLE_CLEAN %
#define SHIFT_L_FOR_CSTYLE_CLEAN <<
#define SHIFT_R_FOR_CSTYLE_CLEAN >>
#define OR_FOR_CSTYLE_CLEAN |
#define XOR_FOR_CSTYLE_CLEAN ^
#define AND_FOR_CSTYLE_CLEAN &
#define EQ_FOR_CSTYLE_CLEAN ==
#define NE_FOR_CSTYLE_CLEAN !=
#define GT_FOR_CSTYLE_CLEAN >
#define GE_FOR_CSTYLE_CLEAN >=
#define LT_FOR_CSTYLE_CLEAN <
#define LE_FOR_CSTYLE_CLEAN <=
case ITM_EXPR_NOT: /* !A */
return (!(EVAL_EXPR(0)));
case ITM_EXPR_NEG: /* ~A */
return (~(EVAL_EXPR(0)));
case ITM_EXPR_LOR: /* A || B */
return (num);
return (num);
return (0);
case ITM_EXPR_LAND: /* A && B */
if (0 == EVAL_EXPR(0))
return (0);
return (0);
return (num);
case ITM_EXPR_ASSIGN: /* A = B */
= num);
} else {
return (0);
}
case ITM_EXPR_IN_EQ: /* in == A */
case ITM_EXPR_SEQ:
return (0);
}
if (*p != *(inbuf + i)) {
return (0);
}
}
return (1);
default:
}
default:
break;
}
return (0);
}
/*
* maintain ITM reference information
*/
static void
{
int r;
r = errno;
if (0 <= fd) {
}
if (0 < len) {
}
errno = r;
}
static itm_ref_t *
itm_ref_inc(const char *itm)
{
int fd;
if (fd == -1) {
return (NULL);
}
return (NULL);
}
if (MAP_FAILED == hdr) {
return (NULL);
}
return (NULL);
}
return (NULL);
}
if ((hdr->ident[0] != ITM_IDENT_0) ||
#if defined(_LITTLE_ENDIAN)
#if defined(_LP64)
#else
#endif
#else
#if defined(_LP64)
#else
#endif
#endif
return (NULL);
}
return (ref);
}
static void
{
}
static void
{
}
static void
{
}
static void
{
}
}
#if defined(DEBUG)
static void
{
char *env_val;
char *p;
return;
for (p = env_val; *p; p++) {
}
}
static void
trace_message(char *format, ...)
{
}
#endif /* DEBUG */