Another useful string handling function

From: James Turner (turnerjh@XTN.NET)
Date: 04/23/98


Since the (oh-so-polite) request was made for another piece of my
code, I'm sending another in, one that has a similar use.  The
following is the basis for string substitution, similar to what act()
does.  You define the table, call renderString, and the result will
have substitutions made.  I currently use it as part of some custom
prompt code, as well as the format specifier for my clan talk code
(giving each clan their own way to form output, so they can include
ranks and subranks in appropriate ways).

Nore that renderString calls an ancillary function, findRenderOffset.
This function returns the offset in the given RENDER_TABLE for a
specific code.  Finally, included is an example of its usage.

struct render_table {
  char c;
  char *string;
  int sub;
};

typedef struct render_table RENDER_TABLE;

int
findRenderOffset(char c, RENDER_TABLE *rtab)
{
  int i;

  for (i = 0; rtab[i].c != 0; i++)
    if (c == rtab[i].c) return i;

  return -1;
}

void
renderString(char *dest, RENDER_TABLE *rtab, const char *s, char spec_char)
{
  int i;

  *dest = 0;

  while (*s) {
    *dest = *s;
    *(dest+1) = 0;

    if (*dest == spec_char) {
      s++;

      i = findRenderOffset(*s, rtab);

      if (i >= 0) {
        if (rtab[i].sub)
          strcpy(dest, rtab[i].string);
        else
          *dest = 0;
        s++;
        dest += strlen(dest);
      }
      else {
        dest++;
      }
    }
    else {
      dest++;
      s++;
    }
  }
  return;
}

/*
A note about the following.  itoa turns an integer into a string.
future modifications for render_table will perhaps include arbitrary
types, but for now, it only supports strings.  The use of multiple
static buffers in itoa is needed because otherwise, the multiple calls
will overwrite each other.  (An alternative would be to have itoa do
strdup's and have a cleanRendertable function).

The third parameter in the render_table structure is whether to
display a given string.  This allows for single tables for imms and
morts (in terms of prompts) so that morts can't see info they
shouldn't.  The entry can serve other functions as well.
*/

#define ITOA_NBUF 100

char *
itoa(int i)
{
  static char tbuf[ITOA_NBUF][MIL];
  static int n = -1;

  n = (n + 1) % ITOA_NBUF;

  snprintf(tbuf[n], MIL, "%d", i);
  tbuf[n][MIL-1] = 0;

  return tbuf[n];
}

const char default_prompt[] = "%i< %hH %sS > %a";

void
render_prompt(CHAR_DATA *ch, char *dest)
{
  RENDER_TABLE rtab[] = {
    {'n', GET_NAME(ch), 1},
    {'h', itoa(GET_HEALTH(ch)), 1},
    {'H', itoa(GET_MAX_HEALTH(ch)), 1},
    {'s', itoa(GET_STAMINA(ch)), 1},
    {'S', itoa(GET_MAX_STAMINA(ch)), 1},
    {'a', affectString(ch), 1},
    {'i', itoa(GET_INVIS_LEV(ch)), GET_INVIS_LEV(ch) > 0},
    {'f', "\r\n"},
    {'%', "%"},
    {'\0', NULL}
  };

  if (IS_NPC(ch)) {
    if (ch->desc && ch->desc->original)
      renderString(dest, rtab, getPrompt(ch->desc->original), '%');
    else
      renderString(dest, rtab, default_prompt, '%');
  }
  else
    renderString(dest, rtab, getPrompt(ch), '%');
}

--
James Turner               turnerjh@xtn.net
                           http://www.vuse.vanderbilt.edu/~turnerj1/


     +------------------------------------------------------------+
     | Ensure that you have read the CircleMUD Mailing List FAQ:  |
     | http://democracy.queensu.ca/~fletcher/Circle/list-faq.html |
     +------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/15/00 PST