/*
 *                      ***************
 *                      * X R F 3 . C *
 *                      ***************
 *
 * Sorted cross reference listing routines. 'prtree' performs an
 * inorder traversal of the id tree, printing the references to'
 * each id while visiting that node.
 *
 * Version V1.3          9-May-80
 * Version V1.4		10-Jul-80 MM	Bummed code, added 80 col. support
 */

#include <stdio.h>
#include "xrf.h"


/*
 * Inorder tree traversal.
 */

prtree(link)
struct idt *link;

   {
   if (link != NULL)
      {
      prtree(link->left);       /* Visit the left */
      prtrefs(link);            /* Print refs for this one */
      prtree(link->right);      /* Visit the right */
      }
   }

/*
 * List out a line of references.
 * Start new page if it gets full.
 */

lstrefs()
   {
   if(++linpg > MAXLIN)                 /* New page if necessary */
      newpage();
   fputss(scanbf, lst);                 /* Write out the string */
   }

/*
 * Print id and references.
 * Share scan buffer for printout.
 * Use newpag.
 *
 * The ref line number field width is hard-wired into the format statement.
 * Trouble is, #define's don't (and shouldn't!) substitute into strings,
 * like formats.
 *
 * Current values are 5 char field (RSIZE) and rperline ref's per line.
 */

prtrefs(link)
struct idt *link;

   {
   register struct ref *r;              /* Ref chain pointer */
   register char *p;                    /* Fast scan buffer pointer */
   register int j;                      /* Counts refs printed on a line */

   char *cpystr();                      /* cpystr returns char pointer */

   r = link->first;                     /* r --> head of ref chain */
   p = scanbf;                          /* p --> start of scan buffer */
   j = 0;                               /*Init refs-per-line */

   p = cpystr(p, link->keyp);           /* Start with the id string */
   while(p < &scanbf[NCPS])             /* Pad with blanks */
         *p++ = ' ';
   *p++ = '\t';                         /* Followed by a tab */
   do
      {                                 /* List Reference line numbers */
      if(j >= rperline)                 /* If this line is full */
         {
         *p = '\0';                     /* Terminate with null */
         lstrefs();                     /* Write it out */
         p = scanbf;                    /* Reset buffer pointer */
         j = 0;                         /* Reset refs-on-line count */
         *p++ = '\t';                   /* Start cont. line w/ 2 tabs */
	 *p++ = '\t';
         }
      j++;
      sprintf(p,"%5d", r->lno);         /* Insert reference into buffer */
      p += RSIZE;                       /* Update buffer pointer */
      r = r->next;                      /* On down the chain */
      }
   while(r != NULL);                    /* Until the end */
   *p = '\0';                           /* Terminate with null */
   lstrefs();                           /* Write the line out */
   }
