diff -r 2a0ada0a1bf8 -r 95847726fe57 kerneltest/e32utils/trace/btracevw.pl --- a/kerneltest/e32utils/trace/btracevw.pl Wed May 12 10:34:10 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1952 +0,0 @@ -# -# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -# All rights reserved. -# This component and the accompanying materials are made available -# under the terms of the License "Eclipse Public License v1.0" -# which accompanies this distribution, and is available -# at the URL "http://www.eclipse.org/legal/epl-v10.html". -# -# Initial Contributors: -# Nokia Corporation - initial contribution. -# -# Contributors: -# -# Description: -# - -#!/usr/bin/perl - -use File::Find; -use File::Spec::Functions; - - - my $TraceFileName; - - my $PrintFlagFilePos = 0; - my $PrintFlagHdrLen = 0; - my $PrintFlagHdrFlags = 0; - my $PrintFlagFormatString = 0; - my $VerboseMode = 0; - my $RawMode = 0; - my $FormatIdIsSubCategory = 0; - my $OutputSawDictionaryMode = 0; - - # for the category range 0-191, the format string is indexed by the category & subcategory - %FormatTables = - ( - 0 => # ERDebugPrintf - { - 0 => "ThreadId %h, %s", - }, - - 1 => # ERKernPrintf - { - 0 => "ThreadId %h, %s", - }, - - 3 => # EThreadIdentification - { - 0 => "ENanoThreadCreate, NThread %x", - 1 => "ENanoThreadDestroy, NThread %x", - 2 => "EThreadCreate, NThread %x, DProcess %x, name %s", - 3 => "EThreadDestroy, NThread %x, DProcess %x, Id %x", - 4 => "EThreadName, NThread %x, DProcess %x, name %s", - 5 => "EProcessName, NThread %x, DProcess %x, name %s", - 6 => "EThreadId, NThread %x, DProcess %x, Id %x", - 7 => "EProcessCreate, DProcess %x", - 8 => "EProcessDestroy, DProcess %x", - }, - ); - - my @typedefs; - my @members; - my %values = ( -# UTF::KInitialClientFormat => {type=>"TFormatId", size=>2, value=>512} - KMaxTUint8 => {type=>"TUint8", size=>1, value=>255}, - KMaxTUint16 => {type=>"TUint16", size=>2, value=>65535} - ); - my %macros; - my @classes; - my @enums; - my %formatStrings; # each enum may have it's own format string - my %formatCategories; # each enum may have it's own format category - - my %filescope; - $filescope{file}=1; - undef $filescope{name}; - - $filescope{typedefs}=\@typedefs; - $filescope{members}=\@members; - $filescope{values}=\%values; - $filescope{macros} = \%macros; - $filescope{FormatTables} = \%FormatTables; - - $filescope{classes} = \@classes; - $filescope{enums} = \@enums; - - $filescope{formatStrings} =\%formatStrings; - $filescope{formatCategories} = \%formatCategories; - - - - if (@ARGV == 0) - { - print "BTraceVw.pl \n"; - print "An unsupported utility which extracts UTrace-style format-strings\n"; - print "from header files & uses these to decode a BTrace output file\n"; - print "Syntax : BTraceVw.pl [-v] [-r] [-sd] [-i ] []\n"; - print "where : -v = verbose mode\n"; - print " : -r = raw output mode\n"; - print " : -sd = produce SAW trace viewer dictionary file\n"; - print " : this file then needs to be merged into the 'com.symbian.analysis.trace.ui.prefs' file\n"; - print " : located under the carbide workspace directory\n"; - print "\n"; - - print "e.g. (this decodes a trace file & produces a comma-separated output file) : \n"; - print "btracevw.pl -i /os/kernelhwsrv/userlibandfileserver/fileserver/inc/f32tracedef.h -i /os/kernelhwsrv/userlibandfileserver/fileserver/inc/utraceefsrv.h -i /os/kernelhwsrv/userlibandfileserver/fileserver/inc/utraceefile.h trace.utf >trace.csv\n"; - print "\n"; - print "e.g. (this overwrites the SAW dictioany file) : \n"; - print "btracevw.pl -sd -i /os/kernelhwsrv/userlibandfileserver/fileserver/inc/f32tracedef.h -i /os/kernelhwsrv/userlibandfileserver/fileserver/inc/utraceefsrv.h -i /os/kernelhwsrv/userlibandfileserver/fileserver/inc/utraceefile.h >com.symbian.analysis.trace.ui.prefs\n"; - - exit; - } - - while (@ARGV > 0) - { - - if ($ARGV[0] eq "-i") - { - shift @ARGV; - ($FilePath) = @ARGV; - shift @ARGV; - - undef @incFiles; - @incFiles; - - find sub { push @incFiles, $File::Find::name if m/\.h$/i;}, $FilePath ; - foreach $incFile (@incFiles) - { - H2Trace($incFile, \%filescope); - } - } - elsif ($ARGV[0] eq "-r") - { - $RawMode = 1; - shift @ARGV; - } - elsif ($ARGV[0] eq "-sd") - { - $OutputSawDictionaryMode = 1; - shift @ARGV; - } - elsif ($ARGV[0] eq "-v") - { - $VerboseMode = 1; - shift @ARGV; - } - else - { - $TraceFileName = "$ARGV[0]"; - shift @ARGV; - } - } - - if ($VerboseMode) - { - dump_scope(\%filescope); - PrintFormatTables(\%FormatTables); - } - if ($OutputSawDictionaryMode) - { - OutputSawDictionary(\%FormatTables); - } - - if (defined ($TraceFileName)) - { - ReadTraceFile($RawMode); - } - - - - -sub ReadTraceFile($) - { - (my $RawMode) = @_; -# print "Trace file is $TraceFileName, RawMode $RawMode, VerboseMode $VerboseMode\n\n"; - - open (LOGFILE, "<$TraceFileName") or die "Can't open $TraceFileName: $!\n"; - binmode (LOGFILE); - - my $val = 0; - - - # enum TFlags from e32btrace.h - $EHeader2Present = 1<<0; - $ETimestampPresent = 1<<1; - $ETimestamp2Present = 1<<2; - $EContextIdPresent = 1<<3; - $EPcPresent = 1<<4; - $EExtraPresent = 1<<5; - $ERecordTruncated = 1<<6; - $EMissingRecord = 1<<7; - - # enum TFlags2 from e32btrace.h - $EMultipartFlagMask = 3<<0; - $ECpuIdMask = 0xfff<<20; - - # enum TMultiPart from e32btrace.h - $EMultipartFirst = 1; - $EMultipartMiddle = 2; - $EMultipartLast = 3; - - $EMaxBTraceDataArray = 80; - - # enum TCategory from e32btrace.h - $EThreadIdentification = 3; - - # enum TThreadIdentification from e32btrace.h - $EThreadCreate = 2; - $EThreadName = 4; - $EProcessName = 5; - $EThreadId = 6; - - # Context Id bits from e32btrace.h - $EContextIdMask = 0x00000003; - $EContextIdThread = 0; - $EContextIdFIQ = 0x1; - $EContextIdIRQ = 0x2; - $EContextIdIDFC = 0x3; - - # enum TClassificationRange from e32btraceu.h - $EAllRangeFirst = 192; - $EAllRangeLast = 222; - - %TCategoryIdToString = - ( - 0 => "ERDebugPrintf", - 1 => "EKernPrintf", - 2 => "EPlatsecPrintf", - 3 => "EThreadIdentification", - 4 => "ECpuUsage", - 5 => "EKernPerfLog", - 6 => "EClientServer", - 7 => "ERequests", - 8 => "EChunks", - 9 => "ECodeSegs", - 10 => "EPaging", - 11 => "EThreadPriority", - 12 => "EPagingMedia", - 13 => "EKernelMemory", - 14 => "EHeap", - 15 => "EMetaTrace", - 16 => "ERamAllocator", - 17 => "EFastMutex", - 18 => "EProfiling", - 19 => "EResourceManager", - 20 => "EResourceManagerUs", - 21 => "ERawEvent ", - 128 => "EPlatformSpecificFirst", - 191 => "EPlatformSpecificLast", - 192 => "ESymbianExtentionsFirst", - - # UTrace "ALL" range - 192 => "EPanic", - 193 => "EError", - 194 => "EWarning", - 195 => "EBorder", - 196 => "EState", - 197 => "EInternals", - 198 => "EDump", - 199 => "EFlow", - 200 => "ESystemCharacteristicMetrics", - 201 => "EAdhoc", - - 253 => "ESymbianExtentionsLast", - 254 => "ETest1", - 255 => "ETest2", - ); - - - %ProcessNames; - %ThreadNames; - %ThreadIds; - - - # print column titles - if ($PrintFlagFilePos) {printf "FilePos, ";} # col #0 - if ($PrintFlagHdrLen) { printf "Len, ";} # col #1 - if ($PrintFlagHdrFlags) {printf "Flags, "; } # col #2 - printf "Category, "; # col #3 - printf "TimeStamp, "; # col #4 - printf "Delta, "; # col #5 - printf "context Id, "; # col #6 - printf "PC, "; # col #7 - printf "UID, "; # col #8 - if ($PrintFlagFormatString){printf "Format string, ";} # col #9 - printf "Formatted text, "; # col #10 - print "\n\n"; - - - while (1) - { - my $pos = tell (LOGFILE); - - # print file pos (col #0) - if ($PrintFlagFilePos){ printf ("0x%08X, ", $pos);} - - my $category; - my $subCategory; - my $multipartFlags = 0; - my $recordData = ""; - my $recordLen; - my $recordPos = 0; - - $recordLen = ReadRecord(LOGFILE, \$pos, \$recordData, \$category, \$subCategory, \$multipartFlags, $RawMode); - if ($recordLen == -1) - {last;} - - - if (!$RawMode && ($multipartFlags == $EMultipartMiddle || $multipartFlags == $EMultipartLast)) - {next;} - -# print record contents -# my $buf; -# for (my $i=0; $i < $recordLen; $i+=4) -# { -# $buf.= sprintf ("%08X ", unpack("V", substr($recordData, $recordPos+$i, 4))); -# } -# printf "\n[$buf\n]"; - - - # for UTrace "ALL" range, read UID - if ($category >= $EAllRangeFirst && $category <= $EAllRangeLast && - (!$RawMode) && $multipartFlags != $EMultipartMiddle && $multipartFlags != $EMultipartLast) - { - $uid = unpack("V", substr($recordData, $recordPos, 4)); - $recordPos+= 4; - - # then read formatID - $FormatIdIsSubCategory = ($subCategory != 0) ? 1 : 0; - if ($FormatIdIsSubCategory) - { - $formatId = $subCategory - } - else - { - $formatId = unpack("V", substr($recordData, $recordPos, 4)); - $recordPos+= 4; - } - } - - - # print UID (col #8) - printf "0x%08X, ", $uid; - - - my $formatTable; - my $formatString; - if ($category >= $EAllRangeFirst && $category <= $EAllRangeLast) - { - $formatString = $FormatTables{$uid}{$formatId}; - } - else - { - $formatString = $FormatTables{$category}{$subCategory}; - } - - - # Get thread names - if ($category == $EThreadIdentification) - { - if ($subCategory == $EProcessName) - { - my $process = unpack("V", substr($recordData, 4, 4)); - my $processName = substr($recordData, 8, $recordLen - 8); -# printf ("\nprocess [%08X] processName [$processName]\n", $process); - $ProcessNames{$process} = $processName; - } - elsif ($subCategory == $EThreadCreate || $subCategory == $EThreadName) - { - my $thread = unpack("V", substr($recordData, 0, 4)); - my $process = unpack("V", substr($recordData, 4, 4)); - my $threadName = substr($recordData, 8, $recordLen - 8); -# printf ("\nprocess [%08X] thread [%08X] threadName [$threadName]\n", $process, $thread, $threadName); - $ThreadNames{$thread} = $ProcessNames{$process} . "::" . $threadName; - } - elsif ($subCategory == $EThreadId) - { - my $thread = unpack("V", substr($recordData, 0, 4)); - my $process = unpack("V", substr($recordData, 4, 4)); - my $threadId = unpack("V", substr($recordData, 8, 4)); -# printf ("\nprocess [%08X] thread [%08X] threadId [%08X]\n", $process, $thread, $threadId); - $ThreadIds{$thread} = $threadId; - } - } - - - # print Format string (col #9) - if ($PrintFlagFormatString) - { - my $formatStringWithoutCommas = $formatString; - $formatStringWithoutCommas=~ s/,/ /g; - printf "%s, ", $formatStringWithoutCommas; - } - - my $formattedText; - - my $lenFormatString = length($formatString); - if ($lenFormatString && !$RawMode && $multipartFlags != $EMultipartMiddle && $multipartFlags != $EMultipartLast) - { - for (my $i=0; $i<$lenFormatString; $i++) - { - my $c = (substr ($formatString, $i, 1)); -# printf "$c\n"; - if ($c eq "%") - { - undef my $fieldLen; - $i++; - $c = (substr ($formatString, $i, 1)); - if ($c eq "%") - { - $formattedText.= substr ($formatString, $i, 1); - next; - } - if ($c eq "*") ## take length from buffer - { - $fieldLen = unpack("V", substr($recordData, $recordPos, 4)); - if ($fieldLen > $recordLen-$recordPos) - { - $formattedText.= "*** Invalid field length ***"; - last; - } - $recordPos+= 4; - $i++; - $c = (substr ($formatString, $i, 1)); - } - if (lc $c eq "x" || $c eq "h") - { - if (defined $fieldLen) - { - if (($fieldLen & 3) == 0) - { - for (my $i=0; $i< $fieldLen; $i+= 4) - { - $formattedText.= sprintf ("%08X ", unpack("V", substr($recordData, $recordPos, 4))); - $recordPos+= 4; - } - } - else - { - for (my $i=0; $i< $fieldLen; $i++) - { - $formattedText.= sprintf ("%02X ", unpack("C", substr($recordData, $recordPos, 1))); - $recordPos++; - } - } - } - else - { - $formattedText.= sprintf ("0x%08X", unpack("V", substr($recordData, $recordPos, 4))); - $recordPos+= 4; - } - $recordPos = ($recordPos + 3) & ~3; - next; - } - # display "%ld" as hex for now as don't know how to get perl to use or display a 64 decimal value - elsif (lc $c eq "l" && substr ($formatString, $i+1, 1) eq "d") - { - $i++; - my $loWord = unpack("V", substr($recordData, $recordPos, 4)); - $recordPos+= 4; - my $hiWord = unpack("V", substr($recordData, $recordPos, 4)); - $recordPos+= 4; - $formattedText.= sprintf ("0x%X:%08X", $hiWord, $loWord); - } - elsif (lc $c eq "l" && substr ($formatString, $i+1, 1) eq "x") - { - $i++; - my $loWord = unpack("V", substr($recordData, $recordPos, 4)); - $recordPos+= 4; - my $hiWord = unpack("V", substr($recordData, $recordPos, 4)); - $recordPos+= 4; - $formattedText.= sprintf ("0x%X:%08X", $hiWord, $loWord); - } - elsif (lc $c eq "d") - { - $formattedText.= sprintf ("%d", unpack("V", substr($recordData, $recordPos, 4))); - $recordPos+= 4; - $recordPos = ($recordPos + 3) & ~3; - next; - } - elsif ($c eq "s") - { - if (!defined $fieldLen) - {$fieldLen = $recordLen - $recordPos;} - $formattedText.= substr($recordData, $recordPos, $fieldLen); - $recordPos+= $fieldLen; - $recordPos = ($recordPos + 3) & ~3; - next; - } - elsif ($c eq "S") - { - if (!defined $fieldLen) - {$fieldLen = $recordLen-$recordPos;} - for (my $j=0; $j < $fieldLen; $j+=2) - { - my $byte = unpack("c", substr ($recordData, $recordPos+$j, 1)); - $formattedText.= sprintf ("%c", $byte); - } - $recordPos+= $fieldLen; - $recordPos = ($recordPos + 3) & ~3; - next; - } - elsif ($c eq "c") - { - my $byte = unpack("c", substr ($recordData, $recordPos, 1)); - $formattedText.= sprintf ("%c", $byte); - } - } - else - { - $formattedText.= $c; - } - } - } - else # no format string : print as hex - { - for (my $i=0; $i < $recordLen; $i+=4) - { - $formattedText.= sprintf ("%08X ", unpack("V", substr($recordData, $i, 4))); - } - $recordPos+= $recordLen; $recordLen = 0; - - } - - - # print Formatted text (col #10) - $formattedText=~ s/,/;/g; - $formattedText=~ s/\r//g; - $formattedText=~ s/\n/,/g; - printf "%s", $formattedText; - - printf("\n"); - - if ($len < 0 || $recordLen < 0) {die "truncated file";} - - - $pos+= ($len +3) & ~3; - seek (LOGFILE, $pos, SEEK_SET) or die "truncated file"; - $i++; - } - - close (LOGFILE); - - if ($VerboseMode) - { - print "*** Processes ***\n"; - for $id ( keys %ProcessNames ) - { - printf ("process %08X ProcessName %s\n", $id, $ProcessNames{$id}); - } - print "*** Thread ***\n"; - for $id ( keys %ThreadNames ) - { - printf ("thread %08X ThreadName %s::%X\n", $id, $ThreadNames{$id}, $ThreadIds{$id}); - } - } - - } - - -sub ReadSingleRecord - { - ($fh, $data, $dataLen, $recordLen, $category, $subCategory, $multipartFlags, $extraN, $totalLen, $offset, $RawMode) = @_; - - my $hdr; - my $flags; - my $header2; - my $timestamp; - my $timestamp2; - my $contextId; - my $programConter; - - my $recordOffset = 0; - - $timestampLast; - my $timestampDelta = 0; - - my $bytesRead = read($fh, $hdr, 4); - - - if ($bytesRead < 4) - {return -1;} - - ($$recordLen,$flags,$$category,$$subCategory) = unpack("CCCC", $hdr); - $$dataLen = $$recordLen-4; - - if ($flags & $EHeader2Present) - {$$multipartFlags = (ReadDword($fh) & $EMultipartFlagMask); $$dataLen-= 4} - else - {$$multipartFlags = 0;} - if ($flags & $ETimestampPresent) - {$timestamp = ReadDword($fh); $$dataLen-= 4;} - if ($flags & $ETimestamp2Present) - {$timestamp2 = ReadDword($fh); $$dataLen-= 4;} - if ($flags & $EContextIdPresent) - {$contextId = ReadDword($fh); $$dataLen-= 4;} - if ($flags & $EPcPresent) - {$programConter = ReadDword($fh); $$dataLen-= 4;} - if ($flags & $EExtraPresent) - {$$extraN = ReadDword($fh); $$dataLen-= 4;} - if ($$multipartFlags != 0) - { - $$totalLen = ReadDword($fh); $$dataLen-= 4; - if ($$multipartFlags == $EMultipartMiddle || $$multipartFlags == $EMultipartLast) - {$$offset = ReadDword($fh); $$totalLen-= 4; $$dataLen-= 4;} - } - - $timestampDelta = $timestamp - $timestampLast; - $timestampLast = $timestamp; - - read($fh, $$data, ($$dataLen + 3) & ~3); - - - if ($RawMode || $$multipartFlags == $EMultipartFirst || $$multipartFlags == 0) - { - # print header len (col #1) - if ($PrintFlagHdrLen){printf ("0x%02X, ", $$recordLen);} - - # print header flags (col #2) - if ($PrintFlagHdrFlags) - { - printf ("%02X ", $flags); - if ($flags & $EHeader2Present) {printf "EHeader2Present ";} - if ($flags & $ETimestampPresent) {printf "ETimestampPresent ";} - if ($flags & $ETimestamp2Present) {printf "ETimestamp2Present ";} - if ($flags & $EContextIdPresent) {printf "EContextIdPresent ";} - if ($flags & $EPcPresent) {printf "EPcPresent ";} - if ($$multipartFlags != 0) - { - printf "EExtraPresent "; - if ($$multipartFlags == $EMultipartFirst) {print "EMultipartFirst ";} - elsif ($$multipartFlags == $EMultipartMiddle) {print "EMultipartMiddle ";} - elsif ($$multipartFlags == $EMultipartLast) {print "EMultipartLast ";} - printf ("ExtraN(0x%08X) ", $$extraN); - } - if ($flags & $ERecordTruncated) {printf "ERecordTruncated ";} - if ($flags & $EMissingRecord) {printf "EMissingRecord ";} - print ","; - } - - # print category (col #3) - printf "(%d;%d) $categoryString , ", $$category, $$subCategory; - - # print timestamp(s) (col #4) - printf "0x"; - if (defined $timestamp2) {printf "%08X : ", $timestamp2;} - printf "%08X", $timestamp; - printf ", ";; - - # print timestamp delta (col #5) - printf "0x%08X, ", $timestampDelta; - - # print context Id (col #6) - if (!$RawMode && defined $ThreadNames{$contextId}) - { - printf ("%s::%X, ", $ThreadNames{$contextId}, $ThreadIds{$contextId}); - } - else - { - if ((($contextId & $EContextIdMask) == $EContextIdThread) || $RawMode) - {printf "0x%08X, ", $contextId;} - elsif (($contextId & $EContextIdMask) == $EContextIdFIQ) - {printf "FIQ, ";} - elsif (($contextId & $EContextIdMask) == $EContextIdIRQ) - {printf "IRQ, ";} - elsif (($contextId & $EContextIdMask) == $EContextIdIDFC) - {printf "IDFC, ";} - } - - # print Program Counter (col #7) - printf "0x%08X, ", $programConter; - } - - - - -######################################################### -# my $hex; -# for (my $i=0; $i < $$dataLen; $i+=4) -# { -# $hex.= sprintf ("%08X ", unpack("V", substr($$data, $i, 4))); -# } -# printf "\nadding [$hex]\n"; -######################################################### - return $bytesRead - } - - -sub ReadRecord - { - ($fh, $recordPos, $recordData, $category, $subCategory, $multipartFlags, $RawMode) = @_; -# printf "CurrentPos %08X\n", $pos; - - - - seek ($fh, $$recordPos, SEEK_SET) or die "truncated file"; - my $recordLen; - my $extraN; - my $totalLen; - my $offset; - my $dataLen; - my $data; - my $bytesRead; - - - $bytesRead = ReadSingleRecord($fh, \$data, \$dataLen, \$recordLen, \$$category, \$$subCategory, \$$multipartFlags, \$extraN, \$totalLen, \$offset, $RawMode); - - if ($bytesRead == -1) # eof ? - {return -1; } - $$recordPos+= ($recordLen +3) & ~3; - - $$recordData = $data; - $offset = $dataLen; - - $offset-= 4; # subtract 4 bytes for UID ????????? - - if ($RawMode || $$multipartFlags != $EMultipartFirst) - {return $dataLen;} - - $pos = $$recordPos; - - while (1) - { - - # find next record, i.e. look for a record which matches $extraN - - seek ($fh, $pos, SEEK_SET) or die "truncated file"; - - my $recordLen; - - my $category; - my $subCategory; - my $multipartFlags; - my $currentExtraN; - my $currentOffset; - - my $totalLen; - my $currentDataLen; - my $data; - $bytesRead = ReadSingleRecord($fh, \$data, \$currentDataLen, \$recordLen, \$category, \$subCategory, \$multipartFlags, \$currentExtraN, \$totalLen, \$currentOffset, $RawMode); - if ($bytesRead == -1) # eof ? - {return -1; } - $pos+= ($recordLen +3) & ~3; - -# printf "\npos %08X, Seaching for (extra %08X, offset %08X), found (extra %08X, offset %08X)\n", -# $pos, $extraN, $offset, $currentExtraN, $currentOffset; - - if ($currentExtraN == $extraN && $currentOffset == $offset) - { - $$recordData.= $data; - $offset+= $currentDataLen; - $dataLen+= $currentDataLen; - } - - if ($multipartFlags == $EMultipartLast) - {last;} - } - - return $dataLen; - } - -sub ReadDword { - (my $fh) = @_; - my $buffer; - - $bytesRead = read($fh, $buffer, 4); - if ($bytesRead < 4) {die "truncated file";} - - my $dword = unpack("V", $buffer); - - return $dword - }; - -sub ReadByte { - (my $fh) = @_; - my $buffer; - - $bytesRead = read($fh, $buffer, 1); - if ($bytesRead < 1) {die "truncated file";} - - my $byte = unpack("C", $buffer); - - return $byte - }; - - - -sub PrintFormatTables($) - { - my ($formatTables) = @_; - - for $tableIndex ( sort keys %$formatTables ) - { - printf ("SYMTraceFormatCategory %08X:\n", $tableIndex); - for $formatId (sort keys %{ $$formatTables{$tableIndex} } ) - { - printf ("%08X => %s\n", $formatId, $$formatTables{$tableIndex}{$formatId}); - } - print "\n"; - } - } - - - -sub OutputSawDictionary($) - { - my ($formatTables) = @_; - - - # SAW enums - $EFieldTypeHexDump = 0; - $EFieldTypeHex = 1; - $EFieldTypeDecimal = 2; - $EFieldTypeStringToEnd = 3; - $EFieldTypeNullTerminatedString = 4; - $EFieldTypeHexDumpToEnd = 5; - $EFieldTypeUnicodeToEnd = 6; - $EFieldTypeNullTerminatedUnicode = 7; - $EFieldTypeCountedUnicode = 8; - $EFieldTypeCountedHexDump = 9; - $EFieldTypeCountedString = 10; - - my $moduleIds; # string containg all UIDs separared by semi-colons - - for $tableIndex ( sort keys %$formatTables ) - { - if ($tableIndex < 256) - { - next; - } - $moduleIds.= sprintf ("%08X;", $tableIndex); - - printf ("MODULEID_%08X_DESC=\n", $tableIndex); - printf ("MODULEID_%08X_NAME=%08X\n", $tableIndex, $tableIndex); - - my $formatIds; - $formatIds = sprintf ("MODULEID_%08X_FORMATIDS=", $tableIndex); - - for $formatId (sort keys %{ $$formatTables{$tableIndex} } ) - { - $formatIds.= sprintf ("%d;", $formatId); - } - printf ("$formatIds\n"); - - - for $formatId (sort keys %{ $$formatTables{$tableIndex} } ) - { - my $fieldCount = 0; - my $formatString = $$formatTables{$tableIndex}{$formatId}; - -#printf ("formatString = (%s)\n", $formatString); - - # format name is the first format string up until the first space or '%' character or end-of line ... - $formatString=~ m/^[^%\s]*/; - my $formatName = $&; - - # thow the format name away - $formatString = $'; - - # strip the leading space - $formatString=~ s/\s*//; - - printf ("MODULEID_%08X_FORMATID_%d_NAME=%s\n", $tableIndex, $formatId, $formatName); -#printf ("MODULEID_%08X_FORMATID_%d_DESC=\n", $tableIndex, $formatId); - - my $lenFormatString = length($formatString); - - my $formattedText; - my $fieldType = $EFieldTypeHex; - my $fieldLen = 0; - while (length($formatString)) - { - my $c = (substr ($formatString, 0, 1)); -#print ("[$formatString][$c]\n"); - $formatString=~ s/.//; # strip the leading space - if ($c eq "%") - { -#print "found %\n"; - my $fieldLenSpecified = 0; - $c = (substr ($formatString, 0, 1)); - $formatString=~ s/.//; # discard char -#print "c2=$c\n"; - if ($c eq "%") - { - $formattedText.= substr ($formatString, 0, 1); - next; - } - if ($c eq "*") ## take length from buffer - { - $fieldLenSpecified = 1; - $c = (substr ($formatString, 0, 1)); - $formatString=~ s/.//; # discard char - } - if (lc $c eq "x" || $c eq "h") - { - ## deal wilth $fieldLenSpecified - if ($fieldLenSpecified) - { - $fieldType = $EFieldTypeCountedHexDump; - $fieldLen = 0; - } - else - { - $fieldType = $EFieldTypeHex; - $fieldLen = 4; - } - } - elsif (lc $c eq "l" && substr ($formatString, 0, 1) eq "d") - { - $formatString=~ s/.//; # discard char - $fieldType = $EFieldTypeDecimal; - $fieldLen = 8; - } - elsif (lc $c eq "l" && substr ($formatString, 0, 1) eq "x") - { - $formatString=~ s/.//; # discard char - $fieldType = $EFieldTypeHex; - $fieldLen = 8; - } - elsif (lc $c eq "d") - { - $fieldType = $EFieldTypeDecimal; - $fieldLen = 4; - } - elsif ($c eq "s") - { - ## deal wilth $fieldLenSpecified - if ($fieldLenSpecified) - { - $fieldType = $EFieldTypeCountedString; - $fieldLen = 0; - } - else - { - $fieldType = $EFieldTypeStringToEnd; - $fieldLen = 0; - } - } - elsif ($c eq "S") - { - ## deal wilth $fieldLenSpecified - if ($fieldLenSpecified) - { - $fieldType = $EFieldTypeCountedUnicode; - $fieldLen = 0; - } - else - { - $fieldType = EFieldTypeUnicodeToEnd; - $fieldLen = 0; - } - } - elsif ($c eq "c") - { - $fieldType = $EFieldTypeHex; - $fieldLen = 1; - } - printf ("MODULEID_%08X_FORMATID_%d_FIELD_%d_NAME=%s\n", $tableIndex, $formatId, $fieldCount, $formattedText); - printf ("MODULEID_%08X_FORMATID_%d_FIELD_%d_TYPE=%s\n", $tableIndex, $formatId, $fieldCount, $fieldType); - if ($fieldLen > 0) - {printf ("MODULEID_%08X_FORMATID_%d_FIELD_%d_LENGTH=%s\n", $tableIndex, $formatId, $fieldCount, $fieldLen);} - $fieldCount++; - $formattedText=""; - - $formatString=~ s/\s//; # strip the leading space - } - else - { -# if ($c eq ":") {$formattedText.= '\\'; } - $formattedText.= $c; - } - } - printf ("MODULEID_%08X_FORMATID_%d_FIELDS=%d\n", $tableIndex, $formatId, $fieldCount); - - } - print "MODULEIDS=$moduleIds\n"; - } - } - - - - - - - - -sub H2Trace($$) -{ - %basictypes = ( - TInt8 => 1, - TUint8 => 1, - TInt16 => 2, - TUint16 => 2, - TInt32 => 4, - TUint32 => 4, - TInt => 4, - TUint => 4, - TBool => 4, - TInt64 => 8, - TUint64 => 8, - TLinAddr => 4, - TVersion => 4, - TPde => 4, - TPte => 4, - TProcessPriority => 4, - TFormatId => 2, - ); - - if (scalar(@_)!= 2) { - die "perl h2trace.pl \n"; - } - my ($infile, $filescope) = @_; - - if ($VerboseMode) - {print "\nOpening $infile\n";} - - open IN, $infile or die "Can't open $infile for input\n"; - my $in; - while () { - $in.=$_; - } - close IN; - - # First remove any backslash-newline combinations - $in =~ s/\\\n//gms; - - # Remove any character constants - $in =~ s/\'(.?(${0})*?)\'//gms; - - # Strip comments beginning with // - $in =~ s/\/\/(.*?)\n/\n/gms; #//(.*?)\n - - # Strip comments (/* */) but leave doxygen comments (/** */) - $in =~ s/\/\*[^*](.*?)\*\//\n/gms; #/*(.*?)*/ - - - # Collapse whitespace into a single space or newline - $in =~ s/\t/\ /gms; - $in =~ s/\r/\ /gms; - - # Tokenize on non-identifier characters - my @tokens0 = split(/(\W)/,$in); - my @tokens; - my $inString = 0; - my $inComment = 0; - my $string; - foreach $t (@tokens0) { - next if ($t eq ""); - next if (!$inString && ($t eq " " or $t eq "")); - if ($inComment == 0) - { - if ($t eq "/") - {$inComment = 1;} - } - elsif ($inComment == 1) - { - if ($t eq "*") - {$inComment = 2;} - else - {$inComment = 0;} - } - elsif ($inComment == 2) - { - if ($t eq "*") - {$inComment = 3;} - } - elsif ($inComment == 3) - { - if ($t eq "/") - { - $inComment = 0; - # if we were in a string, need to push previous '*' - if ($inString) - { - push @tokens, "*"; - } - $inString = 0; # end of comment aborts a string - $string = ""; - } - else - {$inComment = 2;} - } - - if ($t eq "\"") - { - if (!$inString) - { - $inString=1; - next; - } - else - { - $inString=0; - $t = $string; - $string = ""; -# if ($VerboseMode) {print "string : [$t]\n"; } - } - } - - if ($inString) - { - $string.= $t; - next; - } - push @tokens, $t; - } - - my $CurrentTraceFormatString; - my $CurrentTraceFormatCategory; - # format Key as specified by the @TraceFormatCategory tag is either the current category - # or the current UID - my $CurrentFormatTableKey; - - - my $line=1; - parse_scope($filescope, \@tokens, \$line); - - #print $in; - #print join (" ", @tokens); -} # end of H2Trace - - - - sub parse_scope($$$) { - my ($scope, $tokens, $line) = @_; - my $state = 1; - - my @classes; - my $curr_offset=0; - my $overall_align=0; -# print ">parse_scope $scope->{name}\n"; - - while (scalar(@$tokens)) - { - my $t = shift @$tokens; -# printf "t: [$t] [$$line]\n"; - if (!defined ($t)) { - printf "undefined !"; - next; - } - if ($state>=-1 and $t eq "\n") { - ++$$line; - $state=1; - next; - } elsif ($state==-1 and $t ne "\n") { - next; - } elsif ($state==-2 and $t ne ';') { - next; - } - - if ($state>0 and $t eq '#') { - $t = shift @$tokens; - if ($t eq 'define') { - my $ident = shift @$tokens; - my $defn = shift @$tokens; - if ($defn ne '(') { # don't do macros with parameters -# print "MACRO: $ident :== $defn\n"; - $macros{$ident} = $defn; - } - } - $state=-1; # skip to next line - next; - } - - - if (parse_doxygen($scope,$tokens, $line, $t) == 1) - {next;} - - if ($t eq "namespace" ) { - $state=0; - my %cl; - $cl{specifier}=$t; - $cl{scope}=$scope; - $cl{values}=$scope->{values}; - $cl{members}=\$scope->{members}; - $cl{typedefs}=\$scope->{typedefs}; - $cl{FormatTables}=$scope->{FormatTables}; - $cl{formatStrings} =$scope->{formatStrings}; - $cl{formatCategories} =$scope->{formatCategories}; - - my $new_namespace = \%cl; - my $n = get_token($scope,$tokens,$line); - if ($n !~ /\w+/) { - warn "Unnamed $t not supported at line $$line\n"; - return; - } - $new_namespace->{name}=$n; - my @class_match = grep {$_->{name} eq $n} @classes; - my $exists = scalar(@class_match); - my $b = get_token($scope,$tokens,$line); - if ($b eq ':') { - die "Inheritance not supported at line $$line\n"; - } elsif ($b eq ';') { - # forward declaration - push @classes, $new_namespace unless ($exists); - next; - } elsif ($b ne '{') { - warn "Syntax error#1 at line $$line\n"; - return; - } - if ($exists) { - $new_namespace = $class_match[0]; - if ($new_namespace->{complete}) { - warn "Duplicate definition of $cl{specifier} $n\n"; - } - } - push @classes, $new_namespace unless ($exists); - parse_scope($new_namespace, $tokens, $line); - next; - } - - if ($t eq "struct" or $t eq "class" or $t eq "NONSHARABLE_CLASS") { - next if ($state==0); - $state=0; - my %cl; - $cl{specifier}=$t; - $cl{scope}=$scope; - my @members; - my @typedefs; - $cl{members}=\@members; - $cl{typedefs}=\@typedefs; - $cl{FormatTables}=$scope->{FormatTables}; - my $new_class = \%cl; - my $n; - - if ($t eq "NONSHARABLE_CLASS") - { - my $b = get_token($scope,$tokens,$line); - if ($b !~ /\(/) {die "Syntax error at line $$line\n";} - $n = get_token($scope,$tokens,$line); - $b = get_token($scope,$tokens,$line); - if ($b !~ /\)/) {die "Syntax error at line $$line\n";} - } - else - { - $n = get_token($scope,$tokens,$line); - } - - - if ($n !~ /\w+/) { - warn "Unnamed $t not supported at line $$line\n"; - return; - } - $new_class->{name}=$n; - my @class_match = grep {$_->{name} eq $n} @classes; - my $exists = scalar(@class_match); - my $b = get_token($scope,$tokens,$line); - #skip inheritance etc until we get to a '{' or \ ';' - while ($b ne '{' && $b ne ';') - { - $b = get_token($scope,$tokens,$line); - die "Syntax error#2 at line $$line\n" if (!defined $b); - } - if ($b eq ';') { - # forward declaration - push @classes, $new_class unless ($exists); - next; - } - if ($exists) { - $new_class = $class_match[0]; - if ($new_class->{complete}) { - warn "Duplicate definition of $cl{specifier} $n\n"; - } - } - push @classes, $new_class unless ($exists); - parse_scope($new_class, $tokens, $line); - next; - } elsif ($t eq "enum") { - $state=0; - my $n = get_token($scope,$tokens,$line); - my $name=""; - if ($n =~ /\w+/) { - $name = $n; - $n = get_token($scope,$tokens,$line); - } - push @enums, $name; - if ($n ne '{') { - die "Syntax error#4 at line $$line\n"; - } - parse_enum($scope, $tokens, $line, $name); - next; - } elsif ($t eq '}') { - $state=0; - if ($scope->{scope}) { - if ($scope->{specifier} eq "namespace") - { - $scope->{complete}=1; -# print "Scope completed\n"; - last; - } - $t = get_token($scope,$tokens,$line); - # skip to next ';' - while (defined ($t) and $t ne ';') - {$t = get_token($scope,$tokens,$line);} - die "Syntax error#5 at line $$line\n" if ($t ne ';'); - $scope->{complete}=1; -# print "Scope completed\n"; - last; - } - warn "Syntax error#5 at line $$line\n"; - return; - } - $state=0; - if ($scope->{scope}) { - if ($t eq "public" or $t eq "private" or $t eq "protected") { - if (shift (@$tokens) eq ':') { - next; # ignore access specifiers - } - die "Syntax error#6 at line $$line\n"; - } - } - unshift @$tokens, $t; - - my @currdecl = parse_decl_def($scope, $tokens, $line); -# print scalar (@currdecl), "\n"; - if ($t eq 'static') { - next; # skip static members - } - my $typedef; - if ($t eq 'typedef') { -# print "TYPEDEF\n"; - $typedef = 1; - $t = shift @currdecl; - $t = $currdecl[0]; - } else { -# print "NOT TYPEDEF\n"; - $typedef = 0; - } -# print "$currdecl[0]\n"; - next if (scalar(@currdecl)==0); - - if ($t eq "const") { - # check for constant declaration -# print "CONST $currdecl[1] $currdecl[2] $currdecl[3]\n"; - my $ctype = lookup_type($scope, $currdecl[1]); -# print "$ctype->{basic} $ctype->{size}\n"; - if ($ctype->{basic} and $currdecl[2]=~/^\w+$/ and $currdecl[3] eq '=') { - if ($typedef!=0) { - die "Syntax error#7 at line $$line\n"; - } - shift @currdecl; - shift @currdecl; - my $type = $ctype->{name}; - my $name; #### = shift @currdecl; - - if ($scope->{name}) - { - $name = $scope->{name} . "::" . shift @currdecl; - } - else - { - $name = shift @currdecl; - } -# printf "[$name,$scope->{name}]"; - my $size = $ctype->{size}; - shift @currdecl; - my $value = get_constant_expr($scope,\@currdecl,$line); - $values{$name} = {type=>$type, size=>$size, value=>$value}; - next; - } - } - - - - } - } - - sub get_token($$$) { - my ($scope,$tokenlist,$line) = @_; - while (scalar(@$tokenlist)) { - my $t = shift @$tokenlist; - return $t if (!defined($t)); - if (parse_doxygen($scope,$tokenlist, $line, $t) == 1) - {next;} - if ($t !~ /^[\s]*$/) - { - if ($$tokenlist[0] eq ":" and $$tokenlist[1] eq ":") - { - $t.= shift @$tokenlist; - $t.= shift @$tokenlist; - $t.= shift @$tokenlist; -# print "Colon-separated token"; - } - return $t - } - ++$$line; - } - return undef; - } - - sub skip_qualifiers($) { - my ($tokens) = @_; - my $f=0; - my %quals = ( - EXPORT_C => 1, - IMPORT_C => 1, - inline => 1, - virtual => 0, - const => 0, - volatile => 0, - static => 0, - extern => 0, - LOCAL_C => 0, - LOCAL_D => 0, - GLDEF_C => 0, - GLREF_C => 0, - GLDEF_D => 0, - GLREF_D => 0 - ); - for (;;) { - my $t = $$tokens[0]; - my $q = $quals{$t}; - last unless (defined ($q)); - $f |= $q; - shift @$tokens; - } - return $f; - } - - sub parse_indirection($) { - my ($tokens) = @_; - my $level = 0; - for (;;) { - my $t = $$tokens[0]; - if ($t eq '*') { - ++$level; - shift @$tokens; - next; - } - last if ($t ne "const" and $t ne "volatile"); - shift @$tokens; - } - return $level; - } - - sub get_operand($$$) { - my ($scope,$tokens,$line) = @_; - my $t = get_token($scope,$tokens,$line); - if ($t eq '-') { - my $x = get_operand($scope,$tokens,$line); - return -$x; - } elsif ($t eq '+') { - my $x = get_operand($scope,$tokens,$line); - return $x; - } elsif ($t eq '~') { - my $x = get_operand($scope,$tokens,$line); - return ~$x; - } elsif ($t eq '!') { - my $x = get_operand($scope,$tokens,$line); - return $x ? 0 : 1; - } elsif ($t eq '(') { - my $x = get_constant_expr($scope,$tokens,$line); - my $t = get_token($scope,$tokens,$line); - if ($t ne ')') { - warn "Missing ) at line $$line\n"; - return undefined; - } - return $x; - } elsif ($t eq "sizeof") { - my $ident = get_token($scope,$tokens,$line); - if ($ident eq '(') { - $ident = get_token($scope,$tokens,$line); - my $cb = get_token($scope,$tokens,$line); - if ($cb ne ')') { - warn "Bad sizeof() syntax at line $$line\n"; - return undefined; - } - } - $ident = look_through_macros($ident); - if ($ident !~ /^\w+$/) { - warn "Bad sizeof() syntax at line $$line\n"; - return undefined; - } - my $type = lookup_type($scope, $ident); - if (!defined $type) { - warn "Unrecognised type $ident at line $$line\n"; - return undefined; - } - if ($type->{basic}) { - return $type->{size}; - } elsif ($type->{enum}) { - return 4; - } elsif ($type->{ptr}) { - return 4; - } elsif ($type->{fptr}) { - return 4; - } - my $al = $type->{class}->{align}; - my $sz = $type->{class}->{size}; - return ($sz+$al-1)&~($al-1); - } - $t = look_through_macros($t); - if ($t =~ /^0x/i) { - return oct($t); - } elsif ($t =~ /^\d/) { - return $t; - } elsif ($t =~ /^\w+$/) { - my $x = lookup_value($scope,$t); -# die "Unrecognised identifier '$t' at line $$line\n" unless defined($x); - if (!defined($x)) { - print "Unrecognised identifier '$t' at line $$line\n" ; - } - return $x; - } elsif ($t =~ /^\w+::\w+$/) { - my $x = lookup_value($scope,$t); -# die "Unrecognised identifier '$t' at line $$line\n" unless defined($x); - if (!defined($x)) { - print "Unrecognised identifier '$t' at line $$line\n" ; - } - return $x; - } else { - warn "Syntax error#10 at line $$line\n"; - return undefined; - } - } - - sub look_through_macros($) { - my ($ident) = @_; - while ($ident and $macros{$ident}) { - $ident = $macros{$ident}; - } - return $ident; - } - - sub lookup_value($$) { - my ($scope,$ident) = @_; - while ($scope) { - my $vl = $scope->{values}; - if (defined($vl->{$ident})) { - return $vl->{$ident}->{value}; - } - $scope = $scope->{scope}; - } - return undef(); - } - - sub lookup_type($$) { - my ($scope,$ident) = @_; - if ($basictypes{$ident}) { - return {scope=>$scope, basic=>1, name=>$ident, size=>$basictypes{$ident} }; - } - while ($scope) { - if ($basictypes{$ident}) { - return {scope=>$scope, basic=>1, name=>$ident, size=>$basictypes{$ident} }; - } - my $el = $scope->{enums}; - my $cl = $scope->{classes}; - my $td = $scope->{typedefs}; - if (grep {$_ eq $ident} @$el) { - return {scope=>$scope, enum=>1, name=>$ident, size=>4 }; - } - my @match_class = (grep {$_->{name} eq $ident} @$cl); - if (scalar(@match_class)) { - return {scope=>$scope, class=>$match_class[0]}; - } - my @match_td = (grep {$_->{name} eq $ident} @$td); - if (scalar(@match_td)) { - my $tdr = $match_td[0]; - my $cat = $tdr->{category}; - if ($cat eq 'basic' or $cat eq 'enum' or $cat eq 'class') { - $ident = $tdr->{alias}; - next; - } else { - return { scope=>$scope, $cat=>1, $size=>$tdr->{size} }; - } - } - $scope = $scope->{scope}; - } - return undef(); - } - - sub get_mult_expr($$$) { - my ($scope,$tokens,$line) = @_; - my $x = get_operand($scope,$tokens,$line); - my $t; - for (;;) { - $t = get_token($scope,$tokens,$line); - if ($t eq '*') { - my $y = get_operand($scope,$tokens,$line); - $x = $x * $y; - } elsif ($t eq '/') { - my $y = get_operand($scope,$tokens,$line); - if ($y != 0) - {$x = int($x / $y);} - } elsif ($t eq '%') { - my $y = get_operand($scope,$tokens,$line); - if ($y != 0) - {$x = int($x % $y);} - } else { - last; - } - } - unshift @$tokens, $t; - return $x; - } - - sub get_add_expr($$$) { - my ($scope,$tokens,$line) = @_; - my $x = get_mult_expr($scope,$tokens,$line); - my $t; - for (;;) { - $t = get_token($scope,$tokens,$line); - if ($t eq '+') { - my $y = get_mult_expr($scope,$tokens,$line); - $x = $x + $y; - } elsif ($t eq '-') { - my $y = get_mult_expr($scope,$tokens,$line); - $x = $x - $y; - } else { - last; - } - } - unshift @$tokens, $t; - return $x; - } - - sub get_shift_expr($$$) { - my ($scope,$tokens,$line) = @_; - my $x = get_add_expr($scope,$tokens,$line); - my $t, $t2; - for (;;) { - $t = get_token($scope,$tokens,$line); - if ($t eq '<' or $t eq '>') { - $t2 = get_token($scope,$tokens,$line); - if ($t2 ne $t) { - unshift @$tokens, $t2; - last; - } - } - if ($t eq '<') { - my $y = get_add_expr($scope,$tokens,$line); - $x = $x << $y; - } elsif ($t eq '>') { - my $y = get_add_expr($scope,$tokens,$line); - $x = $x >> $y; - } else { - last; - } - } - unshift @$tokens, $t; - return $x; - } - - sub get_and_expr($$$) { - my ($scope,$tokens,$line) = @_; - my $x = get_shift_expr($scope,$tokens,$line); - my $t; - for (;;) { - $t = get_token($scope,$tokens,$line); - if ($t eq '&') { - my $y = get_shift_expr($scope,$tokens,$line); - $x = $x & $y; - } else { - last; - } - } - unshift @$tokens, $t; - return $x; - } - - sub get_xor_expr($$$) { - my ($scope,$tokens,$line) = @_; - my $x = get_and_expr($scope,$tokens,$line); - my $t; - for (;;) { - $t = get_token($scope,$tokens,$line); - if ($t eq '^') { - my $y = get_and_expr($scope,$tokens,$line); - $x = $x ^ $y; - } else { - last; - } - } - unshift @$tokens, $t; - return $x; - } - - sub get_ior_expr($$$) { - my ($scope,$tokens,$line) = @_; - my $x = get_xor_expr($scope,$tokens,$line); - my $t; - for (;;) { - $t = get_token($scope,$tokens,$line); - if ($t eq '|') { - my $y = get_xor_expr($scope,$tokens,$line); - $x = $x | $y; - } else { - last; - } - } - unshift @$tokens, $t; - return $x; - } - - sub get_constant_expr($$$) { - my ($scope,$tokens,$line) = @_; - my $x = get_ior_expr($scope,$tokens,$line); - return $x; - } - - sub parse_enum($$$$) { - my ($scope,$tokens,$line,$enum_name) = @_; - my $vl = $scope->{values}; - my $fstr = $scope->{formatStrings}; - my $fcat = $scope->{formatCategories}; - my $fmtTable = $scope->{FormatTables}; - - my $x = 0; - for (;;) { - my $t = get_token($scope,$tokens,$line); - last if ($t eq '}'); - if (!defined($t)) { - die "Unexpected end of file #2 at line $$line\n"; - } - - if ($t eq '#') { - next; - } - - if ($t !~ /^\w+$/) { - warn "Syntax error#11 at line $$line\n"; - next; - } - - if ($scope->{name}) - { - $t = $scope->{name} . "::" . $t; - } - - if (defined($vl->{$t})) { - warn "Duplicate identifier [$t] at line $$line\n"; - } - my $t2 = get_token($scope,$tokens,$line); - if ($t2 eq ',') { - $vl->{$t} = {type=>$enum_name, size=>4, value=>$x, enum=>1}; - $fstr->{$t} = $CurrentTraceFormatString; - $fcat->{$t} = $CurrentTraceFormatCategory; - if (defined $CurrentTraceFormatCategory && defined $CurrentTraceFormatString) - { $fmtTable->{$CurrentTraceFormatCategory}{$x} = $CurrentTraceFormatString; } - undef $CurrentTraceFormatString; - ++$x; - } elsif ($t2 eq '}') { - $vl->{$t} = {type=>$enum_name, size=>4, value=>$x, enum=>1}; - $fstr->{$t} = $CurrentTraceFormatString; - $fcat->{$t} = $CurrentTraceFormatCategory; - if (defined $CurrentTraceFormatCategory && defined $CurrentTraceFormatString) - { $fmtTable->{$CurrentTraceFormatCategory}{$x} = $CurrentTraceFormatString; } - undef $CurrentTraceFormatString; - ++$x; - last; - } elsif ($t2 eq '=') { - $x = get_constant_expr($scope, $tokens, $line); - $vl->{$t} = {type=>$enum_name, size=>4, value=>$x, enum=>1}; - $fstr->{$t} = $CurrentTraceFormatString; - $fcat->{$t} = $CurrentTraceFormatCategory; - if (defined $CurrentTraceFormatCategory && defined $CurrentTraceFormatString) - { $fmtTable->{$CurrentTraceFormatCategory}{$x} = $CurrentTraceFormatString; } - undef $CurrentTraceFormatString; - ++$x; - $t2 = get_token($scope,$tokens,$line); - last if ($t2 eq '}'); - next if ($t2 eq ','); - warn "Syntax error#12 at line $$line\n"; - } else { - unshift @$tokens, $t2; - } - } - my $t = get_token($scope,$tokens,$line); - if ($t ne ';') { - warn "Missing ; at line $$line\n"; - } - } - - - sub parse_decl_def($$$) { - my ($scope,$tokens,$line) = @_; - my $level=0; - my @decl; - while ( scalar(@$tokens) ) { - my $t = get_token($scope,$tokens, $line); - if ( (!defined ($t) || $t eq ';') and ($level==0)) { - return @decl; - } - - if ($t eq "static") - { - next; - } - - push @decl, $t; - if ($t eq '{') { - ++$level; - } - if ($t eq '}') { - if ($level==0) { - warn "Syntax error#13 at line $$line\n"; - unshift @$tokens, $t; - return @decl; - - } - if (--$level==0) { - return (); # end of function definition reached - } - } - } - die "Unexpected end of file #3 at line $$line\n"; - } - - sub dump_scope($) { - my ($scope) = @_; - my $el = $scope->{enums}; - my $cl = $scope->{classes}; - my $vl = $scope->{values}; - my $fstr = $scope->{formatStrings}; - my $fcat = $scope->{formatCategories}; - print "SCOPE: $scope->{name}\n"; - if (scalar(@$el)) { - print "\tenums:\n"; - foreach (@$el) { - print "\t\t$_\n"; - } - } - if (scalar(keys(%$vl))) { - print "\tvalues:\n"; - foreach $vname (keys(%$vl)) { - my $v = $vl->{$vname}; - my $x = $v->{value}; - my $t = $v->{type}; - my $sz = $v->{size}; - my $fstring = $fstr->{$vname}; - my $fcategory = $fcat->{$vname}; - if ($v->{enum}) { - printf ("\t\t$vname\=$x (enum $t) size=$sz fcat=[0x%x] fstr=[%s]\n", $fcategory,$fstring); - } else { - printf ("\t\t$vname\=$x (type $t) size=$sz fcat=[0x%x] fstr=[%s]\n", $fcategory, $fstring); - } - } - } - if ($scope->{scope}) { - my $members = $scope->{members}; - foreach (@$members) { - my $n = $_->{name}; - my $sz = $_->{size}; - my $off = $_->{offset}; - my $spc = $_->{spacing}; - if (defined $spc) { - print "\t$n\[\]\: spacing $spc size $sz offset $off\n"; - } else { - print "\t$n\: size $sz offset $off\n"; - } - } - print "\tOverall size : $scope->{size}\n"; - print "\tOverall align: $scope->{align}\n"; - } - foreach $s (@$cl) { - dump_scope($s); - } - } - - - - - sub parse_doxygen($$$$) { - my ($scope,$tokens,$line,$t) = @_; - - if ($t ne "/") - { - return 0; # not a doxygen comment - } - if ($t eq "/") { - $state=0; - my $t2 = shift @$tokens; - my $t3 = shift @$tokens; - - if ($t2 ne "*" || $t3 ne "*") - { - unshift @$tokens, $t3; - unshift @$tokens, $t2; - return 0; # not a doxygen comment - } - } -# printf "doxygen start on line %d\n", $$line; - for (;;) { - my $t = shift @$tokens; - if (!defined($t)) - { - warn "Unexpected end of file #4 at line $$line\n"; - return - } - - if ($t eq "\n"){++$$line }; - - if ($t eq '*') - { - my $t2 = shift @$tokens; - last if ($t2 eq '/'); - unshift @$tokens, $t2; - } - - if ($t eq '@') - { - my $t2 = shift @$tokens; - if ($t2 eq 'SYMTraceFormatString') - { - my $t3 = shift @$tokens; -# if ($VerboseMode){print "SYMTraceFormatString = [$t3]\n";} - $CurrentTraceFormatString = $t3; - } - if ($t2 eq 'SYMTraceFormatCategory') - { - $CurrentTraceFormatCategory = get_operand($scope,$tokens,$line); -# if ($VerboseMode){printf ("SYMTraceFormatCategory = 0x%x\n", $CurrentTraceFormatCategory);} - } - else - { - unshift @$tokens, $t2; - } - } - - } -# printf ("doxygen end on line %d\n", $$line); - return 1; # is a doxygen comment - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - -