summaryrefslogtreecommitdiff
path: root/lali.c
diff options
context:
space:
mode:
authorDaniel Cerqueira <dan.git@lispclub.com>2026-08-17 18:36:21 +0100
committerDaniel Cerqueira <dan.git@lispclub.com>2026-08-17 18:36:21 +0100
commitb2db65a84bd8b9d802cd8323fa3fa82aab4d5782 (patch)
treeaa1df731b7561c9ae0f206535e42c0d0dadd12f3 /lali.c
parent916dc69cb429beabc8fe5ff1857d70e423420044 (diff)
use getopt_long() functionality
Diffstat (limited to 'lali.c')
-rw-r--r--lali.c109
1 files changed, 76 insertions, 33 deletions
diff --git a/lali.c b/lali.c
index eaad03e..4ffa35b 100644
--- a/lali.c
+++ b/lali.c
@@ -33,6 +33,7 @@
#include "liblali.h"
+#include <getopt.h>
#define YEARS "2025, 2026"
@@ -85,38 +86,78 @@ void runREPL(int infd, Object **env, GC_PARAM) {
}
int main(int argc, char *argv[]) {
- int options = 0;
- bool repl = false;
- bool close = false;
- bool quiet = false;
-
- if (argc >= 2) {
- if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
- fprintf(stderr, "basic usages:\nnormal: %s [source]...\nclose stdin: %s -c [source]...\nrun repl: %s -r [-q] [source]...\n\nin normal mode, reads from standard input.\nwhen present, load source(s) at startup. can be used as library sources(s).\n", argv[0], argv[0], argv[0]);
- return EXIT_SUCCESS;
- } else if (!strcmp(argv[1], "-c")) {
- options++;
- close = true;
- } else if (!strcmp(argv[1], "-r")) {
- options++;
- repl = true;
- if (argc > 2 && !strcmp(argv[2], "-q")) {
- options++;
- quiet = true;
- }
- } else if (!strcmp(argv[1], "-q")) {
- options++;
- quiet = true;
- if (argc > 2 && !strcmp(argv[2], "-r")) {
- options++;
- repl = true;
- }
- } else if (argv[1][0] == '-') {
- fprintf(stderr, "%s: unrecognized option, `%s'\n", argv[0], argv[1]);
- return EXIT_FAILURE;
- }
+
+ /// Options processing
+
+ int opt_repl = 0; // false
+ int opt_close = 0; // false
+ int opt_quiet = 0; // false
+
+ struct option const longopts[] =
+ {
+ { "repl", no_argument, NULL, 'r' },
+ { "close", no_argument, NULL, 'c' },
+ { "quiet", no_argument, NULL, 'q' },
+ { "help", no_argument, NULL, 'h' },
+ { 0, 0, 0, 0 }
+ };
+
+ char const shortopts[] = "crqh";
+
+ while (true) {
+ int opt = getopt_long(argc, argv, shortopts, longopts, NULL);
+ if (opt < 0)
+ break;
+
+ switch (opt)
+ {
+ case 0:
+ /* If getopt returns 0, then it has already processed a
+ long-named option. We should do nothing. */
+ break;
+
+ case 'h':
+ /* Show help message. */
+ fprintf(stdout, "basic usages:\n\
+normal: %s [file-name]...\n\
+run repl: %s -r|--repl [-q|--quiet] [file-name]...\n\
+close stdin: %s -c|--close [file-name]...\n\
+show help: %s -h|--help\n\
+\n\
+in normal mode, reads from standard input.\n\
+when present, load file-name(s) at startup. can be used as library file-name(s).\n\
+\n\
+you may use unambiguous abbreviations for the long option names.\n",
+ argv[0], argv[0], argv[0], argv[0]);
+ return EXIT_SUCCESS;
+
+ case 'c':
+ /* Close stdin. Useful to just use file-name(s), not stdin. */
+ opt_close = 1; // true
+ break;
+
+ case 'r':
+ /* Enter a REPL. */
+ opt_repl = 1; // true
+ break;
+
+ case 'q':
+ /* Supress copyright message. */
+ opt_quiet = 1; // true
+ break;
+
+ default:
+ fprintf (stderr,
+ "\ttry '%s --help' for a complete list of options.\n",
+ argv[0]);
+ return EXIT_FAILURE;
+ }
}
+ int options = opt_close + opt_repl + opt_quiet;
+
+ /// Lisp setting
+
GC_PARAM = nil;
if (setjmp(exceptionEnv))
@@ -130,6 +171,7 @@ int main(int argc, char *argv[]) {
GC_TRACE(gcEnv, newRootEnv(GC_ROOTS));
+ // File sources processing
int fd = 0;
if (argc > 1) {
@@ -142,18 +184,19 @@ int main(int argc, char *argv[]) {
}
}
- if (repl) {
+ // Main processing
+ if (opt_repl) {
if(!isatty(STDIN_FILENO)) {
fprintf(stderr, "%s: repl does not accept piping\n", argv[0]);
return EXIT_FAILURE;
}
- if (!quiet)
+ if (!opt_quiet)
fprintf(stdout, "lali Copyright (C) %s Daniel Cerqueira\n\nThis is free software: you are free to change and redistribute it,\nunder certain conditions.\nThis program comes with NO WARRANTY, to the extent permitted by law.\n", YEARS);
runREPL(STDIN_FILENO, gcEnv, GC_ROOTS);
}
- else if (!close)
+ else if (!opt_close)
runFile(STDIN_FILENO, gcEnv, GC_ROOTS);
return EXIT_SUCCESS;