/**********************************************************************
 
	Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	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.

**********************************************************************/


#include	"memory_routine.h"
#include	"mlong_char.h"
#include	"xl.h"

void gc_gb_sym_field();

void
set_attribute(XL_SEXP * sym,
	L_CHAR * name,
	L_CHAR * data)
{
XL_SYM_FIELD * sf;
	if ( get_type(sym) != XLT_SYMBOL )
		return; 
	sf = mmalloc(sizeof(*sf),gc_gb_sym_field);
	sf->name = ll_copy_mstr(name);
	sf->data = ll_copy_mstr(data);
	sf->next = sym->symbol.field;
	sym->symbol.field = sf;
}

XL_SEXP *
replace_attribute(XL_SEXP * sym,
	L_CHAR * name,
	L_CHAR * data)
{
XL_SYM_FIELD * sf, * sf_1, * sf_2;
XL_SYM_FIELD ** sfp;
	if ( get_type(sym) != XLT_SYMBOL )
		return sym;
	for ( sf = sym->symbol.field ; sf ; sf = sf->next ) {
		if ( l_strcmp(sf->name,name) )
			continue;
		if ( data == 0 )
			break;
		if ( l_strcmp(sf->data,data) == 0 )
			return sym;
		break;
	}
	if ( sf == 0 ) {
		if ( data == 0 )
			return sym;
		sf_1 = sym->symbol.field;
		sym = get_symbol(sym->symbol.data);
		sym->symbol.field = sf_1;
		set_attribute(sym,name,data);
		return sym;
	}
	else {
		sf_1 = sym->symbol.field;
		sym = get_symbol(sym->symbol.data);
		sfp = &sym->symbol.field;
		for ( ; sf_1 ; sf_1 = sf_1->next ) {
			if ( sf_1 == sf ) {
				if ( data ) {
					sf_2 = mmalloc(sizeof(*sf_2),gc_gb_sym_field);
					sf_2->name = sf_1->name;
					sf_2->data = ll_copy_mstr(data);
					sf_2->next = sf_1->next;
					*sfp = sf_2;
				}
				else {
					*sfp = sf->next;
				}
				break;
			}
			sf_2 = mmalloc(sizeof(*sf_2),gc_gb_sym_field);
			sf_2->name = sf_1->name;
			sf_2->data = sf_1->data;
			sf_2->next = 0;
			*sfp = sf_2;
			sfp = &sf_2->next;
		}
		return sym;
	}
}

