From 6fe6bb790a18ac59012d69d5d1a132e2e04faeae Mon Sep 17 00:00:00 2001
From: Per Lindgren <per.lindgren@ltu.se>
Date: Thu, 15 Nov 2018 14:10:49 +0100
Subject: [PATCH] parsing

---
 README.md   |   4 +-
 src/main.rs | 199 ++++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 149 insertions(+), 54 deletions(-)

diff --git a/README.md b/README.md
index b5f0eef..c7deed7 100644
--- a/README.md
+++ b/README.md
@@ -2,15 +2,13 @@
 A cargo sub-commond for spanning the call stack for a `cortex-m` bare metal application.
 
 ## Installing
-> cargo install --path <PATH_TO cargo-call-stack>
+> cargo install --path <PATH_TO cargo-call-stack> -f
 
 ## Usage
 Assume we have have an existing `cortex-m` bare metal application, e.g., ...
 
 > cargo call-stack --release --example hello1
 
-
-
 ## Tech notes
 
 ### Cargo sub-commands
diff --git a/src/main.rs b/src/main.rs
index 545587e..2f1ba12 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -4,6 +4,80 @@ use std::io::{self, Read, Write};
 use std::process::{Command, Stdio};
 use std::{env, str};
 
+#[derive(Debug)]
+struct Out {
+    hash: Option<String>,
+    crate_name: Option<String>,
+    out_dir: Option<String>,
+}
+
+// Parse the output from rustc
+// we skip the last line (Finished ...)
+// and look for `--crate-name x`, `extra-filename=y` and `--out dir z`
+//
+// Notice, the parsing is a bit of a hack, implemnting look ahead using flags.
+fn parse_out(out_str: &str) -> Out {
+    let mut out = Out {
+        hash: None,
+        crate_name: None,
+        out_dir: None,
+    };
+    let output = out_str;
+    let mut i = output.lines().into_iter();
+    i.next_back(); // skip last line (Finished)
+    if let Some(line) = i.next_back() {
+        let mut crate_name = false;
+        let mut out_dir = false;
+        for part in line.split(' ') {
+            if crate_name {
+                out.crate_name = Some(part.to_string());
+                crate_name = false;
+            } else if out_dir {
+                out.out_dir = Some(part.to_string());
+                out_dir = false;
+            } else if part.starts_with("--crate-name") {
+                crate_name = true;
+            } else if part.starts_with("--out-dir") {
+                out_dir = true;
+            } else if part.starts_with("extra-filename=") {
+                out.hash = Some(part.split('=').nth(1).unwrap().to_string());
+            }
+        }
+    }
+    out
+}
+
+fn parse_output(output: &str) -> (Option<&str>, Option<&str>, Option<&str>) {
+    let mut suffix = None;
+    let mut crate_name = None;
+    let mut example = None;
+
+    let output = str::from_utf8(output.as_bytes()).unwrap();
+    println!("here ...");
+    let mut i = output.lines().into_iter();
+    i.next_back(); // skip last line
+    if let Some(line) = i.next_back() {
+        let mut b = false;
+        for part in line.split(' ') {
+            if b {
+                crate_name = Some(part);
+                b = false;
+            } else if part.starts_with("--crate-name") {
+                b = true;
+                println!("----- here ---------- {:?}", crate_name);
+            } else if part.starts_with("extra-filename=") {
+                suffix = part.split('=').nth(1);
+                println!("----- there ----------");
+            } else if part.starts_with("example") {
+                example = part.split('/').nth(1);
+                println!("----- there ----------");
+            };
+        }
+        //}
+    }
+    (suffix, crate_name, example)
+}
+
 fn main() {
     println!("start sub command");
     // first argument is the path to this binary; the second argument is always "call-stack" -- both can
@@ -57,60 +131,74 @@ fn main() {
         }
     }
 
+    let out = parse_out(str::from_utf8(&output).unwrap());
+    println!("{:?}", out);
+    // } else {
+    //     panic!("could not determine hash, please recompile in `--release` mode");
+    // }
+
     // find out the argument passed to `--example`, if used at all
-    let mut example = None;
-    let mut iargs = args.iter();
-    while let Some(arg) = iargs.next() {
-        if arg == "--example" {
-            example = iargs.next();
-            break;
-        }
-    }
+    // let mut example = None;
+    // let mut iargs = args.iter();
+    // while let Some(arg) = iargs.next() {
+    //     if arg == "--example" {
+    //         example = iargs.next();
+    //         break;
+    //     }
+    // }
 
-    // get the suffix of the example
-    let (example, suffix) = if let Some(example) = example {
-        let mut suffix = None;
-        let output = str::from_utf8(&output).unwrap();
-        println!("here ...");
-        for line in output.lines() {
-            if line.contains(&format!("examples/{}.rs", example)) {
-                for part in line.split(' ') {
-                    if part.starts_with("extra-filename=") {
-                        suffix = part.split('=').nth(1);
-                    }
-                }
-            }
-        }
-        match suffix {
-            None => panic!(format!(
-                "Cannot determine hash, please run `touch example/{}.rs` to force recompiltaion.",
-                example
-            )),
-            Some(s) => (example, s),
-        }
-    } else {
-        // nothing to do if the user didn't use `--example`
-        println!("try to determinte hash");
-        let output = str::from_utf8(&output).unwrap();
-        println!("here ...");
-        let mut suffix = None;
-        for line in output.lines() {
-            for part in line.split(' ') {
-                if part.starts_with("extra-filename=") {
-                    suffix = part.split('=').nth(1);
-                }
-            }
-        }
-        match suffix {
-            None => panic!(format!(
-                "Cannot determine hash, please force recompiltaion."
-            )),
-            Some(s) => panic!("main hash {}", s),
-        }
-        // return;
-    };
+    // let output = str::from_utf8(&output).unwrap();
+
+    // if let (Some(hash), Some(crate_name), example) = parse_output(&output) {
+    //     println!("{:?}, {:?}, {:?}", example, hash, crate_name);
+    // } else {
+    //     panic!("could not determine hash, please recompile in `--release` mode");
+    // }
+
+    // // get the suffix of the example
+    // let (example, suffix) = if let Some(example) = example {
+    //     let mut suffix = None;
+    //     let output = str::from_utf8(&output).unwrap();
+    //     println!("here ...");
+    //     for line in output.lines() {
+    //         if line.contains(&format!("examples/{}.rs", example)) {
+    //             for part in line.split(' ') {
+    //                 if part.starts_with("extra-filename=") {
+    //                     suffix = part.split('=').nth(1);
+    //                 }
+    //             }
+    //         }
+    //     }
+    //     match suffix {
+    //         None => panic!(format!(
+    //             "Cannot determine hash, please run `touch example/{}.rs` to force recompiltaion.",
+    //             example
+    //         )),
+    //         Some(s) => (example, s),
+    //     }
+    // } else {
+    //     // nothing to do if the user didn't use `--example`
+    //     println!("try to determinte hash");
+    //     let output = str::from_utf8(&output).unwrap();
+    //     println!("here ...");
+    //     let mut suffix = None;
+    //     for line in output.lines() {
+    //         for part in line.split(' ') {
+    //             if part.starts_with("extra-filename=") {
+    //                 suffix = part.split('=').nth(1);
+    //             }
+    //         }
+    //     }
+    //     match suffix {
+    //         None => panic!(format!(
+    //             "Cannot determine hash, please force recompiltaion."
+    //         )),
+    //         Some(s) => panic!("main hash {}", s),
+    //     }
+    //     // return;
+    // };
 
-    println!("{:?}", (example, suffix));
+    // println!("{:?}", (example, suffix));
 
     /*
         let profile = if args.iter().any(|a| a == "--release") {
@@ -152,3 +240,12 @@ fn main() {
         unsafe { libc::getuid() }
         */
 }
+// blx511
+// ARN
+// LINDGREN
+// PER
+// 03021968 PiteƄ
+// Swedish
+// pass#
+// Aquamarine
+// Tourist
-- 
GitLab