//-----------------------------------------------------------------
// main.C.sample 
// This file is an example for a main.C Demeter main file.
// It provides sample code fragments showing how to use some of the 
// Demeter runtime libraries. To have a quick test of your environment 
// rename this file to main.C and compile the environment. 
//-----------------------------------------------------------------
#include "UNKNOWN.h"

void out_of_store()
{
  cerr << "UNKNOWN: 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

/*
 * GEN_DIR is a global variable containing the path of the generation
 * environment. This path is used to find the cd-print and cd-parse
 * class dictionaries.
 * Do NOT delete the following statement.
 */

char* GEN_DIR = getenv( "GEN_DIR" );

int main( int argc, char* argv[], char* envp[] )
{
  // set new handler to catch out of memory exception
  set_new_handler( &out_of_store );

  int checkll1 = 1;
  int producefiles = 0;

  //----------------------------------------
  // Parsing an object 
  //----------------------------------------
  // specify file to parse in 
  const int MAXPATH = 256;
  char Dem_input[MAXPATH];
  int i;

  // Input file is first argument
  strcpy(Dem_input, "demeter-input");
  for (i = 2; i <= argc; i++) {

    if (argv[i-1][0] == '-') {
      if (argv[i-1][1] == 'n') checkll1 = 0;
      if (argv[i-1][1] == 'i') producefiles = 1;
    }
    else {
     strcpy( Dem_input, argv[i-1] );
   }
  }

  // parse it in 
//  cout << "Parsing in object in: " << Dem_input << "." << endl;
  Cd_graph* iCd_graph = new Cd_graph();
  if ( ( Cd_graph* ) iCd_graph -> g_parse( Dem_input ) == NULL )
  {
     cerr << "Parser error." << endl;
     exit(1);
  }

  //----------------------------------------
  // Your own code follows after this 
  //----------------------------------------
  cout << endl;

  int success = 1;

  success &= iCd_graph->check_class_names();

  success &= iCd_graph->check_first_class();

  success &= iCd_graph->check_classes();

  success &= iCd_graph->check_repetition();

  success &= iCd_graph->check_parameters();

  success &= iCd_graph->check_formal_classes();

  success &= iCd_graph->check_alternation_params();

  success &= iCd_graph->check_cycle_free();

  if (success) {

    if (producefiles) {
//      mkdir("notmod/cds", 0755);
      success &= iCd_graph->expand_params("cd-param-exp");
    }
    else {
      success &= iCd_graph->expand_params(NULL);
    } 

    if (success) {

      success &= iCd_graph->check_alternatives();

      success &= iCd_graph->check_keywords();

      if (producefiles) {
        success &= iCd_graph->expand_common("cd-com-exp");
      }
      else {
        success &= iCd_graph->expand_common(NULL);
      } 

      if (producefiles) {
        success &= iCd_graph->expand_inherit("cd-inh-exp");
      }
      else {
        success &= iCd_graph->expand_inherit(NULL);
      } 

      success &= iCd_graph->check_part_names();

      iCd_graph->check_inductiveness();


    }

  }

  if (!success) {
    cout << endl << "Semantic check failed." << endl;
    exit(1);
  }
 
  cout << endl << "Semantic check passed." << endl;
  return ( 0 );
}



