FreeCalypso > hg > freecalypso-tools
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); + } +}