#include "fliconv.h" #include #include "std.h" #include "lpc_incl.h" #include "comm.h" #ifdef USE_ICONV struct translation *head; static struct translation *find_translator(const char *encoding){ struct translation *cur = head; while(cur){ if(!strcmp(cur->name, encoding)) break; cur = cur->next; } return cur; } struct translation *get_translator(const char *encoding){ struct translation *ret = find_translator(encoding); if(ret) return ret; ret = (struct translation *)MALLOC(sizeof(struct translation)); char *name = (char *)MALLOC(strlen(encoding)+18+1); strcpy(name, encoding); #ifdef linux strcat(name, "//TRANSLIT//IGNORE"); #endif ret->name = name; ret->incoming = iconv_open("UTF-8", encoding); ret->outgoing = iconv_open(name, "UTF-8"); ret->next = 0; if(ret->incoming == (iconv_t)-1 || ret->outgoing == (iconv_t)-1){ FREE(name); FREE(ret); return 0; } name[strlen(encoding)] = 0; if(!head) head = ret; else { struct translation *cur = head; while(cur->next) cur = cur->next; cur->next = ret; } return ret; } char *translate(iconv_t tr, const char *mes, int inlen, int *outlen){ size_t len = inlen; size_t len2; unsigned char *tmp = (unsigned char *)mes; static char *res = 0; static size_t reslen = 0; char *tmp2; if(!res){ res = (char *)MALLOC(1); reslen = 1; } tmp2 = res; len2 = reslen; while(len){ iconv(tr, (char **)&tmp, &len, &tmp2, &len2); #ifdef PACKAGE_DWLIB if(len > 1 && tmp[0] == 0xff && tmp[1] == 0xf9){ len -=2; tmp +=2; #else if(0){ #endif } else { if(E2BIG == errno){ errno = 0; tmp = (unsigned char *)mes; len = strlen(mes)+1; FREE(res); reslen *= 2; res = (char *)MALLOC(reslen); tmp2 = res; len2 = reslen; continue; } tmp2[0] = 0; *outlen = reslen - len2; return res; } } *outlen = reslen - len2; return res; } #else char *translate(iconv_t tr, const char *mes, int inlen, int *outlen){ *outlen = inlen; return (char *)mes; } #endif char *translate_easy(iconv_t tr, char *mes){ int dummy; char *res = translate(tr, mes, strlen(mes)+1, &dummy); return res; } #ifdef F_SET_ENCODING void f_set_encoding(){ if(current_object->interactive){ struct translation *newt = get_translator((char *)sp->u.string); if(newt){ current_object->interactive->trans = newt; return; } } pop_stack(); push_number(0); } #endif #ifdef F_TO_UTF8 void f_to_utf8(){ struct translation *newt = get_translator((char *)sp->u.string); pop_stack(); if(!newt) error("unknown encoding"); char *text = (char *)sp->u.string; char *translated = translate_easy(newt->incoming, text); pop_stack(); copy_and_push_string(translated); } #endif #ifdef F_UTF8_TO void f_utf8_to(){ struct translation *newt = get_translator((char *)sp->u.string); pop_stack(); if(!newt) error("unknown encoding"); char *text = (char *)sp->u.string; char *translated = translate_easy(newt->outgoing, text); pop_stack(); copy_and_push_string(translated); } #endif #ifdef F_STR_TO_ARR void f_str_to_arr(){ static struct translation *newt = 0; if(!newt){ newt = get_translator("UTF-32"); translate_easy(newt->outgoing, " "); } int len; int *trans = (int *)translate(newt->outgoing, sp->u.string, SVALUE_STRLEN(sp)+1, &len); len/=4; array_t *arr = allocate_array(len); while(len--) arr->item[len].u.number = trans[len]; free_svalue(sp, "str_to_arr"); put_array(arr); } #endif #ifdef F_ARR_TO_STR void f_arr_to_str(){ static struct translation *newt = 0; if(!newt){ newt = get_translator("UTF-32"); } int len = sp->u.arr->size; int *in = (int *)MALLOC(sizeof(int)*(len+1)); char *trans; in[len] = 0; while(len--) in[len] = sp->u.arr->item[len].u.number; trans = translate(newt->incoming, (char *)in, (sp->u.arr->size+1)*4, &len); FREE(in); pop_stack(); copy_and_push_string(trans); } #endif #ifdef F_STRWIDTH void f_strwidth(){ int len = SVALUE_STRLEN(sp); int width = 0; int i; for(i=0; iu.string[i]) & 0xc0) == 0x80); pop_stack(); push_number(width); } #endif