view helpgen/readhelp.syn @ 21:1c9dac05d040

Add lint-style FALLTHROUGH annotations to fallthrough cases. (in the parse engine and thus the output code) Document this, because the old output causes warnings with gcc10.
author David A. Holland
date Mon, 13 Jun 2022 00:04:38 -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);
}

}