1
0
Files
irix-657m-src/eoe/cmd/iconv_comp/iconv_comp.c
2022-09-29 17:59:04 +03:00

3918 lines
85 KiB
C

/**************************************************************************
* *
* Copyright (C) 1995 Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
/*
* iconv_comp.c
*
* Iconv spec compiler
*
*/
#ifndef TESTDEBUG
#define TESTDEBUG 0
#endif
#define ptr_diff_t unsigned long
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <dlfcn.h>
#include <sys/mman.h>
#include <ctype.h>
#include <wchar.h>
#include "iconv.h"
#include "iconv_cnv.h"
#include "iconv_int.h"
#include "in_proc.h"
#include "iconv_comp.h"
#include "iconv_comp.c.h"
#define OBJ( XX ) ( ( ICC_OBJ_TYP * ) ( XX ) )
#define offsetof( typ, fld ) ( (long) ( ( (typ *) 0 )->fld ) )
#define offsetofb( typ, fld ) ( (long) ( &( (typ *) 0 )->fld ) )
ICC_HEAD icc_hd[ 1 ];
extern ICC_TYPEDEF icc_typetab[];
extern int icc_ntypetab;
/* =============================== ALEX_TABLE ======================== */
/* error table
*/
#define ALEX_OFFS 0x300
char * ALEX_TABLE[] = {
(char *) ALEX_OFFS,
#define ALEX_NO_ERROR ( ALEX_OFFS + 1 )
"No error",
#define ALEX_PARSER ( ALEX_OFFS + 2 )
"Parsing error -",
#define ALEX_ESCAPE ( ALEX_OFFS + 3 )
"Escape unnessasary - converted to",
#define ALEX_STROVR ( ALEX_OFFS + 4 )
"String too long. String truncated",
#define ALEX_UNKTOKEN ( ALEX_OFFS + 5 )
"Incorrect input token",
#define ALEX_OVERFLOW ( ALEX_OFFS + 6 )
"Overflow occured in conversion",
#define ALEX_PREVIOUS ( ALEX_OFFS + 7 )
"Previously defined - this one ignored",
#define ALEX_FOUND_HERE ( ALEX_OFFS + 8 )
"Previous defined here",
#define ALEX_TOODEEP ( ALEX_OFFS + 9 )
"Clone and Joins nest too deep",
#define ALEX_NONULLSPEC ( ALEX_OFFS + 10 )
"Null encoding specifiers are not allowed",
#define ALEX_LEXERROR ( ALEX_OFFS + 11 )
"Invalid input token",
#define ALEX_TYPEWRONG ( ALEX_OFFS + 12 )
"Invalid type specifier",
#define ALEX_CNV_ERROR ( ALEX_OFFS + 13 )
"Error in converting to integer",
#define ALEX_EXPECT_STRING ( ALEX_OFFS + 14 )
"Type specified non string type but recieved string",
#define ALEX_EXPECT_INTEGER ( ALEX_OFFS + 15 )
"Type specified non integer type but recieved integer",
#define ALEX_ALREADY_DEFINED ( ALEX_OFFS + 16 )
"resource already defined:",
#define ALEX_ALREADY_HERE ( ALEX_OFFS + 17 )
"resource previously defined here:",
#define ALEX_NOT_DEFINED ( ALEX_OFFS + 18 )
"resource referenced but not defined",
};
/* ----------------------- ALEX_CON_OCTAL ----------------------- */
/* convert a octal string to a long value
*
*/
int alex_con_octal(
char * s, /* the string */
register int l, /* the length */
long * val /* the address to put the value */
) {
register int i;
int z = 1;
unsigned long y = 0;
while ( l -- ) { /* for every character */
i = toascii( * (s++) );
if ( i == 'L' || i == 'l' ) {
if ( l ) {
goto baderr;
}
} else {
/* are we going to overflow ? */
if ( y & ( 0xe0000000 ) && z ) {
z = 0;
inx_error(
inx_last,
ALEX_TABLE,
ALEX_OVERFLOW,
INX_LINE | INX_WARN
);
}
}
if ( isdigit( i ) ) { /* normal 0-9 */
y <<= 3; /* Multiply by 8 */
if ( i > '7' ) { /* is it an octal digit */
/* no octal digit */
inx_error(
inx_last,
ALEX_TABLE,
ALEX_UNKTOKEN,
INX_LINE | INX_ERROR | INX_EXTRA,
"octal value"
);
* val = 0;
return 0;
}
y += ( i - '0' );
} else if ( !l && ( i == 'L' || i == 'l' ) ) {
/* must me last charcter defining a long */
} else {
baderr:
inx_error(
inx_last,
ALEX_TABLE,
ALEX_UNKTOKEN,
INX_LINE | INX_ERROR | INX_EXTRA,
"decimal value"
);
* val = 0;
return 0;
}
} /* while ( l -- ) */
/* deposit the value and return true for success */
* val = y;
return 1;
}
/* ============================= alex_string ============================ */
/* find what the valuw of the escape character is
*/
unsigned char alex_escapeof( text )
char ** text;
{
char * s; /* the string */
long i = 0; /* the value */
int len; /* length of str */
char str[ 4 ]; /* for error messages */
/* an escape char was preceeding this one */
if ( isdigit( ** text ) ) {
len = 1;
s = (* text) + 1;
while ( isdigit( * s ) ) {
/* must be an octal sequence */
s ++;
len ++;
if ( len >= 3 ) {
break;
}
}
alex_con_octal( * text, len, &i );
* text = s - 1;
} else switch ( ** text ) {
case 'n' : { /* newline escape */
i = '\n';
break;
}
case 't' : { /* tab */
i = '\t';
break;
}
case 'r' : { /* carrige return */
i = '\r';
break;
}
case 'b' : { /* back space */
i = '\b';
break;
}
case 'f' : { /* form feed */
i = '\f';
break;
}
case '\\' : { /* the real escape '\' */
i = '\\';
break;
}
case '\'' : { /* the single quote */
i = '\'';
break;
}
case '"' : { /* the single quote */
i = '"';
break;
}
case '>' : { /* the single quote */
i = '>';
break;
}
case '^' : { /* the single quote */
i = '^';
break;
}
case '~' : { /* the single quote */
i = '~';
break;
}
case '-' : { /* the single quote */
i = '-';
break;
}
default : {
/* escape character is not valid - however change it to
* a normal charater and insert it - inform the user */
str[ 2 ] = str[ 0 ] = '\'';
i = str[ 1 ] = **text;
str[ 3 ] = 0;
inx_error(
inx_last, /* the last position */
ALEX_TABLE,
ALEX_ESCAPE,
INX_LINE | INX_INFORM | INX_EXTRA,
str /* show what has happened */
);
break;
}
} /* switch */
return i;
}
/* ============================= alex_string ============================ */
/* have something of the form ( "..." )
*/
void icc_fixstr( void )
{
#define MAXSTR 1024
char stacktext[ MAXSTR ];
int length;
char * text;
char * ptext;
text = stacktext;
ptext = yytext + 1;
length = 0;
/* go through the chars */
while ( * ptext != '"' ) {
/* check string length */
if ( length >= MAXSTR ) {
inx_error(
inx_last,
ALEX_TABLE,
ALEX_STROVR,
INX_LINE | INX_ERROR
);
break;
}
if ( * ptext == '\\' ) {
ptext ++;
if ( *ptext == '\n' ) {
ptext ++;
continue;
}
* text = alex_escapeof( &ptext );
} else {
* text = * ptext;
}
text ++;
ptext ++;
length ++;
}
/* allocate memory for it */
ptext = inx_alloc( length + 1 );
memcpy( ptext, stacktext, length );
ptext[ length ] = 0;
yylval = ( void * ) ptext;
yyleng = 0;
return ;
}
/* ======== icc_fixident ============================================== */
/* PURPOSE:
* Fix identifie
*
* RETURNS:
*
*/
void icc_fixident()
{
char * ptext;
int length = yyleng;
ptext = inx_alloc( length + 1 );
memcpy( ptext, yytext, length + 1 );
yylval = ( void * ) ptext;
yyleng = 0;
return;
} /* end icc_fixident */
/* ======== lexerror ================================================== */
/* PURPOSE:
*
*
* RETURNS:
*
*/
void lexerror()
{
inx_error(
inx_last,
ALEX_TABLE,
ALEX_LEXERROR,
INX_LINE | INX_ERROR
);
} /* end lexerror */
/* ============================= YYERROR =============================== */
/* Yacc goes here when a syntax error occurs - or a stack overflow
*
*/
void yyerror(
const char * s
) {
inx_error(
inx_last,
ALEX_TABLE,
ALEX_PARSER,
INX_LINE | INX_EXTRA | INX_ERROR,
s
);
}
int yywrap()
{
return 1;
}
/* ==================================================================== */
/* ==================================================================== */
/* Function for manipulating lists */
/* ======== icc_compar_string ========================================= */
/* PURPOSE:
* Compare strings.
*
* RETURNS:
*
*/
int icc_compar_string(
ICC_OBJ_TYP * p_o_a,
ICC_OBJ_TYP * p_o_b
) {
/* make sure the string actually exists before calling strcmp */
if ( ! p_o_a->icc_data1 ) {
if ( p_o_b->icc_data1 ) {
return 1;
} else {
return 0;
}
} else if ( ! p_o_b->icc_data1 ) {
return -1;
}
return strcmp( p_o_a->icc_data1, p_o_b->icc_data1 );
} /* end icc_compar_string */
/* ======== icc_compar_meth =========================================== */
/* PURPOSE:
* Method comparator
*
* RETURNS:
*
*/
#define CMPIT( TYP, XX ) \
val = ( \
((ptr_diff_t) (( TYP * )(p_o_a))->XX) - \
((ptr_diff_t) (( TYP * )(p_o_b))->XX) \
); \
if ( val ) { \
return val > 0 ? 1 : -1; \
} \
/* Macro end */
int icc_compar_meth(
ICC_OBJ_TYP * p_o_a,
ICC_OBJ_TYP * p_o_b
) {
ptr_diff_t val;
CMPIT( ICC_METHODS, icc_aobj )
CMPIT( ICC_METHODS, icc_cnv )
CMPIT( ICC_METHODS, icc_cobj )
CMPIT( ICC_METHODS, icc_ctl )
return 0;
} /* end icc_compar_meth */
/* ======== icc_compar_clone ========================================== */
/* PURPOSE:
* Compare for clone object
*
* RETURNS:
*
*/
int icc_compar_clone(
ICC_OBJ_TYP * p_o_a,
ICC_OBJ_TYP * p_o_b
) {
ptr_diff_t val;
CMPIT( ICC_CLONEOBJ, icc_src_dst )
CMPIT( ICC_CLONEOBJ, icc_enc )
CMPIT( ICC_CLONEOBJ, icc_mth )
CMPIT( ICC_CLONEOBJ, icc_newenc )
return 0;
} /* end icc_compar_clone */
/* ======== icc_compar_join =========================================== */
/* PURPOSE:
* Compare join records
*
* RETURNS:
*
*/
int icc_compar_join(
ICC_OBJ_TYP * p_o_a,
ICC_OBJ_TYP * p_o_b
) {
ptr_diff_t val;
CMPIT( ICC_JOINOBJ, icc_dst_enc )
CMPIT( ICC_JOINOBJ, icc_src_enc )
CMPIT( ICC_JOINOBJ, icc_mth_dst )
CMPIT( ICC_JOINOBJ, icc_mth_src )
return 0;
} /* end icc_compar_join */
/* ======== icc_compar_libspec ======================================== */
/* PURPOSE:
*
*
* RETURNS:
*
*/
int icc_compar_libspec(
ICC_OBJ_TYP * p_o_a,
ICC_OBJ_TYP * p_o_b
) {
ptr_diff_t val;
CMPIT( ICC_STDLIBSPEC, icc_from_enc )
CMPIT( ICC_STDLIBSPEC, icc_to_enc )
return 0;
} /* end icc_compar_libspec */
/* ======== icc_compar_libmeth ======================================== */
/* PURPOSE:
*
*
* RETURNS:
*
*/
int icc_compar_libmeth(
ICC_OBJ_TYP * p_o_a,
ICC_OBJ_TYP * p_o_b
) {
ptr_diff_t val;
int i;
CMPIT( ICC_STDLIBMETH, icc_mbwc_obj )
CMPIT( ICC_STDLIBMETH, icc_mbwc_sym )
CMPIT( ICC_STDLIBMETH, icc_ntable_mbwc )
CMPIT( ICC_STDLIBMETH, icc_ntable_wcmb )
i = (( ICC_STDLIBMETH * )(p_o_a))->icc_ntable_mbwc
+ (( ICC_STDLIBMETH * )(p_o_a))->icc_ntable_wcmb;
if ( i ) {
return memcmp(
(( ICC_STDLIBMETH * )(p_o_a))->icc_table,
(( ICC_STDLIBMETH * )(p_o_b))->icc_table,
sizeof( (( ICC_STDLIBMETH * )(p_o_a))->icc_table[ 0 ] ) * i
);
}
return 0;
} /* end icc_compar_libmeth */
/* ======== icc_compar_spec =========================================== */
/* PURPOSE:
* Compare spec records
*
* RETURNS:
*
*/
int icc_compar_spec(
ICC_OBJ_TYP * p_o_a,
ICC_OBJ_TYP * p_o_b
) {
ptr_diff_t val;
CMPIT( ICC_SPEC, icc_from_enc )
CMPIT( ICC_SPEC, icc_to_enc )
return 0;
} /* end icc_compar_spec */
/* ======== icc_compargeneric ========================================= */
/* PURPOSE:
* Generic comparison function
*
* RETURNS:
*
*/
int icc_compargeneric(
ICC_OBJ_TYP * p_o_a,
ICC_OBJ_TYP * p_o_b
) {
ptr_diff_t val;
CMPIT( ICC_OBJ_TYP, icc_data1 )
CMPIT( ICC_OBJ_TYP, icc_data2 )
return 0;
} /* end icc_compargeneric */
/* ======== icc_compar_1_generic ========================================= */
/* PURPOSE:
* Generic comparison function
*
* RETURNS:
*
*/
int icc_compar_1_generic(
ICC_OBJ_TYP * p_o_a,
ICC_OBJ_TYP * p_o_b
) {
ptr_diff_t val;
CMPIT( ICC_OBJ_TYP, icc_data1 )
return 0;
} /* end icc_compar_1_generic */
/* ======== icc_findelem ============================================== */
/* PURPOSE:
* Find an element in the list
*
* RETURNS:
*
*/
void * icc_findelem(
ICC_OBJ_HEAD * p_oh,
ICC_OBJ_TYP * p_o
) {
ICC_CMPFUNC p_func = p_oh->icc_cmpfunc;
ICC_OBJ_TYP * p_obj;
p_obj = p_oh->icc_head;
while ( p_obj ) {
if ( ! ( p_func )( p_o, p_obj ) ) {
return ( void * ) p_obj;
}
p_obj = p_obj->icc_next;
}
return 0;
} /* end icc_findelem */
/* ======== icc_insert ================================================ */
/* PURPOSE:
* Insert an element
*
*/
void icc_insert(
ICC_OBJ_HEAD * p_oh,
ICC_OBJ_TYP * p_o
) {
p_o->icc_num = p_oh->icc_count ++;
p_o->icc_objhead = p_oh;
p_o->icc_used = 0;
p_o->icc_used1 = 0;
p_o->icc_posi[ 0 ] = inx_last[ 0 ];
p_o->icc_next = p_oh->icc_head;
p_oh->icc_head = p_o;
return;
} /* end icc_insert */
/* ======== icc_findgeneric =========================================== */
/* PURPOSE:
* A generic find
*
* RETURNS:
*
*/
ICC_OBJ_TYP * icc_findgeneric(
ICC_OBJ_HEAD * p_oh,
void * data1,
void * data2
) {
ICC_OBJ_TYP a_obj[ 1 ];
a_obj->icc_data1 = data1;
a_obj->icc_data2 = data2;
return icc_findelem( p_oh, a_obj );
} /* end icc_findgeneric */
/* ======== icc_insertgeneric ========================================= */
/* PURPOSE:
* Insert a generic node
*
* RETURNS:
*
*/
ICC_OBJ_TYP * icc_insertgeneric(
ICC_OBJ_HEAD * p_oh,
void * data1,
void * data2
) {
ICC_OBJ_TYP * p_obj;
p_obj = ( ICC_OBJ_TYP * ) inx_alloc( sizeof( ICC_OBJ_TYP ) );
memset( p_obj, 0, sizeof( * p_obj ) );
p_obj->icc_data1 = data1;
p_obj->icc_data2 = data2;
icc_insert( p_oh, p_obj );
return p_obj;
} /* end icc_insertgeneric */
/* ======== icc_insertalloc =========================================== */
/* PURPOSE:
* Allocate a new obj and insert it !
*
* RETURNS:
*
*/
ICC_OBJ_TYP * icc_insertalloc(
ICC_OBJ_HEAD * p_oh,
ICC_OBJ_TYP * p_sobj
) {
ICC_OBJ_TYP * p_obj;
p_obj = ( ICC_OBJ_TYP * ) inx_alloc( p_oh->icc_size );
memcpy( p_obj, p_sobj, p_oh->icc_size );
icc_insert( p_oh, p_obj );
return p_obj;
} /* end icc_insertalloc */
#if TESTDEBUG
#define PSPEC( msg, spec ) fprintf( stderr, "***%s***\n", msg ); printspec( spec );
#define PLSPEC( msg, spec ) fprintf( stderr, "***%s***\n", msg ); printlspec( spec );
/* ======== icc_stringof ============================================== */
/* PURPOSE:
* Get pointer to string
*
* RETURNS:
*
*/
void * icc_stringof(
ICC_OBJ_TYP * p_obj
) {
if ( ! p_obj ) {
return "(null)";
}
return p_obj->icc_data1;
} /* end icc_stringof */
/* ======== icc_stringof1 ============================================= */
/* PURPOSE:
*
*
* RETURNS:
*
*/
void * icc_stringof1(
ICC_OBJ_TYP * p_obj
) {
if ( ! p_obj ) {
return "{null}";
}
return icc_stringof( p_obj->icc_data1 );
} /* end icc_stringof1 */
/* ======== printtable ================================================ */
/* PURPOSE:
*
*
* RETURNS:
*
*/
void printtable(
ICC_SPECTAB * p_tab
) {
if ( p_tab->icc_isfile ) {
fprintf( stderr, " FILE %s\n", icc_stringof1( p_tab->icc_tobj ) );
} else {
fprintf( stderr, " OBJECT %s ", icc_stringof1( p_tab->icc_tobj ) );
fprintf( stderr, "SYMBOL %s\n", icc_stringof1( p_tab->icc_tbl ) );
}
return;
} /* end printtable */
/* ======== printlspec ================================================ */
/* PURPOSE:
*
*
* RETURNS:
*
*/
void printlspec(
ICC_STDLIBSPEC * p_ls
) {
int j;
fprintf( stderr, "Lspec %d\n", p_ls->icc_obj->icc_num );
fprintf( stderr, " from_enc '%s'\n", icc_stringof( p_ls->icc_from_enc ) );
fprintf( stderr, " to_enc '%s'\n", icc_stringof( p_ls->icc_to_enc ) );
fprintf( stderr, " MethNum %d\n", p_ls->icc_meths->icc_obj->icc_num );
fprintf( stderr, " mbwc_dso '%s'\n", icc_stringof1( p_ls->icc_meths->icc_mbwc_obj ) );
fprintf( stderr, " mbwc_sym '%s'\n", icc_stringof1( p_ls->icc_meths->icc_mbwc_sym ) );
fprintf( stderr, " Ntable %d\n", p_ls->icc_meths->icc_ntable_mbwc );
/* dump all tables */
for ( j = 0; j < p_ls->icc_meths->icc_ntable_mbwc; j ++ ) {
printtable( p_ls->icc_meths->icc_table + j );
}
fprintf( stderr, " Ntable %d\n", p_ls->icc_meths->icc_ntable_wcmb );
/* dump all tables */
for ( j = p_ls->icc_meths->icc_ntable_mbwc; j < p_ls->icc_meths->icc_ntable_mbwc + p_ls->icc_meths->icc_ntable_wcmb; j ++ ) {
printtable( p_ls->icc_meths->icc_table + j );
}
fprintf( stderr, "\n" );
return;
} /* end printlspec */
/* ======== printmeth ================================================= */
/* PURPOSE:
* Print a method !
*
* RETURNS:
*
*/
void printmeth(
ICC_METHODS * p_mth
) {
fprintf( stderr, "Meth %d\n", p_mth->icc_obj->icc_num );
fprintf( stderr, " aobj '%s'\n", icc_stringof1( p_mth->icc_aobj ) );
fprintf( stderr, " cnv '%s'\n", icc_stringof1( p_mth->icc_cnv ) );
fprintf( stderr, " cobj '%s'\n", icc_stringof1( p_mth->icc_cobj ) );
fprintf( stderr, " ctl '%s'\n", icc_stringof1( p_mth->icc_ctl ) );
return;
} /* end printmeth */
/* ======== printspec ================================================= */
/* PURPOSE:
* Print content of a spec
*
* RETURNS:
*
*/
void printspec( ICC_SPEC * p_sp )
{
int j;
fprintf( stderr, "Spec %d\n", p_sp->icc_obj->icc_num );
fprintf( stderr, " from_enc '%s'\n", icc_stringof( p_sp->icc_from_enc ) );
fprintf( stderr, " to_enc '%s'\n", icc_stringof( p_sp->icc_to_enc ) );
printmeth( p_sp->icc_mth );
fprintf( stderr, " Ntable %d\n", p_sp->icc_ntable );
/* dump all tables */
for ( j = 0; j < p_sp->icc_ntable; j ++ ) {
printtable( p_sp->icc_table + j );
}
fprintf( stderr, "\n" );
return;
} /* end printspec */
#else
#define PSPEC( msg, spec )
#define PLSPEC( msg, spec )
#endif
/* ======== icc_init ================================================== */
/* PURPOSE:
* Initialize
*
* RETURNS:
*
*/
void icc_init()
{
ICC_HEAD * p_hd = icc_hd;
p_hd->icc_strings->icc_cmpfunc = ( ICC_CMPFUNC ) icc_compar_string;
p_hd->icc_strings->icc_size = sizeof( ICC_OBJ_TYP );
p_hd->icc_objects->icc_cmpfunc = ( ICC_CMPFUNC ) icc_compargeneric;
p_hd->icc_objects->icc_size = sizeof( ICC_OBJ_TYP );
p_hd->icc_symbols->icc_cmpfunc = ( ICC_CMPFUNC ) icc_compargeneric;
p_hd->icc_symbols->icc_size = sizeof( ICC_OBJ_TYP );
p_hd->icc_files->icc_cmpfunc = ( ICC_CMPFUNC ) icc_compargeneric;
p_hd->icc_files->icc_size = sizeof( ICC_OBJ_TYP );
p_hd->icc_specs->icc_cmpfunc = ( ICC_CMPFUNC ) icc_compar_spec;
p_hd->icc_specs->icc_size = sizeof( ICC_SPEC );
p_hd->icc_methods->icc_cmpfunc = ( ICC_CMPFUNC ) icc_compar_meth;
p_hd->icc_methods->icc_size = sizeof( ICC_METHODS );
p_hd->icc_clones->icc_cmpfunc = ( ICC_CMPFUNC ) icc_compar_clone;
p_hd->icc_clones->icc_size = sizeof( ICC_CLONEOBJ );
p_hd->icc_joins->icc_cmpfunc = ( ICC_CMPFUNC ) icc_compar_join;
p_hd->icc_joins->icc_size = sizeof( ICC_JOINOBJ );
p_hd->icc_libspecs->icc_cmpfunc = ( ICC_CMPFUNC ) icc_compar_libspec;
p_hd->icc_libspecs->icc_size = sizeof( ICC_STDLIBSPEC );
p_hd->icc_libmeths->icc_cmpfunc = ( ICC_CMPFUNC ) icc_compar_libmeth;
p_hd->icc_libmeths->icc_size = sizeof( ICC_STDLIBMETH );
p_hd->icc_loc_alias->icc_cmpfunc = ( ICC_CMPFUNC ) icc_compar_1_generic;
p_hd->icc_loc_alias->icc_size = sizeof( ICC_OBJ_TYP );
p_hd->icc_loc_codeset->icc_cmpfunc = ( ICC_CMPFUNC ) icc_compar_1_generic;
p_hd->icc_loc_codeset->icc_size = sizeof( ICC_OBJ_TYP );
p_hd->icc_resources->icc_cmpfunc = ( ICC_CMPFUNC ) icc_compar_1_generic;
p_hd->icc_resources->icc_size = sizeof( ICC_OBJ_TYP );
return;
} /* end icc_init */
/* ======== icc_getstr ================================================ */
/* PURPOSE:
* Get the string corresponding to the string given
*
* RETURNS:
*
*/
ICC_OBJ_TYP * icc_getstr(
char * str
) {
ICC_HEAD * p_hd = icc_hd;
ICC_OBJ_TYP * p_obj;
p_obj = icc_findgeneric( p_hd->icc_strings, str, 0 );
if ( ! p_obj ) {
p_obj = icc_insertgeneric( p_hd->icc_strings, str, 0 );
} else {
inx_free( str );
}
return p_obj;
} /* end icc_getstr */
/* ======== icc_getspec =============================================== */
/* PURPOSE:
*
*
* RETURNS:
*
*/
ICC_SPEC * icc_getspec(
ICC_HEAD * p_hd,
ICC_OBJ_TYP * p_o_a,
ICC_OBJ_TYP * p_o_b
) {
ICC_SPEC a_spec[ 1 ];
ICC_OBJ_TYP * p_obj;
a_spec->icc_from_enc = p_o_a;
a_spec->icc_to_enc = p_o_b;
p_obj = icc_findelem( p_hd->icc_specs, OBJ( a_spec ) );
return ( ICC_SPEC * ) p_obj;
} /* end icc_getspec */
/* ======== icc_getmkgeneric ================================================= */
/* PURPOSE:
* Get or make a generic object
*
* RETURNS:
*
*/
ICC_OBJ_TYP * icc_getmkgeneric(
ICC_OBJ_HEAD * p_oh,
void * data1,
void * data2
) {
ICC_OBJ_TYP * p_obj;
p_obj = icc_findgeneric( p_oh, data1, data2 );
if ( ! p_obj ) {
/* ### if ( ! data2 ) printf( "making DSO %s\n", (( ICC_OBJ_TYP * ) data1 )->icc_data1 ); */
p_obj = icc_insertgeneric( p_oh, data1, data2 );
}
return p_obj;
} /* end icc_getmkgeneric */
/* ======== icc_getmk ================================================= */
/* PURPOSE:
* getmk !
*
* RETURNS:
*
*/
void * icc_getmk(
ICC_OBJ_HEAD * p_oh,
ICC_OBJ_TYP * p_sobj
) {
ICC_OBJ_TYP * p_obj;
p_obj = icc_findelem( p_oh, p_sobj );
if ( ! p_obj ) {
p_obj = icc_insertalloc( p_oh, p_sobj );
}
return ( void * ) p_obj;
} /* end icc_getmk */
/* ======== icc_newspec =============================================== */
/* PURPOSE:
*
*
* RETURNS:
*
*/
ICC_SPEC * icc_newspec(
ICC_HEAD * p_hd,
ICC_OBJ_TYP * p_o_a,
ICC_OBJ_TYP * p_o_b
) {
ICC_SPEC a_spec[ 1 ];
ICC_OBJ_TYP * p_obj;
memset( a_spec, 0, sizeof( a_spec ) );
a_spec->icc_from_enc = p_o_a;
a_spec->icc_to_enc = p_o_b;
p_obj = icc_insertalloc( p_hd->icc_specs, a_spec->icc_obj );
return ( ICC_SPEC * ) p_obj;
} /* end icc_newspec */
/* ======== mkentry =================================================== */
/* PURPOSE:
* This is called when an entry is found in the source files.
*
* RETURNS:
*
*/
void mkentry(
char * from_enc,
char * to_enc,
char * alg_dso,
char * alg_sym,
char * ctl_dso,
char * ctl_sym,
ICC_TBLST * tablelist
) {
ICC_OBJ_TYP * from_enc_str = icc_getstr( from_enc );
ICC_OBJ_TYP * to_enc_str = icc_getstr( to_enc );
ICC_OBJ_TYP * alg_dso_str = icc_getstr( alg_dso );
ICC_OBJ_TYP * alg_sym_str = icc_getstr( alg_sym );
ICC_OBJ_TYP * ctl_dso_str = icc_getstr( ctl_dso );
ICC_OBJ_TYP * ctl_sym_str = icc_getstr( ctl_sym );
ICC_OBJ_TYP ** tbl_lst_str = (ICC_OBJ_TYP **)NULL;
ICC_HEAD * p_hd = icc_hd;
ICC_METHODS a_mth[ 1 ];
ICC_SPEC * spec;
ICC_TBLST * p, * pp;
int num_tblst=0, i;
#ifdef TESTDEBUG3
ICC_TBLST *q;
int count=0;
printf( "mkentry() [ Head of tablelist ]\n" );
for ( count=0, q=tablelist; q; q=q->next, count++ ) {
printf( "- One table -\n" );
printf( " SYM: %s\n", OBJ(q->odata->icc_data1)->icc_data1 );
if ( q->odata->icc_data2 )
printf( " DSO: %s\n", OBJ(q->odata->icc_data2)->icc_data1 );
}
printf( "- table count: %d\n", count );
fflush( stdout );
#endif
if ( ! from_enc || ! to_enc ) {
inx_error(
inx_last, /* the last position */
ALEX_TABLE,
ALEX_NONULLSPEC,
INX_LINE | INX_ERROR
);
}
memset( a_mth, 0, sizeof( a_mth ) );
spec = icc_getspec( p_hd, from_enc_str, to_enc_str );
if ( spec ) {
/* spec is previously defined */
inx_error(
inx_last, /* the last position */
ALEX_TABLE,
ALEX_PREVIOUS,
INX_LINE | INX_WARN
);
inx_error(
spec->icc_posi,
ALEX_TABLE,
ALEX_FOUND_HERE,
INX_LINE | INX_WARN
);
return;
}
/* Multiple spec: tablelist for tbl_dso and tbl_sym. (num_tblst-1 is fine.) */
for ( num_tblst=0, p=tablelist; p != NULL; p=p->next, num_tblst++ );
p_hd->icc_specs->icc_size = sizeof(ICC_SPEC)+sizeof(ICC_SPECTAB)*num_tblst;
spec = icc_newspec( p_hd, from_enc_str, to_enc_str );
/* spec->icc_from_enc = from_enc_str; */
/* spec->icc_to_enc = to_enc_str; */
* spec->icc_posi = * inx_last;
a_mth->icc_aobj = icc_getmkgeneric( p_hd->icc_objects, alg_dso_str, 0 );
a_mth->icc_cnv = icc_getmkgeneric( p_hd->icc_symbols, alg_sym_str, alg_dso_str );
a_mth->icc_cobj = icc_getmkgeneric( p_hd->icc_objects, ctl_dso_str, 0 );
a_mth->icc_ctl = icc_getmkgeneric( p_hd->icc_symbols, ctl_sym_str, ctl_dso_str );
spec->icc_mth = icc_getmk( p_hd->icc_methods, a_mth->icc_obj );
/* icc_ntable must be specified correctly for potential joins */
spec->icc_ntable = num_tblst;
/* We don't have to check validity of each data in the tablelist,
because it's been checked in mktable() and invalid data hasn't
been added to this list in mktablelist().
*/
if ( 0 < num_tblst ) {
tbl_lst_str = (ICC_OBJ_TYP **)inx_alloc( sizeof(ICC_OBJ_TYP *)*num_tblst );
memset( tbl_lst_str, 0, sizeof(ICC_OBJ_TYP *)*num_tblst );
for ( i=num_tblst-1, p=tablelist; -1<i; p=p->next, i-- )
*(tbl_lst_str+i) = p->odata;
}
for ( i=0; i<num_tblst; i++ ) {
if ( ! tbl_lst_str[i]->icc_data2 ) { /* FILE: (ICC_OBJ_TYP *)0 */
spec->icc_table[i].icc_isfile = 1;
spec->icc_table[i].icc_tobj = tbl_lst_str[i];
spec->icc_table[i].icc_tbl = 0;
}
else{
spec->icc_table[i].icc_isfile = 0;
spec->icc_table[i].icc_tobj = icc_getmkgeneric( p_hd->icc_objects,
tbl_lst_str[i]->icc_data2,
0 );
spec->icc_table[i].icc_tbl = tbl_lst_str[i];
}
}
PSPEC( "new entry", spec )
inx_free( tbl_lst_str );
for ( p=tablelist; p != NULL; p=pp ) {
pp = p->next;
inx_free( (void *)p );
}
return;
} /* end mkentry */
/* ======== mkclone =================================================== */
/* PURPOSE:
* Clone record for cloning spec's. This just records them,
* they will used when all input has been compiled.
*
* RETURNS:
*
*/
void mkclone(
int to_from,
char * enc,
char * alg_dso,
char * alg_sym,
char * ctl_dso,
char * ctl_sym,
char * enc_new,
char * alg_dso_new,
char * alg_sym_new,
char * ctl_dso_new,
char * ctl_sym_new
) {
ICC_OBJ_TYP * enc_str = icc_getstr( enc );
ICC_OBJ_TYP * alg_dso_str = icc_getstr( alg_dso );
ICC_OBJ_TYP * alg_sym_str = icc_getstr( alg_sym );
ICC_OBJ_TYP * ctl_dso_str = icc_getstr( ctl_dso );
ICC_OBJ_TYP * ctl_sym_str = icc_getstr( ctl_sym );
ICC_OBJ_TYP * enc_new_str = icc_getstr( enc_new );
ICC_OBJ_TYP * alg_dso_new_str = icc_getstr( alg_dso_new );
ICC_OBJ_TYP * alg_sym_new_str = icc_getstr( alg_sym_new );
ICC_OBJ_TYP * ctl_dso_new_str = icc_getstr( ctl_dso_new );
ICC_OBJ_TYP * ctl_sym_new_str = icc_getstr( ctl_sym_new );
ICC_HEAD * p_hd = icc_hd;
ICC_METHODS a_mth[ 1 ];
ICC_CLONEOBJ clone[ 1 ];
ICC_CLONEOBJ * p_clone;
if ( ! enc ) {
inx_error(
inx_last, /* the last position */
ALEX_TABLE,
ALEX_NONULLSPEC,
INX_LINE | INX_ERROR
);
}
memset( a_mth, 0, sizeof( a_mth ) );
memset( clone, 0, sizeof( clone ) );
* clone->icc_posi = * inx_last;
clone->icc_src_dst = to_from;
clone->icc_enc = enc_str;
a_mth->icc_aobj = icc_getmkgeneric( p_hd->icc_objects, alg_dso_str, 0 );
a_mth->icc_cnv = icc_getmkgeneric( p_hd->icc_symbols, alg_sym_str, alg_dso_str );
a_mth->icc_cobj = icc_getmkgeneric( p_hd->icc_objects, ctl_dso_str, 0 );
a_mth->icc_ctl = icc_getmkgeneric( p_hd->icc_symbols, ctl_sym_str, ctl_dso_str );
clone->icc_mth = icc_getmk( p_hd->icc_methods, a_mth->icc_obj );
a_mth->icc_aobj = icc_getmkgeneric( p_hd->icc_objects, alg_dso_new_str, 0 );
a_mth->icc_cnv = icc_getmkgeneric( p_hd->icc_symbols, alg_sym_new_str, alg_dso_new_str );
a_mth->icc_cobj = icc_getmkgeneric( p_hd->icc_objects, ctl_dso_new_str, 0 );
a_mth->icc_ctl = icc_getmkgeneric( p_hd->icc_symbols, ctl_sym_new_str, ctl_dso_new_str );
clone->icc_newenc = enc_new_str;
clone->icc_newmth = icc_getmk( p_hd->icc_methods, a_mth->icc_obj );
p_clone = icc_findelem( p_hd->icc_clones, clone->icc_obj );
if ( p_clone ) {
if ( p_clone->icc_newmth != clone->icc_newmth ) {
/* spec is previously defined */
inx_error(
inx_last, /* the last position */
ALEX_TABLE,
ALEX_PREVIOUS,
INX_LINE | INX_WARN
);
inx_error(
p_clone->icc_posi,
ALEX_TABLE,
ALEX_FOUND_HERE,
INX_LINE | INX_WARN
);
}
return;
}
icc_insertalloc( p_hd->icc_clones, clone->icc_obj );
return;
} /* end mkclone */
/* ======== mkjoin ==================================================== */
/* PURPOSE:
* This makes a join record. The join is performed after reading
* all input.
*
* RETURNS:
*
*/
void mkjoin(
char * enc,
char * alg_dso,
char * alg_sym,
char * ctl_dso,
char * ctl_sym,
char * enc_2,
char * alg_dso_2,
char * alg_sym_2,
char * ctl_dso_2,
char * ctl_sym_2,
char * alg_dso_new,
char * alg_sym_new,
char * ctl_dso_new,
char * ctl_sym_new
) {
ICC_OBJ_TYP * enc_str = icc_getstr( enc );
ICC_OBJ_TYP * alg_dso_str = icc_getstr( alg_dso );
ICC_OBJ_TYP * alg_sym_str = icc_getstr( alg_sym );
ICC_OBJ_TYP * ctl_dso_str = icc_getstr( ctl_dso );
ICC_OBJ_TYP * ctl_sym_str = icc_getstr( ctl_sym );
ICC_OBJ_TYP * enc_2_str = icc_getstr( enc_2 );
ICC_OBJ_TYP * alg_dso_2_str = icc_getstr( alg_dso_2 );
ICC_OBJ_TYP * alg_sym_2_str = icc_getstr( alg_sym_2 );
ICC_OBJ_TYP * ctl_dso_2_str = icc_getstr( ctl_dso_2 );
ICC_OBJ_TYP * ctl_sym_2_str = icc_getstr( ctl_sym_2 );
ICC_OBJ_TYP * alg_dso_new_str = icc_getstr( alg_dso_new );
ICC_OBJ_TYP * alg_sym_new_str = icc_getstr( alg_sym_new );
ICC_OBJ_TYP * ctl_dso_new_str = icc_getstr( ctl_dso_new );
ICC_OBJ_TYP * ctl_sym_new_str = icc_getstr( ctl_sym_new );
ICC_HEAD * p_hd = icc_hd;
ICC_METHODS a_mth[ 1 ];
ICC_JOINOBJ join[ 1 ];
ICC_JOINOBJ * p_join;
if ( ! enc || ! enc_2 ) {
inx_error(
inx_last, /* the last position */
ALEX_TABLE,
ALEX_NONULLSPEC,
INX_LINE | INX_ERROR
);
}
memset( a_mth, 0, sizeof( a_mth ) );
memset( join, 0, sizeof( join ) );
* join->icc_posi = * inx_last;
join->icc_dst_enc = enc_str;
join->icc_src_enc = enc_2_str;
a_mth->icc_aobj = icc_getmkgeneric( p_hd->icc_objects, alg_dso_str, 0 );
a_mth->icc_cnv = icc_getmkgeneric( p_hd->icc_symbols, alg_sym_str, alg_dso_str );
a_mth->icc_cobj = icc_getmkgeneric( p_hd->icc_objects, ctl_dso_str, 0 );
a_mth->icc_ctl = icc_getmkgeneric( p_hd->icc_symbols, ctl_sym_str, ctl_dso_str );
join->icc_mth_dst = icc_getmk( p_hd->icc_methods, a_mth->icc_obj );
a_mth->icc_aobj = icc_getmkgeneric( p_hd->icc_objects, alg_dso_2_str, 0 );
a_mth->icc_cnv = icc_getmkgeneric( p_hd->icc_symbols, alg_sym_2_str, alg_dso_2_str );
a_mth->icc_cobj = icc_getmkgeneric( p_hd->icc_objects, ctl_dso_2_str, 0 );
a_mth->icc_ctl = icc_getmkgeneric( p_hd->icc_symbols, ctl_sym_2_str, ctl_dso_2_str );
join->icc_mth_src = icc_getmk( p_hd->icc_methods, a_mth->icc_obj );
a_mth->icc_aobj = icc_getmkgeneric( p_hd->icc_objects, alg_dso_new_str, 0 );
a_mth->icc_cnv = icc_getmkgeneric( p_hd->icc_symbols, alg_sym_new_str, alg_dso_new_str );
a_mth->icc_cobj = icc_getmkgeneric( p_hd->icc_objects, ctl_dso_new_str, 0 );
a_mth->icc_ctl = icc_getmkgeneric( p_hd->icc_symbols, ctl_sym_new_str, ctl_dso_new_str );
join->icc_newmth = icc_getmk( p_hd->icc_methods, a_mth->icc_obj );
p_join = icc_findelem( p_hd->icc_joins, join->icc_obj );
if ( p_join ) {
if ( p_join->icc_newmth != join->icc_newmth ) {
/* spec is previously defined */
inx_error(
inx_last, /* the last position */
ALEX_TABLE,
ALEX_PREVIOUS,
INX_LINE | INX_WARN
);
inx_error(
p_join->icc_posi,
ALEX_TABLE,
ALEX_FOUND_HERE,
INX_LINE | INX_WARN
);
}
return;
}
icc_insertalloc( p_hd->icc_joins, join->icc_obj );
return;
} /* end mkjoin */
/* ======== mktablelist =============================================== */
/* PURPOSE:
* This makes a tablelist
*
* RETURNS:
*
*/
void * mktablelist(
ICC_TBLST * head,
ICC_OBJ_TYP * table
) {
ICC_TBLST *p;
#ifdef TESTDEBUG3
ICC_TBLST *q;
#endif
/* mktable() returns 0 for 'table' if the data
is not valid. Then, ignore them and return
'head' for a linked list.
*/
if ( !table ) return head;
p = (ICC_TBLST *)inx_alloc( sizeof( ICC_TBLST ) );
memset( p, 0, sizeof( ICC_TBLST ) );
p->odata = table;
p->next = head;
#ifdef TESTDEBUG3
printf( "mktablelist() ( Head of tablelist )\n" );
for ( q=p; q; q=q->next ) {
printf( "- One table -\n" );
printf( " SYM: %s\n", OBJ(q->odata->icc_data1)->icc_data1 );
if ( q->odata->icc_data2 )
printf( " DSO: %s\n", OBJ(q->odata->icc_data2)->icc_data1 );
fflush( stdout );
}
#endif
/*
head = p;
return head;
*/
return p;
} /* end mktablelist */
/* ======== mktable =================================================== */
/* PURPOSE:
* This makes a table type
*
* RETURNS:
*
*/
void * mktable(
char * tbl_dso,
char * tbl_sym,
int file
) {
ICC_OBJ_TYP * tbl_dso_str = icc_getstr( tbl_dso );
ICC_OBJ_TYP * tbl_sym_str = file ? 0 : icc_getstr( tbl_sym );
ICC_HEAD * p_hd = icc_hd;
#ifdef TESTDEBUG3
printf( "mktable() = DSO: %s SYM: %s\n", tbl_dso, tbl_sym );
fflush( stdout );
#endif
if ( file ) {
if ( tbl_dso ) {
return icc_getmkgeneric( p_hd->icc_files, tbl_dso_str, 0 );
} else {
return 0;
}
} else {
if ( tbl_sym ) {
return icc_getmkgeneric( p_hd->icc_symbols, tbl_sym_str, tbl_dso_str );
} else {
return 0;
}
}
} /* end mktable */
/* ======== mkstdlib ================================================== */
/* PURPOSE:
* Make a stdlib entry
*
* RETURNS:
*
*/
void mkstdlib(
char * from_enc,
char * to_enc,
char * mbwc_dso,
char * mbwc_sym,
ICC_TBLST * tblst_mbwc,
ICC_TBLST * tblst_wcmb
) {
ICC_OBJ_TYP * from_enc_str = icc_getstr( from_enc );
ICC_OBJ_TYP * to_enc_str = icc_getstr( to_enc );
ICC_OBJ_TYP * mbwc_dso_str = icc_getstr( mbwc_dso );
ICC_OBJ_TYP * mbwc_sym_str = icc_getstr( mbwc_sym );
ICC_HEAD * p_hd = icc_hd;
ICC_STDLIBSPEC lspec[ 1 ];
ICC_STDLIBSPEC * p_lspec;
ICC_SPECTAB * p_tab;
ICC_STDLIBMETH * lmeth;
ICC_STDLIBMETH * p_lmeth;
ICC_OBJ_TYP ** tblmbwc = (ICC_OBJ_TYP **)NULL;
ICC_OBJ_TYP ** tblwcmb = (ICC_OBJ_TYP **)NULL;
ICC_TBLST * p, * pp;
int n_tblmbwc, n_tblwcmb, i;
int table_size = 0;
if ( ! from_enc || ! to_enc ) {
inx_error(
inx_last, /* the last position */
ALEX_TABLE,
ALEX_NONULLSPEC,
INX_LINE | INX_ERROR
);
}
/* Multiple spec: tablelist. */
for ( n_tblmbwc=0, p=tblst_mbwc; p != NULL; p=p->next, n_tblmbwc++ );
if ( 0 < n_tblmbwc ) {
tblmbwc = (ICC_OBJ_TYP **)inx_alloc( sizeof(ICC_OBJ_TYP *)*n_tblmbwc );
memset( tblmbwc, 0, sizeof(ICC_OBJ_TYP *)*n_tblmbwc );
for ( i=n_tblmbwc-1, p=tblst_mbwc; -1<i; p=p->next, i-- )
*(tblmbwc+i) = p->odata;
}
for ( n_tblwcmb=0, p=tblst_wcmb; p != NULL; p=p->next, n_tblwcmb++ );
if ( 0 < n_tblwcmb ) {
tblwcmb = (ICC_OBJ_TYP **)inx_alloc( sizeof(ICC_OBJ_TYP *)*n_tblwcmb );
memset( tblwcmb, 0, sizeof(ICC_OBJ_TYP *)*n_tblwcmb );
for ( i=n_tblwcmb-1, p=tblst_wcmb; -1<i; p=p->next, i-- )
*(tblwcmb+i) = p->odata;
}
table_size = sizeof(ICC_SPECTAB)*(n_tblmbwc+n_tblwcmb);
lmeth = (ICC_STDLIBMETH *)inx_alloc( sizeof(ICC_STDLIBMETH) + table_size );
memset( lspec, 0, sizeof( lspec ) );
memset( lmeth, 0, sizeof(*lmeth ) + table_size );
* lspec->icc_posi = * inx_last;
lspec->icc_from_enc = from_enc_str;
lspec->icc_to_enc = to_enc_str;
lmeth->icc_mbwc_obj = icc_getmkgeneric( p_hd->icc_objects, mbwc_dso_str, 0 );
lmeth->icc_mbwc_sym = icc_getmkgeneric( p_hd->icc_symbols, mbwc_sym_str, mbwc_dso_str );
/* We don't have to check validity of each data in the tablelist,
because it's been checked in mktable() and invalid data hasn't
been added to this list in mktablelist().
*/
lmeth->icc_ntable_mbwc = n_tblmbwc;
for ( p_tab=lmeth->icc_table, i=0; i<n_tblmbwc; i++ ) {
/* mbwctbl_obj can only belong to files or symbols */
if ( tblmbwc[i]->icc_objhead == p_hd->icc_files ) {
p_tab[i].icc_isfile = 1;
p_tab[i].icc_tobj = tblmbwc[i];
} else {
/* must be a symbol */
p_tab[i].icc_isfile = 0;
p_tab[i].icc_tobj = icc_getmkgeneric( p_hd->icc_objects,
tblmbwc[i]->icc_data2, 0 );
p_tab[i].icc_tbl = tblmbwc[i];
}
}
lmeth->icc_ntable_wcmb = n_tblwcmb;
for ( p_tab=lmeth->icc_table+lmeth->icc_ntable_mbwc, i=0; i<n_tblwcmb; i++ ) {
/* mbwctbl_obj can only belong to files or symbols */
if ( tblwcmb[i]->icc_objhead == p_hd->icc_files ) {
p_tab[i].icc_isfile = 1;
p_tab[i].icc_tobj = tblwcmb[i];
} else {
/* must be a symbol */
p_tab[i].icc_isfile = 0;
p_tab[i].icc_tobj = icc_getmkgeneric( p_hd->icc_objects,
tblwcmb[i]->icc_data2, 0 );
p_tab[i].icc_tbl = tblwcmb[i];
}
}
p_lspec = icc_findelem( p_hd->icc_libspecs, lspec->icc_obj );
if ( p_lspec ) {
/* spec is previously defined - This is allowed ! take the first*/
/* definition encountered. */
return;
}
p_hd->icc_libmeths->icc_size = sizeof( *lmeth ) + table_size;
p_lmeth = icc_getmk( p_hd->icc_libmeths, lmeth->icc_obj );
lspec->icc_meths = p_lmeth;
#if TESTDEBUG
p_lspec = ( ICC_STDLIBSPEC * )
#endif
icc_insertalloc( p_hd->icc_libspecs, lspec->icc_obj );
#if TESTDEBUG
printlspec( p_lspec );
#endif
inx_free( lmeth );
for ( p=tblst_mbwc; p != NULL; p=pp ) {
pp = p->next;
inx_free( (void *)p );
}
for ( p=tblst_wcmb; p != NULL; p=pp ) {
pp = p->next;
inx_free( (void *)p );
}
return;
} /* end mkstdlib */
/* ======== mklocale_alias ============================================ */
/* PURPOSE:
* Parsed a locale alias
*
* RETURNS:
* null
*/
void * mklocale_alias(
char * locale_name,
char * value
) {
ICC_OBJ_TYP * str_locale_name = icc_getstr( locale_name );
ICC_OBJ_TYP * str_value = icc_getstr( value );
ICC_HEAD * p_hd = icc_hd;
icc_getmkgeneric( p_hd->icc_loc_alias, str_locale_name, str_value );
return 0;
} /* end mklocale_alias */
/* ======== mklocale_codeset ========================================== */
/* PURPOSE:
* Make a locale/codeset pair
*
* RETURNS:
* Null
*/
void * mklocale_codeset(
char * locale_name,
char * value
) {
ICC_OBJ_TYP * str_locale_name = icc_getstr( locale_name );
ICC_OBJ_TYP * str_value = icc_getstr( value );
ICC_HEAD * p_hd = icc_hd;
icc_getmkgeneric( p_hd->icc_loc_codeset, str_locale_name, str_value );
return 0;
} /* end mklocale_codeset */
/* ======== icc_read_input ============================================ */
/* PURPOSE:
* Read input files.
*
* RETURNS:
*
*/
int icc_read_input( int argc, char ** argv, char ** pname )
{
int i;
int error = 0;
for ( i = 1; i < argc; i ++ ) {
if ( ! strcmp( argv[ i ], "-f" ) ) {
if ( i >= argc ) {
fprintf( stderr, "iconv_comp: -f argument not given\n" );
exit( 1 );
}
* pname = argv[ i + 1 ];
i ++;
continue;
}
inx_clear();
inx_setfile( argv[ i ], ( FILE * ) 0 );
yyparse();
if ( inx_iserror() ) {
error = 1;
fprintf( stderr, "%s : has errors\n", argv[ i ] );
inx_stats();
}
}
return error;
} /* end icc_read_input */
/* ======== ICC_SPANEM ================================================ */
/* PURPOSE:
* Span all elements in a linked list
*
* RETURNS:
*
*/
#define ICC_SPANEM( typ, var, hd ) \
for ( \
var = ( typ * ) ( hd->icc_head ); \
var; \
var = ( typ * ) ( ( ICC_OBJ_TYP * ) var )->icc_next \
) \
/* end of macro */
#define ICC_SPANUSED( typ, var, hd ) \
for ( \
var = ( typ * ) ( hd->icc_head ); \
var; \
var = ( typ * ) ( ( ICC_OBJ_TYP * ) var )->icc_next \
) if ( ( ( ICC_OBJ_TYP * ) var )->icc_used ) \
/* end of macro */
/* ======== icc_cmpstr ================================================ */
/* PURPOSE:
* Compare string by string
*
* RETURNS:
*
*/
int icc_cmpstr(
ICC_OBJ_TYP ** pp_a,
ICC_OBJ_TYP ** pp_b
) {
char * sa;
char * sb;
ICC_OBJ_TYP * p_a = * pp_a;
ICC_OBJ_TYP * p_b = * pp_b;
if ( ! p_a ) {
if ( ! p_b ) {
return 0;
}
return 1;
} else if ( ! p_b ) {
return -1;
}
if ( p_a == p_b ) {
return 0;
}
sa = p_a->icc_data1;
sb = p_b->icc_data1;
if ( ! sa ) {
if ( ! sb ) {
return 0;
}
return 1;
} else if ( ! sb ) {
return -1;
}
return strcasecmp( sa, sb );
} /* end icc_cmpstr */
/* ======== icc_compar ================================================ */
/* PURPOSE:
* Comparison routine
*
* RETURNS:
*
*/
int icc_compar(
const ICC_SPEC ** p_a,
const ICC_SPEC ** p_b
) {
int cmp;
cmp = (*p_a)->icc_from_enc->icc_num - (*p_b)->icc_from_enc->icc_num;
if ( cmp ) {
return cmp;
}
return (*p_a)->icc_to_enc->icc_num - (*p_b)->icc_to_enc->icc_num;
} /* end icc_compar */
/* ======== icc_compar_ls ============================================= */
/* PURPOSE:
* Comparison routine
*
* RETURNS:
*
*/
int icc_compar_ls(
const ICC_STDLIBSPEC ** p_a,
const ICC_STDLIBSPEC ** p_b
) {
int cmp;
cmp = (*p_a)->icc_from_enc->icc_num - (*p_b)->icc_from_enc->icc_num;
if ( cmp ) {
return cmp;
}
return (*p_a)->icc_to_enc->icc_num - (*p_b)->icc_to_enc->icc_num;
} /* end icc_compar_ls */
/* ======== icc_nulfnc ================================================ */
/* PURPOSE:
*
*
* RETURNS:
*
*/
#define ALIGN( A, B ) ( 1 + ( ((A)-1) | ((B)-1) ) )
int icc_nulfnc(
char * ptr,
int * prel,
void * data,
int size,
int align
) {
int new;
new = ALIGN( * prel, align );
* prel = new + size;
return new;
} /* end icc_nulfnc */
/* ======== icc_cpyfnc ================================================ */
/* PURPOSE:
*
*
* RETURNS:
*
*/
int icc_cpyfnc(
char * ptr,
int * prel,
void * data,
int size,
int align
) {
int new;
new = ALIGN( * prel, align );
memset( ptr + * prel, 0xff, new - * prel );
memcpy( ptr + new, data, size );
* prel = new + size;
return new;
} /* end icc_cpyfnc */
/* ======== icc_iconv_r_spec_size ===================================== */
/* PURPOSE:
* Calculate a spec size for number of tables
*
* RETURNS:
*
*/
int icc_iconv_r_spec_size(
int n
) {
return
offsetof( ICONV_S_SPEC, iconv_table ) +
n * sizeof( struct ICONV_S_TBLS )
;
} /* end icc_iconv_r_spec_size */
/* ======== icc_iconv_r_libspec_size ================================== */
/* PURPOSE:
* Calculate a lib spec size for number of tables
*
* RETURNS:
*
*/
int icc_iconv_r_libspec_size(
int n
) {
return
offsetof( ICONV_S_LSPEC, iconv_table ) +
n * sizeof( struct ICONV_S_TBLS )
;
} /* end icc_iconv_r_libspec_size */
/* ======== icc_setused =============================================== */
/* PURPOSE:
* Set used flag and return relative address
*
* RETURNS:
*
*/
ICONV_S_RELPTR icc_setused(
ICC_OBJ_HEAD * p_oh,
ICC_OBJ_TYP * p_obj
) {
if ( ! p_obj ) {
return 0;
}
if ( ! p_obj->icc_used ) {
p_oh->icc_usedcount ++;
p_obj->icc_used = 1;
}
return p_obj->icc_robj;
} /* end icc_setused */
/* ======== icc_dump_data ============================================= */
/* PURPOSE:
* Dump the data file
*
* RETURNS:
*
*/
void icc_dump_data(
ICC_HEAD * p_hd,
char * data,
int * prel,
ICC_CPYFNC fnc,
ICC_SPEC ** pp_top,
ICC_STDLIBSPEC ** pp_ls_top,
int nstr,
ICC_OBJ_TYP ** pp_str,
ICONV_S_SPEC * a_sp,
ICONV_S_LSPEC * a_ls_sp
) {
ICONV_S_TABLE a_st[ 1 ];
ICONV_T_OBJECTSPEC a_os[ 1 ];
ICONV_T_SYMBOL a_sy[ 1 ];
ICONV_T_SPECKEY a_sk[ 1 ];
ICONV_T_METHOD a_mt[ 1 ];
ICONV_T_FILE a_fl[ 1 ];
ICONV_S_CODESET_LIST a_cl[ 1 ];
ICONV_T_LOC_CODESET a_lc[ 1 ];
ICONV_S_ALIAS_LIST a_al[ 1 ];
ICONV_T_LOC_ALIAS a_la[ 1 ];
ICONV_S_RESOURCE_LIST a_rl[ 1 ];
ICONV_T_LOC_RESOURCE a_lr[ 1 ];
ICC_SPEC * p_sp;
ICC_SPEC ** pp_sp;
ICC_STDLIBSPEC * p_ls_sp;
ICC_STDLIBMETH * p_lm_sp;
ICC_STDLIBSPEC ** pp_ls_sp;
int i;
int j;
int ntable;
ICC_OBJ_TYP * p_obj;
ICC_OBJ_TYP * p_obj1;
ICC_OBJ_TYP ** pp_obj;
ICC_METHODS * p_mt;
/* First dump the ICONV_S_TABLE */
a_st->iconv_magicnum = ICONV_MAGIC;
a_st->iconv_numfiles = p_hd->icc_files->icc_usedcount;
a_st->iconv_nummethods = p_hd->icc_methods->icc_usedcount;
a_st->iconv_numobject = p_hd->icc_objects->icc_usedcount;
a_st->iconv_symbols = p_hd->icc_symbols->icc_usedcount;
a_st->iconv_numspec = p_hd->icc_specs->icc_count;
a_st->iconv_numlibspec = p_hd->icc_libspecs->icc_count;
a_st->iconv_numlspcobj = p_hd->icc_libmeths->icc_usedcount;
a_st->iconv_numspecobj = p_hd->icc_specs->icc_count;
a_st->iconv_alias_list = p_hd->icc_loc_alias->icc_robj;
a_st->iconv_codeset_list = p_hd->icc_loc_codeset->icc_robj;
a_st->iconv_resource_list = p_hd->icc_resources->icc_robj;
/* Write the ICONV_S_TABLE record */
( * fnc )( data, prel, a_st, offsetof( ICONV_S_TABLE, iconv_speckey ), 8 );
/* Write the keys. */
for ( i = p_hd->icc_specs->icc_count, pp_sp = pp_top; i; pp_sp ++, i -- ) {
p_sp = * pp_sp;
a_sk->iconv_specifier[ ICONV_SRC ] = p_sp->icc_from_enc->icc_robj;
#if TESTDEBUG
p_obj = p_sp->icc_from_enc;
printf( "Keystr1 %d = %s @ %d\n", i, p_obj->icc_data1, p_obj->icc_robj );
#endif
a_sk->iconv_specifier[ ICONV_DST ] = p_sp->icc_to_enc->icc_robj;
#if TESTDEBUG
p_obj = p_sp->icc_to_enc;
printf( "Keystr2 %d = %s @ %d\n", i, p_obj->icc_data1, p_obj->icc_robj );
#endif
a_sk->iconv_spec = p_sp->icc_obj->icc_robj;
( * fnc )( data, prel, a_sk, sizeof( a_sk ), sizeof( ICONV_S_RELPTR ) );
}
/* Write the libspec keys. */
for ( i = p_hd->icc_libspecs->icc_count, pp_ls_sp = pp_ls_top; i; pp_ls_sp ++, i -- ) {
p_ls_sp = * pp_ls_sp;
a_sk->iconv_specifier[ ICONV_SRC ] = p_ls_sp->icc_from_enc->icc_robj;
#if TESTDEBUG
p_obj = p_ls_sp->icc_from_enc;
printf( "LIBKeystr1 %d = %s @ %d\n", i, p_obj->icc_data1, p_obj->icc_robj );
#endif
a_sk->iconv_specifier[ ICONV_DST ] = p_ls_sp->icc_to_enc->icc_robj;
#if TESTDEBUG
p_obj = p_ls_sp->icc_to_enc;
printf( "LIBKeystr2 %d = %s @ %d\n", i, p_obj->icc_data1, p_obj->icc_robj );
#endif
a_sk->iconv_spec =
icc_setused( p_hd->icc_libmeths, p_ls_sp->icc_meths->icc_obj );
( * fnc )( data, prel, a_sk, sizeof( a_sk ), sizeof( ICONV_S_RELPTR ) );
}
/* Write the encoding strings close to the keys */
for ( i = 0; i < nstr; i ++ ) {
p_obj = pp_str[ i ];
p_obj->icc_robj = ( * fnc )(
data,
prel,
p_obj->icc_data1,
1 + strlen( p_obj->icc_data1 ),
1
);
#if TESTDEBUG
printf( "encstr %d = %s @ %d\n", i, p_obj->icc_data1, p_obj->icc_robj );
#endif
}
/* dump the other part of the specs */
for ( i = p_hd->icc_specs->icc_count, pp_sp = pp_top; i; pp_sp ++, i -- ) {
p_sp = * pp_sp;
a_sp->iconv_specnum = pp_sp - pp_top;
a_sp->iconv_meth = icc_setused( p_hd->icc_methods, p_sp->icc_mth->icc_obj );
a_sp->iconv_ntable = p_sp->icc_ntable;
/* dump all tables */
for ( j = 0; j < p_sp->icc_ntable; j ++ ) {
if ( p_sp->icc_table[ j ].icc_isfile ) {
a_sp->iconv_table[ j ].iconv_tableobject =
icc_setused( p_hd->icc_files, p_sp->icc_table[ j ].icc_tobj );
a_sp->iconv_table[ j ].iconv_table = 0;
} else {
a_sp->iconv_table[ j ].iconv_tableobject =
icc_setused( p_hd->icc_objects, p_sp->icc_table[ j ].icc_tobj );
a_sp->iconv_table[ j ].iconv_table =
icc_setused( p_hd->icc_symbols, p_sp->icc_table[ j ].icc_tbl );
}
}
p_sp->icc_obj->icc_robj = ( * fnc )(
data, prel, a_sp, icc_iconv_r_spec_size( p_sp->icc_ntable ),
sizeof( ICONV_S_RELPTR )
);
}
i = 0;
ICC_SPANUSED( ICC_STDLIBMETH, p_lm_sp, p_hd->icc_libmeths ) {
a_ls_sp->iconv_specnum = i ++;
a_ls_sp->iconv_obj_lmth = icc_setused(
p_hd->icc_objects, p_lm_sp->icc_mbwc_obj
);
a_ls_sp->iconv_sym_lmth = icc_setused(
p_hd->icc_symbols, p_lm_sp->icc_mbwc_sym
);
#if TESTDEBUG
printf( "iconv_sym_lmth offset is %d\n", a_ls_sp->iconv_sym_lmth );
#endif
a_ls_sp->iconv_ntable_mbwc = p_lm_sp->icc_ntable_mbwc;
a_ls_sp->iconv_ntable_wcmb = p_lm_sp->icc_ntable_wcmb;
ntable = p_lm_sp->icc_ntable_mbwc + p_lm_sp->icc_ntable_wcmb;
/* dump all tables */
for ( j = 0; j < ntable; j ++ ) {
if ( p_lm_sp->icc_table[ j ].icc_isfile ) {
a_ls_sp->iconv_table[ j ].iconv_tableobject =
icc_setused( p_hd->icc_files, p_lm_sp->icc_table[ j ].icc_tobj );
a_ls_sp->iconv_table[ j ].iconv_table = 0;
} else {
a_ls_sp->iconv_table[ j ].iconv_tableobject =
icc_setused( p_hd->icc_objects, p_lm_sp->icc_table[ j ].icc_tobj );
a_ls_sp->iconv_table[ j ].iconv_table =
icc_setused( p_hd->icc_symbols, p_lm_sp->icc_table[ j ].icc_tbl );
}
}
p_lm_sp->icc_obj->icc_robj = ( * fnc )(
data, prel, a_ls_sp, icc_iconv_r_libspec_size( ntable ),
sizeof( ICONV_S_RELPTR )
);
}
i = 0;
ICC_SPANUSED( ICC_METHODS, p_mt, p_hd->icc_methods ) {
a_mt->iconv_num = i ++;
a_mt->iconv_algobject = icc_setused( p_hd->icc_objects, p_mt->icc_aobj );
a_mt->iconv_algorithm = icc_setused( p_hd->icc_symbols, p_mt->icc_cnv );
a_mt->iconv_ctlobject = icc_setused( p_hd->icc_objects, p_mt->icc_cobj );
a_mt->iconv_control = icc_setused( p_hd->icc_symbols, p_mt->icc_ctl );
p_mt->icc_obj->icc_robj = ( * fnc )(
data, prel, a_mt, sizeof( a_mt ), sizeof( ICONV_S_RELPTR )
);
}
/* Dump resource list */
memset( a_rl, 0, sizeof( a_rl ) );
memset( a_lr, 0, sizeof( a_lr ) );
j = p_hd->icc_resources->icc_count;
a_rl->iconv_count = j;
p_hd->icc_resources->icc_robj =
( * fnc )(
data, prel, a_rl,
offsetof( ICONV_S_RESOURCE_LIST, iconv_resources ),
sizeof( ICONV_S_RELPTR )
);
pp_obj = p_hd->icc_resources->icc_array;
/* Dump each resource */
for ( i = 0; i < j; i ++ ) {
ICC_RES_VALUES * p_vvals;
p_obj = pp_obj[ i ];
a_lr->iconv_resname = icc_setused( p_hd->icc_strings, OBJ(p_obj->icc_data1) );
a_lr->iconv_value = ( (ICC_RES_VALUES * )(p_obj->icc_data2) )->icc_robj;
p_obj->icc_robj = ( * fnc )(
data,
prel,
a_lr, sizeof( a_lr ), sizeof( ICONV_S_RELPTR )
);
#if TESTDEBUG
printf( "resource %d = %s\n", i,
OBJ(p_obj->icc_data1)->icc_data1
);
#endif
}
/* Dump the values for a resource with a magic number */
for ( i = 0; i < j; i ++ ) {
p_obj = pp_obj[ i ];
icc_write_resource(
( ICC_RES_VALUES * )( p_obj->icc_data2 ),
data,
prel, fnc
);
#if TESTDEBUG
printf( "Dumping values for resource %d = %s\n", i,
OBJ(p_obj->icc_data1)->icc_data1
);
#endif
}
i = 0;
/* Dump objects */
ICC_SPANUSED( ICC_OBJ_TYP, p_obj, p_hd->icc_objects ) {
a_os->iconv_num = i;
a_os->iconv_name = icc_setused( p_hd->icc_strings, OBJ(p_obj->icc_data1) );
p_obj->icc_robj =
( * fnc )( data, prel, a_os, sizeof( a_os ), sizeof( ICONV_S_RELPTR ) );
#if TESTDEBUG
printf( "OBJ %d = %s @ %d\n", p_obj->icc_num, OBJ( p_obj->icc_data1 )->icc_data1, p_obj->icc_robj );
#endif
i ++;
}
i = 0;
/* Dump symbols */
ICC_SPANUSED( ICC_OBJ_TYP, p_obj, p_hd->icc_symbols ) {
a_sy->iconv_num = i;
a_sy->iconv_name = icc_setused( p_hd->icc_strings, OBJ(p_obj->icc_data1) );
p_obj->icc_robj =
( * fnc )( data, prel, a_sy, sizeof( a_sy ), sizeof( ICONV_S_RELPTR ) );
i ++;
}
i = 0;
/* Dump files */
ICC_SPANUSED( ICC_OBJ_TYP, p_obj, p_hd->icc_files ) {
a_fl->iconv_num = i;
a_fl->iconv_name = icc_setused( p_hd->icc_strings, OBJ(p_obj->icc_data1) );
p_obj->icc_robj =
( * fnc )( data, prel, a_fl, sizeof( a_fl ), sizeof( ICONV_S_RELPTR ) );
#if TESTDEBUG
printf( "FILE %d = %s @ %d\n", p_obj->icc_num, OBJ( p_obj->icc_data1 )->icc_data1, p_obj->icc_robj );
#endif
i ++;
}
/* Dump locale alias */
memset( a_al, 0, sizeof( a_al ) );
memset( a_la, 0, sizeof( a_la ) );
j = p_hd->icc_loc_alias->icc_count;
a_al->iconv_count = j;
p_hd->icc_loc_alias->icc_robj =
( * fnc )(
data, prel, a_al,
offsetof( ICONV_S_ALIAS_LIST, iconv_aliases ),
sizeof( ICONV_S_RELPTR )
);
pp_obj = p_hd->icc_loc_alias->icc_array;
for ( i = 0; i < j; i ++ ) {
p_obj = pp_obj[ i ];
a_la->iconv_locale = icc_setused( p_hd->icc_strings, OBJ(p_obj->icc_data1) );
a_la->iconv_value = icc_setused( p_hd->icc_strings, OBJ(p_obj->icc_data2) );
p_obj->icc_robj = ( * fnc )(
data,
prel,
a_la, sizeof( a_la ), sizeof( ICONV_S_RELPTR )
);
#if TESTDEBUG
printf( "alias %d = %s %s\n", i,
OBJ(p_obj->icc_data1)->icc_data1,
OBJ(p_obj->icc_data2)->icc_data1
);
#endif
}
/* Dump locale codeset */
memset( a_cl, 0, sizeof( a_cl ) );
memset( a_lc, 0, sizeof( a_lc ) );
j = p_hd->icc_loc_codeset->icc_count;
a_cl->iconv_count = j;
p_hd->icc_loc_codeset->icc_robj =
( * fnc )(
data, prel, a_cl,
offsetof( ICONV_S_CODESET_LIST, iconv_codesets ),
sizeof( ICONV_S_RELPTR )
);
pp_obj = p_hd->icc_loc_codeset->icc_array;
for ( i = 0; i < j; i ++ ) {
p_obj = pp_obj[ i ];
a_lc->iconv_locale = icc_setused( p_hd->icc_strings, OBJ(p_obj->icc_data1) );
a_lc->iconv_value = icc_setused( p_hd->icc_strings, OBJ(p_obj->icc_data2) );
p_obj->icc_robj = ( * fnc )(
data,
prel,
a_lc, sizeof( a_lc ), sizeof( ICONV_S_RELPTR )
);
#if TESTDEBUG
printf( "codeset %d = %s %s\n", i,
OBJ(p_obj->icc_data1)->icc_data1,
OBJ(p_obj->icc_data2)->icc_data1
);
#endif
}
/* Dump strings */
ICC_SPANUSED( ICC_OBJ_TYP, p_obj, p_hd->icc_strings ) {
/* Make sure we have data */
if ( ( ! p_obj->icc_used1 ) && p_obj->icc_data1 ) {
p_obj->icc_robj =
( * fnc )(
data,
prel,
p_obj->icc_data1,
1 + strlen( p_obj->icc_data1 ),
1
);
#if TESTDEBUG
printf( "dumped string \"%s\" at %d\n", p_obj->icc_data1, p_obj->icc_robj );
#endif
} else if ( ! p_obj->icc_used1 ) {
p_obj->icc_robj = 0;
}
}
return;
} /* end icc_dump_data */
/* ======== icc_cmpclone ============================================== */
/* PURPOSE:
* Compare a clone record and a spec record.
*
* RETURNS:
*
*/
int icc_cmpclone(
ICC_HEAD * p_hd,
ICC_CLONEOBJ * p_clone,
ICC_SPEC * p_spec
) {
ICC_OBJ_TYP * enc;
enc = p_clone->icc_src_dst ? p_spec->icc_to_enc : p_spec->icc_from_enc;
return (
( p_clone->icc_enc == enc )
&& ( p_spec->icc_mth == p_clone->icc_mth )
);
} /* end icc_cmpclone */
/* ======== icc_specsize ============================================== */
/* PURPOSE:
* Spec size is determined by number of joins ! This is
* oversize by one table to accomodate position info.
*
* RETURNS:
*
*/
long icc_specsize(
long ntable
) {
return sizeof( ICC_SPEC ) + ( ntable ) * sizeof( struct ICC_SPECTAB );
} /* end icc_specsize */
/* ======== icc_mkclone =============================================== */
/* PURPOSE:
* Make a clone.
*
* RETURNS:
*
*/
int icc_mkclone(
ICC_HEAD * p_hd,
ICC_CLONEOBJ * p_clone,
ICC_SPEC * p_spec
) {
ICC_OBJ_TYP * enc_src;
ICC_OBJ_TYP * enc_dst;
ICC_SPEC * a_spec;
long i;
if ( p_clone->icc_src_dst ) {
enc_dst = p_clone->icc_newenc;
enc_src = p_spec->icc_from_enc;
} else {
enc_dst = p_spec->icc_to_enc;
enc_src = p_clone->icc_newenc;
}
/* Check is spec already exists */
if ( icc_getspec( p_hd, enc_src, enc_dst ) ) return 0;
PSPEC( "Cloning from", p_spec )
a_spec = ( ICC_SPEC * ) inx_alloc(i = icc_specsize(p_spec->icc_ntable));
memcpy( a_spec, p_spec, i );
a_spec->icc_from_enc = enc_src;
a_spec->icc_to_enc = enc_dst;
a_spec->icc_mth = p_clone->icc_newmth;
icc_insert( p_hd->icc_specs, a_spec->icc_obj );
PSPEC( "Cloning to", a_spec )
return 1;
} /* end icc_mkclone */
/* ======== icc_do_clones ============================================= */
/* PURPOSE:
* Process clone records
*
* RETURNS:
*
*/
int icc_do_clones(
ICC_HEAD * p_hd
) {
ICC_CLONEOBJ * p_clone;
ICC_SPEC * p_spec;
int ndone = 0;
ICC_SPANEM( ICC_CLONEOBJ, p_clone, p_hd->icc_clones ) {
ICC_SPANEM( ICC_SPEC, p_spec, p_hd->icc_specs ) {
if ( icc_cmpclone( p_hd, p_clone, p_spec ) ) {
ndone += icc_mkclone( p_hd, p_clone, p_spec );
}
}
}
return ndone;
} /* end icc_do_clones */
/* ======== icc_cmpjoin1 ============================================== */
/* PURPOSE:
* Check to see if spec meets first join criteria
*
* RETURNS:
*
*/
int icc_cmpjoin1(
ICC_HEAD * p_hd,
ICC_JOINOBJ * p_join,
ICC_SPEC * p_spec
) {
return (
( p_join->icc_dst_enc == p_spec->icc_to_enc )
&& ( p_join->icc_mth_dst == p_spec->icc_mth )
);
} /* end icc_cmpjoin1 */
/* ======== icc_cmpjoin2 ============================================== */
/* PURPOSE:
* Compare the second element of the join
*
* RETURNS:
*
*/
int icc_cmpjoin2(
ICC_HEAD * p_hd,
ICC_JOINOBJ * p_join,
ICC_SPEC * p_spec1,
ICC_SPEC * p_spec2
) {
return (
( p_join->icc_src_enc == p_spec2->icc_from_enc )
&& ( p_join->icc_mth_src == p_spec2->icc_mth )
);
} /* end icc_cmpjoin2 */
/* ======== icc_mkjoin ================================================ */
/* PURPOSE:
* Make a join record
*
* RETURNS:
* 1 if join made 0 otherwise
*/
int icc_mkjoin(
ICC_HEAD * p_hd,
ICC_JOINOBJ * p_join,
ICC_SPEC * p_spec1,
ICC_SPEC * p_spec2
) {
ICC_SPEC * a_spec;
int num;
/* Check is spec already exists */
if ( icc_getspec( p_hd, p_spec1->icc_from_enc, p_spec2->icc_to_enc ) ) {
return 0;
}
PSPEC( "Joining 1", p_spec1 )
PSPEC( "and 2", p_spec2 )
num = p_spec1->icc_ntable + p_spec2->icc_ntable;
a_spec = ( ICC_SPEC * ) inx_alloc(icc_specsize( num ));
memcpy( a_spec, p_spec1, icc_specsize( p_spec1->icc_ntable ) );
a_spec->icc_to_enc = p_spec2->icc_to_enc;
a_spec->icc_mth = p_join->icc_newmth;
a_spec->icc_ntable = num;
/* copy table info */
memcpy(
a_spec->icc_table + p_spec1->icc_ntable,
p_spec2->icc_table,
p_spec2->icc_ntable * sizeof( p_spec2->icc_table[ 0 ] )
);
icc_insert( p_hd->icc_specs, a_spec->icc_obj );
PSPEC( "to create spec", a_spec )
return 1;
} /* end icc_mkjoin */
/* ======== icc_do_joins ============================================== */
/* PURPOSE:
* Process join records
*
* RETURNS:
*
*/
int icc_do_joins(
ICC_HEAD * p_hd
) {
ICC_JOINOBJ * p_join;
ICC_SPEC * p_spec_dst;
ICC_SPEC * p_spec_src;
int ndone = 0;
ICC_SPANEM( ICC_JOINOBJ, p_join, p_hd->icc_joins ) {
ICC_SPANEM( ICC_SPEC, p_spec_dst, p_hd->icc_specs ) {
if ( icc_cmpjoin1( p_hd, p_join, p_spec_dst ) ) {
ICC_SPANEM( ICC_SPEC, p_spec_src, p_hd->icc_specs ) {
if ( icc_cmpjoin2( p_hd, p_join, p_spec_dst, p_spec_src ) ) {
ndone += icc_mkjoin( p_hd, p_join, p_spec_dst, p_spec_src );
}
}
}
}
}
return ndone;
} /* end icc_do_joins */
/* ======== icc_procstr =============================================== */
/* PURPOSE:
* Process strings that are used in encodings. These will
* be sorted and stored near the spec keys for the sake of
* memory locality.
*
* RETURNS:
*
*/
void icc_procstr(
ICC_HEAD * p_hd,
ICC_OBJ_TYP *** ppp_str,
int nstr
) {
ICC_OBJ_TYP ** pp_str;
ICC_OBJ_TYP ** pp_stmp;
ICC_OBJ_TYP * p_obj;
int i;
* ppp_str = pp_stmp = pp_str = ( ICC_OBJ_TYP ** ) inx_alloc(
nstr * sizeof( * pp_str )
);
ICC_SPANEM( ICC_OBJ_TYP, p_obj, p_hd->icc_strings ) {
if ( p_obj->icc_used1 ) {
* ( pp_stmp ++ ) = p_obj;
}
#if TESTDEBUG
printf( "encstr %d = %s @ %d\n", p_obj->icc_used1, p_obj->icc_data1, p_obj->icc_robj );
#endif
}
/* Sort the string list. */
qsort(
pp_str,
nstr,
sizeof( * pp_str ),
( icc_qsort_compar ) icc_cmpstr
);
/* Assign a numbering for the strings. */
for ( i = 0; i < nstr; i ++ ) {
pp_str[ i ]->icc_num = i;
#if TESTDEBUG
p_obj=pp_str[ i ];
printf( "sortstr %d = %s @ %d\n", p_obj->icc_used1, p_obj->icc_data1, p_obj->icc_robj );
#endif
}
return;
} /* end icc_procstr */
/* ======== icc_markused ============================================== */
/* PURPOSE:
* Mark used flags
*
* RETURNS:
*
*/
int icc_markused(
ICC_OBJ_HEAD * p_oh,
ICC_OBJ_TYP * p_obj,
int use
) {
if ( ! p_obj ) {
return 0;
}
if ( ! p_obj->icc_used ) {
p_oh->icc_usedcount ++;
p_obj->icc_used = 1;
p_obj->icc_used1 = use;
return 1;
}
return 0;
} /* end icc_markused */
/* ======== icc_strobjcmp_data1 ======================================= */
/* PURPOSE:
* Compare objects where data 1 is a string object
*
* RETURNS:
* int comparison
*/
int icc_strobjcmp_data1(
ICC_OBJ_TYP ** pp_a,
ICC_OBJ_TYP ** pp_b
) {
char * sa;
char * sb;
ICC_OBJ_TYP * p_a = * pp_a;
ICC_OBJ_TYP * p_b = * pp_b;
if ( ! p_a ) {
if ( ! p_b ) {
return 0;
}
return 1;
} else if ( ! p_b ) {
return -1;
}
if ( p_a == p_b ) {
return 0;
}
p_a = p_a->icc_data1;
p_b = p_b->icc_data1;
if ( ! p_a ) {
if ( ! p_b ) {
return 0;
}
return 1;
} else if ( ! p_b ) {
return -1;
}
if ( p_a == p_b ) {
return 0;
}
sa = p_a->icc_data1;
sb = p_b->icc_data1;
if ( ! sa ) {
if ( ! sb ) {
return 0;
}
return 1;
} else if ( ! sb ) {
return -1;
}
return strcmp( sa, sb );
} /* end icc_strobjcmp_data1 */
/* ======== icc_markstring ============================================ */
/* PURPOSE:
* Mark a locale object's strings as used
*
* RETURNS:
*
*/
void icc_markstring(
ICC_OBJ_TYP * p_obj,
int sel
) {
ICC_HEAD * p_hd = icc_hd;
if ( sel==0 || sel==1 )
icc_markused( p_hd->icc_strings, p_obj->icc_data1, 0 );
if ( sel==0 || sel==2 )
icc_markused( p_hd->icc_strings, p_obj->icc_data2, 0 );
return;
} /* end icc_markstring */
/* ======== fix_objs ================================================== */
/* PURPOSE:
* Create an array and sort the list per the funcion
*
* RETURNS:
*
*/
void fix_objs(
ICC_OBJ_HEAD * p_oh,
icc_qsort_compar func,
void ( * mark_func )( ICC_OBJ_TYP * p_obj, int sel ),
int sel
) {
ICC_OBJ_TYP ** p_arr;
ICC_OBJ_TYP * p_obj;
/* remove any previous array */
if ( p_oh->icc_array ) {
inx_free( p_oh->icc_array );
}
/* allocate a new array */
p_arr = ( ICC_OBJ_TYP ** )
inx_alloc( p_oh->icc_count * sizeof( ICC_OBJ_TYP * ) );
p_oh->icc_array = p_arr;
p_oh->icc_robj = 0;
/* populate the array */
ICC_SPANEM( ICC_OBJ_TYP, p_obj, p_oh ) {
* ( p_arr ++ ) = p_obj;
( * mark_func )( p_obj, sel );
}
/* Sort the array */
qsort(
p_oh->icc_array,
p_oh->icc_count,
sizeof( p_oh->icc_array[ 0 ] ),
func
);
return;
} /* end fix_objs */
/* ======== icc_prepare_resource ====================================== */
/* PURPOSE:
* Find correct alignment etc for resource.
*
*/
void icc_prepare_resource(
ICC_RES_VALUES * p_vvals
) {
ICC_RES_VALUE * p_vval;
ICC_TYPEDEF * p_td;
int offset = 0;
p_vvals->icc_align = 1; /* alignment must be at least 1 */
p_vval = p_vvals->icc_head;
/* Loop thru all values and align them appropriately */
while ( p_vval ) {
p_td = p_vval->icc_type;
/* Find the overall alignment requirement */
if ( p_vvals->icc_align < p_td->icc_algn_output ) {
p_vvals->icc_align = p_td->icc_algn_output;
}
/* align the object - this is the offset */
offset = ALIGN( offset, p_td->icc_algn_output );
p_vval->icc_offset = offset;
/* Increment the offset */
offset += p_td->icc_size_output;
/* Go to the next object */
p_vval = p_vval->icc_next;
}
/* Align the object to it's final size */
offset = ALIGN( offset, p_vvals->icc_align );
p_vvals->icc_size = offset;
return;
} /* end icc_prepare_resource */
/* ======== icc_write_resource ======================================== */
/* PURPOSE:
* Write a resource.
*
*/
void icc_write_resource(
ICC_RES_VALUES * p_vvals,
char * ptr,
int * prel,
ICC_CPYFNC fnc
) {
ICC_RES_VALUE * p_vval;
ICC_TYPEDEF * p_td;
int offset;
int magic_resvals = ICONV_MAGIC_RESVALS;
ICC_OBJ_TYP * p_obk;
ICC_OBJ_TYP * p_obj;
/* Function icc_cnv_func() isn't called at 1st icc_dump_data()
call. These object should be marked because of SPANUSED
for objects, symbols and files.
*/
p_vval = p_vvals->icc_head;
while ( p_vval ) {
if ( p_vval->icc_type->icc_typeid == ICC_TYP_REFER ||
p_vval->icc_type->icc_typeid == ICC_TYP_STRING ) {
p_obj = * ( ICC_OBJ_TYP ** ) ( p_vval->icc_data );
icc_markused( p_obj->icc_objhead, p_obj, 0 );
if ( p_vval->icc_type->icc_typeid == ICC_TYP_REFER && p_obj->icc_data2 ) {
p_obk = *(( ICC_OBJ_TYP ** ) ( p_vval->icc_data )+1);
icc_markused( p_obk->icc_objhead, p_obk, 0 );
}
}
p_vval = p_vval->icc_next;
}
/* start with the overall alignment reqmt */
p_vvals->icc_robj = offset = ALIGN( * prel, p_vvals->icc_align );
/* Dump a magic # of values for a resource */
if ( ptr ) memset( ptr + * prel, 0xff, offset - * prel );
( * fnc )( ptr, prel, &magic_resvals, sizeof( magic_resvals ),
sizeof( ICONV_S_RELPTR )
);
offset = ALIGN( * prel, sizeof( ICONV_S_RELPTR ) );
/* Dump values for a resource */
if ( ptr ) {
memset( ptr + * prel, 0xff, offset - * prel + p_vvals->icc_size );
/* span through all elements */
p_vval = p_vvals->icc_head;
/* Loop thru all values and align them appropriately */
while ( p_vval ) {
p_td = p_vval->icc_type;
( * p_td->icc_cnv_func )(
ptr + p_vval->icc_offset + offset,
p_vval
);
#if TESTDEBUG
printf( " Dumped type %s at %d\n",
p_td->icc_typename, p_vval->icc_offset + offset
);
#endif
/* Go to the next object */
p_vval = p_vval->icc_next;
}
}
* prel = offset + p_vvals->icc_size;
return;
} /* end icc_write_resource */
/* ======== process =================================================== */
/* PURPOSE:
* The function to process.
*
* RETURNS:
*
*/
void process( char * filename )
{
ICC_HEAD * p_hd = icc_hd;
ICC_SPEC * p_sp;
ICC_SPEC ** pp_sp;
ICC_SPEC ** pp_top;
ICC_STDLIBSPEC * p_ls_sp;
ICC_STDLIBSPEC ** pp_ls_sp;
ICC_STDLIBSPEC ** pp_ls_top;
int i;
int k;
char * data;
int rel;
char fname[ 1024 ];
int fd;
ICC_OBJ_TYP * p_obj;
ICC_OBJ_TYP ** pp_str;
int nstr;
ICONV_S_SPEC * a_sp;
ICONV_S_LSPEC * a_ls_sp;
int maxtable = 1;
ICC_OBJ_TYP ** pp_obj;
/* process clones and joins */
/* A join may produce somthing cloneable and a clone may produce */
/* somthing joinable so loop the icc_do_clones and icc_do_joins */
/* until no more joins or clones are produced. Limit this to */
/* avoid an infinite loop. */
for (
i = 1024;
i && ( k = ( icc_do_clones( p_hd ) || icc_do_joins( p_hd ) ) );
i --
);
if ( k ) {
inx_error(
0,
ALEX_TABLE,
ALEX_TOODEEP,
INX_ERROR
);
}
/* Can only produce an iconvtab file if there exist specs ! */
if ( ! (
p_hd->icc_specs->icc_count
|| p_hd->icc_libspecs->icc_count
|| p_hd->icc_loc_alias->icc_count
|| p_hd->icc_loc_codeset->icc_count
|| p_hd->icc_resources->icc_count
) ) {
fprintf( stderr, "Found no specs in input\n" );
exit( 0 );
}
pp_top =
pp_sp = ( ICC_SPEC ** )
inx_alloc( p_hd->icc_specs->icc_count * sizeof( ICC_SPEC * ) );
pp_ls_top =
pp_ls_sp = ( ICC_STDLIBSPEC ** )
inx_alloc( p_hd->icc_libspecs->icc_count * sizeof( ICC_STDLIBSPEC * ) );
nstr = 0;
ICC_SPANEM( ICC_SPEC, p_sp, p_hd->icc_specs ) {
* ( pp_sp ++ ) = p_sp;
if ( maxtable < p_sp->icc_ntable ) {
maxtable = p_sp->icc_ntable;
}
nstr += icc_markused( p_hd->icc_strings, p_sp->icc_from_enc, 1 );
nstr += icc_markused( p_hd->icc_strings, p_sp->icc_to_enc, 1 );
}
a_sp = ( ICONV_S_SPEC * ) inx_alloc( icc_iconv_r_spec_size( maxtable ) );
memset( a_sp, 0, icc_iconv_r_spec_size( maxtable ) );
maxtable = 0;
ICC_SPANEM( ICC_STDLIBSPEC, p_ls_sp, p_hd->icc_libspecs ) {
* ( pp_ls_sp ++ ) = p_ls_sp;
if ( maxtable < ( p_ls_sp->icc_meths->icc_ntable_mbwc + p_ls_sp->icc_meths->icc_ntable_wcmb ) ) {
maxtable = ( p_ls_sp->icc_meths->icc_ntable_mbwc + p_ls_sp->icc_meths->icc_ntable_wcmb );
}
nstr += icc_markused( p_hd->icc_strings, p_ls_sp->icc_from_enc, 1 );
nstr += icc_markused( p_hd->icc_strings, p_ls_sp->icc_to_enc, 1 );
}
a_ls_sp = ( ICONV_S_LSPEC * ) inx_alloc( icc_iconv_r_libspec_size( maxtable ) );
memset( a_ls_sp, 0, icc_iconv_r_libspec_size( maxtable ) );
/* process strings that are used in encodings */
icc_procstr( p_hd, & pp_str, nstr );
qsort(
pp_top,
p_hd->icc_specs->icc_count,
sizeof( * pp_top ),
( icc_qsort_compar ) icc_compar
);
for ( i = p_hd->icc_specs->icc_count, pp_sp = pp_top; i; pp_sp ++, i -- ) {
p_sp = * pp_sp;
p_sp->icc_obj->icc_num = pp_sp - pp_top;
PSPEC( "spec dump", p_sp )
}
qsort(
pp_ls_top,
p_hd->icc_libspecs->icc_count,
sizeof( * pp_ls_top ),
( icc_qsort_compar ) icc_compar
);
for ( i = p_hd->icc_libspecs->icc_count, pp_ls_sp = pp_ls_top; i; pp_ls_sp ++, i -- ) {
p_ls_sp = * pp_ls_sp;
p_ls_sp->icc_obj->icc_num = pp_ls_sp - pp_ls_top;
PLSPEC( "libspec dump", p_ls_sp )
}
/* create arrays for aliases, codesets and resources that will be dumped*/
fix_objs(
p_hd->icc_loc_alias,
( icc_qsort_compar ) icc_strobjcmp_data1,
icc_markstring, 0
);
fix_objs(
p_hd->icc_loc_codeset,
( icc_qsort_compar ) icc_strobjcmp_data1,
icc_markstring, 0
);
fix_objs(
p_hd->icc_resources,
( icc_qsort_compar ) icc_strobjcmp_data1,
icc_markstring, 1
);
pp_obj = p_hd->icc_resources->icc_array;
for ( i = p_hd->icc_resources->icc_count; i > 0; i -- ) {
/* Is it really defined or is it just a reference */
if ( ! ( * pp_obj )->icc_data2 ) {
inx_error(
( * pp_obj )->icc_posi,
ALEX_TABLE,
ALEX_NOT_DEFINED,
INX_LINE | INX_ERROR | INX_EXTRA,
OBJ( ( * pp_obj )->icc_data1 )->icc_data1
);
} else {
icc_prepare_resource(
( ICC_RES_VALUES * ) ( ( * pp_obj )->icc_data2 )
);
}
pp_obj ++;
}
/* Check to make sure no errors are found */
if ( inx_iserror() ) {
exit( 1 );
}
/* Dump data to file - This time we dump it only to get relative */
/* pointers set as well as find size required */
rel = 0;
icc_dump_data(
p_hd, ( char * ) 0, & rel, icc_nulfnc,
pp_top, pp_ls_top, nstr, pp_str, a_sp, a_ls_sp
);
data = inx_alloc( rel );
rel = 0;
icc_dump_data(
p_hd, data, & rel, icc_cpyfnc,
pp_top, pp_ls_top, nstr, pp_str, a_sp, a_ls_sp
);
inx_free( a_sp );
sprintf( fname, "%s.new", filename );
fd = creat( fname, 0444 );
if ( fd < 0 ) {
perror( fname );
exit( 1 );
}
fchmod( fd, 0444 );
if ( rel != write( fd, data, rel ) ) {
perror( fname );
close( fd );
unlink( fname );
exit( 1 );
}
close( fd );
if ( rename( fname, filename ) < 0 ) {
perror( fname );
unlink( fname );
exit( 1 );
}
/* File successfully written ! */
inx_free( data );
return;
} /* end process */
/* ======================================================================== */
/* Type conversion functions */
int icc_cnv_int(
int * p_dst,
ICC_RES_VALUE * p_src
) {
* p_dst = * ( long long * ) p_src->icc_data;
return sizeof( * p_dst );
} /* end icc_cnv_int */
int icc_cnv_longlong(
long long * p_dst,
ICC_RES_VALUE * p_src
) {
* p_dst = * ( long long * ) p_src->icc_data;
return sizeof( * p_dst );
} /* end icc_cnv_longlong */
int icc_cnv_short(
short * p_dst,
ICC_RES_VALUE * p_src
) {
* p_dst = * ( long long * ) p_src->icc_data;
return sizeof( * p_dst );
} /* end icc_cnv_short */
int icc_cnv_byte(
char * p_dst,
ICC_RES_VALUE * p_src
) {
* p_dst = * ( long long * ) p_src->icc_data;
return sizeof( * p_dst );
} /* end icc_cnv_byte */
int icc_cnv_string(
ICC_RELPTR * p_dst,
ICC_RES_VALUE * p_src
) {
ICC_OBJ_TYP * p_obj = * ( ICC_OBJ_TYP ** ) ( p_src->icc_data );
* p_dst = p_obj->icc_robj;
icc_markused( p_obj->icc_objhead, p_obj, 0 );
return sizeof( * p_dst );
} /* end icc_cnv_string */
int icc_cnv_reference(
ICONV_REFER * p_dst,
ICC_RES_VALUE * p_src
) {
ICC_OBJ_TYP * p_obj = * ( ICC_OBJ_TYP ** ) ( p_src->icc_data );
ICC_OBJ_TYP * p_obk;
memset( p_dst, 0, sizeof( *p_dst ) );
if ( ! p_obj->icc_data2 ) { /* FILE */
p_dst->iconv_node_type = ICONV_REFER_FILE;
p_dst->_objs._file.iconv_file_ref = p_obj->icc_robj;
} else { /* SYMBOLS */
p_dst->iconv_node_type = ICONV_REFER_SYMBOL;
p_dst->_objs._symbols.iconv_symbol = p_obj->icc_robj;
p_obk = *(( ICC_OBJ_TYP ** ) ( p_src->icc_data )+1);
p_dst->_objs._symbols.iconv_object = p_obk->icc_robj;
#ifdef TESTDEBUG2
printf( "icc_cnv_reference(): DSO name: %s\n",
OBJ(p_obk->icc_data1)->icc_data1 );
fflush(stdout);
#endif
}
return sizeof( * p_dst );
} /* end icc_cnv_reference */
#define ICC_MAKE_TYPE( B, A, C, D, E ) \
{ (A), (B), sizeof(C), sizeof(D), sizeof(D), ( ICC_CNV_FUNC ) (E) }
#define ICC_MAKE_TYPF( B, A, C, D, E, F ) \
{ (A), (B), sizeof(C), sizeof(D), sizeof(E), ( ICC_CNV_FUNC ) (F) }
typedef long long llong;
ICC_TYPEDEF icc_typetab[] = {
ICC_MAKE_TYPE(
"string", ICC_TYP_STRING, void *,
ICONV_S_RELPTR, icc_cnv_string
),
ICC_MAKE_TYPE( "int64", ICC_TYP_INT, llong, llong, icc_cnv_longlong ),
ICC_MAKE_TYPE( "int32", ICC_TYP_INT, llong, int, icc_cnv_int ),
ICC_MAKE_TYPE( "int", ICC_TYP_INT, llong, int, icc_cnv_int ),
ICC_MAKE_TYPE( "int16", ICC_TYP_INT, llong, short, icc_cnv_short ),
ICC_MAKE_TYPE( "int8", ICC_TYP_INT, llong, int, icc_cnv_byte ),
ICC_MAKE_TYPE( "short", ICC_TYP_INT, llong, short, icc_cnv_short ),
ICC_MAKE_TYPE( "char", ICC_TYP_INT, llong, char, icc_cnv_byte ),
ICC_MAKE_TYPF(
"reference", ICC_TYP_REFER, void *,
ICONV_REFER, ICONV_S_RELPTR,
icc_cnv_reference
),
};
int icc_ntypetab = sizeof( icc_typetab )/sizeof( * icc_typetab );
/* ======== mkresource ================================================ */
/* PURPOSE:
* Complete the resource definition.
*
* RETURNS:
*
*/
void * mkresource(
char * param_name,
ICC_RES_VALUES * p_vvals
) {
ICC_OBJ_TYP * param_name_str = icc_getstr( param_name );
ICC_OBJ_TYP * p_obj;
ICC_HEAD * p_hd = icc_hd;
if ( ! p_vvals ) {
inx_free( param_name );
return 0;
}
/* Find the object to see if it's already defined */
p_obj = icc_findgeneric( p_hd->icc_resources, param_name_str, 0 );
if ( ! p_obj ) {
/* If not found - insert it */
p_obj = icc_insertgeneric(
p_hd->icc_resources, param_name_str, p_vvals
);
} else if ( p_obj->icc_data2 ) {
/* Found and already defined */
ICC_RES_VALUES * p_ovvals = p_obj->icc_data2;
inx_error(
inx_last,
ALEX_TABLE,
ALEX_ALREADY_DEFINED,
INX_LINE | INX_ERROR | INX_EXTRA,
param_name_str->icc_data1
);
inx_error(
p_ovvals->icc_posi,
ALEX_TABLE,
ALEX_ALREADY_HERE,
INX_LINE | INX_INFORM | INX_EXTRA,
param_name_str->icc_data1
);
return 0;
} else {
/* referenced only, */
p_obj->icc_data2 = p_vvals;
}
/* Fill in the defined postion */
p_vvals->icc_posi[ 0 ] = inx_last[ 0 ];
return 0;
} /* end mkresource */
/* ======== mkvalues ================================================== */
/* PURPOSE:
* Create a list of values
*
* RETURNS:
*
*/
void * mkvalues(
ICC_RES_VALUES * p_vvals,
ICC_RES_VALUE * p_vval
) {
/* If there was an error - drop away */
if ( ! p_vval ) {
return 0;
}
/* Make sure we don't trample off the end of the list */
p_vval->icc_next = 0;
/* if this is the first value then create the container */
if ( ! p_vvals ) {
p_vvals = inx_alloc( sizeof( * p_vvals ) );
memset( p_vvals, 0, sizeof( * p_vvals ) );
}
/* Is this the first element ? */
if ( ! p_vvals->icc_tail ) {
p_vvals->icc_head = p_vval;
p_vvals->icc_tail = p_vval;
} else {
p_vvals->icc_tail->icc_next = p_vval;
p_vvals->icc_tail = p_vval;
}
return p_vvals;
} /* end mkvalues */
/* ======== mkvalue_str =============================================== */
/* PURPOSE:
* Convert a string value
*
* RETURNS:
*
*/
void * mkvalue_str(
ICC_TYPEDEF * p_td,
char * ident,
char * value
) {
ICC_OBJ_TYP * p_val = icc_getstr( value );
ICC_RES_VALUE * p_vval;
int i;
if ( p_td && ( p_td->icc_typeid != ICC_TYP_STRING ) ) {
inx_error(
inx_last,
ALEX_TABLE,
ALEX_EXPECT_STRING,
INX_LINE | INX_WARN | INX_EXTRA,
p_val->icc_data1
);
p_td = 0;
}
p_vval = inx_alloc(
i = sizeof( p_val ) + sizeof( * p_vval ) - sizeof( p_vval->icc_data )
);
memset( p_vval, 0, i );
* ( ICC_OBJ_TYP ** ) ( p_vval->icc_data ) = p_val;
p_vval->icc_name = ident;
p_vval->icc_type = p_td;
if ( ! p_td ) {
inx_free( p_vval->icc_name );
inx_free( p_vval );
return 0;
}
return p_vval;
} /* end mkvalue_str */
/* ======== mkvalue_int =============================================== */
/* PURPOSE:
*
*
* RETURNS:
*
*/
void * mkvalue_int(
ICC_TYPEDEF * p_td,
char * ident,
char * value
) {
long long * p_val;
char * readto = 0;
ICC_RES_VALUE * p_vval;
int i;
/* integer type */
if ( p_td && ( p_td->icc_typeid != ICC_TYP_INT ) ) {
inx_error(
inx_last,
ALEX_TABLE,
ALEX_EXPECT_INTEGER,
INX_LINE | INX_WARN | INX_EXTRA,
value
);
p_td = 0;
}
p_vval = inx_alloc(
i = sizeof( * p_val ) + sizeof( * p_vval ) - sizeof( p_vval->icc_data )
);
memset( p_vval, 0, i );
p_val = p_vval->icc_data;
* p_val = strtoll( value, & readto, 0 );
if ( readto == value ) {
inx_error(
inx_last,
ALEX_TABLE,
ALEX_CNV_ERROR,
INX_LINE | INX_WARN | INX_EXTRA,
value
);
}
inx_free( value );
p_vval->icc_name = ident;
p_vval->icc_type = p_td;
if ( ! p_td ) {
inx_free( p_vval->icc_name );
inx_free( p_vval );
return 0;
}
return p_vval;
} /* end mkvalue_int */
/* ======== mkvalue_table =============================================== */
/* PURPOSE:
* Convert a table value
*
* RETURNS:
*
*/
void * mkvalue_table(
ICC_TYPEDEF * p_td,
char * ident,
ICC_OBJ_TYP * table
) {
ICC_OBJ_TYP * p_val = table;
ICC_RES_VALUE * p_vval;
int i;
ICC_OBJ_TYP * p_obj;
ICC_HEAD * p_hd = icc_hd;
if ( p_td && ( p_td->icc_typeid != ICC_TYP_REFER ) ) {
inx_error(
inx_last,
ALEX_TABLE,
ALEX_EXPECT_STRING,
INX_LINE | INX_WARN | INX_EXTRA,
(OBJ(p_val->icc_data1))->icc_data1
);
inx_error(
inx_last,
ALEX_TABLE,
ALEX_EXPECT_STRING,
INX_LINE | INX_WARN | INX_EXTRA,
(OBJ(p_val->icc_data2))->icc_data1
);
p_td = 0;
}
p_vval = inx_alloc(
i = sizeof( * p_vval ) - sizeof( p_vval->icc_data )
+ (sizeof( p_val )*2)
);
memset( p_vval, 0, i );
* ( ICC_OBJ_TYP ** )( p_vval->icc_data ) = p_val;
p_vval->icc_name = ident;
p_vval->icc_type = p_td;
/* I put this in this new function: mkvalue_talble(). I don't know why this code
fragment is not included in existing function: mktable().
*/
if ( p_val->icc_data2 ) {
p_obj = icc_getmkgeneric( p_hd->icc_objects, p_val->icc_data2, 0 );
*( ( (ICC_OBJ_TYP **)(p_vval->icc_data) )+1 ) = p_obj;
#ifdef TESTDEBUG2
printf( "mkvalue_talbe(): DSO name: %s\n",
OBJ((*( ( (ICC_OBJ_TYP **)(p_vval->icc_data) )+1 ))->icc_data1)->icc_data1);
fflush(stdout);
#endif
}
if ( ! p_td ) {
inx_free( p_vval->icc_name );
inx_free( p_vval );
return 0;
}
return p_vval;
} /* end mkvalue_table */
/* ======== icc_find_type_spec ======================================== */
/* PURPOSE:
* Find a type spec.
*
* RETURNS:
* 0 if not found.
* pointer to ICC_TYPEDEF if found
*/
ICC_TYPEDEF * icc_find_type_spec(
char * name
) {
ICC_TYPEDEF * p_td;
int i;
for ( i = icc_ntypetab, p_td = icc_typetab; i > 0; i --, p_td ++ ) {
if ( ! strcmp( p_td->icc_typename, name ) ) {
return p_td;
}
}
return 0;
} /* end icc_find_type_spec */
/* ======== mkchktyp ================================================== */
/* PURPOSE:
* convert a string to a typedef
*
* RETURNS:
* ICC_TYPEDEF
*/
void * mkchktyp(
char * typename
) {
ICC_TYPEDEF * p_td;
p_td = icc_find_type_spec( typename );
if ( ! p_td ) {
inx_error(
inx_last, /* the last position */
ALEX_TABLE,
ALEX_TYPEWRONG,
INX_LINE | INX_ERROR | INX_EXTRA,
typename
);
}
inx_free( typename );
return p_td;
} /* end mkchktyp */
#if TESTDEBUG && 0
static moretest()
{
char ** __iconv_gettable( void );
char ** __mbwc_gettable( void );
char ** ps = __iconv_gettable();
iconv_t pi;
if ( ! ps ) {
perror( "Can't open iconv at all\n" );
return;
}
while ( * ps ) {
fprintf( stderr, "Open - '%s' - '%s' ", ps[ 0 ], ps[ 1 ] );
pi = iconv_open( ps[ 1 ], ps[ 0 ] );
if ( pi == ( iconv_t ) -1 ) {
perror( "Error openeing iconv\n" );
} else {
iconv_close( pi );
}
ps += 2;
}
ps = __mbwc_gettable();
while ( * ps ) {
fprintf( stderr, "Open - '%s' - '%s' ", ps[ 0 ], ps[ 1 ] );
pi = ( void * ) __mbwc_find( ps[ 1 ], ps[ 0 ] );
if ( pi == ( iconv_t ) -1 ) {
perror( "Error openeing mbwc\n" );
}
ps += 2;
}
}
#endif
/* ======== main ====================================================== */
/* PURPOSE:
*
*
* RETURNS:
*
*/
void main( int argc, char ** argv )
{
#if !TESTDEBUG
char * name = ( char * ) ICONV_TABNAME;
#else
char * name = "iconvtab";
ICONV_TABNAME = name;
#endif
icc_init();
if ( ! icc_read_input( argc, argv, & name ) ) {
process( name );
}
#if TESTDEBUG && 0
fflush( stdout );
fflush( stderr );
iconv_test();
moretest();
#endif
exit( 0 );
} /* end main */