/******************************************************
 *      lxref.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: lxref.c,v $
 * Revision 2.12  1993/10/08  18:29:03  lotos
 * Nuevas opciones -L -A para modificar extensiones por defecto
 *    del .ls y el .as respecitivamente.
 * Antigua opcion -L pasa a -l (Care!)
 *
 * Revision 2.11  1993/06/16  14:05:48  lotos
 * code cleaning
 * unknown options
 *
 * Revision 2.10  1993/01/18  18:10:59  lotos
 * distribution issues
 *
 * Revision 2.9  1993/01/12  20:19:54  lotos
 * portability issues
 *
 * Revision 2.8  1992/02/21  17:13:59  lotos
 * adapted to new lfe
 * better presentation of reports
 *
 * Revision 2.7  92/01/14  15:23:48  lotos
 * distribution issues
 *
 * Revision 2.6  92/01/13  19:31:09  lotos
 * identification of names
 * adaption to phuscation
 *
 * Revision 2.5  92/01/13  16:59:57  lotos
 * mil cositas, nuevos flags, adaptado al .AT, ...
 *
 * Revision 2.4  91/02/28  19:30:58  lotos
 * adapted to lack of rule 'premiss ::= _value_expression'
 * adapted to information contained in AT
 *
 * Revision 2.3  90/10/30  14:18:31  lotos
 * adapted to compressed CAST
 *
 * Revision 2.2  90/06/04  10:37:56  lotos
 * unused items may be printed apart
 *
 * Revision 2.1  90/06/01  15:06:51  lotos
 * handles identifier classification
 *
 * Revision 1.3  90/03/16  17:50:48  lotos
 * cosmetics
 *
 * Revision 1.2  90/01/29  13:13:56  lotos
 * fixing license details
 *
 * Revision 1.1  90/01/22  12:50:08  lotos
 * Initial revision
 *
 ***********************************/

#ifndef lint
static char rcsid[]= "$Id: lxref.c,v 2.12 1993/10/08 18:29:03 lotos Exp $";
#endif

# include "swbus.h"

#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* specfile = NULL;
PRIVATE FILE* alfile   = NULL;

PRIVATE	TIOCOLOURS iocolours [] = {
# include "colours.c"

	"dec",        c_dec,        IO_int,
	"sname",      c_sname,      IO_int,
	"legend",     c_legend,     IO_IL,
	"aux_legend", c_aux_legend, IO_IL,
	"gateoval",   c_gateoval,   IO_int,
	"isname",     c_isname,     IO_int,
	/* isname is used for indicating that sort_identifiers */
	/* and operation_identifiers appear as renaming or */
	/* actualization. This implies that they are not really */
	/* sorts or operations, only names for them. Hence, there */
	/* are neither iddec nor idref for them, only lexv */
	NULL,         others,       IO_ign
	};

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;
}

PUBLIC char *progname = NULL;

PUBLIC AT*     ATable = NULL;

void
help ()
{
  (void)fprintf (stderr, "usage: lxref -n<name> [options]\n");
  (void)fprintf (stderr, "\t\t-n<name> specification name\n");
  (void)fprintf (stderr, "\toptions:\n");
  (void)fprintf (stderr, "\t\t-L <lsa_extension> Extension for the lsa\n");
  (void)fprintf (stderr, "\t\t-A <at_extension> Extension for the .at\n");
  (void)fprintf (stderr, "\t\t-l after sintactic analysis only\n");
  (void)fprintf (stderr, "\t\t-u items not used\n");
  (void)fprintf (stderr, "\t\t-b only lines\n");
  (void)fprintf (stderr, "\t\t-g gates\n");
  (void)fprintf (stderr, "\t\t-p processes\n");
  (void)fprintf (stderr, "\t\t-t types\n");
  (void)fprintf (stderr, "\t\t-s sorts\n");
  (void)fprintf (stderr, "\t\t-S formal sorts\n");
  (void)fprintf (stderr, "\t\t-P Specification\n");
  (void)fprintf (stderr, "\t\t-v values\n");
  (void)fprintf (stderr, "\t\t-o operations\n");
  (void)fprintf (stderr, "\t\t-O formal operations\n");
  (void)fprintf (stderr, "\t\t-N names (sort-names & operation-names)\n");
  (void)fprintf (stderr, "\t\t-c classified\n");
  (void)fprintf (stderr, "\t\t-h help\n");
  (void)fprintf (stderr, "\t   default full information\n");
}

/* KJT 20/01/23: added "int" type */
int main (argc, argv)
     int argc;
     char* argv[];
{
  char	 *specname = NULL, *alname = NULL, *lname = NULL,
	 *lsaext = NULL, *atext = NULL;
  TNODE  *astroot = NULL;		/* AST root creation*/
  TNODE  *alroot = NULL;
  int    i;
  char   c;
  int    lfe_yes = FALSE;
  int    only_nlines = FALSE;
  int    debugging = FALSE;
  int    classified = FALSE;
  int    e_spec = FALSE;
  int    e_proc = FALSE;
  int    e_gate = FALSE;
  int    e_type = FALSE;
  int    e_sort = FALSE;
  int    e_fsrt = FALSE;
  int    e_val  = FALSE;
  int    e_opn  = FALSE;
  int    e_fopn = FALSE;
  int    e_name = FALSE;
  int    item_not_used = FALSE;  /* if TRUE, list items not used */

  progname = argv[0];
  while (argc > 1) {
    if (argv[1][0] == '-') {
      i = 0;
      while ((c = argv[1][++i]) != '\0')
	switch (c) {
	case 'L' :
	  if (argc > 2) {
	    lsaext = argv[2];
	    argc--;
	    argv++;
	  }
	  else {
	    help (); exit (1);
	  }
	  break;
	case 'A' :
	  if (argc > 2) {
	    atext = argv[2];
	    argc--;
	    argv++;
	  }
	  else {
	    help (); exit (1);
	  }
	  break;
	case 'b' : only_nlines   = TRUE; break;
	case 'c' : classified    = TRUE; break;
	case 'd' : debugging     = TRUE; break;
	case 'g' : e_gate        = TRUE; break;
	case 'h' : help(); exit(0);
	case 'l' : lfe_yes       = TRUE; break;
	case 'n' : specname = strdup(&(argv[1][++i]));
	  i = strlen(argv[1]) - 1;
	  break;
	case 'N' : e_name        = TRUE; break;
	case 'o' : e_opn         = TRUE; break;
	case 'O' : e_fopn        = TRUE; break;
	case 'p' : e_proc        = TRUE; break;
	case 'P' : e_spec        = TRUE; break;
	case 's' : e_sort        = TRUE; break;
	case 'S' : e_fsrt        = TRUE; break;
	case 't' : e_type        = TRUE; break;
	case 'u' : item_not_used = TRUE; break;
	case 'v' : e_val         = 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);
  }

  if ( !e_gate && !e_proc && !e_type && !e_sort &&
       !e_spec && !e_opn  && !e_val  && !e_fsrt &&
       !e_fopn && !e_name ) {
    e_gate = TRUE; e_proc = TRUE; e_type = TRUE;
    e_sort = TRUE; e_spec = TRUE; e_val  = TRUE;
    e_opn  = TRUE; e_fsrt = TRUE; e_fopn = TRUE;
    e_name = TRUE;
  }                             /* default: all options */

  cast_init (iocolours);

  if (strlen (specname) != 0) {
    if (!lfe_yes) {     /* Using LSA and AT */
      if (atext != NULL) {
	alname = emalloc ((strlen(specname) + strlen(atext) + 2)*sizeof(char));
	(void)sprintf (alname, "%s.%s", specname, atext);
      }
      else {
	alname  = emalloc ((strlen (specname) + 6)*sizeof(char));
	(void)sprintf (alname, "%s.as", specname);
      }

      if (lsaext != NULL) {
	lname = emalloc ((strlen(specname) + strlen(lsaext) + 2)*sizeof(char));
	(void)sprintf (lname, "%s.%s", specname, lsaext);
      }
      else {
	lname  = emalloc ((strlen (specname) + 6)*sizeof(char));
	(void)sprintf (lname, "%s.ls", specname);
      }

      specfile = efopen (lname, "r");
      alfile = efopen (alname, "r");

      astroot = restore (specfile);
      grnl = (IAT*) find_attr (c_grnl, astroot)->value;
      grnl->class = 1;
      alroot = restore (alfile);
      SymbolTable= (ST*) find_attr (c_ll, alroot)->value;
      ATable = (AT*) find_attr (c_at, alroot)->value;
    }
    else {      /* Using LFE */
      if (lsaext != NULL) {
	lname = emalloc ((strlen(specname) + strlen(lsaext) + 2)*sizeof(char));
	(void)sprintf (lname, "%s.%s", specname, lsaext);
      }
      else {
	lname  = emalloc ((strlen (specname) + 6)*sizeof(char));
	(void)sprintf (lname, "%s.lfe", specname);
      }

      specfile = efopen (lname, "r");

      astroot = restore (specfile);
      SymbolTable= (ST*) find_attr (c_ll, astroot)->value;
      grnl = (IAT*) find_attr (c_grnl, astroot)->value;
      grnl->class = 1;
    }
  }

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

  if (debugging) {
    save_tree (stderr, astroot);
    exit(0);
  }

  if (classified) {
     if (e_spec)
       print_ts (item_not_used, only_nlines, FALSE, FALSE,
		 FALSE, FALSE, e_spec, FALSE, FALSE, FALSE,
		 FALSE, e_name);
     if (e_proc)
       print_ts (item_not_used, only_nlines, FALSE, e_proc,
		 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
		 FALSE, e_name);
     if (e_type)
       print_ts (item_not_used, only_nlines, FALSE, FALSE,
		 e_type, FALSE, FALSE, FALSE, FALSE, FALSE,
		 FALSE, e_name);
     if (e_sort)
       print_ts (item_not_used, only_nlines, FALSE, FALSE,
		 FALSE, e_sort, FALSE, FALSE, FALSE, FALSE,
		 FALSE, e_name);
     if (e_opn)
       print_ts (item_not_used, only_nlines, FALSE, FALSE,
		 FALSE, FALSE, FALSE, FALSE, e_opn, FALSE,
		 FALSE, e_name);
     if (e_gate)
       print_ts (item_not_used, only_nlines, e_gate, FALSE,
		 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
		 FALSE, e_name);
     if (e_val)
       print_ts (item_not_used, only_nlines, FALSE, FALSE,
		 FALSE, FALSE, FALSE, e_val, FALSE, FALSE,
		 FALSE, e_name);
     if (e_fsrt)
       print_ts (item_not_used, only_nlines, FALSE, FALSE,
		 FALSE, FALSE, FALSE, e_val, FALSE, e_fsrt,
		 FALSE, e_name);
     if (e_fopn)
       print_ts (item_not_used, only_nlines, FALSE, FALSE,
		 FALSE, FALSE, FALSE, e_val, FALSE, FALSE,
		 e_fopn, e_name);
     if (e_name)
       print_ts (item_not_used, only_nlines, FALSE, FALSE,
		 FALSE, FALSE, FALSE, e_val, FALSE, FALSE,
		 FALSE, e_name);
  }
  else
  print_ts (item_not_used, only_nlines, e_gate, e_proc,
	    e_type, e_sort, e_spec, e_val, e_opn, e_fsrt,
	    e_fopn, e_name);
				/* Table impresion             */
  exit (0);
  return 0;
}
