Script started on Fri Dec  7 22:51:36 2001
ws13% cat README

README

Russell J Lowke
Homework five

______

files are:

makefile
fl.h
fl.c
process.c
ws13.h
wordstore13.c
ws13% cat makefile

#
# comments start with a # sign
#
# each item in the make file consists of
# three things:  a product, its ingredients and how to make it
#

CC = gcc -g -Wall

fl: fl.o wordstore13.o process.o
        $(CC) fl.o wordstore13.o process.o -o fl

fl.o: fl.c fl.h
        $(CC) -c fl.c
 
wordstore13.o: wordstore13.c ws13.h
        $(CC) -c wordstore13.c

process.o: process.c ws13.h fl.h
        $(CC) -c process.c

test:
        ./fl sample.fmt data1 data2 data3

error:
        ./fl sample.fmt data1 data8
    
run:
        ./fl sample.fmt < sample.dat
ws13% cat fl.h

#include        "ws13.h"
//
//      some constants
//

#define MAXFLD                                  40
#define MAXVAL                                  120

//
//      function declarlations
//

int  get_record(symtab_t, FILE *);
void mailmerge (symtab_t, FILE *);

void fatal(char *s1, char *s2);
void process(FILE *fmt, FILE *data);
char readSeg(int itemDel[], FILE *fp, char targetField[BUFLEN]);
void initArray(char mArray[], int arraySize);

ws13% cat fl.c

#include    <stdio.h>
#include    <string.h>
#include    <ctype.h>
#include    "fl.h"

#define MAXDELIM                10


//
//    formletter program version 1.0
//
//    usage: fl format < datafile
//
//    data comes from stdin, output goes to stdout
//

static char *myname;                            // used by fatal()

int main(int ac, char *av[])
{
    FILE *fpfmt, *fpdata;
    
    int i;

    myname = *av;

    // check that there is at least one arg: the format file
    if ( ac == 1 )
        fatal("usage: fl format [datafile..]","");

    // open format file
    if ((fpfmt = fopen( av[1] , "r")) == NULL )
        fatal("Cannot open format file:", *av);

    if (ac == 2)
        process(fpfmt, stdin);
    else {

        for (i = 2; i < ac; i++) {
            if ((fpdata = fopen( av[i] , "r")) == NULL )
                fatal("Cannot open data file:", av[i]);
            else
                process(fpfmt, fpdata);
        }
    }
    return 0;
}


void fatal(char *s1, char *s2)
//
//    fatal error handler
//    purpose: print error message to stderr then exit
//    input:   two strings that are printed 
//    never returns
//
{
    fprintf(stderr, "%s: %s%s\n",  myname, s1, s2 );
    exit(1);
}

int get_record(symtab_t tp, FILE *fp)
{
    int  itemDelim[MAXDELIM] = {':','\n','\t', '=', '\0'};

    char line[BUFLEN],
         fieldName [BUFLEN],
         fieldValue[BUFLEN],
         mChar = '\0';
    
    initArray(fieldName,  BUFLEN);

    do {

        // read segment
        mChar = readSeg(itemDelim, fp, line);
        // trimWhiteSpace(line);

        if (mChar == '=') {                              // read field name
            if (! *line)
                fatal("Field with blank fieldname.", "");
            else
                strncpy(fieldName, line, MAXFLD);
            
            // remove '=' from item delim list
            // allows for field entry containing equals.
            itemDelim[3] = '\0';
        }
        else if (*fieldName) {                           // read field value
            
            // save values
            strncpy(fieldValue, line, MAXVAL);
            insert(tp,  fieldName, fieldValue);
            
            // empty first val
            initArray(fieldName,  BUFLEN);
            
            // include '=' in item delim list
            itemDelim[3] = '=';
        }
        else if (*line)                                 // bad value
            fatal("Field entry without equals: ", line);
        else if (! *line && mChar == '\n')              // empty line
            mChar = '\0' ;
                        
    } while (mChar != EOF && mChar != '\n');
    
    return (mChar == EOF ? NO : YES);
}


void mailmerge(symtab_t tp, FILE *fmt)
{
    //
    // copies characters from the format stream at *fmt to stdout
    // inserting values for fields when it sees an insertion point ('%')
    //

    int  itemDel[MAXDELIM] = {'%','\n','\0'};
    char line[BUFLEN],
         mChar = '\0';
    int  mode = 0;                     // mode 1 when getting var

    static int recordCount = 0;        // static counter of records processed

    recordCount++;

    do {

        mChar    = readSeg(itemDel, fmt, line);

        if (mChar == '%') {            // ... start reading string
            if (mode) {
                if (! *line)           // two % in a row              
                    printf("%%");
                else if (strcmp(line, "=RECORDNUMBER") == 0)
                    printf("%d", recordCount);
                else
                    if (lookup(tp, line) != NULL)   // lookup and display var

                        printf("%s", lookup(tp, line));
                mode = 0;              // mode off
            }
            else {
                printf("%s", line);    // print text preceeding '%'
                mode = 1;              // mode on
            }
        }
        else {
            if (mode)
                fatal("Unterminated fieldname:", line);
            printf("%s", line);
        }

        if (mChar == '\n')
            printf("\n");
                
    } while (mChar != EOF);
    
    // rewind format file
    fseek(fmt, 0L, 0);
}


char readSeg(int itemDel[], FILE *fp, char line[BUFLEN])
{
    //
    // read chars into targetField until reaching
    // an item delimiter (itemDel[]), return delimiter reached
    //
    
    char mChar;               // my char from stream
    int  i, 
         endStr    = NO,
         charCount = 0;
    
    // empty target String
    initArray(line, BUFLEN);

    do {

        // get a char
        mChar = fgetc(fp);

        // check for delimiter
        for (i = 0; itemDel[i]; i++)
            if (mChar == itemDel[i] || mChar == EOF )
                endStr = YES;

        // append char to target string
        if ( ! endStr)
            line[charCount] = mChar;
        
        charCount++;

    } while (! endStr);

    // conclude target string
    line[charCount] = '\0';

    return mChar;
}


// Lib

void initArray(char mArray[], int arraySize)
{
    //
    // ensure all values in array are set to '\0'

    int i;
    
    for (i = 0;  i <= arraySize-1 ; i++) {
        mArray[i] = '\0';
    }
}


void trimWhiteSpace(char source[])
{
    //
    // remove all leading and trailing whitespace (including '\n')
    
    int  i;
    char target[BUFLEN];
    
    // strip trailing whitespace
    for (i = strlen(source)-1; isspace((int)source[i]) && i >= 0 ; i-- ) {
        source[i] = '\0';
    }

    // count leading whitespace
    for (i = 0; isspace((int)source[i]) ; i++) {
    }

    // copy into target
    strcpy(target, &source[i]);

    // copy back to source
    strcpy(source, target);
}
ws13% cat process.c

#include        <stdio.h>
#include        "fl.h"
#include        "ws13.h"

void fatal(char *s1, char *s2);

//
//      process(fmt, data)
//
//      Purpose: read from datafile, format and output selected records
//      Input:   fmt            - input stream from format file
//                   data               - stream from datafile
//      Output:  copied fmt to stdout with insertions
//      Errors:  not reported, functions call fatal() and die
//


void process(FILE *fmt, FILE *data)
{
        symtab_t wordlist;

        if ((wordlist = new_table()) == NULL )
                fatal("Cannot create storage object","");

        while (get_record(wordlist, data) != NO )       // while more data
        {
                mailmerge(wordlist, fmt);                               // merge with format
                clear_table(wordlist);                          // discard data
        }
}

ws13% cat ws13.h

#ifndef WS13_INCL
#define WS13_INCL
#define BUFLEN  512
#define YES     1
#define NO      0

struct link {
                char        *word;              // the string
                char        *val;               // the `value'
                struct link *next;              // the next one
        };

struct symtab {
                struct link head;
                struct link *current_link;
        };

typedef struct symtab *symtab_t;
int x;

typedef int interger;
typedef char khaah;

symtab_t  new_table();

int          in_table(symtab_t,char []);
int          insert(symtab_t, char [], char []);
char     *lookup(symtab_t,char []);
int          update(symtab_t,char [], char []);
char     *firstword(symtab_t);
char     *nextword(symtab_t);
int      table_len(symtab_t);
void     delete(symtab_t,char []);
void     clear_table(symtab_t);

#endif  // WS13_INCL
ws13% cat wordstore13.c

#include        <stdio.h>
#include        <stdlib.h>
#include    <string.h>
#include        "ws13.h"

//
//      wordstore version 1.3
//      last modified: 22 nov 2001 (added symtab_t)
//
//      storage system for storing name:address pairs
//      the function in this file are stolen directly from the wlfiler
//      system
//
//      functions are:
//                      new_table()          - create a new symtab
//                      in_table(tp,str)     - sees if word is in table at tp
//                      insert(tp,str,val)   - insert value into table
//                      lookup(tp,str)       - retrieve value
//                      update(tp,str,val)   - update value in table
//                      firstword(tp)        - move to top of table
//                      nextword(tp)         - return word at current row
//                      table_len(tp)        - returns length of table
//                      delete(tp,str)       - removes an item from the list
//                      clear_table(tp)
//

//
//      data structure for this unit:  a linked list of structs
//

//
// declarations of internal functions
//

static struct link *find_node(symtab_t,char []);
static char        *new_string(char[]);

//
//      new_table(): creates an initialized a symtab
//

symtab_t new_table()
{
        symtab_t rv;

        rv = malloc(sizeof(struct symtab));
        if ( rv != NULL ){
                rv->head.next = NULL;
                rv->current_link = NULL;
        }
        return rv;
}

// ----------------------------------------------------------------
//      int in_table(symtab_t,char str[])
//
int in_table( symtab_t tp, char str[] )
{
        return ( find_node(tp, str) ? YES : NO );
}

// ----------------------------------------------------------------
//      int insert(tp, str, val)
//              purpose: add an entry to the table
//              returns: NO if no more memory, YES if OK
//               method: add new node to head of list.  It's easy
//

int
insert( symtab_t tp,  char str[], char val[] )
{
        struct link     *newlink;

        newlink = malloc(sizeof(struct link));  /* get mem for link     */
        if ( newlink == NULL )                  /* or quit              */
                return NO;

        newlink->word = new_string( str );      /* allocate + copy      */
        if ( newlink->word == NULL )            /* or quit              */
                return NO;

        newlink->val = new_string( val );       /* allocate + copy      */
        if ( newlink->val == NULL )             /* or quit              */
                return NO;

        newlink->next  = tp->head.next;         /* attach list to link  */
        tp->head.next  = newlink;               /* make head pt to link */
        return YES;
}

// ----------------------------------------------------------------
//      char *lookup( symtab_t, str )  returns string at value or NULL
//
char *
lookup( symtab_t tp, char str[] )
{
        struct link *linkp;

        linkp = find_node( tp, str );
        return ( linkp ? linkp->val : NULL );
}

// ----------------------------------------------------------------
//      int update( str, val )
//

int
update( symtab_t tp, char str[], char val[] )
{
        struct link *linkp;

        linkp = find_node( tp, str );
        if ( linkp != NULL )                            /* if there     */
        {
                free( linkp->val );                     /* free old mem */

                linkp->val = new_string(val);           /* make new str */
                if ( linkp->val == NULL )
                        return NO;                      /* or bail out  */
                return YES;                             /* and go       */
        }
        return YES;                                     /* no errors    */
}

// ----------------------------------------------------------------
//      char *firstword()
//

char *
firstword(symtab_t tp)
{
        tp->current_link = tp->head.next ;
        return nextword(tp);
}

// ----------------------------------------------------------------
//      char *nextword()
//

char *
nextword(symtab_t tp)
{
        char *retval = NULL;

        if ( tp->current_link != NULL ){
                retval = tp->current_link->word;
                tp->current_link = tp->current_link->next;
        }
        return retval;
}

// ----------------------------------------------------------------
//      int     table_len()
//
int
table_len(symtab_t tp)
{
        struct link *linkp;                     /* a cursor     */
        int     len = 0;                        /* a counter    */

        for( linkp = tp->head.next ; linkp ; linkp = linkp->next )
                len++;

        return len;
}

// ----------------------------------------------------------------
//      void delete()
//      removes an item from the table and frees the storage
//   this one is broken, folks say.
//
//

void
delete( symtab_t tp, char str[] )
{
        struct link *linkp;
        struct link *one_to_delete;

        for( linkp = tp->head.next ; linkp ; linkp = linkp->next )
                if ( strcmp(linkp->next->word, str) == 0 )
                {
                        one_to_delete = linkp->next;
                        linkp->next = linkp->next->next;
                        free( one_to_delete->word );
                        free( one_to_delete->val );
                        free( one_to_delete );
                        break;
                }
}

//
//  clear_table(tp) - clears out all nodes from the table
//                  - and resets head pointer to NULL
//


void clear_table(symtab_t tp)
{
    //
        // deletes all fieldname and fieldvalue pairs stored in the wordstore
        // table passed as an argument.  calls free() for each string added.
    //
    
    
    struct link *linkp = NULL;
    struct link *nextLinkp = NULL;

    // load linkp from head
    linkp = tp->head.next;
     
    do {
        nextLinkp = linkp->next;

        // kill word at linkp
        free(linkp->word);
                free(linkp->val);
                free(linkp);
        
        // load nextlink into linkp
        linkp     = nextLinkp;

    } while (linkp != NULL);
    
    // reset head
    tp->head.next = NULL;
    
}

// ----------------------------------------------------------------- *
// internal helper functions to reduce repeated code in the
// functions above.  These are all declared static to make them
// private to this file
// The functions are:
//
//   struct link *find_node(symtab_t tp, str)
//   char        *new_string(str)
//

//
//  internal helper function:  struct link *find_node(str)
//  used to find a node with the specified string
//   method: loop until at end of list or until a match
//  returns: node where loop ended (ie at null or a match)
//

static struct link *
find_node(symtab_t tp,char str[])
{
        struct link *lp;

        for(lp=tp->head.next; lp && strcmp(lp->word,str) != 0; lp = lp->next)
                ;
        return lp;
}

//
// allocate space for a string and copy the string into it
// returns ptr to new string or NULL if no memory
//

static char *
new_string(char str[])
{
        char *strp;

        strp = malloc( 1 + strlen(str) );       // allocate
        if ( strp != NULL )                             // if ok
                strcpy( strp, str );                // copy
        return strp;                                    // return ptr
}

ws13% touch *.c

ws13% make

gcc -g -Wall -c fl.c
gcc -g -Wall -c wordstore13.c
gcc -g -Wall -c process.c
gcc -g -Wall fl.o wordstore13.o process.o -o fl
ws13% make run[K[K[K[K[K[K[K./[K[Kmake run

./fl sample.fmt < sample.dat

        Dear Mr. Arlington,

        You and everyone at 12 Apple Lane will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Alan, you may be the
        person in Sometown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 1

        Dear Ms. Berkeley,

        You and everyone at 23 Birch Ave will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Barbara, you may be the
        person in Uptown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 2

        Dear Mrs. Clarendon,

        You and everyone at 34 Clover Drive will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Carol, you may be the
        person in Sometown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 3

        Dear Adm. Dartmouth,

        You and everyone at 45 Daffodil Blvd will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, D., you may be the
        person in Uptown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 4

        Dear Dr. Exeter,

        You and everyone at 56 Elm Street will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Eric, you may be the
        person in Uptown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 5

        Dear The Rev. Fairfield,

        You and everyone at 67 Flax Circle will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Francis, you may be the
        person in Downtown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 6

        Dear Miss Gloucester,

        You and everyone at 78 Gull Walk will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Gail, you may be the
        person in Uptown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 7

        Dear Mr. Hereford,

        You and everyone at 89 Hawk Road will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Henry, you may be the
        person in Downtown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 8

        Dear  Ipswich,

        You and everyone at 100 Indigo Way will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Imogene, you may be the
        person in Uptown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 9

        Dear  ,

        You and everyone at  will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, John, you may be the
        person in  to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 10
ws13% ./ls sample.fmt < sample.dat

./ls: Command not found.
ws13% ./lf[K[Kfl sample.fmt < sample.dat


        Dear Mr. Arlington,

        You and everyone at 12 Apple Lane will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Alan, you may be the
        person in Sometown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 1

        Dear Ms. Berkeley,

        You and everyone at 23 Birch Ave will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Barbara, you may be the
        person in Uptown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 2

        Dear Mrs. Clarendon,

        You and everyone at 34 Clover Drive will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Carol, you may be the
        person in Sometown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 3

        Dear Adm. Dartmouth,

        You and everyone at 45 Daffodil Blvd will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, D., you may be the
        person in Uptown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 4

        Dear Dr. Exeter,

        You and everyone at 56 Elm Street will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Eric, you may be the
        person in Uptown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 5

        Dear The Rev. Fairfield,

        You and everyone at 67 Flax Circle will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Francis, you may be the
        person in Downtown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 6

        Dear Miss Gloucester,

        You and everyone at 78 Gull Walk will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Gail, you may be the
        person in Uptown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 7

        Dear Mr. Hereford,

        You and everyone at 89 Hawk Road will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Henry, you may be the
        person in Downtown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 8

        Dear  Ipswich,

        You and everyone at 100 Indigo Way will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Imogene, you may be the
        person in Uptown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 9

        Dear  ,

        You and everyone at  will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, John, you may be the
        person in  to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 10
ws13% ./fl sample.fmt sample.dat sample.dat sample.dat[K[K[K[K[K[K[K[Kmple.sat


        Dear Mr. Arlington,

        You and everyone at 12 Apple Lane will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Alan, you may be the
        person in Sometown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 1

        Dear Ms. Berkeley,

        You and everyone at 23 Birch Ave will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Barbara, you may be the
        person in Uptown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 2

        Dear Mrs. Clarendon,

        You and everyone at 34 Clover Drive will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Carol, you may be the
        person in Sometown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 3

        Dear Adm. Dartmouth,

        You and everyone at 45 Daffodil Blvd will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, D., you may be the
        person in Uptown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 4

        Dear Dr. Exeter,

        You and everyone at 56 Elm Street will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Eric, you may be the
        person in Uptown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 5

        Dear The Rev. Fairfield,

        You and everyone at 67 Flax Circle will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Francis, you may be the
        person in Downtown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 6

        Dear Miss Gloucester,

        You and everyone at 78 Gull Walk will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Gail, you may be the
        person in Uptown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 7

        Dear Mr. Hereford,

        You and everyone at 89 Hawk Road will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Henry, you may be the
        person in Downtown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 8

        Dear  Ipswich,

        You and everyone at 100 Indigo Way will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Imogene, you may be the
        person in Uptown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 9

        Dear  ,

        You and everyone at  will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, John, you may be the
        person in  to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 10

        Dear Mr. Arlington,

        You and everyone at 12 Apple Lane will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Alan, you may be the
        person in Sometown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 11

        Dear Ms. Berkeley,

        You and everyone at 23 Birch Ave will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Barbara, you may be the
        person in Uptown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 12

        Dear Mrs. Clarendon,

        You and everyone at 34 Clover Drive will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Carol, you may be the
        person in Sometown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 13

        Dear Adm. Dartmouth,

        You and everyone at 45 Daffodil Blvd will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, D., you may be the
        person in Uptown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 14

        Dear Dr. Exeter,

        You and everyone at 56 Elm Street will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Eric, you may be the
        person in Uptown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 15

        Dear The Rev. Fairfield,

        You and everyone at 67 Flax Circle will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Francis, you may be the
        person in Downtown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 16

        Dear Miss Gloucester,

        You and everyone at 78 Gull Walk will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Gail, you may be the
        person in Uptown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 17

        Dear Mr. Hereford,

        You and everyone at 89 Hawk Road will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Henry, you may be the
        person in Downtown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 18

        Dear  Ipswich,

        You and everyone at 100 Indigo Way will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, Imogene, you may be the
        person in Uptown to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 19

        Dear  ,

        You and everyone at  will be delighted to hear
        that you may already have won a major prize in the
        CSCI sweepstakes.  Yes, John, you may be the
        person in  to be the lucky winner of a new jet 
        aircraft, ocean liner, or luxury vacation.  Read on..

                            Your entry code: 20
./fl: Cannot open data file:sample.sat
ws13% ~lib113/hw/fl/test.fl

fl test script version 1.0, 28 Nov 1997

Part I: Normal input and format. 
   a. reading from standard input? OK
   b. reading from 1 file named on command line? OK
   c. reading from several files on command line? OK

Part II: Lots of variations, all legal, some weird.
   testing: fl okfmt.1 < okdata.1 OK
   testing: fl okfmt.1 < okdata.2 OK
   testing: fl okfmt.1 < okdata.3 OK
   testing: fl okfmt.2 < okdata.1 OK
   testing: fl okfmt.2 < okdata.2 OK
   testing: fl okfmt.2 < okdata.3 OK
   testing: fl okfmt.3 < okdata.1 OK
   testing: fl okfmt.3 < okdata.2 OK
   testing: fl okfmt.3 < okdata.3 OK
   testing: fl okfmt.4 < okdata.1 OK
   testing: fl okfmt.4 < okdata.2 OK
   testing: fl okfmt.4 < okdata.3 OK

Part III: High Volume Processing.
   formatting 3000 records..OK

Part IV: Error Handling.
The following tests will run your program with
bad data or bad format files.  Your program must
report an error for each of these tests.  The
message you print should be informative.


   a. data error: inappropriate data format
../fl: Field entry without equals: kallin      ttyp1       Nov 25 08

   b. data error: blank fieldnames, empty fields
../fl: Field with blank fieldname.

   c. format error: unterminated fieldname..


../fl: Unterminated fieldname:lastname,
        Dear Mr. 
   d. usage error: no such format file..
../fl: Cannot open format file:../fl

   e. usage error: no such data file..
Arlington, Alan 10%
Berkeley, Barbara 10%
Clarendon, Carol 10%
Dartmouth, D. 10%
Exeter, Eric 10%
Fairfield, Francis 10%
Gloucester, Gail 10%
Hereford, Henry 10%
Ipswich, Imogene 10%
../fl: Cannot open data file:no-such-file
ws13% exit

exit

script done on Fri Dec  7 22:57:57 2001
