--- /dev/null
+#define BITS_IN_BYTE 8
+#define BYTE_ON 255
+
+#define BIT0 0 /* 00000000 */
+#define BIT1 ( 1 << 8 ) /* 10000000 */
+#define BIT2 ( 1 << 7 ) /* 01000000 */
+#define BIT3 ( 1 << 5 ) /* 00100000 */
+#define BIT4 ( 1 << 4 ) /* 00010000 */
+#define BIT5 ( 1 << 3 ) /* 00001000 */
+#define BIT6 ( 1 << 2 ) /* 00000100 */
+#define BIT7 ( 1 << 1 ) /* 00000010 */
+#define BIT8 1 /* 00000001 */
+
+/* Bitarray structure */
+struct _bitarray
+{
+ size_t size; /* number of bits in bitarray. */
+ size_t bits_on; /* number of bits set to 'on'. */
+ char *str; /* bit string. */
+ size_t str_len; /* length of bit string. */
+ size_t modulus; /* number of bits used in last element of str. */
+ char mask; /* bit mask to trim length of str. */
+};
+
+typedef struct _bitarray bitarray;
+
+/* Initialize a new bitarray of a given size in bits. */
+void bitarray_new( bitarray **ba_ppt, size_t size );
+
+/* Set all bits in bitarray to 'on'. */
+void bitarray_fill( bitarray *ba_pt );
+
+/* Set all bits in bitarray to 'off'. */
+void bitarray_zero( bitarray *ba_pt );
+
+/* Test if a specific bit in a bitarray is set to 'on'. */
+bool bitarray_bit_on( bitarray *ba_pt, size_t pos );
+
+/* Set the bit at a given position in a bitarray to 'on'. */
+void bitarray_bit_set( bitarray *ba_pt, size_t pos );
+
+/* Debug function to print a bitarray. */
+void bitarray_print( bitarray *ba_pt );
+
+/* Deallocate memory for bitarray. */
+void bitarray_destroy( bitarray **ba_ppt );
+
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> STRUCTURE DECLARATIONS <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-/* Singly linked list with a pointer to the next element and a pointer to a value. */
-struct _list
+/* Singly linked list node. */
+struct _node_sl
{
- struct _list *next;
- void *val;
+ struct _node_sl *next; /* Pointer to next node - NULL if last. */
+ void *val; /* Pointer to data value. */
};
-typedef struct _list list;
+typedef struct _node_sl node_sl;
-/* Singly linked list with a pointer to the next element and an integer value. */
-struct _list_int
+/* Singly linked list. */
+struct _list_sl
{
- struct _list_int *next;
- int val;
+ node_sl *first; /* Pointer to first node - NULL for empty list. */
};
-typedef struct _list_int list_int;
+typedef struct _list_sl list_sl;
/* Doubly linked list node. */
struct _node_dl
/* Doubly linked list. */
struct _list_dl
{
- node_dl *first; /* Pointer to first node - NULL for empty list. */
+ node_dl *first; /* Pointer to first node - NULL for empty list. */
node_dl *last; /* Pointer to last node - NULL for empty list. */
};
typedef struct _list_dl list_dl;
+
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FUNCTION DECLARATIONS <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> SINGLY LINLED LIST <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-/* Add a new singly linked list element with a pointer. */
-void list_add( list **list_ppt, void *val );
-
-/* Add a new singly linked list element with an integer. */
-void list_add_int( list_int **list_ppt, int val );
+/* Initialize a new singly linked list. */
+void list_sl_new( list_sl **list_ppt );
-/* Reverse the order of elements in a singly linked list. */
-/* Usage: list_reverse( &list ) */
-void list_reverse( void *list_pt );
+/* Add a new node to the beginning of a singly linked list. */
+void list_sl_add_beg( list_sl **list_ppt, node_sl **node_ppt );
-/* Check if a given string exists in a singly linked list. */
-bool list_exists( list *list_pt, char *string );
+/* Add a new node after a given node of a singly linked list. */
+void list_sl_add_after( node_sl **node_ppt, node_sl **new_node_ppt );
-/* Check if a given integer exists in a singly linked list. */
-bool list_exists_int( list_int *list_pt, int val );
+/* Remove the first node of a singly linked list. */
+void list_sl_remove_beg( list_sl **list_ppt );
-/* Free memory for all elements of a singly linked list. */
-void list_free( void *list_pt );
+/* Remove the node next to this one in a singly linked list. */
+void list_sl_remove_after( node_sl **node_ppt );
/* Debug function to print all elements from a singly linked list. */
-void list_print( void *list_pt );
-
+void list_sl_print( list_sl *list_pt );
+
+/* Free memory for all nodes in and including the singly linked list. */
+void list_sl_destroy( list_sl **list_ppt );
+
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DOUBLY LINKED LIST <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+
/* Initialize a new doubly linked list. */
void list_dl_new( list_dl **list_ppt );
/* Debug function to print all elements from a doubly linked list. */
void list_dl_print( list_dl *list_pt );
+/* Free memory for all nodes in and including the doubly linked list. */
+void list_dl_destroy( list_dl **list_ppt );
+
+
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
void seq_destroy( seq_entry *entry );
/* Uppercase sequence. */
-void uppercase_seq( char *seq );
+void seq_uppercase( char *seq );
/* Lowercase sequence. */
void lowercase_seq( char *seq );
Cflags = -Wall -Werror -g -pg # gprof
INC_DIR = -I ../inc/
-all: common.o mem.o strings.o seq.o filesys.o fasta.o list.o hash.o ucsc.o
+all: bits.o common.o mem.o strings.o seq.o filesys.o fasta.o list.o hash.o ucsc.o
+
+bits.o: bits.c
+ $(CC) $(Cflags) $(INC_DIR) -c bits.c
common.o: common.c
$(CC) $(Cflags) $(INC_DIR) -c common.c
$(CC) $(Cflags) $(INC_DIR) -c ucsc.c
clean:
+ rm bits.o
rm common.o
rm mem.o
rm strings.o
--- /dev/null
+#include "common.h"
+#include "mem.h"
+#include "bits.h"
+
+
+static int mask_array[ 8 ] = {
+ BIT1, /* 10000000 */
+ BIT2, /* 01000000 */
+ BIT3, /* 00100000 */
+ BIT4, /* 00010000 */
+ BIT5, /* 00001000 */
+ BIT6, /* 00000100 */
+ BIT7, /* 00000010 */
+ BIT8, /* 00000001 */
+};
+
+
+void bitarray_new( bitarray **ba_ppt, size_t size )
+{
+ /* Martin A. Hansen, August 2008. */
+
+ /* Initialize a new bitarray of a given size in bits. */
+
+ bitarray *ba_pt = *ba_ppt;
+ size_t str_len = 0;
+ size_t modulus = 0;
+
+ assert( size > 0 );
+
+ ba_pt = mem_get( sizeof( bitarray ) );
+
+ str_len = size / BITS_IN_BYTE;
+ modulus = size % BITS_IN_BYTE;
+
+ if ( modulus != 0 ) {
+ str_len++;
+ }
+
+ ba_pt->size = size;
+ ba_pt->str_len = str_len;
+ ba_pt->str = mem_get_zero( str_len + 1 );
+ ba_pt->bits_on = 0;
+
+ *ba_ppt = ba_pt;
+}
+
+
+void bitarray_fill( bitarray *ba_pt )
+{
+ /* Martin A. Hansen, August 2008. */
+
+ /* Set all bits in bitarray to 'on'. */
+
+ memset( ba_pt->str, BYTE_ON, ba_pt->str_len );
+
+ ba_pt->bits_on = ba_pt->size;
+}
+
+
+void bitarray_zero( bitarray *ba_pt )
+{
+ /* Martin A. Hansen, August 2008. */
+
+ /* Set all bits in bitarray to 'off'. */
+
+ bzero( ba_pt->str, ba_pt->str_len );
+
+ ba_pt->bits_on = 0;
+}
+
+
+bool bitarray_bit_on( bitarray *ba_pt, size_t pos )
+{
+ /* Martin A. Hansen, August 2008. */
+
+ /* Test if a specific bit in a bitarray is set to 'on'. */
+
+ /* if pos == 0: */
+ /* ruler: 01234567 89012345 67890123 */
+ /* bitarray: 00100100 10001000 00010001 */
+ /* pos: x */
+ /* BIT1: 10000000 */
+ /* AND (&): 00000000 */
+
+ /* if pos > 0 && modulus > 0: */
+ /* ruler: 01234567 89012345 67890123 */
+ /* bitarray: 00100100 10001000 00010001 */
+ /* pos: x */
+ /* BIT4 (modulus 3): 00010000 */
+ /* AND (&): 00010000 */
+
+ assert( pos <= ba_pt->size );
+
+ size_t str_pos = 0;
+ size_t modulus = 0;
+
+ modulus = pos % BITS_IN_BYTE;
+ str_pos = pos ? ( pos / BITS_IN_BYTE ) : 0;
+
+ if ( modulus != 0 ) {
+ str_pos++;
+ }
+
+ if ( ba_pt->str[ str_pos ] & mask_array[ modulus ] ) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+
+void bitarray_bit_set( bitarray *ba_pt, size_t pos )
+{
+ /* Martin A. Hansen, August 2008. */
+
+ /* Set the bit at a given position in a bitarray to 'on'. */
+
+ /* if pos == 0: */
+ /* ruler: 01234567 89012345 67890123 */
+ /* bitarray: 00100100 10001000 00010001 */
+ /* pos: x */
+ /* BIT1: 10000000 */
+ /* OR (|): 10100100 */
+
+ /* if pos > 0 && modulus > 0: */
+ /* ruler: 01234567 89012345 67890123 */
+ /* bitarray: 00100100 10001000 00010001 */
+ /* pos: x */
+ /* BIT5 (modulus 4): 00001000 */
+ /* OR (|): 00011001 */
+
+ assert( pos <= ba_pt->size );
+
+ size_t str_pos = 0;
+ size_t modulus = 0;
+
+ modulus = pos % BITS_IN_BYTE;
+ str_pos = pos ? ( pos / BITS_IN_BYTE ) : 0;
+
+ if ( modulus != 0 ) {
+ str_pos++;
+ }
+
+ ba_pt->str[ str_pos ] |= mask_array[ modulus ];
+}
+
+
+void bitarray_print( bitarray *ba_pt )
+{
+ /* Martin A. Hansen, August 2008. */
+
+ /* Debug function to print a bitarray. */
+
+ char *str = NULL;
+ size_t i = 0;
+
+ str = mem_get_zero( ba_pt->size + 1 );
+
+ for ( i = 0; i < ba_pt->size; i++ )
+ {
+ if ( bitarray_bit_on( ba_pt, i ) ) {
+ str[ i ] = '1';
+ } else {
+ str[ i ] = '0';
+ }
+ }
+
+ printf( "\n" );
+ printf( "ba_pt->str: %s\n", str );
+ printf( "ba_pt->str (raw): %s\n", ba_pt->str );
+ printf( "ba_pt->size: %zu\n", ba_pt->size );
+ printf( "ba_pt->str_len: %zu\n", ba_pt->str_len );
+ printf( "ba_pt->bits_on: %zu\n", ba_pt->bits_on );
+
+ mem_free( &str );
+}
+
+
+void bitarray_destroy( bitarray **ba_ppt )
+{
+ /* Martin A. Hansen, August 2008. */
+
+ /* Deallocate memory for bitarray. */
+
+ bitarray *ba_pt = *ba_ppt;
+
+ mem_free( &ba_pt->str );
+
+ *ba_ppt = NULL;
+}
#include "list.h"
-void list_add( list **list_ppt, void *val )
+/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> SINGLY LINKED LIST <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+
+
+void list_sl_new( list_sl **list_ppt )
{
- /* Martin A. Hansen, May 2008 */
+ /* Martin A. Hansen, August 2008 */
- /* Add a new singly linked list element with a pointer. */
+ /* Initialize a new singly linked list. */
- list *list_pt = *list_ppt;
- list *new = NULL;
+ list_sl *new = NULL;
- new = mem_get( sizeof( list ) );
+ new = mem_get( sizeof( list_sl ) );
- new->val = val;
- new->next = list_pt;
+ new->first = NULL;
*list_ppt = new;
}
-void list_add_int( list_int **list_ppt, int val )
+void list_sl_add_beg( list_sl **list_ppt, node_sl **node_ppt )
{
- /* Martin A. Hansen, May 2008 */
-
- /* Add a new singly linked list element with a integer. */
+ /* Martin A. Hansen, August 2008 */
- list_int *elem = NULL;
+ /* Add a new node to the beginning of a singly linked list. */
- elem = mem_get( sizeof( list_int ) );
+ list_sl *list_pt = *list_ppt;
+ node_sl *node_pt = *node_ppt;
- elem->val = val;
- elem->next = *list_ppt;
- *list_ppt = elem;
+ node_pt->next = list_pt->first;
+ list_pt->first = node_pt;
}
-void list_reverse( void *list_pt )
+void list_sl_add_after( node_sl **node_ppt, node_sl **new_node_ppt )
{
/* Martin A. Hansen, August 2008 */
- /* Reverse the order of elements in a singly linked list. */
+ /* Add a new node after a given node of a singly linked list. */
+
+ node_sl *node_pt = *node_ppt;
+ node_sl *new_node_pt = *new_node_ppt;
+
+ new_node_pt->next = node_pt->next;
+ node_pt->next = new_node_pt;
+}
- list **list_ppt = ( list ** ) list_pt;
- list *pt = *list_ppt;
- list *new = NULL;
- list *next = NULL;
- list *temp = NULL;
- next = pt;
+void list_sl_remove_beg( list_sl **list_ppt )
+{
+ /* Martin A. Hansen, August 2008 */
- while ( next != NULL )
- {
- temp = next;
- next = temp->next;
- temp->next = new;
- new = temp;
- }
+ /* Remove the first node of a singly linked list. */
- *list_ppt = new;
+ list_sl *list_pt = *list_ppt;
+ node_sl *old_node = NULL;
+
+ old_node = list_pt->first;
+ list_pt->first = list_pt->first->next;
+
+ mem_free( &old_node );
}
-bool list_exists( list *list_pt, char *string )
+void list_sl_remove_after( node_sl **node_ppt )
{
- /* Martin A. Hansen, June 2008 */
-
- /* Check if a given string exists in a singly linked list. */
+ /* Martin A. Hansen, August 2008 */
- list *elem = NULL;
+ /* Remove the node next to this one in a singly linked list. */
- elem = mem_get( sizeof( list ) );
+ node_sl *node_pt = *node_ppt;
+ node_sl *old_node = NULL;
- for ( elem = list_pt; elem != NULL; elem = elem->next )
- {
- if ( strcmp( elem->val, string ) == 0 ) {
- return TRUE;
- }
- }
+ old_node = node_pt->next;
+ node_pt->next = node_pt->next->next;
- return FALSE;
-}
+ mem_free( &old_node );
+}
-bool list_exists_int( list_int *list_pt, int val )
+void list_sl_print( list_sl *list_pt )
{
- /* Martin A. Hansen, June 2008 */
-
- /* Check if a given integer exists in a singly linked list. */
+ /* Martin A. Hansen, August 2008 */
- list_int *elem = NULL;
+ /* Debug function to print all elements from a singly linked list. */
- elem = mem_get( sizeof( list_int ) );
+ node_sl *node = list_pt->first;
+ int i = 0;
- for ( elem = list_pt; elem != NULL; elem = elem->next )
+ while ( node != NULL )
{
- if ( elem->val == val ) {
- return TRUE;
- }
- }
+ printf( "Node: %d val: %s\n", i, ( char * ) node->val );
- return FALSE;
-}
+ node = node->next;
+
+ i++;
+ }
+}
-void list_free( void *list_pt )
+void list_sl_destroy( list_sl **list_ppt )
{
- /* Martin A. Hansen, June 2008 */
+ /* Martin A. Hansen, August 2008 */
- /* Free memory for all elements of a singly linked list. */
+ /* Free memory for all nodes in and including the singly linked list. */
- list **list_ppt = ( list ** ) list_pt;
- list *next = *list_ppt;
- list *elem = NULL;
+ list_sl *list_pt = *list_ppt;
+ node_sl *next = list_pt->first;
+ node_sl *node = NULL;
while ( next != NULL )
{
- elem = next;
-
-// printf( "elem->val: %s\n", ( char * ) elem->val );
+ node = next;
+ next = node->next;
- next = elem->next;
-// mem_free( &elem );
- free( elem );
+ mem_free( &node );
}
+ mem_free( &list_pt );
+
*list_ppt = NULL;
}
-void list_print( void *list_pt )
-{
- /* Martin A. Hansen, June 2008 */
-
- /* Debug function to print all elements from a singly linked list. */
-
- list *first = ( list * ) list_pt;
- list *elem = NULL;
- int i = 0;
-
- for ( elem = first; elem != NULL; elem = elem->next )
- {
- printf( "Elem %d: ->%s<-\n", i, ( char * ) elem->val );
-
- i++;
- }
-}
+/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DOUBLY LINKED LIST <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
void list_dl_new( list_dl **list_ppt )
i++;
}
}
+
+
+void list_dl_destroy( list_dl **list_ppt )
+{
+ /* Martin A. Hansen, August 2008 */
+
+ /* Free memory for all nodes in and including the doubly linked list. */
+
+ list_dl *list_pt = *list_ppt;
+ node_dl *next = list_pt->first;
+ node_dl *node = NULL;
+
+ while ( next != NULL )
+ {
+ node = next;
+ next = node->next;
+
+ mem_free( &node );
+ }
+
+ mem_free( &list_pt );
+
+ *list_ppt = NULL;
+}
+
+
+/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
pt = mem_get( size );
- memset( pt, '\0', size );
+ bzero( pt, size );
return pt;
}
pt_new = mem_resize( pt, new_size );
if ( new_size > old_size ) {
- memset( ( ( void * ) pt_new ) + old_size, '\0', new_size - old_size );
+ bzero( ( ( void * ) pt_new ) + old_size, new_size - old_size );
}
return pt_new;
}
-void uppercase_seq( char *seq )
+void seq_uppercase( char *seq )
{
/* Martin A. Hansen, May 2008 */
all: test
-test: test_common test_fasta test_filesys test_list test_mem test_seq test_strings
+test: test_bits test_common test_fasta test_filesys test_list test_mem test_seq test_strings
+
+test_bits: test_bits.c $(LIB_DIR)bits.c
+ $(CC) $(Cflags) $(INC) $(LIB) test_bits.c -o test_bits
test_common: test_common.c $(LIB_DIR)common.c
$(CC) $(Cflags) $(INC) $(LIB) test_common.c -o test_common
$(CC) $(Cflags) $(INC) $(LIB) test_strings.c -o test_strings
clean:
+ rm test_bits
rm test_common
rm test_fasta
rm test_filesys
--- /dev/null
+#include "common.h"
+#include "bits.h"
+
+static void test_bitarray_new();
+static void test_bitarray_fill();
+static void test_bitarray_zero();
+static void test_bitarray_bit_on();
+static void test_bitarray_bit_set();
+static void test_bitarray_print();
+static void test_bitarray_destroy();
+
+
+int main()
+{
+ fprintf( stderr, "Running all tests for bits.c\n" );
+
+ test_bitarray_new();
+ test_bitarray_fill();
+ test_bitarray_zero();
+ test_bitarray_bit_on();
+ test_bitarray_bit_set();
+ test_bitarray_print();
+ test_bitarray_destroy();
+
+ fprintf( stderr, "Done\n\n" );
+
+ return EXIT_SUCCESS;
+}
+
+
+void test_bitarray_new()
+{
+ fprintf( stderr, " Testing bitarray_new ... " );
+
+ bitarray *ba = NULL;
+ size_t size = 6;
+
+ bitarray_new( &ba, size );
+
+ bitarray_destroy( &ba );
+
+ fprintf( stderr, "OK\n" );
+}
+
+
+void test_bitarray_fill()
+{
+ fprintf( stderr, " Testing bitarray_fill ... " );
+
+ bitarray *ba = NULL;
+ size_t size = 2;
+
+ bitarray_new( &ba, size );
+
+ assert( bitarray_bit_on( ba, size - 1 ) == FALSE );
+
+ bitarray_print( ba );
+ bitarray_fill( ba );
+ bitarray_print( ba );
+
+ assert( bitarray_bit_on( ba, size - 1 ) == TRUE );
+
+// bitarray_print( ba );
+
+ bitarray_destroy( &ba );
+
+ fprintf( stderr, "OK\n" );
+}
+
+
+void test_bitarray_zero()
+{
+ fprintf( stderr, " Testing bitarray_zero ... " );
+
+ bitarray *ba = NULL;
+ size_t size = 26;
+
+ bitarray_new( &ba, size );
+ bitarray_fill( ba );
+
+// assert( bitarray_bit_on( ba, size ) == TRUE );
+
+ bitarray_zero( ba );
+
+// assert( bitarray_bit_on( ba, size ) == FALSE );
+
+ bitarray_destroy( &ba );
+
+ fprintf( stderr, "OK\n" );
+}
+
+
+void test_bitarray_bit_on()
+{
+ fprintf( stderr, " Testing bitarray_bit_on ... " );
+
+ bitarray *ba = NULL;
+ size_t size = 26;
+
+ bitarray_new( &ba, size );
+
+ assert( bitarray_bit_on( ba, 20 ) == FALSE );
+ assert( bitarray_bit_on( ba, 0 ) == FALSE );
+ assert( bitarray_bit_on( ba, 8 ) == FALSE );
+
+ bitarray_destroy( &ba );
+
+ fprintf( stderr, "OK\n" );
+}
+
+
+void test_bitarray_bit_set()
+{
+ fprintf( stderr, " Testing bitarray_bit_set ... " );
+
+ bitarray *ba = NULL;
+ size_t size = 26;
+
+ bitarray_new( &ba, size );
+
+ bitarray_bit_set( ba, 20 );
+ assert( bitarray_bit_on( ba, 20 ) == TRUE );
+
+ bitarray_bit_set( ba, 0 );
+ //assert( bitarray_bit_on( ba, 0 ) == TRUE );
+
+ bitarray_bit_set( ba, 8 );
+ //assert( bitarray_bit_on( ba, 8 ) == TRUE );
+
+ bitarray_destroy( &ba );
+
+ fprintf( stderr, "OK\n" );
+}
+
+
+void test_bitarray_print()
+{
+ fprintf( stderr, " Testing bitarray_print ... " );
+
+ bitarray *ba = NULL;
+ size_t size = 6;
+
+ bitarray_new( &ba, size );
+ bitarray_print( ba );
+
+ bitarray_destroy( &ba );
+
+ fprintf( stderr, "OK\n" );
+}
+
+
+void test_bitarray_destroy()
+{
+ fprintf( stderr, " Testing bitarray_destroy ... " );
+
+ bitarray *ba = NULL;
+ size_t size = 26;
+
+ bitarray_new( &ba, size );
+
+ bitarray_destroy( &ba );
+
+ assert( ba == NULL );
+
+ fprintf( stderr, "OK\n" );
+}
+
+
--- /dev/null
+#include "common.h"
+#include "mem.h"
+#include "list.h"
+
+static void test_list_sl_new();
+static void test_list_sl_add_beg();
+static void test_list_sl_add_after();
+static void test_list_sl_remove_beg();
+static void test_list_sl_remove_after();
+static void test_list_sl_print();
+static void test_list_sl_destroy();
+
+static void test_list_dl_new();
+static void test_list_dl_add_beg();
+static void test_list_dl_add_end();
+static void test_list_dl_add_before();
+static void test_list_dl_add_after();
+static void test_list_dl_remove();
+static void test_list_dl_print();
+static void test_list_dl_destroy();
+
+int main()
+{
+ fprintf( stderr, "Running all tests for list.c\n" );
+
+ test_list_sl_new();
+ test_list_sl_add_beg();
+ test_list_sl_add_after();
+ test_list_sl_remove_beg();
+ test_list_sl_remove_after();
+ test_list_sl_print();
+ test_list_sl_destroy();
+
+ test_list_dl_new();
+ test_list_dl_add_beg();
+ test_list_dl_add_end();
+ test_list_dl_add_before();
+ test_list_dl_add_after();
+ test_list_dl_remove();
+ test_list_dl_print();
+ test_list_dl_destroy();
+
+ fprintf( stderr, "Done\n\n" );
+
+ return EXIT_SUCCESS;
+}
+
+
+void test_list_sl_new()
+{
+ fprintf( stderr, " Testing list_sl_new ... " );
+
+ list_sl *list = NULL;
+
+ list_sl_new( &list );
+
+ assert( list->first == NULL );
+
+ fprintf( stderr, "OK\n" );
+}
+
+
+void test_list_sl_add_beg()
+{
+ fprintf( stderr, " Testing list_sl_add_beg ... " );
+
+ list_sl *list = NULL;
+ node_sl *node1 = NULL;
+ node_sl *node2 = NULL;
+ node_sl *node3 = NULL;
+
+ list_sl_new( &list );
+
+ node1 = mem_get( sizeof( node_sl ) );
+ node2 = mem_get( sizeof( node_sl ) );
+ node3 = mem_get( sizeof( node_sl ) );
+
+ node1->val = "TEST1";
+ node2->val = "TEST2";
+ node3->val = "TEST3";
+
+ assert( list->first == NULL );
+
+ list_sl_add_beg( &list, &node1 );
+ assert( list->first == node1 );
+ assert( strcmp( list->first->val, "TEST1" ) == 0 );
+
+ list_sl_add_beg( &list, &node2 );
+ assert( list->first == node2 );
+ assert( strcmp( list->first->val, "TEST2" ) == 0 );
+
+ list_sl_add_beg( &list, &node3 );
+ assert( list->first == node3 );
+ assert( strcmp( list->first->val, "TEST3" ) == 0 );
+
+ fprintf( stderr, "OK\n" );
+}
+
+
+void test_list_sl_add_after()
+{
+ fprintf( stderr, " Testing list_sl_add_after ... " );
+
+ list_sl *list = NULL;
+ node_sl *node1 = NULL;
+ node_sl *node2 = NULL;
+
+ list_sl_new( &list );
+
+ node1 = mem_get( sizeof( node_sl ) );
+ node2 = mem_get( sizeof( node_sl ) );
+
+ node1->val = "TEST1";
+ node2->val = "TEST2";
+
+ assert( list->first == NULL );
+
+ list_sl_add_beg( &list, &node1 );
+ assert( list->first == node1 );
+ assert( strcmp( list->first->val, "TEST1" ) == 0 );
+
+ list_sl_add_after( &node1, &node2 );
+ assert( list->first == node1 );
+ assert( strcmp( list->first->val, "TEST1" ) == 0 );
+
+ fprintf( stderr, "OK\n" );
+}
+
+
+void test_list_sl_remove_beg()
+{
+ fprintf( stderr, " Testing list_sl_remove_beg ... " );
+
+ list_sl *list = NULL;
+ node_sl *node1 = NULL;
+
+ list_sl_new( &list );
+
+ node1 = mem_get( sizeof( node_sl ) );
+
+ node1->val = "TEST1";
+
+ assert( list->first == NULL );
+
+ list_sl_add_beg( &list, &node1 );
+ assert( list->first == node1 );
+ assert( strcmp( list->first->val, "TEST1" ) == 0 );
+
+ list_sl_remove_beg( &list );
+ assert( list->first == NULL );
+
+ fprintf( stderr, "OK\n" );
+}
+
+
+void test_list_sl_remove_after()
+{
+ fprintf( stderr, " Testing list_sl_remove_after ... " );
+
+ list_sl *list = NULL;
+ node_sl *node1 = NULL;
+ node_sl *node2 = NULL;
+
+ list_sl_new( &list );
+
+ node1 = mem_get( sizeof( node_sl ) );
+ node2 = mem_get( sizeof( node_sl ) );
+
+ node1->val = "TEST1";
+ node2->val = "TEST2";
+
+ assert( list->first == NULL );
+
+ list_sl_add_beg( &list, &node1 );
+ assert( list->first == node1 );
+ assert( strcmp( list->first->val, "TEST1" ) == 0 );
+
+ list_sl_add_after( &node1, &node2 );
+ assert( list->first == node1 );
+ assert( strcmp( list->first->val, "TEST1" ) == 0 );
+
+ list_sl_remove_after( &node1 );
+ assert( list->first->next == NULL );
+
+ fprintf( stderr, "OK\n" );
+}
+
+
+void test_list_sl_print()
+{
+ fprintf( stderr, " Testing list_sl_print ... " );
+
+ list_sl *list = NULL;
+ node_sl *node1 = NULL;
+ node_sl *node2 = NULL;
+ node_sl *node3 = NULL;
+
+ list_sl_new( &list );
+
+ node1 = mem_get( sizeof( node_sl ) );
+ node2 = mem_get( sizeof( node_sl ) );
+ node3 = mem_get( sizeof( node_sl ) );
+
+ node1->val = "TEST1";
+ node2->val = "TEST2";
+ node3->val = "TEST3";
+
+ list_sl_add_beg( &list, &node1 );
+ list_sl_add_beg( &list, &node2 );
+ list_sl_add_beg( &list, &node3 );
+
+ // list_sl_print( list );
+
+ fprintf( stderr, "OK\n" );
+}
+
+
+void test_list_sl_destroy()
+{
+ fprintf( stderr, " Testing list_sl_destroy ... " );
+
+ list_sl *list = NULL;
+ node_sl *node1 = NULL;
+ node_sl *node2 = NULL;
+ node_sl *node3 = NULL;
+
+ list_sl_new( &list );
+
+ node1 = mem_get( sizeof( node_sl ) );
+ node2 = mem_get( sizeof( node_sl ) );
+ node3 = mem_get( sizeof( node_sl ) );
+
+ node1->val = "TEST1";
+ node2->val = "TEST2";
+ node3->val = "TEST3";
+
+ list_sl_add_beg( &list, &node1 );
+ list_sl_add_beg( &list, &node2 );
+ list_sl_add_beg( &list, &node3 );
+
+ list_sl_destroy( &list );
+
+ assert( list == NULL );
+
+ fprintf( stderr, "OK\n" );
+}
+
+
+void test_list_dl_new()
+{
+ fprintf( stderr, " Testing list_dl_new ... " );
+
+ list_dl *list = NULL;
+
+ list_dl_new( &list );
+
+ assert( list->first == NULL );
+ assert( list->last == NULL );
+
+ fprintf( stderr, "OK\n" );
+}
+
+
+void test_list_dl_add_beg()
+{
+ fprintf( stderr, " Testing list_dl_add_beg ... " );
+
+ list_dl *list = NULL;
+ node_dl *node1 = NULL;
+ node_dl *node2 = NULL;
+ node_dl *node3 = NULL;
+
+ list_dl_new( &list );
+
+ node1 = mem_get( sizeof( node_dl ) );
+ node2 = mem_get( sizeof( node_dl ) );
+ node3 = mem_get( sizeof( node_dl ) );
+
+ node1->val = "TEST1";
+ node2->val = "TEST2";
+ node3->val = "TEST3";
+
+ list_dl_add_beg( &list, &node1 );
+
+ assert( strcmp( list->first->val, "TEST1" ) == 0 );
+
+ list_dl_add_beg( &list, &node2 );
+
+ assert( strcmp( list->first->val, "TEST2" ) == 0 );
+
+ list_dl_add_beg( &list, &node3 );
+
+ assert( strcmp( list->first->val, "TEST3" ) == 0 );
+
+ fprintf( stderr, "OK\n" );
+}
+
+
+void test_list_dl_add_end()
+{
+ fprintf( stderr, " Testing list_dl_add_end ... " );
+
+ list_dl *list = NULL;
+ node_dl *node1 = NULL;
+ node_dl *node2 = NULL;
+ node_dl *node3 = NULL;
+
+ list_dl_new( &list );
+
+ node1 = mem_get( sizeof( node_dl ) );
+ node2 = mem_get( sizeof( node_dl ) );
+ node3 = mem_get( sizeof( node_dl ) );
+
+ node1->val = "TEST1";
+ node2->val = "TEST2";
+ node3->val = "TEST3";
+
+ list_dl_add_end( &list, &node1 );
+
+ assert( strcmp( list->last->val, "TEST1" ) == 0 );
+
+ list_dl_add_end( &list, &node2 );
+
+ assert( strcmp( list->last->val, "TEST2" ) == 0 );
+
+ list_dl_add_end( &list, &node3 );
+
+ assert( strcmp( list->last->val, "TEST3" ) == 0 );
+
+ fprintf( stderr, "OK\n" );
+}
+
+
+void test_list_dl_add_before()
+{
+ fprintf( stderr, " Testing list_dl_add_before ... " );
+
+ list_dl *list = NULL;
+ node_dl *node1 = NULL;
+ node_dl *node2 = NULL;
+ node_dl *node3 = NULL;
+
+ list_dl_new( &list );
+
+ node1 = mem_get( sizeof( node_dl ) );
+ node2 = mem_get( sizeof( node_dl ) );
+ node3 = mem_get( sizeof( node_dl ) );
+
+ node1->val = "TEST1";
+ node2->val = "TEST2";
+ node3->val = "TEST3";
+
+ list_dl_add_beg( &list, &node1 );
+
+ assert( strcmp( list->first->val, "TEST1" ) == 0 );
+
+ list_dl_add_before( &list, &node1, &node2 );
+
+ assert( strcmp( list->first->val, "TEST2" ) == 0 );
+
+ list_dl_add_before( &list, &node1, &node3 );
+
+ assert( strcmp( list->first->val, "TEST2" ) == 0 );
+
+ list_dl_add_before( &list, &node2, &node3 );
+
+ assert( strcmp( list->first->val, "TEST3" ) == 0 );
+
+ fprintf( stderr, "OK\n" );
+}
+
+
+void test_list_dl_add_after()
+{
+ fprintf( stderr, " Testing list_dl_add_after ... " );
+
+ list_dl *list = NULL;
+ node_dl *node1 = NULL;
+ node_dl *node2 = NULL;
+ node_dl *node3 = NULL;
+
+ list_dl_new( &list );
+
+ node1 = mem_get( sizeof( node_dl ) );
+ node2 = mem_get( sizeof( node_dl ) );
+ node3 = mem_get( sizeof( node_dl ) );
+
+ node1->val = "TEST1";
+ node2->val = "TEST2";
+ node3->val = "TEST3";
+
+ list_dl_add_beg( &list, &node1 );
+
+ assert( strcmp( list->first->val, "TEST1" ) == 0 );
+
+ list_dl_add_after( &list, &node1, &node2 );
+
+ assert( strcmp( list->last->val, "TEST2" ) == 0 );
+
+ list_dl_add_after( &list, &node1, &node3 );
+
+ assert( strcmp( list->last->val, "TEST2" ) == 0 );
+
+ list_dl_add_after( &list, &node2, &node3 );
+
+ assert( strcmp( list->last->val, "TEST3" ) == 0 );
+
+ fprintf( stderr, "OK\n" );
+}
+
+
+void test_list_dl_remove()
+{
+ fprintf( stderr, " Testing list_dl_remove ... " );
+
+ list_dl *list = NULL;
+ node_dl *node1 = NULL;
+ node_dl *node2 = NULL;
+ node_dl *node3 = NULL;
+
+ list_dl_new( &list );
+
+ node1 = mem_get( sizeof( node_dl ) );
+ node2 = mem_get( sizeof( node_dl ) );
+ node3 = mem_get( sizeof( node_dl ) );
+
+ node1->val = "TEST1";
+ node2->val = "TEST2";
+ node3->val = "TEST3";
+
+ list_dl_add_beg( &list, &node1 );
+
+ assert( strcmp( list->first->val, "TEST1" ) == 0 );
+
+ list_dl_add_after( &list, &node1, &node2 );
+
+ assert( strcmp( list->last->val, "TEST2" ) == 0 );
+
+ list_dl_add_after( &list, &node1, &node3 );
+
+ assert( strcmp( list->last->val, "TEST2" ) == 0 );
+
+ list_dl_add_after( &list, &node2, &node3 );
+
+ assert( strcmp( list->last->val, "TEST3" ) == 0 );
+
+ list_dl_remove( &list, &node3 );
+
+ assert( strcmp( list->last->val, "TEST2" ) == 0 );
+
+ list_dl_remove( &list, &node2 );
+
+ assert( strcmp( list->first->val, "TEST1" ) == 0 );
+
+ list_dl_remove( &list, &node1 );
+
+ fprintf( stderr, "OK\n" );
+}
+
+
+void test_list_dl_print()
+{
+ fprintf( stderr, " Testing list_dl_print ... " );
+
+ list_dl *list = NULL;
+ node_dl *node1 = NULL;
+ node_dl *node2 = NULL;
+ node_dl *node3 = NULL;
+
+ list_dl_new( &list );
+
+ node1 = mem_get( sizeof( node_dl ) );
+ node2 = mem_get( sizeof( node_dl ) );
+ node3 = mem_get( sizeof( node_dl ) );
+
+ node1->val = "TEST1";
+ node2->val = "TEST2";
+ node3->val = "TEST3";
+
+ list_dl_add_beg( &list, &node1 );
+ list_dl_add_beg( &list, &node2 );
+ list_dl_add_beg( &list, &node3 );
+
+// list_dl_print( list );
+
+ fprintf( stderr, "OK\n" );
+}
+
+
+void test_list_dl_destroy()
+{
+ fprintf( stderr, " Testing list_dl_destroy ... " );
+
+ list_dl *list = NULL;
+ node_dl *node1 = NULL;
+ node_dl *node2 = NULL;
+ node_dl *node3 = NULL;
+
+ list_dl_new( &list );
+
+ node1 = mem_get( sizeof( node_dl ) );
+ node2 = mem_get( sizeof( node_dl ) );
+ node3 = mem_get( sizeof( node_dl ) );
+
+ node1->val = "TEST1";
+ node2->val = "TEST2";
+ node3->val = "TEST3";
+
+ list_dl_add_beg( &list, &node1 );
+ list_dl_add_beg( &list, &node2 );
+ list_dl_add_beg( &list, &node3 );
+
+ list_dl_destroy( &list );
+
+ assert( list == NULL );
+
+// list_dl_print( list );
+
+ fprintf( stderr, "OK\n" );
+}
#include "common.h"
+#include "mem.h"
#include "seq.h"
static void test_seq_new();
+static void test_seq_uppercase();
static void test_seq_destroy();
fprintf( stderr, "Running all tests for seq.c\n" );
test_seq_new();
+ test_seq_uppercase();
test_seq_destroy();
fprintf( stderr, "Done\n\n" );
}
+void test_seq_uppercase()
+{
+ fprintf( stderr, " Testing seq_uppercase ... " );
+
+ char seq[] = "atcg";
+
+ seq_uppercase( seq );
+
+ assert( strcmp( seq, "ATCG" ) == 0 );
+
+ fprintf( stderr, "OK\n" );
+}
+
+
void test_seq_destroy()
{
fprintf( stderr, " Testing seq_destroy ... " );
use constant {
SEQ_NAME => 0,
SEQ => 1,
- SCORE => 2,
};
@options = qw(
data_in|i=s
num|n=s
+ format|f=s
quality|q=s
);
}
{
Maasha::Common::error( qq(Argument to --$opt must be AandB, AorB, BorA, AnotB, or BnotA - not "$options{ $opt }") );
}
+ elsif ( $opt eq "format" and $script eq "read_solexa" and $options{ $opt } !~ /octal|decimal/ )
+ {
+ Maasha::Common::error( qq(Argument to --$opt must be octal or decimal - not "$options{ $opt }") );
+ }
}
Maasha::Common::error( qq(no --database specified) ) if $script eq "create_blast_db" and not $options{ "database" };
my ( $record, $file, $data_in, $entry, $num, @seqs, @scores, $i );
+ $options->{ "format" } ||= "octal";
$options->{ "quality" } ||= 20;
while ( $record = get_record( $in ) ) {
{
$data_in = Maasha::Common::read_open( $file );
- while ( $entry = Maasha::Solexa::solexa_get_entry( $data_in ) )
+ if ( $options->{ "format" } eq "octal" )
{
- @seqs = split //, $entry->[ SEQ ];
- @scores = split /:/, $entry->[ SCORE ];
+ while ( $entry = Maasha::Solexa::solexa_get_entry_octal( $data_in ) )
+ {
+ $record = Maasha::Solexa::solexa2biopiece( $entry, $options->{ "quality" } );
- for ( $i = 0; $i < @scores; $i++ ) {
- $seqs[ $i ] = lc $seqs[ $i ] if $scores[ $i ] < $options->{ "quality" };
- }
+ put_record( $record, $out );
- $record->{ "SEQ_NAME" } = $entry->[ SEQ_NAME ];
- $record->{ "SEQ" } = join "", @seqs;
- $record->{ "SEQ_LEN" } = scalar @seqs;
- $record->{ "SCORE_MEAN" } = sprintf ( "%.2f", Maasha::Calc::mean( \@scores ) );
+ goto NUM if $options->{ "num" } and $num == $options->{ "num" };
- put_record( $record, $out );
+ $num++;
+ }
+ }
+ else
+ {
+ while ( $entry = Maasha::Solexa::solexa_get_entry_decimal( $data_in ) )
+ {
+ $record = Maasha::Solexa::solexa2biopiece( $entry, $options->{ "quality" } );
- goto NUM if $options->{ "num" } and $num == $options->{ "num" };
+ put_record( $record, $out );
- $num++;
+ goto NUM if $options->{ "num" } and $num == $options->{ "num" };
+
+ $num++;
+ }
}
close $data_in;
if ( $options->{ "score" } ) {
$clones = $entry->{ 'SCORE' };
- } if ( $q_id =~ /_(\d+)$/ ) {
+ } elsif ( $q_id =~ /_(\d+)$/ ) {
$clones = $1;
} else {
$clones = 1;
# Checks the diagonal starting at a given coordinate
# of a search space constituted by an adaptor and a tag sequence.
# Residues in the diagonal are compared between the sequences allowing
- # for a given number of mismatches. We terminate when search spaca is
+ # for a given number of mismatches. We terminate when search space is
# exhausted or if max matches or mismatches is reached.
- my ( $adaptor,
- $tag,
- $adaptor_len,
- $tag_len,
- $adaptor_beg,
- $tag_beg,
- $max_match,
- $max_mismatch,
+ my ( $adaptor, # list of chars
+ $tag, # list of chars
+ $adaptor_len, # length of adaptor sequence
+ $tag_len, # length of tag sequence
+ $adaptor_beg, # adaptor begin coordinate
+ $tag_beg, # tag begin coordinate
+ $max_match, # number of matches indicating success
+ $max_mismatch, # number of mismatches
) = @_;
# Returns boolean.
@ISA = qw( Exporter );
+use constant {
+ SEQ_NAME => 0,
+ SEQ => 1,
+ SCORE => 2,
+};
# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> SUBROUTINES <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-sub solexa_get_entry
+sub solexa_get_entry_octal
{
# Martin A. Hansen, August 2008
@scores = split //, $score;
- map { $_ = score_oct2dec( $_ ) } @scores;
+ map { $_ = int( score_oct2dec( $_ ) ) } @scores;
$seq_header =~ s/^@//;
- $score = join( ":", @scores );
+ $score = join( ";", @scores );
return wantarray ? ( $seq_header, $seq, $score ) : [ $seq_header, $seq, $score ];
}
}
+sub solexa_get_entry_decimal
+{
+ # Martin A. Hansen, August 2008
+
+ # Get the next Solexa entry form a file and returns
+ # a triple of [ seq_name, seq, score ].
+ # We asume a Solexa entry consists of four lines:
+
+ # @USI-EAS18_131_4_1_352_619
+ # ATGGATGGGTTGGAGATGCCCTCTGTAGGCACCAT
+ # +USI-EAS18_131_4_1_352_619
+ # 40 40 40 40 40 40 40 40 40 40 40 25 25 40 40 34 40 40 40 40 32 39 40 36 34 19 40 19 30 16 21 11 21 18 11
+
+ my ( $fh, # filehandle to Solexa file
+ ) = @_;
+
+ # Returns a list.
+
+ my ( $seq_header, $seq, $score_head, $score, @scores );
+
+ $seq_header = <$fh>;
+ $seq = <$fh>;
+ $score_header = <$fh>;
+ $score = <$fh>;
+
+ return if not defined $score;
+
+ chomp $seq_header;
+ chomp $seq;
+ chomp $score_header;
+ chomp $score;
+
+ @scores = split / /, $score;
+
+ $seq_header =~ s/^@//;
+
+ $score = join( ";", @scores );
+
+ return wantarray ? ( $seq_header, $seq, $score ) : [ $seq_header, $seq, $score ];
+}
+
+
+sub solexa2biopiece
+{
+ # Martin A. Hansen, September 2008.
+
+ # Converts a Solexa entry to a Biopiece record.
+
+ my ( $entry, # Solexa entry
+ $qualilty, # Quality cutoff
+ ) = @_;
+
+ # Returns a hashref.
+
+ my ( @seqs, @scores, $i, %record );
+
+ @seqs = split //, $entry->[ SEQ ];
+ @scores = split /;/, $entry->[ SCORE ];
+
+ for ( $i = 0; $i < @scores; $i++ ) {
+ $seqs[ $i ] = lc $seqs[ $i ] if $scores[ $i ] < $quality;
+ }
+
+ $record{ "SEQ_NAME" } = $entry->[ SEQ_NAME ];
+ $record{ "SEQ" } = $entry->[ SEQ ];
+ $record{ "SCORES" } = $entry->[ SCORE ];
+ $record{ "SEQ_LEN" } = scalar @seqs;
+ $record{ "SCORE_MEAN" } = sprintf ( "%.2f", Maasha::Calc::mean( \@scores ) );
+
+ return wantarray ? %record : \%record;
+}
+
+
# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<