mouse%mcgill-vision.UUCP@Larry.McRCIM.McGill.EDU (der Mouse ) (08/27/88)
Posting-number: Volume 4, Issue 38 Submitted-by: "der Mouse " <mouse%mcgill-vision.UUCP@Larry.McRCIM.McGill.EDU> Archive-name: cvtbase A generalized base-conversion program. No compilation options needed; "cc -o cvtbase cvtbase.c" should work fine. Known to work on BSD and at least one SV-based system. Read the leading comment for more info. As always, bug reports are welcome. Bug fixes are even more welcome. Flames are merely accepted :-). All of the above should be mailed to me at one of the addresses below. der Mouse old: mcgill-vision!mouse new: mouse@larry.mcrcim.mcgill.edu #! /bin/sh # # Shar: Shell Archiver # # This archive created Sat Aug 27 07:01:24 1988 # Run this through sh to create: # cvtbase.c echo x - cvtbase.c \(4639 characters\) sed 's/^X//' > cvtbase.c << \EOF X/* X * cvtbase -- convert from one base to another. Usage: X * X * cvtbase input-base-spec output-base-spec < input > output X * X * where a base spec is one of: X * X * d X * D Specifies "decimal" -- digits 0 through 9 X * X * x X * h Specifies "hexadecimal" -- digits 0-9 and a-f X * X * X X * H Specifies "Hexadecimal" -- digits 0-9 and A-F X * X * o X * O Specifies "octal" -- digits 0 through 7 X * X * b X * B Specifies "binary" -- digits 0 and 1 X * X * or a string of two or more characters, which are the digits (eg. 012 would X * use ternary notation). Any of these may be preceded by a - sign to X * indicate that the base in question is negative. A leading + sign is X * stripped; to enter a string of digits beginning with a + or - sign, you X * must precede the string with a + or - sign (depending on whether you want X * a positive or negative base). X * X * Any base specifier may be preceded by an m (or an M) and one other X * character to change the minus sign (the default is of course -). X * X * For a minus sign to be recognized in the input, it must be immediately X * followed by the number. If anything (such as a space) intervenes, the X * minus sign will be echoed and ignored (as if it were an ordinary X * character). X * X * Bases -1, 0, and 1 are disallowed. X * X * Input is taken from the standard input; the converted output appears X * on the standard output. X * X * Copyright 1988 by Mike Parker. All rights reserved. Non-profit X * redistribution permitted. X */ X#include <stdio.h> X X/* extern */ char **argvec; X Xstatic int errs; X Xstatic int indig; Xstatic char *idigits; Xstatic char isign; Xstatic int ondig; Xstatic char *odigits; Xstatic char osign; X Xchar *index(); X Xlong int get_number(ndig,digits,sign) Xint ndig; Xchar *digits; Xchar sign; X{ X long int retval; X int minus; X char c; X char *cp; X X retval = 0; X minus = 1; X while (1) X { c = getchar(); X if (feof(stdin)) X { if (minus < 0) X { putchar(sign); X minus = 1; X } X exit(0); X } X if ((cp=index(digits,c)) != 0) X { break; X } X if ((c == sign) && (ndig > 0)) X { minus = - minus; X } X else X { if (minus < 0) X { putchar(sign); X minus = 1; X } X putchar(c); X } X } X while (1) X { retval *= ndig; X retval += (cp-digits); X c = getchar(); X if (feof(stdin)) X { break; X } X if ((cp=index(digits,c)) == 0) X { break; X } X } X ungetc(c,stdin); X return(minus*retval); X} X Xput_number(ndig,digits,sign,value) Xint ndig; Xchar *digits; Xchar sign; Xlong int value; X{ X if ((value < 0) && (ndig > 0)) X { putchar(sign); X value = - value; X } X _put_number(ndig,digits,value); X} X X_put_number(ndig,digits,value) Xint ndig; Xchar *digits; Xlong int value; X{ X long int i; X int j; X X i = value / ndig; X j = value % ndig; X if (j < 0) X { j -= ndig; X i ++; X } X if (i != 0) X { _put_number(ndig,digits,i); X } X putchar(digits[j]); X} X Xget_base(arg,Ndig,Digits,Sign) Xchar *arg; Xint *Ndig; X#define ndig (*Ndig) Xchar **Digits; X#define digits (*Digits) Xchar *Sign; X#define sign (*Sign) X{ X int isneg; X char *origarg = arg; X X sign = '-'; X isneg = 0; X if ((*arg == 'm') || (*arg == 'M')) X { sign = *++arg; X if (sign == '\0') X { fprintf(stderr,"%s: %c must be followed by a sign character\n", X argvec[0],arg[-1]); X errs = 1; X return; X } X arg ++; X } X if ((*arg == '+') || (*arg == '-')) X { isneg = (*arg++ == '-'); X } X switch (*arg++) X { case 'b': case 'B': X digits = "01"; X break; X case 'o': case 'O': X digits = "01234567"; X break; X case 'd': case 'D': X digits = "0123456789"; X break; X case 'h': case 'x': X digits = "0123456789abcdef"; X break; X case 'H': case 'X': X digits = "0123456789ABCDEF"; X break; X case '\0': X fprintf(stderr,"%s: null base specifier `%s'\n",argvec[0],origarg); X errs = 1; X return; X break; X default: X if (*arg == '\0') X { fprintf(stderr,"%s: unknown base key `%c' (or base 1)\n", X argvec[0],arg[-1]); X errs = 1; X return; X } X digits = arg-1; X arg = ""; X break; X } X if (*arg) X { fprintf(stderr,"%s: junk `%s' at end of base spec `%s'\n", X argvec[0],arg,origarg); X errs = 1; X return; X } X ndig = strlen(digits) * (isneg ? -1 : 1); X} X Xmain(ac,av) Xint ac; Xchar **av; X{ X long int value; X Xargvec=av;/*grrr...*/ X if (ac < 3) X { fprintf(stderr,"Usage: %s <input-base> <output-base>\n", X argvec[0]); X exit(1); X } X errs = 0; X get_base(av[1],&indig,&idigits,&isign); X get_base(av[2],&ondig,&odigits,&osign); X if (errs) X { exit(1); X } X while (1) X { value = get_number(indig,idigits,isign); X put_number(ondig,odigits,osign,value); X } X} EOF if test 4639 -ne "`wc -c cvtbase.c`" then echo shar: error transmitting cvtbase.c \(should have been 4639 characters\) fi exit 0 # end of shell archive