aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lexer.l13
-rw-r--r--src/main.c48
-rw-r--r--src/parser.y5
-rw-r--r--src/pinocchio.h5
4 files changed, 61 insertions, 10 deletions
diff --git a/src/lexer.l b/src/lexer.l
index 3bbfd12..ed8d599 100644
--- a/src/lexer.l
+++ b/src/lexer.l
@@ -1,13 +1,18 @@
%option noinput
%option nounput
%option noyywrap
+%option yylineno
%{
#include <err.h>
+#include <stdlib.h>
#include "parser.h"
+#include "pinocchio.h"
#define YY_USER_ACTION yylloc.first_line = yylloc.last_line = yylineno;
+
+extern const char *current_file;
%}
%%
@@ -20,7 +25,7 @@
\<=>|⇔ { return EQUIV; }
\( { return OPAR; }
\) { return CPAR; }
-\n { return EOL; } /* Only eat one NL for better interactive usage */
+\n { return EOL; }
[a-zA-Z] {
yylval.ch = *yytext;
return IDENT;
@@ -28,7 +33,9 @@
[ \t]+ ;
- /* TODO: Swap ‘-’ for name of the input file */
-. { errx(1, "%s:%d: Unrecognized character ‘%c’", "-", yylineno, *yytext); }
+. {
+ user_error("%s:%d: Unrecognized character ‘%c’",
+ current_file, yylineno, *yytext);
+}
%%
diff --git a/src/main.c b/src/main.c
index 1457c75..8cd8468 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2,11 +2,13 @@
#include <err.h>
#include <langinfo.h>
#include <locale.h>
+#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include "lexer.h"
#include "parser.h"
@@ -17,7 +19,10 @@
# define __has_builtin(x) (0)
#endif
-static bool utf8;
+static int rv;
+static bool interactive, utf8;
+
+const char *current_file;
static bool eqnsolve(eqn_t *, uint64_t, uint64_t);
static int eqnprint(eqn_t *);
@@ -41,11 +46,31 @@ main(int argc, char **argv)
{
setlocale(LC_ALL, "");
utf8 = strcmp(nl_langinfo(CODESET), "UTF-8") == 0;
- if (argc > 1) {
- if ((yyin = fopen(argv[1], "r")) == NULL)
- err(1, "fopen: %s", argv[1]);
+ interactive = isatty(STDIN_FILENO);
+
+ if (argc == 1) {
+ current_file = "-";
+ for (;;) {
+ int ret = yyparse();
+ if (ret == 0)
+ break;
+ rv = EXIT_FAILURE;
+ }
+ } else for (int i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-") == 0)
+ yyin = stdin;
+ else if ((yyin = fopen(argv[i], "r")) == NULL) {
+ warn("fopen: %s", argv[1]);
+ rv = EXIT_FAILURE;
+ continue;
+ }
+
+ current_file = argv[1];
+ yyparse();
+ fclose(yyin);
}
- return yyparse();
+
+ return rv;
}
void
@@ -204,3 +229,16 @@ eqnfree(eqn_t *e)
}
free(e);
}
+
+void
+user_error(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vwarnx(fmt, ap);
+ va_end(ap);
+ if (interactive)
+ rv = EXIT_FAILURE;
+ else
+ exit(EXIT_FAILURE);
+}
diff --git a/src/parser.y b/src/parser.y
index ae31d16..503c2e4 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -10,6 +10,8 @@
static ast_t astmerge(int, ast_t, ast_t);
static void *xmalloc(size_t);
static void yyerror(const char *);
+
+extern const char *current_file;
%}
%code requires {
@@ -105,6 +107,5 @@ xmalloc(size_t n)
void
yyerror(const char *s)
{
- /* TODO: Get filename */
- errx(1, "-:%d: %s\n", yylloc.first_line, s);
+ user_error("%s:%d: %s", current_file, yylloc.first_line, s);
}
diff --git a/src/pinocchio.h b/src/pinocchio.h
index 0c19def..fb74f3c 100644
--- a/src/pinocchio.h
+++ b/src/pinocchio.h
@@ -20,5 +20,10 @@ typedef struct {
} ast_t;
void astprocess(ast_t);
+void user_error(const char *, ...)
+#if __GNUC__
+ __attribute__((format(printf, 1, 2)))
+#endif
+ ;
#endif /* !PINOCCIO_H */