#!/bin/bash

#     gen_trcs  -- generates `trcs' program
#     Copyright (C) 2000 Anton Kirilov Zinoviev

#     This program is free software; you can redistribute it and/or modify
#     it under the terms of the GNU General Public License as published by
#     the Free Software Foundation; either version 2 of the License, or
#     (at your option) any later version.

#     This program is distributed in the hope that it will be useful,
#     but WITHOUT ANY WARRANTY; without even the implied warranty of
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#     GNU General Public License for more details.

#     You should have received a copy of the GNU General Public License
#     along with this program; if not, write to the Free Software
#     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

#     Contact the author by e-mail: anton@lml.bas.bg, zinoviev@fmi.uni-sofia.bg

cat <<"PART"
#!/bin/bash

#     trcs  -- translates codesets
#     Copyright (C) 2000 Anton Kirilov Zinoviev

#     This program is free software; you can redistribute it and/or modify
#     it under the terms of the GNU General Public License as published by
#     the Free Software Foundation; either version 2 of the License, or
#     (at your option) any later version.

#     This program is distributed in the hope that it will be useful,
#     but WITHOUT ANY WARRANTY; without even the implied warranty of
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#     GNU General Public License for more details.

#     You should have received a copy of the GNU General Public License
#     along with `bash' interpreter; if not, write to the Free Software
#     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

#     Contact the author by e-mail: anton@lml.bas.bg, zinoviev@fmi.uni-sofia.bg

function err() {
    echo -e $1 1>&2
    echo "trcs: Try \`trcs --help' for more information." 1>&2
    exit 2
}

function get_opt() {
    case $1 in
    -)
	op=arg;;
    --*)
	op=`expr $1 : '\(.*\)=.*' '|' $1`;;
    -*)
	op=`expr $1 : '\(-.\).*'`;;
    *)
	op=arg;;
    esac
}

function get_arg() {
    case $1 in
    -)
	arg='-'
	shift;;
    --*)
	arg=`expr $1 : '[^=]*=\(.*\)'`
	if [ -z "$arg" ]; then 
	    arg=$2
	    shift; shift;
	else
	    shift;
	fi;;
    -*)
	arg=`expr $1 : '-.\(.*\)'`
	if [ -z "$arg" ]; then 
	    arg=$2
	    shift; shift;
	else
	    shift;
	fi;;
    *)
	arg=$1
	shift;;
    esac
    if [ -z "$arg" ]; then
	err "trcs: Option \`${op}' requires an argument."
    fi
    args="$*"
}

function no_arg() {
    case $1 in
    --*)
	local x=`expr $1 : '[^=]*=\(.*\)'`
	if [ -n "$x" ]; then 
	    err "trcs: Option \`$1' doesn't allow an argument."
	fi;;
    -*)
	local x=`expr $1 : '-.\(.*\)'`
	if [ -n "$x" ]; then
	    x=-$x
	fi;;
    *) ;;
    esac
    shift
    args="$x $*"
}

PART

cat $1| 
while read a b c; do
    echo "function $a() {"
    echo "cat <<\"EOF\""
    cat <<"CONTROL"
0 0000
1 0001
2 0002
3 0003
4 0004
5 0005
6 0006
7 0007
8 0008
9 0009
10 000A
11 000B
12 000C
13 000D
14 000E
15 000F
16 0010
17 0011
18 0012
19 0013
20 0014
21 0015
22 0016
23 0017
24 0018
25 0019
26 001A
27 001B
28 001C
29 001D
30 001E
31 001F
CONTROL
    cat $3/$a |
	awk '{if ($1>=32) {print}}'
    echo "EOF"
    echo "}"
    echo
done

cat <<"PART"
fromcs=cp1251
tocs=cp1251

while [ -n "$1" ]; do
    get_opt $*
    case $op in
    -C|--copyright)
	no_arg $* ; set -- $args
	cat<<"EOF"
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with `bash' interpreter; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
EOF
	exit;;
    -h|--help)
	no_arg $* ; set -- $args
	cat<<"EOF"
trcs 1.5
Usage: trcs [OPTION]... [FILE]...

       -C, --copyright     display copying conditions and warranty information
       -s, --gen-script    generates recoding script for latter usage
       -l, --list          list all known codesets with their aliases
       -h, --help          display this help and exit
-f BEFORE, --from=BEFORE   codeset of the source
 -t AFTER, --to=AFTER      codeset of the output

If none of -C, -s, -l, -h and their equivalents is given each FILE will be
read assuming it is coded with codeset BEFORE.  On standard output it will be
recoded so to use codeset AFTER.  If there is no FILE given `trcs' will act as
filter.  Both BEFORE and AFTER are case insensitive and default to `cp1251'.

Examples:
           trcs -fcyrillic -t koi8-r letter.txt
           trcs --from cp437 --to=mik screen.txt

Warning: Most often recoding is irreversible operation !
EOF
	exit;;
    -l|--list)
	no_arg $* ; set -- $args
PART

echo "        echo \"Known codesets with their aliases:  \""
echo -n "        echo '"

cat $1 | 
while read a b c; do
    echo -n "$a"
    if [ "$b" = "|" ]; then
	echo -n "  "
    else
	echo -n ' ('`echo $b | sed 's/|/, /g'`')  '
    fi
done
echo "'"
echo "        exit;;"

cat<<"PART"
    -f|--from)
	get_arg $* ; set -- $args
	fromcs=$arg;;
    -t|--to)
	get_arg $* ; set -- $args
	tocs=$arg;;
    -s|--gen-script)
	no_arg $* ; set -- $args
	gen=yes;;
    arg)
	get_arg $* ; set -- $args
	files="${files} ${arg}";;
    *)	err "trcs: Unknown option \`$1'." ;;
    esac
done

[ -z "$files" ] && files="-"

fromcs=`echo ${fromcs}|tr A-Z a-z`
tocs=`echo ${tocs}|tr A-Z a-z`

case ${fromcs} in
PART

cat $1 |
while read a b c; do
    if [ "$b" = "|" ]; then
	b="$a"
    else
	b="$a|$b"
    fi
    echo "$b)"
    echo "    fromcs=$a;;"
done

cat <<"PART"
*)
    err "trcs: Unknown codeset \`${fromcs}'.\ntrcs: Try trcs --list";;
esac

case ${tocs} in
PART

cat $1 |
while read a b c; do
    if [ "$b" == "|" ]; then
	b="$a"
    else
	b="$a|$b"
    fi
    echo "$b)"
    echo "    tocs=$a;;"
done

cat <<"PART"
*)
    err "trcs: Unknown codeset \`${tocs}'.\ntrcs: Try trcs --list";;
esac

tmpfile=/tmp/csrec.$$

[ -f ${tmpfile}.1 ] && err "trcs: The file ${tmpfile}.1 exists !? Try again"
touch ${tmpfile}.1

[ -f ${tmpfile}.2 ] && err "trcs: The file ${tmpfile}.2 exists !? Try again"
touch ${tmpfile}.2

trap "rm ${tmpfile}.1 ${tmpfile}.2; exit 2" HUP INT TERM

{
cat <<EOF
function printcode(code)
{
    if(code==45)
	{
	    printf "'\\\\-'";
	}
    else if(code==91)
	{
	    printf "'\\\\['";
	}
    else
	{
	    printf "'\%o'", code;
	}
}

BEGIN {
EOF

${fromcs} |
awk '{printf "tu[%s]=\"%s\";\n", $1, $2;}'

${tocs} |
awk '{printf "ut[\"%s\"]=%s;\n", $2, $1;}'

cat <<EOF

PART

cat $2 | awk '{
    split($0,a);
    for(i=2;i<=NF;i++) 
	printf "fb[\"%s\",%s] = \"%s\";\n", a[1], i-1, a[i]
}'

cat <<"PART"

for(i=32;i<256;i++)
    {
	t="";
	if (tu[i]!="")
	    {
		u=tu[i];
		if(ut[u]!="")
		    t=ut[u];
		else 
		    {
			j=1;
			while(fb[u,j]!="" && t=="")
			    {
				if(ut[fb[u,j]]!="")
				    t=ut[fb[u,j]];
				j++;
			    }
		    }
	    }
	if (t=="")
	    t=ut["003F"];
	if (t=="")
	    t=ut["0020"];
	tt[i]=t;
	if(tt[i]!=i)
	    notrivial="yes";
    }

print "#!/bin/sh";
print;
print "trap \"exit 0\" PIPE"
print;
if(notrivial!="yes")
    print "cat \"\$@\"";
else
    {
	print "cat \"\$@\" | tr \\\\";

	j=0;
	for(i=32;i<256;i++)
	    {
		if(j==11)
		    {
			printf "\\\\\n";
			j=0;
		    }
		if(tt[i]!=i)
		    {
			printcode(i);
			j++;
		    }
	    }

	print "  \\\\";

	j=0;
	for(i=32;i<256;i++)
	    {
		if(j==11)
		    {
			printf "\\\\\n";
			j=0;
		    }
		if(tt[i]!=i)
		    {
			printcode(tt[i]);
			j++;
		    }
	    }
    }
print;
}
EOF
} >${tmpfile}.1

awk -f ${tmpfile}.1 >${tmpfile}.2

if [ "$gen" = yes ] ; then
    cat ${tmpfile}.2
else
    sh ${tmpfile}.2 ${files}
fi

rm ${tmpfile}.[12]

PART
