]> git.donarmstrong.com Git - biopieces.git/blob - code_c/Maasha/src/lib/fasta.c
unit test of mem.c done
[biopieces.git] / code_c / Maasha / src / lib / fasta.c
1 #include "common.h"
2 #include "mem.h"
3 #include "fasta.h"
4 #include "list.h"
5
6
7 uint fasta_count( FILE *fp )
8 {
9     /* Martin A. Hansen, May 2008 */
10
11     /* Counts all entries in a FASTA file given a file pointer. */
12
13     char buffer[ FASTA_BUFFER ];
14     uint count;
15
16     count = 0;
17
18     while ( ( fgets( buffer, sizeof( buffer ), fp ) ) != NULL )
19     {
20         if ( buffer[ 0 ] == '>' ) {
21             count++;
22         }
23     }
24
25     return count;
26 }
27
28
29 bool fasta_get_entry( FILE *fp, struct seq_entry *entry )
30 {
31     /* Martin A. Hansen, May 2008 */
32
33     /* Get next sequence entry from a FASTA file given a file pointer. */
34
35     int     i;
36     size_t  j;
37     size_t  offset;
38     size_t  seq_len;
39     char    buffer[ FASTA_BUFFER ];
40     int     buffer_len;
41     char   *seq_name = NULL;
42     char   *seq      = NULL;
43
44     entry = mem_get( sizeof( entry ) );
45
46     offset = ftell( fp );
47
48     /* ---- Skip ahead until header line and include header ---- */
49
50     while ( fgets( buffer, sizeof( buffer ), fp ) != NULL )
51     {
52         buffer_len = strlen( buffer );
53
54         offset += buffer_len;
55
56         if ( ( buffer[ 0 ] == '>' ) )
57         {
58             seq_name = mem_get_zero( buffer_len - 1 );
59
60             for ( i = 1; i < buffer_len - 1; i++ ) {
61                 seq_name[ i - 1 ] = buffer[ i ];
62             }
63
64             seq_name[ i ] = '\0';
65
66             break;
67         }
68     }
69
70     /* ---- Determine length of sequence ---- */
71
72     seq_len = 0;
73
74     while ( ( fgets( buffer, sizeof( buffer ), fp ) != NULL ) )
75     {
76         for ( i = 0; buffer[ i ]; i++ )
77         {
78             if ( buffer[ i ] > 32 && buffer[ i ] < 127 ) {
79                 seq_len++;
80             }
81         }
82
83         if ( ( buffer[ 0 ] == '>' ) )
84         {
85             seq_len -= strlen( buffer ) - 1;
86
87             break;
88         }
89     }
90
91     /* ---- Allocate memory for sequence ---- */
92
93     seq = mem_get_zero( seq_len + 1 );
94
95     /* ---- Rewind file pointer and read sequence ---- */
96
97     if ( fseek( fp, offset, SEEK_SET ) < 0 ) {
98         die( "fseek SEEK_SET failed." );
99     }
100
101     j = 0;
102
103     while ( ( fgets( buffer, sizeof( buffer ), fp ) != NULL ) )
104     {
105         for ( i = 0; buffer[ i ]; i++ )
106         {
107             if ( buffer[ i ] > 32 && buffer[ i ] < 127 )
108             {
109                 seq[ j ] = buffer[ i ];
110
111                 if ( j == seq_len - 1 )
112                 {
113                     seq[ j + 1 ] = '\0';
114
115                     entry->seq_name = seq_name;
116                     entry->seq      = seq;
117                     entry->seq_len  = seq_len;
118
119                     return TRUE;
120                 }
121
122                 j++;
123             }
124         }
125     }
126
127     return FALSE;
128 }
129
130
131 void fasta_put_entry( struct seq_entry *entry )
132 {
133     /* Martin A. Hansen, May 2008 */
134
135     /* Output a sequence entry in FASTA format. */
136     printf( ">%s\n%s\n", entry->seq_name, entry->seq );
137 }
138
139
140 void fasta_get_entries( FILE *fp, struct list **entries )
141 {
142     /* Martin A. Hansen, May 2008 */
143
144     /* Given a file pointer to a FASTA file retreives all */
145     /* sequence entries and insert those in a list. */
146
147     struct seq_entry *entry;
148
149     while ( 1 )
150     {
151         entry = mem_get( sizeof( entry ) );
152
153         if ( ! fasta_get_entry( fp, entry ) ) {
154             break;
155         }                                                                                                                       
156
157         list_add( entries, entry );                                                                                             
158     }                                                                                                                           
159
160     list_reverse( entries );                                                                                                    
161 }                                                                                                                               
162                                                                                                                                 
163                                                                                                                                 
164 void fasta_put_entries( struct list *entries )                                                                                  
165 {                                                                                                                               
166     /* Martin A. Hansen, May 2008 */                                                                                            
167
168     /* Output a list of sequence entries as FASTA records. */                                                                   
169
170     struct list *elem;                                                                                                          
171
172     for ( elem = entries; elem != NULL; elem = elem->next ) {                                                                   
173         fasta_put_entry( elem->val );                                                                                           
174     }                                                                                                                           
175 }
176
177
178 void fasta_free_entry( struct seq_entry *entry )
179 {
180     /* Martin A. Hansen, June 2008 */
181
182     /* Deallocates memory from a seq_entry. */
183
184     mem_free( ( void * ) &entry->seq_name );
185     mem_free( ( void * ) &entry->seq );
186     mem_free( ( void * ) &entry );
187 }
188
189