mirror of
https://github.com/zeek/zeek.git
synced 2025-10-09 18:18:19 +00:00
Merge branch 'no_sscanf' of https://github.com/MaxKellermann/zeek
* 'no_sscanf' of https://github.com/MaxKellermann/zeek: util: optimize expand_escape() by avoiding sscanf()
This commit is contained in:
commit
fa5b3bb91e
3 changed files with 65 additions and 22 deletions
7
CHANGES
7
CHANGES
|
@ -1,4 +1,11 @@
|
||||||
|
|
||||||
|
3.1.0-dev.521 | 2020-01-31 14:18:17 -0800
|
||||||
|
|
||||||
|
* util: optimize expand_escape() by avoiding sscanf() (Max Kellermann)
|
||||||
|
|
||||||
|
sscanf() is notoriously slow, and the default scripts have lots of hex
|
||||||
|
escapes. This patch can reduce Zeek's startup time by 3-9%.
|
||||||
|
|
||||||
3.1.0-dev.519 | 2020-01-31 13:19:09 -0800
|
3.1.0-dev.519 | 2020-01-31 13:19:09 -0800
|
||||||
|
|
||||||
* util: optimize tokenize_string() and normalize_path() (Max Kellermann)
|
* util: optimize tokenize_string() and normalize_path() (Max Kellermann)
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
3.1.0-dev.519
|
3.1.0-dev.521
|
||||||
|
|
78
src/util.cc
78
src/util.cc
|
@ -293,6 +293,26 @@ int streq(const char* s1, const char* s2)
|
||||||
return ! strcmp(s1, s2);
|
return ! strcmp(s1, s2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static constexpr int parse_octal_digit(char ch) noexcept
|
||||||
|
{
|
||||||
|
if ( ch >= '0' && ch <= '7' )
|
||||||
|
return ch - '0';
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr int parse_hex_digit(char ch) noexcept
|
||||||
|
{
|
||||||
|
if ( ch >= '0' && ch <= '9' )
|
||||||
|
return ch - '0';
|
||||||
|
else if ( ch >= 'a' && ch <= 'f' )
|
||||||
|
return 10 + ch - 'a';
|
||||||
|
else if ( ch >= 'A' && ch <= 'F' )
|
||||||
|
return 10 + ch - 'A';
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int expand_escape(const char*& s)
|
int expand_escape(const char*& s)
|
||||||
{
|
{
|
||||||
switch ( *(s++) ) {
|
switch ( *(s++) ) {
|
||||||
|
@ -310,23 +330,32 @@ int expand_escape(const char*& s)
|
||||||
--s; // put back the first octal digit
|
--s; // put back the first octal digit
|
||||||
const char* start = s;
|
const char* start = s;
|
||||||
|
|
||||||
// Don't increment inside loop control
|
// require at least one octal digit and parse at most three
|
||||||
// because if isdigit() is a macro it might
|
|
||||||
// expand into multiple increments ...
|
|
||||||
|
|
||||||
// Here we define a maximum length for escape sequence
|
int result = parse_octal_digit(*s++);
|
||||||
// to allow easy handling of string like: "^H0" as
|
|
||||||
// "\0100".
|
|
||||||
|
|
||||||
for ( int len = 0; len < 3 && isascii(*s) && isdigit(*s);
|
if ( result < 0 )
|
||||||
++s, ++len)
|
|
||||||
;
|
|
||||||
|
|
||||||
int result;
|
|
||||||
if ( sscanf(start, "%3o", &result) != 1 )
|
|
||||||
{
|
{
|
||||||
reporter->Warning("bad octal escape: %s ", start);
|
reporter->Error("bad octal escape: %s", start);
|
||||||
result = 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// second digit?
|
||||||
|
int digit = parse_octal_digit(*s);
|
||||||
|
|
||||||
|
if ( digit >= 0 )
|
||||||
|
{
|
||||||
|
result = (result << 3) | digit;
|
||||||
|
++s;
|
||||||
|
|
||||||
|
// third digit?
|
||||||
|
digit = parse_octal_digit(*s);
|
||||||
|
|
||||||
|
if ( digit >= 0 )
|
||||||
|
{
|
||||||
|
result = (result << 3) | digit;
|
||||||
|
++s;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -337,15 +366,22 @@ int expand_escape(const char*& s)
|
||||||
const char* start = s;
|
const char* start = s;
|
||||||
|
|
||||||
// Look at most 2 characters, so that "\x0ddir" -> "^Mdir".
|
// Look at most 2 characters, so that "\x0ddir" -> "^Mdir".
|
||||||
for ( int len = 0; len < 2 && isascii(*s) && isxdigit(*s);
|
|
||||||
++s, ++len)
|
|
||||||
;
|
|
||||||
|
|
||||||
int result;
|
int result = parse_hex_digit(*s++);
|
||||||
if ( sscanf(start, "%2x", &result) != 1 )
|
|
||||||
|
if ( result < 0 )
|
||||||
{
|
{
|
||||||
reporter->Warning("bad hexadecimal escape: %s", start);
|
reporter->Error("bad hexadecimal escape: %s", start);
|
||||||
result = 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// second digit?
|
||||||
|
int digit = parse_hex_digit(*s);
|
||||||
|
|
||||||
|
if ( digit >= 0 )
|
||||||
|
{
|
||||||
|
result = (result << 4) | digit;
|
||||||
|
++s;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue