Example #1
0
void report_break (char* message)
{
  mps_lib_FILE *stream = mps_lib_get_stdout();  
  mps_lib_fputs("Break to debugger:\n    ", stream);
  mps_lib_fputs(message, stream);
  mps_lib_fputc('\n', stream);
  DebugBreak();
}
Example #2
0
void report_error (char* message)
{
  mps_lib_FILE *stream = mps_lib_get_stderr();  
  mps_lib_fputs("\nError:\n", stream);
  mps_lib_fputs(message, stream);
  mps_lib_fputc('\n', stream);
  mps_lib_abort();
}
Example #3
0
void display_integer (int integer, mps_lib_FILE *stream)
{  /* This is naieve. Assume no more than 7 digits */
  int remainder = integer;
  int leading = 1;
  int power;
  if (integer == 0) {
    /* special case needs the leading zero */
      mps_lib_fputs("       0", stream);
      return;
  }
  for (power = 10000000; power > 0; power = power / 10) {
    int exponent = (int)(log10(power));
    int digit = remainder / power;
    remainder = remainder % power;
    if (digit == 0) {
      mps_lib_fputc(leading ? ' ' : '0', stream);
    } else {
      leading = 0;
      mps_lib_fputc('0' + digit, stream);
    };
    if ((exponent == 6) || (exponent == 3))
      if (digit == 0) {
	mps_lib_fputc(leading ? ' ' : ',', stream);
      } else
	mps_lib_fputc(',', stream);
  }
}
Example #4
0
void display_wrapper_stats ()
{
  int largest;
  mps_lib_FILE *stream = mps_lib_get_stdout();
  char *message = "Start of heap statistics";
  mps_lib_fputc('\n', stream);
  mps_lib_fputs(message, stream);
  display_padding_for_string(message, ' ', class_name_size, stream);
  mps_lib_fputs("   (count)     (size)", stream);
  mps_lib_fputs("\n\n", stream);
  display_totals(stream);
  mps_lib_fputc('\n', stream);
  for (largest = biggest_below_value(very_big); 
       largest >= 0; 
       largest = biggest_below_value(largest)) {
    display_wrappers_of_size(largest, stream);
  }
  mps_lib_fputs("End of heap statistics\n\n", stream);
}
Example #5
0
void display_wrapper_breakpoints()
{
  mps_lib_FILE *stream = mps_lib_get_stdout();
  if (wrapper_breaks_cursor >= 0)
    {
      int i;
      mps_lib_fputs("Object allocation breakpoints\n\n", stream);
      mps_lib_fputs("   (class-name)                                    (count)\n\n", stream);
      for (i = 0; i < wrapper_breaks_cursor + 1; i++) {
        wrapper_stats_t wrapper_record = wrapper_breaks + i;
        char *class_name = class_name_from_wrapper(wrapper_record->wrapper_address);

        mps_lib_fputs_(class_name, class_name_size, stream);
        display_padding_for_string(class_name, ' ', class_name_size, stream);
        display_integer(wrapper_record->usage_size, stream);
        mps_lib_fputc('\n', stream);
      }
    }
  else
    mps_lib_fputs("No active object allocation breakpoints\n\n", stream);
}
Example #6
0
static Res WriteULongest(mps_lib_FILE *stream, ULongest w, unsigned base,
                         unsigned width)
{
    static const char digit[16 + 1] = "0123456789ABCDEF";
    /* + 1 for terminator: unused, but prevents compiler warning */
    static const char pad = '0'; /* padding character */
    char buf[MPS_WORD_WIDTH + 1]; /* enough for binary, */
    /* plus one for terminator */
    unsigned i;
    int r;

    AVER(stream != NULL);
    AVER(2 <= base);
    AVER(base <= 16);
    AVER(width <= MPS_WORD_WIDTH);

    /* Add digits to the buffer starting at the right-hand end, so that */
    /* the buffer forms a string representing the number.  A do...while */
    /* loop is used to ensure that at least one digit (zero) is written */
    /* when the number is zero. */
    i = MPS_WORD_WIDTH;
    buf[i] = '\0';
    do {
        --i;
        buf[i] = digit[w % base];
        w /= base;
    } while(w > 0);

    /* If the number is not as wide as the requested field, pad out the */
    /* buffer with zeros. */
    while(i > MPS_WORD_WIDTH - width) {
        --i;
        buf[i] = pad;
    }

    r = mps_lib_fputs(&buf[i], stream);
    if (r == mps_lib_EOF)
        return ResIO;

    return ResOK;
}
Example #7
0
void report_message (char* message)
{
  mps_lib_FILE *stream = mps_lib_get_stdout();  
  mps_lib_fputs(message, stream);
}
Example #8
0
Res WriteF_firstformat_v(mps_lib_FILE *stream,
                         const char *firstformat, va_list args)
{
    const char *format;
    int r;
    size_t i;
    Res res;

    AVER(stream != NULL);

    format = firstformat;

    for(;;) {
        if (format == NULL)
            break;

        while(*format != '\0') {
            if (*format != '$') {
                r = mps_lib_fputc(*format, stream); /* Could be more efficient */
                if (r == mps_lib_EOF) return ResIO;
            } else {
                ++format;
                AVER(*format != '\0');

                switch(*format) {
                case 'A': {                   /* address */
                    WriteFA addr = va_arg(args, WriteFA);
                    res = WriteULongest(stream, (ULongest)addr, 16,
                                        (sizeof(WriteFA) * CHAR_BIT + 3) / 4);
                    if (res != ResOK) return res;
                }
                break;

                case 'P': {                   /* pointer, see .writef.p */
                    WriteFP p = va_arg(args, WriteFP);
                    res = WriteULongest(stream, (ULongest)p, 16,
                                        (sizeof(WriteFP) * CHAR_BIT + 3)/ 4);
                    if (res != ResOK) return res;
                }
                break;

                case 'F': {                   /* function */
                    WriteFF f = va_arg(args, WriteFF);
                    Byte *b = (Byte *)&f;
                    /* ISO C forbits casting function pointers to integer, so
                       decode bytes (see design.writef.f).
                       TODO: Be smarter about endianness. */
                    for(i=0; i < sizeof(WriteFF); i++) {
                        res = WriteULongest(stream, (ULongest)(b[i]), 16,
                                            (CHAR_BIT + 3) / 4);
                        if (res != ResOK) return res;
                    }
                }
                break;

                case 'S': {                   /* string */
                    WriteFS s = va_arg(args, WriteFS);
                    r = mps_lib_fputs((const char *)s, stream);
                    if (r == mps_lib_EOF) return ResIO;
                }
                break;

                case 'C': {                   /* character */
                    WriteFC c = va_arg(args, WriteFC); /* promoted */
                    r = mps_lib_fputc((int)c, stream);
                    if (r == mps_lib_EOF) return ResIO;
                }
                break;

                case 'W': {                   /* word */
                    WriteFW w = va_arg(args, WriteFW);
                    res = WriteULongest(stream, (ULongest)w, 16,
                                        (sizeof(WriteFW) * CHAR_BIT + 3) / 4);
                    if (res != ResOK) return res;
                }
                break;

                case 'U': {                   /* decimal, see .writef.p */
                    WriteFU u = va_arg(args, WriteFU);
                    res = WriteULongest(stream, (ULongest)u, 10, 0);
                    if (res != ResOK) return res;
                }
                break;

                case '3': {                   /* decimal for thousandths */
                    WriteFU u = va_arg(args, WriteFU);
                    res = WriteULongest(stream, (ULongest)u, 10, 3);
                    if (res != ResOK) return res;
                }
                break;

                case 'B': {                   /* binary, see .writef.p */
                    WriteFB b = va_arg(args, WriteFB);
                    res = WriteULongest(stream, (ULongest)b, 2, sizeof(WriteFB) * CHAR_BIT);
                    if (res != ResOK) return res;
                }
                break;

                case '$': {                   /* dollar char */
                    r = mps_lib_fputc('$', stream);
                    if (r == mps_lib_EOF) return ResIO;
                }
                break;

                case 'D': {                   /* double */
                    WriteFD d = va_arg(args, WriteFD);
                    res = WriteDouble(stream, d);
                    if (res != ResOK) return res;
                }
                break;

                default:
                    NOTREACHED;
                }
            }

            ++format;
        }

        format = va_arg(args, const char *);
    }

    return ResOK;
}
Example #9
0
static Res WriteDouble(mps_lib_FILE *stream, double d)
{
    double F = d;
    int E = 0, i, x = 0;
    /* Largest exponent that will print in %f style.  Larger will use %e */
    /* style.  DBL_DIG is chosen for use of doubles as extra-large integers. */
    int expmax = DBL_DIG;
    /* Smallest exponent that will print in %f style.  Smaller will use */
    /* %e style.  -4 is chosen because it is the %g default. */
    int expmin = -4;
    /* Epsilon defines how many digits will be printed.  Using DBL_EPSILON */
    /* prints all the significant digits.  To print fewer digits, set */
    /* epsilon to 10 ^ - N, where N is the desired number of digits. */
    double epsilon = DBL_EPSILON / 2;
    char digits[] = "0123456789";
    /* sign, DBL_DIG, '0.', 'e', '+/-', log10(DBL_MAX_10_EXP), */
    /* terminator.  See .write.double.check. */
    char buf[1+DBL_DIG+2+1+1+DBL_DIG+1];
    int j = 0;

    if (F == 0.0) {
        if (mps_lib_fputs("0", stream) == mps_lib_EOF)
            return ResIO;
        return ResOK;
    }

    if (F < 0) {
        buf[j] = '-';
        j++;
        F = - F;
    }

    /* This scaling operation could introduce rounding errors. */
    for ( ; F >= 1.0 ; F /= 10.0) {
        E++;
        if (E > DBL_MAX_10_EXP) {
            if (mps_lib_fputs("Infinity", stream) == mps_lib_EOF)
                return ResIO;
            return ResOK;
        }
    }
    for ( ; F < 0.1; F *= 10)
        E--;

    /* See if %e notation is required */
    if (E > expmax || E <= expmin) {
        x = E - 1;
        E = 1;
    }

    /* Insert leading 0's */
    if (E <= 0) {
        buf[j] = '0';
        j++;
    }
    if (E < 0) {
        buf[j] = '.';
        j++;
    }
    for (i = -E; i > 0; i--) {
        buf[j] = '0';
        j++;
    }

    /* Convert the fraction to base 10, inserting a decimal according to */
    /* the exponent.  This is Steele and White's FP3 algorithm. */
    do {
        int U;

        if (E == 0) {
            buf[j] = '.';
            j++;
        }
        F *= 10.0;
        U = (int)F;
        F = F - U;
        epsilon *= 10.0;
        E--;
        if (F < epsilon || F > 1.0 - epsilon) {
            if (F < 0.5)
                buf[j] = digits[U];
            else
                buf[j] = digits[U + 1];
            j++;
            break;
        }
        buf[j] = digits[U];
        j++;
    } while (1);

    /* Insert trailing 0's */
    for (i = E; i > 0; i--) {
        buf[j] = '0';
        j++;
    }

    /* If %e notation is selected, append the exponent indicator and sign. */
    if (x != 0) {
        buf[j] = 'e';
        j++;
        if (x < 0) {
            buf[j] = '-';
            j++;
            x = - x;
        }
        else {
            buf[j] = '+';
            j++;
        }

        /* Format the exponent to at least two digits. */
        for (i = 100; i <= x; )
            i *= 10;
        i /= 10;
        do {
            buf[j] = digits[x / i];
            j++;
            x %= i;
            i /= 10;
        } while (i > 0);
    }
    buf[j] = '\0';                /* arnold */

    if (mps_lib_fputs(buf, stream) == mps_lib_EOF)
        return ResIO;
    return ResOK;
}
Res WriteF(mps_lib_FILE *stream, ...)
{
  const char *format;
  int r;
  size_t i;
  Res res;
  va_list args;

  AVER(stream != NULL);
 
  va_start(args, stream);

  for(;;) {
    format = va_arg(args, const char *);
    if (format == NULL)
      break;

    while(*format != '\0') {
      if (*format != '$') {
        r = mps_lib_fputc(*format, stream); /* Could be more efficient */
        if (r == mps_lib_EOF) return ResIO;
      } else {
        ++format;
        AVER(*format != '\0');

        switch(*format) {
          case 'A': {                   /* address */
            WriteFA addr = va_arg(args, WriteFA);
            res = WriteWord(stream, (Word)addr, 16,
                            (sizeof(WriteFA) * CHAR_BIT + 3) / 4);
            if (res != ResOK) return res;
          } break;

          case 'P': {                   /* pointer, see .writef.p */
            WriteFP p = va_arg(args, WriteFP);
            res = WriteWord(stream, (Word)p, 16,
                            (sizeof(WriteFP) * CHAR_BIT + 3)/ 4);
            if (res != ResOK) return res;
          } break;

          case 'F': {                   /* function */
            WriteFF f = va_arg(args, WriteFF);
            WriteFF *fp = &f; /* dodge to placate splint */
            Byte *b = *((Byte **)&fp);
            for(i=0; i < sizeof(WriteFF); i++) {
              res = WriteWord(stream, (Word)(b[i]), 16,
                              (CHAR_BIT + 3) / 4);
              if (res != ResOK) return res;
            }
          } break;
           
          case 'S': {                   /* string */
            WriteFS s = va_arg(args, WriteFS);
            r = mps_lib_fputs((const char *)s, stream);
            if (r == mps_lib_EOF) return ResIO;
          } break;
       
          case 'C': {                   /* character */
            WriteFC c = va_arg(args, WriteFC); /* promoted */
            r = mps_lib_fputc((int)c, stream);
            if (r == mps_lib_EOF) return ResIO;
          } break;
       
          case 'W': {                   /* word */
            WriteFW w = va_arg(args, WriteFW);
            res = WriteWord(stream, (Word)w, 16,
                            (sizeof(WriteFW) * CHAR_BIT + 3) / 4);
            if (res != ResOK) return res;
          } break;

          case 'U': {                   /* decimal, see .writef.p */
            WriteFU u = va_arg(args, WriteFU);
            res = WriteWord(stream, (Word)u, 10, 0);
            if (res != ResOK) return res;
          } break;

          case 'B': {                   /* binary, see .writef.p */
            WriteFB b = va_arg(args, WriteFB);
            res = WriteWord(stream, (Word)b, 2, sizeof(WriteFB) * CHAR_BIT);
            if (res != ResOK) return res;
          } break;
       
          case '$': {                   /* dollar char */
            r = mps_lib_fputc('$', stream);
            if (r == mps_lib_EOF) return ResIO;
          } break;

          case 'D': {                   /* double */
            WriteFD d = va_arg(args, WriteFD);
            res = WriteDouble(stream, d);
            if (res != ResOK) return res;
          } break;
              
          default:
          NOTREACHED;
        }
      }

      ++format;
    }
  }
 
  va_end(args);
 
  return ResOK;
}