/******************************************************
 *      adtxr.c: cross reference generator
 ******************************************************/
/***********************************
   (C) Copyright 1992-1993; dit/upm
   Distributed under the conditions stated in the
   TOPO General Public License (see file LICENSE)
 ***********************************
$Log: adtxr.c,v $
 * Revision 1.16  1994/10/17  16:37:55  lotos
 * fix argument analysis
 *
 * Revision 1.15  1993/10/08  18:30:14  lotos
 * antiguas extensiones .lsa y .at pasan a .ls y .as respectivamente
 *
 * Revision 1.14  1993/06/16  13:59:08  lotos
 * detect unknown options
 *
 * Revision 1.13  1993/06/16  13:51:06  lotos
 * code cleaning, no functionality change
 *
 * Revision 1.12  1993/01/18  18:10:25  lotos
 * distribution issues
 *
 * Revision 1.11  1993/01/12  20:19:45  lotos
 * portability issues
 *
 * Revision 1.10  1992/09/12  10:45:22  lotos
 * fix headers inclusion: version
 *
 * Revision 1.9  1992/02/21  17:12:48  lotos
 * adapted to new lfe
 * better presentation of reports
 *
 * Revision 1.8  92/01/14  15:23:04  lotos
 * distribution issues
 *
 * Revision 1.7  92/01/13  19:05:16  lotos
 * new options,
 * new interface to .at
 *
 * Revision 1.6  91/02/28  17:18:52  lotos
 * rule 'premiss ::= _value_expression' removed
 *
 * Revision 1.5  90/10/30  09:38:26  lotos
 * adapted to new CAST
 *
 * Revision 1.4  90/07/06  20:33:22  lotos
 * add option -n to list single types
 *
 * Revision 1.3  90/06/06  11:27:14  lotos
 * fix help message
 *
 * Revision 1.2  90/06/04  10:38:43  lotos
 * types are classified into
 * basic: not importing any other
 * constructed: importing others (via union, rename, or act)
 * used by others
 * not used by any other
 * those build by renaming of other
 * those built by actualizing other
 *
 * options are mutually exclusive
 *
 * Revision 1.1  90/05/11  12:53:17  lotos
 * Initial revision
 *
 ***********************************/

#ifndef lint
static char rcsid[]= "$Id: adtxr.c,v 1.16 1994/10/17 16:37:55 lotos Exp $";
#endif

# include "swbus.h"

/* KJT 11/03/98: added for NS/OS */

#ifdef __NeXT__
char *strdup(s) register char *s; {

  register char *ns;

  return(((ns=malloc(strlen(s)+1))==0)?0:strcpy(ns,s)); }
#endif

PRIVATE FILE *spefile = NULL; /* specification ast file */
PRIVATE FILE *satfile = NULL; /* specification at  file */
PRIVATE FILE *libfile = NULL; /* library ast file       */
PRIVATE FILE *latfile = NULL; /* library at  file       */

PRIVATE TNODE *speroot = NULL; /* specification AST root */
PRIVATE TNODE *satroot = NULL; /* specficiation at  root */
PRIVATE TNODE *libroot = NULL; /* library AST root       */
PRIVATE TNODE *latroot = NULL; /* library at  root       */

PRIVATE	TIOCOLOURS iocolours [] = {
# include "colours.c"
	"dec",        c_dec,        IO_int,
	"typexr",     c_typexr,     IO_ign,
	"type_class", c_type_class, IO_int,
	"lib_used",   c_lib_used,   IO_int, /* boolean, in fact */
	"is_lib",     c_is_lib,     IO_int, /* also a boolean */
	NULL,         others,       IO_ign
	};

PUBLIC ST   *SLTable  = NULL; /* specification ll table */
PUBLIC AT   *SATable  = NULL; /* specification at table */
PUBLIC ST   *LLTable  = NULL; /* library ll table       */
PUBLIC AT   *LATable  = NULL; /* library at table       */

PUBLIC char *progname = NULL;

PRIVATE FILE*
efopen (filename, mode)
  char* filename, *mode;
{
  FILE* fp;

  if ((fp= fopen (filename, mode)) == NULL) {
    (void) fprintf (stderr, "%s: cannot open file %s mode %s\n",
		    progname, filename, mode);
    exit (1);
  }
  return fp;
}

PRIVATE void
help ()
{
  (void) fprintf (stderr, "usage: %s -o<name> [-<opts>]\n", progname);
  (void) fprintf (stderr, "\t\t-o<name> specification name\n");
  (void) fprintf (stderr, "\t Options:\n");
  (void) fprintf (stderr, "\t\t-l<library>\n");
  (void) fprintf (stderr, "\t\t-u types not used by others ones\n");
  (void) fprintf (stderr, "\t\t-U types used by others ones\n");
  (void) fprintf (stderr, "\t\t-b basic types\n");
  (void) fprintf (stderr, "\t\t-c constructed types\n");
  (void) fprintf (stderr, "\t\t-r types which renames another\n");
  (void) fprintf (stderr, "\t\t-a types which actualizes another\n");
  (void) fprintf (stderr, "\t\t-n<typename> print only <typename>\n");
  (void) fprintf (stderr, "\t\t-i<typename> types which import <typename>\n");
  (void) fprintf (stderr, "\t   default: full information\n");
}

int main	(argc, argv)
     int argc;
     char* argv[];
{
  char	*specname = NULL, /* specification name without extension */
	*libname  = NULL, /* library       name without extension */
	*sname    = NULL, /* <specname>.lsa                       */
	*atname   = NULL, /* <specname>.at                        */
	*lname    = NULL, /* <libname>.lsa                        */
	*latname  = NULL; /* <libname>.at                         */
  int   basic         = FALSE,
	constructed   = FALSE,
	renames       = FALSE,
	actualizes    = FALSE,
	debugging     = FALSE,
	type_not_used = FALSE,
	type_used     = FALSE,
	named_type    = FALSE,
	imported_type = FALSE;
  char  *named, *imported;
  TNODE *aux = NULL;

  progname = argv[0];
  while (argc > 1) {
    if (argv[1][0] == '-') {
      switch (argv[1][1]) {
      case 'a' : actualizes    = TRUE; break;
      case 'b' : basic         = TRUE; break;
      case 'c' : constructed   = TRUE; break;
      case 'd' : debugging     = TRUE; break;
      case 'i' :
	imported_type = TRUE;
	imported = strdup (&(argv[1][2]));
	if (strlen (imported) == 0) {
	  (void)fprintf (stderr, "%s: missing type name\n",
			 progname);
	  help(); exit(1);
	}
	break;
      case 'h' : help(); exit(0);
      case 'l' :
	libname = strdup (&(argv[1][2]));
	break;
      case 'n' :
	named_type = TRUE;
	named = strdup (&(argv[1][2]));
	if (strlen (named) == 0) {
	  (void)fprintf (stderr, "%s: missing type name\n",
			 progname);
	  help(); exit(0);
	}
	break;
      case 'o' :
	specname = strdup (&(argv[1][2]));
	break;
      case 'r' : renames       = TRUE; break;
      case 'u' : type_not_used = TRUE; break;
      case 'U' : type_used     = TRUE; break;
	default :
	  (void)fprintf (stderr, "%s: unknown option %s\n",
			 progname, argv[1]);
	  help(); exit(1);
      }
    }
    else {
      help ();
      exit (1);
    }
    argc--;
    argv++;
  }

  if (specname == NULL) {
    help ();
    exit (1);
  }

  cast_init (iocolours);

  if (strlen (specname) != 0){
    sname  = emalloc ((strlen (specname) + 4)*sizeof(char));
    atname = emalloc ((strlen (specname) + 4)*sizeof(char));

    (void)sprintf (sname, "%s.ls", specname);
    (void)sprintf (atname, "%s.as", specname);

    spefile = efopen (sname, "r");
    satfile = efopen (atname, "r");

    speroot = restore (spefile);
    satroot = restore (satfile);

    grnl = (IAT*) find_attr (c_grnl, speroot)->value;
    grnl->class = 1;
    SLTable = (ST*) find_attr (c_ll, satroot)->value;
    SATable = (AT*) find_attr (c_at, satroot)->value;
  }

  rag (speroot);		/* Table creation from the AST */

  if (libname != NULL)
    if (strlen (libname)) {
      lname   = emalloc ((strlen (libname) + 4)*sizeof(char));
      latname = emalloc ((strlen (libname) + 4)*sizeof(char));

      (void)sprintf (lname, "%s.ls", libname);
      (void)sprintf (latname, "%s.as", libname);

      libfile = efopen (lname, "r");
      latfile = efopen (latname, "r");

      libroot = restore (libfile);
      latroot = restore (latfile);

      grnl = (IAT*) find_attr (c_grnl, libroot)->value;
      grnl->class = 1;
      LLTable = (ST*) find_attr (c_ll, latroot)->value;
      LATable = (AT*) find_attr (c_at, latroot)->value;

      for (aux = gt_fs (libroot); aux != NULL; aux = gt_rb (aux)) {
	set_attr (c_is_lib, aux, (CLR_TYPE) TRUE);
      }
      visit (libroot);
      rag (libroot);
    }

  if (debugging)
    save_tree (stderr, speroot);
  if (tsroot == NULL) {
    (void) printf ("No data types in specification <%s>\n", specname);
    exit (0);
  }

  if (type_not_used || type_used || basic ||
      constructed || renames || actualizes ||
      named_type || imported_type ) {
    if (type_not_used) {
      (void)fprintf (stdout, "\n------- TYPES NOT USED -------\n");
      print_ts (type_not_used, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, "");
    }
    if (type_used) {
      (void)fprintf (stdout, "\n------- TYPES USED -------\n");
      print_ts (FALSE, type_used, FALSE, FALSE, FALSE, FALSE, FALSE, "");
    }
    if (constructed) {
      (void)fprintf (stdout, "\n------- CONSTRUCTED TYPES -------\n");
      print_ts (FALSE, FALSE, constructed, FALSE, FALSE, FALSE, FALSE, "");
    }
    if (basic) {
      (void)fprintf (stdout, "\n------- BASIC TYPES -------\n");
      print_ts (FALSE, FALSE, FALSE, basic, FALSE, FALSE, FALSE, "");
    }
    if (renames) {
      (void)fprintf (stdout, "\n------- TYPES WITH RENAMING -------\n");
      print_ts (FALSE, FALSE, FALSE, FALSE, renames, FALSE, FALSE, "");
    }
    if (actualizes) {
      (void)fprintf (stdout, "\n------- TYPES WITH ACTUALIZING -------\n");
      print_ts (FALSE, FALSE, FALSE, FALSE, FALSE, actualizes, FALSE, "");
    }
    if (named_type && (0 != strcmp ("", named))) {
      (void)fprintf (stdout, "\n------- TYPE %s -------\n", named);
      print_item (name_search (named), "");
    }
    if (imported_type && (0 != strcmp ("", imported))) {
      (void)fprintf (stdout, "\n------- TYPE %s -------\n", imported);
      print_ts (FALSE, FALSE, FALSE, FALSE, FALSE,
		FALSE, imported_type, imported);
    }
  }
  else print_ts (FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, "");
						/* Table impresion */
  exit (0);
  return 0;
}

