view files.c @ 13:120629a5d6bf

seenfile -> placefile (clearer)
author David A. Holland
date Sun, 19 Dec 2010 19:49:43 -0500
parents 800f3a560a3b
children f6177d3ed5c2
line wrap: on
line source

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <err.h>

#include "array.h"
#include "place.h"
#include "files.h"

struct incdir {
	const char *name;
	bool issystem;
};

DECLARRAY(incdir);
DEFARRAY(incdir, );

static struct incdirarray quotepath, bracketpath;

////////////////////////////////////////////////////////////
// management

static
struct incdir *
incdir_create(const char *name, bool issystem)
{
	struct incdir *id;

	id = domalloc(sizeof(*id));
	id->name = name;
	id->issystem = issystem;
	return id;
}

static
void
incdir_destroy(struct incdir *id)
{
	free(id);
}

void
files_init(void)
{
	incdirarray_init(&quotepath);
	incdirarray_init(&bracketpath);
}

DESTROYALL_ARRAY(incdir, );

void
files_cleanup(void)
{
	incdirarray_destroyall(&quotepath);
	incdirarray_cleanup(&quotepath);
	incdirarray_destroyall(&bracketpath);
	incdirarray_cleanup(&bracketpath);
}

////////////////////////////////////////////////////////////
// path setup

void
files_addquotepath(const char *dir, bool issystem)
{
	struct incdir *id;

	id = incdir_create(dir, issystem);
	incdirarray_add(&quotepath, id, NULL);
}

void
files_addbracketpath(const char *dir, bool issystem)
{
	struct incdir *id;

	id = incdir_create(dir, issystem);
	incdirarray_add(&bracketpath, id, NULL);
}

////////////////////////////////////////////////////////////
// parsing

void
file_read(const struct placefile *pf, int fd);

////////////////////////////////////////////////////////////
// path search

static
char *
mkfilename(const char *dir, const char *file)
{
	size_t dlen, flen, rlen;
	char *ret;
	bool needslash = false;

	dlen = strlen(dir);
	flen = strlen(file);
	if (dlen > 0 && dir[dlen-1] != '/') {
		needslash = true;
	}

	rlen = dlen + (needslash ? 1 : 0) + flen;
	ret = domalloc(rlen + 1);
	strcpy(ret, dir);
	if (needslash) {
		strcat(ret, "/");
	}
	strcat(ret, file);
	return ret;
}

static
int
file_tryopen(const char *file)
{
	int fd;

	fd = open(file, O_RDONLY);
	if (fd < 0) {
		return -1;
	}
	/* XXX: do we need to do anything here or is this function pointless?*/
	return fd;
}

static
void
file_search(struct place *place, struct incdirarray *path, const char *name)
{
	unsigned i, num;
	struct incdir *id;
	const struct placefile *pf;
	char *file;
	int fd;

	assert(place != NULL);

	num = incdirarray_num(path);
	for (i=0; i<num; i++) {
		id = incdirarray_get(path, i);
		file = mkfilename(id->name, name);
		fd = file_tryopen(file);
		if (fd >= 0) {
			pf = place_addfile(place, file, id->issystem);
			free(file);
			file_read(pf, fd);
			close(fd);
			return;
		}
		free(file);
	}
	complain(place, "Include file %s not found", name);
	complain_fail();
}

void
file_readquote(struct place *place, const char *name)
{
	file_search(place, &quotepath, name);
}

void
file_readbracket(struct place *place, const char *name)
{
	file_search(place, &bracketpath, name);
}

void
file_readabsolute(struct place *place, const char *name)
{
	const struct placefile *pf;
	int fd;

	assert(place != NULL);

	fd = file_tryopen(name);
	if (fd < 0) {
		warn("%s", name);
		die();
	}
	pf = place_addfile(place, name, false);
	file_read(pf, fd);
	close(fd);
}