Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
3a3f4038
Commit
3a3f4038
authored
Sep 25, 2015
by
Alexander Alekhin
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #5391 from paroj:parser_nonempty
parents
09ba5a28
46ada388
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
74 additions
and
39 deletions
+74
-39
utility.hpp
modules/core/include/opencv2/core/utility.hpp
+4
-1
command_line_parser.cpp
modules/core/src/command_line_parser.cpp
+35
-35
test_utils.cpp
modules/core/test/test_utils.cpp
+35
-3
No files found.
modules/core/include/opencv2/core/utility.hpp
View file @
3a3f4038
...
...
@@ -609,7 +609,7 @@ For example:
const String keys =
"{help h usage ? | | print this message }"
"{@image1 | | image1 for compare }"
"{@image2 |
| image2 for compare }"
"{@image2 |
<none>
| image2 for compare }"
"{@repeat |1 | number }"
"{path |. | path to file }"
"{fps | -1.0 | fps for output video }"
...
...
@@ -623,6 +623,9 @@ Note that there are no default values for `help` and `timestamp` so we can check
Arguments with default values are considered to be always present. Use the `get()` method in these cases to check their
actual value instead.
String keys like `get<String>("@image1")` return the empty string `""` by default - even with an empty default value.
Use the special `<none>` default value to enforce that the returned string must not be empty. (like in `get<String>("@image2")`)
### Usage
For the described keys:
...
...
modules/core/src/command_line_parser.cpp
View file @
3a3f4038
...
...
@@ -4,6 +4,20 @@
namespace
cv
{
namespace
{
static
const
char
*
noneValue
=
"<none>"
;
static
String
cat_string
(
const
String
&
str
)
{
int
left
=
0
,
right
=
(
int
)
str
.
length
();
while
(
left
<=
right
&&
str
[
left
]
==
' '
)
left
++
;
while
(
right
>
left
&&
str
[
right
-
1
]
==
' '
)
right
--
;
return
left
>=
right
?
String
(
""
)
:
str
.
substr
(
left
,
right
-
left
);
}
}
struct
CommandLineParserParams
{
public
:
...
...
@@ -27,7 +41,6 @@ struct CommandLineParser::Impl
std
::
vector
<
String
>
split_range_string
(
const
String
&
str
,
char
fs
,
char
ss
)
const
;
std
::
vector
<
String
>
split_string
(
const
String
&
str
,
char
symbol
=
' '
,
bool
create_empty_item
=
false
)
const
;
String
cat_string
(
const
String
&
str
)
const
;
void
apply_params
(
const
String
&
key
,
const
String
&
value
);
void
apply_params
(
int
i
,
String
value
);
...
...
@@ -98,10 +111,10 @@ void CommandLineParser::getByName(const String& name, bool space_delete, int typ
{
String
v
=
impl
->
data
[
i
].
def_value
;
if
(
space_delete
)
v
=
impl
->
cat_string
(
v
);
v
=
cat_string
(
v
);
// the key was neither specified nor has it a default value
if
(
v
.
empty
()
&&
type
!=
Param
::
STRING
)
{
if
(
(
v
.
empty
()
&&
type
!=
Param
::
STRING
)
||
v
==
noneValue
)
{
impl
->
error
=
true
;
impl
->
error_message
=
impl
->
error_message
+
"Missing parameter: '"
+
name
+
"'
\n
"
;
return
;
...
...
@@ -133,10 +146,10 @@ void CommandLineParser::getByIndex(int index, bool space_delete, int type, void*
if
(
impl
->
data
[
i
].
number
==
index
)
{
String
v
=
impl
->
data
[
i
].
def_value
;
if
(
space_delete
==
true
)
v
=
impl
->
cat_string
(
v
);
if
(
space_delete
==
true
)
v
=
cat_string
(
v
);
// the key was neither specified nor has it a default value
if
(
v
.
empty
()
&&
type
!=
Param
::
STRING
)
{
if
(
(
v
.
empty
()
&&
type
!=
Param
::
STRING
)
||
v
==
noneValue
)
{
impl
->
error
=
true
;
impl
->
error_message
=
impl
->
error_message
+
format
(
"Missing parameter #%d
\n
"
,
index
);
return
;
...
...
@@ -198,7 +211,7 @@ CommandLineParser::CommandLineParser(int argc, const char* const argv[], const S
CommandLineParserParams
p
;
p
.
keys
=
impl
->
split_string
(
l
[
0
]);
p
.
def_value
=
l
[
1
];
p
.
help_message
=
impl
->
cat_string
(
l
[
2
]);
p
.
help_message
=
cat_string
(
l
[
2
]);
p
.
number
=
-
1
;
if
(
p
.
keys
.
size
()
<=
0
)
{
...
...
@@ -221,25 +234,21 @@ CommandLineParser::CommandLineParser(int argc, const char* const argv[], const S
jj
=
0
;
for
(
int
i
=
1
;
i
<
argc
;
i
++
)
{
String
s
=
String
(
argv
[
i
]);
String
s
(
argv
[
i
]);
bool
hasSingleDash
=
s
.
length
()
>
1
&&
s
[
0
]
==
'-'
;
if
(
s
.
find
(
'='
)
!=
String
::
npos
&&
s
.
find
(
'='
)
<
s
.
length
()
)
if
(
hasSingleDash
)
{
std
::
vector
<
String
>
k_v
=
impl
->
split_string
(
s
,
'='
,
true
);
for
(
int
h
=
0
;
h
<
2
;
h
++
)
{
if
(
k_v
[
0
][
0
]
==
'-'
)
k_v
[
0
]
=
k_v
[
0
].
substr
(
1
,
k_v
[
0
].
length
()
-
1
);
bool
hasDoubleDash
=
s
.
length
()
>
2
&&
s
[
1
]
==
'-'
;
String
key
=
s
.
substr
(
hasDoubleDash
?
2
:
1
);
String
value
=
"true"
;
size_t
equalsPos
=
key
.
find
(
'='
);
if
(
equalsPos
!=
String
::
npos
)
{
value
=
key
.
substr
(
equalsPos
+
1
);
key
=
key
.
substr
(
0
,
equalsPos
);
}
impl
->
apply_params
(
k_v
[
0
],
k_v
[
1
]);
}
else
if
(
s
.
length
()
>
2
&&
s
[
0
]
==
'-'
&&
s
[
1
]
==
'-'
)
{
impl
->
apply_params
(
s
.
substr
(
2
),
"true"
);
}
else
if
(
s
.
length
()
>
1
&&
s
[
0
]
==
'-'
)
{
impl
->
apply_params
(
s
.
substr
(
1
),
"true"
);
impl
->
apply_params
(
key
,
value
);
}
else
{
...
...
@@ -317,16 +326,6 @@ void CommandLineParser::Impl::sort_params()
std
::
sort
(
data
.
begin
(),
data
.
end
(),
cmp_params
);
}
String
CommandLineParser
::
Impl
::
cat_string
(
const
String
&
str
)
const
{
int
left
=
0
,
right
=
(
int
)
str
.
length
();
while
(
left
<=
right
&&
str
[
left
]
==
' '
)
left
++
;
while
(
right
>
left
&&
str
[
right
-
1
]
==
' '
)
right
--
;
return
left
>=
right
?
String
(
""
)
:
str
.
substr
(
left
,
right
-
left
);
}
String
CommandLineParser
::
getPathToApplication
()
const
{
return
impl
->
path_to_app
;
...
...
@@ -340,7 +339,8 @@ bool CommandLineParser::has(const String& name) const
{
if
(
name
==
impl
->
data
[
i
].
keys
[
j
])
{
return
!
impl
->
cat_string
(
impl
->
data
[
i
].
def_value
).
empty
();
const
String
v
=
cat_string
(
impl
->
data
[
i
].
def_value
);
return
!
v
.
empty
()
&&
v
!=
noneValue
;
}
}
}
...
...
@@ -404,7 +404,7 @@ void CommandLineParser::printMessage() const
printf
(
", "
);
}
}
String
dv
=
impl
->
cat_string
(
impl
->
data
[
i
].
def_value
);
String
dv
=
cat_string
(
impl
->
data
[
i
].
def_value
);
if
(
dv
.
compare
(
""
)
!=
0
)
{
printf
(
" (value:%s)"
,
dv
.
c_str
());
...
...
@@ -424,7 +424,7 @@ void CommandLineParser::printMessage() const
printf
(
"%s"
,
k
.
c_str
());
String
dv
=
impl
->
cat_string
(
impl
->
data
[
i
].
def_value
);
String
dv
=
cat_string
(
impl
->
data
[
i
].
def_value
);
if
(
dv
.
compare
(
""
)
!=
0
)
{
printf
(
" (value:%s)"
,
dv
.
c_str
());
...
...
modules/core/test/test_utils.cpp
View file @
3a3f4038
...
...
@@ -142,9 +142,8 @@ TEST(CommandLineParser, testPositional_noArgs)
EXPECT_EQ
(
"default1"
,
parser
.
get
<
String
>
(
"@arg1"
));
EXPECT_EQ
(
"default1"
,
parser
.
get
<
String
>
(
0
));
parser
.
get
<
String
>
(
"@arg2"
);
parser
.
get
<
String
>
(
1
);
EXPECT_TRUE
(
parser
.
check
());
EXPECT_EQ
(
""
,
parser
.
get
<
String
>
(
"@arg2"
));
EXPECT_EQ
(
""
,
parser
.
get
<
String
>
(
1
));
}
TEST
(
CommandLineParser
,
testPositional_default
)
...
...
@@ -186,4 +185,37 @@ TEST(CommandLineParser, testPositional_withFlagsAfter)
EXPECT_EQ
(
"test2"
,
parser
.
get
<
String
>
(
1
));
}
TEST
(
CommandLineParser
,
testEmptyStringValue
)
{
static
const
char
*
const
keys3
=
"{ @pos0 | | empty default value }"
"{ @pos1 | <none> | forbid empty default value }"
;
const
char
*
argv
[]
=
{
"<bin>"
};
const
int
argc
=
1
;
cv
::
CommandLineParser
parser
(
argc
,
argv
,
keys3
);
// EXPECT_TRUE(parser.has("@pos0"));
EXPECT_EQ
(
""
,
parser
.
get
<
String
>
(
"@pos0"
));
EXPECT_TRUE
(
parser
.
check
());
EXPECT_FALSE
(
parser
.
has
(
"@pos1"
));
parser
.
get
<
String
>
(
1
);
EXPECT_FALSE
(
parser
.
check
());
}
TEST
(
CommandLineParser
,
positional_regression_5074_equal_sign
)
{
static
const
char
*
const
keys3
=
"{ @eq0 | | }"
"{ eq1 | | }"
;
const
char
*
argv
[]
=
{
"<bin>"
,
"1=0"
,
"--eq1=1=0"
};
const
int
argc
=
3
;
cv
::
CommandLineParser
parser
(
argc
,
argv
,
keys3
);
EXPECT_EQ
(
"1=0"
,
parser
.
get
<
String
>
(
"@eq0"
));
EXPECT_EQ
(
"1=0"
,
parser
.
get
<
String
>
(
0
));
EXPECT_EQ
(
"1=0"
,
parser
.
get
<
String
>
(
"eq1"
));
EXPECT_TRUE
(
parser
.
check
());
}
}
// namespace
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment