home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume6 / copt / numarg.c < prev    next >
C/C++ Source or Header  |  1989-03-07  |  3KB  |  109 lines

  1. static char rcsid[] = "$Header: numarg.c,v 1.1 89/03/03 12:53:25 np Exp $";
  2. /* $Log:    numarg.c,v $
  3.  * Revision 1.1  89/03/03  12:53:25  np
  4.  * Initial revision
  5.  * 
  6.  */
  7.  
  8. /*
  9.  * Copyright (C) 1985-1989 Nigel Perry
  10.  *
  11.  * This program is distributed without any warranty.
  12.  * The author and and distributors accept no resposibility
  13.  * to anyone for the consequence of using this program or
  14.  * whether it serves any particular purpose or works at all,
  15.  * unless they say so in writing.
  16.  *
  17.  * Everyone is granted permission to copy, modify and
  18.  * redistribute this program, but only provided that:
  19.  *
  20.  * 1) They do so without financial or material gain.
  21.  *
  22.  * 2) The copyright notice and this notice are preserved on
  23.  *    all copies.
  24.  *
  25.  * 3) The original source is preserved in any redistribution.
  26.  *
  27.  * I hope you find this program useful!
  28.  *
  29.  */
  30.  
  31. #define repeat while(1)
  32.  
  33. /* convert string to number
  34.  * args:
  35.  *   str:    ptr to string to be parsed
  36.  *   poffset:   ptr to offset into str at which to start, will be updated on exit
  37.  *   base:    base of number to parse (2 -> 36), < 2 implies 0ddd -> oct, 0xddd -> hex, ddd -> dec
  38.  *   pflag:    ptr to flag, on input *pflag = 1 => skip leading junk (blanks always skipped)
  39.  *                 on exit  *pflag = 0 => failed to parse number
  40.  * return:
  41.  *   *pflag = 1 => number parsed
  42.  *   *pflag = 0 => 0, failed to parse
  43.  *
  44.  */
  45.  
  46. int numarg(str, poffset, base, pflag) register char *str;
  47.                       register int base, *poffset, *pflag;
  48. {  int neg, autobase;
  49.    register int val, dig;
  50.    char *start;
  51.    register char c;
  52.  
  53.    neg = autobase = val = 0;
  54.  
  55.    /* if base < 2, set oct/dec/hex */
  56.    if(base < 2) { base = 10; autobase = 1; }
  57.  
  58.    start = str; /* save start */
  59.    str += *poffset; /* add in starting offset */
  60.  
  61.    /* find first digit */
  62.    repeat
  63.    {  switch(c = *str++)
  64.       {  case ' ': continue; /* skip leading blanks */
  65.      case '-': neg = 1; /* flag negative */
  66.      case '+': if( (dig = getdig(*str++, base)) < 0 )
  67.            {  *poffset = str - start;
  68.               return(*pflag = 0); /* error */
  69.            }
  70.            break;
  71.      default: if( (dig = getdig(c, base)) >= 0 )
  72.              break; /* good digit */
  73.           if( *pflag == 1 ) continue; /* skip leading junk */
  74.           *poffset = str - start;
  75.           return(*pflag = 0); /* junk in de way */
  76.       }
  77.       break; /* kill repeat */
  78.    }
  79.  
  80.    /* if get here, dig is first digit & neg flag be set */
  81.    if(dig == 0 && autobase) /* check for oct/hex */
  82.    {  if( (c = *str) == 'x' || c == 'X' ) /* hex */
  83.       {  str++; /* skip x */
  84.      base = 16;
  85.       }
  86.       else
  87.      base = 8;
  88.    }
  89.    else
  90.       val = dig;
  91.  
  92.    /* read in till non-digit */
  93.    while( (dig = getdig(*str++, base)) >= 0 ) val = val * base + dig;
  94.  
  95.    *poffset = str - start - 1;
  96.    *pflag = 1; /* good return */
  97.    return(neg ? -val : val);
  98. }
  99.  
  100. static getdig(c, base) register int c, base;
  101. {  if( c >= '0' && c <= '9' )  /* this SHOULD be a case... B rules! */
  102.       return( (c -= '0') < base ? c : -1 );
  103.    else if( c >= 'a' && c <= 'z' )
  104.       return( (c += 10 - 'a') < base ? c : -1 );
  105.    else if(c >= 'A' && c <= 'Z' )
  106.       return( (c += 10 - 'A') < base ? c : -1);
  107.    else return(-1);
  108. }
  109.