/* ---------------------------------------------------------------------- */
/*                   Copyright (C) 1991 by Natrlich!                     */
/*                      This file is copyrighted!                         */
/*                Refer to the documentation for details.                 */
/* ---------------------------------------------------------------------- */
#include "defines.h"

#if STATISTICS

# include "nasm.h"
# include "imm.h"
# include "seg.h"
# include OSBIND
# include NMALLOC_H
# include <time.h>
# include <stdio.h>


word  _m_expr,    _a_expr,  _efrees, _erfrees,
      _m_label,   _a_label,
      _m_llabel,  _a_llabel,
      _m_char,    _a_char,
      _m_lexpr,   _a_lexpr,
      _m_ref,     _a_ref,
      _m_seg,     _a_seg,
      _m_imm,     _a_imm,
      _m_fix,           _a_fix,
      _m_macro;
long  _s_expr,  _s_label, _s_char,   _z_char, _s_ref,
      _s_macro, _s_lexpr, _s_llabel, _s_imm,  _s_seg, _s_fix,
      _mused, _maxused;

extern word  tok_remain;


static void p( what, alls, malls, size, isize, usage)
char    *what;
word    alls, malls;
long    size;
size_t  isize;
word    usage;
{
   printf("%4u %8s [ %2ld bytes]: %5ld bytes, %2d%% usage (%2d mallocs  %ld bytes)\n",
            alls, what, (long) isize, size * malls, usage, malls, size);
}

# if __NSTDC__

#  define yy( x)                                                                                                                                        \
        (word) ((_m_ ## x * _s_ ## x)                                  \
                ?       ((sizeof( x) * _a_ ## x * 100) / (_m_ ## x * _s_ ## x))  \
                :       0)
#  define xy( x, y)                                                                                                                             \
        (word) ((_m_ ## x * _s_ ## x)                                  \
                ?       ((sizeof( y) * _a_ ## x * 100) / (_m_ ## x * _s_ ## x))  \
                :       0)

# else

#  define yy( x)                                                                                                                                        \
        (word) ((_m_/**/x * _s_/**/x)                                  \
                ?       ((sizeof( x) * _a_/**/x * 100) / (_m_/**/x * _s_/**/x))  \
                :       0)
#  define xy( x, y)                                               \
        (word) ((_m_/**/x * _s_/**/x)                                  \
                ?       ((sizeof( y) * _a_/**/x * 100) / (_m_/**/x * _s_/**/x))  \
                :       0)

# endif


void stats()
{
   long  res, res2;

   printf("\nINTERNAL STATS:\n");
   p("exprs",  _a_expr,  _m_expr,  _s_expr,  sizeof( expr),  yy( expr));
   p("labels", _a_label, _m_label, _s_label, sizeof( label), yy( label));
   p("llabels",_a_llabel,_m_llabel,_s_llabel,sizeof( label), xy( llabel, label));
   p("lexprs" ,_a_lexpr, _m_lexpr, _s_lexpr, sizeof( lexpr), yy( lexpr));
   p("refs",   _a_ref,   _m_ref,   _s_ref,   sizeof( ref),   yy( ref));
   p("imms",   _a_imm,   _m_imm,   _s_imm,   sizeof( imm),   yy( imm));
   p("segs",   _a_seg,   _m_seg,   _s_seg,   sizeof( seg),   yy( seg));
   p("fixes",  _a_fix,   _m_fix,   _s_fix,   sizeof( fix),   yy( fix));
   if( res = _m_macro * _s_macro)
      res  = ((res - (tok_remain * 6)) * 100) / res;
   else
      res = 0;
   p("macros", _m_macro, _m_macro, _s_macro, (size_t) 1, (word) res);
   res = _m_char * _s_char;
   if( res)
      res = (_z_char * 100 + _m_char * _s_char) / res;
   p("strings", _a_char,  _m_char, _s_char, (size_t) 1, (word) res);
   printf("\n%5u expr giveback tries (%u w/success).\n", _efrees, _erfrees);
   printf("   Maximal memory consumption: %ld bytes.\n", _maxused);
}
#endif

