comparison ringtools/imy/convert.c @ 887:3e398f9c31a0

fc-imy2pwt: overhaul melody error handling, report position
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 03 Apr 2022 04:17:08 +0000
parents fd4c9bc7835d
children
comparison
equal deleted inserted replaced
886:0d6814238109 887:3e398f9c31a0
17 17
18 static char *pwt_note_names[12] = {"c", "cs", "d", "ds", "e", "f", "fs", 18 static char *pwt_note_names[12] = {"c", "cs", "d", "ds", "e", "f", "fs",
19 "g", "gs", "a", "as", "b"}; 19 "g", "gs", "a", "as", "b"};
20 20
21 static void 21 static void
22 process_octave_cmd(octchar) 22 melody_error(cp, msg)
23 { 23 char *cp, *msg;
24 if (!isdigit(octchar)) { 24 {
25 fprintf(stderr, 25 unsigned pos;
26 "melody error: '*' octave prefix not followed by digit\n"); 26
27 exit(1); 27 pos = cp - melody_str_buf;
28 } 28 fprintf(stderr, "melody error at offset %u: %s\n", pos, msg);
29 cur_octave = octchar - '0'; 29 exit(1);
30 }
31
32 static void
33 process_octave_cmd(cp)
34 char *cp;
35 {
36 if (!isdigit(cp[1]))
37 melody_error(cp, "'*' octave prefix not followed by digit");
38 cur_octave = cp[1] - '0';
30 } 39 }
31 40
32 static int 41 static int
33 process_note(str, type) 42 process_note(str, type)
34 char *str; 43 char *str;
56 break; 65 break;
57 case 'b': 66 case 'b':
58 note = 11; 67 note = 11;
59 break; 68 break;
60 default: 69 default:
61 fprintf(stderr, 70 melody_error(str, "note letter expected after '&' or '#'");
62 "melody error: note letter expected after '&' or '#'\n");
63 exit(1);
64 } 71 }
65 switch (type) { 72 switch (type) {
66 case 1: 73 case 1:
67 if (note == 0 || note == 5) { 74 if (note == 0 || note == 5)
68 fprintf(stderr, "melody error: invalid flat note\n"); 75 melody_error(str, "invalid flat note");
69 exit(1);
70 }
71 note--; 76 note--;
72 break; 77 break;
73 case 2: 78 case 2:
74 if (note == 4 || note == 11) { 79 if (note == 4 || note == 11)
75 fprintf(stderr, "melody error: invalid sharp note\n"); 80 melody_error(str, "invalid sharp note");
76 exit(1);
77 }
78 note++; 81 note++;
79 break; 82 break;
80 } 83 }
81 if (str[1] < '0' || str[1] > '5') { 84 if (str[1] < '0' || str[1] > '5')
82 fprintf(stderr, 85 melody_error(str, "missing expected note duration digit");
83 "melody error: missing expected note duration digit\n");
84 exit(1);
85 }
86 dur_basic = str[1] - '0'; 86 dur_basic = str[1] - '0';
87 switch (str[2]) { 87 switch (str[2]) {
88 case '.': 88 case '.':
89 dur_mod = 1; 89 dur_mod = 1;
90 break; 90 break;
110 process_rest(str) 110 process_rest(str)
111 char *str; 111 char *str;
112 { 112 {
113 int dur_basic, dur_mod; 113 int dur_basic, dur_mod;
114 114
115 if (str[1] < '0' || str[1] > '5') { 115 if (str[1] < '0' || str[1] > '5')
116 fprintf(stderr, 116 melody_error(str, "missing expected rest duration digit");
117 "melody error: missing expected rest duration digit\n");
118 exit(1);
119 }
120 dur_basic = str[1] - '0'; 117 dur_basic = str[1] - '0';
121 switch (str[2]) { 118 switch (str[2]) {
122 case '.': 119 case '.':
123 dur_mod = 1; 120 dur_mod = 1;
124 break; 121 break;
172 continue; 169 continue;
173 } 170 }
174 /* real stuff */ 171 /* real stuff */
175 switch (*cp) { 172 switch (*cp) {
176 case '*': 173 case '*':
177 process_octave_cmd(cp[1]); 174 process_octave_cmd(cp);
178 cp += 2; 175 cp += 2;
179 continue; 176 continue;
180 case 'c': 177 case 'c':
181 case 'd': 178 case 'd':
182 case 'e': 179 case 'e':
202 cp++; 199 cp++;
203 if (*cp == '+' || *cp == '-') { 200 if (*cp == '+' || *cp == '-') {
204 cp++; 201 cp++;
205 continue; 202 continue;
206 } 203 }
207 if (!isdigit(*cp)) { 204 if (!isdigit(*cp))
208 fprintf(stderr, 205 melody_error(cp, "invalid character after 'V'");
209 "melody error: invalid character after 'V'\n");
210 exit(1);
211 }
212 if (*cp == '1' && cp[1] >= '0' && cp[1] <= '5') 206 if (*cp == '1' && cp[1] >= '0' && cp[1] <= '5')
213 cp += 2; 207 cp += 2;
214 else 208 else
215 cp++; 209 cp++;
216 continue; 210 continue;
217 case '(': 211 case '(':
218 if (repeat_start_ptr) { 212 if (repeat_start_ptr)
219 fprintf(stderr, 213 melody_error(cp, "nested repeat");
220 "melody error: nested repeat\n");
221 exit(1);
222 }
223 cp++; 214 cp++;
224 repeat_start_ptr = cp; 215 repeat_start_ptr = cp;
225 repeat_start_octave = cur_octave; 216 repeat_start_octave = cur_octave;
226 repeat_count = 0; 217 repeat_count = 0;
227 continue; 218 continue;
228 case '@': 219 case '@':
229 if (!repeat_start_ptr) { 220 if (!repeat_start_ptr)
230 fprintf(stderr, 221 melody_error(cp, "'@' not in repeat block");
231 "melody error: '@' not in repeat block\n"); 222 cp++;
232 exit(1); 223 if (!isdigit(*cp))
233 } 224 melody_error(cp, "'@' not followed by digit");
234 cp++;
235 if (!isdigit(*cp)) {
236 fprintf(stderr,
237 "melody error: '@' not followed by digit\n");
238 exit(1);
239 }
240 rpt_set = *cp - '0'; 225 rpt_set = *cp - '0';
241 if (!rpt_set) { 226 if (!rpt_set)
242 fprintf(stderr, 227 melody_error(cp,
243 "melody error: infinite repeat not supported\n"); 228 "infinite repeat not supported");
244 exit(1);
245 }
246 cp++; 229 cp++;
247 if (!repeat_count) 230 if (!repeat_count)
248 repeat_count = rpt_set; 231 repeat_count = rpt_set;
249 continue; 232 continue;
250 case ')': 233 case ')':
251 if (!repeat_start_ptr) { 234 if (!repeat_start_ptr)
252 fprintf(stderr, 235 melody_error(cp, "')' without opening '('");
253 "melody error: ')' without opening '('\n"); 236 if (!repeat_count)
254 exit(1); 237 melody_error(cp, "repeat block without count");
255 }
256 if (!repeat_count) {
257 fprintf(stderr,
258 "melody error: repeat block without count\n");
259 exit(1);
260 }
261 repeat_count--; 238 repeat_count--;
262 if (repeat_count) { 239 if (repeat_count) {
263 cp = repeat_start_ptr; 240 cp = repeat_start_ptr;
264 cur_octave = repeat_start_octave; 241 cur_octave = repeat_start_octave;
265 } else { 242 } else {
266 cp++; 243 cp++;
267 repeat_start_ptr = 0; 244 repeat_start_ptr = 0;
268 } 245 }
269 continue; 246 continue;
270 default: 247 default:
271 fprintf(stderr, 248 melody_error(cp, "non-understood character");
272 "melody error: non-understood character\n"); 249 }
273 exit(1); 250 }
274 } 251 }
275 }
276 }