From af08248997538f4b5eabd95e2fb928b30ca4dd13 Mon Sep 17 00:00:00 2001 From: Seymour Shlien Date: Wed, 28 Oct 2020 10:48:00 -0400 Subject: [PATCH] 2020.10.27 --- VERSION | 2 +- debug.c | 20 +++---- doc/CHANGES | 8 +++ doc/readme.txt | 2 +- drawtune.c | 143 +++++++++++++++++++++++++------------------------ position.c | 4 +- structs.h | 6 ++- yapstree.c | 122 +++++++++++++++++++++++++++-------------- 8 files changed, 183 insertions(+), 124 deletions(-) diff --git a/VERSION b/VERSION index 5efd24d..a9738c9 100644 --- a/VERSION +++ b/VERSION @@ -1,2 +1,2 @@ -2020 October 19 2020 +2020 October 27 2020 diff --git a/debug.c b/debug.c index 22c5d28..cfa27c4 100644 --- a/debug.c +++ b/debug.c @@ -29,7 +29,7 @@ void showfeature(struct feature *ft) case REP2: printf("REP2\n"); break; case PLAY_ON_REP: - printf("PLAY_ON_REP %s\n", (char*)ft->item); + printf("PLAY_ON_REP %s\n", (char*)ft->item.voidptr); break; case BAR1: printf("BAR1\n"); break; @@ -42,25 +42,25 @@ void showfeature(struct feature *ft) case THIN_THICK: printf("THIN_THICK\n"); break; case PART: printf("PART\n"); - astring = ft->item; + astring = ft->item.voidptr; break; case TEMPO: printf("TEMPO\n"); break; case TIME: - afract = ft->item; + afract = ft->item.voidptr; printf("TIME %d / %d\n", afract->num, afract->denom); break; case KEY: printf("KEY\n"); - akey = ft->item; + akey = ft->item.voidptr; break; case REST: printf("REST\n"); - arest = ft->item; + arest = ft->item.voidptr; break; case TUPLE: printf("TUPLE\n"); - atuple = ft->item; + atuple = ft->item.voidptr; break; case NOTE: - anote = ft->item; + anote = ft->item.voidptr; printf("NOTE %c%c %d / %d\n", anote->accidental, anote->pitch, anote->len.num, anote->len.denom); if (anote->gchords != NULL) { @@ -82,7 +82,7 @@ void showfeature(struct feature *ft) ft->x, ft->xleft, ft->xright); break; case CHORDNOTE: - anote = ft->item; + anote = ft->item.voidptr; printf("CHORDNOTE %c%c %d / %d\n", anote->accidental, anote->pitch, anote->len.num, anote->len.denom); printf("stemup=%d beaming=%d base =%d base_exp=%d x=%.1f left=%.1f right=%.1f\n", @@ -143,7 +143,7 @@ void showfeature(struct feature *ft) case DYNAMIC: printf("DYNAMIC\n"); break; case LINENUM: - printf("LINENUM %p\n", (void *)(ft->item)); /* [SDG] 2020-06-03 */ + printf("LINENUM %d\n", ft->item.number); break; case MUSICLINE: printf("MUSICLINE\n"); break; @@ -160,7 +160,7 @@ void showfeature(struct feature *ft) case NOBEAM: printf("NOBEAM\n"); break; case CLEF: printf("CLEF\n"); - theclef = ft->item; + theclef = ft->item.voidptr; break; case SPLITVOICE: printf("SPLITVOICE\n"); default: diff --git a/doc/CHANGES b/doc/CHANGES index ee4dc38..d1fb73e 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -13968,4 +13968,12 @@ Significant changes were made to yapstree.c and drawtune.c. The makefiles folder has been moved to legacy_code. +October 27 2020 + +James Allwright cleaned up the yaps source code, (uninitialized variables) +and memory leaks detected by valgrind. In particular, one of the elements +in the struct feature (item) was changed to a union of a void pointer +and a number. This change propagated to the other files position.c, +debug.c, yaprstree.c and drawtune.c. There are too many changes in +yapstree.c and drawtune.c to list. diff --git a/doc/readme.txt b/doc/readme.txt index 2faba71..d6a3115 100644 --- a/doc/readme.txt +++ b/doc/readme.txt @@ -3,7 +3,7 @@ abcMIDI : abc <-> MIDI conversion utilities midi2abc version 3.46 June 22 2020 abc2midi version 4.44 October 19 2020 abc2abc version 2.12 October 19 2020 -yaps version 1.82 October 19 2020 +yaps version 1.83 October 27 2020 abcmatch version 1.76 October 19 2020 midicopy version 1.37 October 10 2020 diff --git a/drawtune.c b/drawtune.c index ad11bde..22c33af 100644 --- a/drawtune.c +++ b/drawtune.c @@ -1070,7 +1070,7 @@ static void spacechord(struct feature* chordplace) doneflip = 0; while ((place != NULL) && (place->type != CHORDOFF)) { if ((place->type == CHORDNOTE) || (place->type == NOTE)) { - anote = place->item; + anote = place->item.voidptr; thisy = anote->y; if ((lasty - thisy <= 1) && (lastflip != 1)) { anote->fliphead = 1; @@ -1095,7 +1095,7 @@ static void spacechord(struct feature* chordplace) place = chordplace; while ((place != NULL) && (place->type != CHORDOFF)) { if ((place->type == CHORDNOTE) || (place->type == NOTE)) { - anote = place->item; + anote = place->item.voidptr; thisy = anote->y; if (anote->accidental != ' ') { /* find space for this accidental */ @@ -1143,7 +1143,7 @@ static void drawtuple(struct feature* beamset[], int beamctr, int tupleno) int stemup; x0 = beamset[0]->x; - n = beamset[0]->item; + n = beamset[0]->item.voidptr; stemup = n->stemup; if (stemup) { y0 = (double)(TONE_HT*n->y) + n->stemlength; @@ -1151,7 +1151,7 @@ static void drawtuple(struct feature* beamset[], int beamctr, int tupleno) y0 = (double)(TONE_HT*n->y) - n->stemlength; }; x1 = beamset[beamctr-1]->x; - n = beamset[beamctr-1]->item; + n = beamset[beamctr-1]->item.voidptr; if (stemup) { y1 = (double)(TONE_HT*n->y) + n->stemlength; } else { @@ -1200,7 +1200,7 @@ static void drawbeam(struct feature* beamset[], int beamctr, int dograce) }; fprintf(f, "\n"); if (redcolor) fprintf(f,"1.0 0.0 0.0 setrgbcolor\n"); - n = beamset[0]->item; + n = beamset[0]->item.voidptr; stemup = n->stemup; beamdir = 2*stemup - 1; donenotes = 1; @@ -1215,7 +1215,7 @@ static void drawbeam(struct feature* beamset[], int beamctr, int dograce) donenotes = 0; start = -1; for (i=0; iitem; + n = beamset[i]->item.voidptr; if (n->base_exp <= d) { if (start == -1) { start = i; @@ -1230,13 +1230,13 @@ static void drawbeam(struct feature* beamset[], int beamctr, int dograce) if (start == stop) { if (start != 0) { /* half line in front of note */ - n = beamset[start-1]->item; + n = beamset[start-1]->item.voidptr; setxy(&x0, &y0, n, beamset[start-1], offset, half_head); x0 = x0 + (x1-x0)/2; y0 = y0 + (y1-y0)/2; } else { /* half line behind note */ - n = beamset[start+1]->item; + n = beamset[start+1]->item.voidptr; setxy(&x1, &y1, n, beamset[start+1], offset, half_head); x1 = x1 + (x0-x1)/2; y1 = y1 + (y0-y1)/2; @@ -1400,11 +1400,11 @@ static void sizevoice(struct voice* v, struct tune* t) ft->xright = 0.0; break; case PART: - astring = ft->item; + astring = ft->item.voidptr; case TEMPO: break; case TIME: - afract = ft->item; + afract = ft->item.voidptr; if (afract == NULL) { afract = &v->meter; }; @@ -1413,12 +1413,12 @@ static void sizevoice(struct voice* v, struct tune* t) break; case KEY: ft->xleft = 0; - akey = ft->item; + akey = ft->item.voidptr; ft->xright = (float) size_keysig(v->keysig->map, akey->map); set_keysig(v->keysig, akey); break; case REST: - arest = ft->item; + arest = ft->item.voidptr; sizerest(arest, ft); if (intuple) { if (ft->yup > thistuple->height) { @@ -1434,7 +1434,7 @@ static void sizevoice(struct voice* v, struct tune* t) }; break; case TUPLE: - thistuple = ft->item; + thistuple = ft->item.voidptr; if (thistuple->beamed == 0) { intuple = 1; tuplecount = thistuple ->r; @@ -1443,7 +1443,7 @@ static void sizevoice(struct voice* v, struct tune* t) }; break; case NOTE: - anote = ft->item; + anote = ft->item.voidptr; setstemlen(anote, ingrace); sizenote(anote, ft, ingrace); if (inchord) { @@ -1531,13 +1531,13 @@ static void sizevoice(struct voice* v, struct tune* t) case CHORDON: inchord = 1; chordcount = 0; - thischord = ft->item; + thischord = ft->item.voidptr; chordplace = ft; spacechord(chordplace); break; case CHORDOFF: if (thischord != NULL) { - anote = chordhead->item; + anote = chordhead->item.voidptr; thischord->beaming = chordbeaming; if (thischord->beaming == single) { sizechord(thischord, ingrace); @@ -1559,7 +1559,7 @@ static void sizevoice(struct voice* v, struct tune* t) case DYNAMIC: break; case LINENUM: - lineno = (long)(ft->item); + lineno = ft->item.number; break; case MUSICLINE: break; @@ -1574,7 +1574,7 @@ static void sizevoice(struct voice* v, struct tune* t) case NOBEAM: break; case CLEF: - theclef = ft->item; + theclef = ft->item.voidptr; if (theclef == NULL) { theclef = v->clef; } @@ -2278,12 +2278,12 @@ static void setbeams(struct feature* note[], struct chord* chording[], int m, double max; /* printf("Doing setbeams m=%d\n", m); */ - anote = note[0]->item; + anote = note[0]->item.voidptr; stemup = anote->stemup; /* calculate minimum feasible stem lengths */ /* bearing in mind space needed for the tails */ for (i=0; iitem; + anote = note[i]->item.voidptr; anote->stemup = stemup; switch (anote->base) { default: @@ -2325,7 +2325,7 @@ static void setbeams(struct feature* note[], struct chord* chording[], int m, min[i] = TONE_HT*anote->y - min[i]; /* avoid collision with previous note */ if (i > 0) { - anote = note[i-1]->item; + anote = note[i-1]->item.voidptr; if (anote->y*TONE_HT < min[i]) { min[i] = anote->y*TONE_HT; }; @@ -2337,10 +2337,10 @@ static void setbeams(struct feature* note[], struct chord* chording[], int m, }; /* work out clearance from a straight line between 1st and last note */ x1 = note[0]->x; - anote = note[0]->item; + anote = note[0]->item.voidptr; y1 = anote->y*TONE_HT; x2 = note[m-1]->x; - anote = note[m-1]->item; + anote = note[m-1]->item.voidptr; y2 = anote->y*TONE_HT; if (x1 == x2) { printf("Internal error: x1 = x2 = %.1f\n", x1); @@ -2379,7 +2379,7 @@ static void setbeams(struct feature* note[], struct chord* chording[], int m, }; /* raise the line just enough to clear notes */ for (i=0; iitem; + anote = note[i]->item.voidptr; xi = note[i]->x; if (stemup) { anote->stemlength = (float) (y1 + (y2-y1)*(xi-x1)/(x2-x1) + lift - @@ -2392,7 +2392,7 @@ static void setbeams(struct feature* note[], struct chord* chording[], int m, /* now transfer results to chords */ for (i=0; iitem; + anote = note[i]->item.voidptr; chording[i]->stemup = anote->stemup; if (chording[i]->stemup) { chording[i]->stemlength = anote->stemlength; @@ -2431,7 +2431,7 @@ static void beamline(struct feature* ft) switch (p->type) { case NOTE: if (ingrace) { - n = p->item; + n = p->item.voidptr; if (n == NULL) { event_error("Missing NOTE!!!!"); exit(0); @@ -2450,7 +2450,7 @@ static void beamline(struct feature* ft) }; } else { /* non-grace notes*/ - n = p->item; + n = p->item.voidptr; if (n == NULL) { event_error("Missing NOTE!!!!"); exit(0); @@ -2471,9 +2471,9 @@ static void beamline(struct feature* ft) break; case CHORDON: if (ingrace) { - gracelastchord = p->item; + gracelastchord = p->item.voidptr; } else { - lastchord = p->item; + lastchord = p->item.voidptr; }; break; case CHORDOFF: @@ -2521,7 +2521,7 @@ static void measureline(struct feature* ft, double* height, double* descender, while ((p != NULL) && (p->type != PRINTLINE)) { switch (p->type) { case NOTE: - n = p->item; + n = p->item.voidptr; if (n == NULL) { event_error("Missing NOTE!!!!"); exit(0); @@ -2570,7 +2570,7 @@ static void measureline(struct feature* ft, double* height, double* descender, }; break; case REST: - r = p->item; + r = p->item.voidptr; if (r == NULL) { event_error("Missing REST!!!!"); exit(0); @@ -2838,6 +2838,7 @@ static void drawslurtie(struct slurtie* s) struct feature* ft; struct note* n; struct rest* r; + int stemup = 0; ft = s->begin; if (ft == NULL) { @@ -2846,11 +2847,12 @@ static void drawslurtie(struct slurtie* s) }; x0 = ft->x; if ((ft->type == NOTE) || (ft->type == CHORDNOTE)) { - n = ft->item; + n = ft->item.voidptr; y0 = (double)(n->y * TONE_HT); + stemup = n->stemup; } else { if (ft->type == REST) { - r = ft->item; + r = ft->item.voidptr; y0 = (double)(4 * TONE_HT); } else { printf("Internal error: NOT A NOTE/REST (%d)in slur/tie\n" ,ft->type); @@ -2870,11 +2872,12 @@ static void drawslurtie(struct slurtie* s) }; x1 = ft->x; if ((ft->type == NOTE) || (ft->type == CHORDNOTE)) { - n = ft->item; + n = ft->item.voidptr; y1 = (double)(n->y * TONE_HT); + stemup = n->stemup; } else { if (ft->type == REST) { - r = ft->item; + r = ft->item.voidptr; y1 = (double)(4 * TONE_HT); } else { printf("Internal error: NOT A NOTE/REST (%d)in slur/tie\n" ,ft->type); @@ -2882,7 +2885,7 @@ static void drawslurtie(struct slurtie* s) }; }; }; - if (n->stemup) { + if (stemup) { fprintf(f, " %.1f %.1f %.1f %.1f slurdown\n", x0, y0, x1, y1); } else { fprintf(f, " %.1f %.1f %.1f %.1f slurup\n", x0, y0, x1, y1); @@ -2898,6 +2901,7 @@ static void close_slurtie(struct slurtie* s) struct feature* ft; struct note* n; struct rest* r; + int stemup = 0; if ((s == NULL) || (s->crossline == 0)) { return; @@ -2910,11 +2914,12 @@ static void close_slurtie(struct slurtie* s) }; x1 = ft->x; if ((ft->type == NOTE) || (ft->type == CHORDNOTE)) { - n = ft->item; + n = ft->item.voidptr; y1 = (double)(n->y * TONE_HT); + stemup = n->stemup; } else { if (ft->type == REST) { - r = ft->item; + r = ft->item.voidptr; y1 = (double)(4 * TONE_HT); } else { printf("Internal error: NOT A NOTE/REST (%d)in slur/tie\n" ,ft->type); @@ -2924,7 +2929,7 @@ static void close_slurtie(struct slurtie* s) }; x0 = TREBLE_LEFT + TREBLE_RIGHT; y0 = y1; - if (n->stemup) { + if (stemup) { fprintf(f, " %.1f %.1f %.1f %.1f slurdown\n", x0, y0, x1, y1); } else { fprintf(f, " %.1f %.1f %.1f %.1f slurup\n", x0, y0, x1, y1); @@ -2943,7 +2948,7 @@ static void blockline(struct voice* v, struct vertspacing** spacing) ft = ft->next; }; if ((ft != NULL) && (ft->type == PRINTLINE)) { - *spacing = ft->item; + *spacing = ft->item.voidptr; } else { *spacing = NULL; event_error("Expecting line of music - possible voices mis-match"); @@ -2995,7 +3000,7 @@ static int printvoiceline(struct voice* v) (v->place->type == LEFT_TEXT) || (v->place->type == CENTRE_TEXT) || (v->place->type == VSKIP))) { if (v->place->type == LINENUM) { - lineno = (long)(v->place->item); + lineno = v->place->item.number; }; if (v->place->type == NEWPAGE) { newpage(); @@ -3007,7 +3012,7 @@ static int printvoiceline(struct voice* v) printtext(centre, v->place->item, &textfont); }; if (v->place->type == VSKIP) { - vskip((double)((long)v->place->item)); + vskip((double)v->place->item.number); }; v->place = v->place->next; }; @@ -3041,21 +3046,21 @@ static int printvoiceline(struct voice* v) switch (ft->type) { case SINGLE_BAR: fprintf(f, "%.1f bar\n", ft->x); - printbarnumber(ft->x, (long)ft->item); + printbarnumber(ft->x, ft->item.number); break; case DOUBLE_BAR: fprintf(f, "%.1f dbar\n", ft->x); - printbarnumber(ft->x, (long)ft->item); + printbarnumber(ft->x, ft->item.number); inend = endrep(inend, endstr, xend, ft->x, spacing->yend); break; case BAR_REP: fprintf(f, "%.1f fbar1 %.1f rdots\n", ft->x, ft->x+10); - printbarnumber(ft->x, (long)ft->item); + printbarnumber(ft->x, ft->item.number); inend = endrep(inend, endstr, xend, ft->x, spacing->yend); break; case REP_BAR: fprintf(f, "%.1f rdots %.1f fbar2\n", ft->x, ft->x+10); - printbarnumber(ft->x, (long)ft->item); + printbarnumber(ft->x, ft->item.number); inend = endrep(inend, endstr, xend, ft->x, spacing->yend); break; case REP1: @@ -3073,12 +3078,12 @@ static int printvoiceline(struct voice* v) case PLAY_ON_REP: inend = endrep(inend, endstr, xend, ft->x - ft->xleft, spacing->yend); inend = 1; - strcpy(endstr, ft->item); + strcpy(endstr, ft->item.voidptr); xend = ft->x + ft->xright; break; case BAR1: fprintf(f, "%.1f bar\n", ft->x); - printbarnumber(ft->x, (long)ft->item); + printbarnumber(ft->x, ft->item.number); inend = endrep(inend, endstr, xend, ft->x - ft->xleft, spacing->yend); inend = 1; strcpy(endstr, "1"); @@ -3086,7 +3091,7 @@ static int printvoiceline(struct voice* v) break; case REP_BAR2: fprintf(f, "%.1f rdots %.1f fbar2\n", ft->x, ft->x+10); - printbarnumber(ft->x, (long)ft->item); + printbarnumber(ft->x, ft->item.number); inend = endrep(inend, endstr, xend, ft->x - ft->xleft, spacing->yend); inend = 2; strcpy(endstr, "2"); @@ -3106,13 +3111,13 @@ static int printvoiceline(struct voice* v) inend = endrep(inend, endstr, xend, ft->x, spacing->yend); break; case PART: - astring = ft->item; + astring = ft->item.voidptr; break; case TEMPO: - draw_tempo(ft->x, spacing->yinstruct, ft->item); + draw_tempo(ft->x, spacing->yinstruct, ft->item.voidptr); break; case TIME: - afract = ft->item; + afract = ft->item.voidptr; if (afract==NULL) { if (v->line == midline) { draw_meter(&v->meter, ft->x); @@ -3125,14 +3130,14 @@ static int printvoiceline(struct voice* v) }; break; case KEY: - akey = ft->item; + akey = ft->item.voidptr; if (v->line == midline) { draw_keysig(v->keysig->map, akey->map, akey->mult, ft->x, v->clef); }; set_keysig(v->keysig, akey); break; case REST: - arest = ft->item; + arest = ft->item.voidptr; drawrest(arest, ft->x, spacing); if (v->tuple_count > 0) { if (v->tuple_count == v->tuplenotes) { @@ -3147,7 +3152,7 @@ static int printvoiceline(struct voice* v) }; break; case TUPLE: - atuple = ft->item; + atuple = ft->item.voidptr; if (atuple->beamed) { v->beamed_tuple_pending = atuple->n; v->tuplenotes = atuple->r; @@ -3160,7 +3165,7 @@ static int printvoiceline(struct voice* v) }; break; case NOTE: - anote = ft->item; + anote = ft->item.voidptr; if (thischord == NULL) { if (ingrace) { drawgracenote(anote, ft->x, ft, thischord); @@ -3195,7 +3200,7 @@ static int printvoiceline(struct voice* v) }; break; case CHORDNOTE: - anote = ft->item; + anote = ft->item.voidptr; if (ingrace) { drawgracehead(anote, xchord, ft, nostem); } else { @@ -3209,16 +3214,16 @@ static int printvoiceline(struct voice* v) case TEXT: break; case SLUR_ON: - drawslurtie(ft->item); + drawslurtie(ft->item.voidptr); break; case SLUR_OFF: - close_slurtie(ft->item); + close_slurtie(ft->item.voidptr); break; case TIE: - drawslurtie(ft->item); + drawslurtie(ft->item.voidptr); break; case CLOSE_TIE: - close_slurtie(ft->item); + close_slurtie(ft->item.voidptr); break; case TITLE: break; @@ -3247,7 +3252,7 @@ static int printvoiceline(struct voice* v) case VOICE: break; case CHORDON: - thischord = ft->item; + thischord = ft->item.voidptr; chordcount = 0; drawchordtail(thischord, ft->next->x); break; @@ -3274,12 +3279,12 @@ static int printvoiceline(struct voice* v) case GT: break; case DYNAMIC: - psaction = ft->item; + psaction = ft->item.voidptr; if(psaction->color == 'r') redcolor = 1; /* [SS] 2013-11-04 */ if(psaction->color == 'b') redcolor = 0; break; case LINENUM: - lineno = (long)(ft->item); + lineno = ft->item.number; break; case MUSICLINE: v->line = midline; @@ -3300,7 +3305,7 @@ static int printvoiceline(struct voice* v) case NOBEAM: break; case CLEF: - theclef = ft->item; + theclef = ft->item.voidptr; if (theclef != NULL) { copy_clef (v->clef, theclef); }; @@ -3360,7 +3365,7 @@ static int finalsizeline(struct voice* v) ft = ft->next; }; if ((ft != NULL) && (ft->type == PRINTLINE)) { - avertspacing = ft->item; + avertspacing = ft->item.voidptr; avertspacing->height = (float) height; avertspacing->descender = (float) descender; avertspacing->yend = (float) yend; @@ -3401,7 +3406,7 @@ static int getlineheight(struct voice* v, double* height) (v->place->type == LEFT_TEXT) || (v->place->type == CENTRE_TEXT) || (v->place->type == VSKIP))) { if (v->place->type == LINENUM) { - lineno = (long)(v->place->item); + lineno = v->place->item.number; }; if (v->place->type == LEFT_TEXT) { *height = *height + textfont.pointsize + textfont.space; @@ -3410,7 +3415,7 @@ static int getlineheight(struct voice* v, double* height) *height = *height + textfont.pointsize + textfont.space; }; if (v->place->type == VSKIP) { - *height = *height + (double)((long)v->place->item); + *height = *height + (double)(v->place->item.number); }; v->place = v->place->next; }; @@ -3422,7 +3427,7 @@ static int getlineheight(struct voice* v, double* height) v->place = v->place->next; }; if (v->place != NULL) { - spacing = v->place->item; + spacing = v->place->item.voidptr; *height = *height + spacing->height + spacing->descender; v->place = v->place->next; }; diff --git a/position.c b/position.c index 3184f86..ac7d3c0 100644 --- a/position.c +++ b/position.c @@ -148,11 +148,11 @@ static void advance(struct voice* v, int phase, int* items, double* itemspace, d *itemspace = *itemspace + p->xleft + p->xright; *items = *items + 1; if (p->type == REST) { - arest = p->item; + arest = p->item.voidptr; addfract(&v->time, arest->len.num, arest->len.denom); }; if ((p->type == NOTE) && (!v->ingrace)) { - anote = p->item; + anote = p->item.voidptr; notelen = anote->len; if (anote->tuplenotes >0) { diff --git a/structs.h b/structs.h index 250a1e7..982d9a0 100644 --- a/structs.h +++ b/structs.h @@ -104,7 +104,11 @@ struct feature { featuretype type; float xleft, xright, ydown, yup; float x; - void* item; + /* [JA] 2020-10-27 */ + union { + void *voidptr; + int number; + }item; }; /* structure used by both slurs and ties */ diff --git a/yapstree.c b/yapstree.c index 146e910..8c76140 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.82 October 19 2020 yaps" +#define VERSION "1.83 October 27 2020 yaps" #include #ifdef USE_INDEX #define strchr index @@ -325,7 +325,7 @@ static void closebeam(struct voice* v) }; if (v->beamroot == v->beamend) { ft = v->beamroot; - n = ft->item; + n = ft->item.voidptr; n->beaming = single; v->beamroot = NULL; return; @@ -341,7 +341,7 @@ static void closebeam(struct voice* v) switch (ft->type) { case NOTE: if (ingrace == 0) { - n = ft->item; + n = ft->item.voidptr; n->stemup = stemup; }; break; @@ -357,7 +357,7 @@ static void closebeam(struct voice* v) ft = ft->next; }; if (ft == v->beamend) { - n = ft->item; + n = ft->item.voidptr; n->stemup = stemup; n->beaming = endbeam; } else { @@ -377,7 +377,7 @@ static void closegracebeam(struct voice* v) if (ft == NULL) { event_error("Missing grace notes"); } else { - n = ft->item; + n = ft->item.voidptr; if (v->gracebeamroot == v->gracebeamend) { n->beaming = single; } else { @@ -395,13 +395,13 @@ static void insertnote(struct feature* chordplace, struct feature* newfeature) struct feature* previous; int foundplace; - newnote = newfeature->item; + newnote = newfeature->item.voidptr; previous = chordplace; f = chordplace->next; foundplace = 0; n = NULL; while ((f != NULL)&&(f->type==NOTE)&&(foundplace == 0)) { - n = f->item; + n = f->item.voidptr; if (newnote->y > n->y) { foundplace = 1; } else { @@ -506,6 +506,50 @@ static void beamitem(featuretype mytype, void* newitem, struct feature* x) }; } +/* initialize a feature struct with empty values */ +static void init_feature (struct feature *x, featuretype mytype) +{ + x->next = NULL; + x->type = mytype; + x->item.voidptr = NULL; + x->xleft = 0; + x->xright = 0; + x->yup = 0; + x->ydown = 0; +} + +static struct feature *addnumberfeature (featuretype mytype, int number) +/* handles numeric feature types + * may mark the end of a beamed section, so still need to call + * beamitem() on these + */ +{ + struct feature *x; + + if (cv == NULL) { + printf ("ERROR: no current voice in addfeature(status,type=%d\n", mytype); + //printf("status->inhead = %d status->inbody = %d\n", status->inhead, status->inbody); + exit (0); + } + x = (struct feature *)checkmalloc (sizeof (struct feature)); + init_feature (x, mytype); + x->item.number = number; + if (cv->first == NULL) { + cv->first = x; + cv->last = x; + beamitem (mytype, NULL, x); + } else { + if ((cv->last == NULL) || (cv->last->next != NULL)) { + printf ("expecting NULL at list end!\n"); + exit (0); + } + cv->last->next = x; + cv->last = x; + beamitem (mytype, NULL, x); + } + return (x); +} + static struct feature* addfeature(featuretype mytype, void* newitem) /* append a new data element to the linked list for the current voice */ /* The element can be a note or lots of other things */ @@ -521,13 +565,8 @@ static struct feature* addfeature(featuretype mytype, void* newitem) exit(0); }; x = (struct feature*)checkmalloc(sizeof(struct feature)); - x->next = NULL; - x->type = mytype; - x->item = newitem; - x->xleft = 0; - x->xright = 0; - x->yup = 0; - x->ydown = 0; + init_feature (x, mytype); + x->item.voidptr = newitem; if (cv->first == NULL) { cv->first = x; cv->last = x; @@ -697,7 +736,7 @@ int a, b; } else { n->stemup = 0; }; - n->stemlength = 0.0; + n->beaming = single; /* initial default value */ n->syllables = NULL; if (cv->ingrace) { n->gchords = NULL; @@ -708,6 +747,7 @@ int a, b; n->instructions = cv->instructions_pending; cv->instructions_pending = NULL; }; + n->stemlength = 0.0; return(n); } @@ -895,6 +935,7 @@ static void freefeature(void* item, featuretype type) switch(type) { case NOTE: + case CHORDNOTE: n = item; if (n->accents != NULL) { free(n->accents); @@ -958,7 +999,7 @@ static void freevoice(struct voice* v) ft = v->first; while (ft != NULL) { - freefeature(ft->item, ft->type); + freefeature(ft->item.voidptr, ft->type); oldft = ft; ft = ft->next; free(oldft); @@ -969,6 +1010,7 @@ static void freevoice(struct voice* v) }; if (v->tempo != NULL) { freetempo(v->tempo); + free (v->tempo); v->tempo = NULL; }; if (v->clef != NULL) { @@ -1002,6 +1044,7 @@ static void freetune(struct tune* t) }; if (t->tempo != NULL) { freetempo(t->tempo); + free(t->tempo); t->tempo = NULL; }; v = firstitem(&t->voices); @@ -1316,8 +1359,7 @@ event_error("extended overlay not implemented in yaps"); void event_split_voice() { -/* [SS] 2015-11-15 * changed (void*) to (int *) */ -addfeature(SPLITVOICE, (int *) lineno); +addnumberfeature(SPLITVOICE, lineno); event_error("voice split not implemented in yaps"); } @@ -1332,7 +1374,7 @@ void event_linebreak() { /* [SS] 2015-11-15 * changed (void*) to (int *) */ if (xinbody) { - addfeature(LINENUM, (int *)lineno); + addnumberfeature(LINENUM, lineno); }; } @@ -1346,7 +1388,7 @@ static void tidy_ties() for (i=0; itiespending; i++) { ft = cv->tie_place[i]; /* pointer to TIE feature */ - s = ft->item; + s = ft->item.voidptr; addfeature(CLOSE_TIE, s); }; } @@ -1354,7 +1396,7 @@ static void tidy_ties() void event_startmusicline() /* We are at the start of a line of abc notes */ { - cv->linestart = addfeature(MUSICLINE, (void*)NULL); + cv->linestart = addnumberfeature(MUSICLINE, 0); if (cv->more_lyrics != 0) { event_error("Missing continuation w: field"); cv->more_lyrics = 0; @@ -1382,7 +1424,7 @@ static void divide_ties() for (i=0; itiespending; i++) { ft = cv->tie_place[i]; /* pointer to TIE feature */ - s = ft->item; + s = ft->item.voidptr; s->crossline = 1; }; for (i=0; islurcount; i++) { @@ -1397,7 +1439,7 @@ void event_score_linebreak (char ch) if (xinbody) { /* end current score line - code from endmusicline */ - cv->lineend = addfeature (MUSICSTOP, (void *)NULL); + cv->lineend = addnumberfeature (MUSICSTOP, 0); addfeature (PRINTLINE, newvertspacing ()); cv->line = newline; divide_ties (); @@ -1410,7 +1452,7 @@ void event_endmusicline(endchar) char endchar; /* We are at the end of a line of abc notes */ { - cv->lineend = addfeature(MUSICSTOP, (void*)NULL); + cv->lineend = addnumberfeature(MUSICSTOP, 0); if ((endchar == ' ') || (endchar == '!')) { addfeature(PRINTLINE, newvertspacing()); cv->line = newline; @@ -1508,7 +1550,7 @@ char *str; /* string following first word */ vskip(vspace); }; } else { - addfeature(VSKIP, (int*)((int)vspace)); + addnumberfeature(VSKIP, (int)vspace); }; }; }; @@ -1612,7 +1654,7 @@ struct feature* apply_syll(char* s, struct feature* wordplace, int* errors) return(ft); }; if (ft->type == NOTE) { - n = ft->item; + n = ft->item.voidptr; if (n->syllables == NULL) { n->syllables = newlist(); }; @@ -2120,7 +2162,7 @@ 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 */ + addnumberfeature(type, cv->barno); /* save bar number */ if ((playonrep_list != NULL) && (strlen(playonrep_list) > 0)) { event_playonrep(playonrep_list); }; @@ -2398,12 +2440,12 @@ static void resolve_ties(struct feature* f) struct note* n; int i, j; - n = f->item; + n = f->item.voidptr; for (i=0; itiespending; i++) { ft = cv->tie_place[i]; /* pointer to TIE feature */ - s = ft->item; + s = ft->item.voidptr; ft = s->begin; /* pointer to NOTE feature */ - m = ft->item; + m = ft->item.voidptr; if (m->y == n->y) { /* pitch match found */ s->end = f; j = cv->tiespending; @@ -2479,7 +2521,7 @@ int a, b; struct fract* afract; if (n->type == NOTE) { - anote = n->item; + anote = n->item.voidptr; afract = &anote->len; afract->num = afract->num * a; afract->denom = afract->denom * b; @@ -2489,7 +2531,7 @@ int a, b; anote->len.num, anote->len.denom); }; if (n->type == REST) { - arest = n->item; + arest = n->item.voidptr; afract = &arest->len; afract->num = afract->num * a; afract->denom = afract->denom * b; @@ -2509,11 +2551,11 @@ struct fract* getlenfract(struct feature *f) len = NULL; if (f->type == NOTE) { - anote = f->item; + anote = f->item.voidptr; len = &(anote->len); }; if (f->type == REST) { - arest = f->item; + arest = f->item.voidptr; len = &(arest->len); }; return(len); @@ -2561,8 +2603,8 @@ static void brokenadjust() fr1 = getlenfract(cv->laststart); fr2 = getlenfract(cv->thisstart); /* - fr1 = cv->laststart->item; - fr2 = cv->thisstart->item; + fr1 = cv->laststart->item.voidptr; + fr2 = cv->thisstart->item.voidptr; */ if ((fr1->num * fr2->denom) != (fr2->num * fr1->denom)) { failed = 1; @@ -2675,11 +2717,11 @@ struct feature* f; struct note* anote; if (chord_n ==1 && chord_m ==1) return; f = chordplace->next; -anote = f->item; +anote = f->item.voidptr; /* remove old note length from barcount */ addfractions(&cv->barcount, -anote->len.num, anote->len.denom); while ((f != NULL)&&((f->type==NOTE)||(f->type=CHORDNOTE))) { - anote = f->item; + anote = f->item.voidptr; /* remove old note length from barcount */ setfract(&anote->len, chord_n*cv->unitlen.num, chord_m*cv->unitlen.denom); reducef(&anote->len); @@ -2711,8 +2753,8 @@ void event_chordoff(int chord_n, int chord_m) }; ft = cv->chordplace; if ((ft != NULL) && (ft->next != NULL) && (ft->next->type == NOTE)) { - thechord = ft->item; - firstnote = ft->next->item; + thechord = ft->item.voidptr; + firstnote = ft->next->item.voidptr; /* beaming for 1st note in chord */ beamitem(NOTE, firstnote, ft->next); markchord(ft);