[Stack] Optimize GetArgv to only allocate what is needed.

And also only allocate on the heap, not on the stack.
This commit is contained in:
Gijs Noorlander
2018-12-01 22:51:43 +01:00
parent afeed445ca
commit 2290de3c98
4 changed files with 44 additions and 63 deletions
+5 -5
View File
@@ -29,10 +29,10 @@ String Command_GetORSetIP(struct EventStruct *event,
bool hasArgument = false;
{
// Check if command is valid. Leave in separate scope to delete the TmpStr1
char TmpStr1[INPUT_COMMAND_SIZE];
String TmpStr1;
if (GetArgv(Line, TmpStr1, arg + 1)) {
hasArgument = true;
if (!str2ip(TmpStr1, IP)) {
if (!str2ip(TmpStr1.c_str(), IP)) {
String result = F("Invalid parameter: ");
result += TmpStr1;
return return_result(event, result);
@@ -64,17 +64,17 @@ String Command_GetORSetString(struct EventStruct *event,
bool hasArgument = false;
{
// Check if command is valid. Leave in separate scope to delete the TmpStr1
char TmpStr1[INPUT_COMMAND_SIZE];
String TmpStr1;
if (GetArgv(Line, TmpStr1, arg + 1)) {
hasArgument = true;
if (strlen(TmpStr1) > len) {
if (TmpStr1.length() > len) {
String result = targetDescription;
result += F(" is too large. max size is ");
result += len;
serialPrintln();
return return_result(event, result);
} else {
strcpy(target, TmpStr1);
strcpy(target, TmpStr1.c_str());
}
}
}
+2 -7
View File
@@ -224,9 +224,7 @@ void parseCompleteNonCommentLine(
{
String tmpString = event.substring(equalsPos + 1);
//line.replace(F("%eventvalue%"), tmpString); // substitute %eventvalue% with the actual value from the event
char* tmpParam = new char[INPUT_COMMAND_SIZE];
tmpParam[0] = 0;
String tmpParam;
if (GetArgv(tmpString.c_str(),tmpParam,1)) {
line.replace(F("%eventvalue%"), tmpParam); // for compatibility issues
line.replace(F("%eventvalue1%"), tmpParam); // substitute %eventvalue1% in actions with the actual value from the event
@@ -234,7 +232,6 @@ void parseCompleteNonCommentLine(
if (GetArgv(tmpString.c_str(),tmpParam,2)) line.replace(F("%eventvalue2%"), tmpParam); // substitute %eventvalue2% in actions with the actual value from the event
if (GetArgv(tmpString.c_str(),tmpParam,3)) line.replace(F("%eventvalue3%"), tmpParam); // substitute %eventvalue3% in actions with the actual value from the event
if (GetArgv(tmpString.c_str(),tmpParam,4)) line.replace(F("%eventvalue4%"), tmpParam); // substitute %eventvalue4% in actions with the actual value from the event
delete[] tmpParam;
}
}
}
@@ -433,8 +430,7 @@ void processMatchedRule(
{
String tmpString = event.substring(equalsPos + 1);
char* tmpParam = new char[INPUT_COMMAND_SIZE];
tmpParam[0] = 0;
String tmpParam;
if (GetArgv(tmpString.c_str(),tmpParam,1)) {
action.replace(F("%eventvalue%"), tmpParam); // for compatibility issues
@@ -443,7 +439,6 @@ void processMatchedRule(
if (GetArgv(tmpString.c_str(),tmpParam,2)) action.replace(F("%eventvalue2%"), tmpParam); // substitute %eventvalue2% in actions with the actual value from the event
if (GetArgv(tmpString.c_str(),tmpParam,3)) action.replace(F("%eventvalue3%"), tmpParam); // substitute %eventvalue3% in actions with the actual value from the event
if (GetArgv(tmpString.c_str(),tmpParam,4)) action.replace(F("%eventvalue4%"), tmpParam); // substitute %eventvalue4% in actions with the actual value from the event
delete[] tmpParam;
}
}
+33 -45
View File
@@ -520,19 +520,18 @@ void delayBackground(unsigned long delay)
void parseCommandString(struct EventStruct *event, const String& string)
{
checkRAM(F("parseCommandString"));
char *TmpStr1 = new char[INPUT_COMMAND_SIZE]();
String TmpStr1;
event->Par1 = 0;
event->Par2 = 0;
event->Par3 = 0;
event->Par4 = 0;
event->Par5 = 0;
if (GetArgv(string.c_str(), TmpStr1, 2)) { event->Par1 = CalculateParam(TmpStr1); }
if (GetArgv(string.c_str(), TmpStr1, 3)) { event->Par2 = CalculateParam(TmpStr1); }
if (GetArgv(string.c_str(), TmpStr1, 4)) { event->Par3 = CalculateParam(TmpStr1); }
if (GetArgv(string.c_str(), TmpStr1, 5)) { event->Par4 = CalculateParam(TmpStr1); }
if (GetArgv(string.c_str(), TmpStr1, 6)) { event->Par5 = CalculateParam(TmpStr1); }
delete[] TmpStr1;
if (GetArgv(string.c_str(), TmpStr1, 2)) { event->Par1 = CalculateParam(TmpStr1.c_str()); }
if (GetArgv(string.c_str(), TmpStr1, 3)) { event->Par2 = CalculateParam(TmpStr1.c_str()); }
if (GetArgv(string.c_str(), TmpStr1, 4)) { event->Par3 = CalculateParam(TmpStr1.c_str()); }
if (GetArgv(string.c_str(), TmpStr1, 5)) { event->Par4 = CalculateParam(TmpStr1.c_str()); }
if (GetArgv(string.c_str(), TmpStr1, 6)) { event->Par5 = CalculateParam(TmpStr1.c_str()); }
}
/********************************************************************************************\
@@ -639,32 +638,28 @@ byte getNotificationProtocolIndex(byte Number)
\*********************************************************************************************/
bool HasArgv(const char *string, unsigned int argc) {
String tmp;
return GetArgv(string, tmp, argc);
int pos_begin, pos_end;
return GetArgvBeginEnd(string, argc, pos_begin, pos_end);
}
bool GetArgv(const char *string, String& argvString, unsigned int argc) {
size_t string_len = strlen(string);
if (string_len > INPUT_COMMAND_SIZE) string_len = INPUT_COMMAND_SIZE;
char *TmpStr1 = new char[string_len]();
bool hasArgument = GetArgv(string, TmpStr1, string_len, argc);
if (hasArgument) {
argvString = TmpStr1;
int pos_begin, pos_end;
bool hasArgument = GetArgvBeginEnd(string, argc, pos_begin, pos_end);
if (pos_begin >= 0 && pos_end >= 0) {
argvString.reserve(pos_end - pos_begin);
for (int i = pos_begin; i < pos_end && i >= 0; ++i) {
argvString += string[i];
}
}
delete[] TmpStr1;
return hasArgument;
}
boolean GetArgv(const char *string, char *argv, unsigned int argc) {
return GetArgv(string, argv, INPUT_COMMAND_SIZE, argc);
}
boolean GetArgv(const char *string, char *argv, unsigned int argv_size, unsigned int argc)
{
memset(argv, 0, argv_size);
bool GetArgvBeginEnd(const char *string, const unsigned int argc, int& pos_begin, int& pos_end) {
pos_begin = -1;
pos_end = -1;
size_t string_len = strlen(string);
unsigned int string_pos = 0, argv_pos = 0, argc_pos = 0;
char c, d;
unsigned int string_pos = 0, argc_pos = 0;
char c, d; // c = current char, d = next char (if available)
boolean parenthesis = false;
char matching_parenthesis = '"';
@@ -672,8 +667,9 @@ boolean GetArgv(const char *string, char *argv, unsigned int argv_size, unsigned
{
c = string[string_pos];
d = 0;
if ((string_pos + 1) < string_len)
if ((string_pos + 1) < string_len) {
d = string[string_pos + 1];
}
if (!parenthesis && c == ' ' && d == ' ') {}
else if (!parenthesis && c == ' ' && d == ',') {}
@@ -683,40 +679,31 @@ boolean GetArgv(const char *string, char *argv, unsigned int argv_size, unsigned
else if (c == '"' || c == '\'' || c == '[') {
parenthesis = true;
matching_parenthesis = c;
if (c == '[')
if (c == '[') {
matching_parenthesis = ']';
}
}
else
{
if ((argv_pos +2 ) >= argv_size) {
if (loglevelActiveFor(LOG_LEVEL_ERROR)) {
String log = F("GetArgv Error; argv_size exceeded. argc=");
log += argc;
log += F(" argv_size=");
log += argv_size;
log += F(" argv=");
log += argv;
addLog(LOG_LEVEL_ERROR, log);
}
return false;
if (pos_begin == -1) {
pos_begin = string_pos;
pos_end = string_pos;
}
argv[argv_pos++] = c;
argv[argv_pos] = 0;
++pos_end;
if ((!parenthesis && (d == ' ' || d == ',' || d == 0)) || (parenthesis && (d == matching_parenthesis))) // end of word
{
if (d == matching_parenthesis)
if (d == matching_parenthesis) {
parenthesis = false;
argv[argv_pos] = 0;
}
argc_pos++;
if (argc_pos == argc)
{
return true;
}
argv[0] = 0;
argv_pos = 0;
pos_begin = -1;
pos_end = -1;
string_pos++;
}
}
@@ -728,6 +715,7 @@ boolean GetArgv(const char *string, char *argv, unsigned int argv_size, unsigned
/********************************************************************************************\
check the program memory hash
The const MD5_MD5_MD5_MD5_BoundariesOfTheSegmentsGoHere... needs to remain unchanged as it will be replaced by
+4 -6
View File
@@ -688,9 +688,7 @@ unsigned long string2TimeLong(const String &str)
// format 0000WWWWAAAABBBBCCCCDDDD
// WWWW=weekday, AAAA=hours tens digit, BBBB=hours, CCCC=minutes tens digit DDDD=minutes
#define TmpStr1Length 10
char command[20];
char TmpStr1[TmpStr1Length];
int w, x, y;
unsigned long a;
{
@@ -700,8 +698,8 @@ unsigned long string2TimeLong(const String &str)
tmpString.toCharArray(command, 20);
}
unsigned long lngTime = 0;
if (GetArgv(command, TmpStr1, TmpStr1Length, 1))
String TmpStr1;
if (GetArgv(command, TmpStr1, 1))
{
String day = TmpStr1;
String weekDays = F("allsunmontuewedthufrisatwrkwkd");
@@ -711,10 +709,10 @@ unsigned long string2TimeLong(const String &str)
lngTime |= (unsigned long)y << 16;
}
if (GetArgv(command, TmpStr1, TmpStr1Length, 2))
if (GetArgv(command, TmpStr1, 2))
{
y = 0;
for (x = strlen(TmpStr1) - 1; x >= 0; x--)
for (x = TmpStr1.length() - 1; x >= 0; x--)
{
w = TmpStr1[x];
if ( (w >= '0' && w <= '9') || w == '*')