Workaround ndk-stack.exe 64-bit mingw build

Regex generated by x86_64-w64-mingw32 compiler erroneously matches
frame line with #[0-9]+ in "stack:" section even when the line has no
word "pc", "eip", or "ip" in it, eg.

 stack:
   I/DEBUG   ( 1151):     #00  5f09db68  401f01c4  /system/lib/libc.so

Workaround by double-checking the line does contain pc, and ensure it
is a word, not part of filename or something

Change-Id: I247fca80cc20ab16fb4c46eb39b82b91c6f90317
diff --git a/sources/host-tools/ndk-stack/ndk-stack-parser.c b/sources/host-tools/ndk-stack/ndk-stack-parser.c
index 9753244..9ac6934 100755
--- a/sources/host-tools/ndk-stack/ndk-stack-parser.c
+++ b/sources/host-tools/ndk-stack/ndk-stack-parser.c
@@ -124,6 +124,14 @@
  */
 static const char* get_next_token(const char* str, char* token, size_t size);
 
+/* Return pointer to first word "pc", "eip", or "ip" in string "frame"
+ * param:
+ *  frame - a line from dump
+ * Return:
+ *  The first occurrence of "pc", "eip", or "ip"
+ */
+static const char* find_pc(const char *frame);
+
 NdkCrashParser*
 CreateNdkCrashParser(FILE* out_handle, const char* sym_root)
 {
@@ -220,12 +228,22 @@
       // Let it fall through to the EXPECTS_FRAME, in case the dump doesn't
       // contain signal fingerprint.
     case EXPECTS_FRAME:
-      if (MatchRegex(line, &parser->re_frame_header, &match)) {
-        parser->state = EXPECTS_FRAME;
-        return ParseFrame(parser, line + match.rm_so);
-      } else {
+      if (!MatchRegex(line, &parser->re_frame_header, &match))
         return !found;
-      }
+      // Regex generated by x86_64-w64-mingw32 compiler erroneously match
+      // frame line with #[0-9]+ in "stack:" section even when the line has
+      //  no word "pc", "eip", or "ip" in it.
+      //
+      //   stack:
+      //      I/DEBUG   ( 1151):     #00  5f09db68  401f01c4  /system/lib/libc.so
+      //
+      // To workaround, let's double check if pc is found!
+      //
+      if (!(find_pc(line)))
+        return !found;
+
+      parser->state = EXPECTS_FRAME;
+      return ParseFrame(parser, line + match.rm_so);
 
     default:
       return 1;
@@ -275,6 +293,24 @@
   }
 }
 
+static const char *
+find_pc(const char *frame)
+{
+  const char *pcstrs[] = { "pc", "eip", "ip" };
+  int i;
+  for (i=0; i<sizeof(pcstrs)/sizeof(pcstrs[0]); i++) {
+    const char *p = strstr(frame, pcstrs[i]);
+    // check it's a word, not part of filename or something
+    if (p && p!=frame) {
+      char l = p[-1];
+      char r = p[strlen(pcstrs[i])];
+      if ((l==' ' || l=='\t') && (r==' ' || r=='\t'))
+        return p;
+    }
+  }
+  return NULL;
+}
+
 int
 ParseFrame(NdkCrashParser* parser, const char* frame)
 {
@@ -297,17 +333,10 @@
   fprintf(parser->out_handle, "Stack frame %s", frame);
 
   // Advance to the instruction pointer token.
-  wrk = strstr(frame, "pc");
-  if (wrk == NULL) {
-    wrk = strstr(frame, "eip");
-    if (wrk == NULL) {
-      wrk = strstr(frame, "ip");
-      if (wrk == NULL) {
-        fprintf(parser->out_handle,
-                "Parser is unable to locate instruction pointer token.\n");
-        return -1;
-      }
-    }
+  if ((wrk=find_pc(frame)) == NULL) {
+    fprintf(parser->out_handle,
+            "Parser is unable to locate instruction pointer token.\n");
+    return -1;
   }
 
   // Next token after the instruction pointer token is its address.