/* infodump.c V1.1
 *
 * Infocom dictionary dumper, etc. for type 3, 4, 5 and 6 games. If you have
 * Zork I then by defining ZORKI you will get a detailed list of object
 * properties. Properties numbers and use vary between games so this only works
 * for ZORK I.
 *
 * Requires txio.c and tx.h
 *
 * Usage: infodump story-file-name
 *
 * Mark Howell 28 August 1992 howell_ma@movies.enet.dec.com
 *
 * History:
 *    Fix verb table display for later type 4 and 5 games
 */

#include "tx.h"

typedef struct wentry {
    struct wentry *flink;
    unsigned short text;
    int number;
} wentry_t;

#ifdef __STDC__
static void show_header (void);
static void show_synonym (void);
static void show_object (void);
static void print_property_list (unsigned long *, int);
#ifdef ZORKI
static int print_property_values (int, int, int, unsigned long *);
static void print_string (unsigned long *);
#endif
static void show_tree (void);
static void print_object (int, int);
static void print_object_desc (int);
#ifndef ONE_COLUMN
static void show_dictionary (void);
#else
static void show_dictionary2 (void);
#endif
static zword_t get_object_address (zword_t);
static void show_verb_table (void);
static void load_words (int);
static wentry_t *lookup_word (wentry_t *, int);
static void free_words (void);
static void fix_dictionary (void);
#else
static void show_header ();
static void show_synonym ();
static void show_object ();
static void print_property_list ();
#ifdef ZORKI
static int print_property_values ();
static void print_string ();
#endif
static void show_tree ();
static void print_object ();
static void print_object_desc ();
#ifndef ONE_COLUMN
static void show_dictionary ();
#else
static void show_dictionary2 ();
#endif
static zword_t get_object_address ();
static void show_verb_table ();
static void load_words ();
static wentry_t *lookup_word ();
static void free_words ();
static void fix_dictionary ();
#endif

static char alternate_alphabet[3][26];
static wentry_t *wentry_head = NULL;

#ifdef __STDC__
int main (int argc, char *argv [])
#else
int main (argc, argv)
int argc;
char *argv[];
#endif
{
    if (argc != 2) {
        fprintf (stderr, "Usage: %s story-file\n", argv [0]);
        exit (EXIT_FAILURE);
    }

    open_story (argv [1]);

    configure (V3, V6);

    load_cache ();

    if (h_type == V6 && h_alternate_alphabet_offset) {
        unsigned long offset;
        int i, j;

        offset = (unsigned long) h_alternate_alphabet_offset;
        for (i = 0; i < 3; i++) {
            for (j = 0; j < 26; j++)
                alternate_alphabet[i][j] = read_data_byte (&offset);
            lookup_table[i] = &alternate_alphabet[i][0];
        }
    }

    fix_dictionary ();

    show_header ();

    show_synonym ();

    show_object ();

    show_tree ();

    if (h_type != V6) /* Doesn't work for type 6 games yet */
        show_verb_table ();
#ifndef ONE_COLUMN
    show_dictionary ();
#else
    show_dictionary2 ();
#endif
    close_story ();

    exit (EXIT_SUCCESS);

    return (0);

}/* main */

#ifdef __STDC__
static void show_header (void)
#else
static void show_header ()
#endif
{

    printf ("Game type = %d", (int) get_byte (H_TYPE));
    printf (", conf. info. = %x", (unsigned int) get_byte (H_CONFIG));
    printf (", version = %d", (int) get_word (H_VERSION));
    printf (", date = %c%c/%c%c/%c%c\n",
        (char) get_byte (H_RELEASE_DATE + 4), (char) get_byte (H_RELEASE_DATE + 5),
        (char) get_byte (H_RELEASE_DATE + 2), (char) get_byte (H_RELEASE_DATE + 3),
        (char) get_byte (H_RELEASE_DATE + 0), (char) get_byte (H_RELEASE_DATE + 1));

}/* show_header */

#ifdef __STDC__
static void show_synonym (void)
#else
static void show_synonym ()
#endif
{
    unsigned long offset, address;
    int i;

    offset = (unsigned long) h_synonyms_offset;
    printf ("\nSynonym list address = %lx\n\n", offset);

    for (i = 0; i < (3 * 32); i++) {
        address = (unsigned long) read_data_word (&offset) * 2;
        printf ("[%2d] \"", i);
        decode_text (&address);
        printf ("\"\n");
    }
    printf ("\nSynonym list ends at address %lx\n", offset);

}/* show_synonym */

#ifdef __STDC__
static void show_object (void)
#else
static void show_object ()
#endif
{
    unsigned long offset, object_address, address;
    int object_count, data, i, j, k;

    load_words (0x20);

    offset = (unsigned long) h_objects_offset;

    object_address = (unsigned long) get_object_address (1);
    if (h_type == V3) {
        address = object_address + O3_PROPERTY_OFFSET;
        object_count = ((int) read_data_word (&address) - object_address) / O3_SIZE;
    } else {
        address = object_address + O4_PROPERTY_OFFSET;
        object_count = ((int) read_data_word (&address) - object_address) / O4_SIZE;
    }

    printf ("\nObject list address = %lx\n\n", offset);
    printf ("  Object count = %d\n\n", object_count);

    for (i = 1; i <= object_count; i++) {
        object_address = (unsigned long) get_object_address ((zword_t) i);
        printf ("[%3d] Attributes:    ", i);
        if (h_type == V3) {
            for (j = 0; j < 4; j++) {
                data = (int) read_data_byte (&object_address);
                for (k = 7; k >= 0; k--)
                    printf ("%01d", (data >> k) & 1);
                printf (" ");
            }
            printf ("\n");
            printf ("      Parent object: %3d", (int) read_data_byte (&object_address));
            printf ("  Next object: %3d", (int) read_data_byte (&object_address));
            printf ("  Child object: %3d\n", (int) read_data_byte (&object_address));
        } else {
            for (j = 0; j < 6; j++) {
                data = (int) read_data_byte (&object_address);
                for (k = 7; k >= 0; k--)
                    printf ("%01d", (data >> k) & 1);
                printf (" ");
            }
            printf ("\n");
            printf ("      Parent object: %3d", (int) read_data_word (&object_address));
            printf ("  Next object: %3d", (int) read_data_word (&object_address));
            printf ("  Child object: %3d\n", (int) read_data_word (&object_address));
        }
        address = (unsigned long) read_data_word (&object_address);
        printf ("      Property offset: %04lx\n", address);
        printf ("          Description: \"");
        if (read_data_byte (&address))
            decode_text (&address);
        printf ("\"\n");
        printf ("          Properties:\n");
        print_property_list (&address, i);
        printf ("\n");
    }

    printf ("\nObject list ends at address = %lx\n", address);

    free_words ();

}/* show_object */

#ifdef __STDC__
static void print_property_list (unsigned long *address, int obj)
#else
static void print_property_list (address, obj)
unsigned long *address;
int obj;
#endif
{
    int data, count;

    while (data = (int) read_data_byte (address)) {
        printf ("              [%2d] ", data & 0x1f);
        if (h_type == V3)
            count = ((data >> 5) & 0x07) + 1;
        else if (data & 0x80)
            count = read_data_byte (address) & 0x3f;
        else if (data & 0x40)
            count = 2;
        else
            count = 1;
#ifdef ZORKI /* Only works for ZorkI, other games long description, etc. vary */
        if (print_property_values (obj, data, count, address))
#endif
        while (count--)
            printf ("%02x ", (unsigned int) read_data_byte (address));
        printf ("\n");
    }

}/* print_property_list */
#ifdef ZORKI
#ifdef __STDC__
static int print_property_values (int obj, int property, int plen, unsigned long *address)
#else
static int print_property_values (obj, property, plen, address)
int obj, property, plen;
unsigned long *address;
#endif
{
    unsigned long offset;
    int i;
    wentry_t *wentry;

    static const char *directions[] = {
        "Land", "Out", "In", "Down", "Up",
        "Southwest", "Southeast", "Northwest", "Northeast",
        "South", "West", "East", "North"};

    if (h_type == V3)
        property &= 0x1f;
    else
        property &= 0x3f;
    switch (property) {
        case 31: case 30: case 29: case 28: case 27: case 26:
        case 25: case 24: case 23: case 22: case 21: case 20: case 19:
            printf ("%s: ", directions[property - 19]);
            switch (plen) {
                case 1:
                    print_object_desc ((int) read_data_byte (address));
                    break;
                case 2:
                    offset = (unsigned long) read_data_word (address) * story_scaler;
                    print_string (&offset);
                    break;
                case 3:
                    offset = (unsigned long) read_data_word (address) * story_scaler;
                    printf ("action routine: %lx", offset);
                    read_data_byte (address);
                    break;
                case 4:
                    print_object_desc ((int) read_data_byte (address));
                    printf (" if ");
                    i = (int) read_data_byte (address);
                    if (i == 0)
                        printf ("(SP)+");
                    else
                        if (i < 16)
                            printf ("L%02x", i - 1);
                        else
                            printf ("G%02x", i - 16);
                    printf (" != 0 else ");
                    offset = (unsigned long) read_data_word (address) * story_scaler;
                    if (offset)
                        print_string (&offset);
                    else
                        printf ("\"You can't go that way.\"");
                    break;
                case 5:
                    print_object_desc ((int) read_data_byte (address));
                    printf (" ");
                    i = (int) read_data_byte (address);
                    offset = (unsigned long) read_data_word (address) * story_scaler;
                    if (offset)
                        print_string (&offset);
                    else {
                        printf ("else \"The ");
                        print_object_desc (i);
                        printf (" is closed.\"");
                    }
                    read_data_byte (address);
                    break;
                default:
                    return (1);
            }
            break;
        case 18:
            printf ("Names: ");
            for (i = 0; i < (plen / 2); i++) {
                offset = (unsigned long) read_data_word (address);
                print_string (&offset);
                printf (" ");
            }
            break;
        case 17:
            printf ("Action routine: %lx", (unsigned long) read_data_word (address));
            break;
        case 16:
            printf ("Adjectives: ");
            while (plen--) {
                i = (int) read_data_byte (address);
                wentry = lookup_word (NULL, i);
                if (wentry != NULL) {
                    offset = wentry->text;
                    print_string (&offset);
                } else
                    printf ("[%02x]", i);
                printf (" ");
            }
            break;
        case 15:
            printf ("Weight: %d", (int) read_data_word (address));
            break;
        case 14:
            printf ("Initial description: ");
            offset = (unsigned long) read_data_word (address) * story_scaler;
            print_string (&offset);
            break;
        case 13:
            printf ("Find score: %d", (int) read_data_word (address));
            break;
        case 12:
            printf ("Return score: %d", (int) read_data_word (address));
            break;
        case 11:
            printf ("Long description: ");
            offset = (unsigned long) read_data_word (address) * story_scaler;
            print_string (&offset);
            break;
        case 10:
            printf ("Hold capacity: %d", (int) read_data_word (address));
            break;
        case 9:
            printf ("Routine: %lx", (unsigned long) read_data_word (address) * story_scaler);
            break;
        case 8:
            printf ("Read description: ");
            offset = (unsigned long) read_data_word (address) * story_scaler;
            print_string (&offset);
            break;
        case 7:
            printf ("Wait time: %d", (int) read_data_word (address));
            break;
        case 6:
            printf ("Vehicle attribute: %d", (int) read_data_word (address));
            break;
        case 5:
            printf ("Referenced objects: ");
            while (plen--) {
                print_object_desc ((int) read_data_byte (address));
                printf (" ");
            }
            break;
        case 4:
            printf ("Word action routines: ");
            for (i = 0; i < (plen / 4); i++) {
                offset = (unsigned long) read_data_word (address);
                print_string (&offset);
                printf (" = %lx ", (unsigned long) read_data_word (address) * story_scaler);
            }
            break;
        case 3:
            printf ("Spare1: %d", (int) read_data_word (address));
            break;
        case 2:
            printf ("Spare2: %d", (int) read_data_word (address));
            break;
        default:
            return (1);
    }

    return (0);

}/* print_property_values */

#ifdef __STDC__
static void print_string (unsigned long *address)
#else
static void print_string (address)
unsigned long *address;
#endif
{

    printf ("\"");
    decode_text (address);
    printf ("\"");

}/* print_string */
#endif /* ZORKI */
#ifdef __STDC__
static void show_tree (void)
#else
static void show_tree ()
#endif
{
    unsigned long object_address, address;
    int object_count, i;
    unsigned int parent;

    object_address = (unsigned long) get_object_address (1);
    if (h_type == V3) {
        address = object_address + O3_PROPERTY_OFFSET;
        object_count = ((int) read_data_word (&address) - object_address) / O3_SIZE;
    } else {
        address = object_address + O4_PROPERTY_OFFSET;
        object_count = ((int) read_data_word (&address) - object_address) / O4_SIZE;
    }

    printf ("\nObject tree \n\n");

    for (i = 1; i <= object_count; i++) {
        object_address = (unsigned long) get_object_address ((zword_t) i);
        if (h_type == V3) {
            object_address += O3_PARENT;
            parent = (int) read_data_byte (&object_address);
        } else {
            object_address += O4_PARENT;
            parent = (unsigned int) read_data_word (&object_address);
        }
        if (parent == 0)
            print_object (i, 0);
    }

}/* show_tree */

#ifdef __STDC__
static void print_object (int obj, int depth)
#else
static void print_object (obj, depth)
int obj;
int depth;
#endif
{
    unsigned long object_address, address;
    int child, i;

    while (obj) {
        for (i = 0; i < depth; i++)
            printf (" . ");
        printf ("[%3d] ", obj);
        print_object_desc (obj);
        printf ("\n");
        object_address = (unsigned long) get_object_address ((zword_t) obj);
        if (h_type == V3) {
            address = object_address + O3_CHILD;
            child = (int) read_data_byte (&address);
            address = object_address + O3_NEXT;
            obj = (int) read_data_byte (&address);
        } else {
            address = object_address + O4_CHILD;
            child = (int) read_data_word (&address);
            address = object_address + O4_NEXT;
            obj = (unsigned int) read_data_word (&address);
        }
        if (child)
            print_object (child, depth + 1);
    }

}/* print_object */

#ifdef __STDC__
static void print_object_desc (int obj)
#else
static void print_object_desc (obj)
int obj;
#endif
{
    unsigned long object_address, address;

    printf ("\"");
    if (obj) {
        object_address = (unsigned long) get_object_address ((zword_t) obj);
        if (h_type == V3)
            address = object_address + O3_PROPERTY_OFFSET;
        else
            address = object_address + O4_PROPERTY_OFFSET;
        address = (unsigned long) read_data_word (&address);
        if (read_data_byte (&address))
            decode_text (&address);
    }
    printf ("\"");

}/* print_object_desc */
#ifndef ONE_COLUMN
#ifdef __STDC__
static void show_dictionary (void)
#else
static void show_dictionary ()
#endif
{
    unsigned long offset, address;
    int separator_count, word_size, word_count, columns, i, length;

    offset = (unsigned long) h_words_offset;
    printf ("\nDictionary header address = %lx\n\n", offset);
    separator_count = (int) read_data_byte (&offset);
    printf ("  Word separators = \"");
    for (; separator_count; separator_count--)
        printf ("%c", (char) read_data_byte (&offset));
    printf ("\"\n");
    word_size = (int) read_data_byte (&offset);
    word_count = (int) read_data_word (&offset);
    printf ("  Word count = %d, word size = %d\n", word_count, word_size);
    printf ("\nDictionary header ends at address = %lx\n", offset);

    printf ("\nDictionary address = %lx\n", offset);

    columns = 80 / (word_size + 8);

    for (i = 1; i <= word_count; i++) {
        if (i % columns == 1)
            printf ("\n");
        printf ("[%4d] ", i);
        address = offset;
        for (length = decode_text (&address); length <= word_size; length++)
            printf (" ");
        offset += word_size;
    }
    printf ("\n\nDictionary ends at address %lx\n", address);

}/* show_dictionary */
#else /* ONE_COLUMN */
#ifdef __STDC__
static void show_dictionary2 (void)
#else
static void show_dictionary2 ()
#endif
{
    unsigned long offset, address;
    int separator_count, word_size, word_count, data, i, j, length;

    offset = (unsigned long) h_words_offset;
    printf ("\nDictionary header address = %lx\n\n", offset);
    separator_count = (int) read_data_byte (&offset);
    printf ("  Word separators = \"");
    for (; separator_count; separator_count--)
        printf ("%c", (char) read_data_byte (&offset));
    printf ("\"\n");
    word_size = (int) read_data_byte (&offset);
    word_count = (int) read_data_word (&offset);
    printf ("  Word count = %d, word size = %d\n", word_count, word_size);
    printf ("\nDictionary header ends at address = %lx\n", offset);

    printf ("\nDictionary address = %lx\n\n", offset);

    for (i = 1; i <= word_count; i++) {
        printf ("[%4d] ", i);
        address = offset;
        offset += word_size;
        for (length = decode_text (&address); length <= word_size; length++)
            printf (" ");
        data = (zbyte_t) read_data_byte (&address);
        printf ("[%02x](", data);
        for (j = 7; j >= 0; j--)
            printf ("%01d", (data >> j) & 1);
        printf (")");
        while (address < offset)
            printf ("[%02x]", (int) read_data_byte (&address));
        printf ("\n");
    }
    printf ("\nDictionary ends at address %lx\n", offset);

}/* show_dictionary2 */
#endif /* ONE_COLUMN */
#ifdef __STDC__
static zword_t get_object_address (zword_t obj)
#else
static zword_t get_object_address (obj)
zword_t obj;
#endif
{
    int offset;

    if (h_type == V3)
        offset = h_objects_offset + ((P3_MAX_PROPERTIES - 1) * 2) + ((obj - 1) * O3_SIZE);
    else
        offset = h_objects_offset + ((P4_MAX_PROPERTIES - 1) * 2) + ((obj - 1) * O4_SIZE);

    return ((zword_t) offset);

}/* get_object_address */

#ifdef __STDC__
static void show_verb_table (void)
#else
static void show_verb_table ()
#endif
{
    unsigned long offset, address, address1, address2, text_addr;
    int verb_count, count, max_action = 0, flag, i, j, t;
    int table_type, verb_size;
    int verb_table[256];
    wentry_t *wentry;

    load_words (0x40);

    offset = (unsigned long) h_restart_size;
    printf ("\nVerb parse table address %lx\n\n", offset);
    address = (unsigned long) read_data_word (&offset);
    offset = (unsigned long) h_restart_size;
    verb_count = (int) ((address - offset) / 2);
    printf ("  Verb entries = %d\n\n", verb_count);

    address = offset;
    address1 = (unsigned long) read_data_word (&offset);
    address2 = (unsigned long) read_data_word (&offset);
    count = (int) read_data_byte (&address1);
    offset = address;
    verb_size = (address2 - address1) / count;

    if (h_type == V3 || h_type == V4) {
        table_type = 0;
        verb_size = 8;
    } else {
        if (verb_size == 8)
            table_type = 0;
        else
            table_type = 1;
    }

    for (i = 0; i < verb_count; i++) {
        address = (unsigned long) read_data_word (&offset);
        count = (int) read_data_byte (&address);
        flag = 1;
        printf ("[%2x] (%2d) ", 255 - i, count);
        while (count--) {
            printf ("[");
            t = (int) read_data_byte (&address);
            printf ("%02x ", t);
            if (table_type) {
                t = (t >> 6) & 0x03;
                if (t == 0)
                    verb_size = 2;
                else if (t == 1)
                    verb_size = 4;
                else
                    verb_size = 7;
            }
            for (j = 1; j < verb_size; j++) {
                t = (int) read_data_byte (&address);
                printf ("%02x", t);
                if ((table_type && j == 1) || (table_type == 0 && j == 7)) {
                    if (t > max_action)
                        max_action = t;
                    verb_table[t] = 255 - i;
                }
                if (j < (verb_size - 1))
                    printf (" ");
            }
            printf ("]");
            for (j = verb_size; j < 8; j++)
                printf ("   ");
            if (flag) {
                flag = 0;
                wentry = lookup_word (NULL, 255 - i);
                if (wentry != NULL) {
                    do {
                        text_addr = (unsigned long) wentry->text;
                        printf (" \"");
                        decode_text (&text_addr);
                        printf ("\"");
                    } while ((wentry = lookup_word (wentry, 255 - i)) != NULL);
                } else
                    printf (" no verb");
            }
            printf ("\n");
            if (count)
                printf ("          ");
        }
    }
    while (read_data_byte (&address) == 0)
        ;
    offset = address - 1;
    printf ("\nVerb parse table ends at address %lx\n", offset);

    max_action++;

    printf ("\nVerb action table address %lx\n\n", offset);
    printf ("  Action table entries = %d\n\n", max_action);
    for (i = 0; i < max_action; i++) {
        printf ("[%3d] %5x", i, (int) read_data_word (&offset) * story_scaler);
        wentry = lookup_word (NULL, verb_table[i]);
        if (wentry != NULL) {
            do {
                text_addr = (unsigned long) wentry->text;
                printf (" \"");
                decode_text (&text_addr);
                printf ("\"");
            } while ((wentry = lookup_word (wentry, verb_table[i])) != NULL);
        } else
            printf (" no verb");
        printf ("\n");
    }
    printf ("\nVerb action table ends at address %lx\n", offset);

    printf ("\nVerb pre-action table address %lx\n\n", offset);
    printf ("  Pre-action table entries = %d\n\n", max_action);
    for (i = 0; i < max_action; i++) {
        printf ("[%3d] %5x", i, (int) read_data_word (&offset) * story_scaler);
        wentry = lookup_word (NULL, verb_table[i]);
        if (wentry != NULL) {
            do {
                text_addr = (unsigned long) wentry->text;
                printf (" \"");
                decode_text (&text_addr);
                printf ("\"");
            } while ((wentry = lookup_word (wentry, verb_table[i])) != NULL);
        } else
            printf (" no verb");
        printf ("\n");
    }
    printf ("\nVerb pre-action table ends at address %lx\n", offset);

    printf ("\nAdjective table address %lx\n\n", offset);
    count = (int) read_data_word (&offset);
    printf ("  Table entries = %d\n\n", count);
    for (i = 0; i < count; i++) {
        address = (int) read_data_word (&offset);
        if (table_type == 0)
            printf ("[%2x] \"", (int) read_data_word (&offset));
        else
            printf ("[%2x] \"", (int) read_data_byte (&offset));
        decode_text (&address);
        printf ("\"\n");
    }
    printf ("\nAdjective table ends at address %lx\n", offset);

    free_words ();

}/* show_verb_table */

#ifdef __STDC__
static void load_words (int mask)
#else
static void load_words (mask)
int mask;
#endif
{
    unsigned long offset, address;
    int word_count, word_size, flags, i;
    wentry_t *wentry;

    offset = (unsigned long) h_words_offset;
    offset += (unsigned long) read_data_byte (&offset);
    word_size = (int) read_data_byte (&offset);
    word_count = (int) read_data_word (&offset);
    for (i = 0; i < word_count; i++) {
        address = offset;
        if (h_type == V3)
            address += 4;
        else
            address += 6;
        if ((flags = read_data_byte (&address)) & mask) {
            if ((wentry = (wentry_t *) malloc (sizeof (wentry_t))) == NULL) {
                fprintf (stderr, "Insufficient memory!\n");
                exit (EXIT_FAILURE);
            }
            wentry->text = (unsigned short) offset;
            wentry->number = (int) read_data_byte (&address);
            if (((mask == 0x40) && (flags & 0x01) == 0) ||
                ((mask == 0x20) && (flags & 0x02) == 0))
                wentry->number = (int) read_data_byte (&address);
            wentry->flink = wentry_head;
            wentry_head = wentry;
        }
        offset += word_size;
    }

}/* load_words */

#ifdef __STDC__
static wentry_t *lookup_word (wentry_t *wentry, int number)
#else
static wentry_t *lookup_word (wentry, number)
wentry_t *wentry;
int number;
#endif
{
    wentry_t *ptr;

    for (ptr = (wentry == NULL) ? wentry_head : wentry->flink;
         ptr != NULL && ptr->number != number;
         ptr = ptr->flink)
        ;

    return (ptr);

}/* lookup_word */

#ifdef __STDC__
static void free_words (void)
#else
static void free_words ()
#endif
{
    wentry_t *ptr, *next_ptr;

    for (ptr = wentry_head; ptr != NULL; ptr = next_ptr) {
        next_ptr = ptr->flink;
        free (ptr);
    }
    wentry_head = NULL;

}/* free_words */

#ifdef __STDC__
static void fix_dictionary (void)
#else
static void fix_dictionary ()
#endif
{
    unsigned long offset;
    int separator_count, word_size, word_count, i;

    offset = (unsigned long) h_words_offset;
    separator_count = (int) read_data_byte (&offset);
    offset += separator_count;
    word_size = (int) read_data_byte (&offset);
    word_count = (int) read_data_word (&offset);

    for (i = 1; i <= word_count; i++) {
        if ((offset + 4) < (unsigned long) h_data_size)
            if (h_type == V3)
                set_byte (offset + 2, get_byte (offset + 2) | 0x80);
            else
                set_byte (offset + 4, get_byte (offset + 4) | 0x80);
        offset += word_size;
    }

}/* fix_dictionary */
