From f5fd3e2a07010db793827f4f9840d6c401f02257 Mon Sep 17 00:00:00 2001
From: David Phillips <david@sighup.nz>
Date: Mon, 29 Jul 2019 21:17:07 +1200
Subject: Misc tidy up of assembler sources

---
 assembler.c | 47 +++++++++++++++++++++++++++++++++++------------
 lex.c       | 17 ++++++++++++++---
 parse.c     |  2 +-
 3 files changed, 50 insertions(+), 16 deletions(-)

diff --git a/assembler.c b/assembler.c
index 142870f..685fcf6 100644
--- a/assembler.c
+++ b/assembler.c
@@ -1,54 +1,77 @@
 #include <stdio.h>
 #include <stdint.h>
+#include <string.h>
 
 #include "lex.h"
 #include "parse.h"
 #include "instruction.h"
 #include "output.h"
 
+void print_help(const char *argv0)
+{
+	fprintf(stderr, "Syntax: %s <in.asm> <out.bin>\n", argv0);
+}
+
 int main(int argc, char **argv)
 {
+	int error_ret = 1;
 	int ret = 0;
+	const char *path_in = NULL;
+	const char *path_out = NULL;
 	FILE *fin = NULL;
 	FILE *fout = NULL;
 
 	if (argc < 3) {
-		fprintf(stderr, "Syntax: %s <in.asm> <out.bin>\n", argv[0]);
+		print_help(argv[0]);
 		return 1;
 	}
 
-	if ((fin = fopen(argv[1], "r")) == NULL) {
-		fprintf(stderr, "Error opening %s: ", argv[1]);
+	if (strcmp(argv[1], "-q") == 0) {
+		if (argc != 4) {
+			print_help(argv[0]);
+			return 0;
+		}
+		error_ret = 0;
+		path_in = argv[2];
+		path_out = argv[3];
+	} else {
+		path_in = argv[1];
+		path_out = argv[2];
+	}
+
+
+	if ((fin = fopen(path_in, "r")) == NULL) {
+		fprintf(stderr, "Error opening %s: ", path_in);
 		perror("fopen");
-		return 1;
+		return error_ret;
 	}
 
-	if ((fout = fopen(argv[2], "wb")) == NULL) {
-		fprintf(stderr, "Error opening %s: ", argv[2]);
+	if ((fout = fopen(path_out, "wb")) == NULL) {
+		fprintf(stderr, "Error opening %s: ", path_out);
 		perror("fopen");
-		return 1;
+		return error_ret;
 	}
 /****/
 	struct token *tokens = NULL;
 	size_t tok_count = 0;
 
-	if ((tokens = lex(argv[1], fin, &tok_count)) == NULL)
-		return 2;
+	if ((tokens = lex(path_in, fin, &tok_count)) == NULL)
+		return error_ret;
 
 	/* FIXME package these things into `tok_result`, `parse_result` etc */
 	struct instruction *insts;
 	size_t insts_count;
 	struct label *labels;
 	size_t labels_count;
-	if (ret = parse(argv[1], fin, &labels, &labels_count, tokens, tok_count, &insts, &insts_count))
-		return ret;
+	if (ret = parse(path_in, fin, &labels, &labels_count, tokens, tok_count, &insts, &insts_count))
+		return error_ret && ret;
 
 	/* FIXME insert pass for sanity checking identifiers, sizes of values */
 
 	/* FIXME insert optional pass for optimisation */
 
 	if (ret = output(fout, labels, labels_count, insts, insts_count))
-		return ret;
+		return error_ret && ret;
 
 	return 0;
 }
diff --git a/lex.c b/lex.c
index 8bc6640..7294fbb 100644
--- a/lex.c
+++ b/lex.c
@@ -1,15 +1,14 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdarg.h>
 #include <string.h>
 #include <ctype.h>
 
 #include "lex.h"
 #include "util.h"
 
-#define emit(...) fprintf(stderr, "%s at (%zd,%zd): ", filename, 1 + line, 1 + column);\
-                  fprintf(stderr, __VA_ARGS__)
-
 static const char *filename = NULL;
+static FILE *fd;
 static size_t line;
 static size_t column;
 static int context_comment;
@@ -17,6 +16,16 @@ static struct token* tokens;
 static size_t tokens_count;
 static char buffer[1024]; /* XXX limitation: sources must have lines < 1024 bytes */
 
+static void emit(const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+	fprintf(stderr, "%s at (%zd,%zd): ", filename, 1 + line, 1 + column);
+	vfprintf(stderr, fmt, args);
+	indicate_file_area(fd, 1 + line, 1 + column, 1);
+	va_end(args);
+}
+
 static int expect(const char c) {
 	if (buffer[column] != c) {
 		emit("Expected '%c', got '%c'\n", c, buffer[column]);
@@ -324,6 +333,7 @@ int lex_line(void) {
 					return add_token(tok);
 				} else {
 					emit("Unexpected '/'\n");
+					return 1;
 				}
 				break;
 			case ',':
@@ -365,6 +375,7 @@ int lex_line(void) {
 struct token* lex(const char *filename_local, FILE *fin, size_t *len)
 {
 	filename = filename_local;
+	fd = fin;
 	line = 0;
 	tokens = NULL;
 	tokens_count = 0;
diff --git a/parse.c b/parse.c
index 5159753..5da5b61 100644
--- a/parse.c
+++ b/parse.c
@@ -23,7 +23,7 @@ static struct instruction *insts;
 static size_t insts_count;
 static size_t byte_offset;
 
-void emit(const char *fmt, ...)
+static void emit(const char *fmt, ...)
 {
 	va_list args;
 	va_start(args, fmt);
-- 
cgit v1.1