/*
  Copyright Dave Bone 1998 - 2014
  All Rights Reserved. 
  No part of this document may be reproduced without written consent from the author.
	
FILE:		o2_err_hdlr.lex
Date:	  	8 Jul 2003
Purpose:	grammar to process errors from yacco2
Conduit:	none
Change:		11 Mar 2004 - replace tab with space so that
                          displaced error lines up properly
*/
/@
@i "/yacco2/copyright.w"
@** |o2_err_hdlr| grammar.\fbreak
Grammar that processes for printing posted errors from yacco2.
@/
fsm	
(fsm-id "testout_err_hdlr.lex",fsm-filename testout_err_hdlr,fsm-namespace NS_testout_err_hdlr
,fsm-class Ctestout_err_hdlr
,fsm-version "1.0",fsm-date "8 Jul 2003",fsm-debug "false"
,fsm-comments "Logic sequencer: Print out errors from testout grammars - pager_1.")
@"/usr/local/yacco2/grammar-testsuite/testout_T_includes.T"
rules{
Rtestout_err_hdlr (){
  -> Rerrors eog
  -> eog
}

Rerrors (){
  -> Rerror
  -> Rerrors Rerror
}

Rerror	(
lhs{
  user-declaration
  void error_where(CAbs_lr1_sym* E_sym){
    std::string ext_fle;
      if(E_sym->tok_co_ords__.external_file_id__<yacco2::FILE_TBL__.size()){
        ext_fle = yacco2::FILE_TBL__[E_sym->tok_co_ords__.external_file_id__];
}else{
        ext_fle = "File not found";
}
    std::string line_of_data;
    std::ifstream ifile;
    ifile.open(ext_fle.c_str());
    if(ifile.good()){
        yacco2::UINT lno(1);yacco2::UINT dlno(E_sym->tok_co_ords__.line_no__);
        for(;lno<=dlno;++lno){
          getline(ifile,line_of_data);
          if(lno == dlno) break;
          line_of_data.clear();
        }      
    }      

    std::string space(" ");
    std::string::size_type f = line_of_data.find_first_of('\t');
    for(;f != std::string::npos;){
     line_of_data.replace(f,1,space);
     f = line_of_data.find_first_of('\t');
    }
    
    yacco2::lrclog << "Error in file#: " << E_sym->tok_co_ords__.external_file_id__
		<< " \"" << ext_fle.c_str() << "\"" << std::endl;
	yacco2::lrclog << line_of_data.c_str() << std::endl;
    std::cout << "Error in file#: " << E_sym->tok_co_ords__.external_file_id__
		<< " \"" << ext_fle.c_str() << "\"" << std::endl;
	std::cout << line_of_data.c_str() << std::endl;
	for(int pos = 1;pos < E_sym->tok_co_ords__.pos_in_line__;++pos){
	 yacco2::lrclog << ' ';
	 std::cout << ' ';
	}
	yacco2::lrclog << '^' << std::endl;
	yacco2::lrclog << "\tfpos: " << E_sym->tok_co_ords__.rc_pos__
		<< " line#: " << E_sym->tok_co_ords__.line_no__
		<< " cpos: " << E_sym->tok_co_ords__.pos_in_line__
		<< std::endl;
	std::cout << '^' << std::endl;
	std::cout << "\tfpos: " << E_sym->tok_co_ords__.rc_pos__
		<< " line#: " << E_sym->tok_co_ords__.line_no__
		<< " cpos: " << E_sym->tok_co_ords__.pos_in_line__
		<< std::endl;
		if(E_sym->tok_co_ords__.who_file__ != 0){
			yacco2::lrclog << "\twho thru it: " << E_sym->tok_co_ords__.who_file__
				<< " line#: " << E_sym->tok_co_ords__.who_line_no__
				<< std::endl;
			std::cout << "\twho thru it: " << E_sym->tok_co_ords__.who_file__
				<< " line#: " << E_sym->tok_co_ords__.who_line_no__
				<< std::endl;
		}
    ifile.close();
  };
  ***
}
){
  -> "no filename" {
  op
   error_where(sf->p1__);
   yacco2::lrclog << "\t" << sf->p1__->id__ << std::endl;
   std::cout << "\t" << sf->p1__->id__ << std::endl;
  ***
  }      
  -> "bad filename" {
  op
   error_where(sf->p1__);
   yacco2::lrclog << "\t" << sf->p1__->id__
   << " filename: \"" << sf->p1__->file_name()->c_str()
   << "\" does not exist" << std::endl;
   std::cout << "\t" << sf->p1__->id__
   << " filename: \"" << sf->p1__->file_name()->c_str()
   << "\" does not exist" << std::endl;
  ***
  }     
  -> |+| {// catch balance of errors
  op
   error_where(sf->p1__);
   yacco2::lrclog << "\t" << sf->p1__->id__ << std::endl;
   std::cout << "\t" << sf->p1__->id__ << std::endl;
  ***
  }
}  
}// end of rules
