shithub: fnt

ref: 207f8c591b3e831f4a35185b99482cfb34fccf4b
dir: /test.c/

View raw version
#include <u.h>
#include <libc.h>
#include <bio.h>

typedef struct Ctx Ctx;
typedef struct Range Range;

struct Ctx {
	Biobuf *f;
	Range *r;
	u8int *buf;
	int bufsz;
	int off;
};

struct Range {
	int start;
	int len;
	int prevoff;
	Range *par;
};

int
ctxpushrange(Ctx *ctx, int off, int len)
{
	Range *r;
	int x;

	r = nil;
	if(ctx->r != nil){
		if(off+len > ctx->r->len){
			werrstr("range overflow by %d bytes", off+len - ctx->r->len);
			goto err;
		}
		off += ctx->r->start;
	}
	if((r = malloc(sizeof(*r))) == nil){
		werrstr("no memory");
		goto err;
	}
	r->par = ctx->r;
	r->start = off;
	r->len = len;
	r->prevoff = ctx->off;
	if((x = Bseek(ctx->f, off, 0)) != off){
		werrstr("seek offset: need %d, got %d", off, x);
		goto err;
	}
	ctx->off = off;
	ctx->r = r;
	return 0;
err:
	free(r);
	werrstr("ctxpushrange: %r");
	return -1;
}

int
ctxpoprange(Ctx *ctx)
{
	Range *r;
	int x;

	r = ctx->r;
	if(r == nil){
		werrstr("pop without push");
		goto err;
	}
	if((x = Bseek(ctx->f, r->prevoff, 0)) != r->prevoff){
		werrstr("seek offset: need %d, got %d", r->prevoff, x);
		goto err;
	}
	ctx->off = r->prevoff;
	ctx->r = r->par;
	free(r);
	return 0;
err:
	werrstr("ctxpoprange: %r");
	return -1;
}

u8int *
ctxreadn(Ctx *ctx, int n)
{
	Range *r;
	u8int *b;
	int x;

	r = ctx->r;
	if(r != nil && ctx->off+n > r->start+r->len){
		werrstr("short read: need %d at %d, have %d at %d", n, ctx->off, r->len, r->start);
		goto err;
	}
	if(n > ctx->bufsz){
		if((b = realloc(ctx->buf, n)) == nil){
			werrstr("no memory");
			goto err;
		}
		ctx->buf = b;
		ctx->bufsz = n;
	}
	if((x = Bread(ctx->f, ctx->buf, n)) != n){
		werrstr("short read: need %d, got %d; off %d", n, x, ctx->off);
		goto err;
	}
	ctx->off += n;

	return ctx->buf;
err:
	werrstr("ctxreadn: %r");
	return nil;
}

int
ctxarray(Ctx *ctx, void **arr_, void *fun_, int elsz, int num)
{
	int i;
	int (*fun)(Ctx*, void*);
	u8int *arr;

	if((arr = calloc(num, elsz)) == nil){
		werrstr("no memory");
		goto err;
	}
	fun = fun_;
	for(i = 0; i < num; i++){
		if(fun(ctx, arr + i*elsz) < 0)
			goto err;
	}
	*arr_ = arr;
	return 0;
err:
	free(arr);
	werrstr("ctxarray: %r");
	return -1;
}

#include "out.h"

void
main(int argc, char **argv)
{
	TableDirectory td;
	Biobuf *out;
	Ctx ctx;
	int i;

	otfinit();
	out = Bfdopen(1, OWRITE);
	for(i = 1; i < argc; i++){
		Bprint(out, "%s\n", argv[i]);
		if((ctx.f = Bopen(argv[i], OREAD)) == nil){
			fprint(2, "%r\n");
		}else if(read_TableDirectory(&ctx, &td) != 0){
			fprint(2, "%s: %r\n", argv[i]);
		} else {
			print_TableDirectory(out, 0, &td);
		}
		if(ctx.f != nil)
			Bterm(ctx.f);
	}
	Bterm(out);

	exits(nil);
}