diff --git a/src/file_io.cpp b/src/file_io.cpp index 626c517ecf79765f22be632466c359a910715227..5bbe81a739233adfd98cf60ee617bb2a728a3aed 100644 --- a/src/file_io.cpp +++ b/src/file_io.cpp @@ -17,7 +17,7 @@ #include "gar.h" #include "myexception.h" #include "file_io.h" -#include "../yaml/include/yaml.h" +#include "yamc.h" using namespace std; @@ -26,17 +26,6 @@ namespace NFileIO { void Load_01( FILE *F_in, string flong ); void LoadScan_01( FILE *F_in, CScan* sout, int nz ); void Load_96( FILE *F_in, string flong ); - yaml_parser_t parser; - yaml_event_t event; - string last_valid; - void y_next(); - void y_done(); - void y_checktype( int type, string errmsg ); - void y_checkvalue( string value ); - void y_skipvalues( int repet ); - bool y_scalar_from_seq( string seqname, string *ret ); - string y_getscalar( string scalarname ); - bool y_getCoord( string label, CCoord *co ); } //! Load file in current or legacy format. @@ -84,94 +73,6 @@ void NFile::Load(void) } } -void NFileIO::y_next() -{ - if( !yaml_parser_parse( &parser, &event) ) - throw string( "Invalid input? Last valid entry was \"" ) + - last_valid + "\""; -} - -void NFileIO::y_done() -{ - yaml_event_delete( &event); -} - -void NFileIO::y_checktype( int type, string errmsg ) -{ - y_next(); - if( event.type != type ) - throw errmsg; - if( event.type == YAML_SCALAR_EVENT ) - last_valid = (const char*)event.data.scalar.value; - y_done(); -} - -void NFileIO::y_checkvalue( string value ) -{ - y_next(); - if( event.type != YAML_SCALAR_EVENT ) - throw string("No scalar while expecting ") + value; - if( strcmp((const char*)event.data.scalar.value, value.c_str()) ) - throw string("Found ") + (const char*)event.data.scalar.value + - " instead of " + value; - last_valid = (const char*)event.data.scalar.value; - y_done(); -} - -void NFileIO::y_skipvalues( int repet ) -{ - for( int i=0; i<repet; ++i ){ - y_checktype( YAML_SCALAR_EVENT, string( "skip " ) + strg(repet) ); - } -} - -bool NFileIO::y_scalar_from_seq( string seqname, string *ret ) -{ - y_next(); - if( event.type == YAML_SEQUENCE_END_EVENT ) - return false; - if( event.type != YAML_SCALAR_EVENT ) - throw string( "NO scalar in sequence " ) + seqname + - "; last valid entry was \"" + last_valid + "\""; - *ret = (const char*)event.data.scalar.value; - last_valid = (const char*)event.data.scalar.value; - y_done(); - return true; -} - -string NFileIO::y_getscalar( string scalarname ) -{ - string ret; - y_next(); - if( event.type != YAML_SCALAR_EVENT ) - throw string( "NO scalar " ) + scalarname + - "; last valid entry was \"" + last_valid + "\""; - ret = (const char*)event.data.scalar.value; - y_done(); - return ret; -} - -bool NFileIO::y_getCoord( string label, CCoord *co ) -{ - y_next(); - if( event.type == YAML_MAPPING_END_EVENT ) - return false; - if( event.type != YAML_SCALAR_EVENT ) - throw string( "inconsistency where " + label + " expected" ); - if( strcmp((const char*)event.data.scalar.value, label.c_str()) ) - throw string("Found ") + (const char*)event.data.scalar.value + - " instead of " + label; - last_valid = (const char*)event.data.scalar.value; - y_done(); - y_checktype( YAML_MAPPING_START_EVENT, label + ": no map\n" ); - y_checkvalue( "name" ); - co->name = y_getscalar( label + ".name" ); - y_checkvalue( "unit" ); - co->unit = y_getscalar( label + ".unit" ); - y_checktype( YAML_MAPPING_END_EVENT, label + ": no end of map\n" ); - return true; -} - //! Load a YAML file in y08 format. void NFileIO::Load_08( FILE *F_in, string flong ) { @@ -181,89 +82,83 @@ void NFileIO::Load_08( FILE *F_in, string flong ) COld old; CCoord co; CScan sout; + CYamlRead y( F_in ); mystd::fname_divide( flong, &fdir, &fshort, &fext); - memset( &parser, 0, sizeof(parser) ); - memset( &event, 0, sizeof(event) ); - if (!yaml_parser_initialize( &parser )) - throw string("Could not initialize the parser object"); - yaml_parser_set_input_file( &parser, F_in ); - last_valid = "START"; - - y_checktype( YAML_STREAM_START_EVENT, "no stream\n" ); - y_checktype( YAML_DOCUMENT_START_EVENT, "no document\n" ); - y_checktype( YAML_MAPPING_START_EVENT, "main: no map\n" ); - - y_checkvalue( "Meta" ); - y_checktype( YAML_MAPPING_START_EVENT, "Meta: no map\n" ); - y_checkvalue( "format" ); - y_checkvalue( "frida/y08 for yaml1" ); - y_skipvalues( 2 ); - y_checktype( YAML_MAPPING_END_EVENT, "Meta: no end of map\n" ); - - y_checkvalue( "History" ); - y_checktype( YAML_SEQUENCE_START_EVENT, "History: no seq\n" ); - while( y_scalar_from_seq( "history", &lin ) ){ + y.checktype( YAML_STREAM_START_EVENT, "no stream\n" ); + y.checktype( YAML_DOCUMENT_START_EVENT, "no document\n" ); + y.checktype( YAML_MAPPING_START_EVENT, "main: no map\n" ); + + y.checkvalue( "Meta" ); + y.checktype( YAML_MAPPING_START_EVENT, "Meta: no map\n" ); + y.checkvalue( "format" ); + y.checkvalue( "frida/y08 for yaml1" ); + y.skipvalues( 2 ); + y.checktype( YAML_MAPPING_END_EVENT, "Meta: no end of map\n" ); + + y.checkvalue( "History" ); + y.checktype( YAML_SEQUENCE_START_EVENT, "History: no seq\n" ); + while( y.scalar_from_seq( "history", &lin ) ){ old.lDoc.push_back(lin); } - y_checkvalue( "Coord" ); - y_checktype( YAML_MAPPING_START_EVENT, "Coord: no map\n" ); - if( !y_getCoord( "x", &(old.xco) ) ) + y.checkvalue( "Coord" ); + y.checktype( YAML_MAPPING_START_EVENT, "Coord: no map\n" ); + if( !y.getCoord( "x", &(old.xco) ) ) throw string( "no x coord" ); - if( !y_getCoord( "y", &(old.xco) ) ) + if( !y.getCoord( "y", &(old.xco) ) ) throw string( "no y coord" ); iz=0; - while( y_getCoord( "z"+strg(iz), &(co) ) ){ + while( y.getCoord( "z"+strg(iz), &(co) ) ){ old.ZCo.push_back( co ); ++iz; } - if( event.type != YAML_MAPPING_END_EVENT ) + if( y.event.type != YAML_MAPPING_END_EVENT ) throw string( "Coord: no end of map" ); - y_done(); + y.done(); - y_checkvalue( "Param" ); - y_checktype( YAML_SEQUENCE_START_EVENT, "Param: no seq\n" ); + y.checkvalue( "Param" ); + y.checktype( YAML_SEQUENCE_START_EVENT, "Param: no seq\n" ); while( true ){ - y_next(); - if( event.type == YAML_SEQUENCE_END_EVENT ) + y.next(); + if( y.event.type == YAML_SEQUENCE_END_EVENT ) break; - if( event.type != YAML_MAPPING_START_EVENT ) + if( y.event.type != YAML_MAPPING_START_EVENT ) throw string ( "Param: no map" ); - y_done(); - y_checkvalue( "name" ); - co.name = y_getscalar( "param.name" ); - y_checkvalue( "unit" ); - co.unit = y_getscalar( "param(" + co.name + ").unit" ); - y_checkvalue( "value" ); - val = y_getscalar( "param(" + co.name + ").value" ); + y.done(); + y.checkvalue( "name" ); + co.name = y.getscalar( "param.name" ); + y.checkvalue( "unit" ); + co.unit = y.getscalar( "param(" + co.name + ").unit" ); + y.checkvalue( "value" ); + val = y.getscalar( "param(" + co.name + ").value" ); if( mystd::any2dbl( val, &num ) ) throw string( "param(" ) + co.name + "): invalid value " + val; old.RPar.push_back( CParam( co, num ) ); - y_checktype( YAML_MAPPING_END_EVENT, "Param "+co.name+": no eom\n" ); + y.checktype( YAML_MAPPING_END_EVENT, "Param "+co.name+": no eom\n" ); } - y_done(); + y.done(); - y_checkvalue( "Tables" ); - y_checktype( YAML_SEQUENCE_START_EVENT, "Tables: no seq\n" ); + y.checkvalue( "Tables" ); + y.checktype( YAML_SEQUENCE_START_EVENT, "Tables: no seq\n" ); while( true ){ - y_next(); - if( event.type == YAML_SEQUENCE_END_EVENT ) + y.next(); + if( y.event.type == YAML_SEQUENCE_END_EVENT ) break; - if( event.type != YAML_MAPPING_START_EVENT ) + if( y.event.type != YAML_MAPPING_START_EVENT ) throw string ( "Tables: no map" ); - y_done(); + y.done(); sout.Clear(); for( iz=0; iz<old.ZCo.size(); ++iz ){ - y_checkvalue( "z" + strg(iz) ); - val = y_getscalar( "z" + strg(iz) + ".value" ); + y.checkvalue( "z" + strg(iz) ); + val = y.getscalar( "z" + strg(iz) + ".value" ); if( mystd::any2dbl( val, &num ) ) throw "z" + strg(iz) + ": invalid value " + val; sout.z.push_back( num ); } - y_checkvalue( "xy" ); - val = y_getscalar( "xy core data" ); + y.checkvalue( "xy" ); + val = y.getscalar( "xy core data" ); double v,w; string res; while( val != "" ) { @@ -274,12 +169,12 @@ void NFileIO::Load_08( FILE *F_in, string flong ) val = res; }; old.VS.push_back( sout ); - y_checktype( YAML_MAPPING_END_EVENT, "Table: no eom\n" ); + y.checktype( YAML_MAPPING_END_EVENT, "Table: no eom\n" ); } - y_done(); - - yaml_parser_delete( &parser ); + y.done(); + old.name = fshort; + old.lDoc.push_back( "`loaded as " + flong ); old.as_on_disk = true; NOlm::OloAdd(&old); } diff --git a/src/frida2.cpp b/src/frida2.cpp index 2b328c2ff36da125b64d08cf12a3c5b6be5bf340..e874e6ade4464fc8f79ff9d6c30e2abb7de8efcd 100644 --- a/src/frida2.cpp +++ b/src/frida2.cpp @@ -359,17 +359,22 @@ int main() printf( "total time now %g\n", time_total ); } else if (cmd == "r") { - cout << "read RSSM data (rold for old/internal formats):\n" + cout << "read RSSM data (rold for list of old-format commands):\n" + " ry load energy spectra\n" + " ry2 load also spectra for open state\n" + " ry4 load also chopper histograms\n" + " ry8 load spectra for two directions separately\n" + " ryd load only spectra for two directions\n"; + + } else if (cmd == "rold") { + cout << "read old/internal RSSM data files:\n" " rx load energy spectra\n" " rx2 load also spectra for open state\n" " rx4 load also chopper histograms\n" " rx8 load spectra for two directions separately\n" " rxd load only spectra for two directions\n" " rs load series of energy spectra\n" - " rs2 load also spectra for open state\n"; - - } else if (cmd == "rold") { - cout << "read old/internal RSSM data files:\n" + " rs2 load also spectra for open state\n" " rdc load dopp, chop from stream\n" " rda analyse dopp\n" " rca analyse chop\n" @@ -385,20 +390,31 @@ int main() " rx0t load from xml v0, two directions separately\n" " rh load from Drochner histogram\n"; + } else if (cmd == "ry") { + NRSSM::ReadScan( 5, 0 ); + } else if (cmd == "ry2") { + NRSSM::ReadScan( 5, 1 ); + } else if (cmd == "ry4") { + NRSSM::ReadScan( 5, 3 ); + } else if (cmd == "ry8") { + NRSSM::ReadScan( 5, 7 ); + } else if (cmd == "ryd") { + NRSSM::ReadScan( 5, 12 ); + } else if (cmd == "rx") { - NRSSM::ReadScan( 0 ); + NRSSM::ReadScan( 2, 0 ); } else if (cmd == "rx2") { - NRSSM::ReadScan( 1 ); + NRSSM::ReadScan( 2, 1 ); } else if (cmd == "rx4") { - NRSSM::ReadScan( 3 ); + NRSSM::ReadScan( 2, 3 ); } else if (cmd == "rx8") { - NRSSM::ReadScan( 7 ); + NRSSM::ReadScan( 2, 7 ); } else if (cmd == "rxd") { - NRSSM::ReadScan( 12 ); + NRSSM::ReadScan( 2, 12 ); } else if (cmd == "rs") { - NRSSM::ReadSeries( 0 ); + NRSSM::ReadSeries( 2, 0 ); } else if (cmd == "rs2") { - NRSSM::ReadSeries( 1 ); + NRSSM::ReadSeries( 2, 1 ); } else if (cmd == "rdc") { NR_Stream::Stream2DoppChop(); diff --git a/src/rssm.cpp b/src/rssm.cpp index 8404d6ee0b9ed739152b9d612bea49b7a89ac291..af27231c2e83c4ea5160f80ec1afdd95a99430e7 100644 --- a/src/rssm.cpp +++ b/src/rssm.cpp @@ -20,18 +20,20 @@ #include "asi.h" #include "gar.h" #include "rssm.h" +#include "yamc.h" using namespace std; class RssmRawFile { public: - int ReadRaw( string fnam ); + int RdRawXml( string fnam ); + void RdRawYam( FILE *F_in ); double daq_time_step; time_t measured_from; time_t measured_until; int measured_at; double measured_during; - bool incremental; + bool incremental; vector<double> rawdata[6]; vector<double> angles; double temp0, temp1; @@ -40,7 +42,150 @@ class RssmRawFile { }; // Read raw data file, store contents as class variables -int RssmRawFile::ReadRaw( string fnam ) +void RssmRawFile::RdRawYam( FILE *F_in ) +{ + COld old; + string lin, key, val; + CCoord co; + CScan sout; + int iz; + double num; + + daq_time_step=0; + angles.clear(); + + CYamlRead y( F_in ); + + old.as_on_disk = true; + NOlm::OloAdd(&old); + + y.checktype( YAML_STREAM_START_EVENT, "no stream\n" ); + y.checktype( YAML_DOCUMENT_START_EVENT, "no document\n" ); + y.checktype( YAML_MAPPING_START_EVENT, "main: no map\n" ); + + y.checkvalue( "Meta" ); + y.checktype( YAML_MAPPING_START_EVENT, "Meta: no map\n" ); + y.checkvalue( "format" ); + val = y.getscalar( "format" ); + if( strncmp( val.c_str(), "acq5.0 for yaml1", 16 ) ) + throw( string("Unexpected format") ); + y.skipvalues( 2 ); + y.checktype( YAML_MAPPING_END_EVENT, "Meta: no end of map\n" ); + + y.checkvalue( "History" ); + y.checktype( YAML_SEQUENCE_START_EVENT, "History: no seq\n" ); + y.checktype( YAML_MAPPING_START_EVENT, "History: meas: no map\n" ); + y.checkvalue( "measured on SPHERES" ); + old.lDoc.push_back( "measured on SPHERES" ); + y.checktype( YAML_MAPPING_START_EVENT, "History: meas: meas: no map\n" ); + while( true ){ + y.next(); + if( y.event.type == YAML_MAPPING_END_EVENT ){ + y.done(); + break; + } + if( y.event.type != YAML_SCALAR_EVENT ) + throw string( "No scalar key in Hist:meas " + "; last valid entry was \"" + y.last_valid + "\"" ); + key = (const char*)y.event.data.scalar.value; + y.last_valid = key; + y.done(); + y.next(); + if( y.event.type != YAML_SCALAR_EVENT ) + throw string( "No scalar value in Hist:meas " + "; last valid entry was \"" + y.last_valid + "\"" ); + val = (const char*)y.event.data.scalar.value; + y.last_valid = val; + y.done(); + old.lDoc.push_back( " " + key + ": " + val ); + if ( key=="incremental" ){ + if ( val=="true" ) + incremental = true; + else if ( val=="false" ) + incremental = false; + else + throw "Invalid value of 'incremental'"; + } else if ( key=="until" ){ + char date_string[24]; + sscanf( val.c_str(), "%24c", date_string ); + struct tm date_broken; + strptime( date_string, "%F %A %H:%M:%S", &date_broken ); + measured_until = mktime( &date_broken ); + } + } + y.checktype( YAML_MAPPING_END_EVENT, "History: meas: no end of map\n" ); + while( y.scalar_from_seq( "history", &lin ) ){ + old.lDoc.push_back(lin); + } + + y.checkvalue( "Param" ); + y.checktype( YAML_SEQUENCE_START_EVENT, "Param: no seq\n" ); + while( true ){ + y.next(); + if( y.event.type == YAML_SEQUENCE_END_EVENT ) + break; + if( y.event.type != YAML_MAPPING_START_EVENT ) + throw string( "Param: no map; last entry was " + y.last_valid ); + y.done(); + key = y.getscalar( "Param: name or note" ); + if( key=="note" ){ + y.skipvalues( 1 ); + y.checktype( YAML_MAPPING_END_EVENT, "Param: no end of note" ); + continue; + } + if( key!="name" ) + throw string( "Param entry starting neither with note, " + "nor with name" ); + co.name = y.getscalar( "param.name" ); + if ( co.name=="daq_time_step" ){ + // useful double value + y.checkvalue( "unit" ); + co.unit = y.getscalar( "param(" + co.name + ").unit" ); + y.checkvalue( "value" ); + val = y.getscalar( "param(" + co.name + ").value" ); + if( mystd::any2dbl( val, &num ) ) + throw string( "param(" ) + co.name + "): invalid value " + val; + old.RPar.push_back( CParam( co, num ) ); + y.checktype( YAML_MAPPING_END_EVENT, + "Param "+co.name+": no eom\n" ); + if( co.name=="daq_time_step" ) + daq_time_step = num; + } else { + // no useful value + while( true ){ + y.next(); + if( y.event.type == YAML_MAPPING_END_EVENT ) + break; + y.done(); + } + } + } + y.done(); + + y.checkvalue( "Detectors" ); + y.checktype( YAML_MAPPING_START_EVENT, "Detectors: no map\n" ); + y.checkvalue( "note" ); + y.skipvalues( 1 ); + y.checkvalue( "angles" ); + y.checktype( YAML_SEQUENCE_START_EVENT, "Dets:angles: no seq\n" ); + while( true ){ + y.next(); + if( y.event.type == YAML_SEQUENCE_END_EVENT ) + break; + if( y.event.type != YAML_SCALAR_EVENT ) + throw string ( "Dets:angles: no scalar" ); + val = (const char*)y.event.data.scalar.value; + y.done(); + if( mystd::any2dbl( val, &num ) ) + throw "Dets:angles: invalid value " + val; + } + y.done(); + + key = y.getscalar( "Note ?" ) +} + +// Read raw data file, store contents as class variables +int RssmRawFile::RdRawXml( string fnam ) { xmlChar *key, *val, *txt, *syntax, *outform, *format, *axis, *contents, *categ, *txt1, *txt2; @@ -257,8 +402,11 @@ int RssmRawFile::ReadRaw( string fnam ) return 0; } -void NRSSM::ReadScan( int flag ) +void NRSSM::ReadScan( int format, int flag ) +// format values: +// 2 acq2-4 xml +// 5 acq5 yaml // flag values (to be OR'ed): // 1 save also open // 2 save also chop histo @@ -269,9 +417,31 @@ void NRSSM::ReadScan( int flag ) string file_f, name; file_f = wask("Read SPHERES data from xml file"); RssmRawFile R; - int ret = R.ReadRaw( file_f ); - if( ret==1 ) - fprintf( stderr, "Data file not parsed successfully.\n" ); + int ret; + FILE *F_in; + + if ( format==2 ){ + ret = R.RdRawXml( file_f ); + if( ret==1 ) + fprintf( stderr, "Data file not found, or failed to parse.\n" ); + } else if ( format==5 ){ + if( !(F_in = fopen(file_f.c_str(), "r")) ) { + cerr << "Cannot read " << file_f << "\n"; + return; + } + try{ + R.RdRawYam( F_in ); + } + catch( string &e) { + cerr << "Cannot read " << file_f << ":\n"; + cerr << e << endl; + if (F_in) fclose(F_in); + return; + } + } else { + printf( "invalid format" ); + return; + } if( ret ) return; @@ -413,8 +583,10 @@ void NRSSM::ReadScan( int flag ) } -void NRSSM::ReadSeries( int flag ) +void NRSSM::ReadSeries( int format, int flag ) +// format values: +// as above // flag values (to be OR'ed): // 1 save also open @@ -429,13 +601,31 @@ void NRSSM::ReadSeries( int flag ) fser = wask("Read SPHERES data from series"); for( isub=0; ; ++isub ){ RR.push_back( RssmRawFile() ); - ret = RR.back().ReadRaw( fser+"c"+strg(isub) ); - if( ret==1 ){ - printf( "ignore the above warning\n" ); - RR.pop_back(); - break; - } - if( ret ) + if ( format==2 ) { + ret = RR.back().RdRawXml( fser+"c"+strg(isub) ); + if( ret==1 ){ + printf( "ignore the above warning\n" ); + RR.pop_back(); + break; + } + } else if( format==5 ) { + string fnam = fser+"c"+strg(isub); + FILE *F_in; + if( !(F_in = fopen( fnam.c_str(), "r" ) ) ) + break; + try{ + RR.back().RdRawYam( F_in ); + } + catch(exception& e) { + cerr << e.what() << endl; + if (F_in) fclose(F_in); + return; + } + } else { + printf( "invalid format" ); + return; + } + if ( ret ) return; } int nsub = RR.size(); diff --git a/src/rssm.h b/src/rssm.h index 99b2eb2e0bdc4b6ee0b219653fa610953071ee3e..c50e37b08228631bd0a00c7a3439d62eef533c77 100644 --- a/src/rssm.h +++ b/src/rssm.h @@ -1,4 +1,4 @@ namespace NRSSM { - void ReadScan( int flag ); - void ReadSeries( int flag ); + void ReadScan( int format, int flag ); + void ReadSeries( int format, int flag ); }; diff --git a/src/yamc.cpp b/src/yamc.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3d8d9f52fd0bedd8feb361e7a4cc72cc9aba170e --- /dev/null +++ b/src/yamc.cpp @@ -0,0 +1,141 @@ +//**************************************************************************// +//* FRIDA: fast reliable interactive data analysis *// +//* (C) Joachim Wuttke 1990-, v2(C++) 2001- *// +//* http://frida.sourceforge.net *// +//* yamc.cpp *// +//* read YAML data files, using libyaml *// +//**************************************************************************// + +#include <string> +using namespace std; +#include "coord.h" +#include "yamc.h" +#include "mystd.h" + +CYamlRead::CYamlRead( FILE *F_in ) +{ + memset( &parser, 0, sizeof(parser) ); + memset( &event, 0, sizeof(event) ); + if (!yaml_parser_initialize( &parser )) + throw string("Could not initialize the parser object"); + yaml_parser_set_input_file( &parser, F_in ); + last_valid = "START"; +} + +CYamlRead::~CYamlRead() +{ + yaml_parser_delete( &parser ); +} + +void CYamlRead::next() +{ + if( !yaml_parser_parse( &parser, &event) ) + throw string( "Invalid input? Last valid entry was \"" ) + + last_valid + "\""; +} + +void CYamlRead::done() +{ + yaml_event_delete( &event); +} + +void CYamlRead::checktype( int type, string errmsg ) +{ + next(); + if( event.type != type ) + throw errmsg; + if( event.type == YAML_SCALAR_EVENT ) + last_valid = (const char*)event.data.scalar.value; + done(); +} + +void CYamlRead::checkvalue( string value ) +{ + next(); + if( event.type != YAML_SCALAR_EVENT ) + throw string("No scalar while expecting ") + value; + if( strcmp((const char*)event.data.scalar.value, value.c_str()) ) + throw string("Found ") + (const char*)event.data.scalar.value + + " instead of " + value; + last_valid = (const char*)event.data.scalar.value; + done(); +} + +void CYamlRead::skipvalues( int repet ) +{ + for( int i=0; i<repet; ++i ){ + checktype( YAML_SCALAR_EVENT, string( "skip " ) + strg(repet) ); + } +} + +bool CYamlRead::scalar_from_seq( string seqname, string *ret ) +{ + next(); + if( event.type == YAML_SEQUENCE_END_EVENT ){ + done(); + return false; + } + if( event.type != YAML_SCALAR_EVENT ) + throw string( "No scalar in sequence " ) + seqname + + "; last valid entry was \"" + last_valid + "\""; + *ret = (const char*)event.data.scalar.value; + last_valid = (const char*)event.data.scalar.value; + done(); + return true; +} + +bool CYamlRead::line_from_map( string mapname, string *ret ) +{ + next(); + if( event.type == YAML_MAPPING_END_EVENT ){ + done(); + return false; + } + if( event.type != YAML_SCALAR_EVENT ) + throw string( "No scalar key in mapping " ) + mapname + + "; last valid entry was \"" + last_valid + "\""; + *ret = (const char*)event.data.scalar.value; + done(); + next(); + if( event.type != YAML_SCALAR_EVENT ) + throw string( "No scalar value in mapping " ) + mapname + + "; last valid entry was \"" + last_valid + "\""; + *ret += string(": ") + (const char*)event.data.scalar.value; + last_valid = (const char*)event.data.scalar.value; + done(); + return true; +} + +string CYamlRead::getscalar( string scalarname ) +{ + string ret; + next(); + if( event.type != YAML_SCALAR_EVENT ) + throw string( "No scalar " ) + scalarname + + "; last valid entry was \"" + last_valid + "\""; + ret = (const char*)event.data.scalar.value; + done(); + return ret; +} + +bool CYamlRead::getCoord( string label, CCoord *co ) +{ + next(); + if( event.type == YAML_MAPPING_END_EVENT ) + return false; + if( event.type != YAML_SCALAR_EVENT ) + throw string( "inconsistency where " + label + " expected" ); + if( strcmp((const char*)event.data.scalar.value, label.c_str()) ) + throw string("Found ") + (const char*)event.data.scalar.value + + " instead of " + label; + last_valid = (const char*)event.data.scalar.value; + done(); + checktype( YAML_MAPPING_START_EVENT, label + ": no map\n" ); + checkvalue( "name" ); + co->name = getscalar( label + ".name" ); + checkvalue( "unit" ); + co->unit = getscalar( label + ".unit" ); + checktype( YAML_MAPPING_END_EVENT, label + ": no end of map\n" ); + return true; +} + diff --git a/src/yamc.h b/src/yamc.h new file mode 100644 index 0000000000000000000000000000000000000000..0fef933d94f00557a229ee94cd131a12f0bc1f1c --- /dev/null +++ b/src/yamc.h @@ -0,0 +1,27 @@ +//**************************************************************************// +//* FRIDA: fast reliable interactive data analysis *// +//* (C) Joachim Wuttke 1990-, v2(C++) 2001- *// +//* http://frida.sourceforge.net *// +//* yamc.h *// +//* read YAML data files, using libyaml *// +//**************************************************************************// + +#include "../yaml/include/yaml.h" + +class CYamlRead { + public: + yaml_parser_t parser; + yaml_event_t event; + string last_valid; + CYamlRead( FILE *F_in ); + ~CYamlRead(); + void next(); + void done(); + void checktype( int type, string errmsg ); + void checkvalue( string value ); + void skipvalues( int repet ); + bool scalar_from_seq( string seqname, string *ret ); + bool line_from_map( string mapname, string *ret ); + string getscalar( string scalarname ); + bool getCoord( string label, CCoord *co ); +};