- Both Sections: Monday, May 6
Via email or printout by deadline.
Do not attempt to hypothesize on the cause of any "bugs" you find; just describe (in as much detail as possible) any problems your tests uncover.
Feel free to expand your test suite as necessary after April 26. The purpose of the delayed deployment is to encourage you to think about your testing strategy in the abstract first. Since black box testing is performed without consulting the implementation, not having it available right away should not be a problem.
In order to use the files in your development process, copy them to your own workarea first. They can be found on Elvis in the ~clamen/Public/SE/mailalias/ directory. Versions of the resources for Windows platforms (the library and a Visual Studio project) will be developed and placed in the student public area (specific location TBA) on Tuesday, April 22.
- testaliases.cpp
- Sample program (C++ program file)
- mailaliases.h
- Interface specification (C++ header file)
- aliases.txt
- Sample mailalias directory file
- libmailaliases.a
- Unix library (Elvis only; not portable)
- Makefile
- Unix makefile for linking test and library. Assumes libmailaliases.a is in your current directory
class MailAliases {
public:
static MailAliases* MakeMailAliases();
virtual ~MailAliases() { }
virtual bool DefineAlias(const char* alias, const char* targets) = 0;
virtual bool UndefineAlias(const char* alias) = 0;
virtual bool AliasDefined(const char* alias) = 0;
virtual bool LoadAliasFile(const char* filename) = 0;
// Caller assumes ownership of return argument (for memory management)
virtual char* ExpandAlias(const char* alias) = 0;
};
MailAliases instances are constructed via the factory method: MakeMailAliases(). The caller takes ownership of the directory object, and is expected to delete it when they are done with it.The DefineAlias method takes two arguments, both character pointers (C strings). The first is the alias name, the second is a delimited list of addresses (format described below). The elements in this list can be: (1) complete email addresses, local email addresses, or the names of other aliases. Alias names consist of any string that can be formed out of the alphanumeric characters, plus: '-' (hyphen), '_' (underscore), and '.' (period). If is not legal to redefine an alias. DefineAlias returns boolean value true if successful, the boolean value false otherwise.
The UndefineAlias method takes one argument, a character pointer (C string) and returns a boolean value. If the argument names an alias defined in the directory, that alias definition is removed, and the boolean value true is returned. Otherwise, the boolean value false is returned.
The AliasDefined method takes one argument, a character pointer (C string) and returns a boolean value, based on whether or not the argument names an alias defined in the directory.
The LoadAliasFile allows one to define a set of pre-written mail aliases by reading in a text file. The file format can be described as follows: each line defines a mail alias. The alias appears on the left, followed by one or more tab characters. After the tab(s) is a delimited list of addresses, identifical in format to the second argument of DefineAlias. If any definition errors occur during the processing of the file (e.g., syntax error, circular definition), a boolean false value is returned and none of the alias definitions are added to the directory. (See Appendix B for an example of the text file format.)
To expand an alias, call the method ExpandAlias(). The method takes one argument, a character pointer (C string), the (potential) alias to expand, and returns a character pointer (C string). The caller assumes ownership of the memory referenced by that return argument, and is expected to delete the object (freeing the memory) when they are done with it.
The rules for expansion are defined as follows: the argument is looked up in the alias directory. If it names an alias, that alias is expanded (according to its definition). Then each term in that definition that might name another alias is expanded, recursively until all expansions are either complete email addresses or terms that do not name an alias (these are assumed to be local addresses). The addresses are emitted separated by commas and spaces. (See example in Appendix A below.)
The Delimited List of Addresses consists of a sequence of atoms. Atoms are character sequences composed of all printable 7-bit ASCII characters (codes 32-127) except for the following special characters:( ) < > , ; : " [ ] spaceThe delimiters separating items in the list may be any combination of commas, spaces, or semi-colons.
#include <iostream.h>
#include "mailaliases.h"
main() {
MailAliases* dict = MailAliases::MakeMailAliases();
bool b = dict->LoadAliasFile("aliases.txt");
if (! b) {
cout << "ERROR: alias file not loaded" << endl;
}
char* out = 0;
const char* in = "family";
out = dict->ExpandAlias(in);
int lin = strlen(in);
cout << "IN:\t" << in << " (" << lin << ")"
<< endl;
int lout = strlen(out);
cout << "OUT:\t" << out << " (" << lout << ")"
<< endl << endl;
delete out;
delete dict;
}
When linked against a library containing a correct implementation,
and run using the sample alias file below,
this program would emit the following output:
IN: family OUT: clamen@cs.rowan.edu, sclamen@company.ca, lclamen@notaol.com, eclamen@notaol.com, mclamen@someother.edu
help support me clamen@cs.rowan.edu brother mclamen@someother.edu sister eclamen@notaol.com mother lclamen@notaol.com father sclamen@company.ca family me; father mother, sister brother