home *** CD-ROM | disk | FTP | other *** search
- 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);
- }
-