#include <stdio.h>
#include "Xlibint.h"
#include "XlcGeneric.h"
static XLCd create (const char *name, XLCdMethods methods);
static Bool initialize (XLCd lcd);
static void destroy (XLCd lcd);
static XLCdPublicMethodsRec genericMethods = {
{ NULL },
{
NULL,
create,
initialize,
destroy,
NULL
}
};
XLCdMethods _XlcGenericMethods = (XLCdMethods) &genericMethods;
static XLCd
create(
const char *name,
XLCdMethods methods)
{
XLCd lcd;
XLCdPublicMethods new;
lcd = (XLCd) Xmalloc(sizeof(XLCdRec));
if (lcd == NULL)
return (XLCd) NULL;
bzero((char *) lcd, sizeof(XLCdRec));
lcd->core = (XLCdCore) Xmalloc(sizeof(XLCdGenericRec));
if (lcd->core == NULL)
goto err;
bzero((char *) lcd->core, sizeof(XLCdGenericRec));
new = (XLCdPublicMethods) Xmalloc(sizeof(XLCdPublicMethodsRec));
if (new == NULL)
goto err;
memcpy(new,methods,sizeof(XLCdPublicMethodsRec));
lcd->methods = (XLCdMethods) new;
return lcd;
err:
Xfree(lcd);
return (XLCd) NULL;
}
static Bool
string_to_encoding(
const char *str,
char *encoding)
{
char *next;
long value;
int base;
while (*str) {
if (*str == '\\') {
switch (*(str + 1)) {
case 'x':
case 'X':
base = 16;
break;
default:
base = 8;
break;
}
value = strtol(str + 2, &next, base);
if (str + 2 != next) {
*((unsigned char *) encoding++) = (unsigned char) value;
str = next;
continue;
}
}
*encoding++ = *str++;
}
*encoding = '\0';
return True;
}
static Bool
string_to_ulong(
const char *str,
unsigned long *value)
{
const char *tmp1 = str;
int base;
if (*tmp1++ != '\\') {
tmp1--;
base = 10;
} else {
switch (*tmp1++) {
case 'x':
base = 16;
break;
case 'o':
base = 8;
break;
case 'd':
base = 10;
break;
default:
return(False);
}
}
*value = (unsigned long) strtol(tmp1, NULL, base);
return(True);
}
static Bool
add_charset(
CodeSet codeset,
XlcCharSet charset)
{
XlcCharSet *new_list;
int num;
if ((num = codeset->num_charsets))
new_list = (XlcCharSet *) Xrealloc(codeset->charset_list,
(num + 1) * sizeof(XlcCharSet));
else
new_list = (XlcCharSet *) Xmalloc(sizeof(XlcCharSet));
if (new_list == NULL)
return False;
new_list[num] = charset;
codeset->charset_list = new_list;
codeset->num_charsets = num + 1;
return True;
}
static CodeSet
add_codeset(
XLCdGenericPart *gen)
{
CodeSet new, *new_list;
int num;
new = (CodeSet) Xmalloc(sizeof(CodeSetRec));
if (new == NULL)
return NULL;
bzero((char *) new, sizeof(CodeSetRec));
if ((num = gen->codeset_num))
new_list = (CodeSet *) Xrealloc(gen->codeset_list,
(num + 1) * sizeof(CodeSet));
else
new_list = (CodeSet *) Xmalloc(sizeof(CodeSet));
if (new_list == NULL)
goto err;
new_list[num] = new;
gen->codeset_list = new_list;
gen->codeset_num = num + 1;
return new;
err:
Xfree(new);
return NULL;
}
static Bool
add_parse_list(
XLCdGenericPart *gen,
EncodingType type,
const char *encoding,
CodeSet codeset)
{
ParseInfo new, *new_list;
char *str;
unsigned char ch;
int num;
str = (char *) Xmalloc(strlen(encoding) + 1);
if (str == NULL)
return False;
strcpy(str, encoding);
new = (ParseInfo) Xmalloc(sizeof(ParseInfoRec));
if (new == NULL)
goto err;
bzero((char *) new, sizeof(ParseInfoRec));
if (gen->mb_parse_table == NULL) {
gen->mb_parse_table = (unsigned char *) Xmalloc(256);
if (gen->mb_parse_table == NULL)
goto err;
bzero((char *) gen->mb_parse_table, 256);
}
if ((num = gen->mb_parse_list_num))
new_list = (ParseInfo *) Xrealloc(gen->mb_parse_list,
(num + 2) * sizeof(ParseInfo));
else {
new_list = (ParseInfo *) Xmalloc(2 * sizeof(ParseInfo));
}
if (new_list == NULL)
goto err;
new_list[num] = new;
new_list[num + 1] = NULL;
gen->mb_parse_list = new_list;
gen->mb_parse_list_num = num + 1;
ch = (unsigned char) *str;
if (gen->mb_parse_table[ch] == 0)
gen->mb_parse_table[ch] = num + 1;
new->type = type;
new->encoding = str;
new->codeset = codeset;
if (codeset->parse_info == NULL)
codeset->parse_info = new;
return True;
err:
Xfree(str);
if (new)
Xfree(new);
return False;
}
static void
free_charset(
XLCd lcd)
{
XLCdGenericPart *gen = XLC_GENERIC_PART(lcd);
ParseInfo *parse_info;
int num;
if (gen->mb_parse_table)
Xfree(gen->mb_parse_table);
if ((num = gen->mb_parse_list_num) > 0) {
for (parse_info = gen->mb_parse_list; num-- > 0; parse_info++) {
if ((*parse_info)->encoding)
Xfree((*parse_info)->encoding);
Xfree(*parse_info);
}
Xfree(gen->mb_parse_list);
}
if ((num = gen->codeset_num) > 0)
Xfree(gen->codeset_list);
}
#define FORWARD (unsigned long)'+'
#define BACKWARD (unsigned long)'-'
static const char *
getscope(
const char *str,
FontScope scp)
{
unsigned long start = 0;
unsigned long end = 0;
unsigned long dest = 0;
unsigned long shift = 0;
unsigned long direction = 0;
sscanf(str,"[\\x%lx,\\x%lx]->\\x%lx", &start, &end, &dest);
if (dest) {
if (dest >= start) {
shift = dest - start;
direction = FORWARD ;
} else {
shift = start - dest;
direction = BACKWARD;
}
}
scp->start = start ;
scp->end = end ;
scp->shift = shift ;
scp->shift_direction
= direction ;
while (*str) {
if (*str == ',' && *(str+1) == '[')
break;
str++;
}
return str+1;
}
static int
count_scopemap(
const char *str)
{
const char *ptr;
int num=0;
for (ptr=str; *ptr; ptr++) {
if (*ptr == ']') {
num++;
}
}
return num;
}
FontScope
_XlcParse_scopemaps(
const char *str,
int *size)
{
int num=0,i;
FontScope scope,sc_ptr;
const char *str_sc;
num = count_scopemap(str);
scope = (FontScope) Xmalloc(num * sizeof(FontScopeRec));
if (scope == NULL)
return NULL;
for (i=0, str_sc=str, sc_ptr=scope; i < num; i++, sc_ptr++) {
str_sc = getscope(str_sc, sc_ptr);
}
*size = num;
return scope;
}
void
_XlcDbg_printValue(
const char *str,
char **value,
int num)
{
}
static void
dmpscope(
const char* name,
FontScope sc,
int num)
{
}
static XlcCharSet
srch_charset_define(
const char *name,
int *new)
{
XlcCharSet charset;
*new = 0;
charset = _XlcGetCharSet(name);
if (charset == NULL &&
(charset = _XlcCreateDefaultCharSet(name, ""))) {
_XlcAddCharSet(charset);
*new = 1;
charset->source = CSsrcXLC;
}
return charset;
}
static void
read_charset_define(
XLCd lcd,
XLCdGenericPart *gen)
{
int i;
char csd[16], cset_name[256];
char name[BUFSIZ];
XlcCharSet charsetd;
char **value;
int num, new;
XlcSide side = XlcUnknown;
char *tmp;
for (i=0; ; i++) {
charsetd = 0;
sprintf(csd, "csd%d", i);
sprintf(name, "%s.%s", csd, "charset_name");
_XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num);
_XlcDbg_printValue(name,value,num);
if (num > 0) {
strncpy(cset_name,value[0], sizeof cset_name - 1);
cset_name[(sizeof cset_name) - 1] = '\0';
sprintf(name, "%s.%s", csd , "side");
_XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num);
if (num > 0) {
_XlcDbg_printValue(name,value,num);
if (!_XlcNCompareISOLatin1(value[0], "none", 4)) {
side = XlcGLGR;
} else if (!_XlcNCompareISOLatin1(value[0], "GL", 2)) {
side = XlcGL;
strcat(cset_name,":GL");
} else {
side = XlcGR;
strcat(cset_name,":GR");
}
if (charsetd == NULL &&
(charsetd = srch_charset_define(cset_name,&new)) == NULL)
return;
}
} else {
if (i == 0)
continue;
else
break;
}
if (new) {
tmp = (char *)Xmalloc(strlen(cset_name)+1);
if (tmp == NULL)
return;
strcpy(tmp,cset_name);
charsetd->name = tmp;
}
charsetd->side = side ;
sprintf(name, "%s.%s", csd, "length");
_XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num);
if (num > 0) {
_XlcDbg_printValue(name,value,num);
charsetd->char_size = atoi(value[0]);
}
sprintf(name, "%s.%s", csd, "gc_number");
_XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num);
if (num > 0) {
_XlcDbg_printValue(name,value,num);
charsetd->set_size = atoi(value[0]);
}
sprintf(name, "%s.%s", csd, "string_encoding");
_XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num);
if (num > 0) {
_XlcDbg_printValue(name,value,num);
if (!strcmp("False",value[0])) {
charsetd->string_encoding = False;
} else {
charsetd->string_encoding = True;
}
}
sprintf(name, "%s.%s", csd, "sequence");
_XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num);
if (num > 0) {
_XlcDbg_printValue(name,value,num);
tmp = (char *)Xmalloc(strlen(value[0])+1);
if (tmp == NULL)
return;
charsetd->ct_sequence = tmp;
string_to_encoding(value[0],tmp);
}
sprintf(name, "%s.%s", csd, "encoding_name");
_XlcGetResource(lcd, "XLC_CHARSET_DEFINE", name, &value, &num);
if (num > 0) {
_XlcDbg_printValue(name,value,num);
tmp = (char *)Xmalloc(strlen(value[0])+1);
strcpy(tmp,value[0]);
charsetd->encoding_name = tmp;
charsetd->xrm_encoding_name = XrmStringToQuark(tmp);
}
_XlcAddCT(charsetd->name, charsetd->ct_sequence);
}
}
static SegConv
add_conversion(
XLCdGenericPart *gen)
{
SegConv new_list;
int num;
if ((num = gen->segment_conv_num) > 0) {
new_list = (SegConv) Xrealloc(gen->segment_conv,
(num + 1) * sizeof(SegConvRec));
} else {
new_list = (SegConv) Xmalloc(sizeof(SegConvRec));
}
if (new_list == NULL)
return NULL;
gen->segment_conv = new_list;
gen->segment_conv_num = num + 1;
return &new_list[num];
}
static void
read_segmentconversion(
XLCd lcd,
XLCdGenericPart *gen)
{
int i;
char conv[16];
char name[BUFSIZ];
char **value;
int num,new;
SegConv conversion;
for (i=0 ; ; i++) {
conversion = 0;
sprintf(conv, "conv%d", i);
sprintf(name, "%s.%s", conv, "length");
_XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num);
if (num > 0) {
if (conversion == NULL &&
(conversion = add_conversion(gen)) == NULL) {
return;
}
_XlcDbg_printValue(name,value,num);
} else {
if (i == 0)
continue;
else
break;
}
conversion->length = atoi(value[0]);
sprintf(name, "%s.%s", conv, "source_encoding");
_XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num);
if (num > 0) {
char *tmp;
_XlcDbg_printValue(name,value,num);
tmp = (char *)Xmalloc(strlen(value[0])+1);
if (tmp == NULL)
return;
strcpy(tmp,value[0]);
conversion->source_encoding = tmp;
conversion->source = srch_charset_define(tmp,&new);
}
sprintf(name, "%s.%s", conv, "destination_encoding");
_XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num);
if (num > 0) {
char *tmp;
_XlcDbg_printValue(name,value,num);
tmp = (char *)Xmalloc(strlen(value[0])+1);
if (tmp == NULL)
return;
strcpy(tmp,value[0]);
conversion->destination_encoding = tmp;
conversion->dest = srch_charset_define(tmp,&new);
}
sprintf(name, "%s.%s", conv, "range");
_XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num);
if (num > 0) {
_XlcDbg_printValue(name,value,num);
sscanf(value[0],"\\x%lx,\\x%lx",
&(conversion->range.start), &(conversion->range.end));
}
sprintf(name, "%s.%s", conv, "conversion");
_XlcGetResource(lcd, "XLC_SEGMENTCONVERSION", name, &value, &num);
if (num > 0) {
_XlcDbg_printValue(name,value,num);
conversion->conv =
_XlcParse_scopemaps(value[0],&conversion->conv_num);
}
}
}
static ExtdSegment
create_ctextseg(
char **value,
int num)
{
ExtdSegment ret;
char* ptr;
char* cset_name = NULL;
int i,new;
FontScope scope;
ret = (ExtdSegment)Xmalloc(sizeof(ExtdSegmentRec));
if (ret == NULL)
return NULL;
ret->name = (char *)Xmalloc(strlen(value[0]) + 1);
if (ret->name == NULL) {
Xfree (ret);
return NULL;
}
strcpy(ret->name,value[0]);
cset_name = (char*) Xmalloc (strlen(ret->name) + 1);
if (cset_name == NULL) {
Xfree (ret->name);
Xfree (ret);
return NULL;
}
if (strchr(value[0],':')) {
ptr = strchr(ret->name,':');
*ptr = '\0';
ptr++;
if (!_XlcNCompareISOLatin1(ptr, "GL", 2)) {
ret->side = XlcGL;
sprintf(cset_name,"%s:%s",ret->name,"GL");
} else {
ret->side = XlcGR;
sprintf(cset_name,"%s:%s",ret->name,"GR");
}
} else {
ret->side = XlcGLGR;
strcpy(cset_name,ret->name);
}
ret->area = (FontScope)Xmalloc((num - 1)*sizeof(FontScopeRec));
if (ret->area == NULL) {
Xfree (cset_name);
Xfree (ret->name);
Xfree (ret);
return NULL;
}
ret->area_num = num - 1;
scope = ret->area ;
for (i = 1; i < num; i++) {
sscanf(value[i],"\\x%lx,\\x%lx",
&scope[i-1].start, &scope[i-1].end);
}
ret->charset = srch_charset_define(cset_name,&new);
Xfree (cset_name);
return ret;
}
static Bool
load_generic(
XLCd lcd)
{
XLCdGenericPart *gen = XLC_GENERIC_PART(lcd);
char **value;
int num;
unsigned long l;
int i;
int M,ii;
XlcCharSet charset;
gen->codeset_num = 0;
_XlcGetResource(lcd, "XLC_XLOCALE", "wc_encoding_mask", &value, &num);
if (num > 0) {
if (string_to_ulong(value[0], &l) == False)
goto err;
gen->wc_encode_mask = l;
}
_XlcGetResource(lcd, "XLC_XLOCALE", "wc_shift_bits", &value, &num);
if (num > 0)
gen->wc_shift_bits = atoi(value[0]);
if (gen->wc_shift_bits < 1)
gen->wc_shift_bits = 8;
_XlcGetResource(lcd, "XLC_XLOCALE", "use_stdc_env", &value, &num);
if (num > 0 && !_XlcCompareISOLatin1(value[0], "True"))
gen->use_stdc_env = True;
else
gen->use_stdc_env = False;
_XlcGetResource(lcd, "XLC_XLOCALE", "force_convert_to_mb", &value, &num);
if (num > 0 && !_XlcCompareISOLatin1(value[0], "True"))
gen->force_convert_to_mb = True;
else
gen->force_convert_to_mb = False;
for (i = 0; ; i++) {
CodeSetRec *codeset = NULL;
char cs[16];
char name[BUFSIZ];
sprintf(cs, "cs%d", i);
sprintf(name, "%s.%s", cs , "side");
_XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
if (num > 0) {
char *tmp;
if (codeset == NULL && (codeset = add_codeset(gen)) == NULL)
goto err;
if (!_XlcNCompareISOLatin1(value[0], "none", 4)) {
codeset->side = XlcNONE;
} else if (!_XlcNCompareISOLatin1(value[0], "GL", 2)) {
codeset->side = XlcGL;
} else {
codeset->side = XlcGR;
}
tmp = strrchr(value[0], ':');
if (tmp != NULL && !_XlcCompareISOLatin1(tmp + 1, "Default")) {
if (codeset->side == XlcGR)
gen->initial_state_GR = codeset;
else
gen->initial_state_GL = codeset;
}
}
sprintf(name, "%s.%s", cs , "length");
_XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
if (num > 0) {
if (codeset == NULL && (codeset = add_codeset(gen)) == NULL)
goto err;
codeset->length = atoi(value[0]);
if (codeset->length < 1)
codeset->length = 1;
}
sprintf(name, "%s.%s", cs, "mb_encoding");
_XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
if (num > 0) {
static struct {
const char *str;
EncodingType type;
} shifts[] = {
{"<SS>", E_SS},
{"<LSL>", E_LSL},
{"<LSR>", E_LSR},
{0}
};
int j;
if (codeset == NULL && (codeset = add_codeset(gen)) == NULL)
goto err;
for ( ; num-- > 0; value++) {
char encoding[256];
char *tmp = *value;
EncodingType type = E_SS;
for (j = 0; shifts[j].str; j++) {
if (!_XlcNCompareISOLatin1(tmp, shifts[j].str,
strlen(shifts[j].str))) {
type = shifts[j].type;
tmp += strlen(shifts[j].str);
break;
}
}
if (strlen (tmp) > sizeof encoding ||
string_to_encoding(tmp, encoding) == False)
goto err;
add_parse_list(gen, type, encoding, codeset);
}
}
sprintf(name, "%s.%s", cs, "wc_encoding");
_XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
if (num > 0) {
if (codeset == NULL && (codeset = add_codeset(gen)) == NULL)
goto err;
if (string_to_ulong(value[0], &l) == False)
goto err;
codeset->wc_encoding = l;
}
sprintf(name, "%s.%s", cs, "ct_encoding");
_XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
if (num > 0) {
char *encoding;
if (codeset == NULL && (codeset = add_codeset(gen)) == NULL)
goto err;
for ( ; num-- > 0; value++) {
if (strlen (*value) > sizeof name)
goto err;
string_to_encoding(*value, name);
charset = NULL;
if ((encoding = strchr(name, ':')) &&
(encoding = strchr(encoding + 1, ':'))) {
*encoding++ = '\0';
charset = _XlcAddCT(name, encoding);
}
if (charset == NULL) {
charset = _XlcGetCharSet(name);
if (charset == NULL &&
(charset = _XlcCreateDefaultCharSet(name, ""))) {
charset->side = codeset->side;
charset->char_size = codeset->length;
_XlcAddCharSet(charset);
}
}
if (charset) {
if (add_charset(codeset, charset) == False)
goto err;
}
}
}
if (codeset == NULL)
break;
codeset->cs_num = i;
for (M=1; M-1 < codeset->length; M++) {
unsigned long start,end;
ByteInfo tmpb;
sprintf(name,"%s.%s%d",cs,"byte",M);
_XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
if (M == 1) {
if (num < 1) {
codeset->byteM = NULL;
break ;
}
codeset->byteM =
(ByteInfoListRec *)Xmalloc(
(codeset->length)*sizeof(ByteInfoListRec));
if (codeset->byteM == NULL) {
goto err;
}
}
if (num > 0) {
_XlcDbg_printValue(name,value,num);
(codeset->byteM)[M-1].M = M;
(codeset->byteM)[M-1].byteinfo_num = num;
(codeset->byteM)[M-1].byteinfo =
(ByteInfo)Xmalloc( num * sizeof(ByteInfoRec));
for (ii = 0 ; ii < num ; ii++) {
tmpb = (codeset->byteM)[M-1].byteinfo ;
sscanf(value[ii],"\\x%lx,\\x%lx",&start,&end);
tmpb[ii].start = (unsigned char)start;
tmpb[ii].end = (unsigned char)end;
}
}
}
sprintf(name, "%s.%s", cs, "mb_conversion");
_XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
if (num > 0) {
_XlcDbg_printValue(name,value,num);
codeset->mbconv = Xmalloc(sizeof(ConversionRec));
codeset->mbconv->convlist =
_XlcParse_scopemaps(value[0],&(codeset->mbconv->conv_num));
dmpscope("mb_conv",codeset->mbconv->convlist,
codeset->mbconv->conv_num);
}
sprintf(name, "%s.%s", cs, "ct_conversion");
_XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
if (num > 0) {
_XlcDbg_printValue(name,value,num);
codeset->ctconv = Xmalloc(sizeof(ConversionRec));
codeset->ctconv->convlist =
_XlcParse_scopemaps(value[0],&(codeset->ctconv->conv_num));
dmpscope("ctconv",codeset->ctconv->convlist,
codeset->ctconv->conv_num);
}
sprintf(name, "%s.%s", cs, "ct_conversion_file");
_XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
if (num > 0) {
_XlcDbg_printValue(name,value,num);
}
sprintf(name, "%s.%s", cs, "ct_extended_segment");
_XlcGetResource(lcd, "XLC_XLOCALE", name, &value, &num);
if (num > 0) {
_XlcDbg_printValue(name,value,num);
codeset->ctextseg = create_ctextseg(value,num);
}
}
read_charset_define(lcd,gen);
read_segmentconversion(lcd,gen);
if (gen->initial_state_GL == NULL) {
CodeSetRec *codeset;
for (i = 0; i < gen->codeset_num; i++) {
codeset = gen->codeset_list[i];
if (codeset->side == XlcGL)
gen->initial_state_GL = codeset;
}
}
if (gen->initial_state_GR == NULL) {
CodeSetRec *codeset;
for (i = 0; i < gen->codeset_num; i++) {
codeset = gen->codeset_list[i];
if (codeset->side == XlcGR)
gen->initial_state_GR = codeset;
}
}
for (i = 0; i < gen->codeset_num; i++) {
CodeSetRec *codeset = gen->codeset_list[i];
for (ii = 0; ii < codeset->num_charsets; ii++) {
charset = codeset->charset_list[ii];
if (! strcmp(charset->encoding_name, "ISO8859-1"))
charset->string_encoding = True;
if ( charset->string_encoding )
codeset->string_encoding = True;
}
}
return True;
err:
free_charset(lcd);
return False;
}
#ifdef USE_DYNAMIC_LC
static Bool
initialize_core(
XLCd lcd)
{
_XInitDynamicOM(lcd);
_XInitDynamicIM(lcd);
return True;
}
#endif
static Bool
initialize(lcd)
XLCd lcd;
{
XLCdPublicMethods superclass = (XLCdPublicMethods) _XlcPublicMethods;
XLC_PUBLIC_METHODS(lcd)->superclass = superclass;
if (superclass->pub.initialize) {
if ((*superclass->pub.initialize)(lcd) == False)
return False;
}
#ifdef USE_DYNAMIC_LC
if (initialize_core(lcd) == False)
return False;
#endif
if (load_generic(lcd) == False)
return False;
return True;
}
static void
freeByteM(
CodeSet codeset)
{
int i;
ByteInfoList blst;
if (codeset->byteM == NULL) {
return ;
}
blst = codeset->byteM;
for (i = 0; i < codeset->length; i++) {
if (blst[i].byteinfo) {
Xfree(blst[i].byteinfo);
blst[i].byteinfo = NULL;
}
}
Xfree(codeset->byteM);
codeset->byteM = NULL;
}
static void
freeConversion(
CodeSet codeset)
{
Conversion mbconv,ctconv;
if (codeset->mbconv) {
mbconv = codeset->mbconv;
if (mbconv->convlist) {
Xfree(mbconv->convlist);
mbconv->convlist = NULL;
}
Xfree(mbconv);
codeset->mbconv = NULL;
}
if (codeset->ctconv) {
ctconv = codeset->ctconv;
if (ctconv->convlist) {
Xfree(ctconv->convlist);
ctconv->convlist = NULL;
}
Xfree(ctconv);
codeset->ctconv = NULL;
}
}
static void
freeExtdSegment(
CodeSet codeset)
{
ExtdSegment ctextseg;
if (codeset->ctextseg == NULL) {
return;
}
ctextseg = codeset->ctextseg;
if (ctextseg->name) {
Xfree(ctextseg->name);
ctextseg->name = NULL;
}
if (ctextseg->area) {
Xfree(ctextseg->area);
ctextseg->area = NULL;
}
Xfree(codeset->ctextseg);
codeset->ctextseg = NULL;
}
static void
freeParseInfo(
CodeSet codeset)
{
ParseInfo parse_info;
if (codeset->parse_info == NULL) {
return;
}
parse_info = codeset->parse_info;
if (parse_info->encoding) {
Xfree(parse_info->encoding);
parse_info->encoding = NULL;
}
Xfree(codeset->parse_info);
codeset->parse_info = NULL;
}
static void
destroy_CodeSetList(
XLCdGenericPart *gen)
{
CodeSet *codeset = gen->codeset_list;
int i;
if (gen->codeset_num == 0) {
return;
}
for (i=0;i<gen->codeset_num;i++) {
freeByteM(codeset[i]);
freeConversion(codeset[i]);
freeExtdSegment(codeset[i]);
freeParseInfo(codeset[i]);
if (codeset[i]->charset_list) {
Xfree(codeset[i]->charset_list);
codeset[i]->charset_list = NULL;
}
Xfree(codeset[i]); codeset[i]=NULL;
}
Xfree(codeset); gen->codeset_list = NULL;
}
static void
destroy_SegConv(
XLCdGenericPart *gen)
{
SegConv seg = gen->segment_conv;
int i;
if (gen->segment_conv_num == 0) {
return;
}
for (i=0;i<gen->segment_conv_num;i++) {
if (seg[i].source_encoding) {
Xfree(seg[i].source_encoding);
seg[i].source_encoding = NULL;
}
if (seg[i].destination_encoding) {
Xfree(seg[i].destination_encoding);
seg[i].destination_encoding = NULL;
}
if (seg[i].conv) {
Xfree(seg[i].conv); seg[i].conv = NULL;
}
}
Xfree(seg); gen->segment_conv = NULL;
}
static void
destroy_gen(
XLCd lcd)
{
XLCdGenericPart *gen = XLC_GENERIC_PART(lcd);
destroy_SegConv(gen);
destroy_CodeSetList(gen);
if (gen->mb_parse_table) {
Xfree(gen->mb_parse_table);
gen->mb_parse_table = NULL;
}
if (gen->mb_parse_list) {
Xfree(gen->mb_parse_list);
gen->mb_parse_list = NULL;
}
}
static void
destroy(
XLCd lcd)
{
XLCdPublicMethods superclass = XLC_PUBLIC_METHODS(lcd)->superclass;
destroy_gen(lcd);
if (superclass && superclass->pub.destroy)
(*superclass->pub.destroy)(lcd);
}