view anagram/guisupport/help.cpp @ 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 2006 David A. Holland. All Rights Reserved.
 * See the file COPYING for license and usage terms.
 *
 * help.cpp - help data.
 *
 * This file obsoletes the external AnaGram.hlp file found
 * in older versions of AnaGram.
 */

#include "port.h" // for OPTLINK

#include "agstring.h"
#include "assert.h"
#include "help.h"

//#define INCLUDE_LOGGING
#include "log.h"


#include "helpdata.h"


static const HelpTopic empty_topic = {
  "Secret of Life",
  "No help message for this topic."
};

const char *helptopic_gettitle(const HelpTopic *ht) {
  return ht->title;
}

const char *helptopic_gettext(const HelpTopic *ht) {
  return ht->body;
}

////////////////////////////////////////////////////////////

static int OPTLINK helptable_sort(const void *ventrya, const void *ventryb) {
  const helpentry *entrya = (const helpentry *)ventrya;
  const helpentry *entryb = (const helpentry *)ventryb;
  return stricmp(entrya->topic, entryb->topic);
}

static int OPTLINK helptable_search(const void *vkey, const void *ventryb) {
  const char *key = (const char *)vkey;
  const helpentry *entryb = (const helpentry *)ventryb;
  return stricmp(key, entryb->topic);
}

static int OPTLINK topiclist_sort(const void *ventrya, const void *ventryb) {
  const char *const *entrya = (const char *const *)ventrya;
  const char *const *entryb = (const char *const *)ventryb;
  return stricmp(*entrya, *entryb);
}

void help_init(void) {
  LOGSECTION("help_init");
  qsort(helptable, helptablenum, sizeof(helptable[0]), helptable_sort);
  qsort(topiclist, numtopiclist, sizeof(topiclist[0]), topiclist_sort);
}

static const HelpTopic *try_help_topic(const char *topic) {
  LOGSECTION("help_get");
  const void *ventry;
  const helpentry *entry;
  ventry = bsearch(topic, helptable, helptablenum, sizeof(helptable[0]),
		   helptable_search);
  if (!ventry) {
    //fprintf(stderr, "warning: help topic <%s> not found\n", topic);
    return NULL;
  }
  entry = (const helpentry *)ventry;
  return entry->data;
}

////////////////////////////////////////////////////////////

const HelpTopic *help_topic(const char *title) {
  const HelpTopic *ht;

  ht = try_help_topic(title);
  if (ht) {
    return ht;
  }

  AgString titlecopy = title;
  size_t len = titlecopy.size();
  if (len > 0 && titlecopy[len-1] == 's') {
    titlecopy[len-1] = 0;
    ht = try_help_topic(titlecopy.pointer());
    if (ht) {
      return ht;
    }
  }

  // The old help code used to do this. But the new help compiler
  // checks crossreferences (up to trailing 's') so it can't be
  // triggered.
#if 0
  char *t = titlecopy.pointer();
  while (len) {
    while (len && t[len] != ' ') len--;
    while (len && (t[len] == ' ' || ispunct(t[len]))) len--;
    t[len+1] = 0;
    ht = try_help_topic(t);
    if (ht) {
      return ht;
    }
  }
#endif

  return &empty_topic;
}

int help_topicexists(const char *title) {
  // This is *not* supposed to check alternate spellings.
  const HelpTopic *ht = try_help_topic(title);
  return ht != NULL;
}

unsigned helpindex_num(void) {
  return numtopiclist;
}

const char *helpindex_get(unsigned ix) {
  assert(ix < numtopiclist);
  return topiclist[ix];
}