Skip to content

Commit 04a20ae

Browse files
committed
Use TYPEKEY() for all header type code arithmetic
Change the existing TYPEKEY() macro to a static inline so that the input and output types are more accurately recorded. Take care about casting the plain chars to unsigned, to avoid sign extension bugs and compiler and cppcheck warnings. (This new code results in the same or better assembly code as the previous tests and macro.) Also rename a sam_hdr_remove_lines() parameter [trivial], as the declaration in htslib/sam.h uses different parameter prefixes and the coincidence of different h parameters caused a cppcheck warning.
1 parent e098847 commit 04a20ae

File tree

2 files changed

+24
-23
lines changed

2 files changed

+24
-23
lines changed

header.c

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,10 @@ static void sam_hrecs_remove_ref_altnames(sam_hrecs_t *hrecs, int expected, cons
136136
* -1 on failure
137137
*/
138138
static int sam_hrecs_update_hashes(sam_hrecs_t *hrecs,
139-
int type,
139+
khint32_t type,
140140
sam_hrec_type_t *h_type) {
141141
/* Add to reference hash? */
142-
if ((type>>8) == 'S' && (type&0xff) == 'Q') {
142+
if (type == TYPEKEY("SQ")) {
143143
sam_hrec_tag_t *tag = h_type->tag;
144144
int nref = hrecs->nref;
145145
const char *name = NULL;
@@ -259,7 +259,7 @@ static int sam_hrecs_update_hashes(sam_hrecs_t *hrecs,
259259
}
260260

261261
/* Add to read-group hash? */
262-
if ((type>>8) == 'R' && (type&0xff) == 'G') {
262+
if (type == TYPEKEY("RG")) {
263263
sam_hrec_tag_t *tag = sam_hrecs_find_key(h_type, "ID", NULL);
264264
int nrg = hrecs->nrg, r;
265265
khint_t k;
@@ -307,7 +307,7 @@ static int sam_hrecs_update_hashes(sam_hrecs_t *hrecs,
307307
}
308308

309309
/* Add to program hash? */
310-
if ((type>>8) == 'P' && (type&0xff) == 'G') {
310+
if (type == TYPEKEY("PG")) {
311311
sam_hrec_tag_t *tag;
312312
sam_hrec_pg_t *new_pg;
313313
int npg = hrecs->npg;
@@ -392,7 +392,7 @@ static int sam_hrecs_update_hashes(sam_hrecs_t *hrecs,
392392
return 0;
393393
}
394394

395-
static int sam_hrecs_remove_hash_entry(sam_hrecs_t *hrecs, int type, sam_hrec_type_t *h_type) {
395+
static int sam_hrecs_remove_hash_entry(sam_hrecs_t *hrecs, khint32_t type, sam_hrec_type_t *h_type) {
396396
if (!hrecs || !h_type)
397397
return -1;
398398

@@ -401,7 +401,7 @@ static int sam_hrecs_remove_hash_entry(sam_hrecs_t *hrecs, int type, sam_hrec_ty
401401
khint_t k;
402402

403403
/* Remove name and any alternative names from reference hash */
404-
if ((type>>8) == 'S' && (type&0xff) == 'Q') {
404+
if (type == TYPEKEY("SQ")) {
405405
const char *altnames = NULL;
406406

407407
tag = h_type->tag;
@@ -441,7 +441,7 @@ static int sam_hrecs_remove_hash_entry(sam_hrecs_t *hrecs, int type, sam_hrec_ty
441441
}
442442

443443
/* Remove from read-group hash */
444-
if ((type>>8) == 'R' && (type&0xff) == 'G') {
444+
if (type == TYPEKEY("RG")) {
445445
tag = h_type->tag;
446446

447447
while (tag) {
@@ -482,7 +482,7 @@ static int sam_hrecs_remove_hash_entry(sam_hrecs_t *hrecs, int type, sam_hrec_ty
482482
static void sam_hrecs_global_list_add(sam_hrecs_t *hrecs,
483483
sam_hrec_type_t *h_type,
484484
sam_hrec_type_t *after) {
485-
const khint32_t hd_type = 'H' << 8 | 'D';
485+
const khint32_t hd_type = TYPEKEY("HD");
486486
int update_first_line = 0;
487487

488488
// First line seen
@@ -536,7 +536,7 @@ static int sam_hrecs_vadd(sam_hrecs_t *hrecs, const char *type, va_list ap, ...)
536536
sam_hrec_type_t *h_type;
537537
sam_hrec_tag_t *h_tag, *last=NULL;
538538
int new;
539-
khint32_t type_i = (type[0]<<8) | type[1], k;
539+
khint32_t type_i = TYPEKEY(type), k;
540540

541541
if (!strncmp(type, "HD", 2) && (h_type = sam_hrecs_find_type_id(hrecs, "HD", NULL, NULL)))
542542
return sam_hrecs_vupdate(hrecs, h_type, ap);
@@ -648,8 +648,7 @@ static int sam_hrecs_vadd(sam_hrecs_t *hrecs, const char *type, va_list ap, ...)
648648
last = h_tag;
649649
}
650650

651-
int itype = (type[0]<<8) | type[1];
652-
if (-1 == sam_hrecs_update_hashes(hrecs, itype, h_type))
651+
if (-1 == sam_hrecs_update_hashes(hrecs, TYPEKEY(type), h_type))
653652
return -1;
654653

655654
if (!strncmp(type, "PG", 2))
@@ -687,7 +686,7 @@ static int sam_hrecs_remove_line(sam_hrecs_t *hrecs, const char *type_name, sam_
687686
if (!hrecs || !type_name || !type_found)
688687
return -1;
689688

690-
int itype = (type_name[0]<<8) | type_name[1];
689+
khint32_t itype = TYPEKEY(type_name);
691690
khint_t k = kh_get(sam_hrecs_t, hrecs->h, itype);
692691
if (k == kh_end(hrecs->h))
693692
return -1;
@@ -786,12 +785,12 @@ static int sam_hrecs_parse_lines(sam_hrecs_t *hrecs, const char *hdr, size_t len
786785
return -1;
787786
}
788787

789-
type = (((uint8_t) hdr[i+1])<<8) | (uint8_t) hdr[i+2];
790788
if (!isalpha_c(hdr[i+1]) || !isalpha_c(hdr[i+2])) {
791789
sam_hrecs_error("Header line does not have a two character key",
792790
&hdr[l_start], len - l_start, lno);
793791
return -1;
794792
}
793+
type = TYPEKEY(&hdr[i+1]);
795794

796795
i += 3;
797796
if (i == len || hdr[i] == '\n')
@@ -827,7 +826,7 @@ static int sam_hrecs_parse_lines(sam_hrecs_t *hrecs, const char *hdr, size_t len
827826

828827
// Parse the tags on this line
829828
last = NULL;
830-
if ((type>>8) == 'C' && (type&0xff) == 'O') {
829+
if (type == TYPEKEY("CO")) {
831830
size_t j;
832831

833832
if (i == len || hdr[i] != '\t') {
@@ -1624,8 +1623,7 @@ int sam_hdr_remove_except(sam_hdr_t *bh, const char *type, const char *ID_key, c
16241623

16251624
sam_hrec_type_t *type_found = sam_hrecs_find_type_id(hrecs, type, ID_key, ID_value);
16261625
if (!type_found) { // remove all line of this type
1627-
int itype = (type[0]<<8)|(type[1]);
1628-
khint_t k = kh_get(sam_hrecs_t, hrecs->h, itype);
1626+
khint_t k = kh_get(sam_hrecs_t, hrecs->h, TYPEKEY(type));
16291627
if (k == kh_end(hrecs->h))
16301628
return 0;
16311629
type_found = kh_val(hrecs->h, k);
@@ -1650,9 +1648,9 @@ int sam_hdr_remove_except(sam_hdr_t *bh, const char *type, const char *ID_key, c
16501648
return 0;
16511649
}
16521650

1653-
int sam_hdr_remove_lines(sam_hdr_t *bh, const char *type, const char *id, void *h) {
1651+
int sam_hdr_remove_lines(sam_hdr_t *bh, const char *type, const char *id, void *vrh) {
16541652
sam_hrecs_t *hrecs;
1655-
rmhash_t *rh = (rmhash_t *)h;
1653+
rmhash_t *rh = (rmhash_t *)vrh;
16561654

16571655
if (!bh || !type)
16581656
return -1;
@@ -1667,8 +1665,7 @@ int sam_hdr_remove_lines(sam_hdr_t *bh, const char *type, const char *id, void *
16671665
hrecs = bh->hrecs;
16681666
}
16691667

1670-
int itype = (type[0]<<8)|(type[1]);
1671-
khint_t k = kh_get(sam_hrecs_t, hrecs->h, itype);
1668+
khint_t k = kh_get(sam_hrecs_t, hrecs->h, TYPEKEY(type));
16721669
if (k == kh_end(hrecs->h)) // nothing to remove from
16731670
return 0;
16741671

@@ -2411,7 +2408,6 @@ sam_hrec_type_t *sam_hrecs_find_type_id(sam_hrecs_t *hrecs, const char *type,
24112408
if (!hrecs || !type)
24122409
return NULL;
24132410
sam_hrec_type_t *t1, *t2;
2414-
int itype = (type[0]<<8)|(type[1]);
24152411
khint_t k;
24162412

24172413
/* Special case for types we have prebuilt hashes on */
@@ -2444,7 +2440,7 @@ sam_hrec_type_t *sam_hrecs_find_type_id(sam_hrecs_t *hrecs, const char *type,
24442440
}
24452441
}
24462442

2447-
k = kh_get(sam_hrecs_t, hrecs->h, itype);
2443+
k = kh_get(sam_hrecs_t, hrecs->h, TYPEKEY(type));
24482444
if (k == kh_end(hrecs->h))
24492445
return NULL;
24502446

header.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5353
extern "C" {
5454
#endif
5555

56-
#define TYPEKEY(a) (((a)[0]<<8)|((a)[1]))
56+
/*! Make a single integer out of a two-letter type code */
57+
static inline khint32_t TYPEKEY(const char *type) {
58+
unsigned int u0 = (unsigned char) type[0];
59+
unsigned int u1 = (unsigned char) type[1];
60+
return (u0 << 8) | u1;
61+
}
5762

5863
/*
5964
* Proposed new SAM header parsing

0 commit comments

Comments
 (0)