sl@0: # Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: # All rights reserved. sl@0: # This component and the accompanying materials are made available sl@0: # under the terms of "Eclipse Public License v1.0" sl@0: # which accompanies this distribution, and is available sl@0: # at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: # sl@0: # Initial Contributors: sl@0: # Nokia Corporation - initial contribution. sl@0: # sl@0: # Contributors: sl@0: # sl@0: # Description: sl@0: # sl@0: sl@0: use strict; sl@0: use Getopt::Long; sl@0: sl@0: # read in the command line parameters sl@0: my $verbose = 0; sl@0: my $singleLevel = 0; sl@0: my $fromBatchFile = 0; sl@0: my $help = 0; sl@0: GetOptions( 'verbose|v!' => \$verbose, sl@0: '1!' => \$singleLevel, sl@0: 'help|h|?!' => \$help, sl@0: '--fromBatchFile!' => \$fromBatchFile ); sl@0: Usage() if $help; sl@0: my $file = $ARGV[0]; sl@0: if(!defined($file)) sl@0: { sl@0: $file = "$ENV{EPOCROOT}EPOC32\\WINSCW\\C\\LOGS\\LOG.TXT"; sl@0: $file = "$ENV{EPOCROOT}EPOC32\\WINS\\C\\LOGS\\LOG.TXT" if(!-r $file); sl@0: print "No file specified, defaulting to $file\n"; sl@0: } sl@0: print "Verbose mode on\n" if $verbose; sl@0: sl@0: # open up the file for input sl@0: open(INPUT_FILE, "< $file") or die "ERROR: Couldn't open the file \"$file\" for input:"; sl@0: sl@0: # read file without intepretting CR/LF - not ideal on window's systems, but sl@0: # I introduced this to get around apparent problem when seeking back when reading binary data sl@0: # The seek back seemed to seek to somewhere other than where we had last "tell"'ed. sl@0: # binmode fixes this since CR/LF is always seen as 2 distinct chars. sl@0: binmode(INPUT_FILE); sl@0: sl@0: # declare handy arrays sl@0: my %file_handles_text; # a hash of all components seen for ascii and their associated file handle sl@0: my %file_handles_binary; # a hash of all components seen for binary and their associated file handle sl@0: my @comments; # an array of all the comment lines seen so far sl@0: sl@0: # iterate through each line of the file sl@0: my $filepos = tell(INPUT_FILE); sl@0: my $linenum = 1; sl@0: while () { sl@0: # strip off any CR/LF's since we will correctly terminate the line by one sl@0: # if we find the line is ascii. Binary lines should also arrive with a CR/LF at their end. sl@0: my $line = $_; sl@0: print $line if $verbose; sl@0: chomp($line); sl@0: sl@0: my $strlen = length($line); sl@0: if (($strlen == 0) || (ord "$line" == 13)) { sl@0: if ($verbose) { print "Line#: $linenum is an empty line.\n"; } sl@0: } else { sl@0: $line =~ s/\r$//; # chomp CR sl@0: if ($line =~ /^#/) { sl@0: # we are dealing with a comment line sl@0: $line .= "\n"; sl@0: push(@comments, "$line"); sl@0: while((my $component, my $file_handle) = each(%file_handles_text)) { sl@0: print $file_handle "$line" sl@0: } sl@0: } sl@0: else { sl@0: #we are dealing with a component line so check the correct line format and determine if it is ascii or binary sl@0: my @list = split("\t", $line); sl@0: sl@0: my $linetype = "$list[2]"; sl@0: sl@0: if (ord "$linetype" == 97) { sl@0: # this is ascii, so return a CR/LF to line sl@0: $line .= "\n"; sl@0: my $component = lc($list[0] . ($singleLevel? "": "_$list[1]") . ".log"); sl@0: if (not exists $file_handles_text{$component}) { sl@0: # we haven't seen this component before sl@0: local *OUTFILE; sl@0: open(OUTFILE, "> $component") or die "ERROR. Line $linenum: can't open file \"$component\" for output: $!"; sl@0: foreach my $comment (@comments) { sl@0: print OUTFILE "$comment"; sl@0: } sl@0: $file_handles_text{$component} = *OUTFILE; sl@0: } sl@0: my $file_handle = $file_handles_text{$component}; sl@0: print $file_handle "$line"; sl@0: } elsif (ord "$linetype" == 98) { sl@0: #assume it is binary sl@0: my $component = "$list[0]_$list[1].bin"; sl@0: if (not exists $file_handles_binary{$component}) { sl@0: # we haven't seen this component before sl@0: local *OUTFILE; sl@0: open(OUTFILE, "> $component") or die "ERROR. Line $linenum: can't open file \"$component\" for output: $!"; sl@0: binmode(OUTFILE); sl@0: $file_handles_binary{$component} = *OUTFILE; sl@0: } sl@0: sl@0: # go back to start of line since CR/LF might even occur in the length field, sl@0: # then read to each tab until the binary tag is found again sl@0: seek(INPUT_FILE,$filepos,0); sl@0: sl@0: my $old_rs = $/; sl@0: $/ = chr(9); sl@0: do { sl@0: $_ = ; sl@0: } while ((ord "$_" != 98) && (length != 1)); sl@0: $/ = $old_rs; sl@0: sl@0: # read the length as a "little-endian" 4-byte unsigned integer sl@0: my $datalenstr; sl@0: my $numread = read(INPUT_FILE,$datalenstr,4); sl@0: if ($numread != 4) { die "ERROR: did not read all 4 bytes binary data length on line $linenum"; } sl@0: sl@0: my $datatoread = unpack("v",$datalenstr); sl@0: sl@0: # read next char and ensure it is a tab sl@0: my $onechar; sl@0: $numread = read(INPUT_FILE,$onechar,1); sl@0: if ($numread != 1) { die "ERROR: read error when reading tab char in binary line on line $linenum"; } sl@0: if (ord $onechar != 9) { die "ERROR: No tab char in binary line at pos : $filepos where expected between length and data at line $linenum"; } sl@0: sl@0: if ($verbose) { sl@0: print "About to read binary data. Beginning of line is at pos: $filepos "; sl@0: printf " [%X] Tags: ",$filepos; sl@0: foreach my $d (@list) { sl@0: print "[$d]"; sl@0: } sl@0: print "\nBytes to read: $datatoread\n"; sl@0: } sl@0: sl@0: my $datastr; sl@0: $numread = read(INPUT_FILE,$datastr,$datatoread); sl@0: if ($datatoread != $numread) { die "ERROR: only read $numread of expected $datatoread bytes binary data on line $linenum"; } sl@0: sl@0: if ($verbose) { print "Read Completed.\n"; } sl@0: sl@0: sl@0: my $file_handle = $file_handles_binary{$component}; sl@0: print $file_handle "$datastr"; sl@0: sl@0: # finally, read in the trailing CR/LF before reverting to textual reading sl@0: $_ = ; sl@0: sl@0: } else { sl@0: if ($verbose) { sl@0: print "Line# $linenum at filepos $filepos is CORRUPT: linetype field is neither ascii nor binary so ignoring.\n"; sl@0: print "Line fields: "; sl@0: foreach my $d (@list) { sl@0: print "[$d]"; sl@0: } sl@0: print "\n ... skipping line and continuing\n"; sl@0: } sl@0: sl@0: } sl@0: } # comment line check sl@0: } #empty line check sl@0: $filepos = tell(INPUT_FILE); sl@0: #print "filepos at end of line proc: $filepos . input rec #: $."; sl@0: #printf "[%X]\n",$filepos; sl@0: $linenum++; sl@0: } sl@0: sl@0: # and finally clean up sl@0: close(INPUT_FILE) or die "ERROR: failed to close the input log file: $!"; sl@0: my $firstFile = 1; sl@0: while((my $component, my $file_handle) = each(%file_handles_text)) sl@0: { sl@0: printf "%s%s", $firstFile? "Generated: ": ", ", $component; sl@0: $firstFile = 0; sl@0: close($file_handle) or die "ERROR: failed to close the output log file for \"$component\": $!"; sl@0: } sl@0: while((my $component, my $file_handle) = each(%file_handles_binary)) sl@0: { sl@0: printf "%s%s", $firstFile? "Generated: ": ", ", $component; sl@0: $firstFile = 0; sl@0: close($file_handle) or die "ERROR: failed to close the output log file for \"$component\": $!"; sl@0: } sl@0: print "\n"; sl@0: sl@0: sl@0: sub Usage () { sl@0: print $fromBatchFile? "Common Usage: splitlog [logfile] [-v][-1]\n": "Args: [logfile] [-v][-1]\n"; sl@0: print <