#!/usr/bin/env perl

# fixes bug in floating point emulation on sparc64 when
# this script produces off-by-one output on sparc64
use integer;

if (scalar @ARGV != 2)
	{
	print "Usage: perl obj_dat.pl ../../include/openssl/nid.h obj_dat.h\n";
	exit 1;
	}

sub obj_cmp
	{
	local(@a,@b,$_,$r);

	$A=$obj_len{$obj{$nid{$a}}};
	$B=$obj_len{$obj{$nid{$b}}};

	$r=($A-$B);
	return($r) if $r != 0;

	$A=$obj_der{$obj{$nid{$a}}};
	$B=$obj_der{$obj{$nid{$b}}};

	return($A cmp $B);
	}

sub expand_obj
	{
	local(*v)=@_;
	local($k,$d);
	local($i);

	do	{
		$i=0;
		foreach $k (keys %v)
			{
			if (($v{$k} =~ s/(OBJ_[^,]+),/$v{$1},/))
				{ $i++; }
			}
		} while($i);
	foreach $k (keys %v)
		{
		@a=split(/,/,$v{$k});
		$objn{$k}=$#a+1;
		}
	return(%objn);
	}

open (IN,"$ARGV[0]") || die "Can't open input file $ARGV[0]";
open (OUT,">$ARGV[1]") || die "Can't open output file $ARGV[1]";

while (<IN>)
	{
	next unless /^\#define\s+(\S+)\s+(.*)$/;
	$v=$1;
	$d=$2;
	$d =~ s/^\"//;
	$d =~ s/\"$//;
	if ($v =~ /^SN_(.*)$/)
		{
		if(defined $snames{$d})
			{
			print "WARNING: Duplicate short name \"$d\"\n";
			}
		else 
			{ $snames{$d} = "X"; }
		$sn{$1}=$d;
		}
	elsif ($v =~ /^LN_(.*)$/)
		{
		if(defined $lnames{$d})
			{
			print "WARNING: Duplicate long name \"$d\"\n";
			}
		else 
			{ $lnames{$d} = "X"; }
		$ln{$1}=$d;
		}
	elsif ($v =~ /^NID_(.*)$/)
		{ $nid{$d}=$1; }
	elsif ($v =~ /^OBJ_(.*)$/)
		{
		$obj{$1}=$v;
		$objd{$v}=$d;
		}
	}
close IN;

%ob=&expand_obj(*objd);

@a=sort { $a <=> $b } keys %nid;
$n=$a[$#a]+1;

@lvalues=();
$lvalues=0;

for ($i=0; $i<$n; $i++)
	{
	if (!defined($nid{$i}))
		{
		push(@out,"{NULL,NULL,NID_undef,0,NULL,0},\n");
		}
	else
		{
		$sn=defined($sn{$nid{$i}})?"$sn{$nid{$i}}":"NULL";
		$ln=defined($ln{$nid{$i}})?"$ln{$nid{$i}}":"NULL";

		if ($sn eq "NULL") {
			$sn=$ln;
			$sn{$nid{$i}} = $ln;
		}

		if ($ln eq "NULL") {
			$ln=$sn;
			$ln{$nid{$i}} = $sn;
		}
			
		$out ="{";
		$out.="\"$sn\"";
		$out.=","."\"$ln\"";
		$out.=",NID_$nid{$i},";
		if (defined($obj{$nid{$i}}) && $objd{$obj{$nid{$i}}} =~ /,/)
			{
			$v=$objd{$obj{$nid{$i}}};
			$v =~ s/L//g;
			$v =~ s/,/ /g;
			$r=&der_it($v);
			$z="";
			$length=0;
			foreach (unpack("C*",$r))
				{
				$z.=sprintf("0x%02X,",$_);
				$length++;
				}
			$obj_der{$obj{$nid{$i}}}=$z;
			$obj_len{$obj{$nid{$i}}}=$length;

			push(@lvalues,sprintf("%-45s/* [%3d] %s */\n",
				$z,$lvalues,$obj{$nid{$i}}));
			$out.="$length,&(lvalues[$lvalues]),0";
			$lvalues+=$length;
			}
		else
			{
			$out.="0,NULL,0";
			}
		$out.="},\n";
		push(@out,$out);
		}
	}

@a=grep(defined($sn{$nid{$_}}),0 .. $n);
foreach (sort { $sn{$nid{$a}} cmp $sn{$nid{$b}} } @a)
	{
	push(@sn,sprintf("%2d,\t/* \"$sn{$nid{$_}}\" */\n",$_));
	}

@a=grep(defined($ln{$nid{$_}}),0 .. $n);
foreach (sort { $ln{$nid{$a}} cmp $ln{$nid{$b}} } @a)
	{
	push(@ln,sprintf("%2d,\t/* \"$ln{$nid{$_}}\" */\n",$_));
	}

@a=grep(defined($obj{$nid{$_}}) && $objd{$obj{$nid{$_}}} =~ /,/,0 .. $n);
foreach (sort obj_cmp @a)
	{
	$m=$obj{$nid{$_}};
	$v=$objd{$m};
	$v =~ s/L//g;
	$v =~ s/,/ /g;
	push(@ob,sprintf("%2d,\t/* %-32s %s */\n",$_,$m,$v));
	}

print OUT <<'EOF';
/* THIS FILE IS GENERATED FROM objects.h by obj_dat.pl via the
 * following command:
 * perl obj_dat.pl ../../include/openssl/nid.h obj_dat.h */

/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.] */

EOF

printf OUT "#define NUM_NID %d\n",$n;
printf OUT "#define NUM_SN %d\n",$#sn+1;
printf OUT "#define NUM_LN %d\n",$#ln+1;
printf OUT "#define NUM_OBJ %d\n\n",$#ob+1;

printf OUT "static const unsigned char lvalues[%d]={\n",$lvalues+1;
print OUT @lvalues;
print OUT "};\n\n";

printf OUT "static const ASN1_OBJECT kObjects[NUM_NID]={\n";
foreach (@out)
	{
	if (length($_) > 75)
		{
		$out="";
		foreach (split(/,/))
			{
			$t=$out.$_.",";
			if (length($t) > 70)
				{
				print OUT "$out\n";
				$t="\t$_,";
				}
			$out=$t;
			}
		chop $out;
		print OUT "$out";
		}
	else
		{ print OUT $_; }
	}
print  OUT "};\n\n";

printf OUT "static const unsigned int kNIDsInShortNameOrder[NUM_SN]={\n";
print  OUT @sn;
print  OUT "};\n\n";

printf OUT "static const unsigned int kNIDsInLongNameOrder[NUM_LN]={\n";
print  OUT @ln;
print  OUT "};\n\n";

printf OUT "static const unsigned int kNIDsInOIDOrder[NUM_OBJ]={\n";
print  OUT @ob;
print  OUT "};\n\n";

close OUT;

sub der_it
	{
	local($v)=@_;
	local(@a,$i,$ret,@r);

	@a=split(/\s+/,$v);
	$ret.=pack("C*",$a[0]*40+$a[1]);
	shift @a;
	shift @a;
	foreach (@a)
		{
		@r=();
		$t=0;
		while ($_ >= 128)
			{
			$x=$_%128;
			$_/=128;
			push(@r,((($t++)?0x80:0)|$x));
			}
		push(@r,((($t++)?0x80:0)|$_));
		$ret.=pack("C*",reverse(@r));
		}
	return($ret);
	}
