#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);
}