/*
 ***********************************************************************
 *
 *                           Coryright (c)
 *    © Digital Equipment Corporation 1995. All rights reserved.
 *
 *    Restricted Rights: Use, duplication, or disclosure by the U.S.
 *    Government is subject to restrictions as set forth in subparagraph
 *    (c) (1) (ii) of DFARS 252.227-7013, or in FAR 52.227-19, or in FAR
 *    52.227-14 Alt. III, as applicable.
 *
 *    This software is proprietary to and embodies the confidential
 *    technology of Digital Equipment Corporation and other parties.
 *    Possession, use, or copying of this software and media is authorized
 *    only pursuant to a valid written license from Digital or an
 *    authorized sublicensor.
 *
 ***********************************************************************
 *    File Name:	report.c
 *    Author:		John Bartels
 *    Creation Date:07/21/95
 *
 *    Functionality:
 * REPORT.C: this source file contains all of the display functions 
 *  which can be used to generate various types of reports about the 
 *  file/variable relationships. 
 *
 ***********************************************************************
 *    Revision History:
 *  reporting available: 7/21/95 - print all files which refer to each var
 *                       8/03/95 - add reporting by files using var, vars in
 *                                 a file, and unused but declared vars
 *                       8/31/95 - added time/date stamp to banners at top of
 *                                 reports
 */
   #include <stdio.h>  
   #include <stdlib.h>
   #include <string.h>
   #include <time.h>
   #include "defdecs.h"
                                    
/* vars from glblclvr.c */
   extern FILE * OUTFILE;
   extern struct variable * VarHead;
          
   void Display (struct lister *), AllVars (char * name), 
        VarUsedIn (char *, char *), VarsByFile (char *, char *),
        UnusedReport (char *);

/* DISPLAY: print out the list of all files discovered in makefile */           
   void Display (struct lister * current) {
      
      switch (current->data->type) {
/* for target nodes */
  	     case 0:
	        fprintf(OUTFILE, "\n%s\n", current->data->name);
	        break;
/* for source nodes */
	     case 1:
            fprintf(OUTFILE, "\t%s\n", current->data->name);
	        break;
/* for hdr nodes */
	     case 2:
	        fprintf(OUTFILE, "\t\t%s\n", current->data->name);
	        break;
      }
      if (current->data->includes)
         Display (current->data->includes);
      if (current->next)
         Display (current->next);
   }  
                                                           
       
/* ALL VARS generates a listing of all variables for which declarations
   have been found, and tells in which files they were declared and used.
   Report is written to the output file specified.
*/                                                           
   void AllVars (char * dest_name) {
      FILE * dest_fp;
      char time[9], date[9];
      struct variable * current = NULL;
      struct lister * user = NULL;
      
      if (!(dest_fp = fopen (dest_name, "w"))) {
         printf ("Error generating output file!\n");
         exit (1);
      }                                  

/* put a banner at the top of the file */      
      fprintf (dest_fp, "File generated by glblclvr.exe at %s on %s.\n", _strtime (time), _strdate (date));
      fprintf (dest_fp, "\nThis file contains a list of all global DECtalk variables, and shows where\n");
      fprintf (dest_fp, "they are declared, and where they are referenced.\n\n");                            
      
/* traverse the var list */      
      if (VarHead) { 
         current = VarHead;
         
/* print every entry in the list */
         while (current) {
            fprintf (dest_fp, "\nName: %32s  Dec'd: %32s\n", 
            current->name, current->declared_in->data->name);       
                        
/* traverse the list of files using the var, and print every entry in the
   list
*/                   
            if (current->used_by) {
               user = current->used_by;
               while (user) {
                  fprintf (dest_fp, "%38s  ", user->data->name);
                  if (user->next) {
                     user= user->next;
                     fprintf (dest_fp, "%39s", user->data->name);
                  }
                  user = user->next;
                  fprintf (dest_fp, "\n");
               }
            }        
            current= current->next;
         } 
      }
   }           
   
   
   
  
/* VAR USED IN: takes a variable name and the name of the desired 
   output file as arguments, and generates a list of all files which use
   the given variable, as well as the target under which it is declared.
   Results are written to that output file.
*/
  
   
   void VarUsedIn (char * goal_var, char * out_name) { 
      FILE * out_file;                                  
      struct variable * current; 
      struct lister * user;
      char time[9], date[9];
      
      if (! (out_file = fopen (out_name, "w"))) {
         printf ("Couldn't write to file %s!\n", out_name);
         exit(1);
      }
 
/* put a banner at the top of the file */      
      fprintf (out_file, "File generated by glblclvr.exe at %s on %s.\n", _strtime (time), _strdate (date));
      fprintf (out_file, "\nThis file contains a list of all DECtalk files which refer to the\n");
      fprintf (out_file, "variable '%s'.\n\n", goal_var);                   
                               
                         
/* traverse var list */   
      if (VarHead) {
         current = VarHead;
         while (current) {
            if (strcmp (current->name, goal_var) == 0) {
               if (current->used_by) {
                  user = current->used_by;
                  while (user) {
                     fprintf (out_file, "file: %s\n", user->data->name);
                     fprintf (out_file, "target: %s\n", user->parents_name);
                     fprintf (out_file, "\n");
                     user = user->next;
                  }
               } 
            }
            current = current->next;        
         } 
      }  
      fclose (out_file);
   }
                       
                       
                       
                                                                 
                                                                 
/* VARS BY FILE: generates a report of all of the variables which are 
   used in a given goal file, and writes the results to the file  
   out_name.
*/                                           
   void VarsByFile (char * goal_file, char * out_name) {    
      FILE * out_file;
      struct variable * current;
      struct lister * user;                                    
      char time[9], date[9];
      
      if (! (out_file = fopen (out_name, "w"))) {
         printf ("Could write to file %s!\n", out_file);
         exit(1);
      }                                          
                
/* put a banner at the top of the file */      
      fprintf (out_file, "File generated by glblclvr.exe at %s on %s.\n", _strtime (time), _strdate (date));
      fprintf (out_file, "\nThis file contains a list of all variables which appear in the\n");
      fprintf (out_file, "DECtalk file '%s'.\n\n", goal_file);  
                      
/* traverse the variable list... */
      if (VarHead) {
         current = VarHead;
         while (current) {
         
/* traverse the list of all files using this var, searching for entries
   which match the goal file name...
*/         
            if (current->used_by) {
               user = current->used_by;
               while (user) {
                  if (strcmp (goal_file, user->data->name) == 0) {
                     fprintf (out_file, "Var:    %s\n", current->name);
                     fprintf (out_file, "Parent: %s\n\n", user->parents_name);
                  }
                  user = user->next;
               }
            }
            current = current->next;
         }
      }
      fclose (out_file);
   }                                           
  
  
  
   
/* UNUSED REPORT: generates a report of all of the variables which are
   declared but never used inside the system. Writes results to file
   out_name
*/  
   
   void UnusedReport (char * out_name) {
      FILE * out_file; 
      struct variable * current;                        
      char time[9], date[9];
      if (! (out_file = fopen (out_name, "w"))) {
         printf ("Couldn't write to file %s!\n", out_name);
         exit(1);
      }    

/* put a banner at the top of the file */      
      fprintf (out_file, "File generated by glblclvr.exe at %s on %s.\n", _strtime (time), _strdate (date));
      fprintf (out_file, "\nThis file contains a list of all DECtalk global variables which are\n");
      fprintf (out_file, "suspected to be unused.\n\n");
 
/* traverse var list looking for unused vars */ 
      if (VarHead) {
         current = VarHead;
         while (current) {
            if (!current->used_by) {                             
               if (current->pd_def_flag) 
                  fprintf (out_file, "Warning: #def'd, only MAYBE ");
               fprintf (out_file, "Unused:   %s\n", current->name); 
/*             fprintf (out_file, "Under Target: %s\n", current->target_name);  */
               fprintf (out_file, "Declared: %s\n\n", current->declared_in->data->name);
            }                    
            current = current->next;
         }
      }
      fclose (out_file);
   }