# MMP.PM
#
# Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
#


# Processes an mmp file and sets up subroutines to return the data

package Mmp;

require Exporter;
@ISA=qw(Exporter);

@EXPORT=qw(
	Mmp_SetVerbose
	Mmp_ProcessL

	Mmp_AifHash
	Mmp_AllowDllData
	Mmp_BaseFirstObj
	Mmp_BaseObjList
	Mmp_BitMapHash 
	Mmp_CallDllEntryPoints
	Mmp_DataLinkAddress
	Mmp_Def
	Mmp_DocHash
	Mmp_FixedProcess
	Mmp_HeapSize
	Mmp_LangList
	Mmp_LibList 
	Mmp_LinkAs
	Mmp_LongBldPath
	Mmp_MmpFlag
	Mmp_PlatTxt2D
	Mmp_Prj
	Mmp_ProcessPriority
	Mmp_ResrcHash
	Mmp_SrcHash
	Mmp_StackSize
	Mmp_SubPrjHash
	Mmp_SysIncPaths
	Mmp_SysResrcHash
	Mmp_Trg
	Mmp_TrgPath
	Mmp_TrgType
	Mmp_UidList
	Mmp_UnicodeUidList
	Mmp_UserIncPaths
);


use Genutl;
use Prepfile;
use Pathutl;

my %Mode;

my @Mmp2D;
my $MMPFILE;
my @MmpMacros;

my $AllowDllData=0;
my %AifHash;
my @BaseObjList;
my %BitMapHash;
my $CallDllEntryPoints=0;
my $DataLinkAddress='';
my %Def;
$Def{Path}='';
$Def{Base}='';
$Def{Ext}='';
my %DocHash;
my $FirstObj;
my $FixedProcess=0;
my %HeapSize;
my @LangList;
my @LibList;
my $LinkAs;
my $LongBldPath;
my %MmpFlag;
my @PlatTxt2D;
my $Prj;
my $ProcessPriority='';
my %ResrcHash;
my %SrcHash;    
my $StackSize='';
my %SubPrjHash;
my @SysIncPaths;
my %SysResrcHash;
my $Trg;
my $TrgPath='';
my $TrgType;
my @UidList;
my @UnicodeUidList;
my @UserIncPaths;


BEGIN {
	$Mode{'Verbose'}=0;
}

sub Mmp_SetVerbose () {
	$Mode{'Verbose'}=1;
}

sub Mmp_ProcessL ($@) {
	($MMPFILE,@MmpMacros)=@_;


	if ($Mode{Verbose}) {
		&Prepfile_SetVerbose;
	}

# preprocess the project description file
	eval { &Prepfile_ProcessL(\@Mmp2D,$MMPFILE,@MmpMacros); };
	die $@ if $@;


	my @MmpDie=();
	my @MmpWarn=();

	my $OtherPlatSwitch;
	my $PlatTxtSwitch;

	my $MyCurSubPrj;
	my $MmpMacro;
	my $Line;

# process the data structure
	LINE: foreach $Line (@Mmp2D) {
		my $LineNum=shift @$Line;
		$_=shift @$Line;

		if ($PlatTxtSwitch) { 
			if (/^END$/o) {
				$PlatTxtSwitch=0;
				next LINE;
			}
			push @PlatTxt2D, [ $LineNum, $_, @$Line ];
			next LINE;
		}
		if ($OtherPlatSwitch) {
			if (/^END$/o) {
				$OtherPlatSwitch=0;
				next LINE;
			}
			next LINE;
		}
		if (/^START$/) {
			if ($_=shift @$Line) {
				foreach $MmpMacro (@MmpMacros) {
					if ($_ eq $MmpMacro) {
						$PlatTxtSwitch=$LineNum;
						next LINE;
					}
				}
				$OtherPlatSwitch=$LineNum;
				next LINE;
			}
			$OtherPlatSwitch=$LineNum;
			push @MmpWarn, "$LineNum: No Platform specified for START block\n";
			next LINE;
		}

		if (/^AIF$/o) {
			if ($AifHash{'Aif'}) {
				push @MmpWarn, "$LineNum: Attempt to redefine AIF\n";
				next LINE;
			}
			if ($_=shift @$Line) {
				if ($MyCurSubPrj) {
					$AifHash{'Aif'}=$_;
					$AifHash{'SubPrj'}=$MyCurSubPrj;
					next LINE;
				}
				push @MmpDie, "$LineNum: Subproject not specified for AIF \"$_\"\n";
				next LINE;
			}
			push @MmpWarn, "$LineNum: No File specified for keyword AIF\n";
			next LINE;
		}
		if (/^BITMAP$/o) {
			if ($_=shift @$Line) {
				if ($MyCurSubPrj) {
					if (push @{$BitMapHash{$MyCurSubPrj}{$_}}, @$Line) {
						next LINE;
					}
					push @MmpDie, "$LineNum: No source bitmaps specified for target BITMAP \"$_\"\n";
					next LINE;
				}
				push @MmpDie, "$LineNum: Subproject not specified for sources for BITMAP \"$_\"\n";
				next LINE;
			}
			push @MmpWarn, "$LineNum: No Target specified for keyword BITMAP\n";
			next LINE;
		}
		if (/^DEFFILE$/o)  {
			if ($Def{Base}) {
				push @MmpWarn, "$LineNum: Attempt to redefine DEFFILE\n";
				next LINE;
			}
			if ($_=shift @$Line) {
				$Def{Base}=&Path_Split('Base',$_);
				$Def{Ext}=&Path_Split('Ext',$_);
				$Def{Path}=&Path_Split('Path',$_);
				if ($Def{Path}) {
					$Def{Path}=&Path_MakeAbs($MMPFILE,$Def{Path});
				}
				next LINE;
			}
			push @MmpWarn, "$LineNum: No File specified for keyword DEFFILE\n";
			next LINE;
		}
		if (/^DOCUMENT$/o) {
			if (@$Line) {
				if ($MyCurSubPrj) {
					push @{$DocHash{$MyCurSubPrj}}, @$Line;
					next LINE;
				}
				push @MmpDie, "$LineNum: Subproject not specified for Document(s) \"@$Line\"\n";
				next LINE;
			}
			push @MmpWarn, "$LineNum: No Files specified for keyword DOCUMENT\n";
			next LINE;
		}
		if (/^EPOCALLOWDLLDATA$/o) {
			if (@$Line) {
				push @MmpWarn, "$LineNum: Keyword $_ takes no arguments\n";
			}
			$AllowDllData=1;
			next LINE;
		}
		if (/^EPOCCALLDLLENTRYPOINTS$/o) {
			if (@$Line) {
				push @MmpWarn, "$LineNum: Keyword $_ takes no arguments\n";
			}
			$CallDllEntryPoints=1;
			next LINE;
		}
		if (/^EPOCDATALINKADDRESS$/o) {
			if (@$Line) { 
				my $temp=&main::Genutl_AnyToHex(shift @$Line);
				if (defined $temp) {
					$DataLinkAddress=$temp;
					next LINE;
				}
				push @MmpDie, "$LineNum: Data link address doesn't fit expected number format\n";
			}
			push @MmpWarn, "$LineNum: No data link address specified for keyword $_\n";
			next LINE;
		}
		if (/^EPOCFIXEDPROCESS$/o) {
			if (@$Line) {
				push @MmpWarn, "$LineNum: Keyword $_ takes no arguments\n";
			}
			$FixedProcess=1;
			next LINE;
		}
		if (/^EPOCHEAPSIZE$/o) {
			if (@$Line) {
				my $tempMin=&main::Genutl_AnyToHex(shift @$Line);
				if (defined $tempMin) {
					if (@$Line) {
						my $tempMax=&main::Genutl_AnyToHex(shift @$Line);
						if (defined $tempMax) {
							$HeapSize{Min}=$tempMin;
							$HeapSize{Max}=$tempMax;
							next LINE;
						}
						push @MmpDie, "$LineNum: maximum heap size doesn't fit expected number format\n";
						next LINE;
					}
					push @MmpDie, "$LineNum: No maximum heap size specified for keyword $_\n";
					next LINE;
				}
				push @MmpDie, "$LineNum: minimum heap size doesn't fit expected number format\n";
				next LINE;
			}
			push @MmpWarn, "$LineNum: No minimum heap size specified for keyword $_\n";
			next LINE;
		}
		if (/^EPOCPROCESSPRIORITY$/o) {
			if ($ProcessPriority) {
				push @MmpWarn, "$LineNum: Attempt to redefine EPOCPROCESSPRIORITY\n";
				next LINE;
			}
			if ($ProcessPriority=shift @$Line) {
				if ($ProcessPriority=~/^(LOW|BACKGROUND|FOREGROUND|HIGH|WINDOWSERVER|FILESERVER|REALTIMESERVER|SUPERVISOR)$/o) {
					next LINE;
				}
				push @MmpDie, "$LineNum: ProcessPriority \"$ProcessPriority\" not supported\n";
				next LINE;
			}
			push @MmpWarn, "$LineNum: No Priority specified for keyword EPOCPROCESSPRIORITY\n";
			next LINE;
		}
		if (/^EPOCSTACKSIZE$/o) {
			if (@$Line) {
				my $temp=&main::Genutl_AnyToHex(shift @$Line);
				if (defined $temp) {
					$StackSize=$temp;
					next LINE;
				}
				push @MmpDie, "$LineNum: Stack size doesn't fit expected number format\n";
				next LINE;
			}
			push @MmpWarn, "$LineNum: No stack size specified for keyword STACKSIZE\n";
			next LINE;
		}
		if (/^FIRSTOBJECT$/o) {
			if ($FirstObj) {
				push @MmpWarn, "$LineNum: Attempt to redefine FIRSTOBJECT\n";
				next LINE;
			}
			if ($FirstObj=shift @$Line) {
				next LINE;
			}
			push @MmpWarn, "$LineNum: No Object specified for keyword FIRSTOBJECT\n";
			next LINE;
		}
		if (/^LANG$/o) {
			if (@$Line) {
				my $Candidate;
				my $Accepted;
				CANDLOOP: foreach $Candidate (@$Line) {
					foreach $Accepted (@LangList) {
						if ($Candidate eq $Accepted) {
							push @MmpWarn, "$LineNum: Duplicate Language $Candidate removed\n";
							next CANDLOOP; 
						}
					}
					push @LangList, $Candidate;
				}
				next LINE;
			}
			push @MmpWarn, "$LineNum: No Languages specified for keyword LANG\n";
			next LINE;
		}
		if (/^LIBRARY$/o) {
			if (@$Line) {
				my $Candidate;
				my $Accepted;
				CANDLOOP: foreach $Candidate (@$Line) {
					foreach $Accepted (@LibList) {
						if ($Candidate eq $Accepted) {
							push @MmpWarn, "$LineNum: Duplicate Library $Candidate removed\n";
							next CANDLOOP; 
						}
					}
					push @LibList, $Candidate;
				}
				next LINE;
			}
			push @MmpWarn, "$LineNum: No Libraries specified for keyword LIBRARY\n";
			next LINE;
		}
		if (/^LINKAS$/o) {
			if ($LinkAs) {
				push @MmpWarn, "$LineNum: Attempt to redefine LINKAS\n";
				next LINE;
			}
			if ($LinkAs=shift @$Line) {
				next LINE;
			}
			push @MmpWarn, "$LineNum: No name specified for keyword LINKAS\n";
			next LINE;
		}
		if (/^LONGBLDPATH$/o) {
			if ($LongBldPath) {
				push @MmpWarn, "$LineNum: Attempt to redefine LONGBLDPATH\n";
				next LINE;
			}
			if ($LongBldPath=shift @$Line) {
				$LongBldPath=~s-^\\(.*)$-$1-o;  # in case people mistakenly specify abs path for longbldpath
				next LINE;
			}
			$LongBldPath=&Path_Split('Base',$MMPFILE);
			next LINE;
		}
		if (/^NOSTRICTDEF$/o) {
			if ($MmpFlag{NoStrictDef}) {
				push @MmpWarn, "$LineNum: NOSTRICTDEF already set\n";
				next LINE;
			}
			if (@$Line) {
				push @MmpWarn, "$LineNum: Keyword NOSTRICTDEF takes no arguments\n";
			}
			$MmpFlag{NoStrictDef}=1;
			next LINE;
		}
		if (/^OBJECT$/o) {
			if (push @BaseObjList, @$Line) {
				next LINE;
			}
			push @MmpWarn, "$LineNum: No Objects specified for keyword OBJECT\n";
			next LINE;
		}
		if (/^PROJECT$/o) {
			if ($Prj) {
				push @MmpWarn, "$LineNum: Attempt to redefine PROJECT\n";
				next LINE;
			}
			if ($Prj=shift @$Line) {
				$Prj=~s-^\\(.*)$-$1-o;  # in case people mistakenly specify path for prj
				if (-d "\\$Prj") {
					next LINE;
				}
				push @MmpWarn, "$LineNum: PROJECT directory \"\\$Prj\" not found\n";
				next LINE;
			}
			push @MmpWarn, "$LineNum: No Project specified for keyword PROJECT\n";
			next LINE;
		}
		if (/^RESOURCE$/o) {
			if (@$Line) {
				if ($MyCurSubPrj) {
					my $Candidate;
					my $Accepted;
					my $SubPrj;
					CANDLOOP: foreach $Candidate (@$Line) {
						foreach $SubPrj (keys %SubPrjHash) {
							foreach $Accepted (@{$ResrcHash{$SubPrj}}) {
								if ($Candidate eq $Accepted) {
									push @MmpDie, "$LineNum: Duplicate Resource $Candidate specified\n";
									next CANDLOOP; 
								}
							}
						}
						push @{$ResrcHash{$MyCurSubPrj}}, $Candidate;
					}
					next LINE;
				}
				push @MmpDie, "$LineNum: Subproject not specified for Resource(s) \"@$Line\"\n";
				next LINE;
			}
			push @MmpWarn, "$LineNum: No Resources specified for keyword RESOURCE\n";
			next LINE; 
		}
		if (/^SOURCE$/o) {
			if (@$Line) {
				if ($MyCurSubPrj) {
					my $Candidate;
					my $Accepted;
					my $SubPrj;
					CANDLOOP: foreach $Candidate (@$Line) {
						foreach $SubPrj (keys %SubPrjHash) {
							foreach $Accepted (@{$SrcHash{$SubPrj}}) {
								if ($Candidate eq $Accepted) {
									push @MmpDie, "$LineNum: Duplicate Source $Candidate specified\n";
									next CANDLOOP; 
								}
							}
						}
						push @{$SrcHash{$MyCurSubPrj}}, $Candidate;
					}
					next LINE;
				}
				push @MmpDie, "$LineNum: Subproject not specified for Source(s) \"@$Line\"\n";
				next LINE;
			}
			push @MmpWarn, "$LineNum: No Sources specified for keyword SOURCE\n";
			next LINE; 
		}
		if (/^STRICTDEPEND$/o) {
			if ($MmpFlag{StrictDepend}) {
				push @MmpWarn, "$LineNum: STRICTDEPEND already set\n";
				next LINE;
			}
			if (@$Line) {
				push @MmpWarn, "$LineNum: Keyword STRICTDEPEND takes no arguments\n";
			}
			$MmpFlag{StrictDepend}=1;
			next LINE;
		}
		if (/^SUBPROJECT$/o) {
			if ($Prj) {
				if ($MyCurSubPrj=shift @$Line) {
					$MyCurSubPrj=~s-^(.*[^\\])$-$1\\-o;	# in case no terminating backslash
					$MyCurSubPrj=&Path_MakeAbs("\\$Prj\\",$MyCurSubPrj);	# relative subproject paths treated as relative to the project
					@{$SubPrjHash{$MyCurSubPrj}}=();
					@{$DocHash{$MyCurSubPrj}}=() unless defined @{$DocHash{$MyCurSubPrj}};
					@{$ResrcHash{$MyCurSubPrj}}=() unless defined @{$ResrcHash{$MyCurSubPrj}};
					@{$SrcHash{$MyCurSubPrj}}=() unless defined @{$SrcHash{$MyCurSubPrj}};
					@{$SysResrcHash{$MyCurSubPrj}}=() unless defined @{$SysResrcHash{$MyCurSubPrj}};
					if (-d &Path_ChopPath($MyCurSubPrj)) {
						next LINE;
					}
					push @MmpWarn, "$LineNum: SUBPROJECT directory \"$MyCurSubPrj\" not found\n";
					next LINE;
				}
				push @MmpDie, "$LineNum: No Subproject specified for keyword SUBPROJECT\n";
				next LINE;
			}
			push @MmpDie, "$LineNum: PROJECT not specified before Subproject\n";
			next LINE;
		}
		if (/^SYSTEMINCLUDE$/o){
			if (@$Line) {
				my $Candidate;
				my $Accepted;
				CANDLOOP: foreach $Candidate (@$Line) {
					$Candidate=~s-^(.*[^\\])$-$1\\-o;   # ensure path ends with a backslash
					$Candidate=&Path_MakeAbs($MMPFILE,$Candidate);
					foreach $Accepted (@SysIncPaths) {
						if ($Candidate eq $Accepted) {
							push @MmpWarn, "$LineNum: Duplicate SYSTEMINCLUDE path $Candidate removed\n";
							next CANDLOOP; 
						}
					}
					push @SysIncPaths,$Candidate;
					if (-d &Path_ChopPath($Candidate)) {
						next;
					}
					push @MmpWarn, "$LineNum: SYSTEMINCLUDE path \"$Candidate\" not found\n";
				}
				next LINE;
			}
			push @MmpWarn, "$LineNum: No Paths specified for keyword SYSTEMINCLUDE\n";
			next LINE;
		}
		if (/^SYSTEMRESOURCE$/o) {
			if (@$Line) {
				if ($MyCurSubPrj) {
					my $Candidate;
					my $Accepted;
					my $SubPrj;
					CANDLOOP: foreach $Candidate (@$Line) {
						foreach $SubPrj (keys %SubPrjHash) {
							foreach $Accepted (@{$SysResrcHash{$SubPrj}}) {
								if ($Candidate eq $Accepted) {
									push @MmpDie, "$LineNum: Duplicate Resource $Candidate specified\n";
									next CANDLOOP; 
								}
							}
						}
						push @{$SysResrcHash{$MyCurSubPrj}}, $Candidate;
					}
					next LINE;
				}
				push @MmpDie, "$LineNum: Subproject not specified for System Resource(s) \"@$Line\"\n";
				next LINE;
			}
			push @MmpWarn, "$LineNum: No Resources specified for keyword SYSTEMRESOURCE\n";
			next LINE; 
		}
		if (/^TARGET$/o) {
			if ($Trg) {
				push @MmpWarn, "$LineNum: Attempt to redefine TARGET\n";
				next LINE;
			}
			if ($Trg=shift @$Line) {
				next LINE;
			}
			push @MmpWarn, "$LineNum: No Target specified for keyword TARGET\n";
			next LINE;
		}
		if (/^TARGETPATH$/o) {
			if ($TrgPath) {
				push @MmpWarn, "$LineNum: Attempt to redefine TARGETPATH\n";
				next LINE;
			}
			if ($TrgPath=shift @$Line) {
				$TrgPath=~s-^\\(.*)$-$1-o;
				$TrgPath=~s-^(.*[^\\])$-$1\\-o;
				$TrgPath="Z\\$TrgPath";
				next LINE;
			}
			push @MmpWarn, "$LineNum: No Path specified for keyword TARGETPATH\n";
			next LINE;
		}
		if (/^TARGETTYPE$/o) {
			if ($TrgType) {
				push @MmpWarn, "$LineNum: Attempt to redefine TARGETTYPE\n";
				next LINE;
			}
			if ($TrgType=shift @$Line) {
				if ($TrgType=~/^(APP|DLL|EXE|EXEDLL|FSY|IMPLIB|LDD|LIB|PDD)$/o) {
					next LINE;
				}
				push @MmpDie, "$LineNum: TargetType \"$TrgType\" not supported\n";
				next LINE;
			}
			push @MmpWarn, "$LineNum: No Type specified for keyword TARGETTYPE\n";
			next LINE;
		}
		if (/^UID$/o) {
			if (@$Line) {
				foreach (@$Line) {
					if ($#UidList>=1) {
						push @MmpWarn, "$LineNum: Can't specify more than 2 Uids\n";
						next LINE;
					}
					$_=&Genutl_AnyToHex($_);
					if (defined $_) {
						push @UidList, $_;
						next;
					}
					push @MmpDie, "$LineNum: Uid doesn't fit expected number format\n";
					next LINE;
				}
				next LINE;
			}
			push @MmpWarn, "$LineNum: No Uids specified for keyword UID\n";
			next LINE;
		}
		if (/^UNICODEUID$/o) {
			if (@$Line) {
				foreach (@$Line) {
					if ($#UnicodeUidList>=1) {
						push @MmpWarn, "$LineNum: Can't specify more than 2 Unicode Uids\n";
						next LINE;
					}
					$_=&Genutl_AnyToHex($_);
					if (defined $_) {
						push @UnicodeUidList, $_;
						next;
					}
					push @MmpDie, "$LineNum: Unicode Uid doesn't fit expected number format\n";
					next LINE;
				}
				next LINE;
			}
			push @MmpWarn, "$LineNum: No Unicode Uids specified for keyword UNICODEUID\n";
			next LINE;
		}
		if (/^USERINCLUDE$/o) {
			if (@$Line) {
				my $Candidate;
				my $Accepted;
				CANDLOOP: foreach $Candidate (@$Line) {
					$Candidate=~s-^(.*[^\\])$-$1\\-o;   # ensure path ends with a backslash
					$Candidate=&Path_MakeAbs($MMPFILE,$Candidate);
					foreach $Accepted (@UserIncPaths) {
						if ($Candidate eq $Accepted) {
							push @MmpWarn, "$LineNum: Duplicate USERINCLUDE path $Candidate removed\n";
							next CANDLOOP; 
						}
					}
					push @UserIncPaths,$Candidate;
					if (-d &Path_ChopPath($Candidate)) {
						next;
					}
					push @MmpWarn, "$LineNum: USERINCLUDE path \"$Candidate\" not found\n";
				}
				next LINE;
			}
			push @MmpWarn, "$LineNum: No Paths specified for keyword USERINCLUDE\n";
			next LINE;
		}
		push @MmpWarn, "$LineNum: Unrecognised Keyword \"$_\"\n";
	}

	undef $Line;
	undef $MmpMacro;
	undef $MyCurSubPrj;             # unset Current SubProject

	# test the mmp contents
	#----------------------
	if ($PlatTxtSwitch || $OtherPlatSwitch)	{
		push @MmpDie, $PlatTxtSwitch ? $PlatTxtSwitch : $OtherPlatSwitch, ": Unterminated START ... END block\n";
	}
	undef $PlatTxtSwitch;
	undef $OtherPlatSwitch;

	# add errors that can't be trapped during mmp processing
	push @MmpDie, "ERROR: No Project specified\n" unless $Prj;
	push @MmpDie, "ERROR: No Sources specified\n" unless %SrcHash;
	push @MmpDie, "ERROR: No SubProjects specified\n" unless keys %SubPrjHash;
	push @MmpDie, "ERROR: No Target specified\n" unless $Trg;
	push @MmpDie, "ERROR: No TargetType specified\n" unless $TrgType;
	push @MmpWarn, "WARNING: No Uid3 specified in \"$MMPFILE\" for TargetType \"$TrgType\"\n" if $TrgType=~/^APP$/o && $#UidList<1;
	push @MmpWarn, "WARNING: No Unicode Uid3 specified in \"$MMPFILE\" for TargetType \"$TrgType\"\n" if $TrgType=~/^APP$/o && $#UnicodeUidList<1;
	push @MmpWarn, "WARNING: No Unicode Uids specified - only ascii makefile targets will be available\n" if $UidList[0] && (not $UnicodeUidList[0]);

	if (@MmpDie || @MmpWarn) {
		warn "\nMMPFILE \"$MMPFILE\"\n";
		if (@MmpWarn) {
			warn
				"WARNING(S)\n",
				@MmpWarn,
				"\n"
			;
		}
		if (@MmpDie) {
			warn
				"FATAL ERROR(S)\n",
				@MmpDie
			;
			exit;
		}
	}

	# check for languages
	@LangList=('SC') unless @LangList;

	# finish off the uid lists
	while ($#UidList<1) {
		push @UidList, '0x00000000';
	}
	while ($#UnicodeUidList<1) {
		push @UnicodeUidList, '0x00000000';
	}
	if ($UidList[0]=~/^0x00000000$/o) { # put in second uid for known targetypes without them
		if ($TrgType=~/^APP$/o) {
			$UidList[0]='0x1000006c';
		}
		elsif ($TrgType=~/^FSY$/o) {
			$UidList[0]='0x1000008f';
		}
		elsif ($TrgType=~/^LDD$/o) {
			$UidList[0]='0x100000ae';
		}
		elsif ($TrgType=~/^PDD$/o) {
			$UidList[0]='0x100000ad';
		}
		# if ascii uids not specified we can automate the unicode ones too, but we shouldn't
		# if the ascii ones are specified but the unicode ones are not
		if ($UnicodeUidList[0]=~/^0x00000000$/o) { # put in second unicode uid for known targetypes without them
			if ($TrgType=~/^APP$/o) {
				$UnicodeUidList[0]='0x100039ce';
			}
			elsif ($TrgType=~/^FSY$/o) {
				$UnicodeUidList[0]='0x100039df';
			}
			elsif ($TrgType=~/^LDD$/o) {
				$UnicodeUidList[0]='0x100000af';
			}
			elsif ($TrgType=~/^PDD$/o) {
				$UnicodeUidList[0]='0x100039d0';
			}
		}
	}



	$LinkAs=$Trg unless $LinkAs;
		
}


sub Mmp_AifHash () {
	%AifHash;
}
sub Mmp_AllowDllData () {
	$AllowDllData;
}
sub Mmp_BaseFirstObj () {
	$FirstObj;
}
sub Mmp_BaseObjList () {
	@BaseObjList;
}
sub Mmp_BitMapHash () {
	%BitMapHash;
}
sub Mmp_CallDllEntryPoints () {
	$CallDllEntryPoints;
}
sub Mmp_DataLinkAddress () {
	$DataLinkAddress;
}
sub Mmp_Def () {
	%Def;
}
sub Mmp_DocHash () {
	%DocHash;
}
sub Mmp_FixedProcess () {
	$FixedProcess;
}
sub Mmp_HeapSize () {
	%HeapSize;
}
sub Mmp_LangList () {
	@LangList;
}
sub Mmp_LibList () {
	@LibList;
}
sub Mmp_LinkAs () {
	$LinkAs;
}
sub	Mmp_LongBldPath () {
	$LongBldPath;
}
sub Mmp_MmpFlag () {
	%MmpFlag;
}
sub	Mmp_PlatTxt2D () {
	@PlatTxt2D;
}
sub Mmp_Prj () {
	$Prj;
}
sub Mmp_ProcessPriority () {
	$ProcessPriority;
}
sub Mmp_ResrcHash () {
	%ResrcHash;
}
sub Mmp_SrcHash () {
	%SrcHash;
}
sub Mmp_StackSize () {
	$StackSize;
}
sub Mmp_SubPrjHash () {
	%SubPrjHash;
}
sub Mmp_SysIncPaths () {
	@SysIncPaths;
}
sub Mmp_SysResrcHash () {
	%SysResrcHash;
}
sub Mmp_Trg () {
	$Trg;
}
sub Mmp_TrgPath () {
	$TrgPath;
}
sub Mmp_TrgType () {
	$TrgType;
}
sub Mmp_UidList () {
	@UidList;
}
sub Mmp_UnicodeUidList () {
	@UnicodeUidList;
}
sub	Mmp_UserIncPaths () {
	@UserIncPaths;
}

1;
