/* ,file-id archive://[lord]/386/vu/./fmt.c/1998-05-18
*/
/*	Copyright (C) 1997 Tom Lord
 * 
 * This program is provided to you under the terms of the Liberty Software
 * License.  You are NOT permitted to redistribute, modify, or use it
 * except in very specific ways described by that license.
 *
 * This software comes with NO WARRANTY.
 * 
 * You should have received a copy of the Liberty Software License
 * along with this software; see the file =LICENSE.  If not, write to
 * the Tom Lord, 1810 Francisco St. #2, Berkeley CA, 94703, USA.  
 */



#include <errno.h>
#include "fmt.h"



int
fmt_uhex (int * errn, char * str, int size, unsigned long val)
{
  char buf[2 * sizeof (unsigned long)];
  int w;
  int x;

  w = 0;
  do
    {
      int nib;

      nib = (val & 0xf);

      if (nib < 10)
	buf[w] = nib + '0';
      else
	buf[w] = nib - 10 + 'a';

      val >>= 4;
      ++w;
    }
  while (val);

  if (w + 1 > size)
    {
      *errn = ERANGE;
      return -1;
    }

  x = w;
  while (x)
    {
      --x;
      *str = buf[x];
      ++str;
    }
  *str = 0;
  return w;
}

int
fmt_uint (int * errn, char * str, int size, unsigned long val)
{
  char buf[3 * sizeof (long)];
  int w;
  int x;

  w = 0;
  do
    {
      int nib;

      nib = (val % 10);
      buf[w] = nib + '0';
      val /= 10;
      ++w;
    }
  while (val);
  if (w + 1 > size)
    {
      *errn = ERANGE;
      return -1;
    }

  x = w;
  while (x)
    {
      --x;
      *str = buf[x];
      ++str;
    }
  *str = 0;
  return w;
}

int
fmt_int (int * errn, char * str, int size, int val)
{
  if (val >= 0)
    return fmt_uint (errn, str, size, val);
  else if (size == 0)
    {
      *errn = ERANGE;
      return -1;
    }
  else
    {
      int got;
      str[0] = '-';
      got = fmt_uint (errn, str + 1, size - 1, (unsigned int)-val);
      if (got >= 0)
	return 1 + got;
      else
	return got;
    }
}
