/*************************************************
*    The PMW Music Typesetter - 3rd incarnation  *
*************************************************/

/* Copyright (c) Philip Hazel, 1991 - 2019 */

/* Written by Philip Hazel, starting November 1991 */
/* This file last modified: December 2019 */


/* This file contains debugging functions. */

#include "pmwhdr.h"
#include "pagehdr.h"
#include "outhdr.h"


static const char *fontnames[] = {
  "roman", "italic", "bold", "bolditalic", "symbol", "mu", "mf",
  "extra 1", "extra 2", "extra 3", "extra 4",
  "extra 5", "extra 6", "extra 7", "extra 8" };

static const char *clefstrings[] = {
  "Treble", "Soprano", "Mezzo", "Alto", "Tenor", "Bass",
  "Trebledescant", "Trebletenor", "Soprabass", "Contrabass", "None",
  "TrebletenorB", "Hclef" };

static const char *nhstrings[] = {
  "normal", "cross", "harmonic", "none", "only" };

static const char *ntstrings[] = {
  "B   ", "SB  ", "M   ", "c   ", "q   ", "sq  ", "dsq ", "hdsq" };

static const char *accstrings[] = {
  "  ", "##", "$ ", "$$", "% ", "# " };

static const char *ornstrings[] = {
  "fermata", "trill", "trill+sharp", "trill+flat", "trill+natural",
  "tremolo1", "tremolo2", "tremolo3", "mordent", "double mordent",
  "inverted mordent", "double inverted mordent", "turn",
  "inverted turn", "arpeggio", "arpeggio + uparrow", "arpeggio + downarrow",
  "spread" };




/*************************************************
*           Display debugging output             *
*************************************************/

/* Write to debug_file if it is not NULL.

Arguments:
  format    printf-like format
  ...       printf-like data values

Returns:    nothing
*/

void
debug_printf(const char *format, ...)
{
uschar buff[256];
va_list ap;
if (debug_file == NULL) return;
va_start(ap, format);

format_vsprintf(buff, format, ap);
fprintf(debug_file, "%s", CS buff);



fflush(debug_file);
va_end(ap);
}



/*************************************************
*             Show bar data                      *
*************************************************/

/* Show the encoded data items for a specific bar. The bar number is an actual,
absolute bar number, counting from 1. It does not take account of uncounted
bars.

Arguments:
  n            the movement number
  s            the stave number
  b            the bar number

Returns:       nothing
*/

void
debug_showbar(int n, int s, int b)
{
bstr *p;
if (n == 0) n = 1;

if (n > main_lastmovement ||
    s > movement[n]->laststave ||
    b > (movement[n]->stavetable[s])->lastbar)
  {
  debug_printf("Movement %d, stave %d, bar %b does not exist\n", n, s, b);
  return;
  }

p = (movement[n]->stavetable[s])->barindex[b];

format_movt = movement[n];
debug_printf("Contents of bar %b for stave %d in movement %d\n", b, s, n);

if (p == NULL) debug_printf("Empty bar\n\n"); else
  {
  int type = p->type;
  while (type != b_End)
    {
    switch(type)
      {
      case b_Jump:
      debug_printf("Jump %p\n", (void *)(((b_Jumpstr *)p)->next));
      p = (bstr *)(((b_Jumpstr *)p)->next);
      break;

      case b_all:
      debug_printf("All\n");
      break;

      case b_barnum:
        {
        b_barnumstr *pp = (b_barnumstr *)p;
        debug_printf("Barnumber %s %f %f\n", pp->flag? "on": "off",
          pp->x, pp->y);
        }
      break;

      case b_beamacc:
      debug_printf("Beamacc\n");
      break;

      case b_beambreak:
      debug_printf("Beambreak\n");
      break;

      case b_beambreak2:
      debug_printf("Beambreak2\n");
      break;

      case b_beamrit:
      debug_printf("Beamrit\n");
      break;

      case b_bowing:
      debug_printf("Bowing %s\n", ((b_charvaluestr *)p)->value? "above":"below");
      break;

      case b_breakbarline:
      debug_printf("Breakbarline\n");
      break;

      case b_caesura:
      debug_printf("Caesura\n");
      break;

      case b_clef:
      debug_printf("Clef %s\n", clefstrings[((b_clefstr *)p)->trueclef]);
      break;

      /* b_chord is with b_note */

      case b_comma:
      debug_printf("Comma\n");
      break;

      case b_dbar:
      debug_printf("Double bar\n");
      break;

      case b_dotbar:
      debug_printf("Dotbar\n");
      break;

      case b_dotright:
      debug_printf("Dotright %f\n", ((b_dotrightstr *)p)->value);
      break;

      case b_draw:
        {
        tree_node *t = ((b_drawstr *)p)->item;
        debug_printf("Draw %s\n", t->name);
        }
      break;

      case b_dynmove:
        {
        b_dynmovestr *pp = (b_dynmovestr *)p;
        debug_printf("Dyn move %d x=%f y=%f bflags=%d\n", pp->dynamic, pp->x,
          pp->y, pp->bflags);
        }
      break;

      case b_ebar:
      debug_printf("End bar\n");
      break;

      case b_endplet:
      debug_printf("Endplet\n");
      break;

      case b_endslur:
        {
        b_endslurstr *pp = (b_endslurstr *)p;
        debug_printf("Endslur/=%c\n", (pp->id == 0)? ' ' : pp->id);
        }
      break;

      case b_ens:
      debug_printf("Ens\n");
      break;

      case b_ensure:
      debug_printf("Ensure %f\n", ((b_ensurestr *)p)->value);
      break;

      case b_footnote:
      debug_printf("Footnote\n");
      break;

      case b_hairpin:
        {
        b_hairpinstr *pp = (b_hairpinstr *)p;
        debug_printf("Hairpin %c flags=%d x=%f y=%f offset=%f su=%f h=%f\n",
         (pp->opt == 0)? '*' : pp->opt, pp->flags,
            pp->x, pp->y, pp->offset, pp->su, pp->h);
        }
      break;

      case b_ibar:
      debug_printf("Invisible bar\n");
      break;

      case b_justify:
        {
        b_justifystr *pp = (b_justifystr *)p;
        int side = pp->side;
        debug_printf("Justify %c%s\n", pp->opt,
          (side==just_top)? "top" :
          (side==just_bottom)? "bottom" :
          (side==just_left)? "left" :
          (side==just_right)? "right" : "???");
        }
      break;

      case b_key:
        {
        b_keystr *pp = (b_keystr *)p;
        debug_printf("Key %k%s\n", pp->key, pp->warn? "" : " nowarn");
        }
      break;

      case b_linegap:
      debug_printf("Linegap\n");
      break;

      case b_lrepeat:
      debug_printf("Left repeat\n");
      break;

      case b_masq:
      debug_printf("Masquerade %s\n", ntstrings[((b_masqstr *)p)->value]);
      break;

      case b_move:
        {
        b_movestr *pp = (b_movestr *)p;
        debug_printf("Move %f, %f\n", pp->x, pp->y);
        }
      break;

      case b_name:
      debug_printf("Name %d\n", ((b_namestr *)p)->n);
      break;

      case b_nbar:
      debug_printf("Nbar %d y=%f\n", ((b_nbarstr *)p)->n,
        ((b_nbarstr *)p)->y);
      break;

      case b_newline:
      debug_printf("Newline\n");
      break;

      case b_newpage:
      debug_printf("Newpage\n");
      break;

      case b_nopack:
      debug_printf("Nopack\n");
      break;

      case b_chord:
      case b_note:
        {
        b_notestr *pp = (b_notestr *)p;
        debug_printf("%s ", (pp->spitch == 0)? "Rest " :
          (type == b_note)? "Note ":"Chord");
        debug_printf("%s %6d ", ntstrings[pp->notetype], pp->length);
        debug_printf("%s ", accstrings[pp->acc]);
        debug_printf("p=%03d=%03d ", pp->spitch, pp->truepitch);
        debug_printf("f=%08x yx=%f ", pp->flags, pp->yextra);
        debug_printf("al=%f\n", pp->accleft);
        }
      break;

      case b_noteheads:
      debug_printf("Noteheads %s\n", nhstrings[((b_charvaluestr *)p)->value]);
      break;

      case b_notes:
      debug_printf("Notes %s\n", (((b_notesstr *)p)->value)? "on" : "off");
      break;

      case b_ns:
        {
        int i;
        b_nsstr *pp = (b_nsstr *)p;
        debug_printf("Ns ");
        for (i = 0; i < 8; i++)
          debug_printf("%f ", pp->ns[i]);
        debug_printf("\n");
        }
      break;

      case b_nsm:
      debug_printf("Ns *%f\n", ((b_nsmstr *)p)->value);
      break;

      case b_offset:
      debug_printf("beammove %f\n", ((b_offsetstr *)p)->value);
      break;

      case b_olevel:
        {
        b_olevelstr *pp = (b_olevelstr *)p;
        debug_printf("Olevel ");
        if (pp->opt == TRUE) debug_printf("*\n");
        else debug_printf("%f\n", pp->value);
        }
      break;

      case b_olhere:
      debug_printf("Olhere %f\n", ((b_olherestr *)p)->value);
      break;

      case b_ornament:
        {
        b_ornamentstr *pp = (b_ornamentstr *)p;
        debug_printf("Ornament %s x=%f y=%f bflags=%d\n",
          ornstrings[pp->ornament], pp->x, pp->y, pp->bflags);
        }
      break;

      case b_page:
      debug_printf("Page %s%d\n", (((b_pagestr *)p)->relative == 0)? "" : "+",
        ((b_pagestr *)p)->value);
      break;

      case b_pagebots:
      debug_printf("Bottommargin %f\n", ((b_pagebotsstr *)p)->value);
      break;

      case b_pagetops:
      debug_printf("Topmargin %f\n", ((b_pagetopsstr *)p)->value);
      break;

      case b_playchange:
      debug_printf("Playchange\n");
      break;

      case b_plet:
        {
        b_pletstr *pp = (b_pletstr *)p;
        int flags = pp->flags;
        debug_printf("Plet %d ", pp->pletlen);
        if ((flags & plet_a)  != 0) debug_printf("/a");
        if ((flags & plet_b)  != 0) debug_printf("/b");
        if ((flags & plet_bn) != 0) debug_printf("/bn");
        if ((flags & plet_by) != 0) debug_printf("/by");
        if ((flags & plet_x)  != 0) debug_printf("/x");
        if ((flags & plet_lx) != 0) debug_printf("/lx");
        if ((flags & plet_rx) != 0) debug_printf("/rx");
        if ((flags & plet_abs)!= 0) debug_printf("/abs");
        debug_printf(" %f, %f, %f\n", pp->x, pp->yleft, pp->yright);
        }
      break;

      case b_prevbar:
      debug_printf("Prevbar %d %d %d\n", ((b_prevbarstr *)p)->dbar,
        ((b_prevbarstr *)p)->ibar, ((b_prevbarstr *)p)->style);
      break;

      case b_reset:
      debug_printf("Reset\n");
      break;

      case b_resume:
      debug_printf("Resume\n");
      break;

      case b_rrepeat:
      debug_printf("Right repeat\n");
      break;

      case b_setclef:
      debug_printf("Assume clef %s\n", clefstrings[((b_setclefstr *)p)->value]);
      break;

      case b_setkey:
      debug_printf("Assume key %k\n", ((b_setkeystr *)p)->value);
      break;

      case b_settime:
      debug_printf("Assume time %t\n", ((b_settimestr *)p)->value);
      break;

      case b_sghere:
      case b_sgnext:
        {
        b_sgstr *pp = (b_sgstr *)p;
        debug_printf("%s %c %f\n", (type == b_sghere)? "Sghere":"Sgnext",
          (pp->opt)? pp->opt : ' ', pp->value);
        }
      break;

      case b_slope:
      debug_printf("beamslope %f\n", ((b_slopestr *)p)->value);
      break;

      case b_slur:
        {
        b_slurstr *pp = (b_slurstr *)p;
        int flags = pp->flags;
        debug_printf("Slur id=%c flags=", (pp->id == 0)? ' ':pp->id);
        if ((flags & sflag_w) != 0) debug_printf("/w");
        if ((flags & sflag_b) != 0) debug_printf("/b");
        if ((flags & sflag_l) != 0) debug_printf("/l");
        if ((flags & sflag_h) != 0) debug_printf("/h");
        if ((flags & sflag_ol) != 0) debug_printf("/ol");
        if ((flags & sflag_or) != 0) debug_printf("/or");
        if ((flags & sflag_i) != 0) debug_printf("/i");
        if ((flags & sflag_e) != 0) debug_printf("/e");
        if ((flags & sflag_x) != 0) debug_printf("/x");
        debug_printf(" ally=%f\n", pp->ally);
        }
      break;

      case b_slurgap:
      debug_printf("Slurgap\n");
      break;

      case b_slurmod:
      debug_printf("Slurmod\n");
      break;

      case b_space:
      debug_printf("Space %f\n", ((b_spacestr *)p)->value);
      break;

      case b_ssabove:
      case b_sshere:
      case b_ssnext:
        {
        b_ssstr *pp = (b_ssstr *)p;
        debug_printf("%s %d %c %f\n", (type == b_ssabove)? "Ssabove" :
          (type == b_sshere)? "Sshere":"Ssnext",
            pp->stave, (pp->opt)? pp->opt : ' ', pp->value);
        }
      break;

      case b_suspend:
      debug_printf("Suspend\n");
      break;

      case b_text:
        {
        b_textstr *pp = (b_textstr *)p;
        uschar *ss = pp->string;
        int flags = pp->flags;
        BOOL absolute = (flags & text_absolute) != 0;

        debug_printf("Text %s \"", fontnames[pp->font]);
        if ((flags & text_ul) != 0)
          {
          int i;
          for (i = 0; i < pp->ulen; i++) debug_printf("%c", *ss++);
          }
        else debug_printf("%s", ss);
        debug_printf("\"");

        if ((flags & text_fb) != 0) debug_printf("/fb");
        if ((flags & text_ul) != 0)
          {
          if ((flags & text_above) != 0)
            debug_printf("/ol%d", pp->ulevel);
              else debug_printf("/ul%d", pp->ulevel);
          }

        else if ((flags & text_above) != 0)
          {
          debug_printf("/a");
          if (absolute) debug_printf("%f", pp->y);
          }
        else if (absolute) debug_printf("/b%f", pp->y);

        if ((flags & text_atulevel) != 0)
          {
          if ((flags & text_above) != 0)
            debug_printf("/ao");
              else debug_printf("/bu");
          }

        if ((flags & text_baralign) != 0) debug_printf("/bar");
        if ((flags & text_box) != 0) debug_printf("/box");
        if ((flags & text_centre) != 0) debug_printf("/c");
        if ((flags & text_endalign) != 0) debug_printf("/e");
        if ((flags & text_middle) != 0) debug_printf("/m");
        if ((flags & text_rehearse) != 0) debug_printf("/R");
        if ((flags & text_ps) != 0) debug_printf("/ps");
        if ((flags & text_ring) != 0) debug_printf("/ring");

        if (pp->size != 0) debug_printf("/s%d", pp->size + 1);

        if (pp->x < 0) debug_printf("/l%f", -pp->x);
        if (pp->x > 0) debug_printf("/r%f",  pp->x);

        if (!absolute)
          {
          if (pp->y > 0) debug_printf("/u%f",  pp->y);
          if (pp->y < 0) debug_printf("/d%f", -pp->y);
          }

        if (pp->htype != 0) debug_printf("/htype=%d", pp->htype);
        }
      debug_printf("\n");
      break;

      case b_textX:
      debug_printf("TextX %f %f %f\n", ((b_textXstr *)p)->rotate,
        ((b_textXstr *)p)->halfway, ((b_textXstr *)p)->offset);
      break;

      case b_tick:
      debug_printf("Tick\n");
      break;

      case b_tie:
        {
        b_tiestr *pp = (b_tiestr *)p;
        int flags = pp->flags;
        if (flags >= 4) debug_printf("Glissando\n");
        if ((flags & 3) != 0)
          debug_printf("Tie %d/%d\n", pp->abovecount, pp->belowcount);
        }
      break;

      case b_time:
        {
        b_timestr *pp = (b_timestr *)p;
        debug_printf("Time %t%s%s\n", pp->time, pp->warn? "" : " nowarn",
          pp->suppress? " suppress" : "");
        }
      break;

      case b_tremolo:
        {
        b_tremolostr *pp = (b_tremolostr *)p;
        debug_printf("Tremolo /x=%d /j=%d\n", pp->count, pp->join);
        }
      break;

      case b_tripsw:
      debug_printf("Triplets %s\n", (((b_tripswstr *)p)->value)? "on" : "off");
      break;

      case b_ulevel:
        {
        b_ulevelstr *pp = (b_ulevelstr *)p;
        debug_printf("Ulevel ");
        if (pp->opt == TRUE) debug_printf("*\n");
        else debug_printf("%f\n", pp->value);
        }
      break;

      case b_ulhere:
      debug_printf("Ulhere %f\n", ((b_ulherestr *)p)->value);
      break;

      case b_unbreakbarline:
      debug_printf("Unbreakbarline\n");
      break;

      case b_zcopy:
      debug_printf("Zcopy %d\n", ((b_zcopystr *)p)->value);
      break;

      default:
      debug_printf("**** UNKNOWN ITEM TYPE %d ****\n", type);
      break;
      }

    if (type < 0 || type >= b_baditem) break;
    p = (bstr *)((uschar *)p + length_table[type]);
    type = p->type;
    }

  if (((b_Endstr *)p)->overbeam) debug_printf("Overbeam\n");
  debug_printf("\n");
  }
}






#ifdef Debug

/* The remaining functions that follow were used in the early days when I was
debugging on the Acorn. They have been cut out for a long time now, but I
retain them in the source, just in case they are needed again some day. */


/*************************************************
*          Detailed debugging routines           *
*************************************************/


static uschar *stemswapstrings[] = { "default", "up", "down", "left", "right" };



/*************************************************
*            Display a vector                    *
*************************************************/

static void debug_print_vector(uschar *name, uschar *format, int *v,
  int first, int last)
{
int i;
uschar *c = "";
debug_printf("%s = ", name);
for (i = first; i <= last; i++) { debug_printf(format, c, v[i]); c = ", "; }
debug_printf("\n");
}


/*************************************************
*            Display a stave list                *
*************************************************/

static void debug_print_list(uschar *s, stave_list *p)
{
debug_printf("%s = ", s);

if (p == (stave_list *)(-1)) debug_printf("all\n");

else if (p == NULL) debug_printf("empty\n"); else
  {
  uschar buff[256];
  format_sprintf(buff, "%L", p);
  debug_printf("%s\n", buff);
  }
}


/*************************************************
*            Display a stave map                 *
*************************************************/

static int debug_print_map(uschar *s, usint *map)
{
int i;
int last;
uschar *c = "";
debug_printf("%s = ", s);

for (i = 0; i <= MAX_STAVE; i++)
  {
  if (mac_teststave(map, i))
    {
    int s = i;
    while (++i <= MAX_STAVE && mac_teststave(map, i));
    if (s == i-1) debug_printf("%s%d", c, s);
      else debug_printf("%s%d-%d", c, s, i-1);
    last = i-1;
    c = ", ";
    }
  }

debug_printf("\n");
return last;
}



/*************************************************
*           Display text headings                *
*************************************************/

static void debug_heading(uschar *s, headstr *p)
{
while (p != NULL)
  {
  if (p->size < 0)
    {
    tree_node *t = p->drawing;
    debug_printf("%s draw %s %f\n", s, t->name, p->space);
    }
  else
    {
    debug_printf("%s %f \"%s\" %f\n", s, p->size, p->text, p->space);
    }
  p = p->next;
  }
}


/*************************************************
*               Display justify value            *
*************************************************/

static void debug_print_justify(int value)
{
debug_printf("justify = ");
if (value == just_all) debug_printf("all"); else
  {
  if ((value & just_top) != 0) debug_printf("top ");
  if ((value & just_bottom) != 0) debug_printf("bottom ");
  if ((value & just_left) != 0) debug_printf("left ");
  if ((value & just_right) != 0) debug_printf("right ");
  }
debug_printf("\n");
}


/*************************************************
*             Show global variables              *
*************************************************/

void debug_showglobals(void)
{
ptimestr *p = main_printtime;
trkeystr *k = main_transposedkeys;

debug_printf("GLOBAL DATA\n");

debug_printf("Format = %s\n", main_format);
debug_printf("Landscape = %B\n", opt_landscape);
debug_printf("Magnification = %f\n", main_magnification);
debug_printf("Maxvertjustify = %f\n", main_maxvertjustify);
debug_printf("Oldbeambreak = %B\n", opt_oldbeambreak);
debug_printf("Page = %d\n", main_firstpage);
debug_printf("Pagelength = %f = %f\n", main_truepagelength, main_pagelength);

while (p != NULL)
  {
  debug_printf("Printtime %t = \"%s\"/s%d \"%s\"/s%d\n",
    p->time, p->top, p->offsettop+1, p->bot, p->offsetbot+1);
  p = p->next;
  }

debug_printf("Transposedacc = %s\n", main_transposedaccforce?
  "force" : "noforce");

while (k != NULL)
  {
  debug_printf("Transposedkey %k use %k\n", k->oldkey, k->newkey);
  k = k->next;
  }

if (main_pssetup != NULL) debug_heading("Pssetup", main_pssetup);

debug_printf("Totalbars = %d\n", main_totalbars);

/**** Font table
debug_printf("fontcount = %d base count = %d\n", font_count,
  font_basecount);
for (i = 0; i < font_count; i++)
  debug_printf("%s %s %s\n", font_List[i].scname, font_List[i].psname,
    font_List[i].filename);
****/

/**** Fonts in use
for (i = 1; i < font_xx + MaxExtraFont; i++)
  {
  uschar *s = font_List[font_table[i]].psname;
  if (s == NULL) s = "NULL";
  debug_printf("Font %s = %s = %s\n", font_IdStrings[i],
    font_List[font_table[i]].scname, s);
  }
****/

debug_printf("\n");
}



/*************************************************
*          Show heading for movement             *
*************************************************/

void debug_showmovement(int n)
{
int i;
uschar *comma;
movtstr *m;

if (n == 0) n = 1;
m = movement[n];

if (m == NULL) { debug_printf("No data for movement %d\n", n); return; }

debug_printf("Heading data for movement %d\n", n);

debug_heading("Heading", m->heading);
debug_heading("Footing", m->footing);
debug_heading("Pageheading", m->pageheading);
debug_heading("Pagefooting", m->pagefooting);
debug_heading("Lastfooting", m->lastfooting);


debug_print_vector("accadjusts", "%s%f", m->accadjusts, 0, 7);
debug_print_vector("accspacing", "%s%f", m->accspacing, 0, 5);

debug_printf("barcount = %d\n", m->barcount);

if (m->barlinespace == 0x80000000)
  debug_printf("barlinespace = unset\n");
    else debug_printf("barlinespace = %f\n", m->barlinespace);

debug_printf("barlinestyle = %d\n", m->barlinestyle);
debug_printf("barno_textflags = %x\n", m->barno_textflags);
debug_printf("barno_interval = %d\n", m->barno_interval);
debug_printf("beamthickness = %f\n", m->beamdepth);
debug_printf("baroffset = %d\n", m->baroffset);
debug_printf("botmargin = %f\n", m->botmargin);

debug_print_list("bracelist", m->bracelist);
debug_print_list("bracketlist", m->bracketlist);
debug_print_map("breakbarlines", m->breakbarlines);

debug_printf("beamendrests = %B\n", m->beamendrests);
debug_printf("breverests = %B\n", m->breverests);
debug_printf("breveledgerextra = %f\n", m->breveledgerextra);
debug_printf("caesurastyle = %d\n", m->caesurastyle);
debug_printf("check = %s\n", m->check? "true":"false");
debug_printf("checkdoublebars = %B\n", m->checkdoublebars);
debug_printf("dotspacefactor = %f\n", m->dotspacefactor);
debug_printf("extenderlevel = %f\n", m->extenderlevel);

debug_printf("font_time = %s\n", fontnames[m->font_time]);
debug_printf("font_triplet = %s\n", fontnames[m->font_triplet]);

debug_printf("fontsize_barno = %f\n", m->fontsizes->fontsize_barno);
debug_printf("fontsize_clefs = %f\n", m->fontsizes->fontsize_clefs);
debug_printf("fontsize_cue = %f\n", m->fontsizes->fontsize_cue);
debug_printf("fontsize_cuegrace = %f\n", m->fontsizes->fontsize_cuegrace);
debug_printf("fontsize_grace = %f\n", m->fontsizes->fontsize_grace);
debug_printf("fontsize_music = %f\n", m->fontsizes->fontsize_music);
debug_printf("fontsize_rehearse = %f\n", m->fontsizes->fontsize_rehearse);
debug_printf("fontsize_repno = %f\n", m->fontsizes->fontsize_repno);
debug_printf("fontsize_restct = %f\n", m->fontsizes->fontsize_restct);

comma = "";
debug_printf("fontsize_text = ");
for (i = 0; i < MaxFontSizes; i++)
  {
  debug_printf("%s%f", comma, m->fontsizes->fontsize_text[i]);
  comma = ", ";
  }
debug_printf("\n");

debug_printf("fontsize_trill = %f\n", m->fontsizes->fontsize_trill);
debug_printf("fontsize_triplet = %f\n", m->fontsizes->fontsize_triplet);

debug_printf("fontsize_tsfont = %f\n", (m->fontsizes->fontsize_text)[ff_offset_tsfont]);
debug_printf("fontsize_ulay = %f\n", (m->fontsizes->fontsize_text)[ff_offset_ulay]);
debug_printf("fontsize_olay = %f\n", (m->fontsizes->fontsize_text)[ff_offset_olay]);
debug_printf("fontsize_fbass = %f\n", (m->fontsizes->fontsize_text)[ff_offset_fbass]);

debug_printf("fullbarend = %B\n", m->fullbarend);
debug_printf("gracespacing = %f %f\n", m->gracespacing[0],
  m->gracespacing[1]);
debug_printf("gracestyle = %d\n", m->gracestyle);
debug_printf("hairpinlinewidth = %f\n", m->hairpinlinewidth);
debug_printf("hairpinwidth = %f\n", m->hairpinwidth);
debug_printf("hyphenstring = \"%s\"\n", m->hyphenstring);
debug_printf("hyphenthreshold = %f\n", m->hyphenthreshold);

debug_print_list("joinlist", m->joinlist);
debug_print_list("joindottedlist", m->joindottedlist);
debug_print_justify(m->justify);
debug_printf("key = %k\n", m->key);
debug_printf("keydoublebar = %B\n", m->keydoublebar);
debug_printf("keywarn = %B\n", m->keywarn);
debug_printf("laststave = %d\n", m->laststave);

if (m->leftmargin == -1)
  debug_printf("leftmargin = unset\n");
    else debug_printf("leftmargin = %f\n", m->leftmargin);

debug_printf("linelength = %f = %f\n", m->truelinelength, m->linelength);
debug_printf("maxbarcount = %d\n", m->maxbarcount);
debug_printf("movt_opt = %d\n", m->movt_opt);

comma = "";
debug_printf("notespacing = ");
for (i = 0; i < 8; i++)
  {
  debug_printf("%s%f", comma, curmovt->notespacing[i]);
  comma = ", ";
  }
debug_printf("\n");

debug_printf("overlaydepth = %f\n", m->overlaydepth);
debug_printf("play_tempo = %d\n", m->play_tempo);
debug_printf("rehearsalstyle = %d\n", m->rehearsalstyle);
debug_printf("repeatstyle = %d\n", m->repeatstyle);
debug_printf("showtime = %B\n", m->showtime);
debug_printf("showtimebase = %B\n", m->showtimebase);
debug_printf("spreadunderlay = %B\n", m->spreadunderlay);

debug_printf("startbracketbar = %d\n", m->startbracketbar);
debug_printf("startjoin = %B\n", m->startjoin);
debug_printf("startlinespacing = %f, %f, %f, %f\n",
  m->startline->clefspace, m->startline->keyspace,
    m->startline->timespace, m->startline->notespace);

debug_printf("startnotime = %B\n", m->startnotime);
debug_print_map("staves", m->staves);

for (i = 0; i <= m->laststave; i++)
  {
  stavestr *s = m->stavetable[i];
  if (s != NULL)
    {
    snamestr *p = s->stave_name;
    if (p != NULL)
      {
      debug_printf("stavenames %d =", i);
      while (p != NULL)
        {
        debug_printf(" \"%s\"", p->text);
        if ((p->flags & snf_hcentre) != 0) debug_printf("/m");
        if (p->offset != ff_offset_init) debug_printf("/s%d", p->offset+1);
        debug_printf("(%d)", p->linecount);
        if (p->drawing != NULL)
          {
          debug_printf(" draw");
          if (p->args != NULL)
            {
            int i;
            for (i = 1; i <= p->args[0]; i++) debug_printf(" %d", p->args[i]);
            }
          debug_printf(" %s", (p->drawing)->name);
          }
        p = p->next;
        }
      debug_printf("\n");
      }
    }
  }

debug_printf("stavesizes = ");
for (i = 1; i <= MAX_STAVE; i++)
  {
  int size = (m->stavesizes)[i];
  if (size != 1000) debug_printf("%d/%f ", i, size);
  }
debug_printf("\n");

if (m->stave_spacing != NULL)
  {
  int *x = m->stave_spacing;
  int *y = m->stave_ensure;
  for (i = 0; i <= m->laststave; i++)
    if (x[i] != 44000 || y[i] != 0)
      debug_printf("stavespacing %d/%f/%f\n", i, y[i], x[i]);
  }

debug_printf("stemswaptype = %s\n", stemswapstrings[m->stemswaptype]);

for (i = 0; i <= m->laststave; i++)
  if (m->stemswaplevel[i] != P_3L)
    debug_printf("stemswaplevel %d = %d\n", i, m->stemswaplevel[i]);

debug_print_map("suspend", m->suspend);
debug_printf("systemgap = %f\n", m->systemgap);
debug_printf("time = %t\n", m->time);
debug_printf("timewarn = %B\n", m->timewarn);
debug_printf("topmargin = %f\n", m->topmargin);
debug_printf("transpose = %d\n", m->transpose);
debug_printf("trillstring = \"%s\"\n", m->trillstring);
debug_printf("underlaydepth = %f\n", m->underlaydepth);
debug_printf("unfinished = %B\n", m->unfinished);
debug_printf("\n");
}



/*************************************************
*             Show stave data                    *
*************************************************/

void debug_showstave(int n, int s)
{
int i;
if (n == 0) n = 1;
debug_printf("\nMOVEMENT %d STAVE %d\n\n", n, s);
for (i = 1; i <= (movement[n]->stavetable[s])->lastbar; i++)
  debug_showbar(n, s, i);
}



/*************************************************
*           Show a bar's positioning data        *
*************************************************/

/* Subroutine to give length symbolically if possible */

static void symb_length(int moff, uschar *s)
{
if (moff == 0) sprintf(s, "   "); else
if (moff % len_minim == 0)    sprintf(s, "%2dm", moff/len_minim); else
if (moff % len_crotchet == 0) sprintf(s, "%2dc", moff/len_crotchet); else
if (moff % len_quaver == 0)   sprintf(s, "%2dq", moff/len_quaver); else
if (moff % len_squaver == 0)  sprintf(s, "%2ds", moff/len_squaver); else
if (moff % len_dsquaver == 0) sprintf(s, "%2dd", moff/len_dsquaver); else
sprintf(s, "   ");
}

/* The real function */

void debug_showbarpos(int m, int b)
{
barposstr *bp;
posstr *p;
int count;
uschar s[10];

if (m == 0) m = 1;
bp = ((movement[m])->posvector) + b;
p = bp->vector;
count = bp->count;

format_movt = movement[m];
debug_printf("Bar positioning data for bar %b movement %d\n", b, m);
debug_printf("posxRL = %s barnoX = %f barnoY = %f multi = %d force = %d\n",
  (bp->posxRL == -posx_RLleft)? "left" : "right",
    bp->barnoX, bp->barnoY, bp->multi, bp->barnoforce);

symb_length(p->moff, s);
debug_printf("%7d %s %5d %6d\n", p->moff, s, 0, p->xoff);

p++;
count--;

while (count--)
  {
  symb_length(p->moff, s);
  debug_printf("%7d %s %5d %6d\n", p->moff, s, p->xoff - (p-1)->xoff, p->xoff);
  p++;
  }
}



/*************************************************
*              Show page data                    *
*************************************************/

void debug_showpage(int n)
{
sysblock *s;
pagestr *p = main_pageanchor;

if (n == 0) n = 1;

while (p != NULL && n != p->number) p = p->next;
if (p == NULL)
  {
  debug_printf("\nPAGE %d DATA NOT FOUND\n", n);
  return;
  }

debug_printf("\nPAGE %d: topspace = %f spaceleft = %f overrun = %f\n", n,
  p->topspace, p->spaceleft, p->overrun);

s = p->sysblocks;
while (s != NULL)
  {
  if (s->type == sh_heading)
    {
    debug_printf("\n%sHEADING BLOCK\n", (((headblock *)s)->pageheading)?
      "PAGE ":"");
    debug_heading("heading", ((headblock *)s)->headings);
    }
  else
    {
    contstr *cont = s->cont;
    int flags = s->flags;
    int i, laststave;

    debug_printf("\nSYSTEM\n"
                 "warnkey = %B\n"
                 "warntime = %B\n"
                 "stretch = %B\n"
                 "noadvance = %B\n",
        flags & sysblock_warnkey,
        flags & sysblock_warntime,
        flags & sysblock_stretch,
        flags & sysblock_noadvance);
    debug_printf("bars %d to %d\n", s->barstart, s->barend);
    debug_printf("xjustify = %f\n", s->xjustify);
    debug_printf("barlinewidth = %f\n", s->barlinewidth);
    debug_printf("startxposition = %f\n", s->startxposition);
    debug_printf("joinxposition = %f\n", s->joinxposition);
    debug_printf("keyxposition = %f\n", s->keyxposition);
    debug_printf("timexposition = %f\n", s->timexposition);
    debug_printf("firstnoteposition = %f\n", s->firstnoteposition);

    laststave = debug_print_map("staves", s->notsuspend);

    if (s->stavenames != NULL)
      {
      snamestr **p = s->stavenames;
      for (i = 1; i <= laststave; i++)
        if (p[i] != NULL) debug_printf("text %d = \"%s\"\n", i, p[i]->text);
      }

    if (laststave > 1)
      debug_print_vector("stavespacing", "%s%f", s->stavespacing,1,laststave-1);

    debug_printf("systemdepth = %f\n", s->systemdepth);
    debug_printf("systemgap = %f\n", s->systemgap);

    debug_print_vector("olevel", "%s%f", s->olevel, 1, laststave);
    debug_print_vector("ulevel", "%s%f", s->ulevel, 1, laststave);

    debug_printf("CONT STRUCTURES\n");
    for (i = 0; i <= laststave; i++)
      {
      debug_printf("stave %d: ", i);
      if (cont->slurs) debug_printf("slurs ");
      if (cont->hairpin) debug_printf("hairpin ");
      if (cont->nbar) debug_printf("nbar ");
      if (cont->tie) debug_printf("tie ");
      if (cont->ulay) debug_printf("ulay ");
      if (cont->overbeam) debug_printf("overbeam ");

      debug_printf("\n");
      cont++;
      }

    }
  s = s->next;
  }

if (p->footing != NULL && (p->footing)->headings != NULL)
  {
  debug_printf("\nFOOTINGS\n");
  debug_heading("footing", (p->footing)->headings);
  }
}

#endif

/* End of debug.c */
