dc: support for bases 2 and 8, by Nate Case (ncase AT xes-inc.com)
authorDenis Vlasenko <vda.linux@googlemail.com>
Thu, 30 Oct 2008 23:25:50 +0000 (23:25 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Thu, 30 Oct 2008 23:25:50 +0000 (23:25 -0000)
function                                             old     new   delta
print_base                                            87     176     +89
set_output_base                                       81      95     +14
static.bases                                           -       5      +5
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 2/0 up/down: 108/0)             Total: 108 bytes

miscutils/dc.c

index 7d5886eb2f9f5e3111f0c59fd36ac374550ec116..6d4efa9432e272ec5391c6b1c64775266d311488 100644 (file)
@@ -98,19 +98,45 @@ static void not(void)
 
 static void set_output_base(void)
 {
-       base = (unsigned)pop();
-       if ((base != 10) && (base != 16)) {
-               bb_error_msg("error, base %d is not supported", base);
+       static const char bases[] ALIGN1 = { 2, 8, 10, 16, 0 };
+       unsigned b = (unsigned)pop();
+
+       base = *strchrnul(bases, b);
+       if (base == 0) {
+               bb_error_msg("error, base %u is not supported", b);
                base = 10;
        }
 }
 
 static void print_base(double print)
 {
-       if (base == 16)
-               printf("%x\n", (unsigned)print);
-       else
+       unsigned x, i;
+
+       if (base == 10) {
                printf("%g\n", print);
+               return;
+       }
+
+       x = (unsigned)print;
+       switch (base) {
+       case 16:
+               printf("%x\n", x);
+               break;
+       case 8:
+               printf("%o\n", x);
+               break;
+       default: /* base 2 */
+               i = (unsigned)INT_MAX + 1;
+               do {
+                       if (x & i) break;
+                       i >>= 1;
+               } while (i > 1);
+               do {
+                       bb_putchar('1' - !(x & i));
+                       i >>= 1;
+               } while (i);
+               bb_putchar('\n');
+       }
 }
 
 static void print_stack_no_pop(void)