sbsv1/abld/e32util/defutl.pm
changeset 40 68f68128601f
equal deleted inserted replaced
39:fa9d7d89d3d6 40:68f68128601f
       
     1 # Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 # All rights reserved.
       
     3 # This component and the accompanying materials are made available
       
     4 # under the terms of "Eclipse Public License v1.0"
       
     5 # which accompanies this distribution, and is available
       
     6 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 #
       
     8 # Initial Contributors:
       
     9 # Nokia Corporation - initial contribution.
       
    10 #
       
    11 # Contributors:
       
    12 #
       
    13 # Description:
       
    14 # this module requires Pathutl module to have been 'used' by the main program
       
    15 # General Def file utilities
       
    16 # 
       
    17 #
       
    18 
       
    19 package Defutl;
       
    20 
       
    21 require Exporter;
       
    22 @ISA=qw(Exporter);
       
    23 
       
    24 @EXPORT=qw(
       
    25 	Def_ReadFileL Def_WriteFileL
       
    26 );
       
    27 
       
    28 use File::Path;
       
    29 use File::Basename;
       
    30 
       
    31 sub Def_ReadFileL ($$$$) {
       
    32 #	this function reads a .DEF file, putting the export information into a data
       
    33 #	structure
       
    34 
       
    35 	my ($DataStructRef, $FILE, $ExportsOn, $IgnoreSequence)=@_;
       
    36 
       
    37 #	initialisation
       
    38 	@$DataStructRef=();
       
    39 
       
    40 #	this function expects all statements to appear on separate lines - though MSVC doesn't
       
    41 
       
    42 	open (FILE, "<$FILE") or die "could not open $FILE: $!";
       
    43 
       
    44 	my $PreviousOrdinal=0;
       
    45 	my $MultiLineStatement='';
       
    46 	my $NAMEorLIBRARYallowed=1;
       
    47 	my $LineNum=0;
       
    48 	while (<FILE>) {
       
    49 		$LineNum++;
       
    50 
       
    51 		my %Data;
       
    52 		$Data{Line}=$_;
       
    53 		$Data{LineNum}=$LineNum;
       
    54 
       
    55 #		blank lines and comment lines
       
    56 		if (/^\s*(;.*)?$/o) {
       
    57 			push @$DataStructRef, \%Data;
       
    58 			next;
       
    59 		}
       
    60 
       
    61 		if (/^\s*(EXPORTS|SECTIONS|IMPORTS)\s*(\s+\S+.*)?$/io) {
       
    62 #			check for multi-line sections starting
       
    63 			$MultiLineStatement=uc $1;
       
    64 			$NAMEorLIBRARYallowed=0;
       
    65 			unless ($2) {
       
    66 				push @$DataStructRef, \%Data;
       
    67 				next;
       
    68 			}
       
    69 			$_=$2;
       
    70 		}
       
    71 		elsif (/^\s*(NAME|LIBRARY|DESCRIPTION|STACKSIZE|VERSION)\s*(\s+\S+.*)?$/io) {
       
    72 #			set MULTI-LINE statement to OFF
       
    73 			$MultiLineStatement='';
       
    74 #			check single-line statements are specified correctly
       
    75 			$_=uc $1;
       
    76 #			check NAME or LIBRARY statements aren't supplied incorrectly
       
    77 			if (/^(NAME|LIBRARY)$/o) {
       
    78 				unless ($NAMEorLIBRARYallowed) {
       
    79 					die "$FILE($LineNum) : DEFFILE ERROR: NAME or LIBRARY statements must precede all other statements\n";
       
    80 				}
       
    81 				push @$DataStructRef, \%Data;
       
    82 				next;
       
    83 			}
       
    84 			$NAMEorLIBRARYallowed=0;
       
    85 			push @$DataStructRef, \%Data;
       
    86 			next;
       
    87 		}
       
    88 		else {
       
    89 			unless ($MultiLineStatement) {
       
    90 				chomp $_;
       
    91 				die "$FILE($LineNum) : DEFFILE ERROR: Unrecognised Syntax \"$_\"\n";
       
    92 			}
       
    93 		}
       
    94 
       
    95 		if ($MultiLineStatement eq 'EXPORTS') {
       
    96 #			get export data
       
    97 			if (/^\s*(\S+)\s+\@\s*(\d+)\s*(NONAME)?\s*((DATA)\s*(\d+))?\s*(R3UNUSED)?\s*(ABSENT)?\s*(;\s*(.*))?$/io) {
       
    98 				$Data{Name}=$1;
       
    99 				$Data{Ordinal}=$2;
       
   100 				if ($4) {
       
   101 #					Mark the data symbols and retain the size.
       
   102 					$Data{Data} = 1;
       
   103 					if($6){
       
   104 					$Data{Size} = $6;
       
   105 					}
       
   106 				}
       
   107 				if ($7) {
       
   108 					$Data{R3Unused} = 1;
       
   109 				}
       
   110 				if ($8) {
       
   111 					$Data{Absent} = 1;
       
   112 				}
       
   113 				if ($10) {
       
   114 					$Data{Comment}=$10;
       
   115 				}
       
   116 
       
   117 				if ($Data{Name} =~ /^(\S+?)=(\S+)$/) {
       
   118 # 					rename this export
       
   119 					$Data{ExportName}=$1;
       
   120 					$Data{Name}=$2;
       
   121 					if ($Data{Name} =~ /=/) {
       
   122 						die "$FILE($LineNum) : DEFFILE ERROR: $Data{Name} Invalid rename syntax\n";
       
   123 					}
       
   124 				}
       
   125 				else {
       
   126 					$Data{ExportName}=$Data{Name};
       
   127 				}
       
   128 #				test the export - this is probably too slow to bother with
       
   129 				my $ExportRef;
       
   130 				unless ($IgnoreSequence) {
       
   131 #					check ordinal specified in sequence - this check is a style matter
       
   132 #					rather the a .DEF file syntax matter, so maybe it shouldn't be applied
       
   133 					unless ($Data{Ordinal}==($PreviousOrdinal+1)) {
       
   134 						die "$FILE($LineNum) : DEFFILE ERROR: Ordinal not specified in sequence\n";
       
   135 					}
       
   136 				}
       
   137 				$PreviousOrdinal=$Data{Ordinal};
       
   138 				push @$DataStructRef, \%Data;
       
   139 				next;
       
   140 			}
       
   141 			if (/^\s*_E32Startup(\s*\=\s*__E32Startup)?\s+(;\s*(.*))?$/io) {
       
   142 #				Emulator's special entrypoint ordinal
       
   143 				next;
       
   144 			}
       
   145 			if (/^\s*_E32Dll(\s*\=\s*__E32Dll)?\s+(;\s*(.*))?$/io) {
       
   146 #				Emulator's special entrypoint ordinal
       
   147 				next;
       
   148 			}
       
   149 			die "$FILE($LineNum) : DEFFILE ERROR: Incorrect EXPORTS statement syntax\n";
       
   150 		}
       
   151 
       
   152 	}
       
   153 
       
   154 #	decide whether we've ended up with an EXPORTS section specified
       
   155 	if ($MultiLineStatement eq 'EXPORTS') {
       
   156 		$_[2]=1; # $ExportsOn
       
   157 	}
       
   158 	else {
       
   159 		$_[2]=0; # $ExportsOn
       
   160 	}
       
   161 
       
   162 	close FILE or die "DEFFILE ERROR: Can't close file $FILE: $!\n";
       
   163 }
       
   164 
       
   165 sub Def_WriteFileL ($$) {
       
   166 #	Writes an array of text to a file
       
   167 
       
   168 	my ($TextArrayRef, $FILE)=@_;
       
   169 	
       
   170 	# make sure path exists
       
   171 	my($filename, $directories, $suffix) = fileparse($FILE);
       
   172 	unless (-d $directories) {
       
   173 		eval { mkpath[$directories] };
       
   174 		die $@ if $@;
       
   175 	} 
       
   176 
       
   177 	open (FILE, ">$FILE") or die "DEFFILE ERROR: Could not open $FILE: $!\n";
       
   178 	print FILE @$TextArrayRef or die "DEFFILE ERROR: Can't write output to $FILE: $!\n";
       
   179 	close FILE or die "DEFFILE ERROR: Can't close file $FILE: $!\n";
       
   180 }
       
   181 
       
   182 1;