I finally got back to this.  It's pretty a small thing, but makes
lining up certain screens a lot easier (e.g. "olist all" with colored
objects).  The only problem I've found is running gcc with -Wall turns
on -Wformat, which I like, except gcc complains about the new %T
conversion type being unknown.  I can't figure out any way to register
a new conversion type with the compiler.  Anyway...

  printf("-%10.5s-\n", "{Rtesting");
  printf("-%10.5T-\n", "{Rtesting");

Results in:

-     {Rtes-
-     {Rtesti-

So when the color codes go invisible, the truncation and padding are
right using %T instead of %s.  I also decided to use the + flag to
capitalize the first character of the argument.  May add some other
niceties later.  Here's the code so far:

#include <stdio.h>
#include <printf.h>

int printf_coloured_string(FILE *stream, const struct printf_info
*info, const void *const *args)
{
  int length = 0, padding = 0, out = 0;
  const char *src = *((const char **)(*args));
  //see how long the string is
  for (out = 0; src[out]; out++)
  {
    if (src[out] == '{')
      out++;
    else
      length++;
  }
  //check for truncation
  if ((info->prec >= 0) && (length > info->prec))
    length = info->prec;
  //calculate padding
  padding = (info->width - length);
  //figure out how much of the string to write out
  for (out = 0; length > 0 || src[out] == '{'; out++)
  {
    if (src[out] == '{')
      out++;
    else
      length--;
  }
  //left padding
  if (!info->left)
    for (length = 0; padding > length; length++)
      fputc(' ', stream);
  //capitalization
  if (info->showsign)
  {
    for (length = 0; (length < out) && src[length] == '{'; length += 2)
      ;
    fwrite(src, length, 1, stream);
    fputc(toupper(src[length]), stream);
    fwrite(&src[length+1], out - (length + 1), 1, stream);
  }
  //no capitalization
  else
    fwrite(src, out, 1, stream);
  // right padding
  if (info->left)
    for (length = 0; padding > length; length++)
      fputc(' ', stream);
  return padding + out;
}

int printf_coloured_string_arginfo(const struct printf_info *info,
size_t n, int *argtypes)
{
  if (n > 0)
    argtypes[0] = PA_STRING;
  return 1;
}

void init_printf_ext()
{
  register_printf_function('T', &printf_coloured_string,
&printf_coloured_string_arginfo);
}

--Palrich.

On 9/12/05, Dennis <[EMAIL PROTECTED]> wrote:
> If you're using GNU libc, you can extend the printf family of functions
> with your own % codes.  That could save you some work by not having
> to re-implement the existing *printf functionality.
>
> http://www.gnu.org/software/libc/manual/html_node/Customizing-Printf.html
>
>
> Dennis
>
>
> On Mon, 12 Sep 2005, Michael Barton wrote:
>
> > I was wanting to re-implement vs(n)printf to correctly pad and
> > truncate strings with Lope's color codes in them, since lining things
> > up can be such a pain.  I thought to get the bsd version and work from
> > that, but it's... verbose.  I'm sure it has to be.
> >
> > I started on my own and, ugly and incomplete though it is, seems to be
> > a working start.
> >
> > I'd also like to include % codes for CHAR_DATA, OBJ_DATA, etc, so I
> > can effectively replace act() with chprintf() entirely while I'm at
> > it.
> >
> > Has anyone else tackled this?
> >
> > --Palrich.
> > --
> > ROM mailing list
> > [EMAIL PROTECTED]
> > Unsubscribe here ->>> http://www.rom.org/cgi-bin/mailman/listinfo/rom
> >
>
--
ROM mailing list
[EMAIL PROTECTED]
Unsubscribe here ->>> http://www.rom.org/cgi-bin/mailman/listinfo/rom

Reply via email to