Login
User Name:

Password:



Register

Forgot your password?
Hi - Clean SmaugFuss map/description issue..
Dec 15, 2024 7:29 pm
By Samson
AFKMud 2.2.4
Dec 10, 2024 4:09 pm
By Samson
I3 and IMC
Dec 8, 2024 6:35 pm
By Remcon
Ubuntu 22.04.5 LTS
Dec 5, 2024 5:10 pm
By Remcon
SmaugFUSS 1.8/1.9
Nov 29, 2024 11:46 am
By Remcon
SWFOTEFUSS 1.5.1
Author: Various
Submitted by: Samson
SWRFUSS 1.4.1
Author: Various
Submitted by: Samson
SmaugFUSS 1.9.5
Author: Various
Submitted by: Samson
AFKMud 2.2.4
Author: AFKMud Team
Submitted by: Samson
LOP 1.5
Author: Remcon
Submitted by: Remcon
Users Online
Google, Bing

Members: 0
Guests: 11
Stats
Files
Topics
Posts
Members
Newest Member
494
3,808
19,707
588
Mortrex

Today's Birthdays
There are no member birthdays today.
» SmaugMuds » Codebases » SmaugFUSS » SmaugFuss with support for Ru...
Forum Rules | Mark all | Recent Posts

SmaugFuss with support for Russian characters
< Newer Topic :: Older Topic >

Pages:<< prev 1 next >>
Post is unread #1 Mar 11, 2024 6:50 am   Last edited Mar 11, 2024 6:59 am by Voldemar
Go to the top of the page
Go to the bottom of the page

Voldemar

GroupMembers
Posts5
JoinedMar 11, 2024

 
Hello everyone. Who will help add support for Russian characters in KOI8 or Win1251 encoding to Smaugfuss?

Post is unread #2 Mar 13, 2024 3:39 am   
Go to the top of the page
Go to the bottom of the page

Voldemar

GroupMembers
Posts5
JoinedMar 11, 2024

 
as I understand it, no one can help, at least tell me in which direction to move?

Post is unread #3 Mar 13, 2024 5:12 pm   
Go to the top of the page
Go to the bottom of the page

Remcon

GroupAdministrators
Posts1,946
JoinedJul 26, 2005

 
are you talking about what is input by players?

Post is unread #4 Mar 14, 2024 1:19 am   
Go to the top of the page
Go to the bottom of the page

Voldemar

GroupMembers
Posts5
JoinedMar 11, 2024

 
yes, this engine does not understand Russian letters because they are simply not in UTF encoding) as an example, if I write say hello, then everything is fine, but if I write say Привет (hello on russian), it no longer works does not accept Russian characters

Post is unread #5 Mar 14, 2024 1:23 am   
Go to the top of the page
Go to the bottom of the page

Voldemar

GroupMembers
Posts5
JoinedMar 11, 2024

 
I found old files to solve this problem, but there is one problem, for version 1.9 I don’t have enough experience to add it, and in version 1.6 everything will work, but the engine crashes when trying to start with memory leaks


CODEPAGES snippet by Pihhan (pihhan@atlas.cz)

What it does?
Described in codepage.c

Terms of use:
- You sould send me mail that you are using my snippet
- My name must be in codepage.c as author
- nothing else!

How to install:
- add codepage.c and codepage.o into Makefile, where others files are
- add -DCODEPAGES to compiler options in Makefile
- follow instructions and update your source
- make clean, make smaug
- copy codepage.dat and convert.dat into your (mud's) system directory
- if you have not enough codepages, you can make your own convert.dat
by compiling convertor.c and using do.all script

How to unistall:
if you installed all well (and if I wrote it well, I hope I did),
only remove -DCODEPAGES from compiler options and do make clean

in act_comm.c: in translate() about line 184:
CHANGE:
*pbuf2 = lng->alphabet[LOWER(*pbuf) - 'a'];
TO:
#ifdef CODEPAGES
*pbuf2 = lng->alphabet[CHAR_TO_ASCII(LOWER(*pbuf)) - 'a'];
#else
*pbuf2 = lng->alphabet[LOWER(*pbuf) - 'a'];
#endif

in comm.c:
in game_loop() about line 703:
BEFORE:
nanny( d, cmdline );
break;
case CON_PLAYING:
interpret( d->character, cmdline );

ADD:
#ifdef CODEPAGES
/* At login is most telnet commands, we dont know user's charset.
* It is better not allow players to have names or passwords high-ascii, */
strcpy( cmdline, cp_ascii_only(cmdline));
#endif

in init_decriptor() about line 854:
AFTER:
dnew->user = STRALLOC("unknown");
dnew->newstate = 0;
dnew->prevcolor = 0x07;
ADD:
#ifdef CODEPAGES
dnew->cp = cp_default;
#endif

in read_from_buffer() about line 1284:

CHANGE:
if ( d->inbuf[i] == '\b' && k > 0 ) /* BackSpace key */
--k;
else if ( isascii(d->inbuf[i]) && isprint(d->inbuf[i]) )
d->incomm[k++] = d->inbuf[i];
}

TO:

if ( d->inbuf[i] == '\b' && k > 0 ) /* BackSpace key */
--k;
#ifdef CODEPAGES
/* It will change letters from table to table value. It is a little slower,
but it is needed for using different charsets. It changes only newly
received chars. Changes it from user's charset to MUD's default charset.
Telnet commands will be filtered out.
-Pihhan */
else if ( IS_PRINT(d->inbuf[i])
&& (IS_ASCII(d->inbuf[i]) || IS_ALNUM(d->inbuf[i])) ) {
if ( d->inbuf[i] == '\xFF' ) {
int c;

++i;
c = (unsigned) d->inbuf[i];
if ( c==WILL || c==WONT || c==DO || c==DONT ) ++i;
} else
d->incomm[k++] = (char) d->cp->in->table[ (unsigned char) d->inbuf[i] ];
}
#else
/* original */
else if ( isascii(d->inbuf[i]) && isprint(d->inbuf[i]) )
d->incomm[k++] = d->inbuf[i];
#endif
}

in write_to_buffer() about line 1472:
AFTER:
/*
* Append onto an output buffer.
*/
void write_to_buffer( DESCRIPTOR_DATA *d, const char *txt, int length )
{

ADD:

#ifdef CODEPAGES
int i,c=0;
#endif

in write_to_buffer() about line 1531:

CHANGE:
/*
* Copy.
*/
strncpy( d->outbuf + d->outtop, txt, length );

TO:

/*
* Copy.
*/
#ifdef CODEPAGES
/* Before sending data, it will be changed to right values of user's charset.
It translates from MUD's default cp to user's. Leaves telnet commands
unchanged -Pihhan */
for ( i=0; i if ( *txt == '\xFF' ) {
d->outbuf[d->outtop++] = *txt;
++txt;++i;
c = (unsigned) *txt;
if ( c==WILL || c==WONT || c==DO || c==DONT ) {
d->outbuf[d->outtop++] = *txt;
++txt;++i;
}
d->outbuf[d->outtop++] = *txt;
} else d->outbuf[d->outtop++] = (char) d->cp->out->table[ (unsigned char) *txt ];
}
#else
strncpy( d->outbuf + d->outtop, txt, length );
#endif


in db.c: in db_boot() about line 348:

AFTER:
fpArea = NULL;
show_hash( 32 );
unlink( BOOTLOG_FILE );
boot_log( "---------------------[ Boot Log ]--------------------" );

ADD:

#ifdef CODEPAGES
/* loading commands before it set valid codepage. I think it can be ok. */
log_string("Loading codepages.");
load_codepages();
#endif

in str_cmp(): about line 3920:
CHANGE:
for ( ; *astr || *bstr; astr++, bstr++ )
{
if ( LOWER(*astr) != LOWER(*bstr) )
return TRUE;
}

TO:

#ifdef CODEPAGES
/* for well working str_cmp must be an astr ansi or ascii, bstr always ansi!
this allows users with ascii to take objects with high-ascii name */
if ( LOWER(*astr) != LOWER(*bstr)
&& LOWER(*astr) != CHAR_TO_ASCII(LOWER(*bstr)) )
#else
if ( LOWER(*astr) != LOWER(*bstr) )
#endif
return TRUE;
}


in str_prefix() about line 3997:
CHANGE:

for ( ; *astr; astr++, bstr++ )
{
if ( LOWER(*astr) != LOWER(*bstr) )
return TRUE;
}

TO:

for ( ; *astr; astr++, bstr++ )
{
#ifdef CODEPAGES
/* allows users with ascii only to do everything that others can do.
* astr can be ascii/ansi, bstr must be ansi! */
if ( LOWER(*astr) != LOWER(*bstr)
&& LOWER(*astr) != CHAR_TO_ASCII(LOWER(*bstr)) )
#else
if ( LOWER(*astr) != LOWER(*bstr) )
#endif
return TRUE;
}

AFTER str_prefix() about line 4000:
ADD:

#ifdef CODEPAGES
/*
* Compare strings, case insensitive, for prefix matching.
* Return TRUE if astr not a prefix of bstr
* (compatibility with historical functions).
* astr have to be 8bit string, bstr ascii or 8bit. (bstr from input)
*/
bool str_prefix2( const char *astr, const char *bstr )
{
if ( !astr )
{
bug( "Str_prefix2: null astr." );
return TRUE;
}

if ( !bstr )
{
bug( "Str_prefix2: null bstr." );
return TRUE;
}

for ( ; *astr; astr++, bstr++ )
{
/* as in str_prefix, but the longer string is from input(ascii or ansi) */
if ( LOWER(*astr) != LOWER(*bstr)
&& CHAR_TO_ASCII(LOWER(*astr)) != LOWER(*bstr) )
return TRUE;
}

return FALSE;
}
#endif


in save.c: in fwrite_char() about line 317:

ABOVE:
if ( ch->description[0] != '\0' )
fprintf( fp, "Description %s~\n", ch->description );
fprintf( fp, "Sex %d\n", ch->sex );
fprintf( fp, "Class %d\n", ch->class );
fprintf( fp, "Race %d\n", ch->race );

ADD:
#ifdef CODEPAGES
if ( ch->desc && ch->desc->cp != cp_default )
fprintf( fp, "Codepage %s~\n", ch->desc->cp->name );
#endif

/* In fact, it does not matter where it is, but it should be here */

in fread_char() about line 1277:
UNDER:
KEY( "Class", ch->class, fread_number( fp ) );

ADD:
#ifdef CODEPAGES
if ( !str_cmp( word, "Codepage" ) )
{
CODEPAGE_DATA *cp;
fMatch = TRUE;
line = fread_string_nohash( fp );
/* Typing password must be without translating, do not change --Pihhan */
if ( preload ) {
DISPOSE( line );
break;
}
if (!(cp = get_codepage( line ))) {
bug("Player %s has invalid codepage %s.",ch->name,line);
}
else if ( ch->desc ) ch->desc->cp = cp;
DISPOSE( line );
break;
}
#endif

in tables.c: in skill_function() about line 260:
AFTER:

if ( !str_cmp( name, "do_councils" )) return do_councils;
if ( !str_cmp( name, "do_counciltalk" )) return do_counciltalk;
if ( !str_cmp( name, "do_credits" )) return do_credits;
if ( !str_cmp( name, "do_cset" )) return do_cset;

ADD:

#ifdef CODEPAGES
if ( !str_cmp( name, "do_cpedit" )) return do_cpedit;
#endif

in skill_function() about line 421:
AFTER:
case 'k':
if ( !str_cmp( name, "do_khistory" )) return do_khistory;
if ( !str_cmp( name, "do_kick" )) return do_kick;
if ( !str_cmp( name, "do_kill" )) return do_kill;

ADD:
#ifdef CODEPAGES
if ( !str_cmp( name, "do_kodovani" )) return do_kodovani;
#endif

in skill_function() about line 749:
AFTER:

if ( !str_cmp( name, "do_showlayers" )) return do_showlayers;
break;
case 't':
if ( !str_cmp( name, "do_tamp" )) return do_tamp;

ADD:
#ifdef CODEPAGES
if ( !str_cmp( name, "do_tabedit" )) return do_tabedit;
#endif

in skill_function() about line 989:
AFTER:
if ( skill == do_councils ) return "do_councils";
if ( skill == do_counciltalk ) return "do_counciltalk";
if ( skill == do_credits ) return "do_credits";
if ( skill == do_cset ) return "do_cset";

ADD:
#ifdef CODEPAGES
if ( skill == do_cpedit ) return "do_cpedit";
#endif

in skill function() about line 1116:
AFTER:

if ( skill == do_khistory ) return "do_khistory";
if ( skill == do_kick ) return "do_kick";
if ( skill == do_kill ) return "do_kill";


ADD:
#ifdef CODEPAGES
if ( skill == do_kodovani ) return "do_kodovani";
#endif

in skill_function() about line 1434:
AFTER:
if ( skill == do_supplicate ) return "do_supplicate";
if ( skill == do_switch ) return "do_switch";
if ( skill == do_showlayers ) return "do_showlayers";
if ( skill == do_tamp ) return "do_tamp";


ADD:
#ifdef CODEPAGES
if ( skill == do_tabedit ) return "do_tabedit";
#endif


in mud.h: about line 186:
AFTER:
typedef struct extended_bitvector EXT_BV;
typedef struct lcnv_data LCNV_DATA;
typedef struct lang_data LANG_DATA;

ADD:
#ifdef CODEPAGES
typedef struct codepage_data CODEPAGE_DATA;
typedef struct codepage_table CODEPAGE_TABLE;
#endif

about line 659:
ADD:
#ifdef CODEPAGES
struct codepage_data
{
CODEPAGE_DATA * next;
CODEPAGE_DATA * prev;
CODEPAGE_TABLE * out;
CODEPAGE_TABLE * in;
CODEPAGE_TABLE * ascii;
CODEPAGE_TABLE * ascii_in; /* not used this time */
char * name;
char * description;
sh_int isdefault;
};

struct codepage_table
{
CODEPAGE_TABLE * next;
CODEPAGE_TABLE * prev;
char * to;
char * from;
sh_int flags;
sh_int table[256];
};
#endif


about line 856:

AFTER:
/*
* Descriptor (channel) structure.
*/
struct descriptor_data
{
DESCRIPTOR_DATA * next;
DESCRIPTOR_DATA * prev;
DESCRIPTOR_DATA * snoop_by;
CHAR_DATA * character;
CHAR_DATA * original;
char * host;
int port;
int descriptor;
sh_int connected;
sh_int idle;
sh_int lines;
sh_int scrlen;
bool fcommand;
char inbuf [MAX_INBUF_SIZE];
char incomm [MAX_INPUT_LENGTH];
char inlast [MAX_INPUT_LENGTH];
int repeat;
char * outbuf;
unsigned long outsize;
int outtop;
char * pagebuf;
unsigned long pagesize;
int pagetop;
char * pagepoint;
char pagecmd;
char pagecolor;
char * user;
int newstate;
unsigned char prevcolor;
ADD:

#ifdef CODEPAGES
CODEPAGE_DATA * cp;
#endif
/* must be in this structure, the place is unimportant */

about line 4000:
AFTER:

extern int rand_factor;
extern int climate_factor;
extern int neigh_factor;
extern int max_vector;

extern AUCTION_DATA * auction;
extern struct act_prog_data * mob_act_list;

ADD:
#ifdef CODEPAGES
extern CODEPAGE_DATA * cp_default;
extern CODEPAGE_TABLE * cpt_default;
extern char * const codetable_flags[];
extern CODEPAGE_TABLE * cpt_default;
extern CODEPAGE_TABLE * cpt_ctype;
extern CODEPAGE_TABLE * cpt_upper;
extern CODEPAGE_TABLE * cpt_lower;
extern CODEPAGE_TABLE * cpt_ascii;
#endif


about line 4800:

/* db.c ... */
AFTER:
char * show_tilde args( ( char *str ) );
bool str_cmp args( ( const char *astr, const char *bstr ) );
bool str_prefix args( ( const char *astr, const char *bstr ) );

ADD:
#ifndef CODEPAGES
#define str_prefix2 str_prefix
#else
bool str_prefix2 args( ( const char *astr, const char *bstr ) );
#endif

about line 4750:
AFTER:
#define CLASSDIR "../classes/"
#define RACEDIR "../races/"

ADD:
#ifdef CODEPAGES
#define CONVERT_FILE "convert.dat"
#define CODEPAGE_FILE "codepage.dat"
#endif

/*
* Our function prototypes.
* One big lump ... this is every function in Merc.
*/


about line 5300:
AFTER:
int str_free args( ( char *str ) );
void show_hash args( ( int count ) );
char * hash_stats args( ( void ) );
char * check_hash args( ( char *str ) );
void hash_dump args( ( int hash ) );
void show_high_hash args( ( int top ) );

/* newscore.c */
char * get_class args( (CHAR_DATA *ch) );
char * get_race args( (CHAR_DATA *ch) );

ADD:
/* codepages.c */
#ifdef CODEPAGES
CODEPAGE_TABLE *cpt_create( void );
CODEPAGE_DATA *cp_create( void );
CODEPAGE_DATA *get_codepage(char *name);
CODEPAGE_TABLE *get_codepage_table( char *from, char *to );
char *cp_str_translate( CODEPAGE_TABLE *cpt, char *str);
char *cp_ascii_only( char *text );
void cp_initialize(void);
void load_codetables( void );
void load_codepages( void );
void add_codetable( CODEPAGE_TABLE *pcpt );
void fwrite_codetable( FILE *fp, CODEPAGE_TABLE *cpt);
void fwrite_codepage( FILE *fp, CODEPAGE_DATA *cp);
void save_codepages(void);
void fread_cp_internal( FILE *fp );
void fwrite_cp_internal( FILE *fp);
#endif

about line 4200:
/* before, between or after other DECLAREs */
ADD:

#ifdef CODEPAGES
DECLARE_DO_FUN( do_cpedit );
DECLARE_DO_FUN( do_kodovani );
DECLARE_DO_FUN( do_tabedit );
#endif

Post is unread #6 Mar 14, 2024 1:27 am   
Go to the top of the page
Go to the bottom of the page

Voldemar

GroupMembers
Posts5
JoinedMar 11, 2024

 
/******************************************************************************
* SMAUGIC by Pihhan 2001 *
* codepage.c is not in original SMAUG *
* *
* My System of codepages is allowing full 8-bit terminal and 8-bit character *
* set. For English speaking people it is not important, but for the others *
* languages it is needed. English may draw nice text pictures with it, *
* because they can use all characters, especially graphical. Because a few *
* mud clients or telnet supports 8-bit standard, it allows convert output *
* (input too, but it is not very useful) to ascii only characters, which *
* are similar to original. Example: A with caron should be changed to A. *
* This way, players can use full support of their language if they have *
* good client, if they dont have, they can still play with little changes. *
* Some countries have more different codepages they are using, so they need *
* to convert them to one used in MUD, and convert back on output. We have *
* this problems in Czech Republic, but more eastern countries might have *
* problems like this. It is done by Micro$oft, because their codepage used *
* in Windows is different from international standard ISO 8859-2 (Latin-2). *
* I solved this by choosing one internal codepage, which must contain all *
* characters used in language. Users with different codepages have their *
* input/output changed to/from their codepage. This is why Japanese, Korean, *
* Chinese or like shouldn't use this, because their characters are in more *
* than one supported internal codepage, so it is not enough to display all *
* their characters. I am sorry, but support for this is much more difficult. *
* I don't like hard-coded things, so loading and changing codepages can be *
* done online. You as an Immortal can make new codepage when talking with *
* someone using some unknown codepage. *
* *
* Because not all people need this, it has defined CODEPAGES. *
* If it is not defined, codepages won't be used. *
* *
* You can do anything you want with this code. I will be happy if you post * *
* me that you are using this code.
* Any comments, advices or bugfixes are welcome. *
* written by Pihhan (c) 2001 ( pihhan@atlas.cz ) *
*****************************************************************************/

#ifdef CODEPAGES

#include
#include
#ifdef WIN32
#define TELOPT_ECHO '\x01'
#define GA '\xF9'
#define SB '\xFA'
#define WILL '\xFB'
#define WONT '\xFC'
#define DO '\xFD'
#define DONT '\xFE'
#define IAC '\xFF'
#else
#include
#endif
#include "mud.h"

#define NULL_CHAR 0

char * const codetable_flags[] = {
"default", "ascii", "lower", "upper", "constant", "r5", "r6", "r7", "r8", "r9",
"r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19",
"r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29",
"r30", "r31"
};

void cp_initialize(void);
void load_codetables( void );
void add_codetable( CODEPAGE_TABLE *pcpt );

/* These cpt_init_* and cp_init_* are fail safe backup,
it will be replaced with tables read from database files.
It is needed to read these files and if they do not contain
all needed tables, it can run with these hard-coded ascii
tables instead, but without full 8bit input.
It can be changed by cpt_init_ctype, where u sould mark
other characters as alpha and print.
*/

CODEPAGE_TABLE cpt_init_default = {
NULL,NULL,
"DEFAULT!","DEFAULT!",CPT_CONSTANT,
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
100,101,102,103,104,105,106,107,108,109,
110,111,112,113,114,115,116,117,118,119,
120,121,122,123,124,125,126,127,128,129,
130,131,132,133,134,135,136,137,138,139,
140,141,142,143,144,145,146,147,148,149,
150,151,152,153,154,155,156,157,158,159,
160,161,162,163,164,165,166,167,168,169,
170,171,172,173,174,175,176,177,178,179,
180,181,182,183,184,185,186,187,188,189,
190,191,192,193,194,195,196,197,198,199,
200,201,202,203,204,205,206,207,208,209,
210,211,212,213,214,215,216,217,218,219,
220,221,222,223,224,225,226,227,228,229,
230,231,232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,248,249,
250,251,252,253,254,255}
};

CODEPAGE_TABLE cpt_init_ascii = {
NULL,NULL,
"ASCII!","ASCII!",CPT_CONSTANT,
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
100,101,102,103,104,105,106,107,108,109,
110,111,112,113,114,115,116,117,118,119,
120,121,122,123,124,125,126,127, 0, 1,
2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
92, 93, 94, 95, 96, 97, 98, 99,100,101,
102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,
122,123,124,125,126,127}
};

/* this table contains ctype settings like
isprint(), isalpha(), isnumber() etc.
this is used while we are reading tables from files,
after that should be used better dynamic tables.
This table is ascii only */
CODEPAGE_TABLE cpt_init_ctype = {
NULL,NULL,
"ASCII!","CTYPE!",CPT_CONSTANT,
{
512, 512, 512, 512, 512, 512, 512, 512, 512, 864,
608, 608, 608, 608, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 352,3136,3136,3136,3136,3136,3136,3136,
3136,3136,3136,3136,3136,3136,3136,3136,2264,2264,
2264,2264,2264,2264,2264,2264,2264,2264,3136,3136,
3136,3136,3136,3136,3136,2261,2261,2261,2261,2261,
2261,2245,2245,2245,2245,2245,2245,2245,2245,2245,
2245,2245,2245,2245,2245,2245,2245,2245,2245,2245,
2245,3136,3136,3136,3136,3136,3136,2262,2262,2262,
2262,2262,2262,2246,2246,2246,2246,2246,2246,2246,
2246,2246,2246,2246,2246,2246,2246,2246,2246,2246,
2246,2246,2246,3136,3136,3136,3136, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512}
};

CODEPAGE_TABLE cpt_init_upper = {
NULL,NULL,
"ASCII!","UPPER!",CPT_CONSTANT,
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
90, 91, 92, 93, 94, 95, 96, 65, 66, 67,
68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
88, 89, 90,123,124,125,126,127,128,129,
130,131,132,133,134,135,136,137,138,139,
140,141,142,143,144,145,146,147,148,149,
150,151,152,153,154,155,156,157,158,159,
160,161,162,163,164,165,166,167,168,169,
170,171,172,173,174,175,176,177,178,179,
180,181,182,183,184,185,186,187,188,189,
190,191,192,193,194,195,196,197,198,199,
200,201,202,203,204,205,206,207,208,209,
210,211,212,213,214,215,216,217,218,219,
220,221,222,223,224,225,226,227,228,229,
230,231,232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,248,249,
250,251,252,253,254,255}
};

CODEPAGE_TABLE cpt_init_lower = {
NULL,NULL,
"ASCII!","LOWER!",CPT_CONSTANT,
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
60, 61, 62, 63, 64, 97, 98, 99,100,101,
102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,
122, 91, 92, 93, 94, 95, 96, 97, 98, 99,
100,101,102,103,104,105,106,107,108,109,
110,111,112,113,114,115,116,117,118,119,
120,121,122,123,124,125,126,127,128,129,
130,131,132,133,134,135,136,137,138,139,
140,141,142,143,144,145,146,147,148,149,
150,151,152,153,154,155,156,157,158,159,
160,161,162,163,164,165,166,167,168,169,
170,171,172,173,174,175,176,177,178,179,
180,181,182,183,184,185,186,187,188,189,
190,191,192,193,194,195,196,197,198,199,
200,201,202,203,204,205,206,207,208,209,
210,211,212,213,214,215,216,217,218,219,
220,221,222,223,224,225,226,227,228,229,
230,231,232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,248,249,
250,251,252,253,254,255}
};

/* needed for booting and reading database */
CODEPAGE_DATA cp_init_default = {
NULL,NULL,
&cpt_init_default,&cpt_init_default,&cpt_init_default,&cpt_init_default,
"DEFAULT!","",1
};


CODEPAGE_DATA * first_cp;
CODEPAGE_DATA * last_cp;
CODEPAGE_DATA * cp_default = &cp_init_default;
CODEPAGE_TABLE * first_cp_table;
CODEPAGE_TABLE * last_cp_table;
CODEPAGE_TABLE * cpt_default = &cpt_init_default;
CODEPAGE_TABLE * cpt_ctype = &cpt_init_ctype;
CODEPAGE_TABLE * cpt_upper = &cpt_init_upper;
CODEPAGE_TABLE * cpt_lower = &cpt_init_lower;
CODEPAGE_TABLE * cpt_ascii = &cpt_init_ascii;
int top_cp;
int top_cp_table;
char * cp_vnitrni;


/* Creates default codepage, no characters are changed */
CODEPAGE_TABLE *cpt_create( void )
{
int ch;
CODEPAGE_TABLE * cpt;

CREATE( cpt, CODEPAGE_TABLE, 1);
cpt->to = STRALLOC( "default" );
cpt->from = STRALLOC( "default" );
for ( ch = 0; ch <=255; ch++)
cpt->table[ch] = (char) ch;

return cpt;

}

CODEPAGE_DATA *cp_create( void )
{
CODEPAGE_DATA *cp;

if (!cpt_default) {
cpt_default = cpt_create();
LINK(cpt_default, first_cp_table, last_cp_table, next, prev);
}

CREATE( cp, CODEPAGE_DATA, 1);
cp->name = STRALLOC( "newcp" );
cp->description = STRALLOC( "" );
cp->out = cpt_default;
cp->in = cpt_default;
cp->ascii = cpt_default;
cp->isdefault = 0;

return cp;
}

/* used in read_from_buffer and write_to_buffer, main translating func. */
/*void cp_translate( CODEPAGE_TABLE *cpt, char *str, int size, sh_int telnet )
{
int i,c;

if (!cpt || !str)
{
bug("translate: NULL table/str");
return;
}
*/
/* do not change telnet commands */
/* for ( i=0; i if ( *str == '\xFF' ) {
if (telnet) {
++str;++i;
c = (unsigned) *str;
if ( c==WILL || c==WONT || c==DO || c==DONT ) {
++str;++i;
}
} else {
*str = NULL_CHAR;
++str;++i;
c = (unsigned) *str;
if ( c==WILL || c==WONT || c==DO || c==DONT ) {
*str = NULL_CHAR;
++str;++i;
}
*str = NULL_CHAR;
}
} else *str = (char) cpt->table[ (unsigned char) *str ];
}

return;

}*/

/*void cp_translate_in( CODEPAGE_TABLE *cpt, char *str, int size )
{
int i,c;

if (!cpt || !str)
{
bug("translate: NULL table/str");
return;
}
*/
/* ignore any telnet commands */
/* for ( i=0; i if ( *str == '\xFF' ) {
*str = NULL_CHAR;
++str;++i;
c = (unsigned) *str;
if ( c==WILL || c==WONT || c==DO || c==DONT ) {
*str = NULL_CHAR;
++str;++i;
*str = NULL_CHAR;
}
} else *str = (char) cpt->table[ (unsigned char) *str ];
}
return;
}*/

/*void cp_translate_out( CODEPAGE_TABLE *cpt, char *str, int size )
{
int i,c;

if (!cpt || !str)
{
bug("translate: NULL table/str");
return;
}
*/
/* do not change telnet commands */
/* for ( i=0; i if ( *str == '\xFF' ) {
++str;++i;
c = (unsigned) *str;
if ( c==WILL || c==WONT || c==DO || c==DONT ) {
++str;++i;
}
} else *str = (char) cpt->table[ (unsigned char) *str ];
}

return;

}*/

/*void cp_copy_out( CODEPAGE_TABLE *cpt, char *in, char *out, int size )
{
int i,c;

if (!cpt || !out || !in)
{
bug("translate: NULL table/str");
return;
}
*/
/* do not change telnet commands */
/* for ( i=0; i if ( *in == '\xFF' ) {
*out = *in;
++out;++in;++i;
c = (unsigned) *in;
if ( c==WILL || c==WONT || c==DO || c==DONT ) {
*out = *in;
++out;++in;++i;
}
*out = *in;
} else *out = (char) cpt->table[ (unsigned char) *in ];
}

return;

}*/

/* for internal use, doesn't count with telnet commands */
char *cp_str_translate( CODEPAGE_TABLE *cpt, char *str)
{
static char buf[2*MAX_STRING_LENGTH];
char *src;
char *trgt;
char c;

src = str;
trgt = buf;
for ( ; *src != '\0'; src++)
if ( (c = cpt->table[ (unsigned char) *src ]) ) {
*trgt=c;
trgt++;
}
*trgt = '\0';

return buf;
}

/* read ascii only characters, but why? */
char *cp_ascii_only( char *text )
{
static char buf[MAX_STRING_LENGTH];
int i;
for ( i=0; *text != '\0'; text++)
if ( isascii( *text ) ) buf[i++] = *text;
buf[i] = '\0';
return buf;
}

/* find codepage */
CODEPAGE_DATA *get_codepage(char *name)
{
CODEPAGE_DATA *cp;

for( cp = first_cp; cp; cp = cp->next )
if ( !str_cmp( name, cp->name) ) return cp;

return NULL;
}

CODEPAGE_TABLE *get_codepage_table( char *from, char *to )
{
CODEPAGE_TABLE *cpt;

for( cpt = first_cp_table; cpt; cpt = cpt->next )
if ( !str_cmp( to, cpt->to ) && !str_cmp( from, cpt->from ) )
return cpt;

return NULL;
}

int get_tableflag( char *flag )
{
int x;

for ( x = 0; x < (sizeof(codetable_flags) / sizeof(codetable_flags[0])); x++)
if ( !str_cmp(flag, cmd_flags[x]))
return x;
return -1;
}

void show_codepage( CHAR_DATA *ch, CODEPAGE_DATA *cp )
{
ch_printf( ch,
"Name: %s\n\r"
"Input table: from %s to %s\n\r"
"Output table: from %s to %s\n\r"
, cp->name, cp->in->from, cp->in->to, cp->out->from, cp->out->to );
}

/* command for editing character sets, it make codapages visible to players */
void do_cpedit( CHAR_DATA *ch, char *argument)
{
char command[MAX_INPUT_LENGTH];
char name[MAX_INPUT_LENGTH];
char table[MAX_INPUT_LENGTH];
char source[MAX_INPUT_LENGTH];
CODEPAGE_DATA *cp;
CODEPAGE_TABLE *cpt;
DESCRIPTOR_DATA *desc;

if (IS_NPC(ch)) return;

cp = cp_default;
argument = one_argument( argument, name );
if ( name[0] == '\0' || !str_cmp(name,"help")) {
ch_printf(ch, "Use of cpedit:\n\r"
"cpedit list - list of all codepages\n\r"
"cpedit help - this help\n\r"
"cpedit save - saves all codepages and codetables\n\r"
"cpedit show - details of codepage\n\r"
"cpedit create - creates a new codepage\n\r"
"cpedit default - this codepage will be default\n\r"
"cpedit input - change input table to this\n\r"
"cpedit output - change output table to this\n\r"
);
return;
}

if ( !str_cmp(name,"save")) {
save_codepages();
return;
}

if ( !strcmp(name,"list") || !strcmp(name,"vypis") || !*argument ) {
send_to_char("Available codepages:\n\r",ch);
for ( cp = first_cp; cp; cp=cp->next )
pager_printf( ch, "%s (%s->%s->%s) %s\n\r",
cp->name,cp->in->from,cp->in->to,cp->out->to,
cp->isdefault ? "[default]" : "" );
return;
}

/* if ( !strcmp(name,"tables") || !strcmp(name,"tabulky") ) {
send_to_char(":\n\r",ch);
for ( cpt = first_cp_table; cpt; cpt=cpt->next ) {
pager_printf( ch, "%-20s->%-20s", cpt->from,cpt->to);
if (cpt->flags)
pager_printf( ch, " [%s]\n\r", flag_string(cpt->flags, codetable_flags) );
else pager_printf( ch, "\n\r");
}
return;
} */

argument = one_argument( argument, command );
cp = get_codepage( name );

if ( !strcmp(command,"show") || !strcmp(command,"zobrazit") || !*command ) {

if ( !cp ) {
ch_printf(ch, "Codepage %s not found.\n\r", name);
return;
}
show_codepage( ch, cp );
return;
}

if ( !str_cmp(command,"smazat") || !str_cmp(command, "delete") ) {
for ( desc = first_descriptor; desc; desc = desc->next )
if ( desc->cp == cp ) {
send_to_char( "Codepage is in use!\n\r", ch);
return;
}
if ( cp->isdefault ) {
send_to_char( "Cannot delete default codepage!\n\r", ch);
return;
}
UNLINK( cp, first_cp, last_cp, next, prev );
STRFREE( cp->name );
STRFREE( cp->description );
DISPOSE( cp );
send_to_char( "Deleted.\n\r", ch);
return;
}

if ( !str_cmp(command,"default") ) {
CODEPAGE_DATA *cp2;
if ( !cp ) {
ch_printf(ch, "Codepage %s not found.\n\r", name);
return;
}
for ( cp2 = first_cp; cp2; cp2 = cp2->next )
if ( cp2->isdefault ) cp2->isdefault = FALSE;

cp->isdefault = TRUE;
cp_default = cp;
send_to_char( "Set to default!\n\r", ch);
return;
}

if ( !str_cmp(command,"create") || !str_cmp(command,"vytvoшit")) {
if ( cp ) {
ch_printf(ch, "Codepage \"%s\" exists!\n\r",name);
return;
}

cp = cp_create();
if ( cp->name ) STRFREE(cp->name);
cp->name = STRALLOC( name );
LINK( cp, first_cp, last_cp, next, prev);
send_to_char("Created.\n\r",ch);
}

argument = one_argument( argument, table );
argument = one_argument( argument, source );

if ( !str_cmp(table,"input") ) {

if ( !cp ) {
ch_printf(ch, "Codepage %s not found.\n\r", name);
return;
}
cpt = get_codepage_table( source, argument );
if ( !cpt ) {
ch_printf(ch, "Changing table from %s to %s not found!\n\r",
source, argument);
return;
}
cp->in = cpt;
return;
}

if ( !str_cmp(table,"output") ) {
if ( !cp ) {
ch_printf(ch, "Codepage %s not found.\n\r", name);
return;
}
cpt = get_codepage_table( source, argument );
if ( !cpt ) {
ch_printf(ch, "Changing table from %s to %s not found!\n\r",
source, argument);
return;
}

cp->out = cpt;
return;
}

/* unknown command */
do_cpedit( ch, "help");
}

void do_tabedit( CHAR_DATA *ch, char *argument )
{
/* char buf[MAX_INPUT_LENGTH]; */
char command[MAX_INPUT_LENGTH];
char from[MAX_INPUT_LENGTH];
char to[MAX_INPUT_LENGTH];
int flags;
/* CODEPAGE_DATA *cp; */
CODEPAGE_TABLE *cpt;

if (IS_NPC(ch)) return;
argument = one_argument( argument, command );

if ( *command == '\0' || !str_cmp(command,"help")) {
pager_printf( ch, "Usage: tabedit list - prints all tables with flags\n\r"
" tabedit show \n\r"
" tabedit flags \n\r"
" tabedit internal\n\r"
" tabedit internal \n\r"
" tabedit ascii \n\r"
" tabedit upper \n\r"
" tabedit lower \n\r"
" tabedit ctype \n\r");
return;
}

if ( !str_cmp(command,"list") ) {
send_to_pager("Available changing tables:\n\r",ch);
for ( cpt = first_cp_table; cpt; cpt=cpt->next ) {
pager_printf( ch, "%-20s -> %-20s", cpt->from,cpt->to);
if (cpt->flags)
pager_printf( ch, " [%s]\n\r", flag_string(cpt->flags, codetable_flags) );
else pager_printf( ch, "\n\r");
}
return;
}

argument = one_argument( argument, from);
argument = one_argument( argument, to);
cpt = get_codepage_table( from, to );

if ( !str_cmp(command,"show") ) {
if (!cpt) {
send_to_char( "Table not found.\n\r", ch);
return;
}
pager_printf( ch, "From: %s\n\rTo: %s\n\rFlags: %s\n\r",
cpt->from, cpt->to, flag_string( cpt->flags, codetable_flags) );
return;
}

if ( !str_cmp(command,"upper") ) {
if (!cpt) {
send_to_char( "Table not found.\n\r", ch);
return;
}
cpt_upper = cpt;
send_to_char("Done.\n\r",ch);
return;
}

if ( !str_cmp(command,"lower") ) {
if (!cpt) {
send_to_char( "Table not found.\n\r", ch);
return;
}
cpt_lower = cpt;
send_to_char("Done.\n\r",ch);
return;
}

if ( !str_cmp(command,"ctype") ) {
if (!cpt) {
send_to_char( "Table not found.\n\r", ch);
return;
}
cpt_ctype = cpt;
send_to_char("Done.\n\r",ch);
return;
}

if ( !str_cmp(command,"ascii") ) {
if (!cpt) {
send_to_char( "Table not found.\n\r", ch);
return;
}
cpt_ascii = cpt;
send_to_char("Done.\n\r",ch);
return;
}

if ( !str_cmp(command,"internal") ) {
if ( from[0] == '\0' ) {
ch_printf( ch, "System internal codepages:\n\r"
"CTYPE: z %-20s do %-20s\n\r"
"UPPER: z %-20s do %-20s\n\r"
"LOWER: z %-20s do %-20s\n\r"
"ASCII: z %-20s do %-20s\n\r",
cpt_ctype->from,cpt_ctype->to,cpt_upper->from,cpt_upper->to,
cpt_lower->from,cpt_lower->to,cpt_ascii->from,cpt_ascii->to);
return;
}

if (!(cpt=get_codepage_table(from,"CTYPE"))) {
ch_printf( ch, "internal: Table from %s to CTYPE not found.\n\r", from);
} else cpt_ctype = cpt;

if (!(cpt=get_codepage_table(from,"UPPER"))) {
ch_printf( ch, "internal: Table from %s to UPPER not found.\n\r", from);
} else cpt_upper = cpt;

if (!(cpt=get_codepage_table(from,"LOWER"))) {
ch_printf( ch, "internal: Table from %s to LOWER not found.\n\r", from);
} else cpt_lower = cpt;

if (!(cpt=get_codepage_table(from,"ASCII"))) {
ch_printf( ch, "internal: Table from %s to ASCII not found.\n\r", from);
} else cpt_ascii = cpt;

cpt_upper = cpt;
send_to_char("Done.\n\r",ch);
return;
}

if ( !str_cmp(command,"flags") ) {
if (!cpt) {
send_to_char( "Table not found.\n\r", ch);
return;
}
if ( *argument == '\0' ) return;
if ( is_number(argument) )
flags = atoi(argument);
else
flags = get_tableflag(argument);
if (flags < 0 || flags >= 32) {
if (is_number(argument))
send_to_char("Tableflags are from 0 to 31\n\r",ch);
else send_to_char("Flags not found.\n\r",ch);
return;
}
TOGGLE_BIT(cpt->flags,flags);
return;
}

do_tabedit( ch, "help" );
return;
}

void do_kodovani( CHAR_DATA *ch, char *argument )
{
char buf[MAX_INPUT_LENGTH];
CODEPAGE_DATA *cp;

if (IS_NPC(ch)) return;
if (ch->desc) cp = ch->desc->cp;
else return;

/* It is for players and I dont want more versions of this file, so you
* will have to leave it here or delete it. Nice Czech, isn't it? */
#ifdef CZECH
if ( *argument == '\0' ) {
send_to_char("Dostupnб kуdovбnн:\n\r",ch);
for ( cp = first_cp; cp; cp=cp->next )
ch_printf( ch, "%s\n\r", cp->name,cp->in->from,cp->out->to);
if (ch->desc) ch_printf(ch, "Tvй kуdovбnн: %s\n\r",ch->desc->cp->name);
return;
}

argument = one_argument( argument, buf );
if ( !( cp = get_codepage( buf )) ) {
send_to_char("Kodovani nenalezeno.\n\r", ch);
return;
}
ch->desc->cp = cp;
send_to_char("Kodovani nastaveno.\n\r", ch);
#else
if ( *argument == '\0' ) {
send_to_char("Available codepages:\n\r",ch);
for ( cp = first_cp; cp; cp=cp->next )
ch_printf( ch, "%s\n\r", cp->name,cp->in->from,cp->out->to);
if (ch->desc) ch_printf(ch, "Your codepage: %s\n\r",ch->desc->cp->name);
return;
}

argument = one_argument( argument, buf );
if ( !( cp = get_codepage( buf )) ) {
send_to_char("Codepage not found.\n\r", ch);
return;
}
ch->desc->cp = cp;
send_to_char("Done.\n\r", ch);
#endif
}

void save_codepages(void)
{
CODEPAGE_DATA *cp;
CODEPAGE_TABLE *cpt;
char buf[MAX_INPUT_LENGTH];
FILE *fp;

sprintf( buf, "%s%s", SYSTEM_DIR, CONVERT_FILE );
if ( ( fp = fopen( buf, "w" ) ) != NULL ) {
log_string("Saving all convert tables...");
for (cpt = first_cp_table; cpt; cpt=cpt->next )
fwrite_codetable( fp, cpt );
/* log_string("Tabulky ulozeny."); */
fprintf( fp, "\n#END\n");
fclose( fp );
} else
bug("save_codepages: Cannot open %s", buf);

sprintf( buf, "%s%s", SYSTEM_DIR, CODEPAGE_FILE );

if ( ( fp = fopen( buf, "w" ) ) != NULL ) {
log_string("Saving all codepages...");
for ( cp = first_cp; cp; cp=cp->next)
fwrite_codepage( fp, cp );
log_string("Saving system internal tables...");
fwrite_cp_internal( fp );
fprintf( fp, "\n#END\n");
fclose( fp );
log_string("Tables saved.");
} else {
bug("save_codepages: Could not open %s", buf);
return;
}

}

void add_codetable( CODEPAGE_TABLE *pcpt )
{
CODEPAGE_TABLE *tcpt;

for ( tcpt = first_cp_table; tcpt; tcpt = tcpt->next )
if ( strcmp( tcpt->from, pcpt->from) == 0
&& strcmp( tcpt->to, pcpt->to ) == 0 )
{
bug( "add_codetable: duplicate: from \'%s\' to \'%s\'. Deleting.", pcpt->from, pcpt->to );
STRFREE( pcpt->to );
STRFREE( pcpt->from );
DISPOSE( pcpt );
return;
}

if ( !tcpt )
LINK( pcpt, first_cp_table, last_cp_table, next, prev );

top_cp_table++;
}

void fread_codetable( FILE *fp )
{
char buf[MAX_STRING_LENGTH];
char *word;
bool fMatch;
CODEPAGE_TABLE *cpt;
int char_tab, char_val;

if (!fp) {
bug("fread_codetable: NULL file!");
return;
}

cpt = cpt_create(); /* Create structure and set to defaults */

for ( ;; )
{
word = feof( fp ) ? "End" : fread_word( fp );
fMatch = FALSE;

switch ( UPPER(word[0]) )
{
case '*':
fMatch = TRUE;
fread_to_eol( fp );
break;

case 'C':
if ( !strcmp( word, "Change") )
{
char_tab = fread_number( fp );
char_val = fread_number( fp );
cpt->table[ char_tab ] = (char) char_val;
fMatch = TRUE;
}
break;

case 'E':
if ( !strcmp( word, "End" ) )
{
if ( !cpt->to || cpt->to[0]=='\0' )
{
bug( "Fread_codetable: To not found", 0 );
if ( cpt->from ) STRFREE(cpt->from);
if ( cpt->to ) STRFREE(cpt->to);
DISPOSE( cpt );
return;
}
if ( !cpt->from || cpt->from[0]=='\0' )
{
bug( "Fread_codetable: From not found", 0 );
if ( cpt->to ) STRFREE(cpt->to);
if ( cpt->from ) STRFREE(cpt->from);
DISPOSE( cpt );
return;
}

sprintf(buf,"Loaded table %s->%s",cpt->from,cpt->to);
log_string(buf);
add_codetable( cpt );
return;
}
break;

case 'F':
if ( !strcmp( word, "From") )
{
if (cpt->from) STRFREE( cpt->from );
cpt->from = fread_string( fp );
fMatch = TRUE;
}
break;

case 'T':
if ( !strcmp( word, "To") )
{
if (cpt->to) STRFREE( cpt->to );
cpt->to = fread_string( fp );
fMatch = TRUE;
}
break;

}

if ( !fMatch )
{
sprintf( buf, "Fread_codetable: no match: %s", word );
bug( buf, 0 );
}
}
}

void fread_codepage( FILE *fp )
{
char buf[MAX_STRING_LENGTH];
char *word;
bool fMatch;
CODEPAGE_DATA *cp;
char *from, *to;

cp = cp_create(); /* Create structure and set as default */

if (!fp) {
bug("fread_codepage: NULL file!");
return;
}

for ( ;; )
{
word = feof( fp ) ? "End" : fread_word( fp );
fMatch = FALSE;

switch ( UPPER(word[0]) )
{
case '*':
fMatch = TRUE;
fread_to_eol( fp );
break;

case 'A':
if ( !strcmp( word, "Ascii") )
{
from = fread_string( fp );
to = fread_string( fp );
if ( !( cp->ascii = get_codepage_table( from, to )) ) {
bug("fread_codepage: ascii: Convert table from %s to %s does not exist",from,to);
cp->ascii = cpt_default;
}
STRFREE( from );
STRFREE( to );
fMatch = TRUE;
}
break;

case 'D':
if ( !strcmp( word, "Description") )
{
if ( cp->description ) STRFREE( cp->description );
cp->description = fread_string( fp );
fMatch = TRUE;
}
if ( !strcmp( word, "Default") )
{
cp->isdefault = fread_number( fp );
cp_default = cp;
if (cp->ascii) cpt_ascii = cp->ascii;
fMatch = TRUE;
}
break;


case 'I':
if ( !strcmp( word, "In") )
{
from = fread_string( fp );
to = fread_string( fp );
if ( !( cp->in = get_codepage_table( from, to )) ) {
bug("fread_codepage: in: Convert table from %s to %s does not exist",from,to);
cp->in = cpt_default;
}
STRFREE( from );
STRFREE( to );
fMatch = TRUE;
}
break;

case 'N':
if ( !strcmp( word, "Name") )
{
if ( cp->name ) STRFREE( cp->name );
cp->name = fread_string( fp );
fMatch = TRUE;
}
break;
case 'O':
if ( !strcmp( word, "Out") )
{
from = fread_string( fp );
to = fread_string( fp );
if ( !( cp->out = get_codepage_table( from, to )) ) {
bug("fread_codepage: out: Convert table from %s to %s does not exist",from,to);
cp->out = cpt_default;
}
STRFREE( from );
STRFREE( to );
fMatch = TRUE;
}
break;

case 'E':
if ( !strcmp( word, "End" ) )
{
if ( !cp->name && *cp->name != '\0' ) {
bug("fread_codepage: name not found!");
if ( cp->description ) STRFREE( cp->description );
DISPOSE( cp );
break;
}
if ( get_codepage( cp->name ) ) {
bug("Codepage %s already exists. DELETING.",cp->name);
if ( cp->name ) STRFREE( cp->name );
if ( cp->description ) STRFREE( cp->description );
break;
}

if (cp->isdefault) {
cp_default = cp;
if (cp->ascii) cpt_ascii = cp->ascii;
}

sprintf(buf,"Loaded codepage %s.",cp->name);
log_string(buf);
LINK( cp, first_cp, last_cp, next, prev);
return;
}
break;

}

if ( !fMatch )
{
sprintf( buf, "fread_codepage: no match: %s", word );
bug( buf, 0 );
}
}
}

void load_codepages(void)
{
char buf[MAX_INPUT_LENGTH];
FILE *fp;

sprintf( buf, "%s%s", SYSTEM_DIR, CONVERT_FILE );
if ( ( fp = fopen( buf, "r" ) ) != NULL )
{
for ( ; ; )
{
char letter;
char *word;

letter = fread_letter( fp );
if ( letter == '*' )
{
fread_to_eol( fp );
continue;
}

if ( letter != '#' )
{
bug( "load_codepages: # not found.", 0 );
break;
}

word = feof( fp ) ? "END" : fread_word( fp );

if ( !strcmp( word, "TABLE" ) )
{
fread_codetable( fp );
continue;
}
else
if ( !strcmp( word, "CODEPAGE" ) )
{
fread_codepage( fp );
continue;
}
if ( !strcmp( word, "END" ) )
break;
else
{
bug( "load_codepages: bad section.", 0 );
continue;
}
}
fclose( fp );
}
else
{
bug( "Cannot open %s", buf );
exit(1);
}

sprintf( buf, "%s%s", SYSTEM_DIR, CODEPAGE_FILE );
if ( ( fp = fopen( buf, "r" ) ) != NULL )
{
for ( ; ; )
{
char letter;
char *word;

letter = fread_letter( fp );
if ( letter == '*' )
{
fread_to_eol( fp );
continue;
}

if ( letter != '#' )
{
bug( "load_codepages: # not found.", 0 );
break;
}

word = feof( fp ) ? "END" : fread_word( fp );

if ( !strcmp( word, "TABLE" ) )
{
fread_codetable( fp );
continue;
}
else
if ( !strcmp( word, "CODEPAGE" ) )
{
fread_codepage( fp );
continue;
}
if ( !strcmp( word, "INTERNAL" ) )
{
fread_cp_internal( fp );
continue;
}
if ( !strcmp( word, "END" ) )
break;
else
{
bug( "load_codepages: bad section.", 0 );
continue;
}
}
fclose( fp );
}
else
{
bug( "Cannot open %s", buf );
exit(1);
}

}

void fwrite_codepage( FILE *fp, CODEPAGE_DATA *cp)
{
if (!fp) {
bug("fwrite_codepage: NULL file!");
return;
}
if (!cp) {
bug("fwrite_codepage: NULL codepage!");
return;
}

fprintf( fp, "#CODEPAGE\n" );
fprintf( fp, "Name %s~\n", cp->name );
fprintf( fp, "Description %s~\n", strip_cr(cp->description) );
fprintf( fp, "In %s~ %s~\n", cp->in->from, cp->in->to );
fprintf( fp, "Out %s~ %s~\n", cp->out->from, cp->out->to );
fprintf( fp, "Ascii %s~ %s~\n", cp->ascii->from, cp->ascii->to );
if (cp->isdefault)
fprintf( fp, "Default %d\n", cp->isdefault );
fprintf( fp, "End\n\n" );

}

void fwrite_codetable( FILE *fp, CODEPAGE_TABLE *cpt)
{
int c;

if (!fp) {
bug("fwrite_codetable: NULL file!");
return;
}
if (!cpt) {
bug("fwrite_codetable: NULL table!");
return;
}

fprintf( fp, "#TABLE\n" );
fprintf( fp, "From %s~\n", cpt->from );
fprintf( fp, "To %s~\n", cpt->to );
for ( c = 0; c <= 255; c++ )
if ( (unsigned char) cpt->table© != c )
fprintf( fp, "Change %d %d\n", c, (unsigned char) cpt->table© );
fprintf( fp, "End\n\n" );
}

void fwrite_cp_internal( FILE *fp)
{
if (!fp) {
bug("fwrite_cp_internal: NULL file!");
return;
}

if (!cpt_ascii) {
bug("fwrite_cp_internal: ascii not set");
return;
}
if (!cpt_upper) {
bug("fwrite_cp_internal: upper not set");
return;
}
if (!cpt_lower) {
bug("fwrite_cp_internal: lower not set");
return;
}
if (!cpt_default) {
bug("fwrite_cp_internal: default not set");
return;
}
if (!cpt_ctype) {
bug("fwrite_cp_internal: ctype not set");
return;
}

fprintf( fp, "#INTERNAL\n" );
fprintf( fp, "Upper %s~ %s~\n", cpt_upper->from, cpt_upper->to );
fprintf( fp, "Lower %s~ %s~\n", cpt_lower->from, cpt_lower->to );
fprintf( fp, "Ascii %s~ %s~\n", cpt_ascii->from, cpt_ascii->to );
fprintf( fp, "Ctype %s~ %s~\n", cpt_ctype->from, cpt_ctype->to );
fprintf( fp, "Default %s~ %s~\n", cpt_default->from, cpt_default->to );
fprintf( fp, "End\n\n" );

}

void fread_cp_internal( FILE *fp )
{
char buf[MAX_STRING_LENGTH];
char *word;
bool fMatch;
CODEPAGE_DATA *cp;
CODEPAGE_TABLE *cpt;
char *from, *to;

cp = cp_create(); // Create structure and set as default

if (!fp) {
bug("fread_codepage: NULL file!");
return;
}

for ( ;; )
{
word = feof( fp ) ? "End" : fread_word( fp );
fMatch = FALSE;

switch ( UPPER(word[0]) )
{
case '*':
fMatch = TRUE;
fread_to_eol( fp );
break;

case 'A':
if ( !strcmp( word, "Ascii") )
{
from = fread_string_nohash( fp );
to = fread_string_nohash( fp );
if ( !( cpt = get_codepage_table( from, to )) ) {
bug("fread_cp_internal: ascii: Convert table from %s to %s does not exist",from,to);
cpt = cpt_default;
break;
}
cpt_ascii = cpt;
DISPOSE( from );
DISPOSE( to );
fMatch = TRUE;
}
break;

case 'C':
if ( !strcmp( word, "Ctype") )
{
from = fread_string_nohash( fp );
to = fread_string_nohash( fp );
if ( !( cpt = get_codepage_table( from, to )) ) {
bug("fread_cp_internal: ctype: Convert table from %s to %s does not exist",from,to);
cpt = cpt_default;
break;
}
cpt_ctype = cpt;
DISPOSE( from );
DISPOSE( to );
fMatch = TRUE;
}
break;
case 'D':
if ( !strcmp( word, "Default") )
{
from = fread_string_nohash( fp );
to = fread_string_nohash( fp );
if ( !( cpt = get_codepage_table( from, to )) ) {
bug("fread_cp_internal: default: Convert table from %s to %s does not exist",from,to);
cpt = cpt_default;
break;
}
cpt_default = cpt;
DISPOSE( from );
DISPOSE( to );
fMatch = TRUE;
}
break;
case 'E':
if ( !strcmp( word, "End" ) )
{
return;
}
break;
case 'L':
if ( !strcmp( word, "Lower") )
{
from = fread_string_nohash( fp );
to = fread_string_nohash( fp );
if ( !( cpt = get_codepage_table( from, to )) ) {
bug("fread_cp_internal: lower: Convert table from %s to %s does not exist",from,to);
cpt = cpt_default;
break;
}
cpt_lower = cpt;
DISPOSE( from );
DISPOSE( to );
fMatch = TRUE;
}
break;
case 'U':
if ( !strcmp( word, "Upper") )
{
from = fread_string_nohash( fp );
to = fread_string_nohash( fp );
if ( !( cpt = get_codepage_table( from, to )) ) {
bug("fread_cp_internal: upper: Convert table from %s to %s does not exist",from,to);
cpt = cpt_default;
break;
}
cpt_upper = cpt;
DISPOSE( from );
DISPOSE( to );
fMatch = TRUE;
}
break;

}

if ( !fMatch )
{
sprintf( buf, "fread_codepage: no match: %s", word );
bug( buf, 0 );
}
}
}

/* codepages */
#endif

Pages:<< prev 1 next >>