Skip to content

Commit 5d2b228

Browse files
gh-161: Make WARN reject args that can't ~STR.
1 parent 50b7423 commit 5d2b228

1 file changed

Lines changed: 54 additions & 30 deletions

File tree

src/builtins.c

Lines changed: 54 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5824,39 +5824,63 @@ static Value builtin_warn(Interpreter* interp, Value* args, int argc, Expr** arg
58245824

58255825
int forward = (interp->verbose && !interp->shushed);
58265826

5827-
if (forward) {
5828-
printf("WARNING: ");
5829-
for (int i = 0; i < argc; i++) {
5830-
switch (args[i].type) {
5831-
case VAL_BOOL: {
5832-
printf("%s", args[i].as.boolean ? "TRUE" : "FALSE");
5833-
break;
5834-
}
5835-
case VAL_INT: {
5836-
char* s = int_to_base_prefixed_str(args[i].as.i, numeric_base_of(args[i]));
5837-
printf("%s", s);
5838-
free(s);
5839-
break;
5840-
}
5841-
case VAL_FLT: {
5842-
char* s = flt_to_base_prefixed_str(args[i].as.f, numeric_base_of(args[i]), args[i].num_base_nan);
5843-
printf("%s", s);
5844-
free(s);
5845-
break;
5846-
}
5847-
case VAL_STR:
5848-
printf("%s", args[i].as.s);
5849-
break;
5850-
case VAL_FUNC:
5851-
printf("<func %p>", (void*)args[i].as.func);
5852-
break;
5853-
default:
5854-
printf("<null>");
5855-
break;
5827+
/* Build concatenated warning message for validation even when not forwarded. */
5828+
size_t cap = 256;
5829+
char* out = malloc(cap);
5830+
if (!out) RUNTIME_ERROR(interp, "Out of memory", line, col);
5831+
size_t out_len = 0;
5832+
out[0] = '\0';
5833+
5834+
for (int i = 0; i < argc; i++) {
5835+
char* tmp = NULL;
5836+
const char* piece = NULL;
5837+
5838+
switch (args[i].type) {
5839+
case VAL_BOOL:
5840+
piece = args[i].as.boolean ? "TRUE" : "FALSE";
5841+
break;
5842+
case VAL_INT:
5843+
tmp = int_to_base_prefixed_str(args[i].as.i, numeric_base_of(args[i]));
5844+
piece = tmp;
5845+
break;
5846+
case VAL_FLT:
5847+
tmp = flt_to_base_prefixed_str(args[i].as.f, numeric_base_of(args[i]), args[i].num_base_nan);
5848+
piece = tmp;
5849+
break;
5850+
case VAL_STR:
5851+
piece = args[i].as.s ? args[i].as.s : "";
5852+
break;
5853+
default: {
5854+
char buf[128];
5855+
snprintf(buf, sizeof(buf), "WARN expects BOOL, INT, FLT, or STR argument, got %s", value_type_name(args[i]));
5856+
free(out);
5857+
RUNTIME_ERROR(interp, buf, line, col);
5858+
break;
58565859
}
58575860
}
5858-
printf("\n");
5861+
5862+
size_t piece_len = strlen(piece);
5863+
if (out_len + piece_len + 1 > cap) {
5864+
size_t newcap = cap;
5865+
while (out_len + piece_len + 1 > newcap) newcap *= 2;
5866+
char* nout = realloc(out, newcap);
5867+
if (!nout) {
5868+
if (tmp) free(tmp);
5869+
free(out);
5870+
RUNTIME_ERROR(interp, "Out of memory", line, col);
5871+
}
5872+
out = nout;
5873+
cap = newcap;
5874+
}
5875+
memcpy(out + out_len, piece, piece_len);
5876+
out_len += piece_len;
5877+
out[out_len] = '\0';
5878+
5879+
if (tmp) { free(tmp); tmp = NULL; }
58595880
}
5881+
5882+
if (forward) printf("WARNING: %s\n", out);
5883+
free(out);
58605884
return value_bool(forward != 0);
58615885
}
58625886

0 commit comments

Comments
 (0)