//	ggch.c		gg630504 hg9ieg linux.ubuntu.gcc
//	2010-03-06 - 2024-05-27

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "ggstd.h"
#include "ggch.h"

#include "ggchlwr_.h"

#include "ggchlwr_.c"



#include "ggch852_.h"

#include "ggch852_.c"


CH		chUprFromB[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

SZ		szASCIICh[] = {
// 0      1      2      3      4      5      6      7      8      9      a      b      c      d      e      f     
"NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", "BS",  "HT",  "LF",  "VT",  "FF",  "CR",  "SO",  "SI",
"DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", "CAN", "EM",  "SUB", "ESC", "FS",  "GS",  "RS",  "US"
};


//$ CtFromSzuCtSz ------------------------------------------------------
CT		CtFromSzuCtSz( szu_, ct_, sz_ )
SZU		szu_;	// ki:	cél unicode tömb
CT		ct_;	// be:	cél unicode szöveg hossza
SZ		sz_;	// be:	forrás utf-8 szöveg
			// vissza:	maradék unicode karakterek száma
{
CU		cu;

while( !(ct_==0 || (cu = CuFromPsz( &sz_ ))==0) )
	{
	*szu_++ = cu;
	ct_--;
	}
*szu_ = cuEos;
return( ct_ );
}


//$ CtLenSzu -----------------------------------------------------------
CT		CtLenSzu( szu_ )
SZU		szu_;	// be: unicode szöveg
			// vissza: unicode karakterek száma
{
CT		ct;

for( ct = 0; !(*szu_==cuEos); szu_++, ct++ )
	;

return( ct );
}


//$ CuFromPsz ----------------------------------------------------------
// unikódra utf-8 szöveg 1 karakterét
// ggfs.c - CuGetH()
CU		CuFromPsz( psz_ )
PSZ		psz_;	// be/ki:	utf8-ra mutató
			// vissza:	unicode
			// oldal:	utf8-ra mutató továbblép a következő karakterre
{
CU		cuAct;
CHU		uchAct;

cuAct = 0;
uchAct = (CHU)*((*psz_)++);

if( (uchAct & 0b10000000)==0b00000000 ) // 0xxx xxxx
	{
	return( uchAct );
	}
else	if( (uchAct & 0b11100000)==0b11000000 ) // 110x xxxx .... ....
	{
	cuAct = uchAct & 0b00011111;
	uchAct = (CHU)*((*psz_)++);
	if( (uchAct & 0b11000000)==0b10000000 ) // .... .... 10xx xxxx
		{
		cuAct <<= 6;
		cuAct += uchAct & 0b00111111;
		return( cuAct );
		}
	else	return( rFail );
	}
else	if( (uchAct & 0b11110000)==0b11100000 ) // 1110 xxxx .... .... .... ....
	{
	cuAct = uchAct & 0b00001111;
	uchAct = (CHU)*((*psz_)++);
	if( (uchAct & 0b11000000)==0b10000000 ) // .... .... 10xx xxxx .... ....
		{
		cuAct <<= 6;
		cuAct += uchAct & 0b00111111;
		uchAct = (CHU)*((*psz_)++);
		if( (uchAct & 0b11000000)==0b10000000 ) // .... .... .... .... 10xx xxxx
			{
			cuAct <<= 6;
			cuAct += uchAct & 0b00111111;
			return( cuAct );
			}
		else	return( rFail );
		}
	else	return( rFail );
	}
else	if( (uchAct & 0b11111000)==0b11110000 ) // 1111 0xxx ... ... ... ... ... ...
	{
	cuAct = uchAct & 0b00000111;
	uchAct = (CHU)*((*psz_)++);
	if( (uchAct & 0b11000000)==0b10000000 ) // .... .... 10xx xxxx .... .... ... ...
		{
		cuAct <<= 6;
		cuAct += uchAct & 0b00111111;
		uchAct = (CHU)*((*psz_)++);
		if( (uchAct & 0b11000000)==0b10000000 ) // .... .... .... .... 10xx xxxx ... ...
			{
			cuAct <<= 6;
			cuAct += uchAct & 0b00111111;
			uchAct = (CHU)*((*psz_)++);
			if( (uchAct & 0b11000000)==0b10000000 ) // .... .... 10xx xxxx .... .... ... ...
				{
				cuAct <<= 6;
				cuAct += uchAct & 0b00111111;
				return( cuAct );
				}
			else	return( rFail );
			}
		else	return( rFail );
		}
	else	return( rFail );
	}
else	return( rFail );
}


//$ CuFromSz -----------------------------------------------------------
// sz_ első karakterét unicode-ra konvertálja
CU		CuFromSz( sz_ )
SZ		sz_;	// be:	utf8-ra mutató
			// vissza:	unicode
{
return( CuFromPsz( &sz_ ) );
}


//$ FIsBlankCh ---------------------------------------------------------
F	FIsBlankCh( ch_ )
CH	ch_;
{
return( ch_==' ' || 
ch_==chBs || 
ch_==chCr ||
ch_==chFf || 
ch_==chHt || 
ch_==chLf || 
ch_==chVt );
}


//$ FIsBlankCu ---------------------------------------------------------
F	FIsBlankCu( cu_ )
CU	cu_;
{
return( cu_==' ' || cu_==cuNBSp || 
cu_==cuBs || 
cu_==cuCr || 
cu_==cuFf || 
cu_==cuHt || 
cu_==cuLf || 
cu_==cuVt );
}


//$ FIsEolsCh ----------------------------------------------------------
F	FIsEolsCh( ch_ )
CH	ch_;
{
return( ch_==chEos || ch_==chCr || ch_==chLf );
}


//$ FIsEolsCu ----------------------------------------------------------
F	FIsEolsCu( cu_ )
CU	cu_;
{
return( cu_==chEos || cu_==cuCr || cu_==cuLf );
}


//$ FIsEolsMc ----------------------------------------------------------
F	FIsEolsMc( mc_ )
MC	mc_;
{
return( mc_==mcEos || mc_==mcCr || mc_==mcLf );
}


//$ McLwrMc ------------------------------------------------------------
CU		McLwrMc( cu_ )
CU		cu_;
{
PUPRLWR		p;

for( p = uprlwrMp; p->szUpr!=NULL; p++ )
	if( cu_ == p->cuUpr )
		return( p->cuLwr );
return( cu_ );
}


//$ McUprMc ------------------------------------------------------------
CU		McUprMc( cu_ )
CU		cu_;
{
PUPRLWR		p;

for( p = uprlwrMp; p->szLwr!=NULL; p++ )
	if( cu_ == p->cuLwr )
		return( p->cuUpr );
return( cu_ );
}


//$ SzASCIICu ----------------------------------------------------------
SZ		SzASCIICu( cu_ )
CU		cu_;
{
return( cu_==127 ? "del" : ( cu_>=0 && cu_<=31 ? szASCIICh[cu_] : NULL ) );
}


//$ SzASCIISzCh --------------------------------------------------------
SZ		SzASCIISzCh( sz_, ch_ )
SZ		sz_;
CH		ch_;
{
if( (CHU)ch_==127 )
	strcpy( sz_, "del" );
else	if( (CHU)ch_>=0 && (CHU)ch_<=31 )
		strcpy( sz_, szASCIICh[(CHU)ch_] );
	else	{
		sz_[0] = ch_;
		sz_[1] = chEos;
		}
return( sz_ );
}


//$ SzClangSzCh --------------------------------------------------------
// C stílusú szövegre konvertál karaktert
SZ		SzClangSzCh( sz_, ch_ )
SZ		sz_;	// ki:	szöveg
CH		ch_;	// be:	karakter
			// vissza:	szöveg
{
if( ch_=='\a' )	{ strcpy( sz_, "\\a" ); goto ret; }
if( ch_=='\b' )	{ strcpy( sz_, "\\b" ); goto ret; }
if( ch_=='\f' )	{ strcpy( sz_, "\\f" ); goto ret; }
if( ch_=='\n' )	{ strcpy( sz_, "\\n" ); goto ret; }
if( ch_=='\r' )	{ strcpy( sz_, "\\r" ); goto ret; }
if( ch_=='\t' )	{ strcpy( sz_, "\\t" ); goto ret; }
if( ch_=='\v' )	{ strcpy( sz_, "\\v" ); goto ret; }
if( ch_=='\\' )	{ strcpy( sz_, "\\\\" ); goto ret; }
if( ch_=='\'' )	{ strcpy( sz_, "\\\'" ); goto ret; }
if( ch_=='\"' )	{ strcpy( sz_, "\\\"" ); goto ret; }
if( (CHU)ch_>=' ' && (CHU)ch_<0x7f )	{ *sz_ = ch_; sz_[1] = chEos; goto ret; }
sprintf( sz_, "\\x%x02X", ch_ ); goto ret;
//-------
ret:
return( sz_ );
}


//$ SzCommaSz ----------------------------------------------------------
// , <- .
SZ		SzCommaSz( sz_ )
SZ		sz_;
{
PCH		pch;

for( pch = sz_; *pch!=chEos; pch++ )
	if( *pch == '.' )
		*pch = ',';
return( sz_ );
}


//$ SzCtrlFromClangSzSz ------------------------------------------------
// "\n" <-- "\\n"
SZ		SzCtrlFromClangSzSz( szDest_, szSou_ )
SZ		szDest_;
SZ		szSou_;
{
PCH		pchD;
CH		ch;

pchD = szDest_;
while( (ch=*szSou_)!=chEos )
	{
	if( ch == '\\' )
		{
		ch = szSou_[1];
		switch( ch )
			{
		case '\\':	*pchD++ = '\\';	szSou_ += 2;	break;
		case '\'':	*pchD++ = '\'';	szSou_ += 2;	break;
		case '\"':	*pchD++ = '\"';	szSou_ += 2;	break;
		case '\?':	*pchD++ = '\?';	szSou_ += 2;	break;
		case 'a':	*pchD++ = '\a';	szSou_ += 2;	break;
		case 'b':	*pchD++ = '\b';	szSou_ += 2;	break;
		case 'f':	*pchD++ = '\f';	szSou_ += 2;	break;
		case 'n':	*pchD++ = '\n';	szSou_ += 2;	break;
		case 'r':	*pchD++ = '\r';	szSou_ += 2;	break;
		case 't':	*pchD++ = '\t';	szSou_ += 2;	break;
		case 'v':	*pchD++ = '\v';	szSou_ += 2;	break;

		default:	*pchD++ = '\\';	szSou_++;	break;
			}
		}
	else	{
		*pchD++ = ch;
		szSou_++;
		}
	}
*pchD = chEos;

return( szDest_ );
}


//$ SzDotSz ------------------------------------------------------------
// . <- ,
SZ		SzDotSz( sz_ )
SZ		sz_;
{
PCH		pch;

for( pch = sz_; *pch!=chEos; pch++ )
	if( *pch == ',' )
		*pch = '.';
return( sz_ );
}


//$ SzFromSzCtSzu ------------------------------------------------------
SZ		SzFromSzCtSzu( szDest_, ctDest_, szuSou_ )
SZ		szDest_;
CT		ctDest_;
SZU		szuSou_;
{
PCH		pchD;
CH		szTmp[10];
PCH		pchTmp;

pchD = szDest_;
while( !(ctDest_==0 || *szuSou_==cuEos ) )
	{
	SzFromSzCu( szTmp, *szuSou_ );
	pchTmp = szTmp;
	while( !(ctDest_==0 || *pchTmp==chEos ) )
		{
		*pchD++ = *pchTmp++;
		ctDest_--;
		}
	szuSou_++;
	}


*pchD = chEos;
return( szDest_ );
}


//$ SzFromSzCu ---------------------------------------------------------
// http://hu.wikipedia.org/wiki/UTF-8
// visszatérési érték a string végére mutat
SZ		SzFromSzCu( sz_, cu_ )
SZ		sz_;
CU		cu_;
{

if( (cu_ & 0xffffff80) == 0 )			// 00000000 00000000 00000000 0xxxxxxx
	{
	*sz_++ = cu_ & 0x7f;
	}
else	if( (cu_ & 0xfffff800) == 0 )		// 00000000 00000000 00000yyy yyxxxxxx
	{
	*sz_++ = 0xc0 | ((cu_ & 0x7c0) >> 6);	
	*sz_++ = 0x80 | (cu_ &   0x3f );	
	}
else	if( (cu_ & 0xffff0000) == 0 )		// 00000000 00000000 zzzzyyyy yyxxxxxx
	{
	*sz_++ = 0xe0 | ((cu_ & 0xf000 ) >> 12 );	
	*sz_++ = 0x80 | ((cu_ &  0xfc0 ) >> 6 );	
	*sz_++ = 0x80 | (cu_ &    0x3f );	
	}
else	if( (cu_ & 0xffe00000) == 0 )		// 00000000 000wwwzz zzzzyyyy yyxxxxxx
	{
	*sz_++ = 0xf0 | ((cu_ & 0x1c0000 ) >> 18 );	
	*sz_++ = 0x80 | ((cu_ &  0x3f000 ) >> 12 );	
	*sz_++ = 0x80 | ((cu_ &    0xfc0 ) >> 6 );	
	*sz_++ = 0x80 | (cu_ &      0x3f );	

	}

*sz_ = chEos;
return( sz_ );
}


//$ SzFromX852SzSz -----------------------------------------------------
// utf-8-ra konvertál régi windows 852-es kólapú szöveget 
SZ		SzFromX852SzSz( szDest_, szSou_ )
SZ		szDest_;	// utf-8
SZ		szSou_;		// win 852
{
PCH		pchD;
PCH		pchU;
PCP852		p852;
CH		ch;

pchD = szDest_;
while( (ch=*szSou_)!=chEos )
	{
	// keres
	p852 = cp852Mp;
	while( p852->sz852!=NULL && strncmp( szSou_, p852->sz852, p852->ct852 )!=0 )
		p852++;
	if( p852->sz852!=NULL )
		{ // megvan, át kell másolni UTF-8-at
		pchU = p852->szUtf8;
		while( *pchU!=chEos )
			*pchD++ = *pchU++;
		szSou_ += p852->ct852;
		} 
	else	{ // nincs
		*pchD++ = ch;
		szSou_++;
		}
	}
*pchD = chEos;

return( szDest_ );
}


//$ SzLwrSzCtSzuCtSz ---------------------------------------------------
SZ		SzLwrSzCtSzuCtSz( szDest_, ctDest_, szuTmp_, ctTmp_, szSou_ )
SZ		szDest_;	// be: eredmény szöveg utf-8
CT		ctDest_;	// be: eredmény max hossz
SZU		szuTmp_;	// be: unicode szöveg munkaváltozó
CT		ctTmp_;		// be: unicode munkaváltozó max hossz
SZ		szSou_;		// be: forrás szöveg utf-8
{
CtFromSzuCtSz(  szuTmp_, ctTmp_, szSou_ );	// unicode <- utf-8
SzuLwrSzuCtSzu( szuTmp_, ctTmp_, szuTmp_ );	// kisbetűs
SzFromSzCtSzu(  szDest_, ctDest_, szuTmp_ );	// utf-8 <- unicode
return( szDest_ );
}


//$ SzRmCrLfSz ---------------------------------------------------------
// szöveg végéről törli a \r \n karaktereket
SZ		SzRmCrLfSz( sz_ )
SZ		sz_;
{
PCH		pchEnd;

for( pchEnd = sz_; *pchEnd!=chEos; pchEnd++ )
	;

for( ; pchEnd!=sz_ && ( pchEnd[-1]==chLf || pchEnd[-1]==chCr ); pchEnd-- )
	;

*pchEnd = chEos;
return( sz_ );
}


//$ SzTrim2Sz ----------------------------------------------------------
// szöveg elején és végén lévő sp tab karaktereket törli
SZ		SzTrim2Sz( sz_ )
SZ		sz_;	// be, ki: szöveg
{
PCH		pchStart;
PCH		pchEnd;

// elejéről nem szóköz keresése
for( pchStart = sz_; *pchStart!=chEos && FIsBlankCh( *pchStart ); pchStart++ )
	;

// legvége keresése
for( pchEnd = pchStart; *pchEnd!=chEos; pchEnd++ )
	;

// vissza keres
for( ; pchEnd!=pchStart && FIsBlankCh( pchEnd[-1] ); pchEnd-- )
	;

*pchEnd = chEos;
return( pchStart );
}


//$ SzuCpySzuSzu -------------------------------------------------------
// unicode-os szöveget másol
SZU		SzuCpySzuSzu( d_, s_ )
SZU		d_;	// ki:	cél unicode szöveg
SZU		s_;	// be:	forrás unicode szöveg
			// vissza:	cél unicode szöveg
{
SZU		r;

r = d_;
while( !(*s_==cuEos) )
	*d_++ = *s_++;
*d_ = cuEos;
return( r );
}


//$ SzuLwrSzuCtSzu -----------------------------------------------------
SZU		SzuLwrSzuCtSzu( szuDest_, ct_, szuSou_ )
SZU		szuDest_;
CT		ct_;
SZU		szuSou_;
{
PCU		pcuS;
PCU		pcuD;

pcuS = szuSou_;
pcuD = szuDest_;
while( !(ct_==0 || *pcuS==cuEos) )
	{
	*pcuD++ = McLwrMc( *pcuS++ );
	ct_--;
	}
*pcuD = cuEos;
return( szuSou_ );
}


//$ SzuLwrSzuSzu -------------------------------------------------------
SZU		SzuLwrSzuSzu( szuDest_, szuSou_ )
SZU		szuDest_;
SZU		szuSou_;
{
PCU		pcuS;
PCU		pcuD;

pcuS = szuSou_;
pcuD = szuDest_;
while( !(*pcuS == cuEos) )
	{
	*pcuD++ = McLwrMc( *pcuS++ );
	}
*pcuD = cuEos;
return( szuSou_ );
}


//$ SzUprSzCtSzuCtSz ---------------------------------------------------
SZ		SzUprSzCtSzuCtSz( szDest_, ctDest_, szuTmp_, ctTmp_, szSou_ )
SZ		szDest_;	// be: eredmény szöveg utf-8
CT		ctDest_;	// be: eredmény max hossz
SZU		szuTmp_;	// be: unicode szöveg munkaváltozó
CT		ctTmp_;		// be: unicode munkaváltozó max hossz
SZ		szSou_;		// be: forrás szöveg utf-8
{
CtFromSzuCtSz(  szuTmp_, ctTmp_, szSou_ );	// unicode <- utf-8
SzuUprSzuCtSzu( szuTmp_, ctTmp_, szuTmp_ );	// nagybetűs
SzFromSzCtSzu(  szDest_, ctDest_, szuTmp_ );	// utf-8 <- unicode
return( szDest_ );
}


//$ SzuUprSzuCtSzu -----------------------------------------------------
SZU		SzuUprSzuCtSzu( szuDest_, ct_, szuSou_ )
SZU		szuDest_;
CT		ct_;
SZU		szuSou_;
{
PCU		pcuS;
PCU		pcuD;

pcuS = szuSou_;
pcuD = szuDest_;
while( !(ct_==0 || *pcuS==cuEos) )
	{
	*pcuD++ = McUprMc( *pcuS++ );
	ct_--;
	}
*pcuD = cuEos;
return( szuSou_ );
}


//$ SzuUprSzuSzu -------------------------------------------------------
SZU		SzuUprSzuSzu( szuDest_, szuSou_ )
SZU		szuDest_;
SZU		szuSou_;
{
PCU		pcuS;
PCU		pcuD;

pcuS = szuSou_;
pcuD = szuDest_;
while( !(*pcuS == cuEos) )
	*pcuD++ = McUprMc( *pcuS++ );
*pcuD = cuEos;
return( szuSou_ );
}

//$ SuaFromSz ----------------------------------------------------------
SUA		SuaFromSz( sz_ )
SZ		sz_;
{
CU		cu;
RA		ra;
R		r;

RInitPraSs( &ra, sizeof( CU ) );

while( (cu = CuFromPsz( &sz_ )) != 0 )
	{
	if( (r = RPushPraPv( &ra, &cu )) != rSucceed )
		{
		RFreePra( &ra );
		return( NULL );
		}
	}
cu = cuEos;

if( (r = RPushPraPv( &ra, &cu )) != rSucceed )
	{
	RFreePra( &ra );
	return( NULL );
	}

return( ra.pv );
}


//@

