/*
 * CPP Macro symbol tables.  Extra overhead is required
 * to translate constant expression macros into Ada
 * manifest constants.
 */
#include <sys/types.h>
#include "ansi.h"
#include "files.h"
#include "hash.h"
#include "buffer.h"
#include "cpp.h"
#include "cpp_hide.h"
#include "allocate.h"
#include "config.h"

#undef NULL
#define NULL	0

#ifndef MACRO_TABLE_SIZE		/* must be a power of 2 */
#define MACRO_TABLE_SIZE		512
#endif

macro_t *macro_list_head;
static macro_t *macro_list_tail;
static macro_t *hash_table[MACRO_TABLE_SIZE];

#ifdef _MIPS_SZINT
static char mips_szint[8];
#endif
#ifdef _MIPS_SZLONG
static char mips_szlong[8];
#endif
#ifdef _MIPS_SZPTR
static char mips_szptr[8];
#endif
#ifdef _MIPS_FPSET
static char mips_fpset[8];
#endif
#ifdef _MIPSEB
static char mips_eb[8];
#endif
#ifdef _MIPS_ISA
static char mips_isa[8];
#endif
#ifdef _MIPS_SIM
static char mips_sim[8];
#endif

struct autodefs {
	char *name;
	char *value;
} deftab[] = {
	{"__ANSI_CPP__","1"},
	{"_LANGUAGE_C","1"},
	{"LANGUAGE_C","1"},
	{"__STDC__","1"},

#ifdef _MIPS_SZINT
	{"_MIPS_SZINT", mips_szint},
#endif
#ifdef _MIPS_SZLONG
	{"_MIPS_SZLONG", mips_szlong},
#endif
#ifdef _MIPS_SZPTR
	{"_MIPS_SZPTR", mips_szptr},
#endif
#ifdef _MIPS_FPSET
	{"_MIPS_FPSET",mips_fpset},
#endif
#ifdef _MIPS_ISA
	{"_MIPS_ISA",mips_isa},
#endif
#ifdef _MIPS_SIM
	{"_MIPS_SIM",mips_sim},
#endif
#ifdef _MIPSEB
	{"_MIPSEB",mips_eb},
#endif
#ifdef _IBMR2
	{"_IBMR2","1"},
#endif
#ifdef _AIX
	{"_AIX","1"},
#endif
#ifdef _AIX32
	{"_AIX32","1"},
#endif
#ifdef _CFE
	{"_CFE","1"},
#endif
#ifdef __DSO__
	{"__DSO__","1"},
#endif
#ifdef host_mips
	{"host_mips","1"},
#endif
#ifdef _LONGLONG
	{"_LONGLONG","1"},
#endif
#ifdef mips
	{"mips","1"},
#endif
#ifdef MIPSEB
	{"MIPSEB","1"},
#endif
#ifdef sgi
	{"sgi","1"},
#endif
#ifdef sun
	{"sun","1"},
#endif
#ifdef __sun
	{"__sun","1"},
#endif
#ifdef sparc
	{"sparc","1"},
#endif
#ifdef __sparc
	{"__sparc","1"},
#endif
#ifdef SVR3
	{"SVR3","1"},
#endif
#ifndef __SVR4
	{"__SVR4", "1"},
#endif
#ifdef _SVR4_SOURCE
	{"_SVR4_SOURCE","1"},
#endif
#ifdef _MIPSEB
	{"_MIPSEB","1"},
#endif
#ifdef _POSIX_SOURCE
	{"_POSIX_SOURCE","1"},
#endif
#ifdef SYSTYPE_SVR4
	{"SYSTYPE_SVR4","1"},
#endif
#ifdef _SYSTYPE_SVR4
	{"_SYSTYPE_SVR4","1"},
#endif
#ifdef SYSTYPE_SYSV
	{"SYSTYPE_SYSV","1"},
#endif
#ifdef _SYSTYPE_SYSV
	{"_SYSTYPE_SYSV","1"},
#endif
#ifdef __EXTENSIONS__
	{"__EXTENSIONS__","1"},
#endif
#ifdef __host_mips
	{"__host_mips","1"},
#endif
#ifdef host_mips
	{"host_mips","1"},
#endif
#ifdef __INLINE_INTRINSICS
	{"__INLINE_INTRINSICS","1"},
#endif
#ifdef __mips
	{"__mips","1"},
#endif
#ifdef _MODERN_C
	{"_MODERN_C","1"},
#endif
#ifdef __sgi
	{"__sgi","1"},
#endif
#ifdef _SGI_SOURCE
	{"_SGI_SOURCE","1"},
#endif
#ifdef __SVR3
	{"__SVR3","1"},
#endif
#ifdef unix
	{"unix", "1"},
#endif
#ifdef __unix
	{"__unix","1"},
#endif
	{NULL, NULL}
};

static void
macro_add_to_list(m)
	macro_t *m;
{
	if (macro_list_head) {
		macro_list_tail->macro_next = m;
	}
	else {
		macro_list_head = m;
	}
	macro_list_tail = m;
}

static void
macro_add_to_table(m)
	macro_t *m;
{
	int index;

	m->macro_hash = common_hash(m->macro_name);

	index = m->macro_hash & (MACRO_TABLE_SIZE - 1);

	m->macro_hash_link = hash_table[index];
	hash_table[index] = m;
}

void
macro_undef(name)
	char *name;
{
	macro_t *m, *last;
	hash_t hash;
	int index;

	assert(name != NULL);

	hash = common_hash(name);
	index = hash & (MACRO_TABLE_SIZE - 1);

	last = NULL;

	for (m = hash_table[index]; m; m = m->macro_hash_link) {
		if (m->macro_hash == hash && !strcmp(m->macro_name, name)) {
			if (last == NULL) {
				hash_table[index] = m->macro_hash_link;
			}
			else {
				last->macro_hash_link = m->macro_hash_link;
			}
		}
		else {
			last = m;
		}
	}
}

void
macro_def(name, body, len, params, definition)
	char *name, *body;
	int len, params;
	file_pos_t definition;
{
	macro_t *m;

	assert(name != NULL);

	m = (macro_t*) allocate(sizeof(macro_t));

	m->macro_name = name;
	m->macro_body = body;
	m->macro_body_len = len;
	m->macro_params = params;
	m->macro_definition = definition;

	if (definition != 0) {
		macro_add_to_list(m);
	}

	macro_add_to_table(m);
}

macro_t*
macro_find(name)
	char *name;
{
	macro_t *m;
	hash_t hash;
	int index;

	hash = common_hash(name);
	index = hash & (MACRO_TABLE_SIZE - 1);

	for (m = hash_table[index]; m; m = m->macro_hash_link) {
		if (m->macro_hash == hash && !strcmp(m->macro_name, name)) {
			return m;
		}
	}

	return NULL;
}

void
macro_init(force)
	int force;
{
	static int macro_initialized = 0;
	macro_t *m;
	int i;

	if (macro_initialized) {
		if (!force) return;
		memset(hash_table, 0, sizeof(hash_table));
		macro_list_head = NULL;
		macro_list_tail = NULL;
	}

	macro_initialized = 1;

	m = (macro_t*) allocate(sizeof(macro_t));
	m->macro_name = "__FILE__";
	m->macro_params = BUILTIN_FILE;
	macro_add_to_table(m);

	m = (macro_t*) allocate(sizeof(macro_t));
	m->macro_name = "__LINE__";
	m->macro_params = BUILTIN_LINE;
	macro_add_to_table(m);

#ifdef _MIPS_SZINT
	sprintf(mips_szint,"%d",_MIPS_SZINT);
#endif
#ifdef _MIPS_SZLONG
	sprintf(mips_szlong,"%d",_MIPS_SZLONG);
#endif
#ifdef _MIPS_SZPTR
	sprintf(mips_szptr,"%d",_MIPS_SZPTR);
#endif
#ifdef _MIPS_FPSET
	sprintf(mips_fpset,"%d",_MIPS_FPSET);
#endif
#ifdef _MIPS_ISA
	sprintf(mips_isa,"%d",_MIPS_ISA);
#endif
#ifdef _MIPS_SIM
	sprintf(mips_sim,"%d",_MIPS_SIM);
#endif
#ifdef _MIPSEB
	sprintf(mips_eb,"%d",_MIPSEB);
#endif

	for (i = 0; deftab[i].name != NULL; i++) {
		macro_def(deftab[i].name, deftab[i].value,
				  strlen(deftab[i].value), -1, 0);
	}
}

void
cpp_show_predefines()
{
	int i;

	puts("__FILE__\n__LINE__");

	for (i = 0; deftab[i].name != NULL; i++) {
		printf("%s\t%s\n", deftab[i].name,
			   (deftab[i].value) ? deftab[i].value : "");
	}
}


syntax highlighted by Code2HTML, v. 0.9.1