--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Data::Dumper;
+
+@ARGV || do {
+ die "Usage: $0 SRCFILE ...\n"
+ . "Extract log message from specified source code,\n"
+ . "and output log lists in CSV format.\n"
+ . "\n"
+ . "Example:\n"
+ . " \$ $0 ../src/*.c ../module/*/*.c*\n";
+};
+
+my %all_log;
+$| = 1;
+
+# pick out all log message!
+for my $src (@ARGV) {
+ print STDERR "reading $src ... ";
+ if (!-f $src) {
+ print STDERR "\n$src: No such file\nPush Enter key to continue.\n";
+ <STDIN>;
+ next;
+ }
+ my $fh;
+ if (!open $fh, "<", $src) {
+ print STDERR "\n$src: Cannot open file\nPush Enter key to continue.\n";
+ <STDIN>;
+ next;
+ }
+ my $all_line;
+ map { $all_line .= $_ } <$fh>;
+ close $fh;
+
+ # remove all CRLF
+ $all_line =~ s/[\r\n]//g;
+ my $count = 0;
+
+ # log function regex
+ while ($all_line =~ /
+ ( # capture start
+ (?:
+ LOGGER_PUT_LOG_([^\s(]+) \s* \( \s* # LOGGER_PUT_LOG_LEVEL start
+ | # or
+ PUT_LOG_([^\s(]+) \s* \( [^,]+, \s* # PUT_LOG_LEVEL start
+ )
+ ([^\s,]+) \s* , \s* # log category
+ (\d+) \s* , \s* # log number
+ ( (?: (?: "[^"]*" \s* )+ | [^,)]+) ) # log message
+ .*? # any argument
+ \) \s* ; # log function end
+ ) # capture end
+ /xsg) {
+ my ($log, $category, $number, $message) = ($1, $4, $5, $6);
+ my $level = $2 || $3;
+
+ # push to hash table (push for duplicate log)
+ push @{ $all_log{$category}{$level}{$number}{file } }, $src;
+ push @{ $all_log{$category}{$level}{$number}{log } }, $log;
+ push @{ $all_log{$category}{$level}{$number}{message } }, $message;
+
+ $count++;
+ }
+ print STDERR "$count logs.\n";
+}
+
+#print Dumper \%all_log;
+#exit;
+
+# output log list
+my %summary;
+my @duplicate_list;
+for my $category (sort keys %all_log) {
+ print "===== $category =====\n";
+ for my $level ( sort keys %{ $all_log{$category} } ) {
+ print "----- $level -----\n";
+ for my $number ( sort { $a <=> $b } keys %{ $all_log{$category}{$level} } ) {
+ my $entry = $#{ $all_log{$category}{$level}{$number}{file} };
+ for (0 .. $entry) {
+ my $file = $all_log{$category}{$level}{$number}{file }[$_];
+ my $log = $all_log{$category}{$level}{$number}{log }[$_];
+ my $message = $all_log{$category}{$level}{$number}{message}[$_];
+ # CSV
+ print "$category,$level,$number,$file,$message,";
+ if ($entry > 0) {
+ # duplicate tag
+ print "DUPLICATE";
+ push @duplicate_list, "$file: $log\n";
+ }
+ print "\n";
+ $summary{$category}{all}++;
+ $summary{$category}{$level}++;
+ $summary{$category}{duplicate}{all} += $entry;
+ $summary{$category}{duplicate}{$level} += $entry;
+ }
+ }
+ }
+ print "\n";
+}
+
+# print all duplicate log
+#print "===== DUPLICATE LOG =====\n";
+#for (@duplicate_list) {
+# print;
+#}
+#print "\n";
+
+# print summary
+print "===== SUMMARY =====\n";
+for my $category (sort keys %summary) {
+ # category has duplicate log
+ if ( $summary{$category}{duplicate}{all} ) {
+ print "$category (duplicate)\n";
+ printf "ALL: %d(%d), ", $summary{$category}{all} || 0, $summary{$category}{duplicate}{all} || 0;
+ printf "FATAL: %d(%d), ", $summary{$category}{FATAL} || 0, $summary{$category}{duplicate}{FATAL} || 0;
+ printf "ERROR: %d(%d), ", $summary{$category}{ERROR} || 0, $summary{$category}{duplicate}{ERROR} || 0;
+ printf "WARN: %d(%d), ", $summary{$category}{WARN} || 0, $summary{$category}{duplicate}{WARN} || 0;
+ printf "INFO: %d(%d), ", $summary{$category}{INFO} || 0, $summary{$category}{duplicate}{INFO} || 0;
+ printf "DEBUG: %d(%d)", $summary{$category}{DEBUG} || 0, $summary{$category}{duplicate}{DEBUG} || 0;
+ print "\n";
+ }
+ # category has no duplicate log
+ else {
+ print "$category\n";
+ printf "ALL: %d, ", $summary{$category}{all} || 0;
+ printf "FATAL: %d, ", $summary{$category}{FATAL} || 0;
+ printf "ERROR: %d, ", $summary{$category}{ERROR} || 0;
+ printf "WARN: %d, ", $summary{$category}{WARN} || 0;
+ printf "INFO: %d, ", $summary{$category}{INFO} || 0;
+ printf "DEBUG: %d ", $summary{$category}{DEBUG} || 0;
+ print "\n";
+ }
+}