mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-08-03 10:46:12 +00:00
Add bulk region hierarchy command to CLI
Add a new command `region bulk` for defining region hierarchies in a single line. This command allows users to create multiple regions in a single message. Updated the documentation to include usage examples and detailed parameter descriptions.
This commit is contained in:
@@ -756,6 +756,46 @@ This document provides an overview of CLI commands that can be sent to MeshCore
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
#### Bulk-define region hierarchy (single line)
|
||||||
|
**Usage:**
|
||||||
|
- `region bulk <token> [<token> ...]`
|
||||||
|
|
||||||
|
**Parameters (tokens):** Space-separated. A logical **cursor** starts at the wildcard `*`.
|
||||||
|
|
||||||
|
- **`name`** — Create `name` as a child of the current cursor (same as `region put name` with that parent). Cursor moves to `name`.
|
||||||
|
- **`name|jump`** or **`name,jump`** — Create `name` as a child of the current cursor, then move the cursor to `jump` (must already exist: created earlier in this command or already on the node). `jump` is **not** the parent of `name`; use this to pop back up and start another branch.
|
||||||
|
|
||||||
|
**Note:** Same flood defaults as `region put` (flood allowed on each created region).
|
||||||
|
|
||||||
|
**Note:** Does **not** persist to flash. The reply is the region tree (same format as bare `region`) so you can review before **`region save`**.
|
||||||
|
|
||||||
|
**Note:** On error, the reply is a short `Err - ...` message; regions placed before the failure remain (same as a partial chain of `region put`).
|
||||||
|
|
||||||
|
**Note:** Repeater serial accepts one line up to **160 characters** total; split very large trees across multiple `region bulk` commands.
|
||||||
|
|
||||||
|
**Note:** `|` only splits once per token. `region bulk a|b|c|d` is **not** a flat-list shorthand — use `region bulk a|* b|* c|* d|*` for multiple children of `*`.
|
||||||
|
|
||||||
|
**Example — linear chain:**
|
||||||
|
```
|
||||||
|
region bulk west pnw wa w-wa sea
|
||||||
|
region save
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example — branched tree** (equivalent to `region put west` … `region put sw-wa wa`):
|
||||||
|
```
|
||||||
|
region bulk west pnw or pdx|pnw wa sw-wa
|
||||||
|
region save
|
||||||
|
```
|
||||||
|
Same with comma as jump delimiter: `region bulk west pnw or pdx,pnw wa sw-wa`
|
||||||
|
|
||||||
|
**Example — flat list** (each region child of `*`):
|
||||||
|
```
|
||||||
|
region bulk west|* pnw|* or|* pdx|* wa|* sw-wa
|
||||||
|
region save
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
#### Remove a region
|
#### Remove a region
|
||||||
**Usage:**
|
**Usage:**
|
||||||
- `region remove <name>`
|
- `region remove <name>`
|
||||||
|
|||||||
@@ -898,6 +898,70 @@ void CommonCLI::handleGetCmd(uint32_t sender_timestamp, char* command, char* rep
|
|||||||
void CommonCLI::handleRegionCmd(char* command, char* reply) {
|
void CommonCLI::handleRegionCmd(char* command, char* reply) {
|
||||||
reply[0] = 0;
|
reply[0] = 0;
|
||||||
|
|
||||||
|
// `region bulk ...` — 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++;
|
||||||
|
if (strncmp(cmd, "region bulk", 11) == 0 && (cmd[11] == ' ' || cmd[11] == '\0')) {
|
||||||
|
char* payload = cmd + 11;
|
||||||
|
while (*payload == ' ') payload++;
|
||||||
|
if (*payload == '\0') {
|
||||||
|
snprintf(reply, 160, "Err - empty bulk");
|
||||||
|
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* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_region_map->exportTo(reply, 160);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const char* parts[4];
|
const char* parts[4];
|
||||||
int n = mesh::Utils::parseTextParts(command, parts, 4, ' ');
|
int n = mesh::Utils::parseTextParts(command, parts, 4, ' ');
|
||||||
if (n == 1) {
|
if (n == 1) {
|
||||||
|
|||||||
Reference in New Issue
Block a user