/*
 * Main file for the Demeter tree-prop tool.
 *
 * cd-abstract finds the maximal class dictionary from which both the two 
 * given class dictionaries are extensions. The two class dictionaries 
 * must be in ANTI-CDCNF!
 *
 * $Log: main.C,v $
 * Revision 5.4.1.2  1994/10/13  02:09:07  demeter
 * *** empty log message ***
 *
 * Revision 5.4.1.1  1994/05/12  19:59:14  demeter
 * *** empty log message ***
 *
 * Revision 5.4  1994/05/12  19:59:13  demeter
 * *** empty log message ***
 *
 * Revision 5.3.1.1  1994/01/26  19:07:52  huersch
 *  No changes.
 *
 * Revision 5.3  1994/01/26  19:07:50  huersch
 * *** empty log message ***
 *
 * Revision 5.2.1.1  1994/01/24  18:47:23  huersch
 *  No changes.
 *
 * Revision 5.2  1994/01/24  18:47:14  huersch
 * *** empty log message ***
 *
 * Revision 5.1.1.1  1993/11/15  15:12:59  demeter
 * *** empty log message ***
 *
 * Revision 5.1  1993/11/15  15:12:58  demeter
 * *** empty log message ***
 *
 * Revision 5.0.1.2  1993/10/12  16:07:25  huersch
 * Uniformed and beautified code, added new command line evaluation.
 *
 */


#include "cdabs.h"
#include <iostream.h>
#include <string.h>

void out_of_store()
{
   cerr << "cd-abstract: operator new failed, out of store.\n";
   exit( 1 );
}

#ifndef __GNUC__
extern PF set_new_handler( PF );
#else
extern "C"  PF set_new_handler( PF );
#endif

extern int _demeter_hash(const char* classname);
int greeting = _demeter_hash("Greeting");



char *GEN_DIR = getenv("GEN_DIR");

Adjacency_Nlist* new_anl = new Adjacency_Nlist();

void abstract(Cd_graph* cd1, Cd_graph* cd2)
{
  Cd_graph* ret_graph;
  if (ret_graph = cd1->abstract(cd2)) { 
    cout << "\nTHE ABSTRACTED GRAPH : \n\n";
    ret_graph->g_print();}
  else {
    cout << "\nNO COMMON ABSTRACTION \n";
  }
}

int main( int argc, char *argv[],char *envp[] )
{
  if (GEN_DIR == NULL)
    GEN_DIR = "./scanner/";   // just to make sure

  // command line evaluation
  const int MAXPATH = 256;
  char dem_in1[MAXPATH];
  char dem_in2[MAXPATH];
  switch ( argc ) {
  case 1: 
    strcpy( dem_in1, "demeter-input" );          // default argument
    strcpy( dem_in2, "demeter-input2" );         // default argument
    break;
  case 2: 
    strcpy( dem_in1, "demeter-input" );          // default argument
    strcpy( dem_in2, argv[1] );
    break;
  case 3: 
    strcpy( dem_in1, argv[1] );
    strcpy( dem_in2, argv[2] );
    break;
  default: 
    cerr << "\nUsage: cd-abstract [[class-dictionaray1] class-dictionary2].\n" 
	 << "\nDefault arguments:\n"
	 << "   cd1 -- demeter-input\n"
	 << "   cd1 -- demeter-input2\n"
	 << endl;
    exit( 1 );
  }
  
  set_new_handler( &out_of_store );
  
  cout << "***   CD-ABSTRACT   ***\n\n"
       << "Note: the two class dictionary must be in ANTI-CDCNF" << endl;

  cout << "\n Parsing class dictionary 1.\n";
  Demeter_in *iDemeter_in1 = new Demeter_in();
  iDemeter_in1 = ( Demeter_in * ) iDemeter_in1 -> g_parse( dem_in1 );
  if ( !iDemeter_in1 ) {
    cerr << "cd-abstract error: parsing " << dem_in1 << " failed." << endl;
    exit ( 1 );
  }

  cout << "\n Parsing class dictionary 2.\n";
  Demeter_in *iDemeter_in2 = new Demeter_in();
  iDemeter_in2	 = ( Demeter_in * ) iDemeter_in2 -> g_parse( dem_in2 );
  if ( !iDemeter_in2 ) {
    cerr << "cd-abstract error: parsing " << dem_in2 << " failed." << endl;
    exit ( 1 );
  }
  cout << endl;

  // Finally, run actual abstraction algorithm.
  abstract((Cd_graph*)iDemeter_in1->get_input(),
	   (Cd_graph*)iDemeter_in2->get_input());
  cout << endl;

  return ( 0 );
}
