/*
	perled.c	Creates perl-script of recodes
			analoguous to .C file.
*/

#include "ReCoder.h"
#include "Eng2Alt.h"
#include <ctype.h>
#include <string.h>

#ifdef	__linux__
#define	BINPERL		"/usr/bin/perl"
#else
#define	BINPERL		"/usr/local/bin/perl"
#endif

#define	RECODERFILENAME	"perl-recoder"
#define	ENG2ALTFILENAME	"perl-eng2alt"

BYTE RusAlt2upper (BYTE ch)
{
  if	  (ch<=(BYTE)'Ÿ')	return(ch);
  else if (ch<=(BYTE)'¯')	return(ch-(BYTE)' ');
  else if ((ch>=(BYTE)'à')&&(ch<=(BYTE)'ï'))
	return(ch-(BYTE)'P');
  else if (ch==(BYTE)'ñ')	return((BYTE)'ð');
  return(ch);
}

char * STRUPPER (char * s)
{
	char *str=strdup(s);
	char * t = str;
	if (t == NULL)	return NULL;
	while (*t != '\0')
	{
		if ((unsigned char)*t > (unsigned char)127)
			*t = RusAlt2upper(*t);
		else
			*t = toupper(*t);
		t++;
	}
	return str;
}



void MakeReCoderFile (char * filename)
{
  int i;
  FILE * f;

  if ((f=fopen(filename, "w")) == NULL)
  {
    fprintf(stderr,"Cannot open \"%s\" for writing.\n", filename);
    return;
  }

  fprintf(f,
	"#!" BINPERL "\n\n"
  );

  fprintf(f,
	"#	Written by Roytman Alexey\n"
	"# email: roytman AT cs DOT bgu DOT ac DOT il\n"
	"# http://www.cs.bgu.ac.il/~roytman/\n\n"
  );

#define	FORMAT	"%c"
#define	OFORMAT	"\\%03o"
#define	PRINTTABLE(x)	fprintf(f,	"$" #x "=\t' ");		\
			for (i=0;i<128;i++)				\
			  if (isalnum(x[i])||isspace(x[i])||		\
				((x[i] >= (BYTE)128)&&(x[i] != (BYTE)0377)))	\
				fprintf(f,FORMAT,x[i]);			\
			  else						\
				fprintf(f,OFORMAT,x[i]);		\
			fprintf(f,	"';\n");

  PRINTTABLE(Tbl_GOST_alt)
  PRINTTABLE(Tbl_GOST_main)
  PRINTTABLE(Tbl_MIC)
  PRINTTABLE(Tbl_KOI8)
  PRINTTABLE(Tbl_BESTA)
  PRINTTABLE(Tbl_CP1251)
  PRINTTABLE(Tbl_ISO8859_5)
  PRINTTABLE(Tbl_KOI7)
  PRINTTABLE(Tbl_KOI7_inv)
  PRINTTABLE(Tbl_Macintosh)

#undef	FORMAT
#undef	OFORMAT
#undef	PRINTTABLE

  fprintf(f,
	"\n"
	"#print \"\\$0=$0 \\$#ARGV=$#ARGV \\@ARGV=\\(@ARGV\\)\\n\";\n"
	"\n"
	"$from = 'nop';\n"
	"$to = 'nop';\n"
	"\n"
	"$_ = $ARGV[0];\n"
	"SWITCH:	{\n"
	"	if (/-.2./)\n"
	"	{\n"
	"#		print \"\\-X2Y\\n\";\n"
	"\n"
	"		if	(/.*a2.*/){ $from=$Tbl_GOST_alt	; }\n"
	"		elsif	(/.*k2.*/){ $from=$Tbl_KOI8	; }\n"
	"		elsif	(/.*b2.*/){ $from=$Tbl_BESTA	; }\n"
	"		elsif	(/.*72.*/){ $from=$Tbl_KOI7	; }\n"
	"		elsif	(/.*l2.*/){ $from=$Tbl_KOI7_inv	; }\n"
	"		elsif	(/.*w2.*/){ $from=$Tbl_CP1251	; }\n"
	"		elsif	(/.*i2.*/){ $from=$Tbl_ISO8859_5	; }\n"
	"		elsif	(/.*g2.*/){ $from=$Tbl_MIC	; }\n"
	"		elsif	(/.*o2.*/){ $from=$Tbl_GOST_main	; }\n"
	"		elsif	(/.*m2.*/){ $from=$Tbl_Macintosh	; }\n"
	"\n"
	"		if	(/.*2a.*/){ $to=$Tbl_GOST_alt	; }\n"
	"		elsif	(/.*2k.*/){ $to=$Tbl_KOI8	; }\n"
	"		elsif	(/.*2b.*/){ $to=$Tbl_BESTA	; }\n"
	"		elsif	(/.*27.*/){ $to=$Tbl_KOI7	; }\n"
	"		elsif	(/.*2l.*/){ $to=$Tbl_KOI7_inv	; }\n"
	"		elsif	(/.*2w.*/){ $to=$Tbl_CP1251	; }\n"
	"		elsif	(/.*2i.*/){ $to=$Tbl_ISO8859_5	; }\n"
	"		elsif	(/.*2g.*/){ $to=$Tbl_MIC	; }\n"
	"		elsif	(/.*2o.*/){ $to=$Tbl_GOST_main	; }\n"
	"		elsif	(/.*2m.*/){ $to=$Tbl_Macintosh	; }\n"
	"\n"
	"		else		{ die \"Invalid switch $_\\n\";	}\n"
	"\n"
	"		last SWITCH;\n"
	"	}\n"
	"	elsif	(($#ARGV == -1) or
			 ($ARGV[0] =~ /^(-)(-)?h(elp)?$/i))	# Eats '-hu' as helpmode.\n"
	"	{\n"
	"		print \"helpmode\\n\";\n"
	"		print \"Usage:	$0 option\\n\";\n"
	"		print \"  where option is of form '-X2Y'\\n\";\n"
	"		print \"  where 'X' and 'Y' are from the set {a,k,b,7,l,w,i,g,o,m}\\n\";\n"
	"		print \" (alternative,koi8,besta,koi7,latin,winCP1251,iso,main,osnovnaja,macintosh)\\n\";\n"
	"		print \"For more help refer to the original ReCoder\\n\";\n"
	"		exit;\n"
	"	}\n"
	"	else	#filename(s)\n"
	"	{\n"
	"		print \"filename: $ARGV[0]\\n\";\n"
	"		exit;\n"
	"	}\n"
	"}\n"
	"\n"
	"#$from=\"abc\";\n"
	"#$to=\"ABC\";\n"
	"#print \".$from.\\n\\n\";\n"
	"#print \".$to.\\n\\n\";\n"
	"\n"
	"if ($from eq 'nop')	{ die \"Source encoding not set.\\n\"; }\n"
	"if ($to eq 'nop')	{ die \"Destination encoding not set.\\n\"; }\n"
	"\n"
	"while (<STDIN>)\n"
	"{\n"
	"#eval \"tr/$from/$to/, 1\" or die $@;\n"
	"eval \"tr/$from/$to/\";\n"
	"print;\n"
	"}\n"
	"\n"
	"\n"
	"#End.\n"
  );

  fclose (f);
}/*MakeReCoderFile*/



void MakeEngFile (char * filename)
{
  int i,len;
  FILE * f;

  if ((f=fopen(filename, "w")) == NULL)
  {
    fprintf(stderr,"Cannot open \"%s\" for writing.\n", filename);
    return;
  }

  fprintf(f,
	"#!" BINPERL "\n\n"
	"while (<STDIN>)\n"
	"{\n"
  );

#define MAX_LEN	5

  for (len=MAX_LEN; len>0; len--)
  for (i=0; TranslateTable[i].English != NULL ;i++)
  {
  	if (strlen(TranslateTable[i].English) != len)	continue;

	if (strcmp(TranslateTable[i].English, "\\") == 0)	 /* \\	*/
		continue;

	if	(TranslateTable[i].English[0] == '\\')	/* Normal case	*/
		fprintf(f,"s/\\%s/%s/g;\n",		/* \', \`	*/
			TranslateTable[i].English,
			TranslateTable[i].Russian);
  	else if	((TranslateTable[i].English[0] == '`')||
  	    	 (TranslateTable[i].English[0] == '\''))
		fprintf(f,"s/\\%s/%s/g;\n",
			TranslateTable[i].English,
			TranslateTable[i].Russian);
	else
		fprintf(f,"s/%s/%s/g;\n",
			TranslateTable[i].English,
			TranslateTable[i].Russian);

if (len>1)					/* If not one letter...	*/
{
  	if	(TranslateTable[i].English[0] == '\\')	/* First letter	*/
		fprintf(f,"s/\\%s/%s/g;\n",		/* \', \`	*/
			TranslateTable[i].English,
			TranslateTable[i].Russian);
	else if	((TranslateTable[i].English[0] == '`')|| /* is capital	*/
		 (TranslateTable[i].English[0] == '\''))
		fprintf(f,"s/\\%s/%s/g;\n",
			TranslateTable[i].English,
			TranslateTable[i].Russian);
	else
	{
	TranslateTable[i].Russian=STRUPPER(TranslateTable[i].Russian);

		fprintf(f,"s/%c%s/%s/g;\n",
			toupper(TranslateTable[i].English[0]),
			&TranslateTable[i].English[1],
			TranslateTable[i].Russian);
	}
}/*if only one letter*/

	TranslateTable[i].English=STRUPPER(TranslateTable[i].English);
	TranslateTable[i].Russian=STRUPPER(TranslateTable[i].Russian);

  	if	(TranslateTable[i].English[0] == '\\')	/* All capitals	*/
		fprintf(f,"s/\\%s/%s/g;\n",
			TranslateTable[i].English,
			TranslateTable[i].Russian);
	else if	((TranslateTable[i].English[0] == '`')||
		 (TranslateTable[i].English[0] == '\''))
		fprintf(f,"s/\\%s/%s/g;\n",
			TranslateTable[i].English,
			TranslateTable[i].Russian);
	else
		fprintf(f,"s/%s/%s/g;\n",
			TranslateTable[i].English,
			TranslateTable[i].Russian);

  }
  fprintf(f,
	"print;\n"
	"}\n"
  );

  fclose (f);
}/*MakeEngFile*/


int main (void)
{
  MakeReCoderFile (RECODERFILENAME);
  MakeEngFile	  (ENG2ALTFILENAME);

  return 0;			/* Not to warn `make', when in Makefile	*/
}


/*<EOF>*/

