home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume6
/
copt
/
numarg.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-03-07
|
3KB
|
109 lines
static char rcsid[] = "$Header: numarg.c,v 1.1 89/03/03 12:53:25 np Exp $";
/* $Log: numarg.c,v $
* Revision 1.1 89/03/03 12:53:25 np
* Initial revision
*
*/
/*
* Copyright (C) 1985-1989 Nigel Perry
*
* This program is distributed without any warranty.
* The author and and distributors accept no resposibility
* to anyone for the consequence of using this program or
* whether it serves any particular purpose or works at all,
* unless they say so in writing.
*
* Everyone is granted permission to copy, modify and
* redistribute this program, but only provided that:
*
* 1) They do so without financial or material gain.
*
* 2) The copyright notice and this notice are preserved on
* all copies.
*
* 3) The original source is preserved in any redistribution.
*
* I hope you find this program useful!
*
*/
#define repeat while(1)
/* convert string to number
* args:
* str: ptr to string to be parsed
* poffset: ptr to offset into str at which to start, will be updated on exit
* base: base of number to parse (2 -> 36), < 2 implies 0ddd -> oct, 0xddd -> hex, ddd -> dec
* pflag: ptr to flag, on input *pflag = 1 => skip leading junk (blanks always skipped)
* on exit *pflag = 0 => failed to parse number
* return:
* *pflag = 1 => number parsed
* *pflag = 0 => 0, failed to parse
*
*/
int numarg(str, poffset, base, pflag) register char *str;
register int base, *poffset, *pflag;
{ int neg, autobase;
register int val, dig;
char *start;
register char c;
neg = autobase = val = 0;
/* if base < 2, set oct/dec/hex */
if(base < 2) { base = 10; autobase = 1; }
start = str; /* save start */
str += *poffset; /* add in starting offset */
/* find first digit */
repeat
{ switch(c = *str++)
{ case ' ': continue; /* skip leading blanks */
case '-': neg = 1; /* flag negative */
case '+': if( (dig = getdig(*str++, base)) < 0 )
{ *poffset = str - start;
return(*pflag = 0); /* error */
}
break;
default: if( (dig = getdig(c, base)) >= 0 )
break; /* good digit */
if( *pflag == 1 ) continue; /* skip leading junk */
*poffset = str - start;
return(*pflag = 0); /* junk in de way */
}
break; /* kill repeat */
}
/* if get here, dig is first digit & neg flag be set */
if(dig == 0 && autobase) /* check for oct/hex */
{ if( (c = *str) == 'x' || c == 'X' ) /* hex */
{ str++; /* skip x */
base = 16;
}
else
base = 8;
}
else
val = dig;
/* read in till non-digit */
while( (dig = getdig(*str++, base)) >= 0 ) val = val * base + dig;
*poffset = str - start - 1;
*pflag = 1; /* good return */
return(neg ? -val : val);
}
static getdig(c, base) register int c, base;
{ if( c >= '0' && c <= '9' ) /* this SHOULD be a case... B rules! */
return( (c -= '0') < base ? c : -1 );
else if( c >= 'a' && c <= 'z' )
return( (c += 10 - 'a') < base ? c : -1 );
else if(c >= 'A' && c <= 'Z' )
return( (c += 10 - 'A') < base ? c : -1);
else return(-1);
}