2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 06:15:47 +00:00

util: Introduce ovs_scan_len()

This is similar to ovs_scan but takes int pointer as extra
parameter, this pointer point to starting index of the string.
On successful scan this API stores number of characters
scanned.  This API is useful for parsing complex odp actions
e.g. tun_push action.

Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Acked-by: Thomas Graf <tgraf@noironetworks.com>
Acked-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
Pravin B Shelar
2014-11-10 12:46:11 -08:00
parent 493823d8d5
commit f071cbbaad
2 changed files with 68 additions and 35 deletions

View File

@@ -1613,34 +1613,13 @@ scan_chars(const char *s, const struct scan_spec *spec, va_list *args)
return s + n;
}
/* This is an implementation of the standard sscanf() function, with the
* following exceptions:
*
* - It returns true if the entire format was successfully scanned and
* converted, false if any conversion failed.
*
* - The standard doesn't define sscanf() behavior when an out-of-range value
* is scanned, e.g. if a "%"PRIi8 conversion scans "-1" or "0x1ff". Some
* implementations consider this an error and stop scanning. This
* implementation never considers an out-of-range value an error; instead,
* it stores the least-significant bits of the converted value in the
* destination, e.g. the value 255 for both examples earlier.
*
* - Only single-byte characters are supported, that is, the 'l' modifier
* on %s, %[, and %c is not supported. The GNU extension 'a' modifier is
* also not supported.
*
* - %p is not supported.
*/
bool
ovs_scan(const char *s, const char *format, ...)
static bool
ovs_scan__(const char *s, int *n, const char *format, va_list *args)
{
const char *const start = s;
bool ok = false;
const char *p;
va_list args;
va_start(args, format);
p = format;
while (*p != '\0') {
struct scan_spec spec;
@@ -1735,24 +1714,24 @@ ovs_scan(const char *s, const char *format, ...)
}
switch (c) {
case 'd':
s = scan_int(s, &spec, 10, &args);
s = scan_int(s, &spec, 10, args);
break;
case 'i':
s = scan_int(s, &spec, 0, &args);
s = scan_int(s, &spec, 0, args);
break;
case 'o':
s = scan_int(s, &spec, 8, &args);
s = scan_int(s, &spec, 8, args);
break;
case 'u':
s = scan_int(s, &spec, 10, &args);
s = scan_int(s, &spec, 10, args);
break;
case 'x':
case 'X':
s = scan_int(s, &spec, 16, &args);
s = scan_int(s, &spec, 16, args);
break;
case 'e':
@@ -1760,24 +1739,24 @@ ovs_scan(const char *s, const char *format, ...)
case 'g':
case 'E':
case 'G':
s = scan_float(s, &spec, &args);
s = scan_float(s, &spec, args);
break;
case 's':
s = scan_string(s, &spec, &args);
s = scan_string(s, &spec, args);
break;
case '[':
s = scan_set(s, &spec, &p, &args);
s = scan_set(s, &spec, &p, args);
break;
case 'c':
s = scan_chars(s, &spec, &args);
s = scan_chars(s, &spec, args);
break;
case 'n':
if (spec.type != SCAN_DISCARD) {
*va_arg(args, int *) = s - start;
*va_arg(*args, int *) = s - start;
}
break;
}
@@ -1786,13 +1765,66 @@ ovs_scan(const char *s, const char *format, ...)
goto exit;
}
}
ok = true;
if (n) {
*n = s - start;
}
ok = true;
exit:
va_end(args);
return ok;
}
/* This is an implementation of the standard sscanf() function, with the
* following exceptions:
*
* - It returns true if the entire format was successfully scanned and
* converted, false if any conversion failed.
*
* - The standard doesn't define sscanf() behavior when an out-of-range value
* is scanned, e.g. if a "%"PRIi8 conversion scans "-1" or "0x1ff". Some
* implementations consider this an error and stop scanning. This
* implementation never considers an out-of-range value an error; instead,
* it stores the least-significant bits of the converted value in the
* destination, e.g. the value 255 for both examples earlier.
*
* - Only single-byte characters are supported, that is, the 'l' modifier
* on %s, %[, and %c is not supported. The GNU extension 'a' modifier is
* also not supported.
*
* - %p is not supported.
*/
bool
ovs_scan(const char *s, const char *format, ...)
{
va_list args;
bool res;
va_start(args, format);
res = ovs_scan__(s, NULL, format, &args);
va_end(args);
return res;
}
/*
* This function is similar to ocs_scan(), extra parameter `n` is added to
* return number of scanned characters.
*/
bool
ovs_scan_len(const char *s, int *n, const char *format, ...)
{
va_list args;
bool success;
int n1;
va_start(args, format);
success = ovs_scan__(s + *n, &n1, format, &args);
va_end(args);
if (success) {
*n = *n + n1;
}
return success;
}
void
xsleep(unsigned int seconds)
{