|
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; |