view helpgen/readhelp.syn @ 4:bebb2ba69e1d

maybe help with getting tex to fail properly on error
author David A. Holland
date Sat, 18 Apr 2020 17:12:17 -0400
parents 13d2b8934445
children
line wrap: on
line source

{
/*
 * 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);
}

}