/*
 * libc.h - Component or module libraries
 *
 * Copyright 2012 by Werner Almesberger
 *
 * 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.
 */

#define	_GNU_SOURCE /* for strcasecmp */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <assert.h>

#include "util.h"
#include "libs.h"


const struct entry *lookup_sym(const struct lib *lib, const char *name)
{
	const struct file *file;
	const struct entry *e;

	for (file = lib->files; file; file = file->next)
		for (e = file->entries; e; e = e->next)
			if (!strcasecmp(e->names->s, name))
				return e;
	return NULL;
}


void add_name(struct entry *e, char *s)
{
	char *nl;
	struct name **p;

	nl = strchr(s, '\n');
	if (nl)
		*nl = 0;
	for (p = &e->names; *p; p = &(*p)->next);
	*p = alloc_type(struct name);
	(*p)->s = stralloc(s);
	(*p)->next = NULL;
}


struct entry *new_entry(struct lib *lib, int units)
{
	struct entry *e;

	e = alloc_type(struct entry);	
	e->names = NULL;
	e->units = units;
	e->file = lib->files;
	e->next = lib->files->entries;
	lib->files->entries = e;
	return e;
}


void add_lib(struct lib *lib, const char *path)
{
	struct file *file;

	file = alloc_type(struct file);
	file->path = stralloc(path);
	file->entries = NULL;
	file->lib = lib;
	file->next = lib->files;
	lib->files = file;

	lib->add_lib(lib, path);
}


void add_libdir(struct lib *lib, const char *path)
{
	DIR *dir;
	const struct dirent *de;
	size_t len;
	char *tmp;

	assert(strlen(lib->ext) == 4);
	dir = opendir(path);
	if (!dir) {
		perror(path);
		exit(1);
	}
	while (1) {
		de = readdir(dir);
		if (!de)
			break;
		if (strchr(de->d_name, '~'))
			continue;
		len = strlen(de->d_name);
		if (len < 4)
			continue;
		if (strcmp(de->d_name+len-4, lib->ext))
			continue;
		if (asprintf(&tmp, "%s/%s", path, de->d_name) < 0) {
			perror("asprintf");
			exit(1);
		}
		add_lib(lib, tmp);
	}
	closedir(dir);
}