#include <stream.h>
#include <escseq.h>

void usage ()
{
   SET_A_PEN (2)
   cout << BOLD_ON;
   cout << "\nChange © by  Harald Pehl in 1993\n\n";
   SET_A_PEN (1)
   cout << "Synthax: Change -d -o -h -b Zahl\n\n";
   cout << BOLD_OFF;
   cout << "Zahl ist z.B.: \'123\' ( =dez. ),\n"
           "               \'0123\' ( =okt. ),\n"
           "               \'0x123\' ( =hex. ),\n"
           "               \'b10101\' ( =bin. ).\n\n";
   cout << "-d = Zahl wird nach dezimal umgerechnet\n"
           "-h = Zahl wird nach hexadezmal umgerechnet\n"
           "-o = Zahl wird nach oktal umgerechnet\n"
           "-b = Zahl wird nach binär umgerechnet\n\n";
   exit (0);
}


char *itoa (unsigned int zahl, int mode)
{
   char c, *dest = 0;
   int flag = 0, shift = 0;
   unsigned int maxpot = 0;
   static char ergebnis[12] = "0x";
   
   if (mode == 8)
   {
      shift  = 3;
      dest   = ergebnis+1;
      maxpot = 010000000000;
   }
   else
   {
      shift  = 4;
      dest   = ergebnis+2;
      maxpot = 0x10000000;
   }
   while (maxpot >= 1)
   {
      c = zahl / maxpot + '0';
      if ((c != '0') || (maxpot == 1) || flag)
      {
         flag = 1;
         if (mode == 16)
            if (c > '9')   c += 7;
         *dest++ = c;
      }
      zahl %= maxpot;
      maxpot >>= shift;
   }
   *dest = 0;
   return ergebnis;
}


char *itob (unsigned int zahl)
{
   int flag = 0;
   static char ergebnis[33] = "b";
   char *dest = ergebnis+1;
   unsigned int muster = 0x80000000;

   for (int n = 0 ; n < 32 ; n++)
   {
      if (zahl & muster)
      {
         flag = 1;
         *dest++ = '1';
      }
      else
         if (flag)   
            *dest++ = '0';
      zahl <<= 1;
   }
   if (!flag) 
      *dest++ = '0';
   *dest = 0;
   return ergebnis;
}


void main (int argc, char **argv)
{
   char c, dec = 0, oct = 0, hex = 0, bin = 0;
   
   while (--argc > 0 && **++argv == '-')
   {
      while (c = *++argv[0])
      {
         switch (c)
         {
            case 'd':
            case 'D': dec = 1; break;
            case 'h': 
            case 'H': hex = 1; break;
            case 'o': 
            case 'O': oct = 1; break;
            case 'b': 
            case 'B': bin = 1; break;
            default : cout << "\nFehler: Illegale Option \"" <<c<< "\".\n";
                      argc = 0;
                      break;
         }
      }
   }
   if (argc != 1)
      usage ();
   else
   {
      char *s = *argv;
      unsigned int zahl = 0;
      int base = 10, error = 0;
      
      switch (*s)
      {
         case '0': 
            if (*++s == 'x' || *s == 'X')
            {
               *s++;
               base = 16;
            }
            else
               base =  8;
            break;
         case 'b':
         case 'B':
            *s++;
            base = 2;
      }
      while ((c = *s++ & 0xff) && !error)
      {
         if (c >= '0' && c <= base+47)
            c -= '0';
         else if (base == 16)
         {
            if (c >= 'A' && c <= 'F') 
               c -= 'A'-10;
            else if (c >= 'a' && c<= 'f')
               c -= 'a'-10;
            else  error = 1;
         }
         else error = 1;
         zahl = zahl * base + c;
      }
      if (error)  
         usage ();
      if (dec == 0 && hex == 0 && oct == 0 && bin == 0)
         dec = hex = oct = bin = 1;
      cout << "\n" << *argv << " --> ";
      if (dec)    cout << zahl << " (dez)   ";
      if (hex)    cout << (base == 16 ? *argv : itoa (zahl, 16)) << " (hex)   ";
      if (oct)    cout << (base ==  8 ? *argv : itoa (zahl,  8)) << " (okt)   ";
      if (bin)    cout << (base ==  2 ? *argv : itob (zahl))     << " (bin)   ";
      cout << "\n\n";
   }
}
