@@ -34,6 +34,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3434#include  <string.h> 
3535#include  <assert.h> 
3636#include  <errno.h> 
37+ #include  "htslib/hts_expr.h" 
3738#include  "textutils_internal.h" 
3839#include  "header.h" 
3940
@@ -898,6 +899,84 @@ static int sam_hrecs_parse_lines(sam_hrecs_t *hrecs, const char *hdr, size_t len
898899    return  0 ;
899900}
900901
902+ static  int  sam_hrecs_tag_lookup (sam_hrec_type_t  * h_type , const  char  * tagname ,
903+                                 char  type , hts_expr_val_t  * result ) {
904+     sam_hrec_tag_t  * tag  =  sam_hrecs_find_key (h_type , tagname , NULL );
905+     if  (tag  ==  NULL  ||  tag -> len  <  3 ) {
906+         result -> is_str  =  (type  ==  'Z' );
907+         result -> s .l  =  0 ;
908+         result -> d  =  0.0 ;
909+         result -> is_true  =  0 ;
910+         return  0 ;
911+     }
912+ 
913+     result -> is_true  =  1 ;
914+     switch  (type ) {
915+     case  'f' :
916+         result -> is_str  =  0 ;
917+         result -> d  =  strtod (& tag -> str [3 ], NULL );
918+         return  0 ;
919+ 
920+     case  'i' :
921+         result -> is_str  =  0 ;
922+         result -> d  =  strtoll (& tag -> str [3 ], NULL , 0 );
923+         return  0 ;
924+ 
925+     case  'Z' :
926+         result -> is_str  =  1 ;
927+         ks_clear (& result -> s );
928+         return  (kputsn (& tag -> str [3 ], tag -> len - 3 , & result -> s ) >= 0 )? 0  : -1 ;
929+     }
930+ 
931+     return  -1 ;
932+ }
933+ 
934+ static  int  sam_hrecs_sym_lookup (void  * data , char  * str , char  * * end ,
935+                                 hts_expr_val_t  * result ) {
936+     sam_hrec_type_t  * h_type  =  (sam_hrec_type_t  * ) data ;
937+ 
938+     switch  (* str ) {
939+     case  't' :
940+         if  (memcmp (str , "type" , 4 ) ==  0 ) {
941+             * end  =  & str [4 ];
942+             result -> is_str  =  1 ;
943+             ks_clear (& result -> s );
944+             kputc_ (h_type -> type  >> 8 , & result -> s );
945+             kputc (h_type -> type  &  0xff , & result -> s );
946+             return  (ks_len (& result -> s ) ==  2 )? 0  : -1 ;
947+         }
948+         break ;
949+ 
950+     case  '@' :
951+         if  (isalpha_c (str [1 ]) &&  isalpha_c (str [2 ])) {
952+             * end  =  & str [3 ];
953+             result -> is_str  =  0 ;
954+             result -> is_true  =  result -> d  =  (h_type -> type  ==  TYPEKEY (& str [1 ]));
955+             return  0 ;
956+         }
957+         break ;
958+ 
959+     case  '[' :
960+         if  (str [1 ] &  str [2 ]) {
961+             if  (str [3 ] ==  ']' ) {
962+                 * end  =  & str [4 ];
963+                 return  sam_hrecs_tag_lookup (h_type , & str [1 ], 'Z' , result );
964+             }
965+             else  if  (str [3 ] ==  ':'  &&  str [4 ] &&  str [5 ] ==  ']' ) {
966+                 if  (!strchr ("fiZ" , str [4 ])) {
967+                     hts_log_error ("Unrecognised %.6s type code" , str );
968+                     return  -1 ;
969+                 }
970+                 * end  =  & str [6 ];
971+                 return  sam_hrecs_tag_lookup (h_type , & str [1 ], str [4 ], result );
972+             }
973+         }
974+         break ;
975+     }
976+ 
977+     return  -1 ;
978+ }
979+ 
901980/*! Update sam_hdr_t target_name and target_len arrays 
902981 * 
903982 *  @return 0 on success; -1 on failure 
@@ -1762,6 +1841,21 @@ int sam_hdr_remove_lines(sam_hdr_t *bh, const char *type, const char *id, void *
17621841    return  ret ;
17631842}
17641843
1844+ int  sam_hdr_passes_filter (sam_hdr_t  * bh , sam_hdr_line_itr_t  * iter , hts_filter_t  * filt ) {
1845+     hts_expr_val_t  result ;
1846+     int  ret ;
1847+     if  (hts_filter_eval (filt , iter , sam_hrecs_sym_lookup , & result ) >= 0 ) {
1848+         ret  =  result .is_true ;
1849+     }
1850+     else  {
1851+         hts_log_error ("Couldn't process sam_hdr filter expression" );
1852+         ret  =  -1 ;
1853+     }
1854+ 
1855+     hts_expr_val_free (& result );
1856+     return  ret ;
1857+ }
1858+ 
17651859int  sam_hdr_count_lines (sam_hdr_t  * bh , const  char  * type ) {
17661860    int  count ;
17671861    sam_hrec_type_t  * first_ty , * itr_ty ;
0 commit comments