// ---------------------------------------------------------------------- // // HepNtuple-chform.cc - implementation of the chform interpreter function for // the HepNtuple class // // The following methods can be found in this file: // string AttribsToChForm(HepAList listOfColumns) // string AttribsToChform(const int nc, const ColumnAttribs* CAs) // both return the chform string representing the // list of ColumnAttribs. The first one is used to // implement Block::format(); // // HepAList addColumnsFromFormat(const char* chform) // Create and add to the block the columns represented // by chForm. It return a list of new ColumnAttribs // // In addition of this public function, this files contains a string of // static functions used to parse the chform string. #include "HepTuple/HepNtuple.h" #include "HepTuple/Column.h" // include for sscanf #include #include USING( std::string ) ZM_BEGIN_NAMESPACE( zmht ) /* namespace zmht { */ // **** a few global data for the next few subroutines ******** static char Cur_tx[100] = {0}; static ColumnAttribs* Cur_ca; static const char* Cur_p; static std::STL_VECTOR(ColumnAttribs*) newColumnAttribs; // **** some subroutines ******** #ifdef NEVER //count the number of tags in the string static int count_tag_nmb(const char *st) { char cc; int i = 0; int j = 1; while( (cc=st[i++])!=0 ) { while( (cc!=',')&&(cc!='(')&&(cc!='[')&&(cc!=0) ) cc=st[i++]; if(cc=='(') { while( (cc!=')')&&(cc!=0) ) cc=st[i++]; if(cc==0) ZMthrow(ZMxHepBadFormat("count_tag_num(): unmatched () ? ")); } else if(cc=='[') { while( (cc!=']')&&(cc!=0) ) cc=st[i++]; if(cc==0) ZMthrow(ZMxHepBadFormat("count_tag_num(): unmatched [] ? ")); } else if(cc==0) return j; else j++; //has to be ',' } return j; } //count_tag_nmb() #endif //get the next valid char static char get_vc() { char cc = *Cur_p; while(cc) { /* list of valid char */ if ((cc>='a')&&(cc<='z')) return cc; else if((cc>='A')&&(cc<='Z')) return cc; else if((cc>='0')&&(cc<='9')) return cc; else if((cc=='*')||(cc=='!')) return cc; else if((cc=='$')||(cc==',')) return cc; else if((cc=='-')||(cc=='+')) return cc; else if((cc=='(')||(cc==')')) return cc; else if((cc=='[')||(cc==']')) return cc; else if((cc=='.')) return cc; else if((cc=='_')||(cc==':')||(cc=='.')) return cc; else if((cc==' ')||(cc=='\t')||(cc=='\n')) { Cur_p++; cc = *Cur_p; } else ZMthrow(ZMxHepBadFormat("get_vc(): an invalid char in the ChForm string")); } /*while*/ return (0); } //get_vc() //get the next tag static int get_str() { char cc; int gg = 0; int ff = 1; cc = get_vc(); while(ff) { if ((cc>='a')&&(cc<='z')) { Cur_tx[gg] = cc; gg++; cc= *(++Cur_p); } else if((cc>='A')&&(cc<='Z')) { Cur_tx[gg] = cc; gg++; cc= *(++Cur_p); } else if((cc>='0')&&(cc<='9')) { Cur_tx[gg] = cc; gg++; cc= *(++Cur_p); } else if((cc=='_')||(cc=='$')) { Cur_tx[gg] = cc; gg++; cc= *(++Cur_p); } else if((cc=='.')) { Cur_tx[gg] = cc; gg++; cc= *(++Cur_p); } else { ff = 0; Cur_tx[gg] = 0; } } return gg; } //get_str() //get a int number static int get_dn() { char cc; int gg = 0; int ff = 1; cc = get_vc(); while(ff) { cc = *Cur_p; if(((cc>='0')&&(cc<='9'))||(cc=='-')||(cc=='+')) { Cur_tx[gg] = cc; gg++; Cur_p++; } else { ff = 0; Cur_tx[gg] = 0; } } if(gg>0) sscanf(Cur_tx,"%d",&gg); else ZMthrow(ZMxHepBadFormat("get_dn(): Cannot get the i-number")); return gg; } //get_dn() //get a int number static int get_dimension() { char cc; int gg = 0; int ff = 1; if ( Cur_ca->index.length() != 0) { ZMthrow(ZMxHepBadFormat("get_dimension(): Index can only be on last dimension")); return 0; } cc = get_vc(); //in case of a index.... if ( ((cc>='a')&&(cc<='z')) || ((cc>='A')&&(cc<='Z')) ) { get_str(); Cur_ca->index = Cur_tx; // Now look for the index span: for ( std::string::size_type i = 0 ; i < newColumnAttribs.size(); i++ ) { if ( newColumnAttribs[i]->tag == Cur_ca->index ) { return newColumnAttribs[i]->indexHi; } } ZMthrow(ZMxHepBadFormat (string("get_dimension(): Did not find index ") + Cur_tx)); return 0; } while(ff) { cc = *Cur_p; if(((cc>='0')&&(cc<='9'))||(cc=='-')||(cc=='+')) { Cur_tx[gg] = cc; gg++; Cur_p++; } else { ff = 0; Cur_tx[gg] = 0; } } if(gg>0) sscanf(Cur_tx,"%d",&gg); else ZMthrow(ZMxHepBadFormat("get_dn(): Cannot get the i-number")); return gg; } //get_dimension() //get a float number static float get_fn() { char cc; float gg = 0.0; int ii = 0; int ff = 1; cc = get_vc(); while(ff) { cc = *Cur_p; if((cc>='0')&&(cc<='9')||(cc=='.')||(cc=='-')||(cc=='+')) { Cur_tx[ii] = cc; ii++; Cur_p++; } else { ff = 0; Cur_tx[ii] = 0; } } if(ii>0) sscanf(Cur_tx,"%f",&gg); else ZMthrow(ZMxHepBadFormat("get_fn: Cannot get the f-number")); return gg; } //get_fn() //get the FORTRAN default type static int set_df_typs() { char cc = Cur_ca->tag[0]; if( ((cc>='i')&&(cc<='n')) || ((cc>='I')&&(cc<='N')) ) { Cur_ca->type = Int4_ct; return 2; } else { Cur_ca->type = Float4_ct; return 0; } } //set_df_typs() //get the type from * static int get_type() { char cc; int n; Cur_p++; cc = get_vc(); if(cc=='R') { Cur_p++; cc = get_vc(); if(cc=='*') { Cur_p++; n = get_dn(); if(n<1) ZMthrow(ZMxHepBadFormat("get_type(): R* format does not have ?")); } else n = 4; if(n==4) Cur_ca->type = Float4_ct; else if(n==8) Cur_ca->type = Float8_ct; else if(n==16) Cur_ca->type = Float16_ct; else ZMthrow(ZMxHepBadFormat("get_type(): Float(Real) can have 4,8,16 bytes only!")); return 1; } else if(cc=='I') { Cur_p++; cc = get_vc(); if(cc=='*') { Cur_p++; n = get_dn(); if(n<1) ZMthrow(ZMxHepBadFormat("get_type(): I* format does not have ?")); } else n = 4; if(n==1) Cur_ca->type = Int1_ct; else if(n==2) Cur_ca->type = Int2_ct; else if(n==4) Cur_ca->type = Int4_ct; else if(n==8) Cur_ca->type = Int8_ct; else ZMthrow(ZMxHepBadFormat("get_type(): Int can have 1,2,4,8 bytes only!")); return 2; } else if(cc=='U') { Cur_p++; cc = get_vc(); if(cc=='*') { Cur_p++; n = get_dn(); if(n<1) ZMthrow(ZMxHepBadFormat("get_type(): U* format does not have ?")); } else n = 4; if(n==1) Cur_ca->type = Uint1_ct; else if(n==2) Cur_ca->type = Uint2_ct; else if(n==4) Cur_ca->type = Uint4_ct; else if(n==8) Cur_ca->type = Uint8_ct; else ZMthrow(ZMxHepBadFormat("get_type(): UnsignedInt can have 1,2,4,8 bytes only!")); return 2; } else if(cc=='L') { Cur_p++; cc = get_vc(); if(cc=='*') { Cur_p++; n = get_dn(); if(n<1) ZMthrow(ZMxHepBadFormat("get_type(): U* format does not have ?")); } else n = 4; if(n==1) Cur_ca->type = Bool_ct; else if(n==2) Cur_ca->type = Bool2_ct; else if(n==4) Cur_ca->type = Bool4_ct; else ZMthrow(ZMxHepBadFormat("get_type(): Logic can have 1,2,4 bytes only!")); return 1; } else if(cc=='C') { Cur_p++; cc = get_vc(); if(cc=='*') { Cur_p++; n = get_dn(); if(n<1) ZMthrow(ZMxHepBadFormat("get_type(): C* format does not have ?")); } else n = 4; if(n==1) Cur_ca->type = Char_ct; else if(n==4) Cur_ca->type = Char4_ct ; else if(n==8) Cur_ca->type = Char8_ct ; else if(n==12) Cur_ca->type = Char12_ct ; else if(n==16) Cur_ca->type = Char16_ct ; else if(n==20) Cur_ca->type = Char20_ct ; else if(n==24) Cur_ca->type = Char24_ct ; else if(n==28) Cur_ca->type = Char28_ct ; else if(n==32) Cur_ca->type = Char32_ct ; else ZMthrow(ZMxHepBadFormat("get_type(): char-string can have 4,8,...32 bytes only!")); return 1; } else if (cc=='O') { Cur_p++; cc = get_vc(); if(cc=='*') { Cur_p++; n = get_dn(); ZMthrow(ZMxHepBadFormat("get_type(): O can not have a * format ?")); } Cur_ca->type = Ptr_ct; return 1; } cc = Cur_ca->tag[0]; if( ((cc>='i')&&(cc<='n')) || ((cc>='I')&&(cc<='N')) ) { Cur_ca->type = Int4_ct; return 3; } else { Cur_ca->type = Float4_ct; return 0; } } //get_type() //set the default packing bits static int get_ndim(const char* cp) { int n = 0; int i = 1; while(cp[i]!=')') { n++; while((cp[i]!=',')&&(cp[i]!=0)&&(cp[i]!=')')) i++; if(cp[i]==0) { ZMthrow(ZMxHepBadFormat("get_ndims(): miss matched ( and ) !")); } else if(cp[i]==')') return n; i++; } // this statement is only reached in case of missing ')' return 0; } //get_ndim() //set the default packing bits static int set_df_pack() { int rg,i,j; rg = Cur_ca->indexHi - Cur_ca->indexLo; if(rg<0) ZMthrow(ZMxHepBadFormat("set_df_pack(): indexHitag = new char [i+1]; // Cur_ca->tag = Cur_tx; } cc = get_vc(); // Those are now the default // Cur_ca->index = 0; // Cur_ca->nbits = 0; // Cur_ca->ndim = 0; // Cur_ca->indexLo = 0; Cur_ca->indexHi = 0; // Cur_ca->rangeLo = 0.0; Cur_ca->rangeHi = 0.0; //case of TAG[] if (cc == '[') { Cur_p++; if(set_df_typs()) { Cur_ca->indexLo = get_dn(); while((cc = *Cur_p)!=',') { if(cc == 0) ZMthrow(ZMxHepBadFormat (string("5: missing Hi range? ")+Cur_ca->tag)); Cur_p++; } Cur_p++; Cur_ca->indexHi = get_dn(); } else ZMthrow(ZMxHepBadFormat (string("7: Range for R type data should be at the end! ") +Cur_ca->tag)); cc = get_vc(); if(cc!=']') ZMthrow(ZMxHepBadFormat (string("9: Need a ']' to finish the range! ")+Cur_ca->tag)); Cur_p++; cc = get_vc(); if(cc==':') { j = get_type(); if(j<2) //get the * from tag[]:* ZMthrow(ZMxHepBadFormat (string("11: Has to be 'I' or 'U' type for tag[]...! ") +Cur_ca->tag)); cc = get_vc(); if(cc==':') { Cur_p++; Cur_ca->nbits = get_dn(); //get the } else if((j==0)||(j==3)) { ZMthrow(ZMxHepBadFormat (string("13: Unknown format after tag[]: ?") +Cur_ca->tag)); } } cc = get_vc(); if (cc==',') Cur_p++; else if(cc!=0) ZMthrow(ZMxHepBadFormat (string("15: Unknown format after tag[]....!") +Cur_ca->tag)); if(!Cur_ca->nbits) Cur_ca->nbits = set_df_pack(); } //case of array else if (cc == '(') { i = 0; // Cur_ca->extents = new int [get_ndim(Cur_p)]; if (get_ndim(Cur_p) > MAX_DIM) ZMthrow(ZMxHepTooBig("NDIM to large")); do { Cur_p++; Cur_ca->ndim++; Cur_ca->extents[i++] = get_dimension(); cc = get_vc(); } while(cc==','); if(Cur_ca->ndim!=i) ZMthrow(ZMxHepBadFormat (string("17: ?? Miss match in the NDIM???? !!!") +Cur_ca->tag)); if ( cc != ')' ) ZMthrow(ZMxHepBadFormat (string("19: Need ')' to finish the dimension specification!") +Cur_ca->tag)); Cur_p++; cc = get_vc(); if ( cc == ':' ) { j = get_type(); //get the * from tag():* cc = get_vc(); if(cc==':') { Cur_p++; cc = get_vc(); if( (cc>='0')&&(cc<='9') ) Cur_ca->nbits = get_dn(); //get the cc = get_vc(); if( cc == ':' ) { //get the range Cur_p++; cc = get_vc(); if( cc!='[' ) ZMthrow(ZMxHepBadFormat (string("21: Need '[' for ...::[] range!") +Cur_ca->tag)); Cur_p++; if(j<2) Cur_ca->rangeLo = get_fn(); else Cur_ca->indexLo = get_dn(); while( (cc=get_vc()) != ',' ) { if (cc == 0) ZMthrow(ZMxHepBadFormat (string("23: Need '[,]' for ...::[] range!") +Cur_ca->tag)); Cur_p++; } Cur_p++; if(j<2) Cur_ca->rangeHi = get_fn(); else Cur_ca->indexHi = get_dn(); while( (cc=get_vc()) != ']' ) { if (cc == 0) ZMthrow(ZMxHepBadFormat (string("25: Need '[,]' for ...::[] range!") +Cur_ca->tag)); Cur_p++; } Cur_p++; } else { if((!Cur_ca->nbits)&&((j==1)||(j==2))) { ZMthrow(ZMxHepBadFormat (string("27: Unknown format after tag():*:.. !") +Cur_ca->tag)); } else if (!Cur_ca->nbits) { ZMthrow(ZMxHepBadFormat (string("29: Unknown format after tag()::.. !") +Cur_ca->tag)); } } } else if((j!=1)&&(j!=2)) { ZMthrow(ZMxHepBadFormat (string("30: Unknown format after tag():.. !") +Cur_ca->tag)); } } else { set_df_typs(); } cc = get_vc(); if (cc==',') Cur_p++; else if(cc!=0) { ZMthrow(ZMxHepBadFormat (string("31: UNknown format after tag()....!") +Cur_ca->tag)); } } //case of tag:... else if (cc == ':') { j = get_type(); //get the * from tag:* cc = get_vc(); if(cc==':') { Cur_p++; cc = get_vc(); if( (cc>='0')&&(cc<='9') ) Cur_ca->nbits = get_dn(); //get the cc = get_vc(); if( cc == ':' ) { //get the range Cur_p++; cc = get_vc(); if( cc!='[' ) ZMthrow(ZMxHepBadFormat (string("33: Need '[' for ...::[] range!") +Cur_ca->tag)); Cur_p++; if(j<2) Cur_ca->rangeLo = get_fn(); else Cur_ca->indexLo = get_dn(); while( (cc=get_vc()) != ',' ) { if (cc == 0) ZMthrow(ZMxHepBadFormat (string("35: Need '[,]' for ...::[] range!") +Cur_ca->tag)); Cur_p++; } Cur_p++; if(j<2) Cur_ca->rangeHi = get_fn(); else Cur_ca->indexHi = get_dn(); while( (cc=get_vc()) != ']' ) { if (cc == 0) ZMthrow(ZMxHepBadFormat (string("37: Need '[,]' for ...::[] range!") +Cur_ca->tag)); Cur_p++; } Cur_p++; } else { if((!Cur_ca->nbits)&&((j==1)||(j==2))) { ZMthrow(ZMxHepBadFormat (string("39: Unknown format after tag:*:.. !") +Cur_ca->tag)); } else if (!Cur_ca->nbits) { ZMthrow(ZMxHepBadFormat (string("41: Unknown format after tag::.. !") +Cur_ca->tag)); } } } else if((j!=1)&&(j!=2)) { ZMthrow(ZMxHepBadFormat (string("42: Unknown format after tag:.. !") +Cur_ca->tag)); } cc = get_vc(); if (cc==',') Cur_p++; else if(cc!=0) { ZMthrow(ZMxHepBadFormat (string("43: Unknown format after tag()....!") +Cur_ca->tag)); } } else if (cc == ',') { Cur_p++; set_df_typs(); } else if (cc == 0 ) { set_df_typs(); } else { ZMthrow(ZMxHepBadFormat (string("45: UNknown char after tag...!") +Cur_ca->tag)); } newColumnAttribs.push_back(Cur_ca); } //big while loop return newColumnAttribs; } ZM_END_NAMESPACE( zmht ) /* } // namespace zmht */