1 /* 2 Purpose : Parse user input 3 Author : Ky-Anh Huynh 4 Date : 2017 Sep 19th 5 License : MIT 6 */ 7 8 module plotbar.utils; 9 10 void parse_argument(string[] args, out uint min_percent) 11 in { 12 assert(args.length > 0, "Input args must contain a program name."); 13 } 14 out { 15 assert(min_percent < 100, "Mininum percent must less than 100."); 16 } 17 do { 18 import std.conv; 19 import std.exception; 20 import std.getopt; 21 import std.stdio; 22 import core.stdc.stdlib: exit; 23 import std.format; 24 25 try { 26 auto helpInformation = getopt(args, 27 "m", "Minimum percent to display (0 -> 99)", &min_percent, 28 std.getopt.config.stopOnFirstNonOption 29 ); 30 31 if (helpInformation.helpWanted) { 32 defaultGetoptPrinter("dzplotbar - Draw 2-d barchart.", helpInformation.options); 33 exit(0); 34 } 35 36 } 37 catch (GetOptException exc) { 38 // Stop processing at the first unknown argument 39 } 40 catch (Exception exc) { 41 throw new Exception(format(":: Error: %s", exc.msg)); 42 } 43 44 if (min_percent >= 100) { 45 throw new Exception(":: Error: min percent must be less than 100."); 46 } 47 } 48 49 unittest { 50 import std.exception; 51 52 uint min_percent = 0; 53 parse_argument(["foo"], min_percent); 54 assert(min_percent == 0); 55 assertThrown(parse_argument(["foo", "-m", "-1"], min_percent), "Negative percent should throw an exception."); 56 assertThrown(parse_argument(["foo", "-m", "100"], min_percent), "Percent >= 100 should raise an error."); 57 58 parse_argument(["foo", "-n", "10", "-m", "10"], min_percent); 59 assert(min_percent == 10, "min percent is parsed"); 60 61 parse_argument(["foo", "-m", "10", "-m", "11", "-n", "10"], min_percent); 62 assert(min_percent == 11, "min percent is 11"); 63 } 64 65 void read_key_value(ref double[string] plotdata, in string line) { 66 import std.string : strip, split; 67 import std.array: join; 68 import std.math; 69 import std.stdio; 70 import std.format: formattedRead; 71 72 auto line_st = line.strip(); 73 auto line_st2 = line_st; 74 try { 75 string key; 76 double value; 77 if (line_st.length) { 78 auto line_st_ = line_st.split.join(' '); 79 line_st_.formattedRead!"%s %f"(key, value); 80 if (key.length && !isNaN(value) && value >= 0) { 81 plotdata[key] = value + plotdata.get(key, 0); 82 } 83 else { 84 debug(2) stderr.writefln(":: Line discarded: %s", line_st2); 85 } 86 } 87 } 88 catch (Exception exc) { 89 debug(2) stderr.writefln(":: Line ignored: %s", line_st2); 90 } 91 } 92 93 unittest { 94 double[string] result; 95 96 result.read_key_value(""); 97 assert(result is null); 98 99 result.read_key_value("a 1"); 100 result.read_key_value("b x"); 101 assert(result.length && result["a"] == 1, "Can parse key = a from space delimiter input."); 102 assert("b" !in result, "Invalid value should not be included."); 103 104 result.read_key_value("c\t1"); 105 assert(result.length && result["c"] == 1, "Can parse key = c from tab delimiter input."); 106 }