~lovesyao/+junk/transgs

« back to all changes in this revision

Viewing changes to nazo/args.d

  • Committer: Nazo
  • Date: 2008-10-18 08:26:14 UTC
  • Revision ID: lovesyao@hotmail.com-20081018082614-22qgtg2gsotz5r2i
initial checkin

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
module nazo.args;
 
2
/**
 
3
 * mainの引数を扱う
 
4
 * History:
 
5
 *          0.0.0.1 バージョン付け開始
 
6
 * Authors: Nazo
 
7
 * Version: 0.0.0.1
 
8
 * License: Public Domain
 
9
 */
 
10
import std.conv;
 
11
 
 
12
template TOption(T){
 
13
  ///コンストラクタ
 
14
  this(string longer,T* prop){
 
15
    _tmp("",longer,prop);
 
16
  }
 
17
  ///コンストラクタ
 
18
  this(string shorter,string longer,T* prop){
 
19
    _tmp(shorter,longer,prop);
 
20
  }
 
21
  //dmdのmixinのバグ避け。thisの扱いが変?
 
22
  protected void _tmp(string shorter,string longer,T* prop){
 
23
    this.shorter=shorter;
 
24
    this.longer=longer;
 
25
    this.prop=prop;
 
26
  }
 
27
  ///プロパティへのポインタ
 
28
  T* prop;
 
29
}
 
30
 
 
31
///オプション
 
32
class Option{
 
33
  ///-*。省略可。
 
34
  string shorter;
 
35
  ///--*。省略不可。
 
36
  string longer;
 
37
}
 
38
 
 
39
///フラグオプション
 
40
class FlagOption:Option{
 
41
  mixin TOption!(bool);
 
42
  //バグ回避
 
43
  this(string longer,bool* prop){
 
44
    _tmp("",longer,prop);
 
45
  }
 
46
  this(string shorter,string longer,bool* prop){
 
47
    _tmp(shorter,longer,prop);
 
48
  }
 
49
  this(string shorter,string longer,bool* prop,bool set){
 
50
    _tmp(shorter,longer,prop);
 
51
    this.set=set;
 
52
  }
 
53
  ///もし指定されていたらセットする値
 
54
  bool set=true;
 
55
}
 
56
 
 
57
class ArgsOption:Option{}
 
58
///文字列のオプション
 
59
class StringOption:ArgsOption{
 
60
  mixin TOption!(string);
 
61
}
 
62
///数値のオプション
 
63
class UintOption:ArgsOption{
 
64
  mixin TOption!(uint);
 
65
}
 
66
 
 
67
///コマンドラインオプションを扱う
 
68
class Args{
 
69
  private string[] args;
 
70
  private FlagOption[] fopts;
 
71
  private ArgsOption[] aopts;
 
72
  ///オプションをセットします。
 
73
  public void setOption(Option opt){
 
74
    if(ArgsOption t=cast(ArgsOption)opt){
 
75
      aopts~=t;
 
76
    }else if(FlagOption t=cast(FlagOption)opt){
 
77
      fopts~=t;
 
78
    }else{
 
79
      assert(0);
 
80
    }
 
81
  }
 
82
  ///コンストラクタ
 
83
  this(string[] args){
 
84
    this.args=args;
 
85
  }
 
86
  ///設定します。オプションを除いた残りを返します。
 
87
  ///Bugs: -faild -ok okval
 
88
  string[] set(){
 
89
    string[] result;
 
90
    bool isOptions=true;
 
91
    string beforeCommand;
 
92
    foreach(uint index,string _arg;args){
 
93
      auto arg=_arg;
 
94
      if(index==0)continue;
 
95
      else if(isOptions){
 
96
        bool ok=false;
 
97
        if(arg[0]=='-'&&beforeCommand!="")
 
98
          throw new Exception(beforeCommand~" is not supported.");
 
99
        foreach(FlagOption opt;fopts){
 
100
          if(arg=="-"~opt.shorter||arg=="--"~opt.longer){*opt.prop=opt.set;ok=true;break;}
 
101
        }
 
102
        if(ok)continue;
 
103
        if(arg[0]=='-')beforeCommand=arg;
 
104
        else if(beforeCommand!=""){
 
105
          bool ok2=false;
 
106
          foreach(ArgsOption opt;aopts){
 
107
            if(beforeCommand=="-"~opt.shorter||beforeCommand=="--"~opt.longer){
 
108
              if(StringOption t=cast(StringOption)opt)*t.prop=arg;
 
109
              else if(UintOption t=cast(UintOption)opt)*t.prop=.toUint(arg);
 
110
              else assert(0);
 
111
              ok2=true;break;
 
112
            }
 
113
          }
 
114
          if(!ok2)
 
115
            throw new Exception(beforeCommand~" is not supported.");
 
116
          beforeCommand="";
 
117
        }else isOptions=false;
 
118
      }
 
119
      if(!isOptions){if(arg[0]=='\\')arg=arg[1..$];result~=arg;}
 
120
    }
 
121
    if(beforeCommand!="")throw new Exception(beforeCommand~" is not supported or parameter is missing.");
 
122
    return result;
 
123
  }
 
124
}
 
125
 
 
126
struct TestOptions{
 
127
  string stringTest;
 
128
  uint uintTest;
 
129
  bool flagTest;
 
130
  bool flagTest2=true;
 
131
}
 
132
import std.stdio;
 
133
unittest{
 
134
  static string[] sargs=["test","-t","test","-t2","12","--flag","-s","test","test"];
 
135
  Args arg=new Args(sargs);
 
136
  TestOptions* test=new TestOptions;
 
137
  arg.setOption(new StringOption("t","test",&test.stringTest));
 
138
  arg.setOption(new UintOption("t2","test2",&test.uintTest));
 
139
  arg.setOption(new FlagOption("f","flag",&test.flagTest));
 
140
  arg.setOption(new FlagOption("s","ssss",&test.flagTest2,false));
 
141
  string[] items=arg.set();
 
142
  assert(test.stringTest=="test");
 
143
  assert(test.uintTest==12);
 
144
  assert(test.flagTest==true);
 
145
  assert(test.flagTest2==false);
 
146
  static string[] tmp=["test","test"];
 
147
  assert(items==tmp);
 
148
}