Skip to content

Commit cbda87d

Browse files
gh-32: Add source mode.
1 parent 8b848ab commit cbda87d

File tree

1 file changed

+46
-9
lines changed

1 file changed

+46
-9
lines changed

src/main.c

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,8 @@ static int run_repl(int verbose) {
279279

280280
int main(int argc, char** argv) {
281281
const char* path = NULL;
282+
int source_mode = 0;
283+
char* source_text = NULL;
282284
int verbose_flag = 0;
283285
int explicit_ext_count = 0;
284286

@@ -304,6 +306,24 @@ int main(int argc, char** argv) {
304306
continue;
305307
}
306308

309+
if (strcmp(arg, "-source") == 0) {
310+
if (i + 1 >= argc) {
311+
fprintf(stderr, "Missing argument for -source\n");
312+
extensions_shutdown();
313+
builtins_reset_dynamic();
314+
return PREFIX_ERROR_IO;
315+
}
316+
source_mode = 1;
317+
source_text = strdup(argv[++i]);
318+
if (!source_text) {
319+
extensions_shutdown();
320+
builtins_reset_dynamic();
321+
fprintf(stderr, "Out of memory\n");
322+
return PREFIX_ERROR_MEMORY;
323+
}
324+
continue;
325+
}
326+
307327
if (is_extension_arg(arg)) {
308328
char* err = NULL;
309329
if (load_extension_input(arg, &err) != 0) {
@@ -342,7 +362,7 @@ int main(int argc, char** argv) {
342362
}
343363
free(err);
344364

345-
if (path) {
365+
if (path && !source_mode) {
346366
char* prog_dir = path_dirname_dup(path);
347367
char* base = path_basename_no_ext_dup(path);
348368
if (!prog_dir || !base) {
@@ -414,7 +434,7 @@ int main(int argc, char** argv) {
414434
}
415435
}
416436

417-
if (!path) {
437+
if (!path && !source_mode) {
418438
int repl_rc = run_repl(verbose_flag);
419439
extensions_shutdown();
420440
builtins_reset_dynamic();
@@ -423,17 +443,30 @@ int main(int argc, char** argv) {
423443

424444
char* src = NULL;
425445
char* source_label = NULL;
426-
/* Canonicalize the provided program path now so it's correct even if
427-
the process changes cwd below. This prevents relative paths like
428-
"./tests/test2.pre" from resolving incorrectly after chdir. */
446+
447+
if (source_mode) {
448+
source_label = strdup("<source>");
449+
src = strdup(source_text ? source_text : "");
450+
if (!source_label || !src) {
451+
free(source_label);
452+
free(src);
453+
extensions_shutdown();
454+
builtins_reset_dynamic();
455+
fprintf(stderr, "Out of memory\n");
456+
return PREFIX_ERROR_MEMORY;
457+
}
458+
} else {
459+
/* Canonicalize the provided program path now so it's correct even if
460+
the process changes cwd below. This prevents relative paths like
461+
"./tests/test2.pre" from resolving incorrectly after chdir. */
429462
#if defined(_MSC_VER)
430-
if (path) source_label = _fullpath(NULL, path, 0);
463+
if (path) source_label = _fullpath(NULL, path, 0);
431464
#else
432-
if (path) source_label = realpath(path, NULL);
465+
if (path) source_label = realpath(path, NULL);
433466
#endif
434-
if (!source_label && path) source_label = strdup(path);
467+
if (!source_label && path) source_label = strdup(path);
435468

436-
FILE* f = fopen(path, "rb");
469+
FILE* f = fopen(path, "rb");
437470
if (!f) {
438471
fprintf(stderr, "Failed to open '%s'\n", path);
439472
extensions_shutdown();
@@ -462,6 +495,7 @@ int main(int argc, char** argv) {
462495
size_t r = fread(src, 1, (size_t)sz, f);
463496
src[r] = '\0';
464497
fclose(f);
498+
}
465499

466500
Lexer lex;
467501
lexer_init(&lex, src, source_label);
@@ -472,6 +506,7 @@ int main(int argc, char** argv) {
472506
Stmt* program = parser_parse(&parser);
473507
if (parser.had_error) {
474508
free(src);
509+
if (source_text) free(source_text);
475510
extensions_shutdown();
476511
builtins_reset_dynamic();
477512
return PREFIX_ERROR_SYNTAX;
@@ -503,13 +538,15 @@ int main(int argc, char** argv) {
503538
if (res.error) free(res.error);
504539
free(src);
505540
if (source_label) free(source_label);
541+
if (source_text) free(source_text);
506542
extensions_shutdown();
507543
builtins_reset_dynamic();
508544
return PREFIX_ERROR_RUNTIME;
509545
}
510546

511547
free(src);
512548
if (source_label) free(source_label);
549+
if (source_text) free(source_text);
513550
extensions_shutdown();
514551
builtins_reset_dynamic();
515552
return PREFIX_SUCCESS;

0 commit comments

Comments
 (0)