shithub: moonfish

Download patch

ref: 38a3f2070fac030b3073f196b9b52b075426ae0a
parent: e0cf64b0632f1b8f7a359c35beb09d992c9cee96
author: zamfofex <zamfofex@twdb.moe>
date: Sat Oct 26 14:00:46 EDT 2024

improve error messages

--- a/tools/analyse.c
+++ b/tools/analyse.c
@@ -29,7 +29,6 @@
 	struct moonfish_ply plies[256];
 	int i, count;
 	pthread_mutex_t *mutex;
-	char *argv0;
 	int x, y;
 	FILE *in, *out;
 	char *fen;
@@ -372,7 +371,7 @@
 				
 				arg = strtok_r(NULL, "\r\n\t ", &buffer);
 				if (arg == NULL || moonfish_int(arg, &ply.depth) || ply.depth < 0) {
-					fprintf(stderr, "%s: malformed 'depth' in 'info' command\n", fancy->argv0);
+					fprintf(stderr, "malformed 'depth' in 'info' command\n");
 					exit(1);
 				}
 				
@@ -383,7 +382,7 @@
 				
 				arg = strtok_r(NULL, "\r\n\t ", &buffer);
 				if (arg == NULL || moonfish_int(arg, &pv) || pv <= 0) {
-					fprintf(stderr, "%s: malformed 'multipv' in 'info' command\n", fancy->argv0);
+					fprintf(stderr, "malformed 'multipv' in 'info' command\n");
 					exit(1);
 				}
 				
@@ -401,7 +400,7 @@
 					arg = strtok_r(NULL, "\r\n\t ", &buffer);
 					if (arg == NULL) break;
 					if (moonfish_from_uci(&ply.chess, &move, arg)) {
-						fprintf(stderr, "%s: invalid move: %s\n", fancy->argv0, arg);
+						fprintf(stderr, "invalid move: '%s'\n", arg);
 						exit(1);
 					}
 					if (i == 0 && pv == 1) {
@@ -431,17 +430,17 @@
 				
 				arg = strtok_r(NULL, "\r\n\t ", &buffer);
 				if (arg == NULL || moonfish_int(arg, &ply.white) || ply.white < 0) {
-					fprintf(stderr, "%s: malformed 'wdl' win in 'info' command\n", fancy->argv0);
+					fprintf(stderr, "malformed 'wdl' win in 'info' command\n");
 					exit(1);
 				}
 				arg = strtok_r(NULL, "\r\n\t ", &buffer);
 				if (arg == NULL || moonfish_int(arg, &ply.draw) || ply.draw < 0) {
-					fprintf(stderr, "%s: malformed 'wdl' draw in 'info' command\n", fancy->argv0);
+					fprintf(stderr, "malformed 'wdl' draw in 'info' command\n");
 					exit(1);
 				}
 				arg = strtok_r(NULL, "\r\n\t ", &buffer);
 				if (arg == NULL || moonfish_int(arg, &ply.black) || ply.black < 0) {
-					fprintf(stderr, "%s: malformed 'wdl' loss in 'info' command\n", fancy->argv0);
+					fprintf(stderr, "malformed 'wdl' loss in 'info' command\n");
 					exit(1);
 				}
 				
@@ -462,7 +461,7 @@
 				
 				arg = strtok_r(NULL, "\r\n\t ", &buffer);
 				if (arg == NULL || moonfish_int(arg, &fancy->taken) || fancy->taken < 0) {
-					fprintf(stderr, "%s: malformed 'time' in 'info' command\n", fancy->argv0);
+					fprintf(stderr, "malformed 'time' in 'info' command\n");
 					exit(1);
 				}
 				
@@ -479,7 +478,7 @@
 				
 				arg = strtok_r(NULL, "\r\n\t ", &buffer);
 				if (arg == NULL || moonfish_int(arg, &score)) {
-					fprintf(stderr, "%s: malformed 'cp' in 'info score' command\n", fancy->argv0);
+					fprintf(stderr, "malformed 'cp' in 'info score' command\n");
 					exit(1);
 				}
 				
@@ -505,7 +504,7 @@
 				
 				arg = strtok_r(NULL, "\r\n\t ", &buffer);
 				if (arg == NULL || moonfish_int(arg, &score)) {
-					fprintf(stderr, "%s: malformed 'mate' in 'info score' command\n", fancy->argv0);
+					fprintf(stderr, "malformed 'mate' in 'info score' command\n");
 					exit(1);
 				}
 				
@@ -759,11 +758,10 @@
 	
 	fancy = malloc(sizeof *fancy);
 	if (fancy == NULL) {
-		perror(argv[0]);
+		perror("malloc");
 		return 1;
 	}
 	
-	fancy->argv0 = argv[0];
 	fancy->mutex = &mutex;
 	fancy->offset = 0;
 	fancy->pv[0] = 0;
@@ -798,7 +796,7 @@
 	if (args[0].value != NULL) {
 		fancy->fen = args[0].value;
 		if (moonfish_from_fen(&fancy->plies[0].chess, fancy->fen)) {
-			fprintf(stderr, "%s: invalid FEN\n", argv[0]);
+			moonfish_usage(args, format, argv[0]);
 		}
 	}
 	
@@ -806,7 +804,7 @@
 		
 		file = fopen(args[1].value, "r");
 		if (file == NULL) {
-			perror(argv[0]);
+			perror("fopen");
 			return 1;
 		}
 		
@@ -825,7 +823,7 @@
 		
 		fancy->fen = malloc(128);
 		if (fancy->fen == NULL) {
-			perror(argv[0]);
+			perror("malloc");
 			return 1;
 		}
 		
@@ -836,7 +834,7 @@
 	/* configure the terminal for displaying the user interface */
 	
 	if (tcgetattr(0, &moonfish_termios)) {
-		perror(argv[0]);
+		perror("tcgetattr");
 		return 1;
 	}
 	
@@ -850,7 +848,7 @@
 	action.sa_flags = 0;
 	
 	if (sigaction(SIGTERM, &action, NULL) || sigaction(SIGINT, &action, NULL) || sigaction(SIGQUIT, &action, NULL)) {
-		perror(argv[0]);
+		perror("sigaction");
 		return 1;
 	}
 	
@@ -858,7 +856,7 @@
 	termios.c_lflag &= ~(ECHO | ICANON);
 	
 	if (tcsetattr(0, TCSANOW, &termios)) {
-		perror(argv[0]);
+		perror("tcsetattr");
 		return 1;
 	}
 	
@@ -901,7 +899,7 @@
 	
 	error = pthread_create(&thread, NULL, &moonfish_start, fancy);
 	if (error) {
-		fprintf(stderr, "%s: %s\n", fancy->argv0, strerror(error));
+		fprintf(stderr, "pthread_create: %s\n", strerror(error));
 		return 1;
 	}
 	
@@ -1027,7 +1025,7 @@
 		if (ch0 == 0x20 && y1 == 8 && x1 >= 21 && x1 <= 40) {
 			if (fancy->plies[fancy->i].best[0] != 0) {
 				if (moonfish_from_uci(&fancy->plies[fancy->i].chess, &move, fancy->plies[fancy->i].best)) {
-					fprintf(stderr, "%s: invalid best move: %s\n", fancy->argv0, fancy->plies[fancy->i].best);
+					fprintf(stderr, "invalid best move: %s\n", fancy->plies[fancy->i].best);
 					return 1;
 				}
 				moonfish_play(fancy, &move);
--- a/tools/chat.c
+++ b/tools/chat.c
@@ -8,7 +8,7 @@
 #include "tools.h"
 #include "https.h"
 
-static void moonfish_parse_chat(char *argv0, char *line, char ***command, int *count)
+static void moonfish_parse_chat(char *line, char ***command, int *count)
 {
 	int length;
 	
@@ -34,7 +34,7 @@
 		if (*line == ':') {
 			(*command)[*count] = strdup(line + 1);
 			if ((*command)[*count] == NULL) {
-				perror(argv0);
+				perror("strdup");
 				exit(1);
 			}
 			(*count)++;
@@ -44,11 +44,11 @@
 		length = 0;
 		while (line[length] != ' ' && line[length] != 0) length++;
 		(*command)[*count] = strndup(line, length);
-		line += length;
 		if ((*command)[*count] == NULL) {
-			perror(argv0);
+			perror("strndup");
 			exit(1);
 		}
+		line += length;
 		
 		while (*line == ' ') line++;
 		(*count)++;
@@ -63,7 +63,7 @@
 	free(command);
 }
 
-static void moonfish_read_chat(char *argv0, struct tls *tls, char *username, char **channel, char **message)
+static void moonfish_read_chat(struct tls *tls, char *username, char **channel, char **message)
 {
 	static int under_count = 0;
 	
@@ -74,13 +74,13 @@
 	
 	for (;;) {
 		
-		line = moonfish_read_line(argv0, tls);
+		line = moonfish_read_line(tls);
 		if (line == NULL) {
-			fprintf(stderr, "%s: IRC connection closed unexpectedly\n", argv0);
+			fprintf(stderr, "IRC connection closed unexpectedly\n");
 			exit(1);
 		}
 		
-		moonfish_parse_chat(argv0, line, &command, &count);
+		moonfish_parse_chat(line, &command, &count);
 		free(line);
 		
 		if (count == 0) continue;
@@ -92,14 +92,14 @@
 			under_count++;
 			
 			if (under_count > 16) {
-				fprintf(stderr, "%s: Tried too many nicknames\n", argv0);
+				fprintf(stderr, "tried too many nicknames\n");
 				exit(1);
 			}
 			
-			moonfish_write_text(argv0, tls, "NICK ");
-			moonfish_write_text(argv0, tls, username);
-			for (i = 0 ; i < under_count ; i++) moonfish_write_text(argv0, tls, "_");
-			moonfish_write_text(argv0, tls, "\r\n");
+			moonfish_write_text(tls, "NICK ");
+			moonfish_write_text(tls, username);
+			for (i = 0 ; i < under_count ; i++) moonfish_write_text(tls, "_");
+			moonfish_write_text(tls, "\r\n");
 			
 			continue;
 		}
@@ -108,13 +108,13 @@
 			
 			if (count < 2) {
 				moonfish_free_chat(command, count);
-				moonfish_write_text(argv0, tls, "PONG\r\n");
+				moonfish_write_text(tls, "PONG\r\n");
 				continue;
 			}
 			
-			moonfish_write_text(argv0, tls, "PONG ");
-			moonfish_write_text(argv0, tls, command[1]);
-			moonfish_write_text(argv0, tls, "\r\n");
+			moonfish_write_text(tls, "PONG ");
+			moonfish_write_text(tls, command[1]);
+			moonfish_write_text(tls, "\r\n");
 			moonfish_free_chat(command, count);
 			continue;
 		}
@@ -122,19 +122,19 @@
 		if (!strcmp(command[0], "PRIVMSG")) {
 			
 			if (count < 3) {
-				fprintf(stderr, "%s: Invalid IRC message\n", argv0);
+				fprintf(stderr, "malformed IRC message\n");
 				exit(1);
 			}
 			
 			*channel = strdup(command[1]);
 			if (*channel == NULL) {
-				perror(argv0);
+				perror("strdup");
 				exit(1);
 			}
 			
 			*message = strdup(command[2]);
 			if (*message == NULL) {
-				perror(argv0);
+				perror("strdup");
 				exit(1);
 			}
 			
@@ -146,7 +146,7 @@
 	}
 }
 
-static void moonfish_chat(char *argv0, char **command, char **options, char *host, char *port, char *username, char *channels)
+static void moonfish_chat(char **command, char **options, char *host, char *port, char *username, char *channels)
 {
 	struct tls *tls;
 	char *channel;
@@ -179,31 +179,31 @@
 	
 	fprintf(in, "ucinewgame\n");
 	
-	tls = moonfish_connect(argv0, host, port);
+	tls = moonfish_connect(host, port);
 	
 	/* todo: validate password */
 	password = getenv("moonfish_chat_password");
 	if (password != NULL && *password != 0) {
-		moonfish_write_text(argv0, tls, "PASS ");
-		moonfish_write_text(argv0, tls, password);
-		moonfish_write_text(argv0, tls, "\r\n");
+		moonfish_write_text(tls, "PASS ");
+		moonfish_write_text(tls, password);
+		moonfish_write_text(tls, "\r\n");
 	}
 	
-	moonfish_write_text(argv0, tls, "USER ");
-	moonfish_write_text(argv0, tls, username);
-	moonfish_write_text(argv0, tls, " 0 * ");
-	moonfish_write_text(argv0, tls, username);
-	moonfish_write_text(argv0, tls, "\r\nNICK ");
-	moonfish_write_text(argv0, tls, username);
-	moonfish_write_text(argv0, tls, "\r\n");
+	moonfish_write_text(tls, "USER ");
+	moonfish_write_text(tls, username);
+	moonfish_write_text(tls, " 0 * ");
+	moonfish_write_text(tls, username);
+	moonfish_write_text(tls, "\r\nNICK ");
+	moonfish_write_text(tls, username);
+	moonfish_write_text(tls, "\r\n");
 	
-	moonfish_write_text(argv0, tls, "JOIN ");
-	moonfish_write_text(argv0, tls, channels);
-	moonfish_write_text(argv0, tls, "\r\n");
+	moonfish_write_text(tls, "JOIN ");
+	moonfish_write_text(tls, channels);
+	moonfish_write_text(tls, "\r\n");
 	
 	names = strdup("");
 	if (names == NULL) {
-		perror(argv0);
+		perror("strdup");
 		exit(1);
 	}
 	
@@ -215,7 +215,7 @@
 		if (channel != NULL) free(channel);
 		if (message != NULL) free(message);
 		
-		moonfish_read_chat(argv0, tls, username, &channel, &message);
+		moonfish_read_chat(tls, username, &channel, &message);
 		
 		if (!strcmp(message, "!chess reset")) {
 			
@@ -222,9 +222,9 @@
 			moonfish_chess(&chess);
 			fprintf(in, "ucinewgame\n");
 			
-			moonfish_write_text(argv0, tls, "PRIVMSG ");
-			moonfish_write_text(argv0, tls, channel);
-			moonfish_write_text(argv0, tls, " :The board has been reset.\r\n");
+			moonfish_write_text(tls, "PRIVMSG ");
+			moonfish_write_text(tls, channel);
+			moonfish_write_text(tls, " :The board has been reset.\r\n");
 			
 			continue;
 		}
@@ -243,15 +243,15 @@
 			for (i = 0 ; fen[i] != 0 ; i++) {
 				if (fen[i] == ' ') fen[i] = '_';
 			}
-			moonfish_write_text(argv0, tls, "PRIVMSG ");
-			moonfish_write_text(argv0, tls, channel);
-			moonfish_write_text(argv0, tls, " :https://lichess.org/export/fen.gif?fen=");
-			moonfish_write_text(argv0, tls, fen);
-			moonfish_write_text(argv0, tls, "\r\n");
+			moonfish_write_text(tls, "PRIVMSG ");
+			moonfish_write_text(tls, channel);
+			moonfish_write_text(tls, " :https://lichess.org/export/fen.gif?fen=");
+			moonfish_write_text(tls, fen);
+			moonfish_write_text(tls, "\r\n");
 			
-			moonfish_write_text(argv0, tls, "PRIVMSG ");
-			moonfish_write_text(argv0, tls, channel);
-			moonfish_write_text(argv0, tls, " :Game over!\r\n");
+			moonfish_write_text(tls, "PRIVMSG ");
+			moonfish_write_text(tls, channel);
+			moonfish_write_text(tls, " :Game over!\r\n");
 			
 			continue;
 		}
@@ -258,7 +258,7 @@
 		
 		names = realloc(names, strlen(names) + strlen(name) + 2);
 		if (names == NULL) {
-			perror(argv0);
+			perror("realloc");
 			exit(1);
 		}
 		
@@ -267,9 +267,7 @@
 		
 		fprintf(in, "isready\n");
 		moonfish_wait(out, "readyok");
-		fprintf(in, "position startpos moves");
-		fprintf(in, names);
-		fprintf(in, "\n");
+		fprintf(in, "position startpos moves%s\n", names);
 		
 		fprintf(in, "isready\n");
 		moonfish_wait(out, "readyok");
@@ -278,7 +276,7 @@
 		name0 = moonfish_wait(out, "bestmove");
 		names = realloc(names, strlen(names) + strlen(name0) + 2);
 		if (names == NULL) {
-			perror(argv0);
+			perror("realloc");
 			exit(1);
 		}
 		
@@ -286,7 +284,7 @@
 		strcat(names, name0);
 		
 		if (moonfish_from_uci(&chess, &move, name0)) {
-			fprintf(stderr, "%s: invalid move '%s' by the bot\n", argv0, name0);
+			fprintf(stderr, "malformed move '%s' by the bot\n", name0);
 			exit(1);
 		}
 		
@@ -297,26 +295,27 @@
 		for (i = 0 ; fen[i] != 0 ; i++) {
 			if (fen[i] == ' ') fen[i] = '_';
 		}
-		moonfish_write_text(argv0, tls, "PRIVMSG ");
-		moonfish_write_text(argv0, tls, channel);
-		moonfish_write_text(argv0, tls, " :");
-		moonfish_write_text(argv0, tls, name);
-		moonfish_write_text(argv0, tls, "\r\n");
 		
-		moonfish_write_text(argv0, tls, "PRIVMSG ");
-		moonfish_write_text(argv0, tls, channel);
-		moonfish_write_text(argv0, tls, " :https://lichess.org/export/fen.gif?fen=");
-		moonfish_write_text(argv0, tls, fen);
-		moonfish_write_text(argv0, tls, "\r\n");
+		moonfish_write_text(tls, "PRIVMSG ");
+		moonfish_write_text(tls, channel);
+		moonfish_write_text(tls, " :");
+		moonfish_write_text(tls, name);
+		moonfish_write_text(tls, "\r\n");
 		
+		moonfish_write_text(tls, "PRIVMSG ");
+		moonfish_write_text(tls, channel);
+		moonfish_write_text(tls, " :https://lichess.org/export/fen.gif?fen=");
+		moonfish_write_text(tls, fen);
+		moonfish_write_text(tls, "\r\n");
+		
 		if (moonfish_finished(&chess)) {
 			
 			moonfish_chess(&chess);
 			fprintf(in, "ucinewgame\n");
 			
-			moonfish_write_text(argv0, tls, "PRIVMSG ");
-			moonfish_write_text(argv0, tls, channel);
-			moonfish_write_text(argv0, tls, " :Game over!\r\n");
+			moonfish_write_text(tls, "PRIVMSG ");
+			moonfish_write_text(tls, channel);
+			moonfish_write_text(tls, " :Game over!\r\n");
 		}
 	}
 }
@@ -346,8 +345,6 @@
 	}
 	
 	if (!strcmp(*command, "--")) command++;
-	
-	moonfish_chat(argv[0], command, options, args[0].value, args[1].value, args[2].value, args[3].value);
-	fprintf(stderr, "%s: unreachable\n", argv[0]);
+	moonfish_chat(command, options, args[0].value, args[1].value, args[2].value, args[3].value);
 	return 1;
 }
--- a/tools/https.c
+++ b/tools/https.c
@@ -7,7 +7,7 @@
 
 #include "https.h"
 
-int moonfish_read(char *argv0, struct tls *tls, void *data0, size_t length)
+int moonfish_read(struct tls *tls, void *data0, size_t length)
 {
 	char *data;
 	ssize_t result;
@@ -20,7 +20,7 @@
 		if (result == 0) return 1;
 		if (result == TLS_WANT_POLLIN || result == TLS_WANT_POLLOUT) continue;
 		if (result == -1) {
-			fprintf(stderr, "%s: %s\n", argv0, tls_error(tls));
+			fprintf(stderr, "%s\n", tls_error(tls));
 			exit(1);
 		}
 		
@@ -31,7 +31,7 @@
 	return 0;
 }
 
-int moonfish_write(char *argv0, struct tls *tls, void *data0, size_t length)
+int moonfish_write(struct tls *tls, void *data0, size_t length)
 {
 	char *data;
 	ssize_t result;
@@ -44,7 +44,7 @@
 		if (result == 0) return 1;
 		if (result == TLS_WANT_POLLIN || result == TLS_WANT_POLLOUT) continue;
 		if (result == -1) {
-			fprintf(stderr, "%s: %s\n", argv0, tls_error(tls));
+			fprintf(stderr, "%s\n", tls_error(tls));
 			exit(1);
 		}
 		
@@ -55,12 +55,12 @@
 	return 0;
 }
 
-int moonfish_write_text(char *argv0, struct tls *tls, char *text)
+int moonfish_write_text(struct tls *tls, char *text)
 {
-	return moonfish_write(argv0, tls, text, strlen(text));
+	return moonfish_write(tls, text, strlen(text));
 }
 
-char *moonfish_read_line(char *argv0, struct tls *tls)
+char *moonfish_read_line(struct tls *tls)
 {
 	char *line;
 	size_t length;
@@ -72,11 +72,11 @@
 		
 		line = realloc(line, length + 1);
 		if (line == NULL) {
-			perror(argv0);
+			perror("realloc");
 			exit(1);
 		}
 		
-		if (moonfish_read(argv0, tls, line + length, 1)) {
+		if (moonfish_read(tls, line + length, 1)) {
 			if (length == 0) {
 				free(line);
 				return NULL;
@@ -92,42 +92,42 @@
 	}
 }
 
-void moonfish_request(char *argv0, struct tls *tls, char *host, char *request, char *token, char *type, int length)
+void moonfish_request(struct tls *tls, char *host, char *request, char *token, char *type, int length)
 {
 	char length_string[64];
 	
-	moonfish_write_text(argv0, tls, request);
-	moonfish_write_text(argv0, tls, " HTTP/1.0\r\n");
+	moonfish_write_text(tls, request);
+	moonfish_write_text(tls, " HTTP/1.0\r\n");
 	
 	if (token != NULL) {
-		moonfish_write_text(argv0, tls, "Authorization: Bearer ");
-		moonfish_write_text(argv0, tls, token);
-		moonfish_write_text(argv0, tls, "\r\n");
+		moonfish_write_text(tls, "Authorization: Bearer ");
+		moonfish_write_text(tls, token);
+		moonfish_write_text(tls, "\r\n");
 	}
 	
-	moonfish_write_text(argv0, tls, "Connection: close\r\n");
+	moonfish_write_text(tls, "Connection: close\r\n");
 	
-	moonfish_write_text(argv0, tls, "Host: ");
-	moonfish_write_text(argv0, tls, host);
-	moonfish_write_text(argv0, tls, "\r\n");
+	moonfish_write_text(tls, "Host: ");
+	moonfish_write_text(tls, host);
+	moonfish_write_text(tls, "\r\n");
 	
 	if (type != NULL) {
 		
-		moonfish_write_text(argv0, tls, "Content-Type: ");
-		moonfish_write_text(argv0, tls, type);
-		moonfish_write_text(argv0, tls, "\r\n");
+		moonfish_write_text(tls, "Content-Type: ");
+		moonfish_write_text(tls, type);
+		moonfish_write_text(tls, "\r\n");
 		
 		sprintf(length_string, "%d", length);
 		
-		moonfish_write_text(argv0, tls, "Content-Length: ");
-		moonfish_write_text(argv0, tls, length_string);
-		moonfish_write_text(argv0, tls, "\r\n");
+		moonfish_write_text(tls, "Content-Length: ");
+		moonfish_write_text(tls, length_string);
+		moonfish_write_text(tls, "\r\n");
 	}
 	
-	moonfish_write_text(argv0, tls, "User-Agent: moonfish/0\r\n\r\n");
+	moonfish_write_text(tls, "User-Agent: moonfish/0\r\n\r\n");
 }
 
-int moonfish_response(char *argv0, struct tls *tls)
+int moonfish_response(struct tls *tls)
 {
 	static char success0[] = "HTTP/1.0 2";
 	static char success1[] = "HTTP/1.1 2";
@@ -134,14 +134,15 @@
 	
 	char *line;
 	
-	line = moonfish_read_line(argv0, tls);
+	line = moonfish_read_line(tls);
 	
 	if (strncmp(line, success0, sizeof success0 - 1) && strncmp(line, success1, sizeof success1 - 1)) {
 		return 1;
 	}
+	
 	for (;;) {
 		free(line);
-		line = moonfish_read_line(argv0, tls);
+		line = moonfish_read_line(tls);
 		if (*line == 0) {
 			free(line);
 			break;
@@ -151,18 +152,18 @@
 	return 0;
 }
 
-struct tls *moonfish_connect(char *argv0, char *host, char *port)
+struct tls *moonfish_connect(char *host, char *port)
 {
 	struct tls *tls;
 	
 	tls = tls_client();
 	if (tls == NULL) {
-		fprintf(stderr, "%s: Could not create libtls client\n", argv0);
+		fprintf(stderr, "could not create libtls client\n");
 		exit(1);
 	}
 	
 	if (tls_connect(tls, host, port)) {
-		fprintf(stderr, "%s: %s\n", argv0, tls_error(tls));
+		fprintf(stderr, "%s\n", tls_error(tls));
 		exit(1);
 	}
 	
@@ -169,10 +170,10 @@
 	return tls;
 }
 
-void moonfish_close(char *argv0, struct tls *tls)
+void moonfish_close(struct tls *tls)
 {
 	if (tls_close(tls)) {
-		fprintf(stderr, "%s: %s\n", argv0, tls_error(tls));
+		fprintf(stderr, "%s\n", tls_error(tls));
 		exit(1);
 	}
 	
@@ -179,20 +180,20 @@
 	tls_free(tls);
 }
 
-int moonfish_basic_request(char *argv0, char *host, char *port, char *request, char *token, char *type, char *body)
+int moonfish_basic_request(char *host, char *port, char *request, char *token, char *type, char *body)
 {
 	int status;
 	struct tls *tls;
 	
-	tls = moonfish_connect(argv0, host, port);
+	tls = moonfish_connect(host, port);
 	
 	if (type == NULL && body != NULL) type = "application/x-www-form-urlencoded";
 	
-	moonfish_request(argv0, tls, host, token, request, type, body == NULL ? 0 : strlen(body));
+	moonfish_request(tls, host, token, request, type, body == NULL ? 0 : strlen(body));
 	
-	if (body != NULL) moonfish_write_text(argv0, tls, body);
+	if (body != NULL) moonfish_write_text(tls, body);
 	
-	status = moonfish_response(argv0, tls);
-	moonfish_close(argv0, tls);
+	status = moonfish_response(tls);
+	moonfish_close(tls);
 	return status;
 }
--- a/tools/https.h
+++ b/tools/https.h
@@ -3,12 +3,12 @@
 
 #include <tls.h>
 
-int moonfish_read(char *argv0, struct tls *tls, void *data, size_t length);
-int moonfish_write(char *argv0, struct tls *tls, void *data, size_t length);
-int moonfish_write_text(char *argv0, struct tls *tls, char *text);
-char *moonfish_read_line(char *argv0, struct tls *tls);
-void moonfish_request(char *argv0, struct tls *tls, char *host, char *request, char *token, char *type, int length);
-int moonfish_response(char *argv0, struct tls *tls);
-int moonfish_basic_request(char *argv0, char *host, char *port, char *request, char *token, char *type, char *body);
-struct tls *moonfish_connect(char *argv0, char *host, char *port);
-void moonfish_close(char *argv0, struct tls *tls);
+int moonfish_read(struct tls *tls, void *data, size_t length);
+int moonfish_write(struct tls *tls, void *data, size_t length);
+int moonfish_write_text(struct tls *tls, char *text);
+char *moonfish_read_line(struct tls *tls);
+void moonfish_request(struct tls *tls, char *host, char *request, char *token, char *type, int length);
+int moonfish_response(struct tls *tls);
+int moonfish_basic_request(char *host, char *port, char *request, char *token, char *type, char *body);
+struct tls *moonfish_connect(char *host, char *port);
+void moonfish_close(struct tls *tls);
--- a/tools/learn.c
+++ b/tools/learn.c
@@ -10,16 +10,15 @@
 
 #define moonfish_count 192
 
-static double moonfish_next_line(char *argv0, char *line, FILE *file)
+static double moonfish_next_line(char *line, FILE *file)
 {
 	char *arg, *end;
 	double score;
 	
-	errno = 0;
 	if (fgets(line, 2048, file) == NULL) {
 		
-		if (errno) {
-			perror(argv0);
+		if (!feof(stdin)) {
+			perror("fgets");
 			exit(1);
 		}
 		
@@ -26,7 +25,7 @@
 		errno = 0;
 		rewind(file);
 		if (errno) {
-			perror(argv0);
+			perror("rewind");
 			exit(1);
 		}
 	}
@@ -33,7 +32,7 @@
 	
 	arg = strrchr(line, ' ');
 	if (arg == NULL) {
-		fprintf(stderr, "%s: improper FEN line\n", argv0);
+		fprintf(stderr, "malformed FEN line\n");
 		exit(1);
 	}
 	
@@ -40,7 +39,7 @@
 	errno = 0;
 	score = strtod(arg + 1, &end);
 	if (errno || (*end != 0 && *end != '\n') || score > 10000 || score < -10000) {
-		fprintf(stderr, "%s: unexpected score\n", argv0);
+		fprintf(stderr, "unexpected score\n");
 		exit(1);
 	}
 	
@@ -71,7 +70,7 @@
 	return error;
 }
 
-static double moonfish_step(char *argv0, FILE *file, double *gradient)
+static double moonfish_step(FILE *file, double *gradient)
 {
 	static char line[2048];
 	
@@ -84,7 +83,7 @@
 	for (i = 0 ; i < moonfish_count ; i++) gradient[i] = 0;
 	
 	for (i = 0 ; i < 2048 ; i++) {
-		score = moonfish_next_line(argv0, line, file);
+		score = moonfish_next_line(line, file);
 		error += moonfish_gradient(gradient, score, line);
 	}
 	
@@ -109,17 +108,10 @@
 	
 	file = fopen(argv[1], "r");
 	if (file == NULL) {
-		perror(argv[0]);
+		perror("fopen");
 		return 1;
 	}
 	
-	errno = 0;
-	rewind(file);
-	if (errno) {
-		perror(argv[0]);
-		return 1;
-	}
-	
 	iteration = 0;
 	
 	for (;;) {
@@ -127,7 +119,7 @@
 		iteration++;
 		if (iteration > 0x1000) return 0;
 		
-		error = moonfish_step(argv[0], file, gradient);
+		error = moonfish_step(file, gradient);
 		
 		printf("\n");
 		for (i = 0 ; i < moonfish_count ; i++) printf("%.0f,", moonfish_values[i]);
--- a/tools/lichess.c
+++ b/tools/lichess.c
@@ -14,7 +14,6 @@
 #include "https.h"
 
 struct moonfish_game {
-	char *argv0;
 	char *host;
 	char *port;
 	char *token;
@@ -24,9 +23,9 @@
 	char fen[512];
 };
 
-static void moonfish_json_error(char *argv0)
+static void moonfish_json_error(void)
 {
-	fprintf(stderr, "%s: malformed JSON\n", argv0);
+	fprintf(stderr, "malformed JSON\n");
 	exit(1);
 }
 
@@ -74,7 +73,7 @@
 			root = NULL;
 		}
 		
-		line = moonfish_read_line(game->argv0, tls);
+		line = moonfish_read_line(tls);
 		if (line == NULL) break;
 		
 		pthread_mutex_lock(&moonfish_mutex);
@@ -86,13 +85,13 @@
 		
 		end = NULL;
 		root = cJSON_ParseWithOpts(line, &end, 1);
-		if (end != line + strlen(line)) moonfish_json_error(game->argv0);
+		if (end != line + strlen(line)) moonfish_json_error();
 		free(line);
 		
-		if (!cJSON_IsObject(root)) moonfish_json_error(game->argv0);
+		if (!cJSON_IsObject(root)) moonfish_json_error();
 		
 		type = cJSON_GetObjectItem(root, "type");
-		if (!cJSON_IsString(type)) moonfish_json_error(game->argv0);
+		if (!cJSON_IsString(type)) moonfish_json_error();
 		
 		state = NULL;
 		
@@ -101,21 +100,21 @@
 		if (!strcmp(type->valuestring, "gameFull")) {
 			
 			state = cJSON_GetObjectItem(root, "state");
-			if (!cJSON_IsObject(state)) moonfish_json_error(game->argv0);
+			if (!cJSON_IsObject(state)) moonfish_json_error();
 			
 			white = 0;
 			
 			white_player = cJSON_GetObjectItem(root, "white");
-			if (!cJSON_IsObject(white_player)) moonfish_json_error(game->argv0);
+			if (!cJSON_IsObject(white_player)) moonfish_json_error();
 			
 			id = cJSON_GetObjectItem(white_player, "id");
 			if (id != NULL && !cJSON_IsNull(id)) {
-				if (!cJSON_IsString(id)) moonfish_json_error(game->argv0);
+				if (!cJSON_IsString(id)) moonfish_json_error();
 				if (!strcmp(id->valuestring, game->username)) white = 1;
 			}
 			
 			fen = cJSON_GetObjectItem(root, "initialFen");
-			if (!cJSON_IsString(fen)) moonfish_json_error(game->argv0);
+			if (!cJSON_IsString(fen)) moonfish_json_error();
 			
 			if (strcmp(fen->valuestring, "startpos")) {
 				strcpy(game->fen, "fen ");
@@ -130,12 +129,12 @@
 		if (state == NULL) continue;
 		
 		if (white == -1) {
-			fprintf(stderr, "%s: 'gameState' event received prior to 'gameFull' event\n", game->argv0);
+			fprintf(stderr, "received 'gameState' event prior to 'gameFull' event\n");
 			exit(1);
 		}
 		
 		moves = cJSON_GetObjectItem(state, "moves");
-		if (!cJSON_IsString(moves)) moonfish_json_error(game->argv0);
+		if (!cJSON_IsString(moves)) moonfish_json_error();
 		
 		count = 0;
 		if (moves->valuestring[0] != 0) {
@@ -156,10 +155,10 @@
 		winc = cJSON_GetObjectItem(state, "winc");
 		binc = cJSON_GetObjectItem(state, "binc");
 		
-		if (!cJSON_IsNumber(wtime)) moonfish_json_error(game->argv0);
-		if (!cJSON_IsNumber(btime)) moonfish_json_error(game->argv0);
-		if (!cJSON_IsNumber(winc)) moonfish_json_error(game->argv0);
-		if (!cJSON_IsNumber(binc)) moonfish_json_error(game->argv0);
+		if (!cJSON_IsNumber(wtime)) moonfish_json_error();
+		if (!cJSON_IsNumber(btime)) moonfish_json_error();
+		if (!cJSON_IsNumber(winc)) moonfish_json_error();
+		if (!cJSON_IsNumber(binc)) moonfish_json_error();
 		
 		fprintf(in, "isready\n");
 		moonfish_wait(out, "readyok");
@@ -178,7 +177,7 @@
 				for (;;) {
 					
 					if (moonfish_from_uci(&chess, &move, name)) {
-						fprintf(stderr, "%s: invalid move '%s' from the bot\n", game->argv0, name);
+						fprintf(stderr, "malformed move '%s' from the bot\n", name);
 						exit(1);
 					}
 					
@@ -207,7 +206,7 @@
 		
 		name = moonfish_wait(out, "bestmove");
 		if (name == NULL) {
-			fprintf(stderr, "%s: could not find 'bestmove' command\n", game->argv0);
+			fprintf(stderr, "could not find 'bestmove' command\n");
 			exit(1);
 		}
 		
@@ -223,17 +222,17 @@
 			}
 			
 			if (moonfish_from_uci(&chess, &move, name)) {
-				fprintf(stderr, "%s: invalid move '%s' from the bot\n", game->argv0, name);
+				fprintf(stderr, "malformed move '%s' from the bot\n", name);
 				exit(1);
 			}
 		}
 		
 		snprintf(request, sizeof request, "POST /api/bot/game/%s/move/%s", game->id, name);
-		if (moonfish_basic_request(game->argv0, game->host, game->port, game->token, request, NULL, NULL)) {
-			fprintf(stderr, "%s: could not make move '%s' in game '%s'\n", game->argv0, name, game->id);
+		if (moonfish_basic_request(game->host, game->port, game->token, request, NULL, NULL)) {
+			fprintf(stderr, "could not make move '%s' in game '%s'\n", name, game->id);
 			snprintf(request, sizeof request, "POST /api/bot/game/%s/resign", game->id);
-			if (moonfish_basic_request(game->argv0, game->host, game->port, game->token, request, NULL, NULL)) {
-				fprintf(stderr, "%s: could not resign game '%s'\n", game->argv0, game->id);
+			if (moonfish_basic_request(game->host, game->port, game->token, request, NULL, NULL)) {
+				fprintf(stderr, "could not resign game '%s'\n", game->id);
 			}
 			break;
 		}
@@ -258,25 +257,25 @@
 	game = data;
 	
 	moonfish_spawn(game->argv, &in, &out, NULL);
-	tls = moonfish_connect(game->argv0, game->host, game->port);
+	tls = moonfish_connect(game->host, game->port);
 	
 	snprintf(request, sizeof request, "GET /api/bot/game/stream/%s", game->id);
 	
-	moonfish_request(game->argv0, tls, game->host, request, game->token, NULL, 0);
+	moonfish_request(tls, game->host, request, game->token, NULL, 0);
 	
-	if (moonfish_response(game->argv0, tls)) {
-		fprintf(stderr, "%s: could not request game event stream\n", game->argv0);
+	if (moonfish_response(tls)) {
+		fprintf(stderr, "could not request game event stream\n");
 		exit(1);
 	}
 	
 	moonfish_handle_game_events(tls, game, in, out);
 	
-	moonfish_close(game->argv0, tls);
+	moonfish_close(tls);
 	free(game);
 	return NULL;
 }
 
-static void moonfish_handle_events(struct tls *tls, char *argv0, char *host, char *port, char *token, char **argv, char *username)
+static void moonfish_handle_events(struct tls *tls, char *host, char *port, char *token, char **argv, char *username)
 {
 	char request[2048];
 	char *line;
@@ -297,9 +296,9 @@
 			root = NULL;
 		}
 		
-		line = moonfish_read_line(argv0, tls);
+		line = moonfish_read_line(tls);
 		if (line == NULL) {
-			fprintf(stderr, "%s: connection with Lichess closed\n", argv0);
+			fprintf(stderr, "connection with Lichess closed\n");
 			exit(1);
 		}
 		
@@ -310,34 +309,33 @@
 		
 		end = NULL;
 		root = cJSON_ParseWithOpts(line, &end, 1);
-		if (end != line + strlen(line)) moonfish_json_error(argv0);
+		if (end != line + strlen(line)) moonfish_json_error();
 		free(line);
 		
-		if (!cJSON_IsObject(root)) moonfish_json_error(argv0);
+		if (!cJSON_IsObject(root)) moonfish_json_error();
 		
 		type = cJSON_GetObjectItem(root, "type");
-		if (!cJSON_IsString(type)) moonfish_json_error(argv0);
+		if (!cJSON_IsString(type)) moonfish_json_error();
 		
 		if (!strcmp(type->valuestring, "gameStart")) {
 			
 			challenge = cJSON_GetObjectItem(root, "game");
-			if (!cJSON_IsObject(challenge)) moonfish_json_error(argv0);
+			if (!cJSON_IsObject(challenge)) moonfish_json_error();
 			
 			id = cJSON_GetObjectItem(challenge, "id");
-			if (!cJSON_IsString(id)) moonfish_json_error(argv0);
+			if (!cJSON_IsString(id)) moonfish_json_error();
 			
 			game = malloc(sizeof *game);
 			if (game == NULL) {
-				fprintf(stderr, "%s: could not allocate game\n", argv0);
+				perror("malloc");
 				exit(1);
 			}
 			
 			if (strlen(id->valuestring) > sizeof game->id - 1) {
-				fprintf(stderr, "%s: game ID '%s' too long\n", argv0, id->valuestring);
+				fprintf(stderr, "game ID '%s' too long\n", id->valuestring);
 				exit(1);
 			}
 			
-			game->argv0 = argv0;
 			game->host = host;
 			game->port = port;
 			game->token = token;
@@ -347,7 +345,7 @@
 			
 			error = pthread_create(&thread, NULL, &moonfish_handle_game, game);
 			if (error) {
-				fprintf(stderr, "%s: %s\n", argv0, strerror(error));
+				fprintf(stderr, "pthread_create: %s\n", strerror(error));
 				exit(1);
 			}
 			
@@ -357,21 +355,21 @@
 		if (strcmp(type->valuestring, "challenge")) continue;
 		
 		challenge = cJSON_GetObjectItem(root, "challenge");
-		if (!cJSON_IsObject(challenge)) moonfish_json_error(argv0);
+		if (!cJSON_IsObject(challenge)) moonfish_json_error();
 		
 		id = cJSON_GetObjectItem(challenge, "id");
-		if (!cJSON_IsString(id)) moonfish_json_error(argv0);
+		if (!cJSON_IsString(id)) moonfish_json_error();
 		
 		variant = cJSON_GetObjectItem(challenge, "variant");
-		if (!cJSON_IsObject(variant)) moonfish_json_error(argv0);
+		if (!cJSON_IsObject(variant)) moonfish_json_error();
 		
 		variant = cJSON_GetObjectItem(variant, "key");
-		if (!cJSON_IsString(variant)) moonfish_json_error(argv0);
+		if (!cJSON_IsString(variant)) moonfish_json_error();
 		
 		if (!strcmp(variant->valuestring, "fromPosition")) {
 			
 			fen = cJSON_GetObjectItem(challenge, "initialFen");
-			if (!cJSON_IsString(fen)) moonfish_json_error(argv0);
+			if (!cJSON_IsString(fen)) moonfish_json_error();
 			
 			invalid = moonfish_from_fen(&chess, fen->valuestring);
 			
@@ -384,8 +382,8 @@
 			
 			if (invalid) {
 				snprintf(request, sizeof request, "POST /api/challenge/%s/decline", id->valuestring);
-				if (moonfish_basic_request(argv0, host, port, token, request, NULL, "reason=standard")) {
-					fprintf(stderr, "%s: could not decline challenge '%s' (chess 960 FEN)\n", argv0, id->valuestring);
+				if (moonfish_basic_request(host, port, token, request, NULL, "reason=standard")) {
+					fprintf(stderr, "could not decline challenge '%s' (chess 960 FEN)\n", id->valuestring);
 				}
 				continue;
 			}
@@ -393,31 +391,31 @@
 		
 		if (strcmp(variant->valuestring, "standard")) {
 			snprintf(request, sizeof request, "POST /api/challenge/%s/decline", id->valuestring);
-			if (moonfish_basic_request(argv0, host, port, token, request, NULL, "reason=standard")) {
-				fprintf(stderr, "%s: could not decline challenge '%s' (variant)\n", argv0, id->valuestring);
+			if (moonfish_basic_request(host, port, token, request, NULL, "reason=standard")) {
+				fprintf(stderr, "could not decline challenge '%s' (variant)\n", id->valuestring);
 			}
 			continue;
 		}
 		
 		speed = cJSON_GetObjectItem(challenge, "speed");
-		if (!cJSON_IsString(speed)) moonfish_json_error(argv0);
+		if (!cJSON_IsString(speed)) moonfish_json_error();
 		
 		if (!strcmp(speed->valuestring, "correspondence")) {
 			snprintf(request, sizeof request, "POST /api/challenge/%s/decline", id->valuestring);
-			if (moonfish_basic_request(argv0, host, port, token, request, NULL, "reason=tooSlow")) {
-				fprintf(stderr, "%s: could not decline challenge '%s' (too slow)\n", argv0, id->valuestring);
+			if (moonfish_basic_request(host, port, token, request, NULL, "reason=tooSlow")) {
+				fprintf(stderr, "could not decline challenge '%s' (too slow)\n", id->valuestring);
 			}
 			continue;
 		}
 		
 		snprintf(request, sizeof request, "POST /api/challenge/%s/accept", id->valuestring);
-		if (moonfish_basic_request(argv0, host, port, token, request, NULL, NULL)) {
-			fprintf(stderr, "%s: could not accept challenge '%s'\n", argv0, id->valuestring);
+		if (moonfish_basic_request(host, port, token, request, NULL, NULL)) {
+			fprintf(stderr, "could not accept challenge '%s'\n", id->valuestring);
 		}
 	}
 }
 
-static char *moonfish_username(char *argv0, char *host, char *port, char *token)
+static char *moonfish_username(char *host, char *port, char *token)
 {
 	char *line;
 	char *username;
@@ -425,34 +423,34 @@
 	cJSON *root, *id;
 	struct tls *tls;
 	
-	tls = moonfish_connect(argv0, host, port);
+	tls = moonfish_connect(host, port);
 	
-	moonfish_request(argv0, tls, host, "GET /api/account", token, NULL, 0);
+	moonfish_request(tls, host, "GET /api/account", token, NULL, 0);
 	
-	if (moonfish_response(argv0, tls)) {
-		fprintf(stderr, "%s: could not request the Lichess username\n", argv0);
+	if (moonfish_response(tls)) {
+		fprintf(stderr, "could not request the Lichess account information\n");
 		exit(1);
 	}
 	
-	line = moonfish_read_line(argv0, tls);
+	line = moonfish_read_line(tls);
 	
 	end = NULL;
 	root = cJSON_ParseWithOpts(line, &end, 1);
-	if (end != line + strlen(line)) moonfish_json_error(argv0);
+	if (end != line + strlen(line)) moonfish_json_error();
 	free(line);
 	
-	if (!cJSON_IsObject(root)) moonfish_json_error(argv0);
+	if (!cJSON_IsObject(root)) moonfish_json_error();
 	
 	id = cJSON_GetObjectItem(root, "id");
-	if (!cJSON_IsString(id)) moonfish_json_error(argv0);
+	if (!cJSON_IsString(id)) moonfish_json_error();
 	
 	username = strdup(id->valuestring);
 	if (username == NULL) {
-		perror(argv0);
+		perror("strdup");
 		exit(1);
 	}
 	
-	moonfish_close(argv0, tls);
+	moonfish_close(tls);
 	
 	return username;
 }
@@ -506,20 +504,18 @@
 	action.sa_flags = 0;
 	
 	if (sigaction(SIGCHLD, &action, NULL)) {
-		perror(argv[0]);
+		perror("sigaction");
 		return 1;
 	}
 	
-	tls = moonfish_connect(argv[0], args[0].value, args[1].value);
-	moonfish_request(argv[0], tls, args[0].value, "GET /api/stream/event", token, NULL, 0);
-	if (moonfish_response(argv[0], tls)) {
-		fprintf(stderr, "%s: could not request event stream\n", argv[0]);
+	tls = moonfish_connect(args[0].value, args[1].value);
+	moonfish_request(tls, args[0].value, "GET /api/stream/event", token, NULL, 0);
+	if (moonfish_response(tls)) {
+		fprintf(stderr, "could not request event stream\n");
 		return 1;
 	}
 	
-	username = moonfish_username(argv[0], args[0].value, args[1].value, token);
-	moonfish_handle_events(tls, argv[0], args[0].value, args[1].value, token, command, username);
-	
-	fprintf(stderr, "%s: Unreachable\n", argv[0]);
+	username = moonfish_username(args[0].value, args[1].value, token);
+	moonfish_handle_events(tls, args[0].value, args[1].value, token, command, username);
 	return 1;
 }
--- a/tools/perft.c
+++ b/tools/perft.c
@@ -2,7 +2,6 @@
 /* copyright 2024 zamfofex */
 
 #include <stdio.h>
-#include <errno.h>
 #include <stdlib.h>
 
 #include "../moonfish.h"
--