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