/* ---------------------------------------------------------------------
   (c) ED 1997-2003
   Project      : CLIB
   Function     : Fonctions de conversion int -> asciiz
   Module       : ITOA
   File         : ITOA.C
   Created      : 03-06-1997
   Modified     : 12-11-03
   --------------------------------------------------------------------- */

/* ---------------------------------------------------------------------
   Log

   1.0 : 03-06-97 : Creation (recuperation ETCD-2G/P4.1)
   1.1 : 04-06-97 : itoa16 -> ctoa16 (uchar)
   .                creation de wtoa16 (ushort)
   .                itoa10 -> wtoa10 (ushort)
   1.2 : 12-04-00 : creation de ultoa16 (ulong)
   1.3 : 13-04-00 : creation de ultoa10 (ulong)
   1.4 : 09-03-02 : optimisation wtoa10()
   1.5 : 12-09-03 : ajoute ultoa2
   1.6 : 12-11-03 : ajout de itoa_sid() et itoa_sver()

   --------------------------------------------------------------------- */
#ifdef __cplusplus
#error This source file is not C++ but rather C. Please use a C-compiler
#endif

#include "ed/inc/itoa.h"
#include "ed/inc/sys.h"
#include "ed/inc/bits.h"

#include <stddef.h>
#include <stdlib.h>

/* macros ============================================================== */
#define VER "1.6"
#define MOD "ITOA"
#define CPY "(c) ED 1997-2003"

/* constants =========================================================== */
static char const Thex[] = "0123456789ABCDEF";

/* types =============================================================== */
/* structures ========================================================== */
/* private data ======================================================== */
/* private functions =================================================== */
/* internal public data ================================================ */
/* internal public functions =========================================== */
/* entry points ======================================================== */

/* ------------------------------------------------------------------------
   itoa_sver()
   ------------------------------------------------------------------------

   ------------------------------------------------------------------------
   E :
   S : chaine 'version'
   ------------------------------------------------------------------------ */
char const *itoa_sver (void)
{
   return VER;
}

/* ------------------------------------------------------------------------
   itoa_sid()
   ------------------------------------------------------------------------

   ------------------------------------------------------------------------
   E :
   S : chaine 'module' + 'copyright'
   ------------------------------------------------------------------------ */
char const *itoa_sid (void)
{
   return MOD " " CPY;
}

/* ------------------------------------------------------------------------
   Fonction wtoa10(n,s)
   ------------------------------------------------------------------------
   E : entier 16 bits
   E : pointeur de chaine
   S : -
   ------------------------------------------------------------------------
   role : convertit un entier en une chaine ascii DECIMALE sur 1 a 5 digits
   "xxxxx"  (0-65635)
   ------------------------------------------------------------------------ */
void wtoa10 (uint const n, char *const s)
{
   ulong rem = n;
   int i = 0;
   ulong d = 10000L;            /* max : 65635 */
   int ena = 0;                 /* par defaut, ignorer */

   ENUM_CHECK ();

   LIM_PTR (s, ITOA_MAX);
   do
   {
      ldiv_t x = ldiv ((long) rem, (long) d);
      rem = x.rem;

      /* eliminer les 0 d'entete */
      if (x.quot)
      {
         ena = 1;
      }

      if (ena)
      {
         s[i] = (char) ('0' + x.quot);
         CHK_PTR (s, ITOA_MAX);
         i++;
      }
      d /= 10;

   }
   while (d > 1);

   /* unites (reste) */
   s[i] = (char) ('0' + rem);
   CHK_PTR (s, ITOA_MAX);
   i++;

   s[i] = 0;
}

/* ------------------------------------------------------------------------
   Fonction ultoa10(n,s)
   ------------------------------------------------------------------------
   E : entier long
   E : pointeur de chaine
   S : -
   ------------------------------------------------------------------------
   role : convertit un entier en une chaine ascii DECIMALE sur 1 a 10 digits
   "xxxxx"  (0-4294967295)
   ------------------------------------------------------------------------ */
void ultoa10 (ulong const n, char *const s)
{
   ulong rem = n;
   size_t i = 0;
   ulong d = 1000000000UL;      /* max : 4294967295 */
   int ena = 0;                 /* par defaut, ignorer */

   ENUM_CHECK ();

   LIM_PTR (s, ITOA_MAX);

   do
   {
      ulong quot = rem / d;
      rem = n % d;

      /* eliminer les 0 d'entete */
      if (quot)
      {
         ena = 1;
      }

      if (ena)
      {
         (s[i] = (char) ('0' + quot));
         CHK_PTR (s, ITOA_MAX);
         i++;
      }
      d /= 10;

   }
   while (d > 1);

   /* unites (reste) */
   s[i] = (char) ('0' + rem);
   CHK_PTR (s, ITOA_MAX);
   i++;

   s[i] = 0;

}

/* ------------------------------------------------------------------------
   Fonction uctoa16(n,s)
   ------------------------------------------------------------------------
   E : char non signe
   E : pointeur de chaine
   S : -
   ------------------------------------------------------------------------
   role : convertit un char en une chaine ascii HEXA sur 2 digits "xx"
   (00-FF)
   ------------------------------------------------------------------------ */
void uctoa16 (uchar const n, char *const s)
{
   size_t i;

   ENUM_CHECK ();

   LIM_PTR (s, ITOA_MAX);
   for (i = 0; i < 2; i++)
   {
      s[i] = Thex[(n >> ((1 - i) * 4)) & 0x0F];
      CHK_PTR (s, ITOA_MAX);
   }
   s[i] = 0;
}

/* ------------------------------------------------------------------------
   Fonction wtoa16(n,s)
   ------------------------------------------------------------------------
   E : entier 16 bits
   E : pointeur de chaine
   S : -
   ------------------------------------------------------------------------
   role : convertit un entier en une chaine ascii HEXA sur 4 digits "xxxx"
   (0000-FFFF)
   ------------------------------------------------------------------------ */
void wtoa16 (uint const n, char *const s)
{
   size_t i;

   ENUM_CHECK ();

   LIM_PTR (s, ITOA_MAX);
   for (i = 0; i < 4; i++)
   {
      s[i] = Thex[(n >> ((3 - i) * 4)) & 0x0F];
      CHK_PTR (s, ITOA_MAX);
   }
   s[i] = 0;
}

/* ------------------------------------------------------------------------
   Fonction ultoa16(n,s)
   ------------------------------------------------------------------------
   E : entier long
   E : pointeur de chaine
   S : -
   ------------------------------------------------------------------------
   role : convertit un entier en une chaine ascii HEXA sur 8 digits
   "xxxxxxxx" (00000000-FFFFFFFF)
   ------------------------------------------------------------------------ */
void ultoa16 (ulong const n, char *const s)
{
   size_t i;

   ENUM_CHECK ();

   LIM_PTR (s, ITOA_MAX);
   for (i = 0; i < 8; i++)
   {
      s[i] = Thex[(size_t) (n >> ((7 - i) * 4)) & 0x0F];
      CHK_PTR (s, ITOA_MAX);
   }
   s[i] = 0;
}

/* ------------------------------------------------------------------------
   Fonction ultoa2(n,s)
   ------------------------------------------------------------------------
   E : entier long
   E : largeur
   E : pointeur de chaine
   S : -
   ------------------------------------------------------------------------
   role : convertit un entier en une chaine ascii BINAIRE
   ------------------------------------------------------------------------ */
void ultoa2 (ulong const n, uint const larg, char *const s)
{
   uint i = larg;

   LIM_PTR (s, ITOA_MAX);
   while (i)
   {
      i--;
      s[i] = (char) ('0' + mGET (n, BIT (larg - 1 - i)));
      CHK_PTR (s, ITOA_MAX);
   }
   s[larg] = 0;
}

/* public data ========================================================= */
