home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume25 / pty4 / part04 / scan.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-18  |  5.0 KB  |  190 lines

  1. /* scan.c, scan.h: scanning library
  2. Daniel J. Bernstein, brnstnd@nyu.edu.
  3. No dependencies.
  4. No environment requirements.
  5. 7/18/91: Baseline. scan 1.0, public domain.
  6. No known patent problems.
  7.  
  8. XXX: still need floating-point scanning
  9.  
  10. */
  11.  
  12. #include "scan.h"
  13.  
  14. /* just to keep track of what special characters we're using */
  15. #define zero '0'
  16. #define plus '+'
  17. #define minus '-'
  18. #define alow 'a'
  19. #define acap 'A'
  20. #define space ' '
  21. #define tab '\t'
  22. #define xlow 'x'
  23. #define xcap 'x'
  24.  
  25. /* Note that the digits here are defined as '0', '0' + 1, '0' + 2, etc. */
  26. /* The letters are defined similarly, starting from 'a' and 'A'. */
  27. /* This may produce unintuitive results with a weird character set. */
  28.  
  29. unsigned int scan_plusminus(s,sign) char *s; int *sign;
  30. {
  31.  if (*s == plus) { *sign = 1; return 1; }
  32.  if (*s == minus) { *sign = -1; return 1; }
  33.  *sign = 1; return 0;
  34. }
  35.  
  36. unsigned int scan_0x(s,base) char *s; unsigned int *base;
  37. {
  38.  if (*s == zero)
  39.   {
  40.    if ((s[1] == xlow) || (s[1] == xcap))
  41.     { *base = 16; return 2; }
  42.    *base = 8; return 1;
  43.   }
  44.  *base = 10; return 0;
  45. }
  46.  
  47. unsigned int scan_ulong(s,u) char *s; unsigned long *u;
  48. {
  49.  unsigned int pos; unsigned long result; unsigned long c;
  50.  pos = 0; result = 0;
  51.  while ((c = (unsigned long) (unsigned char) (s[pos] - zero)) < 10)
  52.   { result = result * 10 + c; ++pos; }
  53.  *u = result; return pos;
  54. }
  55.  
  56. unsigned int scan_xlong(s,u) char *s; unsigned long *u;
  57. {
  58.  unsigned int pos; unsigned long result; unsigned long c;
  59.  pos = 0; result = 0;
  60.  while (((c = (unsigned long) (unsigned char) (s[pos] - zero)) < 10)
  61.       ||(((c = (unsigned long) (unsigned char) (s[pos] - alow)) < 6)
  62.        &&(c = c + 10))
  63.       ||(((c = (unsigned long) (unsigned char) (s[pos] - acap)) < 6)
  64.        &&(c = c + 10))
  65.        ) /* XXX: this gets the job done */
  66.   { result = result * 16 + c; ++pos; }
  67.  *u = result; return pos;
  68. }
  69.  
  70. unsigned int scan_nbblong(s,n,base,bext,u)
  71. char *s; unsigned int n; unsigned int base; unsigned int bext; unsigned long *u;
  72. /* Note that n == 0 means scan forever. Hopefully this is a good choice. */
  73. {
  74.  unsigned int pos; unsigned long result; unsigned long c;
  75.  pos = 0; result = 0;
  76.  while (((c = (unsigned long) (unsigned char) (s[pos] - zero)) < base)
  77.       ||(((c = (unsigned long) (unsigned char) (s[pos] - alow)) < bext)
  78.        &&(c = c + base))
  79.       ||(((c = (unsigned long) (unsigned char) (s[pos] - acap)) < bext)
  80.        &&(c = c + base))
  81.        ) /* XXX: this gets the job done */
  82.   { result = result * (base + bext) + c; ++pos; if (pos == n) break; }
  83.  *u = result; return pos;
  84. }
  85.  
  86. unsigned int scan_uint(s,u) char *s; unsigned int *u;
  87. {
  88.  unsigned int pos; unsigned long result;
  89.  pos = scan_ulong(s,&result);
  90.  *u = result; return pos;
  91. }
  92.  
  93. unsigned int scan_xint(s,u) char *s; unsigned int *u;
  94. {
  95.  unsigned int pos; unsigned long result;
  96.  pos = scan_xlong(s,&result);
  97.  *u = result; return pos;
  98. }
  99.  
  100. unsigned int scan_nbbint(s,n,base,bext,u)
  101. char *s; unsigned int n; unsigned int base; unsigned int bext; unsigned int *u;
  102. {
  103.  unsigned int pos; unsigned long result;
  104.  pos = scan_nbblong(s,n,base,bext,&result);
  105.  *u = result; return pos;
  106. }
  107.  
  108. unsigned int scan_ushort(s,u) char *s; unsigned short *u;
  109. {
  110.  unsigned int pos; unsigned long result;
  111.  pos = scan_ulong(s,&result);
  112.  *u = result; return pos;
  113. }
  114.  
  115. unsigned int scan_xshort(s,u) char *s; unsigned short *u;
  116. {
  117.  unsigned int pos; unsigned long result;
  118.  pos = scan_xlong(s,&result);
  119.  *u = result; return pos;
  120. }
  121.  
  122. unsigned int scan_nbbshort(s,n,base,bext,u)
  123. char *s; unsigned int n; unsigned int base; unsigned int bext; unsigned short *u;
  124. {
  125.  unsigned int pos; unsigned long result;
  126.  pos = scan_nbblong(s,n,base,bext,&result);
  127.  *u = result; return pos;
  128. }
  129.  
  130. unsigned int scan_charsetnskip(s,chars,n) char *s; char *chars; unsigned int n;
  131. {
  132.  unsigned int pos;
  133.  pos = 0;
  134.  while (chars[s[pos]]) /* user's responsibility to check for null */
  135.    if (++pos == n)
  136.      break;
  137.  return pos;
  138. }
  139.  
  140. unsigned int scan_noncharsetnskip(s,chars,n) char *s; char *chars; unsigned int n;
  141. {
  142.  unsigned int pos;
  143.  pos = 0;
  144.  while (!chars[s[pos]]) /* again, user's responsibility to check for null */
  145.    if (++pos == n)
  146.      break;
  147.  return pos;
  148. }
  149.  
  150. unsigned int scan_whitenskip(s,n) char *s; unsigned int n;
  151. {
  152.  unsigned int pos; char c;
  153.  pos = 0;
  154.  while (((c = s[pos]) == space) || (c == tab)) /* XXX: this is slow */
  155.    if (++pos == n)
  156.      break;
  157.  return pos;
  158. }
  159.  
  160. unsigned int scan_nonwhitenskip(s,n) char *s; unsigned int n;
  161. {
  162.  unsigned int pos; char c;
  163.  pos = 0;
  164.  /* This is the only function without ``str'' in its name where we
  165.     check specially for nulls. */
  166.  while ((c = s[pos]) && (c != space) && (c != tab)) /* XXX: this is slow */
  167.    if (++pos == n)
  168.      break;
  169.  return pos;
  170. }
  171.  
  172. unsigned int scan_strncmp(s,t,n) char *s; char *t; unsigned int n;
  173. {
  174.  unsigned int pos; char c;
  175.  pos = 0;
  176.  while ((c = s[pos]) && (c == t[pos]))
  177.    if (++pos == n)
  178.      break;
  179.  return pos;
  180. }
  181.  
  182. unsigned int scan_memcmp(s,t,n) char *s; char *t; unsigned int n;
  183. /* This is the only function where n == 0 means do nothing. */
  184. {
  185.  unsigned int pos;
  186.  pos = 0;
  187.  while (n) if (s[pos] != t[pos]) break; else { --n; ++pos; }
  188.  return pos;
  189. }
  190.