Pedro Delgado Perez
2013-May-14 14:50 UTC
[LLVMdev] CommandLine: using cl::Positional with enum
Hi Daniel, Thanks for your answer.> I am considering fixing the bug in the LLVM CommandLine library but is > going to be a long time before I can look at it. So don't wait for me > to do that. >Ok, ok, but, if you end up fixing this, please keep me post.> If you are really desperate to have the command line options in the > way you want they you may need to implement it yourself or use another > library (e.g.http://www.boost.org/doc/libs/1_53_0/doc/html/program_options.html [ http://www.boost.org/doc/libs/1_53_0/doc/html/program_options.html ] > ). > > Personally I think it's more important your tool does something rather > than spending time worrying about how it's command line interface > looks, so I would personally just implement everything as an optional > argument and then after parsing check yourself that your options have > been set as you want them. >Yes, I will try using that library, but if it's too complicated I will simply implement the arguments as optional. Thanks again, Pedro. El dia 12 may 2013 15:19, Daniel Liew <daniel.liew at imperial.ac.uk> escribió:> On 10 May 2013 09:44, Pedro Delgado Perez > <pedro.delgadoperez at mail.uca.es> wrote: > >> Hi Daniel, >> >> I would like to go deeper with CommandLine and I was asking if you could >> help me again. >> >> Look, following the same example you put in the last message: >> >> ./prog <option1> | ( <option2> --arg1 --arg2) | ( <option3> --arg1 ) >> >> What I really really want is the same except I don't want the "--" prefix is >> present in any of the arguments. >> >> ./prog <option1> | ( <option2> arg1 arg2) | ( <option3> arg1 ) >> >> The problem is clear: in this case, the arguments can't be optional. So I >> thought to delete all the "cl:opt" and process the arguments before calling: >> >> ClangTool Tool(OptionsParser.getCompilations(), >> OptionsParser.getSourcePathList()); >> > Oh you're using Clang stuff. I know nothing about this so I can't > really help you here. > > >> in order to give an error if the arguments provided were not correct. But, >> if arguments are correct, then the next error is shown: >> >> warning: /home/user/clang-llvm/build/arg1: 'linker' input unused >> >> >> error: unable to handle compilation, expected exactly one compiler job in '' >> Error while processing /home/user/clang-llvm/build/arg1 >> >> How can I manage this? I was thinking about not calling the ClangTool >> Tool(OptionsParser.getCompilations(), OptionsParser.getSourcePathList()); >> but, I don't know if this would be another problem. In addition, I would >> have to create my own option --help, isn't it? >> What do you recommend me to do? >> > I am considering fixing the bug in the LLVM CommandLine library but is > going to be a long time before I can look at it. So don't wait for me > to do that. > > If you are really desperate to have the command line options in the > way you want they you may need to implement it yourself or use another > library (e.g. http://www.boost.org/doc/libs/1_53_0/doc/html/program_options.html [ http://www.boost.org/doc/libs/1_53_0/doc/html/program_options.html ] > ). > > Personally I think it's more important your tool does something rather > than spending time worrying about how it's command line interface > looks, so I would personally just implement everything as an optional > argument and then after parsing check yourself that your options have > been set as you want them. > > Thanks, > Dan. > >> Thanks in advance, >> >> Pedro. >> >> El dia 08 may 2013 13:56, Daniel Liew <daniel.liew at imperial.ac.uk> escribió: >> >> Hi, >> >> Please try and format your e-mails better. Your e-mail is incredibly >> hard to read due to its lack of new lines. >> >> I don't think the designer of the CommandLine library ever intended for >> cl::Positional to be used with cl::opt<T> where T is an enum. >> >> e.g. >> >> enum OptLevel { >> g, O1, O2, O3 >> }; >> >> cl::opt<OptLevel> OptimizationLevel(cl::desc("Choose optimization level:"), >> cl::values( >> clEnumVal(g , "No optimizations, enable debugging"), >> clEnumVal(O1, "Enable trivial optimizations"), >> clEnumVal(O2, "Enable default optimizations"), >> clEnumVal(O3, "Enable expensive optimizations"), >> clEnumValEnd), >> cl::Positional >> ); >> >> int >> main (int argc, char ** argv) >> { >> cl::ParseCommandLineOptions(argc, argv); >> >> // Easy access in gdb (getValue is inlined!) >> OptLevel* test = &(OptimizationLevel.getValue() ); >> } >> >> It also doesn't make a huge amount of sense (based on the output of >> -help) either because the OptimizationLevel options have the "-" prefix >> which is almost always taken to mean that it is optional and NOT >> positional. -help shows... >> >> Choose optimization level: >> -g - No optimizations, enable debugging >> -O1 - Enable trivial optimizations >> -O2 - Enable default optimizations >> -O3 - Enable expensive optimizations >> >> Trying >> >> $ ./program -O1 >> $ ./program O1 >> $ ./program -- -O1 >> $ ./program -- O1 >> >> does not result in OptimizationLevel being modified by calling >> ParseCommandLineOptions (I tested this in gdb). >> >> This behaviour is arguably a bug. You're welcome to try and fix it. >> >> I would like to suggest an alternative though. If I understand you >> correctly you're looking for your command line syntax to be something >> like... >> >> ./prog <option1> | ( <option2> --arg1 --arg2) | ( <option3> --arg1 ) >> >> I don't see why you should really care about the order, i.e. this is >> probably okay. >> >> ./prog --arg1 <option1> >> >> So why not make every argument optional (i.e. no positional arguments) >> >> then after calling ParseCommandLineOptions you can check the user has >> used the right options by doing something like... >> >> // Note cl::opt<T> is a type of Option >> Option* NOTValidForOption1[] = { &arg1, &arg2}; >> Option* NOTValidForOption3[] = { &arg2 }; >> >> switch(YourOption) >> { >> case Option1: >> for(int I=0; I < sizeof(NOTValidForOption1)/sizeof(Option*);++I) >> { >> if(NotValidForOption1[I]->getNumOccurrences() != 0) >> { >> //Fail >> } >> } >> break; >> >> case Option2: >> break; >> >> case Option3: >> // similar to Option1 >> } >> >> ^ Note the above certainly code be coded better, this is just to give >> you an idea. >> >> You could also make it more obvious in the output of -help that only >> certain options should be used with each other by putting them into >> categories (see cl::cat() in documentation). Note this will only work >> for you if arguments are mutually exclusive as an option may only be in >> one category. >> >> Hope that helps. >> >> Dan. >> >> On 07/05/13 08:58, Pedro Delgado Perez wrote: >> >> Hi,I've been trying to code through CommandLine the options I want my tool >> accepts, but I find quite impossible to achieve robustly what I need .Look, >> I want the tool accepts a list of arguments in a particular order. For this >> goal, I know the cl::Positional flag. But, the problem is that *the first >> argument must be one of a set of options *(like a kind of subcommand of the >> tool). In my case, only the three next commands are possible: >> >> myTool option1myTool option2 arg1 arg2 myTool option3 arg1and I don't want a >> different order is possible, for instance, this is not permitted:myTool arg2 >> option2 arg1So, I thought about using an enum for this first argument:enum >> OptLevel{option1, option2, option3};cl::opt<OptLevel> >> OptionsLevel(cl::Positional, cl::desc("Choose one of these >> options:"),cl::values(clEnumVal(option1, "..."),clEnumVal(option2, >> "..."),clEnumVal(option3, "..."), clEnumValEnd),);After that, the rest of >> arguments are also particular of the option selected as the first argument, >> i.e, the rest of arguments are related with the first one. So I thought I >> could independently parse these arguments with:cl::list<std::string> Argv >> (cl::ConsumeAfter, cl::desc("<program arguments>..."));But, doing this when >> I run:myTool option1 file.cpp --I got the next error:"error - this >> positional option will never be matched, because it does not Require a value >> and a cl::ConsumeAfter option is active!"So, I modify "OptionsLeve >> >> lOptionsLevel" including the cl::Required flagThe error is now:"option: does >> not allow a value! option1 specified.option: must be specified at least >> once!option: must be specified at least once!option: must be specified at >> least once!"Then, I decided to use cl::PositionalEatsArgs instead of >> cl::ConsumeAfter. Then, this is the result:"option: does not allow a value! >> option1 specified."But, this time, the program continues. However, if I run >> "myTool option3 arg1 file.cpp --" it gives me a different problem:"warning: >> ../build/arg1: 'linker' input unusederror: unable to handle compilation, >> expected exactly one compiler job in ' '"But the program still goes on.Is >> there a way to accomplish what I have explained? I don't want those errors >> and warnings. Thanks,Pedro. >> >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu [ http://llvm.cs.uiuc.edu ] >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev [ http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev ] >>-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130514/90ea7eba/attachment.html>
Apparently Analagous Threads
- [LLVMdev] CommandLine: using cl::Positional with enum
- [LLVMdev] CommandLine: using cl::Positional with enum
- [LLVMdev] CommandLine: using cl::Positional with enum
- [LLVMdev] CommandLine: using cl::Positional with enum
- [LLVMdev] CommandLine: using cl::Positional with enum