# HG changeset patch # User Mychaela Falconia # Date 1648959428 0 # Node ID 3e398f9c31a0383096d490b5dd222752ae1aea27 # Parent 0d681423810967e843be678c818222507dd04d93 fc-imy2pwt: overhaul melody error handling, report position diff -r 0d6814238109 -r 3e398f9c31a0 ringtools/imy/convert.c --- a/ringtools/imy/convert.c Sun Apr 03 04:00:09 2022 +0000 +++ b/ringtools/imy/convert.c Sun Apr 03 04:17:08 2022 +0000 @@ -19,14 +19,23 @@ "g", "gs", "a", "as", "b"}; static void -process_octave_cmd(octchar) +melody_error(cp, msg) + char *cp, *msg; { - if (!isdigit(octchar)) { - fprintf(stderr, - "melody error: '*' octave prefix not followed by digit\n"); - exit(1); - } - cur_octave = octchar - '0'; + unsigned pos; + + pos = cp - melody_str_buf; + fprintf(stderr, "melody error at offset %u: %s\n", pos, msg); + exit(1); +} + +static void +process_octave_cmd(cp) + char *cp; +{ + if (!isdigit(cp[1])) + melody_error(cp, "'*' octave prefix not followed by digit"); + cur_octave = cp[1] - '0'; } static int @@ -58,31 +67,22 @@ note = 11; break; default: - fprintf(stderr, - "melody error: note letter expected after '&' or '#'\n"); - exit(1); + melody_error(str, "note letter expected after '&' or '#'"); } switch (type) { case 1: - if (note == 0 || note == 5) { - fprintf(stderr, "melody error: invalid flat note\n"); - exit(1); - } + if (note == 0 || note == 5) + melody_error(str, "invalid flat note"); note--; break; case 2: - if (note == 4 || note == 11) { - fprintf(stderr, "melody error: invalid sharp note\n"); - exit(1); - } + if (note == 4 || note == 11) + melody_error(str, "invalid sharp note"); note++; break; } - if (str[1] < '0' || str[1] > '5') { - fprintf(stderr, - "melody error: missing expected note duration digit\n"); - exit(1); - } + if (str[1] < '0' || str[1] > '5') + melody_error(str, "missing expected note duration digit"); dur_basic = str[1] - '0'; switch (str[2]) { case '.': @@ -112,11 +112,8 @@ { int dur_basic, dur_mod; - if (str[1] < '0' || str[1] > '5') { - fprintf(stderr, - "melody error: missing expected rest duration digit\n"); - exit(1); - } + if (str[1] < '0' || str[1] > '5') + melody_error(str, "missing expected rest duration digit"); dur_basic = str[1] - '0'; switch (str[2]) { case '.': @@ -174,7 +171,7 @@ /* real stuff */ switch (*cp) { case '*': - process_octave_cmd(cp[1]); + process_octave_cmd(cp); cp += 2; continue; case 'c': @@ -204,60 +201,40 @@ cp++; continue; } - if (!isdigit(*cp)) { - fprintf(stderr, - "melody error: invalid character after 'V'\n"); - exit(1); - } + if (!isdigit(*cp)) + melody_error(cp, "invalid character after 'V'"); if (*cp == '1' && cp[1] >= '0' && cp[1] <= '5') cp += 2; else cp++; continue; case '(': - if (repeat_start_ptr) { - fprintf(stderr, - "melody error: nested repeat\n"); - exit(1); - } + if (repeat_start_ptr) + melody_error(cp, "nested repeat"); cp++; repeat_start_ptr = cp; repeat_start_octave = cur_octave; repeat_count = 0; continue; case '@': - if (!repeat_start_ptr) { - fprintf(stderr, - "melody error: '@' not in repeat block\n"); - exit(1); - } + if (!repeat_start_ptr) + melody_error(cp, "'@' not in repeat block"); cp++; - if (!isdigit(*cp)) { - fprintf(stderr, - "melody error: '@' not followed by digit\n"); - exit(1); - } + if (!isdigit(*cp)) + melody_error(cp, "'@' not followed by digit"); rpt_set = *cp - '0'; - if (!rpt_set) { - fprintf(stderr, - "melody error: infinite repeat not supported\n"); - exit(1); - } + if (!rpt_set) + melody_error(cp, + "infinite repeat not supported"); cp++; if (!repeat_count) repeat_count = rpt_set; continue; case ')': - if (!repeat_start_ptr) { - fprintf(stderr, - "melody error: ')' without opening '('\n"); - exit(1); - } - if (!repeat_count) { - fprintf(stderr, - "melody error: repeat block without count\n"); - exit(1); - } + if (!repeat_start_ptr) + melody_error(cp, "')' without opening '('"); + if (!repeat_count) + melody_error(cp, "repeat block without count"); repeat_count--; if (repeat_count) { cp = repeat_start_ptr; @@ -268,9 +245,7 @@ } continue; default: - fprintf(stderr, - "melody error: non-understood character\n"); - exit(1); + melody_error(cp, "non-understood character"); } } }