1 /** 2 * Copyright: Copyright (c) 2010-211 Jacob Carlborg. All rights reserved. 3 * Authors: Jacob Carlborg 4 * Version: Initial created: Aug 15, 2010 5 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) 6 */ 7 module dvm.util.OptionParser; 8 9 import tango.text.Arguments; 10 import tango.text.convert.Format; 11 import tango.io.Stdout; 12 13 import mambo.core._; 14 import mambo.util.Traits; 15 16 import dvm.dvm.Options; 17 import dvm.dvm.Exceptions; 18 19 class OptionParser 20 { 21 string banner; 22 // string[] separator; 23 24 private 25 { 26 alias Format format; 27 Arguments arguments; 28 void delegate (string[] args) argsDg; 29 string helpText; 30 Option[] options; 31 } 32 33 this () 34 { 35 arguments = new Arguments; 36 } 37 38 OptionParser separator (string[] args ...) 39 { 40 foreach (arg ; args) 41 buildHelpText(arg); 42 43 return this; 44 } 45 46 OptionParser on (char shortOption, string longOption, string helpText, void delegate () dg) 47 { 48 arguments(longOption).aliased(shortOption).help(helpText).bind(dg); 49 buildHelpText(shortOption, longOption, helpText); 50 51 return this; 52 } 53 54 OptionParser on (string longOption, string helpText, void delegate () dg) 55 { 56 arguments(longOption).help(helpText).bind(dg); 57 buildHelpText(longOption, helpText); 58 59 return this; 60 } 61 62 OptionParser on (char shortOption, string longOption, string helpText, void delegate (string) dg) 63 { 64 arguments(longOption).aliased(shortOption).help(helpText).params(1).bind(cast(const(char)[] delegate (const(char)[])) dg); 65 buildHelpText(shortOption, longOption, helpText); 66 67 return this; 68 } 69 70 OptionParser on (string longOption, string helpText, void delegate (string) dg) 71 { 72 arguments(longOption).help(helpText).params(1).bind(cast(const(char)[] delegate (const(char)[])) dg); 73 buildHelpText(longOption, helpText); 74 75 return this; 76 } 77 78 OptionParser on (void delegate (string[]) dg) 79 { 80 argsDg = dg; 81 return this; 82 } 83 84 OptionParser parse (string input, bool sloppy = false) 85 { 86 if (!arguments.parse(input, sloppy)) 87 throw new InvalidOptionException(arguments.errors(&stderr.layout.sprint).assumeUnique, __FILE__, __LINE__); 88 89 handleArgs(cast(string[]) arguments(null).assigned); 90 91 return this; 92 } 93 94 OptionParser parse (string[] input, bool sloppy = false) 95 { 96 if (!arguments.parse(input, sloppy)) 97 throw new InvalidOptionException(arguments.errors(&stderr.layout.sprint).assumeUnique, __FILE__, __LINE__); 98 99 handleArgs(cast(string[]) arguments(null).assigned); 100 101 return this; 102 } 103 104 override string toString () 105 { 106 return format("{}\n{}", banner, buildHelpText).assumeUnique; 107 } 108 109 private void handleArgs (string[] args) 110 { 111 if (argsDg) argsDg(args); 112 } 113 114 private void buildHelpText (char shortOption, string longOption, string helpText) 115 { 116 options ~= Option(shortOption, longOption, helpText); 117 } 118 119 private void buildHelpText (string option, string helpText) 120 { 121 buildHelpText(char.init, option, helpText); 122 } 123 124 private void buildHelpText (string str) 125 { 126 buildHelpText("", str); 127 } 128 129 private string buildHelpText () 130 { 131 string help; 132 auto len = lengthOfLongestOption; 133 auto indentation = Options.instance.indentation; 134 auto numberOfIndentations = Options.instance.numberOfIndentations; 135 136 foreach (option ; options) 137 { 138 if (option.longOption.length == 0 && option.shortOption == char.init) 139 help ~= format("{}\n", option.helpText); 140 141 else if (option.shortOption == char.init) 142 help ~= format("{}--{}{}{}{}\n", 143 indentation ~ indentation, 144 option.longOption, 145 " ".repeat(len - option.longOption.length), 146 indentation.repeat(numberOfIndentations), 147 option.helpText); 148 149 else 150 help ~= format("{}-{}, --{}{}{}{}\n", 151 indentation, 152 option.shortOption, 153 option.longOption, 154 " ".repeat(len - option.longOption.length), 155 indentation.repeat(numberOfIndentations), 156 option.helpText); 157 } 158 159 return help; 160 } 161 162 private size_t lengthOfLongestOption () 163 { 164 size_t len; 165 166 foreach (option ; options) 167 if (option.longOption.length > len) 168 len = option.longOption.length; 169 170 return len; 171 } 172 } 173 174 private: 175 176 struct Option 177 { 178 char shortOption; 179 string longOption; 180 string helpText; 181 }