Script started on Mon Nov 12 21:16:27 2001
ws18% cat test.c

//
//      wordlist table module version 5
//
//      modified from v4, Russel Lowke Nov 8th, 2001
//

#include                        <stdio.h>
#include                        <stdlib.h>
#include                        <string.h>
#include                        "wl.h"
#define MAXTABLE        26

//      structure: linked list of structs
//
struct link {
        char            * word;                                                 // pointer to word
        int                   value;                                            // word count
        struct link * next;                                                     // pointer to next link
};


//  globals
//
struct link   gHead[MAXTABLE];                                  // symbol table heads
struct link * gMyLink;                                                  // link being looked at
int               gStreamAt;                                            // track current table stream


//
//  return stream for a given word
//
int getStream(char str[])
{
        int stream = str[0] - 'a';                                      // stream for this string
                                                                                                // a = 0, z = 25

        if (stream < 0 || stream > 25)                          // ensure stream is
                        stream = -1;                                            // within bounds
        
        return stream;
}


//
//      initalize module
//
void init_table()
{
        int i;                                                                          // counter
        
        // create symbol table with 
        // 26 version links of head nodes - one for each letter a thru z
        
        for (i = 0; i < MAXTABLE; i++) {
                gHead[i].next = NULL;
        }
}


//
//  search table for word, returning ptr to that word - if found
//
struct link * searchTable(char str[])
{
        // linkp = head of table stream 
        struct  link * linkp = gHead[getStream(str)].next;
        
        // loop through words
        while(linkp != NULL) {
                
                if (strcmp(str, linkp->word) == 0)              // found duplicate
                        return linkp;                   
                else if (strcmp(str, linkp->word) < 0)  // past word, stop looking
                        return NULL;                                            // ( 1/2's search time )
                else {
                        linkp = linkp->next;                            // ... get next word
                }
        }
        
        return NULL;
}


//
//      check if word is in table
//
int in_table(char str[])
{
        return (searchTable(str) != NULL);
}


//
//  retrieve value from table
//      
int lookup(char str[])
{
        struct link * linkp = searchTable(str);
        
        if (linkp == NULL)
                return NO;                                                              // not found
        else
                return linkp->value;                                    // return value
}


//
//  update value in table
//
int update(char str[], int val)
{
        struct link * linkp = searchTable(str);
        
        if (linkp == NULL)
                return NO;                                                              // not found
        else {
                linkp->value = val;                                             // update
                return YES;
        }
}



//
//      insert a new value into table
//
int insert(char str[], int val)
{
        int                   stream = getStream(str);          // stream for this word
        char            * newstr ;
        struct link     * newlink,
                        * prevLink = NULL;

        // get memory and allocate values for struct
        newstr = malloc( 1 + strlen(str));
        if (newstr == NULL)                                                     // out of memory
                return NO;
        strcpy( newstr, str );
        newlink = malloc(sizeof(struct link));
        if (newlink == NULL)                                            // out of memory
                return NO;
        
        // store word and value into newlink
        newlink->word      = newstr;
        newlink->value     = val;

        // traverse list, looking for place to insert word str
        for (prevLink =  &gHead[stream], gMyLink  = gHead[stream].next;
                 gMyLink != NULL;
                 prevLink = gMyLink, gMyLink  = gMyLink->next ) {
                
                // break if link word is after newstr
                if (strcmp(newstr, gMyLink->word) < 0) {
                        break;
                }
        }
        
        // squeeze newlink into linked list
        newlink->next = gMyLink;                                        // attach to next link
        prevLink->next = newlink;                                       // attach to previous link
        
        return YES;
}


//
//  delete word from table
//
void word_delete(char str[])
{
        struct  link * linkp,                                           // link
                     * prevLink;                                        // previous link
        int             stream = getStream(str);                        // stream for this word

        prevLink = &gHead[stream];
        for( linkp = gHead[stream].next ; linkp ; prevLink = linkp,
                                                         linkp    = linkp->next ) {
                if ( strcmp( linkp->word, str) == 0 ) { // if found
                        prevLink->next = linkp->next;           // kill link word
                        free(linkp);                                            // free memory
                        break;
                }
        }       
}


//
//      return first word
//
char * firstword()
{
        gStreamAt = 0;                                                          // set global streamAt
        gMyLink = gHead[gStreamAt].next;                        // set global gMyLink
        return nextword();
}


//
//      return next word
//
char * nextword()
{
        char *ret_val;

        if ( gMyLink == NULL ) {
                gStreamAt++;                                                    // increment to next stream
                if (gStreamAt == MAXTABLE)                              // check end of table
                        return NULL;
                else
                        gMyLink = gHead[gStreamAt].next;        // recursive, load new stream
                        return nextword();                              
        }
        else {
                ret_val = gMyLink->word;                                // return word
                gMyLink = gMyLink->next;                                // get next word
                return ret_val;
        }
}
ws18% exit

exit

script done on Mon Nov 12 21:16:36 2001
