Mercurial > ~dholland > hg > ag > index.cgi
diff helpgen/readhelp.syn @ 0:13d2b8934445
Import AnaGram (near-)release tree into Mercurial.
author | David A. Holland |
---|---|
date | Sat, 22 Dec 2007 17:52:45 -0500 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/helpgen/readhelp.syn Sat Dec 22 17:52:45 2007 -0500 @@ -0,0 +1,226 @@ +{ +/* + * AnaGram, a System for Syntax Directed Programming + * Copyright 1993 Parsifal Software. All Rights Reserved. + * Copyright 2006 David A. Holland. All Rights Reserved. + * See the file COPYING for license and usage terms. + * + * readhelp.syn - Toplevel syntax for help source file. + */ +#include <sys/types.h> +#include <sys/stat.h> +#include <assert.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "utils.h" +#include "topic.h" +#include "helpgen.h" +} + +[ + pointer input + pointer type = unsigned char * + context type = unsigned char * + default token type = void + line numbers +] + +left = 169 +right = 170 +quote = '\'' + +range = 0..255 +eof = 0 +tab = '\t' +nl = '\n' +cr = '\r' +blank = ' ' + tab +text = ~eof & ~cr & ~nl + +(int) letter + -> text & ~blank & ~',' & ~(left + right):c = c; + +(void) blanks + -> blank + -> blanks, blank + +(void) eol + -> ["//", text...], cr?, nl + +(void) new line + -> cr?, nl + +(void) continue + -> blanks?, [eol, blanks?] + +(void) name + -> letter:c = startstr(), addstr(c); + -> name, letter:c = addstr(c); + -> name, blanks, letter:c = addstr(' '), addstr(c); + +(const char *) title + -> name, blanks? = getstr(); + +(void) titles + -> title:t = topic_addtitle(curtopic, t); + -> titles, ',', continue, title:t = topic_addtitle(curtopic, t); + +(long) text lines + -> text unit..., new line = CONTEXT - inputdata; + -> text lines, text unit..., new line + +(void) text unit +// -> text - (left + right + quote) +// -> quote, ~eof + -> text - (left + right) + -> cross reference + +(void) cross reference + -> cross reference text, blanks?, right = see_xref(getstr()); + +(void) cross reference text + -> left = startstr(); + -> cross reference text, letter:c = addstr(c); + -> cross reference text, blanks, letter:c = addstr(' '), addstr(c); + -> cross reference text, blanks?, cr?, nl = addstr(' '); + +(long) block body + -> text lines + -> block body, blank lines, text lines + +(long) blank lines + -> new line = CONTEXT - inputdata; + -> blank lines, new line + +(long) end block + -> blank lines, "##" + -> "##" = CONTEXT - inputdata; + +(void) block + -> !{ startblock(); }, titles, eol, real block body = endblock(); + +(void) real block body + -> blank lines?, block body:bb, end block:be = block(bb,be); + -> end block = block(0,0); + +(void) file $ + -> blocks, eof + +(void) blocks + -> + -> blocks, blanks?, eol + -> blocks, block + +//////////////////////////////////////////////////////////// +// +// string buffer + +{ +static char string_space[4096]; +static size_t string_pos; + +static void startstr(void) { + string_pos = 0; +} + +static void addstr(int ch) { + if (string_pos >= sizeof(string_space)-1) { + fprintf(stderr, "String buffer overflow - make string_space larger\n"); + exit(1); + } + string_space[string_pos++] = ch; +} + +static const char *getstr(void) { + string_space[string_pos] = 0; + return string_space; +} +} + +//////////////////////////////////////////////////////////// +// +// current topic +{ +static struct topic *curtopic; + +static void startblock(void) { + assert(curtopic == NULL); + curtopic = topic_create(); +} + +static void endblock(void) { + help_addtopic(curtopic); + curtopic = NULL; +} + +static void see_xref(const char *ref) { + topic_addref(curtopic, ref); +} + +} + +//////////////////////////////////////////////////////////// +// +// pointer input support +{ + +#define GET_CONTEXT CONTEXT = PCB.pointer + +static unsigned char *inputdata; + +static void block(long head, long tail) { + long length = tail - head; + assert(length >= 0); + if (length > 0) { + topic_setbody(curtopic, (const char *)(inputdata+head), length); + } +} + +static off_t getlength(int fd) { + struct stat st; + if (fstat(fd, &st) < 0) { + fprintf(stderr, "fstat failed: %s", strerror(errno)); + exit(1); + } + return st.st_size; +} + +void load(const char *path) { + char *buf; + off_t len; + int fd, r; + + fd = open(path, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "%s: %s\n", path, strerror(errno)); + exit(1); + } + + len = getlength(fd); + buf = domalloc(len+1); + r = read(fd, buf, len); + if (r < 0) { + fprintf(stderr, "%s: read: %s\n", path, strerror(errno)); + exit(1); + } + if (r < len) { + fprintf(stderr, "%s: read: short count %d of %ld\n", path, r, (long) len); + exit(1); + } + buf[r] = 0; + close(fd); + + inputdata = (unsigned char *) buf; + PCB.pointer = inputdata; + readhelp(); + inputdata = NULL; + free(buf); +} + +} +