/* $Id: label.c,v 1.4 2009/01/27 15:40:22 potyra Exp $ 
 *
 * Copyright (C) 2008-2009 FAUcc Team <info@faumachine.org>.
 * This program is free software. You can redistribute it and/or modify it
 * under the terms of the GNU General Public License, either version 2 of
 * the License, or (at your option) any later version. See COPYING.
 */

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

#include "label.h"
#include "stmt.h"

struct label *
label_new(const char *identifier)
{
	struct label *label;

	label = malloc(sizeof *label);
	assert(label);

	memset(label, 0, sizeof *label);

	label->identifier = identifier;

	return label;
}

static void
label_free(struct label *label)
{
	if (! label->ref_first
	 && ! label->def_first) {
#if 0
		free(label);
#endif
	}
}

void
label_ref_add(struct label *label, struct stmt *s)
{
	s->ref_prev = label->ref_last;
	s->ref_next = NULL;
	if (s->ref_prev) {
		s->ref_prev->ref_next = s;
	} else {
		label->ref_first = s;
	}
	label->ref_last = s;
}

void
label_ref_del(struct label *label, struct stmt *s)
{
	if (s->ref_prev) {
		s->ref_prev->ref_next = s->ref_next;
	} else {
		label->ref_first = s->ref_next;
	}
	if (s->ref_next) {
		s->ref_next->ref_prev = s->ref_prev;
	} else {
		label->ref_last = s->ref_prev;
	}

	label_free(label);
}

void
label_def_add(struct label *label, struct stmt *s)
{
	s->def_prev = label->def_last;
	s->def_next = NULL;
	if (s->def_prev) {
		s->def_prev->def_next = s;
	} else {
		label->def_first = s;
	}
	label->def_last = s;
}

void
label_def_del(struct label *label, struct stmt *s)
{
	if (s->def_prev) {
		s->def_prev->def_next = s->def_next;
	} else {
		label->def_first = s->def_next;
	}
	if (s->def_next) {
		s->def_next->def_prev = s->def_prev;
	} else {
		label->def_last = s->def_prev;
	}

	label_free(label);
}
