view place.c @ 12:6c15ca895585

improve places more
author David A. Holland
date Sun, 19 Dec 2010 19:39:26 -0500
parents b9d50e786322
children 120629a5d6bf
line wrap: on
line source

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

#include "utils.h"
#include "array.h"
#include "place.h"

#define NOWHERE_LINE      0
#define BUILTIN_LINE      1
#define COMMANDLINE_LINE  2

struct seenfile {
	struct place includedfrom;
	char *name;
	bool fromsystemdir;
};
DECLARRAY(seenfile);
DEFARRAY(seenfile, );

static struct seenfilearray seenfiles;
static bool overall_failure;

////////////////////////////////////////////////////////////
// seenfiles

static
struct seenfile *
seenfile_create(const struct place *from, char *name, bool fromsystemdir)
{
	struct seenfile *sf;

	sf = domalloc(sizeof(*sf));
	sf->includedfrom = *from;
	sf->name = name;
	sf->fromsystemdir = fromsystemdir;
	return sf;
}

static
void
seenfile_destroy(struct seenfile *sf)
{
	free(sf->name);
	free(sf);
}

DESTROYALL_ARRAY(seenfile, );

struct seenfile *
place_seen_file(const struct place *place, char *file, bool issystem)
{
	struct seenfile *sf;

	sf = seenfile_create(place, file, issystem);
	seenfilearray_add(&seenfiles, sf, NULL);
	return sf;
}

////////////////////////////////////////////////////////////
// places

void
place_setnowhere(struct place *p)
{
	p->type = P_NOWHERE;
	p->file = NULL;
	p->line = 0;
	p->column = 0;
}

void
place_setbuiltin(struct place *p, unsigned num)
{
	p->type = P_BUILTIN;
	p->file = NULL;
	p->line = num;
	p->column = 1;
}

void
place_setcommandline(struct place *p, unsigned column)
{
	p->file = NULL;
	p->line = COMMANDLINE_LINE;
	p->column = column;
}

static
const char *
place_getname(const struct place *p)
{
	switch (p->type) {
	    case P_NOWHERE: return "<nowhere>";
	    case P_BUILTIN: return "<built-in>";
	    case P_COMMANDLINE: return "<command-line>";
	    case P_FILE: return p->file->name;
	}
	assert(0);
	return NULL;
}

static
void
place_printfrom(const struct place *p)
{
	const struct place *from;

	from = &p->file->includedfrom;
	if (from->type != P_NOWHERE) {
		place_printfrom(from);
		fprintf(stderr, "In file included from %s:%u:%u:\n",
			place_getname(from), from->line, from->column);
	}
}

////////////////////////////////////////////////////////////
// complaints

void
complain(const struct place *p, const char *fmt, ...)
{
	va_list ap;

	place_printfrom(p);
	fprintf(stderr, "%s:%u:%u: ", place_getname(p), p->line, p->column);
	va_start(ap, fmt);
	vfprintf(stderr, fmt, ap);
	va_end(ap);
	fprintf(stderr, "\n");
}

void
complain_fail(void)
{
	overall_failure = true;
}

bool
complain_failed(void)
{
	return overall_failure;
}

////////////////////////////////////////////////////////////
// module init and cleanup

void
place_init(void)
{
	seenfilearray_init(&seenfiles);
}

void
place_cleanup(void)
{
	seenfilearray_destroyall(&seenfiles);
	seenfilearray_cleanup(&seenfiles);
}