sync
[app.Builder.js] / tests / options.js
1 //<script type="text/javascript">
2
3 XObject = import XObject.XObject
4  
5 /**
6  * Options parsing is needed as GLib's built in GOptionGroup is not feasible to use in an introspected way at present.
7  * 
8  * usage :
9  * 
10  * o = new Options(
11  *    help_desription : 'Help about this',
12  *    options : [
13  *        { short : 'a', long: 'test', description : 'a test', flag_array: true , flag_boolean : false}
14  *    ]
15  * );
16  * cfg = o.parse(Seed.argv);
17  * 
18  * Currently only supports simple parsing
19  * eg. --longarg test -b test
20  * 
21  * Does not support --aaaaa=bbbb
22  */
23 Options  = XObject.define(
24     function (cfg) {
25         options = []; // default.
26         XObject.extend(this,cfg);
27     },
28     Object,
29     {
30         /**
31          * @cfg {String} help_description what appears at the start of the help message.
32          */
33         help_description: '',
34         /**
35          * @cfg {Boolean} If extra arguments are allowed.
36          */
37         allow_extra : false,
38         /**
39          * @param {Object} Resulting key/value of data.
40          */
41         result : false,
42         /**
43          * @prop {Array} the arguments
44          */
45         args: false,
46         /**
47          * @prop {Array} extra the arguments that are not accounted for.
48          */
49         extra: false,
50         /**
51          * parse the argv
52          * usage: options.parse(Seed.argv)
53          */
54         parse: function (argv)
55         {
56             var _this = this;
57             this.options.forEach(function(a) {
58                 if (a.flag_boolean) {
59                     _this.result[a.name] = false;
60                     return;
61                 }
62                 if (a.flag_array) {
63                     _this.result[a.name] = [];
64                     return;
65                 }
66             })
67             this.result = {};
68             this.extra = {};
69             var args = Array.prototype.slice.call(Seed.argv);
70             args.shift(); //seed
71             args.shift(); //script..
72         
73             for(var i =0; i < args.length;i++) {
74                 
75                 var a= this.findArg(args[i]);
76                 
77                 if (!a) {
78                     if (!this.allow_extra) {
79                         throw {
80                             name: "ArgumentError", 
81                             message: "Unknown argument: " + args[i] 
82                         };
83                     }
84                     this.extra.push(args[i]);
85                 }
86                 
87                 if (a.long == 'help' ) {
88                     this.showHelp();
89                     return;
90                 }
91                 
92                 if (a.flag_boolean) {
93                     this.result[a.long] = true;
94                     continue;
95                 }
96                 var next = args[i+1];
97                 if (this.findArg(next)) {
98                     throw {
99                         name: "ArgumentError", 
100                         message: "Invalid argument sequence: " + args[i] + ' ' + next;
101                     };
102                 }
103                 // type juggling -- fixme...
104                 
105                 if (a.flag_array) {
106                     this.result[a.long].push(next);
107                     i++;
108                     continue;
109                 }
110             
111                 if (typeof(this.result[a.long]) != 'undefined') {
112                     throw {
113                         name: "ArgumentError", 
114                         message: "Invalid argument duplicate: " + args[i] + ' ' + next;
115                     };
116                 }
117                 
118                 this.result[a.long] = next;
119                 i++;
120             }
121             return this.result;
122         }
123         
124         
125     },
126     
127     findArg : function(str)
128     {
129         var ret = false;
130         var type = str.substring(0,1) == '-' ? 'short' : '';
131         type = str.substring(0,2) == '--' ? 'long' : type;
132         if (type == '') {
133             return false; // not an arg..
134         }
135         var match = str.substring(type =='long' ? 2 , 1);
136         this.options.forEach(function(o)) {
137             if (ret) {
138                 return; // no more parsing.
139             }
140             if (o[type] == 'match') {
141                 ret = o;
142             }
143             
144         }
145         return ret;
146         
147     },
148     
149     
150     showHelp: function()
151     {
152         print(this.help_description);
153         this.options.forEach(function(o) {
154             // fixme needs tidying up..
155             print('  --' + o.long + '   (-' + o.short + ')  ' + o.description);
156         }
157         Seed.quit();
158             
159     }
160 }