From 54a3b903c44c7b9cf6ac21c66f0bc5113e8fe084 Mon Sep 17 00:00:00 2001 From: Seymour Shlien Date: Mon, 12 Oct 2020 07:59:07 -0400 Subject: [PATCH] 2020.10.12 --- abcmatch.c | 2 +- doc/CHANGES | 20 ++++ doc/readme.txt | 8 +- matchsup.c | 1 + parseabc.c | 317 +++++++++++++++++++++++++++++++++++-------------- parseabc.h | 10 ++ store.c | 6 +- structs.h | 1 - toabc.c | 81 ++++--------- yapstree.c | 43 +------ 10 files changed, 288 insertions(+), 201 deletions(-) diff --git a/abcmatch.c b/abcmatch.c index 9785bb9..be41144 100644 --- a/abcmatch.c +++ b/abcmatch.c @@ -49,7 +49,7 @@ Matching: -#define VERSION "1.75 October 01 2020 abcmatch" +#define VERSION "1.75 October 12 2020 abcmatch" #include #include #include diff --git a/doc/CHANGES b/doc/CHANGES index 7aa2105..fca07c6 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -13918,3 +13918,23 @@ and applying an appropriate pitchbend to each of these channels. This may pose a problem for some software which attempts to render the midi file in music notation. + +October 12 2020 +James Allwright has made significant improvements to parseabc.c, toabc.c, +and yapstree.c related to repeat checking. In parseabc.c, new functions +were introduced: init_voice_contexts, reset_parser_status, +interpret_voice_label, check_bar_repeats, and check_and_call_bar(). +The functions isnumberp(), init_voicecode(), and interpret_voicestring() +have been retired. Reset_parser_status() is called each time a new +X: reference field command is encountered. Check_bar_repeats() replaces +a lot of the code that appears in event_bar() defined in toabc.c and +yapstree.c. parsemusic() calls event_bar indirectly through the +function check_and_call_bar(). Minor changes were made to toabc.c, store.c +and yapstree.c to accommodate the changes to parseabc. In particular, +a new flag repcheck is introduced and connected to parseabc.c as +an extern (in parseabc.h). In addition a new struct (voice_context) +has been introduced in parseabc.h. + + + + diff --git a/doc/readme.txt b/doc/readme.txt index 1797946..768f0c7 100644 --- a/doc/readme.txt +++ b/doc/readme.txt @@ -1,10 +1,10 @@ abcMIDI : abc <-> MIDI conversion utilities midi2abc version 3.46 June 22 2020 -abc2midi version 4.42 October 01 2020 -abc2abc version 2.10 October 01 2020 -yaps version 1.80 October 07 2020 -abcmatch version 1.74 October 01 2020 +abc2midi version 4.43 October 12 2020 +abc2abc version 2.11 October 12 2020 +yaps version 1.81 October 12 2020 +abcmatch version 1.75 October 12 2020 midicopy version 1.37 October 10 2020 24th January 2002 diff --git a/matchsup.c b/matchsup.c index 1968ddb..ac61d34 100644 --- a/matchsup.c +++ b/matchsup.c @@ -824,6 +824,7 @@ void event_octave(num, local) /* used internally by other routines when octave=N is encountered */ /* in I: or K: fields */ int num; +int local; { if (dotune) { if (pastheader || local) { diff --git a/parseabc.c b/parseabc.c index 71469c5..72dd4a6 100644 --- a/parseabc.c +++ b/parseabc.c @@ -90,10 +90,12 @@ int chorddecorators[DECSIZE]; char decorations[] = ".MLRH~Tuv'OPS"; /* 2020-05-01 */ char *abbreviation[SIZE_ABBREVIATIONS]; -int voicecodes = 0; -/* [SS] 2015-03-16 allow 24 voices */ -/*char voicecode[16][30]; for interpreting V: string */ -char voicecode[24][30]; /*for interpreting V: string */ +int num_voices = 0; /* [JA] 2020-10-12 */ +int repcheck = 1; /* enables/ disables repeat checking */ +/* abc2midi disables repeat checking because it does its own thing */ +voice_context_t voicecode[MAX_VOICES]; +int voicenum; /* current voice number */ +int has_voice_fields = 0; int decorators_passback[DECSIZE]; /* this global array is linked as an external to store.c and @@ -329,30 +331,6 @@ skiptospace (p) *p = *p + 1; } - -int -isnumberp (p) - char **p; -/* returns 1 if positive number, returns 0 if not a positive number */ -/* ie -4 or 1A both return 0. This function is needed to get the */ -/* voice number. */ -{ - char **c; - c = p; - while (( **c != ' ') && ( **c != TAB) && **c != '\0') - { - if (( **c >= 0) && (**c <= 9)) /*[SDG] 2020-06-03 */ - *c = *c + 1; - else - return 0; - } - return 1; -/* could use isdigit(**c) */ -/* is zero a positive number? is V:0 ok? [SS] */ -} - - - int readnumf (num) char *num; @@ -788,72 +766,137 @@ lcase (s) }; } - -void -init_voicecode () +/* [JA] 2020-10-12 */ +void init_voice_contexts (void) { int i; - for (i = 0; i < 24; i++) /* [SS} 2015-03-15 */ - voicecode[i][0] = 0; - voicecodes = 0; + for (i = 0; i < MAX_VOICES; i++) { /* [SS} 2015-03-15 */ + voicecode[i].label[0] = '\0'; + voicecode[i].expect_repeat = 0; + voicecode[i].repeat_count = 0; + } } +/* [JA] 2020-10-12 */ +/* called at the start of each tune */ +static void reset_parser_status (void) +{ + voicenum = 0; + has_voice_fields = 0; + num_voices = 1; + parserinchord = 0; + ingrace = 0; + slur = 0; + init_voice_contexts (); +} + + void print_voicecodes () { int i; - if (voicecodes == 0) + if (num_voices == 0) return; printf ("voice mapping:\n"); - for (i = 0; i < voicecodes; i++) + for (i = 0; i < num_voices; i++) { if (i % 4 == 3) printf ("\n"); - printf ("%s %d ", voicecode[i], i + 1); + printf ("%s %d ", voicecode[i].label, i + 1); } printf ("\n"); } -int -interpret_voicestring (char *s) -{ -/* if V: is followed by a string instead of a number - * we check to see if we have encountered this string - * before. We assign the number associated with this - * string and add it to voicecode if it was not encountered - * before. If more than 16 distinct strings were encountered - * we report an error -1. +/* [JA] 2020-10-12 */ +int interpret_voice_label (char *s, int num) +/* We expect a numeric value indicating the voice number. + * The assumption is that these will ocuur in the order in which voices + * appear, so that we have V:1, V:2, ... V:N if there are N voices. + * The abc standard 2.2 allows strings instead of these numbers to + * represent voices. + * This function should be called with either + * an empty string and a valid num or + * a valid string and num set to 0. + * + * If num is non-zero, we check that it is valid and return it. + * If the number is one above the number of voices currently in use, + * we allocate a new voice. + * + * If num is zero and the string is not empty, we check if string + * has been assigned to one of the existing voices. If not, we + * allocate a new voice and assign the string to it. + * + * If we exceed MAX_VOICES voices, we report an error. + * + * we return a voice number in the range 1 - num_voices */ +{ int i; char code[32]; - char msg[80]; /* [PHDM] 2012-11-22 */ + char msg[80]; /* [PHDM] 2012-11-22 */ char *c; c = readword (code, s); -/* [PHDM] 2012-11-22 */ - if (*c != '\0' && *c != ' ' && *c != ']') + if (num > 0) + { + if (num > num_voices + 1) { - sprintf (msg, "invalid character `%c' in Voice ID", *c); - event_error (msg); + char error_message[80]; + + snprintf(error_message, 80, "V:%d out of sequence, treating as V:%d", + num, num_voices); + event_warning(error_message); + num = num_voices + 1; } + /* declaring a new voice */ + if (num == num_voices + 1) + { + if (num_voices >= MAX_VOICES) + { + event_warning("Number of available voices exceeded"); + return 1; + } + num_voices = num_voices + 1; + voicecode[num_voices - 1].label[0] = '\0'; + } + return num; + } +/* [PHDM] 2012-11-22 */ + if (*c != '\0' && *c != ' ' && *c != ']') { + sprintf (msg, "invalid character `%c' in Voice ID", *c); + event_error (msg); + } /* [PHDM] 2012-11-22 */ if (code[0] == '\0') - return 0; - if (voicecodes == 0) - { - strcpy (voicecode[voicecodes], code); - voicecodes++; - return voicecodes; + { + event_warning("Empty V: field, treating as V:1"); + return 1; + } + /* Has supplied label been used for one of the existing voices ? */ + if (has_voice_fields) + { + for (i = 0; i < num_voices; i++) { + if (strcmp (code, voicecode[i].label) == 0) { + return i + 1; + } } - for (i = 0; i < voicecodes; i++) - if (stringcmp (code, voicecode[i]) == 0) - return (i + 1); - if ((voicecodes + 1) > 23) /* [SS] 2015-03-16 */ - return -1; - strcpy (voicecode[voicecodes], code); - voicecodes++; - return voicecodes; + } + /* if we have got here, we have a new voice */ + if ((num_voices + 1) > MAX_VOICES) {/* [SS] 2015-03-16 */ + event_warning("Number of available voices exceeded"); + return 1; + } + /* First V: field is a special case. We are already on voice 1, + * so we don't increment the number of voices, but we will set + * status->has_voice_fields on returning from this function. + */ + if (has_voice_fields) + { + num_voices++; + } + strncpy (voicecode[num_voices - 1].label, code, 31); + return num_voices; } /* The following three functions parseclefs, parsetranspose, @@ -1479,22 +1522,14 @@ parsevoice (s) vparams.other[0] = '\0'; /* [SS] 2011-04-18 */ skipspace (&s); - if (isnumberp (&s) == 1) - { - num = readnump (&s); - } - else - { - num = interpret_voicestring (s); - if (num == 0) - event_error ("No voice number or string in V: field"); - if (num == -1) - { - event_error ("More than 16 voices encountered in V: fields"); - num = 0; - } - skiptospace (&s); - }; + num = 0; + if (isdigit(*s)) { /* [JA] 2020-10-12 */ + num = readnump (&s); + } + num = interpret_voice_label (s, num); + has_voice_fields = 1; + skiptospace (&s); + voicenum = num; skipspace (&s); while (*s != '\0') { @@ -2115,9 +2150,14 @@ parsefield (key, field) { event_error ("second X: field in header"); }; + if (inbody) + { + /* [JA] 2020-10-14 */ + event_error ("Missing blank line before new tune"); + } event_refno (x); ignore_line =0; /* [SS] 2017-04-12 */ - init_voicecode (); /* [SS] 2011-01-01 */ + reset_parser_status(); /* [JA] 2020-10-12 */ inhead = 1; inbody = 0; parserinchord = 0; @@ -2376,6 +2416,99 @@ print_inputline () printf ("\n"); } +/* [JA] 2020-10-12 */ +/* Look for problems in the use of repeats */ +static void check_bar_repeats (int bar_type, char *replist) +{ + voice_context_t *cv = &voicecode[voicenum]; + + switch (bar_type) { + case SINGLE_BAR: + break; + case DOUBLE_BAR: + break; + case THIN_THICK: + break; + case THICK_THIN: + break; + case BAR_REP: + if (cv->expect_repeat) { + event_warning ("Expecting repeat, found |:"); + }; + cv->expect_repeat = 1; + cv->repeat_count = cv->repeat_count + 1; + break; + case REP_BAR: + if (!cv->expect_repeat) { + char error_message[80]; + + if (cv->repeat_count == 0) + { + snprintf(error_message, 80, "Missing repeat at start ? Unexpected :|%s found", replist); + event_warning (error_message); + } + else + { + snprintf(error_message, 80, "Unexpected :|%s found", replist); + event_warning (error_message); + } + }; + cv->expect_repeat = 0; + cv->repeat_count = cv->repeat_count + 1; + break; + case BAR1: + if (!cv->expect_repeat) { + if (cv->repeat_count == 0) + { + event_warning ("Missing repeat at start ? found |1"); + } + else + { + event_warning ("found |1 in non-repeat section"); + } + }; + break; + case REP_BAR2: + if (!cv->expect_repeat) { + if (cv->repeat_count == 0) + { + event_warning ("Missing repeat at start ? found :|2"); + } + else + { + event_warning ("No repeat expected, found :|2"); + } + }; + cv->expect_repeat = 0; + cv->repeat_count = cv->repeat_count + 1; + break; + case DOUBLE_REP: + if (!cv->expect_repeat) { + if (cv->repeat_count == 0) + { + event_warning ("Missing repeat at start ? found ::"); + } + else + { + event_warning ("No repeat expected, found ::"); + } + }; + cv->expect_repeat = 1; + cv->repeat_count = cv->repeat_count + 1; + break; + }; +} + +/* [JA] 2020-10-12 */ +static void check_and_call_bar(int bar_type, char *replist) +{ + if (repcheck) + { + check_bar_repeats (bar_type, replist); + } + event_bar (bar_type, replist); +} + void parsemusic (field) char *field; @@ -2459,20 +2592,20 @@ parsemusic (field) switch (*p) { case ':': - event_bar (BAR_REP, ""); + check_and_call_bar (BAR_REP, ""); p = p + 1; break; case '|': - event_bar (DOUBLE_BAR, ""); + check_and_call_bar (DOUBLE_BAR, ""); p = p + 1; break; case ']': - event_bar (THIN_THICK, ""); + check_and_call_bar (THIN_THICK, ""); p = p + 1; break; default: p = getrep (p, playonrep_list); - event_bar (SINGLE_BAR, playonrep_list); + check_and_call_bar (SINGLE_BAR, playonrep_list); }; break; case ':': @@ -2480,20 +2613,20 @@ parsemusic (field) switch (*p) { case ':': - event_bar (DOUBLE_REP, ""); + check_and_call_bar (DOUBLE_REP, ""); p = p + 1; break; case '|': p = p + 1; p = getrep (p, playonrep_list); - event_bar (REP_BAR, playonrep_list); + check_and_call_bar (REP_BAR, playonrep_list); if (*p == ']') p = p + 1; /* [SS] 2013-10-31 */ break; /* [JM] 2018-02-22 dotted bar line ... this is legal */ default: /* [SS] 2018-02-08 introducing DOTTED_BAR */ - event_bar (DOTTED_BAR,""); + check_and_call_bar (DOTTED_BAR,""); }; break; case ' ': @@ -2558,9 +2691,9 @@ parsemusic (field) { case '|': p = p + 1; - event_bar (THICK_THIN, ""); + check_and_call_bar (THICK_THIN, ""); if (*p == ':') { /* [SS] 2015-04-13 [SDG] 2020-06-04 */ - event_bar (BAR_REP, ""); + check_and_call_bar (BAR_REP, ""); p = p + 1; } break; @@ -2596,7 +2729,7 @@ parsemusic (field) /*if (!inchordflag && *p == '|') { [SS] 2018-12-21 not THICK_THIN bar line*/ if (!parserinchord && *p == '|') { /* [SS] 2019-06-06 not THICK_THIN bar line*/ p = p + 1; /* skip over | */ - event_bar (THIN_THICK, "");} + check_and_call_bar (THIN_THICK, "");} else { readlen (&chord_n, &chord_m, &p); /* [SS] 2019-06-06 */ event_chordoff (chord_n, chord_m); diff --git a/parseabc.h b/parseabc.h index ba65dec..95bcd73 100644 --- a/parseabc.h +++ b/parseabc.h @@ -32,12 +32,22 @@ struct voice_params { char other[V_STRLEN+1]; /* [SS] 2011-04-18 */ }; +typedef struct voice_context { + char label[31]; + int expect_repeat; + int repeat_count; +} voice_context_t; + +#define MAX_VOICES 30 + /* holds a fraction */ struct fraction { int num; int denom; }; +extern int repcheck; /* allows backend to enable/disable repeat checking */ +extern voice_context_t voicecode[MAX_VOICES]; #ifndef KANDR extern int readnump(char **p); diff --git a/store.c b/store.c index c3a18a4..bf22448 100644 --- a/store.c +++ b/store.c @@ -185,7 +185,7 @@ int main() */ -#define VERSION "4.42 Ocober 01 2020 abc2midi" +#define VERSION "4.43 Ocober 12 2020 abc2midi" /* enables reading V: indication in header */ #define XTEN1 1 @@ -892,6 +892,10 @@ char **filename; } else { check = 0; }; + /* disable repeat checking because abc2midi does its own workaround + * attempting to fix various repeat errors. + */ + repcheck = 0; /* look for filename-from-tune-titles option */ namelimit = 252; titlenames = 0; diff --git a/structs.h b/structs.h index bf0e862..ecc6680 100644 --- a/structs.h +++ b/structs.h @@ -151,7 +151,6 @@ struct voice { struct fract barcount; int barno; int barchecking; - int expect_repeat; int brokentype, brokenmult, brokenpending; int tiespending; struct feature* tie_place[MAX_TIES]; diff --git a/toabc.c b/toabc.c index cc84f48..428b439 100644 --- a/toabc.c +++ b/toabc.c @@ -21,7 +21,7 @@ /* back-end for outputting (possibly modified) abc */ -#define VERSION "2.10 October 06 2020 abc2abc" +#define VERSION "2.11 October 12 2020 abc2abc" /* for Microsoft Visual C++ 6.0 or higher */ #ifdef _MSC_VER @@ -66,7 +66,7 @@ struct fract chordfactor; /* factor of the first note in a chord [PHDM] 2013-03- struct fract breakpoint; /* used to break bar into beamed sets of notes */ int barno; /* number of bar within tune */ int newspacing; /* was -s option selected ? */ -int barcheck, repcheck; /* indicate -b and -r options selected */ +int barcheck; /* indicate -b and -r options selected */ int echeck; /* was error-checking turned off ? (-e option) */ int newbreaks; /* was -n option selected ? */ int nodouble_accidentals; @@ -105,8 +105,6 @@ char* clef = ""; /* [SS] 2020-01-22 */ extern int nokey; /* signals no key signature assumed */ extern int nokeysig; /* signals -nokeys or -nokeysf option */ -extern int voicecodes ; /* from parseabc.c */ -extern char voicecode[16][30]; /*for interpreting V: string */ struct voicetype { /* information needed for each voice */ int number; /* voice number from V: field */ @@ -115,7 +113,6 @@ struct voicetype { /* information needed for each voice */ struct abctext* currentline; int bars_remaining; int bars_complete; - int expect_repeat; /* [SS] 2018-12-01 */ int drumchan; } voice[MAX_VOICES]; int voicecount, this_voice, next_voice; @@ -1206,7 +1203,6 @@ int num; voice[voice_index].bars_complete = 0; voice[voice_index].bars_remaining = bars_per_line; voice[voice_index].drumchan = 0; - voice[voice_index].expect_repeat = -1; /* [SS] 2018-12-01 */ }; voice[voice_index].currentline = NULL; return(voice_index); @@ -1236,38 +1232,26 @@ struct voice_params *vp; }; }; }; - if (strlen(s) == 0) { - if(voicecodes >= n) emit_string_sprintf("V:%s",voicecode[n-1]); - else emit_int_sprintf("V:%d", n); - if (vp->gotclef) {sprintf(output," clef=%s", vp->clefname); - emit_string(output);} - if (vp->gotoctave) {sprintf(output," octave=%d", vp->octave); - emit_string(output);} - if (vp->gottranspose) {sprintf(output," transpose=%d", vp->transpose); - emit_string(output);} - if (vp->gotname) {sprintf(output," name=%s", vp->namestring); - emit_string(output);} - if (vp->gotsname) {sprintf(output," sname=%s", vp->snamestring); - emit_string(output);} - if( vp->gotmiddle ) { sprintf(output, " middle=%s", vp->middlestring); - emit_string(output);} - if( vp->gotother ) { sprintf(output, " %s", vp->other); - emit_string(output);} /* [SS] 2011-04-18 */ + if (strlen(voicecode[n-1].label) > 0) { + emit_string_sprintf("V:%s",voicecode[n-1].label); } else { - if(voicecodes >= n) emit_string_sprintf("V:%s",voicecode[n-1]); - emit_int_sprintf("V:%d ", n); - if (vp->gotclef) {sprintf(output," clef=%s", vp->clefname); - emit_string(output);} - if (vp->gotoctave) {sprintf(output," octave=%d", vp->octave); - emit_string(output);} - if (vp->gottranspose) {sprintf(output," transpose=%d", vp->transpose); - emit_string(output);} - if (vp->gotname) {sprintf(output," name=%s", vp->namestring); - emit_string(output);} - if( vp->gotmiddle ) { sprintf(output, " middle=%s", vp->middlestring); - emit_string(output);} - if( vp->gotother ) { sprintf(output, " %s", vp->other); - emit_string(output);} /* [SS] 2011-04-18 */ + emit_int_sprintf("V:%d", n); + } + if (vp->gotclef) {sprintf(output," clef=%s", vp->clefname); + emit_string(output);} + if (vp->gotoctave) {sprintf(output," octave=%d", vp->octave); + emit_string(output);} + if (vp->gottranspose) {sprintf(output," transpose=%d", vp->transpose); + emit_string(output);} + if (vp->gotname) {sprintf(output," name=%s", vp->namestring); + emit_string(output);} + if (vp->gotsname) {sprintf(output," sname=%s", vp->snamestring); + emit_string(output);} + if( vp->gotmiddle ) { sprintf(output, " middle=%s", vp->middlestring); + emit_string(output);} + if( vp->gotother ) { sprintf(output, " %s", vp->other); + emit_string(output);} /* [SS] 2011-04-18 */ + if (strlen(s) != 0) { emit_string(s); }; inmusic = 0; @@ -1426,8 +1410,6 @@ static void start_tune() count.denom = 1; barno = 0; tuplenotes = 0; - /* expect_repeat is now a voice struct variable [SS] 2018-12-01 */ - /* expect_repeat = -1; repeat from start may occur [J-FM] 2012-06-04 */ inlinefield = 0; if (barlen.num == 0) { /* generate missing time signature */ @@ -1741,39 +1723,18 @@ char* replist; break; case BAR_REP: emit_string("|:"); - if (voice[this_voice].expect_repeat > 0 && repcheck) - { - /* no error if first repeat [J-FM] 2012-06-04 */ - event_error("Expecting repeat, found |:"); - }; - voice[this_voice].expect_repeat = 1; break; case REP_BAR: emit_string_sprintf(":|%s", replist); - if ((!voice[this_voice].expect_repeat) && (repcheck)) { - event_warning("No repeat expected, found :|"); - }; - voice[this_voice].expect_repeat = 0; break; case BAR1: emit_string("|1"); - if ((!voice[this_voice].expect_repeat) && (repcheck)) { - event_warning("found |1 in non-repeat section"); - }; break; case REP_BAR2: emit_string(":|2"); - if ((!voice[this_voice].expect_repeat) && (repcheck)) { - event_warning("No repeat expected, found :|2"); - }; - voice[this_voice].expect_repeat = 0; break; case DOUBLE_REP: emit_string("::"); - if ((voice[this_voice].expect_repeat) && (repcheck)) { - event_error("No repeat expected, found ::"); - }; - voice[this_voice].expect_repeat = 1; break; }; if ((count.num*barlen.denom != barlen.num*count.denom) && diff --git a/yapstree.c b/yapstree.c index f28ed6c..51453fd 100644 --- a/yapstree.c +++ b/yapstree.c @@ -22,7 +22,7 @@ /* yapstree.c - back-end for abc parser. */ /* generates a data structure suitable for typeset music */ -#define VERSION "1.80 October 07 2020 yaps" +#define VERSION "1.81 October 12 2020 yaps" #include #ifdef USE_INDEX #define strchr index @@ -64,7 +64,6 @@ char outputroot[256]; char matchstring[256]; int fileopen; -int repcheck; int xinhead; int xinbody; int suppress; @@ -792,7 +791,6 @@ static struct voice* newvoice(int n) v->inslur = 0; v->ingrace = 0; v->inchord = 0; - v->expect_repeat = 0; v->tuplenotes = 0; v->thistuple = NULL; v->tuple_count = 0; @@ -2195,45 +2193,6 @@ char* playonrep_list; checkbar(type); /* increment bar number if bar complete */ /* [SS] 2015-11-15 * changed (void*) to (int *) */ addfeature(type, (int *)cv->barno); /* save bar number */ - switch(type) { - case SINGLE_BAR: - break; - case DOUBLE_BAR: - break; - case THIN_THICK: - break; - case THICK_THIN: - break; - case BAR_REP: - if ((cv->expect_repeat) && (repcheck)) { - event_error("Expecting repeat, found |:"); - }; - cv->expect_repeat = 1; - break; - case REP_BAR: - if ((!cv->expect_repeat) && (repcheck)) { - event_error("No repeat expected, found :|"); - }; - cv->expect_repeat = 0; - break; - case BAR1: - if ((!cv->expect_repeat) && (repcheck)) { - event_error("found |1 in non-repeat section"); - }; - break; - case REP_BAR2: - if ((!cv->expect_repeat) && (repcheck)) { - event_error("No repeat expected, found :|2"); - }; - cv->expect_repeat = 0; - break; - case DOUBLE_REP: - if ((!cv->expect_repeat) && (repcheck)) { - event_error("No repeat expected, found ::"); - }; - cv->expect_repeat = 1; - break; - }; if ((playonrep_list != NULL) && (strlen(playonrep_list) > 0)) { event_playonrep(playonrep_list); };