@@ -34,6 +34,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
34
#include <string.h>
35
35
#include <assert.h>
36
36
#include <errno.h>
37
+ #include "htslib/hts_expr.h"
37
38
#include "textutils_internal.h"
38
39
#include "header.h"
39
40
@@ -898,6 +899,84 @@ static int sam_hrecs_parse_lines(sam_hrecs_t *hrecs, const char *hdr, size_t len
898
899
return 0 ;
899
900
}
900
901
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
+
901
980
/*! Update sam_hdr_t target_name and target_len arrays
902
981
*
903
982
* @return 0 on success; -1 on failure
@@ -1757,6 +1836,21 @@ int sam_hdr_remove_lines(sam_hdr_t *bh, const char *type, const char *id, void *
1757
1836
return ret ;
1758
1837
}
1759
1838
1839
+ int sam_hdr_passes_filter (sam_hdr_t * bh , sam_hdr_line_t * line , hts_filter_t * filt ) {
1840
+ hts_expr_val_t result ;
1841
+ int ret ;
1842
+ if (hts_filter_eval (filt , line , sam_hrecs_sym_lookup , & result ) >= 0 ) {
1843
+ ret = result .is_true ;
1844
+ }
1845
+ else {
1846
+ hts_log_error ("Couldn't process sam_hdr filter expression" );
1847
+ ret = -1 ;
1848
+ }
1849
+
1850
+ hts_expr_val_free (& result );
1851
+ return ret ;
1852
+ }
1853
+
1760
1854
int sam_hdr_count_lines (sam_hdr_t * bh , const char * type ) {
1761
1855
int count ;
1762
1856
sam_hrec_type_t * first_ty , * itr_ty ;
0 commit comments