|
1 # Copyright (c) 2003-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 # |
|
15 |
|
16 use strict; |
|
17 use Getopt::Long; |
|
18 |
|
19 # read in the command line parameters |
|
20 my $verbose = 0; |
|
21 my $singleLevel = 0; |
|
22 my $fromBatchFile = 0; |
|
23 my $help = 0; |
|
24 GetOptions( 'verbose|v!' => \$verbose, |
|
25 '1!' => \$singleLevel, |
|
26 'help|h|?!' => \$help, |
|
27 '--fromBatchFile!' => \$fromBatchFile ); |
|
28 Usage() if $help; |
|
29 my $file = $ARGV[0]; |
|
30 if(!defined($file)) |
|
31 { |
|
32 $file = "$ENV{EPOCROOT}EPOC32\\WINSCW\\C\\LOGS\\LOG.TXT"; |
|
33 $file = "$ENV{EPOCROOT}EPOC32\\WINS\\C\\LOGS\\LOG.TXT" if(!-r $file); |
|
34 print "No file specified, defaulting to $file\n"; |
|
35 } |
|
36 print "Verbose mode on\n" if $verbose; |
|
37 |
|
38 # open up the file for input |
|
39 open(INPUT_FILE, "< $file") or die "ERROR: Couldn't open the file \"$file\" for input:"; |
|
40 |
|
41 # read file without intepretting CR/LF - not ideal on window's systems, but |
|
42 # I introduced this to get around apparent problem when seeking back when reading binary data |
|
43 # The seek back seemed to seek to somewhere other than where we had last "tell"'ed. |
|
44 # binmode fixes this since CR/LF is always seen as 2 distinct chars. |
|
45 binmode(INPUT_FILE); |
|
46 |
|
47 # declare handy arrays |
|
48 my %file_handles_text; # a hash of all components seen for ascii and their associated file handle |
|
49 my %file_handles_binary; # a hash of all components seen for binary and their associated file handle |
|
50 my @comments; # an array of all the comment lines seen so far |
|
51 |
|
52 # iterate through each line of the file |
|
53 my $filepos = tell(INPUT_FILE); |
|
54 my $linenum = 1; |
|
55 while (<INPUT_FILE>) { |
|
56 # strip off any CR/LF's since we will correctly terminate the line by one |
|
57 # if we find the line is ascii. Binary lines should also arrive with a CR/LF at their end. |
|
58 my $line = $_; |
|
59 print $line if $verbose; |
|
60 chomp($line); |
|
61 |
|
62 my $strlen = length($line); |
|
63 if (($strlen == 0) || (ord "$line" == 13)) { |
|
64 if ($verbose) { print "Line#: $linenum is an empty line.\n"; } |
|
65 } else { |
|
66 $line =~ s/\r$//; # chomp CR |
|
67 if ($line =~ /^#/) { |
|
68 # we are dealing with a comment line |
|
69 $line .= "\n"; |
|
70 push(@comments, "$line"); |
|
71 while((my $component, my $file_handle) = each(%file_handles_text)) { |
|
72 print $file_handle "$line" |
|
73 } |
|
74 } |
|
75 else { |
|
76 #we are dealing with a component line so check the correct line format and determine if it is ascii or binary |
|
77 my @list = split("\t", $line); |
|
78 |
|
79 my $linetype = "$list[2]"; |
|
80 |
|
81 if (ord "$linetype" == 97) { |
|
82 # this is ascii, so return a CR/LF to line |
|
83 $line .= "\n"; |
|
84 my $component = lc($list[0] . ($singleLevel? "": "_$list[1]") . ".log"); |
|
85 if (not exists $file_handles_text{$component}) { |
|
86 # we haven't seen this component before |
|
87 local *OUTFILE; |
|
88 open(OUTFILE, "> $component") or die "ERROR. Line $linenum: can't open file \"$component\" for output: $!"; |
|
89 foreach my $comment (@comments) { |
|
90 print OUTFILE "$comment"; |
|
91 } |
|
92 $file_handles_text{$component} = *OUTFILE; |
|
93 } |
|
94 my $file_handle = $file_handles_text{$component}; |
|
95 print $file_handle "$line"; |
|
96 } elsif (ord "$linetype" == 98) { |
|
97 #assume it is binary |
|
98 my $component = "$list[0]_$list[1].bin"; |
|
99 if (not exists $file_handles_binary{$component}) { |
|
100 # we haven't seen this component before |
|
101 local *OUTFILE; |
|
102 open(OUTFILE, "> $component") or die "ERROR. Line $linenum: can't open file \"$component\" for output: $!"; |
|
103 binmode(OUTFILE); |
|
104 $file_handles_binary{$component} = *OUTFILE; |
|
105 } |
|
106 |
|
107 # go back to start of line since CR/LF might even occur in the length field, |
|
108 # then read to each tab until the binary tag is found again |
|
109 seek(INPUT_FILE,$filepos,0); |
|
110 |
|
111 my $old_rs = $/; |
|
112 $/ = chr(9); |
|
113 do { |
|
114 $_ = <INPUT_FILE>; |
|
115 } while ((ord "$_" != 98) && (length != 1)); |
|
116 $/ = $old_rs; |
|
117 |
|
118 # read the length as a "little-endian" 4-byte unsigned integer |
|
119 my $datalenstr; |
|
120 my $numread = read(INPUT_FILE,$datalenstr,4); |
|
121 if ($numread != 4) { die "ERROR: did not read all 4 bytes binary data length on line $linenum"; } |
|
122 |
|
123 my $datatoread = unpack("v",$datalenstr); |
|
124 |
|
125 # read next char and ensure it is a tab |
|
126 my $onechar; |
|
127 $numread = read(INPUT_FILE,$onechar,1); |
|
128 if ($numread != 1) { die "ERROR: read error when reading tab char in binary line on line $linenum"; } |
|
129 if (ord $onechar != 9) { die "ERROR: No tab char in binary line at pos : $filepos where expected between length and data at line $linenum"; } |
|
130 |
|
131 if ($verbose) { |
|
132 print "About to read binary data. Beginning of line is at pos: $filepos "; |
|
133 printf " [%X] Tags: ",$filepos; |
|
134 foreach my $d (@list) { |
|
135 print "[$d]"; |
|
136 } |
|
137 print "\nBytes to read: $datatoread\n"; |
|
138 } |
|
139 |
|
140 my $datastr; |
|
141 $numread = read(INPUT_FILE,$datastr,$datatoread); |
|
142 if ($datatoread != $numread) { die "ERROR: only read $numread of expected $datatoread bytes binary data on line $linenum"; } |
|
143 |
|
144 if ($verbose) { print "Read Completed.\n"; } |
|
145 |
|
146 |
|
147 my $file_handle = $file_handles_binary{$component}; |
|
148 print $file_handle "$datastr"; |
|
149 |
|
150 # finally, read in the trailing CR/LF before reverting to textual reading |
|
151 $_ = <INPUT_FILE>; |
|
152 |
|
153 } else { |
|
154 if ($verbose) { |
|
155 print "Line# $linenum at filepos $filepos is CORRUPT: linetype field is neither ascii nor binary so ignoring.\n"; |
|
156 print "Line fields: "; |
|
157 foreach my $d (@list) { |
|
158 print "[$d]"; |
|
159 } |
|
160 print "\n ... skipping line and continuing\n"; |
|
161 } |
|
162 |
|
163 } |
|
164 } # comment line check |
|
165 } #empty line check |
|
166 $filepos = tell(INPUT_FILE); |
|
167 #print "filepos at end of line proc: $filepos . input rec #: $."; |
|
168 #printf "[%X]\n",$filepos; |
|
169 $linenum++; |
|
170 } |
|
171 |
|
172 # and finally clean up |
|
173 close(INPUT_FILE) or die "ERROR: failed to close the input log file: $!"; |
|
174 my $firstFile = 1; |
|
175 while((my $component, my $file_handle) = each(%file_handles_text)) |
|
176 { |
|
177 printf "%s%s", $firstFile? "Generated: ": ", ", $component; |
|
178 $firstFile = 0; |
|
179 close($file_handle) or die "ERROR: failed to close the output log file for \"$component\": $!"; |
|
180 } |
|
181 while((my $component, my $file_handle) = each(%file_handles_binary)) |
|
182 { |
|
183 printf "%s%s", $firstFile? "Generated: ": ", ", $component; |
|
184 $firstFile = 0; |
|
185 close($file_handle) or die "ERROR: failed to close the output log file for \"$component\": $!"; |
|
186 } |
|
187 print "\n"; |
|
188 |
|
189 |
|
190 sub Usage () { |
|
191 print $fromBatchFile? "Common Usage: splitlog [logfile] [-v][-1]\n": "Args: [logfile] [-v][-1]\n"; |
|
192 print <<ENDHERESTRING; |
|
193 Where: |
|
194 [logfile] = CDU log file (default: {EPOCROOT}\\EPOC32\\WINS[CW]\\C\\LOGS\\LOG.TXT) |
|
195 [-v] = verbose output |
|
196 [-1] = split only at component level (one file per unique first tag) |
|
197 |
|
198 Input Log file format: |
|
199 as specified in the FLOGGER documentation. Briefly, there are three |
|
200 types of log messages: |
|
201 1) Comment lines. These contain a '#' character at the beginning of |
|
202 the line. |
|
203 2) Ascii Log lines. Contains tab separated fields - the first being the |
|
204 name of the component that logged that particular message. |
|
205 3) Binary Log lines. Same fields as an ascii line but then contains |
|
206 a specified number of bytes of raw data. |
|
207 |
|
208 Output: |
|
209 This script will create a number of files in the current |
|
210 directory - one for each component found in the input log file. Each |
|
211 file will have the same name as the first two tags separated by an underscore. |
|
212 If the component is logging ascii test, its output log file will contain all |
|
213 comment lines, and all log lines relating to that particular component. |
|
214 If the component is logging binary data, only the actual data is placed in |
|
215 the output log file. |
|
216 Ascii output files are given the extension *.log while binary files have |
|
217 extension *.bin |
|
218 |
|
219 "Out of Memory": |
|
220 error may mean the file is corrupt and the script tried to |
|
221 read a section of binary data which isn't there. Try rerunning with the "-v" |
|
222 flag to help diagnose. File position numbers reported should correlate exactly |
|
223 with the byte position if displaying file in a hex editor. |
|
224 ENDHERESTRING |
|
225 |
|
226 exit 1; |
|
227 } |