@@ -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