sbsv1_os/e32toolp/e32util/defutl.pm
changeset 0 83f4b4db085c
child 10 d4b442d23379
equal deleted inserted replaced
-1:000000000000 0:83f4b4db085c
       
     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 strict;
       
    29 use File::Path;
       
    30 use File::Basename;
       
    31 
       
    32 sub Def_ReadFileL ($$$$) {
       
    33 #	this function reads a .DEF file, putting the export information into a data
       
    34 #	structure
       
    35 
       
    36 	my ($DataStructRef, $FILE, $ExportsOn, $IgnoreSequence)=@_;
       
    37 
       
    38 #	initialisation
       
    39 	@$DataStructRef=();
       
    40 
       
    41 #	this function expects all statements to appear on separate lines - though MSVC doesn't
       
    42 
       
    43 	open (FILE, "<$FILE") or die "could not open $FILE: $!";
       
    44 
       
    45 	my $PreviousOrdinal=0;
       
    46 	my $MultiLineStatement='';
       
    47 	my $NAMEorLIBRARYallowed=1;
       
    48 	my $LineNum=0;
       
    49 	while (<FILE>) {
       
    50 		$LineNum++;
       
    51 
       
    52 		my %Data;
       
    53 		$Data{Line}=$_;
       
    54 		$Data{LineNum}=$LineNum;
       
    55 
       
    56 #		blank lines and comment lines
       
    57 		if (/^\s*(;.*)?$/o) {
       
    58 			push @$DataStructRef, \%Data;
       
    59 			next;
       
    60 		}
       
    61 
       
    62 		if (/^\s*(EXPORTS|SECTIONS|IMPORTS)\s*(\s+\S+.*)?$/io) {
       
    63 #			check for multi-line sections starting
       
    64 			$MultiLineStatement=uc $1;
       
    65 			$NAMEorLIBRARYallowed=0;
       
    66 			unless ($2) {
       
    67 				push @$DataStructRef, \%Data;
       
    68 				next;
       
    69 			}
       
    70 			$_=$2;
       
    71 		}
       
    72 		elsif (/^\s*(NAME|LIBRARY|DESCRIPTION|STACKSIZE|VERSION)\s*(\s+\S+.*)?$/io) {
       
    73 #			set MULTI-LINE statement to OFF
       
    74 			$MultiLineStatement='';
       
    75 #			check single-line statements are specified correctly
       
    76 			$_=uc $1;
       
    77 #			check NAME or LIBRARY statements aren't supplied incorrectly
       
    78 			if (/^(NAME|LIBRARY)$/o) {
       
    79 				unless ($NAMEorLIBRARYallowed) {
       
    80 					die "$FILE($LineNum) : DEFFILE ERROR: NAME or LIBRARY statements must precede all other statements\n";
       
    81 				}
       
    82 				push @$DataStructRef, \%Data;
       
    83 				next;
       
    84 			}
       
    85 			$NAMEorLIBRARYallowed=0;
       
    86 			push @$DataStructRef, \%Data;
       
    87 			next;
       
    88 		}
       
    89 		else {
       
    90 			unless ($MultiLineStatement) {
       
    91 				chomp $_;
       
    92 				die "$FILE($LineNum) : DEFFILE ERROR: Unrecognised Syntax \"$_\"\n";
       
    93 			}
       
    94 		}
       
    95 
       
    96 		if ($MultiLineStatement eq 'EXPORTS') {
       
    97 #			get export data
       
    98 			if (/^\s*(\S+)\s+\@\s*(\d+)\s*(NONAME)?\s*((DATA)\s*(\d+))?\s*(R3UNUSED)?\s*(ABSENT)?\s*(;\s*(.*))?$/io) {
       
    99 				$Data{Name}=$1;
       
   100 				$Data{Ordinal}=$2;
       
   101 				if ($4) {
       
   102 #					Mark the data symbols and retain the size.
       
   103 					$Data{Data} = 1;
       
   104 					if($6){
       
   105 					$Data{Size} = $6;
       
   106 					}
       
   107 				}
       
   108 				if ($7) {
       
   109 					$Data{R3Unused} = 1;
       
   110 				}
       
   111 				if ($8) {
       
   112 					$Data{Absent} = 1;
       
   113 				}
       
   114 				if ($10) {
       
   115 					$Data{Comment}=$10;
       
   116 				}
       
   117 
       
   118 				if ($Data{Name} =~ /^(\S+?)=(\S+)$/) {
       
   119 # 					rename this export
       
   120 					$Data{ExportName}=$1;
       
   121 					$Data{Name}=$2;
       
   122 					if ($Data{Name} =~ /=/) {
       
   123 						die "$FILE($LineNum) : DEFFILE ERROR: $Data{Name} Invalid rename syntax\n";
       
   124 					}
       
   125 				}
       
   126 				else {
       
   127 					$Data{ExportName}=$Data{Name};
       
   128 				}
       
   129 #				test the export - this is probably too slow to bother with
       
   130 				my $ExportRef;
       
   131 				unless ($IgnoreSequence) {
       
   132 #					check ordinal specified in sequence - this check is a style matter
       
   133 #					rather the a .DEF file syntax matter, so maybe it shouldn't be applied
       
   134 					unless ($Data{Ordinal}==($PreviousOrdinal+1)) {
       
   135 						die "$FILE($LineNum) : DEFFILE ERROR: Ordinal not specified in sequence\n";
       
   136 					}
       
   137 				}
       
   138 				$PreviousOrdinal=$Data{Ordinal};
       
   139 				push @$DataStructRef, \%Data;
       
   140 				next;
       
   141 			}
       
   142 			if (/^\s*_E32Startup(\s*\=\s*__E32Startup)?\s+(;\s*(.*))?$/io) {
       
   143 #				Emulator's special entrypoint ordinal
       
   144 				next;
       
   145 			}
       
   146 			if (/^\s*_E32Dll(\s*\=\s*__E32Dll)?\s+(;\s*(.*))?$/io) {
       
   147 #				Emulator's special entrypoint ordinal
       
   148 				next;
       
   149 			}
       
   150 			die "$FILE($LineNum) : DEFFILE ERROR: Incorrect EXPORTS statement syntax\n";
       
   151 		}
       
   152 
       
   153 	}
       
   154 
       
   155 #	decide whether we've ended up with an EXPORTS section specified
       
   156 	if ($MultiLineStatement eq 'EXPORTS') {
       
   157 		$_[2]=1; # $ExportsOn
       
   158 	}
       
   159 	else {
       
   160 		$_[2]=0; # $ExportsOn
       
   161 	}
       
   162 
       
   163 	close FILE or die "DEFFILE ERROR: Can't close file $FILE: $!\n";
       
   164 }
       
   165 
       
   166 sub Def_WriteFileL ($$) {
       
   167 #	Writes an array of text to a file
       
   168 
       
   169 	my ($TextArrayRef, $FILE)=@_;
       
   170 	
       
   171 	# make sure path exists
       
   172 	my($filename, $directories, $suffix) = fileparse($FILE);
       
   173 	unless (-d $directories) {
       
   174 		eval { mkpath[$directories] };
       
   175 		die $@ if $@;
       
   176 	} 
       
   177 
       
   178 	open (FILE, ">$FILE") or die "DEFFILE ERROR: Could not open $FILE: $!\n";
       
   179 	print FILE @$TextArrayRef or die "DEFFILE ERROR: Can't write output to $FILE: $!\n";
       
   180 	close FILE or die "DEFFILE ERROR: Can't close file $FILE: $!\n";
       
   181 }
       
   182 
       
   183 1;