summaryrefslogtreecommitdiff
path: root/src/cam/options.cpp
AgeCommit message (Collapse)Author
2021-07-27cam: options: Restore std::cerr adjustment fieldLaurent Pinchart
The std::cerr adjustment is set to std::left to print the usage text. Restore it to its original value when done, to avoid affecting the caller. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-07-22cam: options: Fail parsing when non-option arguments are foundLaurent Pinchart
The options parser currently ignores non-option arguments silently, which is confusing. It's a common error to run 'cam -c1 -C 10' and expect only 10 frames to be captured. As the -C option takes an optional argument, the number 10 is interpreted as a non-option argument instead of the argument to the -C option. Fail parsing with an appropriate message and print usage information when a non-option argument is found. The parser may be extended later to accept non-option arguments when the application has a use for them. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-07-22cam: options: Avoid copies of OptionvValue and KeyValueParser::OptionsLaurent Pinchart
The OptionValue toKeyValues() and toArray() functions return a copy of the values. This is unnecessary, and can cause use-after-free issues when taking references to the return values. Return references instead to optimize the implementation and avoid issues. The behaviour of the two functions is now undefined in case of an option type mismatch. The current implementation catches this with an assertion. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-07-22cam: options: Add empty() function to OptionValue classLaurent Pinchart
Add a convenience helper to check if an option value is empty, based on the value type. This is useful as a shortcut syntax to check if an option has been set. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-07-22cam: options: Drop some OptionValue cast operatorsLaurent Pinchart
While OptionValue cast operators to int and std::string allow useful shortcut syntaxes, the cast operators to KeyValueParser::Options and std::vector<OptionValue> are less useful. A an explicit static_cast call would be more cumbersome to write than an explicit .toKeyValues() or toArray(), and implicit cast hide too much of what's going on. Drop those two cast operators, and replace the only implicit cast occurrence with .toKeyValues(). While at it, drop the local opts variable in StreamKeyValueParser::roles() as it isn't used. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-07-22cam: options: Support parent-child relationship between optionsLaurent Pinchart
Add support for creating a tree-based hieararchy of options instead of a flat list. This is useful to support options that need to be interpreted in the context of a particular occurrence of an array option. The usage text automatically documents the options in their corresponding context: Options: -c, --camera camera ... Specify which camera to operate on, by id or by index -h, --help Display this help message -I, --info Display information about stream(s) -l, --list List all cameras --list-controls List cameras controls -p, --list-properties List cameras properties -m, --monitor Monitor for hotplug and unplug camera events Options valid in the context of --camera: -C, --capture[=count] Capture until interrupted by user or until <count> frames captured -F, --file[=filename] Write captured frames to disk If the file name ends with a '/', it sets the directory in which to write files, using the default file name. Otherwise it sets the full file path and name. The first '#' character in the file name is expanded to the camera index, stream name and frame sequence number. The default file name is 'frame-#.bin'. -s, --stream key=value[,key=value,...] ... Set configuration of a camera stream height=integer Height in pixels pixelformat=string Pixel format name role=string Role for the stream (viewfinder, video, still, raw) width=integer Width in pixels --strict-formats Do not allow requested stream format(s) to be adjusted --metadata Print the metadata for completed requests Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-07-22cam: options: Move key string left in usage() for key-value parserLaurent Pinchart
When printing usage information for a key-value parser, the documentation of the keys and values is printed in the second column of the usage text: -s, --stream key=value[,key=value,...] ... Set configuration of a camera stream height=integer Height in pixels pixelformat=string Pixel format name role=string Role for the stream (viewfinder, video, still, raw) width=integer Width in pixels -h, --help Display this help message This results in long lines. Improve this by moving the key description to the first column, and aligning the value description as other option description text: -s, --stream key=value[,key=value,...] ... Set configuration of a camera stream height=integer Height in pixels pixelformat=string Pixel format name role=string Role for the stream (viewfinder, video, still, raw) width=integer Width in pixels -h, --help Display this help message Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-07-22cam: options: Slit OptionsParser::usage() in two functionsLaurent Pinchart
To prepare for code reuse, split the printing of options out of OptionsParser::usage() to a separate function. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-07-22cam: options: Add optionName() function to Option structureLaurent Pinchart
Add an Option::optionName() function that returns a string describing the option name, with leading dashes. As a result, OptionsParser::parseValueError() function becomes a single-line function and can be inlined in its caller. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-07-22cam: options: Document the options parser APILaurent Pinchart
Before extending the option parser, document its existing API. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-07-22cam: options: Move Option struct to options.cppLaurent Pinchart
The Option structure is an internal implementation detail and shouldn't be exposed in the API. Move it to options.cpp. This requires moving the inline constructors and destructors for the KeyValueParser and OptionsParser classes to options.cpp as well, as they need a full definition of the Option structure. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2020-10-21cam: options: Rename optional arg to prevent shadowingKieran Bingham
The parseValue function is given the optarg directly from the getopt library, but the function retains the same name. This causes an shadowed variable of the global optarg variable to be present in the parseValue function. While this is not harmful, rename it to work towards disabling shadowed variables. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2020-10-12cam: options: fix access to uninit variableTomi Valkeinen
operator[] doesn't check if the option exists in the values_ map, so it can return a pointer to location outside the map. Fix by returning an empty OptionValue if the option is not found. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@iki.fi> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> [Kieran: Adjust s_empty naming to 'empty'] Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2020-05-01cam: options: Add public method to invalidate optionsNiklas Söderlund
Extend OptionsBase<T> with a public invalidate() method. This allows for further examination of the options and if found unsuitable be invalidated. The intended user for this new interface are subclasses of KeyValueParser. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-11-26cam: options: Fix unitialized variable warningLaurent Pinchart
gcc 8 and 9 complain about the OptionValue::integer_ member being possibly used initialized when compiled in release mode. I haven't been able to find where this could be the case, and the compiler error message isn't helpful: In file included from ../../src/cam/options.cpp:14: ../../src/cam/options.h: In member function ‘bool OptionsBase<T>::parseValue(const T&, const Option&, const char*) [with T = std::__cxx11::basic_string<char>]’: ../../src/cam/options.h:84:7: error: ‘<anonymous>.OptionValue::integer_’ may be used uninitialized in this function [-Werror=maybe-uninitialized] class OptionValue ^~~~~~~~~~~ ../../src/cam/options.h: In member function ‘bool OptionsBase<T>::parseValue(const T&, const Option&, const char*) [with T = int]’: ../../src/cam/options.h:84:7: error: ‘<anonymous>.OptionValue::integer_’ may be used uninitialized in this function [-Werror=maybe-uninitialized] class OptionValue ^~~~~~~~~~~ Furthermore valgrind doesn't report any issue. This is likely a false positive, but fix it nonetheless as the fix is cheap. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2019-11-08libcamera: Remove unneeded semicolonsLaurent Pinchart
Comply with the coding style by removing lots of unneeded semicolons. Fix a few other coding style violations on the lines touched by those fixes. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2019-10-23libcamera: Standardise on C compatibility headersLaurent Pinchart
Now that our usage of C compatibility header is documented, use them consistently through the source code. While at it, group the C and C++ include statements as defined in the coding style, and fix a handful of #include ordering issues. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-06-19cam: Support base 16 and base 8 when parsing integer optionsLaurent Pinchart
Integer options have to use base 10. This isn't user-friendly when specifying pixel formats. Detect the base automatically to support base 16. As a side effect, integer values starting with 0 will be interpreted in base 8. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-04-26cam: options: Fix string concatenationLaurent Pinchart
Adding an integer value to a char pointer doesn't concatenate strings, it indexes in the pointed string. Fix it. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2019-04-26cam: options: Don't initialise variable-length arraysLaurent Pinchart
According to clang, variable-length arrays can't be initialised. Don't do so, and explicitly set the last element to 0 instead. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2019-03-27cam: Separate options valid() and empty()Laurent Pinchart
An empty option list is not necessarily an error. Add a new empty() function to test the option list for emptiness, and modify the valid() function to only notify parsing errors. As a side effect this allows accessing partially parsed options, which may be useful in the future. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-03-27cam: options: Add support for repeatable optionsNiklas Söderlund
Add a flag to indicate if an option can be repeatable. If an option is repeatable it must be accessed thru the array interface, even if it's only specified once by the user. Also update the usage generator to indicate which options are repeatable. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-03-27cam: options: Add an array data type to OptionValueNiklas Söderlund
To allow specifying the same argument option multiple times a new type of OptionValue is needed. As parsing of options is an iterative process there is a need to append options as they are parsed so instead of setting values using the constructor a new addValue() method is used. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-03-25cam: options: Create separate enum for OptionValue typesNiklas Söderlund
In preparation for support of multiple instances of the same option, create a separate enum for the OptionValue types as it will diverge from enum OptionType. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-02-13cam: options: Fix coding style issue related to templatesLaurent Pinchart
Our coding style doesn't add a space after the template keyword. Fix the source code accordingly. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-02-01cam: options: Add explicit conversion methods to OptionValueLaurent Pinchart
The OptionValue class defines operators to convert the variant to all the supported option types. As a convenience, add explicit methods to perform the same operations, avoiding the need to write long static_cast<>() statements in the caller. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-02-01cam: options: Add a key=value parserNiklas Söderlund
Some options passed to the cam utility need to be complex and specify a list of key=value pairs. Add a new parser to deal with these options, usable on its own to parse key=value pairs from any string. Integrate the KeyValueParser into the existing OptionsParser. The cam application can fully describe all its options in one location and perform full parsing of all arguments in one go. The KeyValueParser also integrates itself with the usage() printing of the OptionsParser. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-02-01cam: options: Add option type handling to options parserLaurent Pinchart
Extend the options parser with support for option types. All options must now specify the type of their argument, and the parser automatically parses the argument and handles errors internally. Available types are none, integer or string. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-02-01cam: options: Return whether addOption() succeeds or notNiklas Söderlund
To later extend the options handling to cover subparsing of arguments it will be needed to know if the addition of the option itself was successful or not. The information is already present in addOption() this change just makes it available. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-02-01cam: options: Create a template class for optionsNiklas Söderlund
In preparation to adding more parsers create a template class to hold the parsed information. The rational for making it a template are that different parsers can index the options using different data types. The OptionsParser index its options using an int while the upcoming KeyValyeParser will index its options using strings for example. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-01-27cam: options: Indent multi-line help message correctlyLaurent Pinchart
Split multi-line help messages and indent all lines the same way. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-01-25cam: options: optional arguments needs to be specified as --foo=barNiklas Söderlund
It's not stated in the getopt_long documentation but optional arguments need to be specified as '--foo=bar' instead of '--foo bar', otherwise the value is not propagated to optarg during argument parsing. Update the usage printing helper to reflect this requirement. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-01-22cam: options: Don't implement move semantics for OptionsParser::OptionsLaurent Pinchart
The compiler creates a move constructor automatically when none is supplied, and it does the right thing by default in this case. Using std::move() inside the function prevents the compiler from doing return value optimization and actually hinders performances. Using std::move() in the caller is unnecessary, the move constructor is used automatically by the compiler. For all these reasons remove the tentative optimization that resulted in worse performances and worse code. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-01-22cam: Extract option parser to separate fileLaurent Pinchart
And turn it into an OptionsParser object. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>