Introduction
For this assignment, you will write a program to analyse and manage genetic sequences. These sequences are the DNA extracted from the Mitochondria of a genus of butterflies called Astraptes. Your program will use linked lists to store the DNA sequences.
The Data
To begin your program will read in the data from a file. This file is organized as follows. Each sample (drawn from one particular butterfly) is described by two lines in the file. The first line is a descriptor of the sample, while the second line contains the actual DNA. The format of the first line of each sample:
1. the character "<",
2. a sequnce code, consisting of upper-case letters, digits, and dashes ("-"),
3. the character "|",
4. a sample ID, consisting of upper-case letters, digits, and dashes ("-"),
5. the character "|",
6. the species of the samples, consisting of a name (the genus) of alphabetic characters (with the first letter capitalized), then a space and another name (the species) of alphabetic characters (all capitalized), and
7. the newline character.
The second line of each sample conists of the DNA sequence which is made up of the characters G, A, T, C, and N. These characters represent the DNA bases, Guanine, Adenine, Thymine, Cytosine respectively, plus a null symbol (N) which indicates an absence of data.
Operation
Your program will prompt the user for a command with the command "> ". It will accept the following commands:
1. READ FROM filename SEQUENCE sequence_code INTO varname ;
2. SUMMARIZE varname ;
3. PRINT varname ;
4. REVERSE varname ;
5. SELECT varname 123-456 INTO varname2 ;
6. COMPARE varname TO varname2 ;
7. DELETE varname ;
8. QUIT ;
In each of these commands, uppercase letters denote reserved words which must be typed exactly as shown, while lowercase letters denote user selected variable names. These variable names can consist of the characters a-z and the number 0-9. Each variable name has a maximum length of 31 characters, and a maximum of 8 variables can be used at any time. If the user tries to use more than 8 variable names, your program should print "ERROR: to many variables!" to the standard error stream. If the user's input does not match the pattern of any of the commands above, your program will print "ERROR: syntax error!".
The functionality of each of these commands is as follows:
READ FROM filename SEQUENCE sequence_code INTO varname ; This command opens the file indicated by "filename" and searches for the sequence code given by "sequence_code". If the given sequence code is not found in the filename, the program will print "ERROR: missing code!". Otherwise, it will associate the sequence with the given sequence code with a vriable named "varname". Note: "varname" is not an actual variable inside your "C" program (since program variables must be defined at compile time), but rather a name the program's user can use to refer to the sequence. You might want to use an array to associate the varname strings with the sequences. Internally, you must represent the sequence as a linked list.
SUMMARIZE varname ; This command will cause your program to count the number of A's, C's, G's, and T's in the program and report the number of each. The output should look like:
Sequence "varname" contains:
17 A's
19 C's
56 G's
4 T's
PRINT varname ; This command causes your program to print out the sequence. The sequence should be printed out one letter at a time, in order, with no spaces, punctuation or new-lines. The N's should be printed as well as the other characters.
REVERSE varname ; This command will reverse the given sequence. All future operations involving the sequence given by "varname" will be performed on the reversed sequence.
SELECT varname 123-456 INTO varname2 ; This command will create a new sequence identified by "varname2". The new sequence will consist of the 123rd letter in the sequence "varname" up to BUT NOT INCLUDING the 456th letter. The two sequences should be independent and can be manipulated independently.
COMPARE varname TO varname2 ; This command compares two sequences, "varname" and "varname2". If the sequences are of unequal length, the program will pring "Error: length missmatch!", otherwise it will print a comparison of the strings. This involves printing both sequences and printing a string of characters consisting of blank spaces and Xs. The blank spaces indicate where the two sequences are the same and the Xs indicate where they are different. The printing should be organized so that the maximum line with is 60 characters and everything lines up. An example will clarify this. Suppose "varname" is the sequence: ACGTAACCGAAGCTCAAGCTTTTCCAAGCAAGCCCAGACCAAAAGTTTTGGAGAGAGCCAAGCTGC and "varname2" is the nearly identical sequence: ACGTAACCGAAGCTCAGGCTTTTCGAAGCAAGCCCAGACCACACATTTTGGAGAGAGCCAAGCTGC then the program should print:
ACGTAACCGAAGCTCAAGCTTTTCCAAGCAAGCCCAGACCAAAAGTTTTGGAGAGAGCCA
ACGTAACCGAAGCTCAGGCTTTTCGAAGCAAGCCCAGACCACACATTTTGGAGAGAGCCA
X X X XX
AGCTGC
AGCTGC
Note that the program prints out the sequences and the differences in blocks of 60 characters, with a blank line between blocks.
DELETE varname ; This command deletes the sequence (and linked list) associated with "varname". This means that an additional variable can now be allocated before reaching the maximum of 8. The memory associated with the sequence should obviously be freed.
QUIT ; This command should free the memory associated with all sequences still in the computer's memory and exit the program.
Data
An example datafile is found here. Much more data can be found via the "View Public Projects" link on the barcodinglife.org home page.
Other criteria
In addition to meeting the functional requirements outline above, your program must:
* be composed of 4 files linklist.c (which contains the code to implement linked list operations), linklist.h (which contains the prototypes for linklist.c), main.c (which contains the code to process the commands and calls the lined list operations).
* compile with no warnings or errors using the "--std=c89 --Wall --pedantic" flags,
* be broken up into small functions that perform specific modular tasks,
* use good indentation, blank lines, whitespace,
* contain one comment for each function, explaining what the function does, and what arguments it takes and what value it returns,
* contain comments for any part of the code whose functionality cannot be easily understood by a competent C programmer,
* contain no comments describing things that are obvious,
* use meaningful variable names,
* use consistent formatting throughout,
* include a makefile that will compile your program when the command "make" is issued (with the "--std=c89 --Wall --pedantic" flags), your makefile should first produce the object file linklist.o and then combine it with the main.c to produce an output file called "a4".
* your code should use memory parsimoniously and only write to memory locations that are allocated to you.
* your code should check the return values of malloc statements and free all memory that was allocated when it ends.