Refactor region def with helpers, refine docs

Extract the inline cursor-walk in handleRegionCmd into file-local
helpers (skipSpaces, rtrimSpaces, takeToken, splitNameJump,
processRegionDefSegment), grouped immediately above the consumer.
Behavior is identical; addresses PR #2540 review feedback on
readability.

Tighten the region def docs: collapse five Note callouts into three
grouped paragraphs (Behavior / Existing regions / Limits), add a
case-sensitivity caveat plus an error example, note the cursor reset
between split commands, and use generic placeholder names.
This commit is contained in:
agessaman
2026-05-21 19:25:01 -07:00
parent f3c6c34883
commit 1296aa7792
2 changed files with 77 additions and 73 deletions

View File

@@ -895,68 +895,71 @@ void CommonCLI::handleGetCmd(uint32_t sender_timestamp, char* command, char* rep
}
}
static char* skipSpaces(char* s) {
while (*s == ' ') s++;
return s;
}
static void rtrimSpaces(char* s) {
char* e = s + strlen(s);
while (e > s && e[-1] == ' ') *--e = '\0';
}
static char* takeToken(char** cursor) {
char* p = skipSpaces(*cursor);
if (*p == '\0') { *cursor = p; return nullptr; }
char* tok = p;
while (*p && *p != ' ') p++;
if (*p) *p++ = '\0';
*cursor = p;
return tok;
}
static char* splitNameJump(char* tok) {
for (char* q = tok; *q; q++) {
if (*q == '|' || *q == ',') {
*q = '\0';
char* jump = skipSpaces(q + 1);
rtrimSpaces(jump);
return jump;
}
}
return nullptr;
}
static bool processRegionDefSegment(RegionMap* map, char* tok, RegionEntry** cursor, char* reply) {
char* jump = splitNameJump(tok);
char* name = skipSpaces(tok);
if (*name == '\0') { snprintf(reply, 160, "Err - empty name"); return false; }
if (jump && *jump == '\0') { snprintf(reply, 160, "Err - empty jump"); return false; }
RegionEntry* r = map->putRegion(name, (*cursor)->id);
if (r == NULL) { snprintf(reply, 160, "Err - put failed: %s", name); return false; }
r->flags = 0;
if (jump) {
RegionEntry* j = map->findByNamePrefix(jump);
if (j == NULL) { snprintf(reply, 160, "Err - unknown jump: %s", jump); return false; }
*cursor = j;
} else {
*cursor = r;
}
return true;
}
void CommonCLI::handleRegionCmd(char* command, char* reply) {
reply[0] = 0;
// `region def ...` — cursor-walk over space-separated tokens (must run before
// parseTextParts, which only keeps 4 segments and mutates the buffer).
char* cmd = command;
while (*cmd == ' ') cmd++;
// `region def`: must run before parseTextParts mutates the buffer
char* cmd = skipSpaces(command);
if (strncmp(cmd, "region def", 10) == 0 && (cmd[10] == ' ' || cmd[10] == '\0')) {
char* payload = cmd + 10;
while (*payload == ' ') payload++;
if (*payload == '\0') {
snprintf(reply, 160, "Err - empty def");
return;
}
RegionEntry* cursor = &_region_map->getWildcard();
char* p = payload;
while (*p) {
while (*p == ' ') p++;
if (*p == '\0') break;
char* tok = p;
while (*p && *p != ' ') p++;
if (*p) *p++ = '\0';
char* payload = skipSpaces(cmd + 10);
rtrimSpaces(payload);
if (*payload == '\0') { snprintf(reply, 160, "Err - empty def"); return; }
char* jump = nullptr;
for (char* q = tok; *q; q++) {
if (*q == '|' || *q == ',') {
*q = '\0';
jump = q + 1;
break;
}
}
char* name = tok;
while (*name == ' ') name++;
if (jump) {
while (*jump == ' ') jump++;
char* je = jump + strlen(jump);
while (je > jump && je[-1] == ' ') *--je = '\0';
}
if (*name == '\0') {
snprintf(reply, 160, "Err - empty name");
return;
}
if (jump && *jump == '\0') {
snprintf(reply, 160, "Err - empty jump");
return;
}
auto r = _region_map->putRegion(name, cursor->id);
if (r == NULL) {
snprintf(reply, 160, "Err - put failed: %s", name);
return;
}
r->flags = 0;
if (jump) {
auto j = _region_map->findByNamePrefix(jump);
if (j == NULL) {
snprintf(reply, 160, "Err - unknown jump: %s", jump);
return;
}
cursor = j;
} else {
cursor = r;
}
RegionEntry* cursor = &_region_map->getWildcard();
for (char* tok; (tok = takeToken(&payload)) != nullptr; ) {
if (!processRegionDefSegment(_region_map, tok, &cursor, reply)) return;
}
_region_map->exportTo(reply, 160);
return;