135 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* 
 | 
						|
 * Table of all global definitions. Since the ack convention is to prepend
 | 
						|
 * syms with '_' for C interfacing, we need to know about them and add/remove
 | 
						|
 * teh '_' as neccessary
 | 
						|
 */
 | 
						|
 | 
						|
#include <errno.h>
 | 
						|
#include <string.h>
 | 
						|
#include <ctype.h>
 | 
						|
#include <stdio.h>
 | 
						|
 | 
						|
#include "asm86.h"
 | 
						|
 | 
						|
/* this should be fine for common minix assembly files */
 | 
						|
#define SYM_MAX		1024
 | 
						|
#define SYM_MAX_LEN	64
 | 
						|
 | 
						|
struct sym {
 | 
						|
	char 	name[SYM_MAX_LEN];
 | 
						|
	int	gl;
 | 
						|
};
 | 
						|
 | 
						|
static struct sym syms[SYM_MAX];
 | 
						|
 | 
						|
static int syms_num = 0;
 | 
						|
 | 
						|
static struct sym * sym_exists(const char * n)
 | 
						|
{
 | 
						|
	int i;
 | 
						|
 | 
						|
	for (i = 0; i < syms_num; i++) {
 | 
						|
		if (strcmp(syms[i].name, n) == 0)
 | 
						|
			return &syms[i];
 | 
						|
	}
 | 
						|
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static int is_local_label_ref(const char *n)
 | 
						|
{
 | 
						|
	int i;
 | 
						|
	int l = strlen(n);
 | 
						|
 | 
						|
	for(i = 0; i < l - 1; i++)
 | 
						|
		if (!isdigit(n[i]))
 | 
						|
			return 0;
 | 
						|
	if (n[l-1] != 'b' && n[l-1] != 'f')
 | 
						|
		return 0;
 | 
						|
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
static int is_hex(const char *n)
 | 
						|
{
 | 
						|
	int i;
 | 
						|
	for(i = 0; n[i]; i++)
 | 
						|
		if (!isxdigit(n[i]))
 | 
						|
			return 0;
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
static int is_dec(const char *n)
 | 
						|
{
 | 
						|
	int i;
 | 
						|
	for(i = 0; n[i]; i++)
 | 
						|
		if (!isdigit(n[i]))
 | 
						|
			return 0;
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
static int is_number(const char * n)
 | 
						|
{
 | 
						|
	if (n[0] == '0' && n[1] == 'x')
 | 
						|
		return is_hex(n + 2);
 | 
						|
	else
 | 
						|
		return is_dec(n);
 | 
						|
}
 | 
						|
 | 
						|
int syms_is_global(const char * n)
 | 
						|
{
 | 
						|
	struct sym *s;
 | 
						|
 | 
						|
	if (!n || is_number(n) || is_local_label_ref(n) || isregister(n))
 | 
						|
		return 0;
 | 
						|
	
 | 
						|
	/* if not found, it must be extern -> global */
 | 
						|
	if (!(s = sym_exists(n)))
 | 
						|
		return 1;
 | 
						|
 | 
						|
	return s->gl;
 | 
						|
}
 | 
						|
 | 
						|
static int add(const char * n, int isgl)
 | 
						|
{
 | 
						|
	if (syms_num >= SYM_MAX)
 | 
						|
		return -ENOMEM;
 | 
						|
	if (!n || strlen(n) >= SYM_MAX_LEN)
 | 
						|
		return -EINVAL;
 | 
						|
 | 
						|
	/* ignore numbers */
 | 
						|
	if (is_number(n))
 | 
						|
		return 0;
 | 
						|
 | 
						|
	strcpy(syms[syms_num].name, n);
 | 
						|
	syms[syms_num].gl = isgl;
 | 
						|
	syms_num++;
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
int syms_add(const char *n)
 | 
						|
{
 | 
						|
	return add(n, 0);
 | 
						|
}
 | 
						|
 | 
						|
int syms_add_global(const char *n)
 | 
						|
{
 | 
						|
	return add(n, 1);
 | 
						|
}
 | 
						|
 | 
						|
void syms_add_global_csl(expression_t * exp)
 | 
						|
{
 | 
						|
	if (!exp)
 | 
						|
		return;
 | 
						|
 | 
						|
	if (exp->operator == ',') {
 | 
						|
		syms_add_global_csl(exp->left);
 | 
						|
		syms_add_global_csl(exp->right);
 | 
						|
	}
 | 
						|
	else {
 | 
						|
		syms_add_global(exp->name);
 | 
						|
	}
 | 
						|
}
 | 
						|
 |