~aleteoryx/9c

9795eaaacde6cf788660eced4df90738d6681f01 — glenda 13 days ago b70954c
basics of something new
3 files changed, 343 insertions(+), 3 deletions(-)

M mkfile
M queuesrv.c
A ufx2font.c
M mkfile => mkfile +2 -1
@@ 5,7 5,8 @@ bins=\
	maze\
	spiral\
	queuesrv\
	pres 
	pres\
	ufx2font

all:VQ: $bins


M queuesrv.c => queuesrv.c +4 -2
@@ 39,7 39,7 @@ char *ctlbuf;
void
usage(void)
{
	fprint(2,"usage: queuefs [ -Ds ] [ -n maxname ] [ service ]\n");
	fprint(2,"usage: queuesrv [ -Ds ] [ -n maxname ] [ service ]\n");
	exits("usage");
}



@@ 174,8 174,10 @@ delqueue(QueueDesc* qd)
	queue = file->aux;

	for(i = 0; i < queue->length && queue->members[i] == nil; i++);

	removefile(file);

	if(i == queue->length){
		removefile(file);
		free(queue);
	}else
		queue->state = QDeleted;

A ufx2font.c => ufx2font.c +337 -0
@@ 0,0 1,337 @@
#include <u.h>
#include <libc.h>
#include <bio.h>


/* entry has 1 byte in widtab + 8 bytes per tile */
#define ufxlen(n) (1 + ((n)*(n)*8))


enum{
	MR_BLANK,
	MR_SINGLE,
	MR_RANGE
};
struct MapRule{
	struct MapRule *next;

	uchar ty;
	uint start, end;
};
struct Mapping{
	struct Mapping *next;

	uint linum;

	Rune start;
	union {Rune end; uint idx;};
	struct MapRule *rules;
};
struct MapFile{
	struct MapFile *next;

	char *file;

	struct Mapping *mappings;
};


uint fwidth, nglyphs;

uchar setconv, donaive, doholes;
struct MapFile *mapfiles, *lastmf;

uchar wasmferr, wasreaderr;


void
bioerr(char *s)
{
	wasreaderr = 1;
	wasmferr = 1;
	fprint(2, "%s: %s\n", argv0, s);
}
char *
readtoken(Biobuf *b, char **line, uint *linum)
{
	char *ret, *p;

	while(*line != nil){
		p = *line;
		while(p[0] != '\0' && strchr("\t\r ", p[0]) != nil)
			p++;

		if(strchr("#;\n", p[0]) != nil){
			*line = Brdline(b, '\n');
			(*linum)++;
			continue;
		}
		ret = p;

		while(strchr("\t\r\n ", p[0]) == nil)
			p++;

		*line = p;
		if(p[0] != '\n')
			(*line)++;
		p[0] = '\0';

		return ret;
	}

	return nil;
}
#pragma varargck argpos mferr 3
void
mferr(char *file, uint linum, char *fmt, ...)
{
	char buf[1024];
	va_list va;

	va_start(va, fmt);
	vsnprint(buf, sizeof(buf), fmt, va);
	va_end(va);
	if(linum != 0)
		fprint(2, "%s: %s:%ud: %s\n", argv0, file, linum, buf);
	else
		fprint(2, "%s: %s: %s\n", argv0, file, buf);

	wasmferr = 1;
}
void
_parsemapfile(Biobuf *b, struct MapFile *mf)
{
	char *line, *tok, *p;
	uint linum = 1;
	struct Mapping *mlast = nil;
	struct MapRule *rlast;

	wasreaderr = 0;
	line = Brdline(b, '\n');
	if(line == nil){
		if(!wasreaderr)
			fprint(2, "%s: warn: %s: empty file\n", argv0, mf->file);
		return;
	}

	tok = readtoken(b, &line, &linum);
	while(tok != nil){
		if(strcmp(tok, "mapping") == 0){
			if(mlast == nil)
				mf->mappings = mlast = malloc(sizeof(struct Mapping));
			else
				mlast = mlast->next = malloc(sizeof(struct Mapping));

			mlast->linum = linum;
			mlast->rules = nil;
			mlast->next = nil;

			tok = readtoken(b, &line, &linum);
			if(tok == nil){
				mferr(mf->file, linum, "unexpected eof");
				return;
			}

			mlast->start = strtoul(tok, &p, 0);
			if(tok == p){
				mferr(mf->file, linum, "empty lower rune bound");
				return;
			}
			tok = p;

			if(tok[0] == '\0'){	/* 1:1 mapping */
				tok = readtoken(b, &line, &linum);
				if(tok == nil){
					mferr(mf->file, linum, "unexpected eof");
					return;
				}
				mlast->idx = strtoul(tok, &p, 0);
				
				if(tok == p || p[0] != '\0'){
					mferr(mf->file, linum, "bad glyph index");
					return;
				}

				tok = readtoken(b, &line, &linum);
				continue;
			}else if(tok[0] != '-'){
				mferr(mf->file, linum, "bad rune range");
				return;
			}
			tok++;

			/* many:many mapping */
			mlast->end = strtoul(tok, &p, 0);
			if(tok == p){
				mferr(mf->file, linum, "empty upper rune bound");
				return;
			}else if(p[0] != '\0'){
				mferr(mf->file, linum, "bad upper rune bound");
				return;
			}

			rlast = nil;
			while((tok = readtoken(b, &line, &linum)) != nil){
				if(rlast == nil)
					mlast->rules = rlast = malloc(sizeof(struct MapRule));
				else
					rlast = rlast->next = malloc(sizeof(struct MapRule));

				rlast->next = nil;

				if(strcmp(tok, "blank") == 0){
					rlast->ty = MR_BLANK;
					continue;
				}else if(tok[0] == '-'){	/* e.g. -0x4f */
					tok++;
					rlast->ty = MR_RANGE;
					rlast->start = 0;
					rlast->end = strtoul(tok, &p, 0);
					if(tok == p || p[0] != '\0'){
						mferr(mf->file, linum, "bad upper glyph bound");
						return;
					}
					continue;
				}

				rlast->start = strtoul(tok, &p, 0);
				if(tok == p)
					break;	/* return to toplevel parser */
				else if(p[0] == '\0'){
					rlast->ty = MR_SINGLE;
					continue;
				}else if(p[0] != '-'){
					mferr(mf->file, linum, "bad lower glyph bound");
					return;
				}

				rlast->ty = MR_RANGE;

				tok = p+1;
				if(tok[0] == '\0'){	/* e.g. 0x80- */
					rlast->end = nglyphs - 1;
					continue;
				}
				rlast->end = strtoul(tok, &p, 0);
				if(tok == p || p[0] != '\0'){
					mferr(mf->file, linum, "bad upper glyph bound");
					return;
				}
			} /* end while */

			if(rlast == nil){
				mferr(mf->file, linum, "unexpected eof");
				return;
			}
		}else{
			mferr(mf->file, linum, "unknown verb %s", tok);
			return;
		}
	} /* end while */
}
void
parsemapfile(struct MapFile *mf)
{
	Biobuf *b;

	b = Bopen(mf->file, OREAD);
	if(b == nil){
		fprint(2, "%s: %r\n", argv0);
		wasmferr = 1;
		return;
	}
	Blethal(b, bioerr);

	_parsemapfile(b, mf);

	Bterm(b);
}
void
printmapfile(struct MapFile *mf)
{
	struct Mapping *mp;
	struct MapRule *rp;

	print("mapfile: %s\n", mf->file);

	for(mp = mf->mappings; mp != nil; mp = mp->next){
		if(mp->rules == nil)
			print("\t%ud: %ux => %ux\n", mp->linum, mp->start, mp->idx);
		else{
			print("\t%ud: %ux - %ux =>\n", mp->linum, mp->start, mp->end);
			for(rp = mp->rules; rp != nil; rp = rp->next){
				switch(rp->ty){
				case MR_SINGLE:
					print("\t\t%ux\n", rp->start);
					break;
				case MR_RANGE:
					print("\t\t%ux - %ux\n", rp->start, rp->end);
					break;
				case MR_BLANK:
					print("\t\tblank\n");
					break;
				}
			}
		}
	}
}


void
usage(void)
{
	fprint(2, "usage: %s [-nh] [-m mapfile] [-l length] [-x width] in.ufx out/\n", argv0);
	exits("usage");
}

void
main(int argc, char **argv)
{
	char *infile, *outdir;
	struct MapFile *mf;

	ARGBEGIN{
	case 'l':
		nglyphs = atoi(EARGF(usage()));
		break;
	case 'x':
		fwidth = atoi(EARGF(usage()));
		break;
	case 'n':
		setconv = 1;
		donaive = 1;
		break;
	case 'h':
		setconv = 1;
		doholes = 1;
		break;
	case 'm':
		setconv = 1;
		if(lastmf == nil)
			mapfiles = lastmf = malloc(sizeof(struct MapFile));
		else
			lastmf = lastmf->next = malloc(sizeof(struct MapFile));
		lastmf->file = EARGF(usage());
		lastmf->next = nil;
		lastmf->mappings = nil;
		break;
	default:
		usage();
	}ARGEND;
	
	if(argv0 == nil)
		argv0 = "ufx2font";

	if(argc != 2)
		usage();


	// TODO: calculate length etc etc

	for(mf = mapfiles; mf != nil; mf = mf->next)
		parsemapfile(mf);
	if(wasmferr)
		exits("mapfile");
	for(mf = mapfiles; mf != nil; mf = mf->next)
		printmapfile(mf);
}