home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume4 / cvtbase < prev    next >
Internet Message Format  |  1989-02-03  |  6KB

  1. Path: xanth!mcnc!rutgers!tut.cis.ohio-state.edu!cwjcc!hal!ncoast!allbery
  2. From: mouse%mcgill-vision.UUCP@Larry.McRCIM.McGill.EDU (der Mouse )
  3. Newsgroups: comp.sources.misc
  4. Subject: v04i038: generalized base converter
  5. Message-ID: <8808271107.AA22874@Larry.McRCIM.McGill.EDU>
  6. Date: 27 Aug 88 11:07:19 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: mouse%mcgill-vision.UUCP@Larry.McRCIM.McGill.EDU (der Mouse )
  9. Lines: 269
  10. Approved: allbery@ncoast.UUCP
  11.  
  12. Posting-number: Volume 4, Issue 38
  13. Submitted-by: "der Mouse " <mouse%mcgill-vision.UUCP@Larry.McRCIM.McGill.EDU>
  14. Archive-name: cvtbase
  15.  
  16. A generalized base-conversion program.  No compilation options needed;
  17. "cc -o cvtbase cvtbase.c" should work fine.
  18.  
  19. Known to work on BSD and at least one SV-based system.  Read the
  20. leading comment for more info.
  21.  
  22. As always, bug reports are welcome.  Bug fixes are even more welcome.
  23. Flames are merely accepted :-).  All of the above should be mailed to
  24. me at one of the addresses below.
  25.  
  26.                     der Mouse
  27.  
  28.             old: mcgill-vision!mouse
  29.             new: mouse@larry.mcrcim.mcgill.edu
  30.  
  31. #! /bin/sh
  32. #
  33. # Shar: Shell Archiver
  34. #
  35. # This archive created Sat Aug 27 07:01:24 1988
  36. # Run this through sh to create:
  37. #    cvtbase.c
  38. echo x - cvtbase.c \(4639 characters\)
  39. sed 's/^X//' > cvtbase.c << \EOF
  40. X/*
  41. X * cvtbase -- convert from one base to another.  Usage:
  42. X *
  43. X * cvtbase input-base-spec output-base-spec < input > output
  44. X *
  45. X * where a base spec is one of:
  46. X *
  47. X *    d
  48. X *    D    Specifies "decimal" -- digits 0 through 9
  49. X *
  50. X *    x
  51. X *    h    Specifies "hexadecimal" -- digits 0-9 and a-f
  52. X *
  53. X *    X
  54. X *    H    Specifies "Hexadecimal" -- digits 0-9 and A-F
  55. X *
  56. X *    o
  57. X *    O    Specifies "octal" -- digits 0 through 7
  58. X *
  59. X *    b
  60. X *    B    Specifies "binary" -- digits 0 and 1
  61. X *
  62. X * or a string of two or more characters, which are the digits (eg. 012 would
  63. X *  use ternary notation).  Any of these may be preceded by a - sign to
  64. X *  indicate that the base in question is negative.  A leading + sign is
  65. X *  stripped; to enter a string of digits beginning with a + or - sign, you
  66. X *  must precede the string with a + or - sign (depending on whether you want
  67. X *  a positive or negative base).
  68. X *
  69. X * Any base specifier may be preceded by an m (or an M) and one other
  70. X *  character to change the minus sign (the default is of course -).
  71. X *
  72. X * For a minus sign to be recognized in the input, it must be immediately
  73. X *  followed by the number.  If anything (such as a space) intervenes, the
  74. X *  minus sign will be echoed and ignored (as if it were an ordinary
  75. X *  character).
  76. X *
  77. X * Bases -1, 0, and 1 are disallowed.
  78. X *
  79. X * Input is taken from the standard input; the converted output appears
  80. X *  on the standard output.
  81. X *
  82. X * Copyright 1988 by Mike Parker.  All rights reserved.  Non-profit
  83. X *  redistribution permitted.
  84. X */
  85. X#include <stdio.h>
  86. X
  87. X/* extern */ char **argvec;
  88. X
  89. Xstatic int errs;
  90. X
  91. Xstatic int indig;
  92. Xstatic char *idigits;
  93. Xstatic char isign;
  94. Xstatic int ondig;
  95. Xstatic char *odigits;
  96. Xstatic char osign;
  97. X
  98. Xchar *index();
  99. X
  100. Xlong int get_number(ndig,digits,sign)
  101. Xint ndig;
  102. Xchar *digits;
  103. Xchar sign;
  104. X{
  105. X long int retval;
  106. X int minus;
  107. X char c;
  108. X char *cp;
  109. X
  110. X retval = 0;
  111. X minus = 1;
  112. X while (1)
  113. X  { c = getchar();
  114. X    if (feof(stdin))
  115. X     { if (minus < 0)
  116. X    { putchar(sign);
  117. X      minus = 1;
  118. X    }
  119. X       exit(0);
  120. X     }
  121. X    if ((cp=index(digits,c)) != 0)
  122. X     { break;
  123. X     }
  124. X    if ((c == sign) && (ndig > 0))
  125. X     { minus = - minus;
  126. X     }
  127. X    else
  128. X     { if (minus < 0)
  129. X    { putchar(sign);
  130. X      minus = 1;
  131. X    }
  132. X       putchar(c);
  133. X     }
  134. X  }
  135. X while (1)
  136. X  { retval *= ndig;
  137. X    retval += (cp-digits);
  138. X    c = getchar();
  139. X    if (feof(stdin))
  140. X     { break;
  141. X     }
  142. X    if ((cp=index(digits,c)) == 0)
  143. X     { break;
  144. X     }
  145. X  }
  146. X ungetc(c,stdin);
  147. X return(minus*retval);
  148. X}
  149. X
  150. Xput_number(ndig,digits,sign,value)
  151. Xint ndig;
  152. Xchar *digits;
  153. Xchar sign;
  154. Xlong int value;
  155. X{
  156. X if ((value < 0) && (ndig > 0))
  157. X  { putchar(sign);
  158. X    value = - value;
  159. X  }
  160. X _put_number(ndig,digits,value);
  161. X}
  162. X
  163. X_put_number(ndig,digits,value)
  164. Xint ndig;
  165. Xchar *digits;
  166. Xlong int value;
  167. X{
  168. X long int i;
  169. X int j;
  170. X
  171. X i = value / ndig;
  172. X j = value % ndig;
  173. X if (j < 0)
  174. X  { j -= ndig;
  175. X    i ++;
  176. X  }
  177. X if (i != 0)
  178. X  { _put_number(ndig,digits,i);
  179. X  }
  180. X putchar(digits[j]);
  181. X}
  182. X
  183. Xget_base(arg,Ndig,Digits,Sign)
  184. Xchar *arg;
  185. Xint *Ndig;
  186. X#define ndig (*Ndig)
  187. Xchar **Digits;
  188. X#define digits (*Digits)
  189. Xchar *Sign;
  190. X#define sign (*Sign)
  191. X{
  192. X int isneg;
  193. X char *origarg = arg;
  194. X
  195. X sign = '-';
  196. X isneg = 0;
  197. X if ((*arg == 'm') || (*arg == 'M'))
  198. X  { sign = *++arg;
  199. X    if (sign == '\0')
  200. X     { fprintf(stderr,"%s: %c must be followed by a sign character\n",
  201. X            argvec[0],arg[-1]);
  202. X       errs = 1;
  203. X       return;
  204. X     }
  205. X    arg ++;
  206. X  }
  207. X if ((*arg == '+') || (*arg == '-'))
  208. X  { isneg = (*arg++ == '-');
  209. X  }
  210. X switch (*arg++)
  211. X  { case 'b': case 'B':
  212. X       digits = "01";
  213. X       break;
  214. X    case 'o': case 'O':
  215. X       digits = "01234567";
  216. X       break;
  217. X    case 'd': case 'D':
  218. X       digits = "0123456789";
  219. X       break;
  220. X    case 'h': case 'x':
  221. X       digits = "0123456789abcdef";
  222. X       break;
  223. X    case 'H': case 'X':
  224. X       digits = "0123456789ABCDEF";
  225. X       break;
  226. X    case '\0':
  227. X       fprintf(stderr,"%s: null base specifier `%s'\n",argvec[0],origarg);
  228. X       errs = 1;
  229. X       return;
  230. X       break;
  231. X    default:
  232. X       if (*arg == '\0')
  233. X    { fprintf(stderr,"%s: unknown base key `%c' (or base 1)\n",
  234. X            argvec[0],arg[-1]);
  235. X      errs = 1;
  236. X      return;
  237. X    }
  238. X       digits = arg-1;
  239. X       arg = "";
  240. X       break;
  241. X  }
  242. X if (*arg)
  243. X  { fprintf(stderr,"%s: junk `%s' at end of base spec `%s'\n",
  244. X                argvec[0],arg,origarg);
  245. X    errs = 1;
  246. X    return;
  247. X  }
  248. X ndig = strlen(digits) * (isneg ? -1 : 1);
  249. X}
  250. X
  251. Xmain(ac,av)
  252. Xint ac;
  253. Xchar **av;
  254. X{
  255. X long int value;
  256. X
  257. Xargvec=av;/*grrr...*/
  258. X if (ac < 3)
  259. X  { fprintf(stderr,"Usage: %s <input-base> <output-base>\n",
  260. X            argvec[0]);
  261. X    exit(1);
  262. X  }
  263. X errs = 0;
  264. X get_base(av[1],&indig,&idigits,&isign);
  265. X get_base(av[2],&ondig,&odigits,&osign);
  266. X if (errs)
  267. X  { exit(1);
  268. X  }
  269. X while (1)
  270. X  { value = get_number(indig,idigits,isign);
  271. X    put_number(ondig,odigits,osign,value);
  272. X  }
  273. X}
  274. EOF
  275. if test 4639 -ne "`wc -c cvtbase.c`"
  276. then
  277. echo shar: error transmitting cvtbase.c \(should have been 4639 characters\)
  278. fi
  279. exit 0
  280. # end of shell archive
  281.