// idbg - IJVM debugger.
// Copyright 2000 Tom Rothamel <tom-idbg@onegeek.org>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "idbg.h"

struct Method *methods = NULL;
struct Variable *constants = NULL;

char *split(char *s) {

	if (!s) return NULL;
	
	while (*s) {
		if (*s == ' ') {
			*s = 0;
			s++;
			return s;
		}
		s++;
	}

	return NULL;
}

int lookup_method_offset(char *method, int o) {
	Method *m;

	m = lookup_method_name(method);
	if (!m) return -1;
	
	if (o == -1) {
		o = 0;
		if (m->addr != 0) o = 4;
	}
	
	return m->addr + o;
}
	

Method *lookup_method_name(char *name) {
	Method *m;

	m = methods;

	while (m) {
		if (!strcmp(name, m->name)) return m;
		m = m->next;
	}

	return NULL;
}

Method *lookup_method_addr(int addr) {
	Method *m;

	m = methods;
	
	while (m) {
		if (addr >= m->addr && addr <= m->addr + m->len) return m;
		m = m->next;
	}

	return NULL;
}

Variable *lookup_variable_num(Variable *v, int num) {
	while (v) {
		if (num == v->num) return v;
		v = v->next;
	}

	return NULL;
}

Variable *lookup_constant(int num) {
	return lookup_variable_num(constants, num);
}		

int read_symbols(FILE *f) {
	char buf[1024];
	char *args[4];

	Method *m;
	Variable *v;
	
	while (fgets(buf, 1024, f)) {
		if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = 0;
		
		args[0] = buf;
		args[1] = split(args[0]);

		if (!args[1]) return 0;
		
		if (!strcmp(args[0], "ijvm-debug")) {
			if (atoi(args[1]) != 1) return 0;
		} else if (!strcmp(args[0], "method")) {
			args[2] = split(args[1]);
			args[3] = split(args[2]);

			if (!args[3]) return 0;
			
			m = new Method;
			m->name = strdup(args[1]);
			m->addr = atoi(args[2]);
			m->len = atoi(args[3]);
			m->vars = NULL;

			m->next = methods;
			methods = m;
		} else if (!strcmp(args[0], "variable")) {
			args[2] = split(args[1]);
			args[3] = split(args[2]);
			if (!args[3]) return 0;
			
			m = lookup_method_name(args[1]);

			if (!m) return 0;

			v = new Variable;
			v->num = atoi(args[2]);
			v->name = strdup(args[3]);
			v->next = m->vars;
			m->vars = v;
		} else if (!strcmp(args[0], "constant")) {
			args[2] = split(args[1]);
			if (!args[2]) return 0;
			
			v = new Variable;
			v->name = strdup(args[2]);
			v->num = atoi(args[1]);
			v->next = constants;
			constants = v;			
		}
	}

	return 1;
}
		

