home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_09_06 / 9n06014a < prev    next >
Text File  |  1991-05-06  |  3KB  |  119 lines

  1. /* _Fmtval function */
  2. #include <limits.h>
  3. #include <locale.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6.  
  7.  
  8.         /* macros */
  9. #define FN_INT_CUR    -2
  10. #define FN_LCL_CUR    -1
  11.  
  12.  
  13. char *_Fmtval(char *buf, double d, int fdarg)
  14.     {    /* format number by locale-specific rules */
  15.     char *cur_sym, dec_pt, *grps, grp_sep, *sign;
  16.     const char *fmt;
  17.     int fd, neg;
  18.     struct lconv *p = localeconv();
  19.  
  20.  
  21.     if (0 <= d)
  22.         neg = 0;
  23.     else
  24.         d = -d, neg = 1;
  25.     if (fdarg == FN_INT_CUR)
  26.         {    /* get international currency parameters */
  27.         cur_sym = p->int_curr_symbol;
  28.         dec_pt = p->mon_decimal_point[0];
  29.         fmt = "$-V";
  30.         fd = p->int_frac_digits;
  31.         grps = p->mon_grouping;
  32.         grp_sep = p->mon_thousands_sep[0];
  33.         sign = neg ? p->negative_sign : p->positive_sign;
  34.         }
  35.     else if (fdarg == FN_LCL_CUR)
  36.         {    /* get local currency parameters */
  37.         static const char *ftab[5][2][2] = {
  38.             "(V$)",  "-V$",  "V$-",  "V-$",  "V$-",
  39.             "($V)",  "-$V",  "$V-",  "-$V",  "$-V",
  40.             "(V $)", "-V $", "V $-", "V- $", "V $-",
  41.             "($ V)", "-$ V", "$ V-", "-$ V", "$ -V"};
  42.  
  43.  
  44.         cur_sym = p->currency_symbol;
  45.         dec_pt = p->mon_decimal_point[0];
  46.         if (neg)
  47.             fmt = ftab[p->n_sign_posn < 0 || 4 < p->n_sign_posn
  48.                 ? 0 : p->n_sign_posn][p->n_cs_precedes == 1]
  49.                 [p->n_sep_by_space == 1];
  50.         else
  51.             fmt = ftab[p->p_sign_posn < 0 || 4 < p->p_sign_posn
  52.                 ? 0 : p->p_sign_posn][p->p_cs_precedes == 1]
  53.                 [p->p_sep_by_space == 1];
  54.         fd = p->frac_digits;
  55.         grps = p->mon_grouping;
  56.         grp_sep = p->mon_thousands_sep[0];
  57.         sign = neg ? p->negative_sign : p->positive_sign;
  58.         }
  59.     else
  60.         {    /* get numeric parameters (cur_sym not used) */
  61.         dec_pt = p->decimal_point[0];
  62.         fmt = "-V";
  63.         fd = fdarg;
  64.         grps = p->grouping;
  65.         grp_sep = p->thousands_sep[0];
  66.         sign = neg ? "-" : "";
  67.         }
  68.      {    /* build string in buf under control of fmt */
  69.     char *end, *s;
  70.     const char *g;
  71.     size_t i, ns;
  72.  
  73.  
  74.     for (s = buf; *fmt; ++fmt, s += strlen(s))
  75.         switch (*fmt)
  76.             {    /* process a format char */
  77.         case '$':    /* insert currency symbol string */
  78.             strcpy(s, cur_sym);
  79.             break;
  80.         case '-':    /* insert sign string */
  81.             strcpy(s, sign);
  82.             break;
  83.         default:    /* insert literal format char */
  84.             *s++ = *fmt, *s = '\0';
  85.             break;
  86.         case 'V':    /* insert formatted value */
  87.             sprintf(s, "%#.*f",
  88.                 0 < fd && fd != CHAR_MAX ? fd : 0, d);
  89.             end = strchr(s, p->decimal_point[0]);
  90.             for (ns = 0, i = end - s, g = grps; 0 < i; ++ns)
  91.                 {    /* count separators to add */
  92.                 if (g[0] <= 0 || i <= g[0] || g[0] == CHAR_MAX)
  93.                     break;
  94.                 i -= g[0];
  95.                 if (g[1] != 0)
  96.                     ++g;
  97.                 }
  98.             memmove(end + ns, end, strlen(end) + 1);
  99.             i = end - s, end += ns;
  100.             *end = 0 <= fd && fd != CHAR_MAX ? dec_pt : '\0';
  101.             for (g = grps; 0 < i; --ns)
  102.                 {    /* copy up and insert separators */
  103.                 if (g[0] <= 0 || i <= g[0] || g[0] == CHAR_MAX)
  104.                     break;
  105.                 i -= g[0], end -= g[0];
  106.                 memmove(end, end - ns, g[0]);
  107.                 *--end = grp_sep;
  108.                 if (g[1] != 0)
  109.                     ++g;
  110.                 }
  111.             }
  112.      }
  113.     return (buf);
  114. -    }
  115.  
  116.  
  117.  
  118.  
  119.