#include <stdio.h>
#include "common.h"
#include "module.h"
#include "allocate.h"
#include "hash.h"
#include "error.h"
#include "segment.h"
#include "public.h"
#include "extern.h"
#include "virdef.h"
#include "list.h"

extern HASHREC ** PublicHash;
extern char *modname;
extern HASHREC ** ExternHash;				// Pass 1 hash table for externs
extern int NumExternItems;// Hash table is used as an indexed array
															// during pass 2, this is the number of items
															// (current module)

/*
 * Read in the virdef record
 */
static void ReadVIRDEFs(BOOL is32, BYTE *buffer, 
			int size, char *name, uint pass)
{
	// Size of record is 0: then just increment the index used for the next
  // extern record
  if (size == 0) {
    if (pass == 2) {
			ExternHash[NumExternItems++] = 0;
		}
		return;
	}
  // Read in all strings this record
  while(size > 0) {
		char *string;
		int dtype, ctype, comlen;
    SEGMENT *seg;
		// Read the name
    string = ReadName(&buffer, &size, TRUE);

		// Ignore the type index
    ReadIndex(&buffer, &size);
		
		dtype = ReadByte(&buffer, &size);
		if ((dtype == COMDEFFAR) || (dtype == COMDEFNEAR))
			fatal("COMDEFs not supported in module %s\n", name);

    seg = GetSegment(dtype);

    ctype = ReadByte(&buffer, &size);
		switch (ctype) {
			case 0x81:
				comlen = ReadWord(&buffer, &size);
				break;
			case 0x84:
				comlen = ReadWord(&buffer, &size) + (ReadByte(&buffer, &size) << 16);
				break;
			case 0x88:
				comlen = ReadDword(&buffer, &size);
				break;
			default:
				if (ctype & 0x80)
					fatal("Unknown COMDEF/VIRDEF length in module %s\n", name);
				comlen = ctype;
		}

    if (pass == 1) {
			seg->VIRDEF_size += comlen;
    }
    else {
			PUBLIC *public;
		  public = (PUBLIC *) AllocateMemory(sizeof(PUBLIC));
		  public->name = string;
      public->module = name;
			public->segment = seg;		/* SEGMENT unused during fixups, assumed flat */
			public->offset = comlen;	/* Hiding the VIRDEF length in the public offset */
			public->absoffset = seg->VIRDEF_alloc;
			public->VIRDEF = TRUE;
			seg->VIRDEF_alloc += comlen;
#ifdef DEBUG
			printf("Initting VIRDEF %s address %x module %s\n", string, public->absoffset, name);
#endif
			ExternHash[NumExternItems++] = (HASHREC *) public;
		}
  }
    
  CheckSize(size);
}
// Public extern definitions record handled here
void VIRDEFDefinitions(BOOL is32,BYTE *buffer, 
			int size, char *name, uint pass)
{
    ReadVIRDEFs(is32,buffer, size,name, pass);
}