
//
// Main Program for loading and threading libraries
//
//
//    Copyright (C) 2000-1 by Hugh Jack <jackh@gvsu.edu>
//
//    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.
//
//
// Last Modified: March 9, 2001
//

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

#include "../include/variables.h"



global_variables::global_variables(){
	first = NULL;
}


global_variables::~global_variables(){
	for(; first != NULL;){
		delete_var(first->name);
	}
}


global_variable	*global_variables::add_var(char *name, int type, int len){
	global_variable	*now, *last;
	int	flag;

	flag = 0;
	if(first == NULL){	// an empty list
		now = new global_variable();
		now->next = NULL;
		now->last = NULL;
		first = now;
		flag = 1;
	} else {			// search for the name in the list
		for(now = first, last = NULL; now != NULL; last = now, now = now->next){
			if(strcmp(name, now->name) == 0){
				break;
			}
		}
		if(now == NULL){
			now = new global_variable();
			last->next = now;
			now->last = last;
			now->next = NULL;
			flag = 1;
		}
	}

	if(flag == 0){	// a matching variable was found, check for mismatches
		if(now->type != type){
			_error_log(MINOR, "Added variable type doesn't match");
		}
		if((type == _STRUCT) || (type == _STRING)){
			if(len != now->len){
				_error_log(MINOR, "Structure lenghts don't match");
			}
		}
	} else {		// This is a new variable
		char	*temp;
		temp = new char[strlen(name) + 1];
		strcpy(temp, name);
		now->name = temp;
		if(type == _INT){
			now->var = (unsigned char*)(new int);
		} else if(type == _REAL){
			now->var = (unsigned char*)(new double);
		} else if(type == _BYTE){
			now->var = (unsigned char*)(new unsigned short);
		} else if(type == _STRING){
			now->var = (unsigned char*)(new char[len]);
			now->var[0] = 0;
		} else if(type == _STRUCT){
			now->var = (new unsigned char[len]);
		} else {
			_error_log(MINOR, "Data type not recognized, using bytes and given length");
			now->var = (new unsigned char[len]);
		}
		now->type = type;
		now->len = len;
		now->lock = UNLOCKED;
		now->status = _IDLE;
	}

	return now;
}



int global_variables::delete_var(char *name){
	int	error;
	global_variable	*now;

	error = NO_ERROR;
	for(now = first; now != NULL; now = now->next){
		if(strcmp(now->name, name) == 0){ break; }
	}
	if(now != NULL){
		delete now->name;
		if(now == first){
			first = first->next;
		} else {
			now->last->next = now->next;
			if(now->next != NULL){
				now->next->last = now->last;
			}
		}
	}

	return error;
}



global_variable	*global_variables::find(char *name){
	global_variable	*var;

	for(var = first; var != NULL; var = var->next){
		if(strcmp(var->name, name) == 0) return var;
	}

	return NULL;
}


int global_variables::dump(){
	int	error;

	error = NO_ERROR;
	for(global_variable *var = first; var != NULL; var = var->next){
		printf("Variable [%s]:\n", var->name);
		if(var->type == _INT) printf("    Type: _INT = %d\n", ((int*)var->var)[0]);
		if(var->type == _STRING) printf("    Type: _STRING\n");
		if(var->type == _STRUCT) printf("    Type: _STRUCT\n");
		if(var->type == _REAL) printf("    Type: _REAL\n");
		printf("    Length: %d\n", var->len);
	}

	return error;
}











