feat: introduce a new replace template syntax ${*} - #98
Conversation
There was a problem hiding this comment.
Pull request overview
Introduces a new replace-template token ${*} for the C hhss implementation so templates can resolve to a randomly chosen section in rt.db (and supports mixed forms like ${*|user|char}).
Changes:
- Add wildcard section selection in
replace_templates()and route to the existing user/non-user replacement handlers. - Introduce
rtdbquerybyidx()to queryrt.dbsections by index and add section-name constants (SECTNAME_*) inglobal.h. - Prevent
[*]from being used as a literal section name inrt.dbparsing.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| hhss/dat.db | Updates sample data to exercise the new ${*} template. |
| hhss/c/rtdbparse.h | Exposes rtdbquerybyidx() for index-based section lookup. |
| hhss/c/rtdbparse.c | Implements rtdbquerybyidx() and disallows * as a section name. |
| hhss/c/replace.internals.h | Includes global.h for section-name constants used by replacement logic. |
| hhss/c/replace.c | Implements ${*} wildcard replacement behavior over rt.db sections. |
| hhss/c/global.h | Adds SECTNAME_WILDCARD / SECTNAME_USER macros for consistent section naming. |
| if (STREQL(rt, SECTNAME_WILDCARD)) { /* wildcard template? */ | ||
| v = rand_range(0, array_size(rtdb) - 1); | ||
| sectarr = rtdbquerybyidx(rtdb, v, §name); |
There was a problem hiding this comment.
rtdbcheck(), which is called before replace_templates(), ensures that rt.db shouldn't be empty. Therefore, I don't think we need to validate the emptiness once more here.
| extern array_t *rtdbquerybyidx(array_t *table, size_t idx, const char **sectname) { | ||
| mapper_t *mapper = array_get(table, idx); | ||
| *sectname = mapper->sect; | ||
| return mapper->addr; | ||
| } |
There was a problem hiding this comment.
rtdbquerybyidx, as its name implies, expects idx be [0, rtdb.len - 1]. So I don't want to bother checking out-of-range errors. That's so cumbersome.
| l->run[rearpos] = '\0'; | ||
| return l->run + frontpos; | ||
|
|
||
| if (STREQL(ret, SECTNAME_WILDCARD)) { | ||
| reason = "section name can't be *"; | ||
| synerr(); |
There was a problem hiding this comment.
intended for convenience
| if (STREQL(rt, SECTNAME_WILDCARD)) { /* wildcard template? */ | ||
| v = rand_range(0, array_size(rtdb) - 1); |
There was a problem hiding this comment.
Replace templates other than ${user} is currently a feature only supported by the C implementation.
|
done |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
hhss/c/rtdbparse.c:67
- rtdbcheck() does not currently reject an empty rt.db (dbsiz==0), so wildcard replacement (${*}) can still reach rand_range(0, array_size(rtdb) - 1) with an empty table and fail with an internal range error. Add an explicit empty-db validation in rtdbcheck() so the failure is reported clearly and before template replacement runs.
sectname = m->sect;
sectarr_siz = array_size(sectarr);
if (STREQL(sectname, SECTNAME_USER)) {
if (sectarr_siz >= threshold)
| extern array_t *rtdbquerybyidx(array_t *table, size_t idx, const char **sectname) { | ||
| mapper_t *mapper = array_get(table, idx); | ||
| if (sectname) *sectname = mapper->sect; |
| array_t *rtdbparse(array_t *linestr); | ||
| array_t *rtdbquery(array_t *table, const char *sectname); | ||
| array_t *rtdbquerybyidx(array_t *table, size_t idx, const char **sectname); | ||
| void rtdbcheck(array_t *db); |
${*} resolves to the arbitrary sections in
rt.db. Incidentally, it is valid to write like${*|user|char}.closes #72.