view anagram/guisupport/help.cpp @ 15:f5acaf0c8a29

Don't cast through "volatile int". Causes a gcc warning nowadays. XXX: should put something else back here to frighten the optimizer
author David A. Holland
date Tue, 31 May 2022 01:00:55 -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];
}