Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * OpenSPARC T2 Processor File: command_opts.h | |
5 | * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
6 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. | |
7 | * | |
8 | * The above named program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public | |
10 | * License version 2 as published by the Free Software Foundation. | |
11 | * | |
12 | * The above named program is distributed in the hope that it will be | |
13 | * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public | |
18 | * License along with this work; if not, write to the Free Software | |
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. | |
20 | * | |
21 | * ========== Copyright Header End ============================================ | |
22 | */ | |
23 | #ifndef COMMAND_OPTS_H__ | |
24 | #define COMMAND_OPTS_H__ | |
25 | ||
26 | /************************************************************************ | |
27 | ** | |
28 | ** Copyright (C) 2007, Sun Microsystems, Inc. | |
29 | ** | |
30 | ** Sun considers its source code as an unpublished, proprietary | |
31 | ** trade secret and it is available only under strict license provisions. | |
32 | ** This copyright notice is placed here only to protect Sun in the event | |
33 | ** the source is deemed a published work. Disassembly, decompilation, | |
34 | ** or other means of reducing the object code to human readable form | |
35 | ** is prohibited by the license agreement under which this code is | |
36 | ** provided to the user or company in possession of this copy. | |
37 | ** | |
38 | *************************************************************************/ | |
39 | ||
40 | #include <sys/types.h> | |
41 | #include <stdlib.h> | |
42 | #include <list> | |
43 | #include <map> | |
44 | #include <vector> | |
45 | #include <set> | |
46 | #include <string> | |
47 | ||
48 | #include "vcpu.h" | |
49 | ||
50 | // The CommandOptions, Option, ArgumentOption, and ExclusiveOptions | |
51 | // classes enable configuration based command line option flag | |
52 | // parsing. Options with and without values are supported, as well as | |
53 | // groups of exclusive options (similar to GUI's radio buttons). | |
54 | // | |
55 | // An option's initial on-off state may be set, defaulting to off | |
56 | // (false). By default, an option may appear many times on the | |
57 | // command line, the last instance taking effect. This behavior can | |
58 | // be reversed so that an option may appear only once. | |
59 | // | |
60 | // Options with argument values are strictly typed and are initialized | |
61 | // with a default value. | |
62 | // | |
63 | // Mutually exclusive options are described in the ExclusiveOptions | |
64 | // class. The exclusive options are added to the ExclusiveOptions | |
65 | // object. If one of the exclusive options appears on the command | |
66 | // line, one of two behaviors occurs. In this case, by default every | |
67 | // other exclusive option is turned off. Alternatively, if two | |
68 | // exclusive options appear, the option parser stops with a fatal | |
69 | // error. | |
70 | // | |
71 | // Options (and any derived class such as ArgumentOption) objects are | |
72 | // added to a CommandOptions object. The CommandOptions object holds | |
73 | // all the legal options, described by these option objects, and | |
74 | // supplies a parse() method that takes an argv[] array and scans it | |
75 | // for matching options. parse() updates the state in the option | |
76 | // objects, so that their off-on and arguments values can be queried, | |
77 | // and sets a stl vector of strings to any remaining positional | |
78 | // arguments. | |
79 | // | |
80 | // If parse() succeeds, it returns true. If it fails, it returns | |
81 | // false and a subsequent call to get_error_msg() will return a | |
82 | // message describing the error. | |
83 | ||
84 | ||
85 | class Option | |
86 | { | |
87 | public: | |
88 | ||
89 | friend class ExclusiveOptions; | |
90 | ||
91 | enum Result { | |
92 | NOT_FOUND, | |
93 | ON_OFF_FOUND, | |
94 | VALUE_FOUND, | |
95 | PARSE_ERROR | |
96 | }; | |
97 | ||
98 | enum Repeatable { | |
99 | REPEATABLE, | |
100 | NOT_REPEATABLE | |
101 | }; | |
102 | ||
103 | enum OnOff { | |
104 | OFF, | |
105 | ON | |
106 | }; | |
107 | ||
108 | // Creates a repeatable, initially off option by default | |
109 | Option(std::string name_, | |
110 | Repeatable repeatable_ = REPEATABLE, | |
111 | OnOff on_off_default = OFF) : | |
112 | name(name_), | |
113 | on_off(on_off_default), | |
114 | repeatable(repeatable_), | |
115 | seen(false) | |
116 | {} | |
117 | ||
118 | virtual ~Option() {} | |
119 | ||
120 | std::string get_name() const { return name; } | |
121 | ||
122 | bool is_on() const { return on_off == ON; } | |
123 | bool is_off() const { return on_off == OFF; } | |
124 | ||
125 | void turn_off() { on_off = OFF; } | |
126 | ||
127 | Result parse(const std::string& cmd_line_arg, const char* val_str); | |
128 | ||
129 | virtual std::string get_error_msg() const | |
130 | { | |
131 | return error_msg; | |
132 | } | |
133 | ||
134 | virtual void print(FILE* fp = stdout) const | |
135 | { | |
136 | fprintf(fp, "-%s is %s", get_name().c_str(), is_on() ? "ON" : "OFF"); | |
137 | std::string val_str = print_value(); | |
138 | if (val_str != "") | |
139 | fprintf(fp, " -- value is is %s", val_str.c_str()); | |
140 | fprintf(fp, "\n"); | |
141 | } | |
142 | ||
143 | protected: | |
144 | bool seen; | |
145 | std::string error_msg; | |
146 | virtual bool takes_argument() const { return false; } | |
147 | ||
148 | virtual Result parse_value(const std::string& val_str) | |
149 | { | |
150 | fprintf(stderr, "Internal error: called Option::parse_value()\n"); | |
151 | exit(-1); | |
152 | return Option::PARSE_ERROR; | |
153 | } | |
154 | ||
155 | virtual std::string print_value() const | |
156 | { | |
157 | return ""; | |
158 | } | |
159 | ||
160 | private: | |
161 | Option() : | |
162 | name(""), | |
163 | on_off(OFF), | |
164 | repeatable(REPEATABLE) | |
165 | {} | |
166 | ||
167 | const std::string name; | |
168 | OnOff on_off; | |
169 | const Repeatable repeatable; | |
170 | std::list<ExclusiveOptions*> excl_opts; | |
171 | }; | |
172 | ||
173 | ||
174 | template <typename T> | |
175 | class ArgumentOption : public Option | |
176 | { | |
177 | public: | |
178 | ArgumentOption(std::string name_, | |
179 | const T& default_value, | |
180 | Repeatable repeatable_ = REPEATABLE, | |
181 | OnOff on_off_default = OFF) : | |
182 | Option(name_, repeatable_, on_off_default), | |
183 | value(default_value) | |
184 | {} | |
185 | ||
186 | virtual ~ArgumentOption() {} | |
187 | ||
188 | T get_value() const { return value; } | |
189 | ||
190 | virtual Result parse_value(const std::string& val_str) = 0; | |
191 | ||
192 | protected: | |
193 | T value; | |
194 | ||
195 | virtual bool takes_argument() const { return true; } | |
196 | ||
197 | virtual std::string print_value() const = 0; | |
198 | ||
199 | ArgumentOption() {} | |
200 | }; | |
201 | ||
202 | ||
203 | class ExclusiveOptions | |
204 | { | |
205 | public: | |
206 | enum Compatible { | |
207 | COMPATIBLE, | |
208 | INCOMPATIBLE | |
209 | }; | |
210 | ||
211 | ExclusiveOptions(Compatible compatible_ = COMPATIBLE) : | |
212 | compatible(compatible_) | |
213 | {} | |
214 | ||
215 | virtual ~ExclusiveOptions() {} | |
216 | ||
217 | ExclusiveOptions& add(Option& opt) | |
218 | { | |
219 | options[opt.get_name()] = &opt; | |
220 | opt.excl_opts.push_back(this); | |
221 | return *this; | |
222 | } | |
223 | ||
224 | bool update(Option& opt); | |
225 | ||
226 | std::string get_error_msg() const | |
227 | { | |
228 | return error_msg; | |
229 | } | |
230 | ||
231 | private: | |
232 | const Compatible compatible; | |
233 | std::map<std::string,Option*> options; | |
234 | ||
235 | std::string error_msg; | |
236 | }; | |
237 | ||
238 | class UnsignedOption : public ArgumentOption<uint64_t> | |
239 | { | |
240 | public: | |
241 | UnsignedOption(std::string name_, | |
242 | uint64_t default_value = 0, | |
243 | Repeatable repeatable_ = REPEATABLE, | |
244 | uint64_t base_ = 0) : | |
245 | ArgumentOption(name_, default_value, repeatable_, OFF), | |
246 | base(base_) | |
247 | {} | |
248 | ||
249 | ~UnsignedOption() {} | |
250 | ||
251 | static bool parse_number(const std::string& num_str, | |
252 | uint64_t& value, | |
253 | std::string& error_msg, | |
254 | int base = 0) | |
255 | { | |
256 | if (num_str[0] == '-') | |
257 | { | |
258 | error_msg = "Leading '-' not allowed with "; | |
259 | return false; | |
260 | } | |
261 | ||
262 | char *endptr; | |
263 | uint64_t parse_value = strtoull(num_str.c_str(), &endptr, base); | |
264 | if (*endptr != '\0') | |
265 | { | |
266 | error_msg = "Illegal numeric argument passed to "; | |
267 | return false; | |
268 | } | |
269 | value = parse_value; | |
270 | return true; | |
271 | } | |
272 | ||
273 | Result parse_value(const std::string& val_str) | |
274 | { | |
275 | if (parse_number(val_str, value, error_msg, base)) | |
276 | return VALUE_FOUND; | |
277 | else | |
278 | { | |
279 | error_msg += "-" + get_name() + "option"; | |
280 | return PARSE_ERROR; | |
281 | } | |
282 | } | |
283 | ||
284 | private: | |
285 | UnsignedOption() : base(0) {} | |
286 | ||
287 | const uint64_t base; | |
288 | ||
289 | std::string print_value() const | |
290 | { | |
291 | char buf[100]; | |
292 | sprintf(buf, "0x%llx", value); | |
293 | return buf; | |
294 | } | |
295 | }; | |
296 | ||
297 | ||
298 | class SignedOption : public ArgumentOption<int64_t> | |
299 | { | |
300 | public: | |
301 | SignedOption(std::string name_, | |
302 | uint64_t default_value = 0, | |
303 | Repeatable repeatable_ = REPEATABLE, | |
304 | uint64_t base_ = 0) : | |
305 | ArgumentOption(name_, default_value, repeatable_, OFF), | |
306 | base(base_) | |
307 | {} | |
308 | ||
309 | ~SignedOption() {} | |
310 | ||
311 | static bool parse_number(const std::string& num_str, | |
312 | int64_t& value, | |
313 | std::string& error_msg, | |
314 | int base = 0) | |
315 | { | |
316 | char *endptr; | |
317 | int64_t parse_value = strtoll(num_str.c_str(), &endptr, base); | |
318 | if (*endptr != '\0') | |
319 | { | |
320 | error_msg = "Illegal numeric argument passed to "; | |
321 | return false; | |
322 | } | |
323 | value = parse_value; | |
324 | return true; | |
325 | } | |
326 | ||
327 | Result parse_value(const std::string& val_str) | |
328 | { | |
329 | if (parse_number(val_str, value, error_msg, base)) | |
330 | return VALUE_FOUND; | |
331 | else | |
332 | { | |
333 | error_msg += "-" + get_name() + "option"; | |
334 | return PARSE_ERROR; | |
335 | } | |
336 | } | |
337 | ||
338 | private: | |
339 | SignedOption() : base(0) {} | |
340 | ||
341 | const uint64_t base; | |
342 | ||
343 | std::string print_value() const | |
344 | { | |
345 | char buf[100]; | |
346 | sprintf(buf, "%lld", value); | |
347 | return buf; | |
348 | } | |
349 | }; | |
350 | ||
351 | ||
352 | class StringOption : public ArgumentOption<std::string> | |
353 | { | |
354 | public: | |
355 | StringOption(std::string name_, | |
356 | std::string default_value = "", | |
357 | Repeatable repeatable_ = REPEATABLE) : | |
358 | ArgumentOption(name_, default_value, repeatable_, OFF) | |
359 | {} | |
360 | ||
361 | ~StringOption() {} | |
362 | ||
363 | Result parse_value(const std::string& val_str) | |
364 | { | |
365 | value = val_str; | |
366 | return VALUE_FOUND; | |
367 | } | |
368 | ||
369 | private: | |
370 | StringOption() {} | |
371 | ||
372 | std::string print_value() const | |
373 | { | |
374 | return value; | |
375 | } | |
376 | }; | |
377 | ||
378 | class CpuSet | |
379 | { | |
380 | public: | |
381 | ||
382 | typedef std::set<uint32_t>::iterator iterator; | |
383 | typedef std::set<uint32_t>::const_iterator const_iterator; | |
384 | ||
385 | static int get_nr_cpus() { return max_cpu_ndx + 1; } | |
386 | ||
387 | CpuSet(int singleton_ndx = -1) | |
388 | { | |
389 | if (singleton_ndx != -1) | |
390 | insert(singleton_ndx); | |
391 | } | |
392 | ||
393 | virtual ~CpuSet() {} | |
394 | ||
395 | const_iterator begin() const { return cpu_set.begin(); } | |
396 | iterator begin() { return cpu_set.begin(); } | |
397 | const_iterator end() const { return cpu_set.end(); } | |
398 | iterator end() { return cpu_set.end(); } | |
399 | ||
400 | CpuSet& insert_all() | |
401 | { | |
402 | for (int ndx = 0; ndx < get_nr_cpus(); ++ndx) | |
403 | insert(ndx); | |
404 | return *this; | |
405 | } | |
406 | ||
407 | CpuSet& clear_all() | |
408 | { | |
409 | cpu_set.clear(); | |
410 | return *this; | |
411 | } | |
412 | ||
413 | CpuSet& insert(uint32_t ndx, bool* out_of_range = NULL) | |
414 | { | |
415 | if (ndx < get_nr_cpus()) | |
416 | { | |
417 | cpu_set.insert(ndx); | |
418 | if (out_of_range != NULL) | |
419 | *out_of_range = false; | |
420 | } | |
421 | else if (out_of_range != NULL) | |
422 | *out_of_range = true; | |
423 | ||
424 | return *this; | |
425 | } | |
426 | ||
427 | CpuSet& insert_mask(uint64_t mask, bool* out_of_range = NULL) | |
428 | { | |
429 | bool local_out_of_range = false; | |
430 | ||
431 | for (int ndx = 0; ndx < 64 && !local_out_of_range; ++ndx) | |
432 | if (mask & (1ULL << ndx)) | |
433 | insert(ndx, &local_out_of_range); | |
434 | ||
435 | if (out_of_range != NULL) | |
436 | *out_of_range = local_out_of_range; | |
437 | ||
438 | return *this; | |
439 | } | |
440 | ||
441 | iterator find(uint32_t ndx, bool* out_of_range = NULL) | |
442 | { | |
443 | if (out_of_range != NULL) | |
444 | *out_of_range = (ndx < get_nr_cpus()); | |
445 | ||
446 | return cpu_set.find(ndx); | |
447 | } | |
448 | ||
449 | bool find_one(uint32_t ndx, bool* out_of_range = NULL) | |
450 | { | |
451 | if (out_of_range != NULL) | |
452 | *out_of_range = (ndx < get_nr_cpus()); | |
453 | ||
454 | return find(ndx, out_of_range) != cpu_set.end(); | |
455 | } | |
456 | ||
457 | bool operator!=(const CpuSet& rhs) | |
458 | { | |
459 | return cpu_set != rhs.cpu_set; | |
460 | } | |
461 | ||
462 | std::string print() const | |
463 | { | |
464 | std::string rtn; | |
465 | ||
466 | for (const_iterator iter = cpu_set.begin(); | |
467 | iter != cpu_set.end(); | |
468 | ++iter) | |
469 | { | |
470 | char buf[100]; | |
471 | sprintf(buf, ",%d", *iter); | |
472 | rtn += buf; | |
473 | } | |
474 | return rtn.empty() ? "" : rtn.substr(1); | |
475 | } | |
476 | ||
477 | protected: | |
478 | ||
479 | static int& max_cpu_ndx; | |
480 | ||
481 | std::set<uint32_t> cpu_set; | |
482 | }; | |
483 | ||
484 | class CpuOption : public ArgumentOption<CpuSet> | |
485 | { | |
486 | public: | |
487 | enum Singleton { | |
488 | SINGLETON, | |
489 | MULTITUDE | |
490 | }; | |
491 | ||
492 | CpuOption(int cpu_ndx, | |
493 | Singleton singleton_ = SINGLETON) | |
494 | : | |
495 | ArgumentOption("cpu", CpuSet(cpu_ndx)), | |
496 | singleton(singleton_) | |
497 | {} | |
498 | ||
499 | CpuOption(const CpuSet& default_cpuset, | |
500 | Singleton singleton_ = SINGLETON) | |
501 | : | |
502 | ArgumentOption("cpu", default_cpuset), | |
503 | singleton(singleton_) | |
504 | {} | |
505 | ||
506 | ~CpuOption() {} | |
507 | ||
508 | Result parse_value(const std::string& val_str) | |
509 | { | |
510 | if (val_str == "all") | |
511 | { | |
512 | if (singleton == SINGLETON) | |
513 | { | |
514 | error_msg = "Only one cpu can be passed to the -" + get_name() + | |
515 | " option"; | |
516 | return PARSE_ERROR; | |
517 | } | |
518 | ||
519 | value.insert_all(); | |
520 | } | |
521 | else /* if "all" */ | |
522 | { | |
523 | value.clear_all(); | |
524 | ||
525 | std::string t; | |
526 | int start=0; | |
527 | int end; | |
528 | while (1) | |
529 | { | |
530 | end=val_str.find(",", start); | |
531 | ||
532 | std::string tok = val_str.substr(start, (end-start)); | |
533 | ||
534 | std::string left; | |
535 | std::string right; | |
536 | std::string stride="1"; | |
537 | ||
538 | int pos = tok.find(".."); | |
539 | left = tok.substr(0, pos); | |
540 | if (pos != std::string::npos) | |
541 | { | |
542 | std::string rhs = tok.substr(pos+2); | |
543 | // further tokenize rhs by ":" | |
544 | int cpos = rhs.find(":"); | |
545 | right = rhs.substr(0, cpos); | |
546 | if (cpos != std::string::npos) | |
547 | stride = rhs.substr(cpos+1); | |
548 | } | |
549 | else | |
550 | { | |
551 | right = left; | |
552 | } | |
553 | ||
554 | Result rv = insert_values(left, right, stride); | |
555 | if (rv == PARSE_ERROR) return rv; | |
556 | ||
557 | ||
558 | if (end == std::string::npos) break; | |
559 | start = end+1; | |
560 | } // while more tokens | |
561 | ||
562 | } /* some or "all" cpus specified? */ | |
563 | ||
564 | return VALUE_FOUND; | |
565 | } | |
566 | ||
567 | private: | |
568 | CpuOption() {} | |
569 | ||
570 | Singleton singleton; | |
571 | ||
572 | std::string print_value() const | |
573 | { | |
574 | return value.print(); | |
575 | } | |
576 | ||
577 | Result insert_values(std::string leftstr, std::string rightstr, std::string stridestr) { | |
578 | uint64_t left, right, stride; | |
579 | UnsignedOption uso(get_name()); | |
580 | ||
581 | Result rv;; | |
582 | ||
583 | rv = uso.parse_value(leftstr); | |
584 | if (rv != VALUE_FOUND) return rv; | |
585 | left = uso.get_value(); | |
586 | ||
587 | rv = uso.parse_value(rightstr); | |
588 | if (rv != VALUE_FOUND) return rv; | |
589 | right = uso.get_value(); | |
590 | ||
591 | rv = uso.parse_value(stridestr); | |
592 | if (rv != VALUE_FOUND) return rv; | |
593 | stride = uso.get_value(); | |
594 | ||
595 | if (stride == 0) { | |
596 | error_msg = "stride must be a positive number"; | |
597 | return PARSE_ERROR; | |
598 | } | |
599 | // fprintf(stderr, "insert_values: left=%lld right=%lld stride=%lld\n", left, right, stride); | |
600 | ||
601 | char buf[512]; | |
602 | if (left > right) { | |
603 | sprintf(buf, "upper limit of range (%d) cannot be less than lower limit (%d)", | |
604 | left, right); | |
605 | error_msg = buf; | |
606 | return PARSE_ERROR; | |
607 | } | |
608 | uint64_t v; | |
609 | for (v=left; v<=right; v += stride) { | |
610 | bool out_of_bounds = false; | |
611 | // fprintf(stderr, "parse_value: trying to insert value %d\n", v); | |
612 | value.insert(v, &out_of_bounds); | |
613 | if (out_of_bounds) { | |
614 | error_msg = "Cpu number passed to -" + get_name() + " too big"; | |
615 | return PARSE_ERROR; | |
616 | } | |
617 | } | |
618 | ||
619 | return VALUE_FOUND; | |
620 | } // insert_values | |
621 | }; | |
622 | ||
623 | ||
624 | class OptionList | |
625 | { | |
626 | public: | |
627 | typedef std::list<Option*>::iterator iterator; | |
628 | iterator begin() { return opt_list.begin(); } | |
629 | iterator end() { return opt_list.end(); } | |
630 | ||
631 | OptionList& push_front(Option* option) | |
632 | { | |
633 | opt_list.push_front(option); | |
634 | return *this; | |
635 | } | |
636 | ||
637 | private: | |
638 | std::list<Option*> opt_list; | |
639 | }; | |
640 | ||
641 | class AddressingOptions : public OptionList | |
642 | { | |
643 | public: | |
644 | enum AddrType { | |
645 | PA, | |
646 | RA, | |
647 | VA | |
648 | }; | |
649 | ||
650 | AddressingOptions(AddrType default_addr_type_) | |
651 | : | |
652 | pa_opt("pa", Option::REPEATABLE), | |
653 | ra_opt("ra", Option::REPEATABLE), | |
654 | va_opt("va", Option::REPEATABLE), | |
655 | context_id("context_id", 0), | |
656 | partition_id("partition_id", 0), | |
657 | pa_ra_va_exclusive(ExclusiveOptions::INCOMPATIBLE), | |
658 | default_addr_type(default_addr_type_) | |
659 | { | |
660 | pa_ra_va_exclusive.add(pa_opt).add(ra_opt).add(va_opt); | |
661 | ||
662 | push_front(&pa_opt); | |
663 | push_front(&ra_opt); | |
664 | push_front(&va_opt); | |
665 | push_front(&context_id); | |
666 | push_front(&partition_id); | |
667 | } | |
668 | ||
669 | Option pa_opt; | |
670 | Option ra_opt; | |
671 | Option va_opt; | |
672 | UnsignedOption context_id; | |
673 | UnsignedOption partition_id; | |
674 | ||
675 | ||
676 | Vcpu::TranslateMode translate_mode() | |
677 | { | |
678 | if (pa_opt.is_on()) | |
679 | { | |
680 | return Vcpu::TRANSLATE_PA_TO_PA; | |
681 | } | |
682 | else if (ra_opt.is_on()) | |
683 | { | |
684 | if (partition_id.is_on()) | |
685 | return Vcpu::TRANSLATE_RA_TO_PA_PID; | |
686 | else | |
687 | return Vcpu::TRANSLATE_RA_TO_PA; | |
688 | } | |
689 | else if (va_opt.is_on()) | |
690 | { | |
691 | if (context_id.is_off()) | |
692 | // ignore partition_id in this case | |
693 | return Vcpu::TRANSLATE_VA_TO_PA; | |
694 | else if (partition_id.is_off()) | |
695 | return Vcpu::TRANSLATE_VA_TO_PA_CTX; | |
696 | else | |
697 | return Vcpu::TRANSLATE_VA_TO_PA_CTX_PID; | |
698 | } | |
699 | else | |
700 | { | |
701 | switch (default_addr_type) | |
702 | { | |
703 | case PA: return Vcpu::TRANSLATE_PA_TO_PA; | |
704 | case RA: return Vcpu::TRANSLATE_RA_TO_PA; | |
705 | case VA: return Vcpu::TRANSLATE_VA_TO_PA; | |
706 | } | |
707 | return Vcpu::TRANSLATE_VA_TO_PA; | |
708 | } | |
709 | } | |
710 | ||
711 | private: | |
712 | ExclusiveOptions pa_ra_va_exclusive; | |
713 | AddrType default_addr_type; | |
714 | }; | |
715 | ||
716 | class CommandOptions | |
717 | { | |
718 | public: | |
719 | CommandOptions() {} | |
720 | virtual ~CommandOptions() {} | |
721 | ||
722 | bool parse(const char* cmd_line, | |
723 | std::vector<std::string>& positional_args); | |
724 | ||
725 | bool parse(int argc, | |
726 | const char** argv, | |
727 | std::vector<std::string>& positional_args); | |
728 | ||
729 | std::string get_error_msg() const | |
730 | { | |
731 | return error_msg; | |
732 | } | |
733 | ||
734 | CommandOptions& add(Option& opt) | |
735 | { | |
736 | options[opt.get_name()] = &opt; | |
737 | return *this; | |
738 | } | |
739 | ||
740 | CommandOptions& add(OptionList& opt_list) | |
741 | { | |
742 | for (OptionList::iterator iter = opt_list.begin(); | |
743 | iter != opt_list.end(); | |
744 | ++iter) | |
745 | add(**iter); | |
746 | ||
747 | return *this; | |
748 | } | |
749 | ||
750 | void print(FILE* fp = stdout) const | |
751 | { | |
752 | for (std::map<std::string,Option*>::const_iterator iter = options.begin(); | |
753 | iter != options.end(); | |
754 | ++iter) | |
755 | iter->second->print(); | |
756 | } | |
757 | ||
758 | private: | |
759 | std::map<std::string,Option*> options; | |
760 | ||
761 | std::string error_msg; | |
762 | }; | |
763 | ||
764 | #endif /* COMMAND_OPTS_H__ */ |