/************************************************************* * File: lib/atob.c * Purpose: Part of C runtime library * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970304 Start of revision history */ #include "string.h" /* a well behaved strncpy (always null terminates the dest) */ #define strNcpy(x,y,z) strncpy(x,y,z),(x)[z]=0 #ifdef TEST main(argc,argv) int argc; char *argv[]; { unsigned long n; int len; if (argc != 3) { printf("arg count %d\n",argc); exit(1); } if (!atob(&len,argv[2],10)) { printf("bad len\n"); exit(1); } if (gethex(&n,argv[1],len)) printf("OK: %08x\n",n); else printf("ERROR\n"); } #endif int _atob(unsigned int *vp,char *p,int base); /************************************************************* * atob(vp,p,base) * converts p to binary result in vp, rtn 1 on success */ int atob(unsigned int *vp,char *p,int base) { int r; if (base == 0) { if (p[0] == '0') { if (p[1] == 'x') r = _atob(vp,&p[2],16); else if (p[1] == 't'|| p[1] == 'n') r = _atob(vp,&p[2],10); else if (p[1] == 'o') r = _atob(vp,&p[2],8); else r = _atob(vp,p,8); } else r = _atob(vp,p,10); } else r = _atob(vp,p,base); return(r); } /************************************************************* * _atob(vp,p,base) */ int _atob(unsigned int *vp,char *p,int base) { int digit,neg; unsigned int value,v1,v2; char *q,tmp[20]; if (base == 16 && (q=strchr(p,'.'))) { if (q-p > 20-1) return(0); strNcpy(tmp,p,q-p); if (!_atob(&v1,tmp,16)) return(0); q++; if (strchr(q,'.')) return(0); if (!_atob(&v2,q,16)) return(0); *vp = (v1<<16)+v2; return(1); } neg = 0; if (base == 10 && *p == '-') { neg = 1; p++; } value = *vp = 0; for (;*p;p++) { value *= base; if (*p >= '0' && *p <= '9') digit = *p - '0'; else if (*p >= 'a' && *p <= 'f') digit = *p - 'a' + 10; else if (*p >= 'A' && *p <= 'F') digit = *p - 'A' + 10; else return(0); if (digit >= base) return(0); value += digit; } if (base == 10 && neg) value = 0-value; *vp = value; return(1); } /************************************************************* * char *btoa(dst,value,base) * converts value to ascii, result in dst */ char *btoa(dst,value,base) char *dst; int base; unsigned int value; { char buf[34],digit; int i,j,rem,neg; if (value == 0) { dst[0] = '0'; dst[1] = 0; return(dst); } neg = 0; if (base == 10 && (value&(1L<<31))) { value = (~value)+1; neg = 1; } for (i=0;value != 0;i++) { rem = value % base; value /= base; if (rem >= 0 && rem <= 9) digit = rem + '0'; else if (rem >= 10 && rem <= 36) digit = (rem-10) + 'a'; buf[i] = digit; } buf[i] = 0; if (neg) strcat(buf,"-"); /* reverse the string */ for (i=0,j=strlen(buf)-1;j>=0;i++,j--) dst[i] = buf[j]; dst[i] = 0; return(dst); } /************************************************************* * gethex(vp,p,n) * convert n hex digits from p to binary, result in vp, * rtn 1 on success */ gethex(vp,p,n) unsigned long *vp; char *p; int n; { unsigned long v; int digit; for (v=0;n>0;n--) { if (*p==0) return(0); v <<= 4; if (*p >= '0' && *p <= '9') digit = *p - '0'; else if (*p >= 'a' && *p <= 'f') digit = *p - 'a' + 10; else if (*p >= 'A' && *p <= 'F') digit = *p - 'A' + 10; else return(0); v |= digit; p++; } *vp = v; return(1); }