/* $Id$ 
 *
 * Mangle/Demangle VHDL names to intermediate code names.
 *
 * Copyright (C) 2008-2009 FAUmachine 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 "util/mangle_names.h"
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

static void
replace_all(char *b, size_t sz, const char *tok, const char *rep)
{
	size_t tok_len;
	size_t rep_len;
	size_t cnt;
	size_t avail;
	char *remainder;
	char *s;
	char *dest;

	tok_len = strlen(tok);
	rep_len = strlen(rep);


	for (;;) {
		s = strstr(b, tok);
		if (s == NULL) {
			break;
		}
		
		remainder = s + tok_len;
		dest = s + rep_len;
		if (dest != remainder) {
			cnt = strlen(remainder) + 1;
			avail = sz - (dest - b);
			if (cnt < avail) {
				cnt = avail;
			}
			memmove(dest, remainder, cnt);
		}

		memcpy(s, rep, rep_len);
	}

	b[sz - 1] = '\0';
}

int
mangle_name(const char *name, char *dst, size_t sz)
{
	int r;
	
	r = snprintf(dst, sz, "%s", name);
	assert(r >= 0);
	assert((size_t)r < sz);
	replace_all(dst, sz, ":", "__c_");
	replace_all(dst, sz, "[", "__b_");
	replace_all(dst, sz, "]", "__B_");
	replace_all(dst, sz, " ", "__e_");
	replace_all(dst, sz, ",", "__s_");

	return strlen(dst);
}

int
demangle_name(const char *name, char *dst, size_t sz)
{
	snprintf(dst, sz, "%s", name);
	replace_all(dst, sz, "__c_", ":");
	replace_all(dst, sz, "__b_", "[");
	replace_all(dst, sz, "__B_", "]");
	replace_all(dst, sz, "__e_", " ");
	replace_all(dst, sz, "__s_", ",");

	return 0;
}
