Skip to content

Commit 08b7956

Browse files
gh-48: Add -private mode.
1 parent 4a8db0b commit 08b7956

File tree

4 files changed

+25
-12
lines changed

4 files changed

+25
-12
lines changed

docs/SPECIFICATION.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,8 @@
467467

468468
- Verbose tracebacks: if the `-verbose` flag is supplied on the command line, tracebacks include the environment snapshots described in Section 10.8. In concise traceback mode the `-verbose` flag causes the interpreter to attach an `env_snapshot` entry to each frame shown; in verbose traceback mode the same flag expands the printed `State snapshot: blocks to include the selected local environment and any small set of globals included by policy. The snapshot contents follow the requirements in Section 10.2 and are suitable for deterministic replay.
469469

470+
- Private mode: if the `-private` flag is supplied on the command line, the interpreter MUST disable the state logger and suppress environment snapshots in tracebacks. Tracebacks MUST still be emitted (concise or verbose as requested) but MUST omit any `env_snapshot` content and must not emit state-log entries; the traceback should clearly indicate when snapshot information has been suppressed.
471+
470472
Notes:
471473

472474
- The interpreter MAY support additional flags and a different ordering of arguments; the rules above define the semantics for `argv[1]`, `-source`, and `-verbose` specifically and are intended to be stable for tooling and replay purposes.

src/interpreter.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ static void trace_pop_frame(Interpreter* interp) {
8989

9090
static void trace_log_step(Interpreter* interp, Stmt* stmt, Env* env) {
9191
if (!interp || !stmt) return;
92+
if (interp->private_mode) return;
9293
if (interp->trace_stack_count == 0) {
9394
if (trace_push_frame(interp, "<top-level>", env ? env : interp->global_env, 0, 0, 0) != 0) return;
9495
}
@@ -176,7 +177,7 @@ char* interpreter_format_traceback(Interpreter* interp, const char* error_msg, i
176177
trace_append(&out, &len, &cap, row);
177178
snprintf(row, sizeof(row), " State log index: %d State id: %s\n", frame->last_step_index, frame->state_id);
178179
trace_append(&out, &len, &cap, row);
179-
if (interp->verbose) {
180+
if (interp->verbose && !interp->private_mode) {
180181
char* snap = trace_env_snapshot(frame->env);
181182
if (snap && snap[0] != '\0') {
182183
trace_append(&out, &len, &cap, " Env snapshot: ");
@@ -204,7 +205,7 @@ void interpreter_reset_traceback(Interpreter* interp, Env* top_env) {
204205
interp->trace_next_step_index = 0;
205206
snprintf(interp->trace_last_state_id, sizeof(interp->trace_last_state_id), "seed");
206207
interp->trace_last_rule[0] = '\0';
207-
if (top_env) {
208+
if (top_env && !interp->private_mode) {
208209
(void)trace_push_frame(interp, "<top-level>", top_env, 0, 0, 0);
209210
}
210211
}
@@ -2736,7 +2737,7 @@ static ExecResult exec_stmt_list(Interpreter* interp, StmtList* list, Env* env,
27362737

27372738
// ============ Main entry point ============
27382739

2739-
void interpreter_init(Interpreter* interp, const char* source_path, bool verbose) {
2740+
void interpreter_init(Interpreter* interp, const char* source_path, bool verbose, bool private_mode) {
27402741
if (!interp) return;
27412742
memset(interp, 0, sizeof(*interp));
27422743
interp->global_env = env_create(NULL);
@@ -2746,6 +2747,7 @@ void interpreter_init(Interpreter* interp, const char* source_path, bool verbose
27462747
interp->modules = NULL;
27472748
interp->current_thr = NULL;
27482749
interp->verbose = verbose ? 1 : 0;
2750+
interp->private_mode = private_mode ? 1 : 0;
27492751
interp->source_path = source_path ? strdup(source_path) : NULL;
27502752
interp->trace_stack = NULL;
27512753
interp->trace_stack_count = 0;
@@ -2754,9 +2756,11 @@ void interpreter_init(Interpreter* interp, const char* source_path, bool verbose
27542756
snprintf(interp->trace_last_state_id, sizeof(interp->trace_last_state_id), "seed");
27552757
interp->trace_last_rule[0] = '\0';
27562758

2757-
if (trace_push_frame(interp, "<top-level>", interp->global_env, 0, 0, 0) != 0) {
2758-
fprintf(stderr, "Out of memory\n");
2759-
exit(1);
2759+
if (!interp->private_mode) {
2760+
if (trace_push_frame(interp, "<top-level>", interp->global_env, 0, 0, 0) != 0) {
2761+
fprintf(stderr, "Out of memory\n");
2762+
exit(1);
2763+
}
27602764
}
27612765

27622766
builtins_init();
@@ -2820,7 +2824,7 @@ void interpreter_destroy(Interpreter* interp) {
28202824

28212825
ExecResult exec_program(Stmt* program, const char* source_path) {
28222826
Interpreter interp;
2823-
interpreter_init(&interp, source_path, false);
2827+
interpreter_init(&interp, source_path, false, false);
28242828

28252829
LabelMap labels = {0};
28262830
ExecResult res = exec_stmt_list(&interp, &program->as.block, interp.global_env, &labels);

src/interpreter.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ typedef struct Interpreter {
9494
bool isolate_env_writes;
9595
// Traceback/logging state
9696
int verbose;
97+
int private_mode;
9798
char* source_path;
9899
TraceFrame* trace_stack;
99100
size_t trace_stack_count;
@@ -105,7 +106,7 @@ typedef struct Interpreter {
105106

106107
// Initialize/destroy a reusable interpreter session.
107108
// `source_path` sets the primary module source label (e.g. script path or "<repl>").
108-
void interpreter_init(Interpreter* interp, const char* source_path, bool verbose);
109+
void interpreter_init(Interpreter* interp, const char* source_path, bool verbose, bool private_mode);
109110
void interpreter_destroy(Interpreter* interp);
110111

111112
// Main entry point

src/main.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,9 @@ static void repl_update_line_state(const char* line, int* brace_depth, int* line
204204
*line_continuation = (end > 0 && line[end - 1] == '^') ? 1 : 0;
205205
}
206206

207-
static int run_repl(int verbose) {
207+
static int run_repl(int verbose, int private_flag) {
208208
Interpreter interp;
209-
interpreter_init(&interp, "<repl>", verbose != 0);
209+
interpreter_init(&interp, "<repl>", verbose != 0, private_flag != 0);
210210

211211
char* entry = NULL;
212212
size_t entry_len = 0;
@@ -282,6 +282,7 @@ int main(int argc, char** argv) {
282282
int source_mode = 0;
283283
char* source_text = NULL;
284284
int verbose_flag = 0;
285+
int private_flag = 0;
285286
int explicit_ext_count = 0;
286287

287288
builtins_reset_dynamic();
@@ -306,6 +307,11 @@ int main(int argc, char** argv) {
306307
continue;
307308
}
308309

310+
if (strcmp(arg, "-private") == 0) {
311+
private_flag = 1;
312+
continue;
313+
}
314+
309315
if (strcmp(arg, "-source") == 0) {
310316
if (i + 1 >= argc) {
311317
fprintf(stderr, "Missing argument for -source\n");
@@ -435,7 +441,7 @@ int main(int argc, char** argv) {
435441
}
436442

437443
if (!path && !source_mode) {
438-
int repl_rc = run_repl(verbose_flag);
444+
int repl_rc = run_repl(verbose_flag, private_flag);
439445
extensions_shutdown();
440446
builtins_reset_dynamic();
441447
return repl_rc;
@@ -530,7 +536,7 @@ int main(int argc, char** argv) {
530536
}
531537

532538
Interpreter interp;
533-
interpreter_init(&interp, source_label, verbose_flag != 0);
539+
interpreter_init(&interp, source_label, verbose_flag != 0, private_flag != 0);
534540
ExecResult res = exec_program_in_env(&interp, program, interp.global_env);
535541
interpreter_destroy(&interp);
536542
if (res.status == EXEC_ERROR) {

0 commit comments

Comments
 (0)