~aleteoryx/9c

4e44d053e0bc1de0fd9043d024d0952328d7cbc7 — glenda 10 months ago 2b71a3c
becoming a supervillain
2 files changed, 173 insertions(+), 1 deletions(-)

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

all:VQ: $bins


A pres.c => pres.c +171 -0
@@ 0,0 1,171 @@
#include <u.h>
#include <libc.h>
#include <stdio.h>
#include <draw.h>
#include <event.h>
#include <cursor.h>

int checkonly;
char *file, *contents;

typedef struct Slide {
	char *cmd;
	char *arg;
	int nlines;
	char *lines[];
} Slide;

char *
nextline(char **p)
{
	char *line;
	while(1){
		line = *p;
		while(**p != '\n' && **p != '\0') (*p)++;
		if(**p == '\0')
			return nil;

		**p = '\0';
		(*p)++;
		return line;
	}
}

Slide *
nextslide(char **p)
{
	char *cmd, *arg, *line1, *line, *lineN;
	int nlines, blines, i;
	Slide *s;

	while(1){
		if((cmd = nextline(p)) == nil)
			return nil;
		if(cmd[0] != '%')
			continue;
		break;
	}

	cmd++;
	arg = cmd;

	while(*arg != ' ' && *arg != '\t' && *arg != '\0') arg++;
	if(*arg == '\0')
		arg = nil;
	else
		*(arg++) = '\0';

	line1 = nextline(p);
	if(line1 != nil && *line1 == '%'){
		*p = line1;
		line1[strlen(line1)] = '\n';
		line1 = nil;
	}
	if(line1 == nil){
		s = malloc(sizeof(Slide));
		s->cmd = cmd;
		s->arg = arg;
		s->nlines = 0;
		return s;
	}
	lineN = line1;
	nlines = 1;
	blines = 0;

	while((line = nextline(p)) != nil){
		if(*line == '\0'){
			blines++;
			continue;
		}
		if(*line == '%'){
			*p = line;
			line[strlen(line)] = '\n';
			break;
		}

		nlines += blines;
		blines = 0;
		nlines++;
		lineN = line;
	}

	s = malloc(sizeof(Slide) + sizeof(char*) * nlines);

	s->cmd = cmd;
	s->arg = arg;
	s->nlines = nlines;

	line = line1;
	for(i = 0; line != lineN; i++){
		s->lines[i] = line;
		line += strlen(line) + 1;
	}
	s->lines[i] = lineN;

	return s;
}

void
checkfile(void)
{
	int i;
	char *c2, *p;
	Slide *s;

	c2 = strdup(contents);
	p = c2;

	while((s = nextslide(&p)) != nil){
		print("Slide: %s (%d lines)\n", s->cmd, s->nlines);
		if(s->arg != nil)
			print("\targ: %s\n", s->arg);
		for(i = 0; i < s->nlines; i++)
			print("\tline %d: %s\n", i, s->lines[i]);
	}
}

void
usage(void)
{
	fprint(2,"usage: %s [ -c ] filename\n", argv0);
	exits("usage");
}

void
main(int argc, char *argv[])
{
	int fd;
	Dir *d;

	ARGBEGIN{
	case 'c':
		checkonly = 1;
		break;
	default:
		usage();
	}ARGEND

	if(argc != 1)
		usage();

	file = argv[0];

	if((fd = open(file, OREAD)) < 0)
		sysfatal("%r");
	if((d = dirfstat(fd)) == nil)
		sysfatal("%r");

	contents = malloc(d->length + 2);
	if(readn(fd, contents, d->length) < 0)
		sysfatal("%r");
	// cursed but makes the handling nicer above
	contents[d->length] = '\n';
	contents[d->length + 1] = '\0';
	free(d);
	close(fd);

	checkfile();

	if(checkonly)
		exits(nil);
}