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

  1. /* fmt.c, fmt.h: formatting library
  2. Daniel J. Bernstein, brnstnd@nyu.edu.
  3. No dependencies.
  4. No environment requirements.
  5. 10/5/91: Cleaned up fmt_rvis, added fmt_unrvis.
  6. 9/1/91: Added fmt_nvis, fmt_rvis.
  7. 8/28/91: Added fmt_vis.
  8. 7/18/91: Baseline. fmt 1.0, public domain.
  9. No known patent problems.
  10.  
  11. XXX: still need floating-point formatting
  12.  
  13. */
  14.  
  15. #include "fmt.h"
  16.  
  17. /* To find out the actual length of the formatted value, pass a first
  18. argument of (char *) 0. */
  19.  
  20. #define zero '0'
  21. #define alow 'a'
  22. #define plus '+'
  23. #define minus '-'
  24. #define xlow 'x'
  25.  
  26. unsigned int fmt_ulong(s,u) char *s; unsigned long u;
  27. {
  28.  unsigned int len; unsigned long q;
  29.  len = 1; q = u;
  30.  while (q > 9) { ++len; q /= 10; }
  31.  if (s)
  32.   {
  33.    s += len;
  34.    do { *--s = zero + (u % 10); u /= 10; } while(u); /* handles u == 0 */
  35.   }
  36.  return len;
  37. }
  38.  
  39. unsigned int fmt_xlong(s,u) char *s; unsigned long u;
  40. {
  41.  unsigned int len; unsigned long q; unsigned long c;
  42.  len = 1; q = u;
  43.  while (q > 15) { ++len; q /= 16; }
  44.  if (s)
  45.   {
  46.    s += len;
  47.    do { c = u & 15; *--s = (c > 9 ? alow - 10 : zero) + c; u /= 16; } while(u);
  48.   }
  49.  return len;
  50. }
  51.  
  52. unsigned int fmt_nbblong(s,n,base,bext,u)
  53. char *s; unsigned int n; unsigned int base; unsigned int bext; unsigned long u;
  54. /* I hope this meaning of n (min, not max) doesn't hurt anything. */
  55. {
  56.  unsigned int len; unsigned long q; unsigned long c;
  57.  len = 1; q = u; bext += base;
  58.  while (q > bext - 1) { ++len; q /= bext; } if (len < n) len = n;
  59.  if (s)
  60.   {
  61.    s += len;
  62.    do { c = u % bext; *--s = (c >= base ? alow - base : zero) + c; u /= bext; }
  63.    while(u);
  64.   }
  65.  return len;
  66. }
  67.  
  68. unsigned int fmt_ushort(s,u) char *s; unsigned short u;
  69. {
  70.  unsigned long l; l = u; return fmt_ulong(s,l);
  71. }
  72.  
  73. unsigned int fmt_xshort(s,u) char *s; unsigned short u;
  74. {
  75.  unsigned long l; l = u; return fmt_xlong(s,l);
  76. }
  77.  
  78. unsigned int fmt_nbbshort(s,n,base,bext,u)
  79. char *s; unsigned int n; unsigned int base; unsigned int bext; unsigned short u;
  80. {
  81.  unsigned long l; l = u; return fmt_nbblong(s,n,base,bext,l);
  82. }
  83.  
  84. unsigned int fmt_uint(s,u) char *s; unsigned int u;
  85. {
  86.  unsigned long l; l = u; return fmt_ulong(s,l);
  87. }
  88.  
  89. unsigned int fmt_xint(s,u) char *s; unsigned int u;
  90. {
  91.  unsigned long l; l = u; return fmt_xlong(s,l);
  92. }
  93.  
  94. unsigned int fmt_nbbint(s,n,base,bext,u)
  95. char *s; unsigned int n; unsigned int base; unsigned int bext; unsigned int u;
  96. {
  97.  unsigned long l; l = u; return fmt_nbblong(s,n,base,bext,l);
  98. }
  99.  
  100. unsigned int fmt_plusminus(s,sign) char *s; int sign;
  101. {
  102.  if (s) *s = ((sign < 0) ? minus : plus); return 1;
  103. }
  104.  
  105. unsigned int fmt_minus(s,sign) char *s; int sign;
  106. {
  107.  if (sign > 0) return 0;
  108.  if (s) *s = minus; return 1;
  109. }
  110.  
  111. unsigned int fmt_0x(s,base) char *s; int base;
  112. {
  113.  if (base == 10) return 0;
  114.  if (s) *s = zero; if (base == 8) return 1;
  115.  if (s) s[1] = xlow; return 2;
  116. }
  117.  
  118. unsigned int fmt_strncpy(s,t,n) char *s; char *t; unsigned int n;
  119. {
  120.  unsigned int len;
  121.  len = 0;
  122.  if (s) { while (s[len] = t[len]) if (++len == n) break; }
  123.  else { while (t[len]) if (++len == n) break; }
  124.  return len;
  125. }
  126.  
  127. unsigned int fmt_memcpy(s,t,n) char *s; char *t; unsigned int n;
  128. /* This and fmt_vis are the only functions where n == 0 means do nothing. */
  129. {
  130.  unsigned int len;
  131.  if (s)
  132.    for (len = 0;len < n;++len)
  133.      s[len] = t[len];
  134.  return n;
  135. }
  136.  
  137. static unsigned int fmt_xvis(s,t,n,x) char *s; char *t; unsigned int n; int x;
  138. {
  139.  unsigned int len;
  140.  for (len = 0;n;--n,++t)
  141.   {
  142.    int ch;
  143.    ch = (int) (unsigned int) (unsigned char) *t;
  144.    /* XXX: ASCII dependent! */
  145.    if (ch > 127)
  146.     { if (s) { s[len] = 'M'; s[len + 1] = '-'; } len += 2; ch -= 128; }
  147.    if (((ch >= 32) && (ch <= 126)) || (ch == x))
  148.     { if (s) s[len] = ch; ++len; continue; }
  149.    if (s) s[len] = '^'; ++len;
  150.    if (s) s[len] = 64 + (ch & 31) - 32 * (ch == 127); ++len;
  151.   }
  152.  return len;
  153. }
  154.  
  155. unsigned int fmt_vis(s,t,n) char *s; char *t; unsigned int n;
  156. {
  157.  return fmt_xvis(s,t,n,-1);
  158. }
  159.  
  160. unsigned int fmt_nvis(s,t,n) char *s; char *t; unsigned int n;
  161. {
  162.  return fmt_xvis(s,t,n,'\n');
  163. }
  164.  
  165. /* invertible! */
  166. unsigned int fmt_rvis(s,t,n) char *s; char *t; unsigned int n;
  167. {
  168.  unsigned int len;
  169.  for (len = 0;n;--n,++t)
  170.   {
  171.    int ch;
  172.    ch = (int) (unsigned int) (unsigned char) *t;
  173.    /* XXX: ASCII dependent! */
  174.    if ((ch >= 32) && (ch <= 126) && (ch != '^'))
  175.     { if (s) s[len] = ch; ++len; continue; }
  176.    if (ch == 127)
  177.     { if (s) { s[len] = '^'; s[len + 1] = '?'; } len += 2; continue; }
  178.    if (ch == '^')
  179.     { if (s) { s[len] = '^'; s[len + 1] = ' '; } len += 2; continue; }
  180.    if (ch == 10)
  181.     { if (s) { s[len] = '^'; s[len + 1] = '$'; } len += 2; continue; }
  182.    if ((ch >= 0) && (ch <= 31))
  183.     { if (s) { s[len] = '^'; s[len + 1] = 64 + (ch & 31); } len += 2; continue; }
  184.    if (s) { s[len] = '^'; s[len + 1] = 'x'; } len += 2;
  185.    if (s) { s[len] = (ch >= 160) ? alow + ((ch/16) - 10) : zero + (ch/16); }
  186.    ++len; ch = ch & 15;
  187.    if (s) { s[len] = (ch >= 10) ? alow + (ch - 10) : zero + ch; }
  188.    ++len;
  189.   }
  190.  s[len] = '\n';
  191.  return len + 1;
  192. }
  193.  
  194. unsigned int fmt_unrvis(s,t,n) char *s; char *t; unsigned int n;
  195. {
  196.  unsigned int len;
  197.  for (len = 0;n;--n,++t)
  198.   {
  199.    if (*t == '\n')
  200.      continue;
  201.    if (*t != '^')
  202.     {
  203.      if (s) *s++ = *t; ++len;
  204.      continue;
  205.     }
  206.    if (n < 2)
  207.      return len;
  208.    ++t; --n;
  209.    if (*t == '?')
  210.     { if (s) *s++ = 127; ++len; continue; }
  211.    if (*t == ' ')
  212.     { if (s) *s++ = '^'; ++len; continue; }
  213.    if ((*t >= 64) && (*t <= 95))
  214.     { if (s) *s++ = *t - 64; ++len; continue; }
  215.    if (*t == '$')
  216.     { if (s) *s++ = 10; ++len; continue; }
  217.    if (n < 3)
  218.      return len;
  219.    if (*t != 'x')
  220.      return len; /* XXX */
  221.    ++t;
  222.    if (s)
  223.      if (*t < alow)
  224.        *s = *t - zero;
  225.      else
  226.        *s = *t - alow + 10;
  227.    if (s)
  228.      *s <<= 4;
  229.    ++t;
  230.    if (s)
  231.      if (*t < alow)
  232.        *s += *t - zero;
  233.      else
  234.        *s += *t - alow + 10;
  235.    if (s) ++s;
  236.    ++len; n -= 2;
  237.   }
  238.  return len;
  239. }
  240.