Consider a utility which can be used in different modes, like:
utility.exe --mode x (one list of arguments expected)
utility.exe --mode y (different list of arguments expected)
How can i write code for parsing such arguments in Boost.Program_Options???
You could parse this mode out yourself (or with boost program options use a way that ignores unknown options), and then depending on that outcome, you could feed the cmd line arguments to different boost program option objects.
Related
I have a simple c code. I am running the binary of that with my pin tool:
pin -t tool.so -- test/test.o a
Here, test/test.o is a binary, and a is some random command line argument to the pin tool (say tool.so), and not the binary (so, there is a distinction between passing command line argument to the pin tool and to the binary).
I would like to know how can I pass command line input (say arg1) to the binary which I am running with the pin tool.
(like we would pass with - ./test/test.o arg1)
Note: I think knowing my pin tool and the c code is irrelevant here.
What you describe here will pass command line arguments to the program you're running. Command line arguments to the tool are all the arguments that come after the -t argument and before the -- (double dash) which indicates the binary and its arguments
I have a small Go app with a cli using flags and I've been asked to make it more testable.
My app gets called on the command line like
deploy.exe <task> <command> -tenant tenant_name -validate -package "c:\some dir\\"
Based on which task and command a different execution path is called and ultimately a func residing in another package is called like:
if command == "db" {
dbhelper.RunDBCmds(*tenant, *validate, *package)
}
I need to write unit tests for just the flag parsing, without calling the actual functions at the end.
I'm fairly new to Go and I'm struggling figuring out how to accomplish this. I've thought about adding my Os.Args() and Flag parsing to a function that takes input and outputs a pointer of sorts to the RunDBCmds(*tenant, ...) func. However, I'm just not sure I can accomplish returning a pointer to a function.
I'd appreciate any advice on how I can make my code more testable without actually invoking the functions.
If all of your tasks/commands have different sets of flags I would end up with introducing some kind of Command abstraction. The best example can be found in the Go source code itself:
base.Commands = []*base.Command{
work.CmdBuild,
clean.CmdClean,
doc.CmdDoc,
envcmd.CmdEnv,
bug.CmdBug,
fix.CmdFix,
//...
}
Each command can have its own flag.FlagSet to parse command-specific flags:
// A Command is an implementation of a go command
// like go build or go fix.
type Command struct {
// Run runs the command.
// The args are the arguments after the command name.
Run func(cmd *Command, args []string)
// UsageLine is the one-line usage message.
// The first word in the line is taken to be the command name.
UsageLine string
// Short is the short description shown in the 'go help' output.
Short string
// Long is the long message shown in the 'go help <this-command>' output.
Long string
// Flag is a set of flags specific to this command.
Flag flag.FlagSet
// CustomFlags indicates that the command will do its own
// flag parsing.
CustomFlags bool
}
Using this approach you can separate commands' flags parsing from the execution.
Is there any way to get clang output to insert carriage returns? When compiling with the verbose option, I just get these huge unreadable dumps of compiler flags and paths.
Use popen to start your clang session. Create a new command line as clang -v (including the space) and concatenate the arguments that you usually feed to clang itself. After the final argument, add 2>&1 to convert Clang's stderr output to regular stdout so popen can pick it up. Then loop over popen's input and parse each separate line, adding extra information where you see fit.
As an example, I grabbed the entire set of flags for my local Clang using
clang -cc1 --help
and incorporated this as a single long string in my C program. Then I looped over the return results from popen, scanning for flags starting with -, and when one was found, I scanned the long flags string for this. If it found something, I write it out on a separate line in green (using ANSI escape sequences). Then I test the flags string if an argument should follow – these usually have a leading <...> indicator. If so, I write it out in blue. Finally, I write out the entire flag explanation line until I encounter an end-of-line.
With my very rough program called colorclang – 123 lines of actual code – I get output like this:
As it is, it tests every input line for possible flags so there is some mis-coloring. More exact parsing is possible; I'd have to add separate routines for the single line starting with "/usr/bin/clang" (for the common Clang flags), the single line starting with "/usr/bin/ld" (and parse the loader flags), and possibly the lines after each #include .. statement.
Pieced together with the help of Complete list of clang flags?, Steve Kemp's answer to C: Run a System Command and Get Output?, and after deducing clang -v writes to stderr, larsman's answer to c popen won't catch stderr.
I need to run source command from c++ program and pass filename and also some arguments. Is it possible? I want to use them in script like command line arguments (with argc, argv0, ...). http://www.astro.princeton.edu/~rhl/Tcl-Tk_docs/tcl/source.n.html here is not specified how to do it.
When doing this from C or C++, you should:
Initialise the Tcl library and create a Tcl interpreter.
Set the global variables argv0, argv and argc to the values expected by a normal Tcl script. This is exactly what tclsh does; the variables are entirely ordinary apart from being initialised this way.
argv0 is the name of the “main” script, which might be the script you're about to source.
argv is a Tcl list of all the other arguments; argc is the length of that list.
Use Tcl_FSEvalFileEx(interp,pathPtr,encoding) to execute the file; the source command is a very thin wrapper around that call. You probably want to pass the encoding argument as NULL, and the pathPtr argument is a Tcl_Obj reference.
If your script accepts the arguments in argv, just set this variable before you source this script.
But if this script calls exit, it will terminate the entire process, usually not what you want. You could use a slave interp to avoid this.
There are 3 predefined variables:
$argc - number items of arguments passed to a script.
$argv - list of the arguments.
$argv0 - name of the script.
So in your case, assuming the file sourced is in the same directory and its name is passed as a first argument:
source [lindex $argv 0]
I'm writing a program in C++ that is a wrapper for some benchmarks that contains some setup code at the beginning and analisys code in the end.
I want to run up to two benchmarks in parallel. The original commandlines for these are:
/path0/benchmark0 -switch0 -switch1 -switch2
/path1/benchmark1 -arg0 -arg1 -arg2 -arg4
And I want to put these on my wrapper's commandline:
wrapper -setup_arg0 -setup_arg1 -analysis_arg0 --command0 /path0/benchmark0 -switch0 -switch1 -switch2 --command1 /path1/benchmark1 -arg0 -arg1 -arg2 -arg4
Where I want to get two std::vector<std::string>s, one for each of command0 and command1, containing the original commandlines. This is how I'm doing it (using boost::program_options):
("command0", po::value<std::vector< std::string> >(&command0)->multitoken(), "command line for thread 0")
("command1", po::value<std::vector< std::string> >(&command1)->multitoken(), "command line for thread 1")
and this basically works. However, if the benchmark's arguments begin with - (as most switches on most programs I've seen do), the program_options tries to parse them as part of the wrapper's switches, because it doesn't know that they should be grouped together under command0 or command1.
Does program_options support that? If so, how?
Example:
Where I work there is a convention for doing this by "terminating" the multitoken like this:
wrapper <snip> --command0 /path0/benchmark0 -switch0 -switch1 -switch2 -command0-
(in this example I terminated --command0 with -command0-.)
How can I make program_options handle it like this?
I think it's best if you take command0 and command1's values as a single string. e.g.,
wrapper --command0 "/path0/benchmark0 ..." --command1 "/path1/benchmark1 ..."
Yes, there's more work for you in that you have to wordexp your respective command strings (unless you're already just passing those strings straight to the shell ;-)), but it more cleanly separates out what's for the wrapper and what's for the invoked commands.