pgplus/bin/
pgplus/help_files/
pgplus/port_redirector/
pgplus/src/configure/makefiles/
/*
 * Playground+ - historee.c
 * History lib for creating, maintaining and cleaning dynamic
 *  history buffers... an excersise in pointer play (c) phypor 1998
 * ---------------------------------------------------------------------------
 *
 * Modifications to original release:
 *  Include paths
 *  commented out su history stufs, to be used as an example in creating others
 *  removed strcasestr func, as its found in xstring.c for pg+
 *  changed malloc to MALLOC and free to FREE
 *
 * Notes:
 *     to add a history to anything else, just give it
 *     a history * pointer, either in the struct for it
 *     or as a global var (depending on how you will need it),
 *     init_history to give it some memory,
 *     add items to it with the add_to_hist,
 *     use stack_hist as a possible method to retrieve the history,
 *     and free_hist when you are finished.
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

#include "include/config.h"
#include "include/player.h"
#include "include/proto.h"


history *init_hist(int max)
{
  history *nh;

  nh = (history *) MALLOC(sizeof(history));
  if (!nh)
  {
    log("error", "Failed to malloc history.");
    return (history *) NULL;
  }

  memset(nh, 0, sizeof(history));

  nh->hist = (char **) MALLOC((max + 1) * sizeof(char *));
  if (!nh->hist)
  {
    FREE(nh);
    log("error", "Failed to malloc history.");
    return (history *) NULL;
  }
  memset(nh->hist, 0, max * sizeof(char *));

  nh->max = max;
  return nh;
}


void add_to_hist(history * h, char *str)
{
  int i;

  if (!h)			/* malloc failed at some point... */
    return;

  for (i = 0; i < h->max; i++)	/* find the first free one */
    if (!h->hist[i])
      break;

  if (i == h->max)		/* if the handles are full */
  {
    FREE(h->hist[i - 1]);	/* get rid of the last one */
    h->hist[i - 1] = (char *) NULL;
  }

  for (i = h->max; i > 0; i--)	/* shift the handles down */
    h->hist[i] = h->hist[i - 1];

  /* malloc something to point to */
  h->hist[0] = (char *) MALLOC(strlen(str) + 1);

  if (!h->hist[0])		/* make sure we got it */
  {
    log("error", "Failed to malloc history");
    return;
  }
  /* clean it and put it in */
  memset(h->hist[0], 0, strlen(str) + 1);
  strcpy(h->hist[0], str);
}

int stack_hist(history * h, int lines, char *needle)
{
  int i;

  if (!h || !h->hist[0])
    return -1;

  for (i = 0; h->hist[i + 1]; i++);	/* get to the end to put the oldest top */

  if (lines > 0)
    i = i < lines ? i : lines - 1;	/* use the smallest */

  if (!needle || !*needle)
    for (; i >= 0; i--)
      stack += sprintf(stack, "%s", h->hist[i]);
  else
    for (; i >= 0; i--)
      if (strcasestr(h->hist[i], needle))
	stack += sprintf(stack, "%s", h->hist[i]);

  return 0;
}

void clean_hist(history * h)
{
  int i;

  if (!h || !h->hist)		/* make sure its got memory */
    return;

  for (i = 0; i < h->max; i++)
    if (h->hist[i])
    {
      FREE(h->hist[i]);
      h->hist[i] = (char *) NULL;
    }
}

void free_hist(history * h)
{
  clean_hist(h);
  FREE(h->hist);
  FREE(h);
}


void init_global_histories(void)
{
/* init any global histories here...such as 
   SuHistory = init_hist (HIST_SU);
 */

}




#ifdef EXAMPLES
  /* su history */
#define HIST_SU         50

history *SuHistory;


void zap_suhist(player * p, char *str)
{
  clean_hist(SuHistory);
  tell_player(p, " SuperUsers History zapped!\n");
}


void view_su_history(player * p, char *str)
{
  char *oldstack = stack, *needle = "";
  int lines = -1;

  if (*str && !strcmp(str, "?"))	/* use strcmp so ? can be first char of
					   pattern to be matched */
  {
    tell_player(p,
    " Format : suhist                to view the entire suhist, unabriged\n"
       "          suhist #              to view the mot recent # of lines\n"
		"          suhist <str>          to view all lines strcasestr'ing <str>\n"
		"          suhist ?              to view the format\n");
    return;
  }

  if (*str && isdigit(*str))
  {
    lines = atoi(str);
    if (lines < 2)
      lines = 2;
    stack += sprintf(stack, "--- SuperUsers History (last %d lines) ---\n",
		     lines);
  }
  else if (*str)
  {
    stack += sprintf(stack, "--- SuperUsers History (searching %s) ---\n",
		     str);
    needle = str;
  }
  else
    stack += sprintf(stack, "--- SuperUsers History --------------------\n")
      ;

  if (stack_hist(SuHistory, lines, needle) < 0)
  {
    tell_player(p, " SuperUsers History is empty.\n");
    stack = oldstack;
    return;
  }
  stack += sprintf(stack, "-------------------------------------------\n");
  stack = end_string(stack);
  tell_player(p, oldstack);
  stack = oldstack;
}

#endif /* EXAMPLES */