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