#!/usr/bin/perl

# Transform a MSGLIB message file into a "gencat" input file

%id = ();		# No assigned msgIDs so far
if(-e 'msglib.id' || -e 'MSGLIB.ID') {
	print STDERR "Reading msglib.id\n";
	die "Cannot open MSGLIB.ID" unless open(IN, 'msglib.id') || open(IN, 'MSGLIB.ID');
	while(<IN>) {
		($id, $num) = split(/\s+/, $_);
		$num =~ tr/A-Z/a-z/;
		die "Syntax error" if $id !~ /^[IWEMY]_/ || $num !~ /^0x[0-9a-f]+$/;
		die "Keyword $id defined multiple" if defined $id{$id} && $id{$id} ne $num;
		die "The message ID is assigned to two keywords: $id{$num} and $id" if defined $id{$num} && $id{$num} ne $id;
		$id{$id} = $num;
		$id{$num} = $id;
	}
	close IN;
}

$group = 0;
$lastGroup = -1;
while( ($file = shift) ) {
	if($file eq '-g') {
		$group = shift;
		die "Use option: -g group_number\n" unless $group =~ /^[0-9]$/;
		die "Group number must range 0..15" if $group < 0 || $group > 15;
	} elsif($file eq '-H') {
		$header = shift;
		die "Use option: -H file_name\n" unless $header;
	} elsif($file eq '-h' || $file eq '-?') {
		print "Transform a message file of MSGLIB into 'gencat' input

Useage: $0 {-g group_number | file}...

	-g assigns a group to all following files
";
		exit 1;
	} else {
			# Read a message file
		die "Cannot open file $file" unless open(IN, $file);
		print STDERR "Processing file: $file\n";
		if($lastGroup != $group) {
			# Change set number
			print "\$set $group\n";
			$lastGroup = $group;
		}
		$line = '';
		while( &readMsg ) {
			if(defined $id{$symMsgID}) {
				$numMsgID = $id{$symMsgID};
				die "Message $symMsgID already declared in group " . substr($numMsgID, 0, 3) if hex(substr($numMsgID, 0, 3)) != $group;
			} else {
				$numMsgID = 1;
				while(defined $id{sprintf("0x%04x", $numMsgID + ($group << 12))}) {
					if(++$numMsgID >= hex('0xfff')) {
						die "Too many messages in group #$group";
					}
				}
				$numMsgID += $group << 12;
				$numMsgID = sprintf("0x%04x", $numMsgID);
				$id{$numMsgID} = $symMsgID;
				$id{$symMsgID} = $numMsgID;
			}
			print hex(substr($numMsgID, 3)) . " $msgBody\n";
		}
		close IN;
	}
}

if($header) {
	die "Cannot create $header" unless open(OUT, ">$header");
	foreach $id (sort keys %id) {
		next if $id =~ /^\d/;
		print OUT "#define $id 0x" . substr($id{$id}, 3) . "\n";
	}
	close OUT;
}

exit 0;

sub readMsg {
	while($line !~ /^>>>>>>/) {
		return 0 unless $line = <IN>;
	}

	die "Syntax error" unless $line =~ /^>>>>>>\s*([EWMIY]_\S+)/;
	$symMsgID = $1;
	$msgBody = '';
	while(<IN>) {
		chop;
		($line = $_, return 1) if /^>>>>>>/;
		$msgBody .= "\\n" if $msgBody;
		$msgBody .= "\\\n$_";
	}
	$line = '';
	return 1;
}
