diff ringtools/imy/firstpass.c @ 882:fd4c9bc7835d

fc-imy2pwt program written, compiles
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 03 Apr 2022 03:30:27 +0000
parents
children 0d6814238109
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ringtools/imy/firstpass.c	Sun Apr 03 03:30:27 2022 +0000
@@ -0,0 +1,118 @@
+/*
+ * This module implements the first pass of fc-imy2pwt processing:
+ * reading and parsing the iMelody input file at the level of lines,
+ * storing the melody for subsequent processing and catching the
+ * optional BEAT: line, if present.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "sizelimits.h"
+
+extern char *imy_filename;
+extern char melody_str_buf[MELODY_BUF_SIZE];
+extern unsigned beats_per_min;
+
+static char *melody_write_ptr, *melody_write_endp;
+static int lineno;
+
+static void
+copy_melody_str(line)
+	char *line;
+{
+	char *cp, *np;
+
+	cp = line;
+	while (isspace(*cp))
+		cp++;
+	if (!*cp) {
+		fprintf(stderr, "%s line %d: empty melody line\n",
+			imy_filename, lineno);
+		exit(1);
+	}
+	for (np = cp; *cp && !isspace(*cp); cp++)
+		;
+	if (*cp)
+		*cp++ = '\0';
+	while (isspace(*cp))
+		cp++;
+	if (*cp) {
+		fprintf(stderr, "%s line %d: single melody string expected\n",
+			imy_filename, lineno);
+		exit(1);
+	}
+	if (strlen(np) > (melody_write_endp - melody_write_ptr)) {
+		fprintf(stderr, "%s line %d: melody buffer size exceeded\n",
+			imy_filename, lineno);
+		exit(1);
+	}
+	strcpy(melody_write_ptr, np);
+	melody_write_ptr += strlen(np);
+}
+
+static void
+process_beat_line(line)
+	char *line;
+{
+	if (!isdigit(*line)) {
+		fprintf(stderr, "%s line %d: number expected on BEAT: line\n",
+			imy_filename, lineno);
+		exit(1);
+	}
+	beats_per_min = atoi(line);
+	if (beats_per_min < 25 || beats_per_min > 900) {
+		fprintf(stderr, "%s line %d: bpm number is out of range\n",
+			imy_filename, lineno);
+		exit(1);
+	}
+}
+
+read_imy_firstpass()
+{
+	FILE *inf;
+	char linebuf[LINE_BUF_SIZE];
+	int prev_line_is_melody;
+
+	inf = fopen(imy_filename, "r");
+	if (!inf) {
+		perror(imy_filename);
+		exit(1);
+	}
+	melody_write_ptr = melody_str_buf;
+	melody_write_endp = melody_str_buf + MELODY_BUF_SIZE - 1;
+	for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) {
+		if (!index(linebuf, '\n')) {
+			fprintf(stderr,
+				"%s line %d: too long or unterminated\n",
+				imy_filename, lineno);
+			exit(1);
+		}
+		if (linebuf[0] == ' ' || linebuf[0] == '\t') {
+			if (lineno == 1) {
+				fprintf(stderr,
+					"%s line 1: invalid continuation\n",
+					imy_filename);
+				exit(1);
+			}
+			if (prev_line_is_melody)
+				copy_melody_str(linebuf);
+			continue;
+		}
+		if (!strncasecmp(linebuf, "MELODY:", 7)) {
+			copy_melody_str(linebuf + 7);
+			prev_line_is_melody = 1;
+		} else if (!strncasecmp(linebuf, "BEAT:", 5)) {
+			process_beat_line(linebuf + 5);
+			prev_line_is_melody = 0;
+		} else
+			prev_line_is_melody = 0;
+	}
+	fclose(inf);
+	if (!melody_str_buf[0]) {
+		fprintf(stderr, "error: no melody found in %s\n", imy_filename);
+		exit(1);
+	}
+}