/* Extract from stream the longest string made up of alphanumeric char and
   '_' (i.e. n-char-sequence).
   The user must free the returned string. */
static char *
extract_suffix (FILE *stream)
{
  int c;
  size_t nread = 0;
  size_t strsize = 100;
  char *str = mpc_alloc_str (strsize);

  c = getc (stream);
  while (isalnum ((unsigned char) c) || c == '_') {
    str [nread] = (char) c;
    nread++;
    if (nread == strsize) {
      str = mpc_realloc_str (str, strsize, 2 * strsize);
      strsize *= 2;
         }
    c = getc (stream);
  }

  str = mpc_realloc_str (str, strsize, nread + 1);
  strsize = nread + 1;
  str [nread] = '\0';

  if (c != EOF)
    ungetc (c, stream);
  return str;
}
Beispiel #2
0
char *
mpc_get_str (int base, size_t n, mpc_srcptr op, mpc_rnd_t rnd)
{
  size_t needed_size;
  char *real_str;
  char *imag_str;
  char *complex_str = NULL;

  if (base < 2 || base > 36)
    return NULL;

  real_str = get_pretty_str (base, n, MPC_RE (op), MPC_RND_RE (rnd));
  imag_str = get_pretty_str (base, n, MPC_IM (op), MPC_RND_IM (rnd));

  needed_size = strlen (real_str) + strlen (imag_str) + 4;

  complex_str = mpc_alloc_str (needed_size);
MPC_ASSERT (complex_str != NULL);

  strcpy (complex_str, "(");
  strcat (complex_str, real_str);
  strcat (complex_str, " ");
  strcat (complex_str, imag_str);
  strcat (complex_str, ")");

  mpc_free_str (real_str);
  mpc_free_str (imag_str);

  return complex_str;
}
Beispiel #3
0
static char *
pretty_zero (mpfr_srcptr zero)
{
  char *pretty;

  pretty = mpc_alloc_str (3);

  pretty[0] = mpfr_signbit (zero) ? '-' : '+';
  pretty[1] = '0';
  pretty[2] = '\0';

  return pretty;
}
/* Extract from the stream the longest string of characters which are neither
   whitespace nor brackets (except for an optional bracketed n-char_sequence
   directly following nan or @nan@ independently of case).
   The user must free the returned string.                                    */
static char *
extract_string (FILE *stream)
{
  int c;
  size_t nread = 0;
  size_t strsize = 100;
  char *str = mpc_alloc_str (strsize);
  size_t lenstr;

  c = getc (stream);
  while (c != EOF && c != '\n'
         && !isspace ((unsigned char) c)
         && c != '(' && c != ')') {
    str [nread] = (char) c;
    nread++;
    if (nread == strsize) {
      str = mpc_realloc_str (str, strsize, 2 * strsize);
      strsize *= 2;
    }
    c = getc (stream);
  }

  str = mpc_realloc_str (str, strsize, nread + 1);
  strsize = nread + 1;
  str [nread] = '\0';

  if (nread == 0)
    return str;

  lenstr = nread;

  if (c == '(') {
    size_t n;
    char *suffix;
    int ret;

    /* (n-char-sequence) only after a NaN */
    if ((nread != 3
         || tolower ((unsigned char) (str[0])) != 'n'
         || tolower ((unsigned char) (str[1])) != 'a'
         || tolower ((unsigned char) (str[2])) != 'n')
        && (nread != 5
            || str[0] != '@'
            || tolower ((unsigned char) (str[1])) != 'n'
            || tolower ((unsigned char) (str[2])) != 'a'
            || tolower ((unsigned char) (str[3])) != 'n'
            || str[4] != '@')) {
      ungetc (c, stream);
      return str;
    }

    suffix = extract_suffix (stream);
    nread += strlen (suffix) + 1;
    if (nread >= strsize) {
      str = mpc_realloc_str (str, strsize, nread + 1);
      strsize = nread + 1;
    }

    /* Warning: the sprintf does not allow overlap between arguments. */
    ret = sprintf (str + lenstr, "(%s", suffix);
    MPC_ASSERT (ret >= 0);
    n = lenstr + (size_t) ret;
    MPC_ASSERT (n == nread);

    c = getc (stream);
    if (c == ')') {
      str = mpc_realloc_str (str, strsize, nread + 2);
      strsize = nread + 2;
      str [nread] = (char) c;
      str [nread+1] = '\0';
      nread++;
    }
    else if (c != EOF)
      ungetc (c, stream);

    mpc_free_str (suffix);
  }
  else if (c != EOF)
    ungetc (c, stream);

  return str;
}
int
mpc_inp_str (mpc_ptr rop, FILE *stream, size_t *read, int base,
mpc_rnd_t rnd_mode)
{
   size_t white, nread = 0;
   int inex = -1;
   int c;
   char *str;

   if (stream == NULL)
      stream = stdin;

   white = skip_whitespace (stream);
   c = getc (stream);
   if (c != EOF) {
     if (c == '(') {
       char *real_str;
       char *imag_str;
       size_t n;
       int ret;

       nread++; /* the opening parenthesis */
       white = skip_whitespace (stream);
       real_str = extract_string (stream);
       nread += strlen(real_str);

       c = getc (stream);
       if (!isspace ((unsigned int) c)) {
         if (c != EOF)
           ungetc (c, stream);
         mpc_free_str (real_str);
         goto error;
       }
       else
         ungetc (c, stream);

       white += skip_whitespace (stream);
       imag_str = extract_string (stream);
       nread += strlen (imag_str);

       str = mpc_alloc_str (nread + 2);
       ret = sprintf (str, "(%s %s", real_str, imag_str);
       MPC_ASSERT (ret >= 0);
       n = (size_t) ret;
       MPC_ASSERT (n == nread + 1);
       mpc_free_str (real_str);
       mpc_free_str (imag_str);

       white += skip_whitespace (stream);
       c = getc (stream);
       if (c == ')') {
         str = mpc_realloc_str (str, nread +2, nread + 3);
         str [nread+1] = (char) c;
         str [nread+2] = '\0';
         nread++;
       }
       else if (c != EOF)
         ungetc (c, stream);
     }
     else {
       if (c != EOF)
         ungetc (c, stream);
       str = extract_string (stream);
       nread += strlen (str);
     }

     inex = mpc_set_str (rop, str, base, rnd_mode);

     mpc_free_str (str);
   }

error:
   if (inex == -1) {
      mpfr_set_nan (MPC_RE(rop));
      mpfr_set_nan (MPC_IM(rop));
   }
   if (read != NULL)
     *read = white + nread;
   return inex;
}
Beispiel #6
0
static char *
prettify (const char *str, const mp_exp_t expo, int base, int special)
{
  size_t sz;
  char *pretty;
  char *p;
  const char *s;
  mp_exp_t x;
  int sign;

  sz = strlen (str) + 1; /* + terminal '\0' */

  if (special)
    {
      /* special number: nan or inf */
      pretty = mpc_alloc_str (sz);
      strcpy (pretty, str);

      return pretty;
    }

  /* regular number */

  sign = (str[0] == '-' || str[0] == '+');

  x = expo - 1; /* expo is the exponent value with decimal point BEFORE
                   the first digit, we wants decimal point AFTER the first
                   digit */
  if (base == 16)
    x <<= 2; /* the output exponent is a binary exponent */

  ++sz; /* + decimal point */

  if (x != 0)
    {
      /* augment sz with the size needed for an exponent written in base
         ten */
      mp_exp_t xx;

      sz += 3; /* + exponent char + sign + 1 digit */

      if (x < 0)
        {
          /* avoid overflow when changing sign (assuming that, for the
             mp_exp_t type, (max value) is greater than (- min value / 10)) */
          if (x < -10)
            {
              xx = - (x / 10);
              sz++;
            }
          else
            xx = -x;
        }
      else
        xx = x;

      /* compute sz += floor(log(expo)/log(10)) without using libm
         functions */
      while (xx > 9)
        {
          sz++;
          xx /= 10;
        }
    }

  pretty = mpc_alloc_str (sz);
  p = pretty;

  /* 1. optional sign plus first digit */
  s = str;
  *p++ = *s++;
  if (sign)
    *p++ = *s++;

  /* 2. decimal point */
#ifdef HAVE_LOCALECONV
  *p++ = *localeconv ()->decimal_point;
#else
  *p++ = '.';
#endif
  *p = '\0';

  /* 3. other significant digits */
  strcat (pretty, s);

  /* 4. exponent (in base ten) */
  if (x == 0)
    return pretty;

  p = pretty + strlen (str) + 1;

  switch (base)
    {
    case 10:
      *p++ = 'e';
      break;
    case 2:
    case 16:
      *p++ = 'p';
      break;
    default:
      *p++ = '@';
    }

  *p = '\0';

  sprintf (p, "%+"MPC_EXP_FORMAT_SPEC, x);

  return pretty;
}