/**
 *  handling error occured due to failed assertion
 * this error handler only works during parser phase since it uses
 * Token_t to know the line number

 * TODO: we need to make this function more general
 **/
void 
fortran_error_handler(int signum)
{
  // get the current filename 
  std::string sFilename = getCurrentFilename();
  if (sFilename.size()==0) {
     fprintf(stderr, "ERROR while parsing the source code\n");
  } else {
    
    SgScopeStatement* scope = astScopeStack.front();
    SgStatement* lastStatement = scope;
    SgStatementPtrList statementList = scope->generateStatementList();
    if (statementList.empty() == false)
       {
         lastStatement = statementList.back();
       }
    int lineNumberOfLastStatement = (astScopeStack.empty() == false) ? lastStatement->get_file_info()->get_line() : 0;
    // get the latest token parsed
    if (lineNumberOfLastStatement > 0)
      std::cerr <<"FATAL ERROR in file "<<sFilename<<":"<<lineNumberOfLastStatement<<std::endl;
    else
     std::cerr <<"FATAL ERROR while parsing "<<sFilename<<std::endl;
  }
  fflush(NULL); // flush all stdio
  fortran_error_handler_end();
  exit(-1);
}
void
MidLevelRewrite<MidLevelInterfaceNodeCollection>::
insert (
   SgStatement* target,
   const string & transformationString,
   ScopeIdentifierEnum inputRelativeScope,
   PlacementPositionEnum locationInScope )
   {
     ROSE_ASSERT (target != NULL);

#if 0
     printf ("MidLevelRewrite<MidLevelInterfaceNodeCollection>::insert(): inputRelativeScope = %s \n",
          MidLevelCollectionTypedefs::getRelativeScopeString(inputRelativeScope).c_str());
#endif

  // Error Reporting
  // Test to see if this is a supported statement (a few are not supported in the rewrite mechanism)
     if ( insertSupported(target,inputRelativeScope) == false )
        {
          printf ("ERROR (MidLevelRewrite<MidLevelInterfaceNodeCollection>::insert): \n");
          printf ("     This %s statement is not currently supported (or not supported \n",target->sage_class_name());
          printf ("     in its position relative to other statements) within the AST Rewrite Mechanism. \n");
          printf ("Work Around: \n");
          printf ("     Use the parent node as a target instead (and specify corresponding appropriate (longer) string. \n");
          printf ("     exiting ... \n");
          ROSE_ABORT();
        }

  // Use a more general interface to allow relative strings to be used in the high level interface 
  // even though they are not required mid level interface.
     MidLevelInterfaceNodeCollection stringAndNodeCollection;

  // DQ (1/15/2003): Needed to add handling of StatementScope insert handling.
  // The specification for scope can be either surrounding scope of statement scope
  // If it is statement scope then the target must contain a list of statements.
     ScopeIdentifierEnum scope = inputRelativeScope;

     if (scope == MidLevelCollectionTypedefs::StatementScope)
        {
       // Not clear if this is a sufficent test
          ROSE_ASSERT (isSgScopeStatement(target) != NULL);

       // Now specify a new target (use any statement inside the scope pointer to by target)
       // printf ("Before resetting target is a: %s \n",target->sage_class_name());

       // Not clear if this works for ALL scope statements!          
          SgScopeStatement* scope = isSgScopeStatement(target);
          ROSE_ASSERT (scope != NULL);
          SgStatementPtrList statementList = scope->generateStatementList();
          resetTargetStatementAndLocation (target,statementList,locationInScope);

       // Reset the target to a statement in the scope pointed to by the target
          ROSE_ASSERT (target != NULL);

       // printf ("Reset target is a: %s \n",target->sage_class_name());
       // printf ("Reset target location is: %s \n",MidLevelCollectionTypedefs::getRelativeLocationString(locationInScope).c_str());
        }

     bool buildInNewScope = false;
     TransformationStringTemplatedType<MidLevelCollectionTypedefs> 
          transformation (target,transformationString,scope,locationInScope,buildInNewScope);

#if 0
     transformation.display("In mid level insert");
#endif
#if 0
     printf ("After display ... exiting ... \n");
     ROSE_ASSERT (false);
#endif

     stringAndNodeCollection.addString(target,transformation);

#if 0
  // PreamblePositionInScope = 1 /*!< Source code to be placed at the top of a specified scope */ ,
  // TopOfCurrentScope       = 2 /*!< Top of scope (current location must be a scope)  */ ,
  // BeforeCurrentPosition   = 3 /*!< Before  */ ,
  // ReplaceCurrentPosition  = 4 /*!< Replace */ ,
  // AfterCurrentPosition    = 5 /*!< After   */ ,
  // BottomOfCurrentScope    = 6 /*!< Bottom of scope (current location must be a scope)  */ ,
#endif

  // Be careful to include/exclude the current statement when generating the prefix!
     bool prefixIncludesCurrentStatement = true;
     switch(locationInScope)
        {
          case MidLevelCollectionTypedefs::TopOfCurrentScope:
          case MidLevelCollectionTypedefs::BeforeCurrentPosition:
          case MidLevelCollectionTypedefs::ReplaceCurrentPosition:
               prefixIncludesCurrentStatement = false;
               break;

          case MidLevelCollectionTypedefs::AfterCurrentPosition:
          case MidLevelCollectionTypedefs::BottomOfCurrentScope:
               prefixIncludesCurrentStatement = true;
               break;

          default:
               printf ("Error, default reached in MidLevelRewrite<MidLevelInterfaceNodeCollection>::insert() \n");
               ROSE_ASSERT (false);
        }

#if 0
     printf ("In MidLevelRewrite<MidLevelInterfaceNodeCollection>::insert() prefixIncludesCurrentStatement = %s \n",
          (prefixIncludesCurrentStatement == true) ? "true" : "false");
#endif

     stringAndNodeCollection.writeAllChangeRequests(target,prefixIncludesCurrentStatement);

#if 0
     printf ("Exiting in MidLevelRewrite<MidLevelInterfaceNodeCollection>::insert() \n");
     ROSE_ABORT();
#endif
   }