logcat: Add -D print dividers flag

Permits a single thread to collect several log buffer and
to separate them out into named buckets by keying off the
dividers ---------

Change-Id: I5a92c67383a73ea566cb9b9732d26d88d9c41c66
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index 829a0af..d831d66 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -1,4 +1,4 @@
-// Copyright 2006-2014 The Android Open Source Project
+// Copyright 2006-2015 The Android Open Source Project
 
 #include <assert.h>
 #include <ctype.h>
@@ -178,18 +178,19 @@
     return;
 }
 
-static void maybePrintStart(log_device_t* dev) {
-    if (!dev->printed) {
-        dev->printed = true;
+static void maybePrintStart(log_device_t* dev, bool printDividers) {
+    if (!dev->printed || printDividers) {
         if (g_devCount > 1 && !g_printBinary) {
             char buf[1024];
-            snprintf(buf, sizeof(buf), "--------- beginning of %s\n",
+            snprintf(buf, sizeof(buf), "--------- %s %s\n",
+                     dev->printed ? "switch to" : "beginning of",
                      dev->device);
             if (write(g_outFD, buf, strlen(buf)) < 0) {
                 perror("output error");
                 exit(-1);
             }
         }
+        dev->printed = true;
     }
 }
 
@@ -227,6 +228,7 @@
                     "  -n <count>      Sets max number of rotated logs to <count>, default 4\n"
                     "  -v <format>     Sets the log print format, where <format> is:\n\n"
                     "                  brief color long process raw tag thread threadtime time\n\n"
+                    "  -D              print dividers between each log buffer\n"
                     "  -c              clear (flush) the entire log and exit\n"
                     "  -d              dump the log and then exit (don't block)\n"
                     "  -t <count>      print only the most recent <count> lines (implies -d)\n"
@@ -329,6 +331,7 @@
     log_device_t* devices = NULL;
     log_device_t* dev;
     bool needBinary = false;
+    bool printDividers = false;
     struct logger_list *logger_list;
     unsigned int tail_lines = 0;
     log_time tail_time(log_time::EPOCH);
@@ -345,7 +348,7 @@
     for (;;) {
         int ret;
 
-        ret = getopt(argc, argv, "cdt:T:gG:sQf:r:n:v:b:BSpP:");
+        ret = getopt(argc, argv, "cdDt:T:gG:sQf:r:n:v:b:BSpP:");
 
         if (ret < 0) {
             break;
@@ -398,6 +401,10 @@
                 }
             break;
 
+            case 'D':
+                printDividers = true;
+            break;
+
             case 'g':
                 getLogSize = 1;
             break;
@@ -839,8 +846,10 @@
     if (needBinary)
         android::g_eventTagMap = android_openEventTagMap(EVENT_TAG_MAP_FILE);
 
+    dev = NULL;
     while (1) {
         struct log_msg log_msg;
+        log_device_t* d;
         int ret = android_logger_list_read(logger_list, &log_msg);
 
         if (ret == 0) {
@@ -865,17 +874,20 @@
             exit(EXIT_FAILURE);
         }
 
-        for(dev = devices; dev; dev = dev->next) {
-            if (android_name_to_log_id(dev->device) == log_msg.id()) {
+        for(d = devices; d; d = d->next) {
+            if (android_name_to_log_id(d->device) == log_msg.id()) {
                 break;
             }
         }
-        if (!dev) {
+        if (!d) {
             fprintf(stderr, "read: Unexpected log ID!\n");
             exit(EXIT_FAILURE);
         }
 
-        android::maybePrintStart(dev);
+        if (dev != d) {
+            dev = d;
+            android::maybePrintStart(dev, printDividers);
+        }
         if (android::g_printBinary) {
             android::printBinary(&log_msg);
         } else {