<commit_before>#include <string>
#include <algorithm>
#include <mutex>
#include <sstream>
#include <dirent.h>
#include "text_helper.hpp"

namespace
{
  /* The purpose of the DaaBufferHolder is to -DELAY-
   * the loading of data until the first time the data
   * is requested.
   */
  class DataBufferLoader:public fastuidraw::reference_counted<DataBufferLoader>::default_base
  {
  public:
    explicit
    DataBufferLoader(const std::string &pfilename):
      m_filename(pfilename)
    {}

    fastuidraw::reference_counted_ptr<fastuidraw::DataBufferBase>
    buffer(void)
    {
      fastuidraw::reference_counted_ptr<fastuidraw::DataBufferBase> R;

      m_mutex.lock();
      if (!m_buffer)
        {
          m_buffer = FASTUIDRAWnew fastuidraw::DataBuffer(m_filename.c_str());
        }
      R = m_buffer;
      m_mutex.unlock();

      return R;
    }

  private:
    std::string m_filename;
    std::mutex m_mutex;
    fastuidraw::reference_counted_ptr<fastuidraw::DataBufferBase> m_buffer;
  };

  class FreeTypeFontGenerator:public fastuidraw::GlyphSelector::FontGeneratorBase
  {
  public:
    FreeTypeFontGenerator(fastuidraw::reference_counted_ptr<DataBufferLoader> buffer,
                          fastuidraw::reference_counted_ptr<fastuidraw::FreeTypeLib> lib,
                          fastuidraw::FontFreeType::RenderParams render_params,
                          int face_index,
                          const fastuidraw::FontProperties &props):
      m_buffer(buffer),
      m_lib(lib),
      m_render_params(render_params),
      m_face_index(face_index),
      m_props(props)
    {}

    virtual
    fastuidraw::reference_counted_ptr<const fastuidraw::FontBase>
    generate_font(void) const
    {
      fastuidraw::reference_counted_ptr<fastuidraw::FreeTypeFace::GeneratorBase> h;
      fastuidraw::reference_counted_ptr<fastuidraw::DataBufferBase> buffer;
      fastuidraw::reference_counted_ptr<const fastuidraw::FontBase> font;
      buffer = m_buffer->buffer();
      h = FASTUIDRAWnew fastuidraw::FreeTypeFace::GeneratorMemory(buffer, m_face_index);
      font = FASTUIDRAWnew fastuidraw::FontFreeType(h, m_props, m_render_params, m_lib);
      return font;
    }

    virtual
    const fastuidraw::FontProperties&
    font_properties(void) const
    {
      return m_props;
    }

  private:
    fastuidraw::reference_counted_ptr<DataBufferLoader> m_buffer;
    fastuidraw::reference_counted_ptr<fastuidraw::FreeTypeLib> m_lib;
    fastuidraw::FontFreeType::RenderParams m_render_params;
    int m_face_index;
    fastuidraw::FontProperties m_props;
  };

  void
  preprocess_text(std::string &text)
  {
    /* we want to change '\t' into 4 spaces
     */
    std::string v;
    v.reserve(text.size() + 4 * std::count(text.begin(), text.end(), '\t'));
    for(std::string::const_iterator iter = text.begin(); iter != text.end(); ++iter)
      {
        if (*iter != '\t')
          {
            v.push_back(*iter);
          }
        else
          {
            v.push_back(' ');
          }
      }
    text.swap(v);
  }

  void
  add_fonts_from_file(const std::string &filename,
                      fastuidraw::reference_counted_ptr<fastuidraw::FreeTypeLib> lib,
                      fastuidraw::reference_counted_ptr<fastuidraw::GlyphSelector> glyph_selector,
                      fastuidraw::FontFreeType::RenderParams render_params)
  {
    FT_Error error_code;
    FT_Face face(nullptr);

    lib->lock();
    error_code = FT_New_Face(lib->lib(), filename.c_str(), 0, &face);
    lib->unlock();

    if (error_code == 0 && face != nullptr && (face->face_flags & FT_FACE_FLAG_SCALABLE) != 0)
      {
        fastuidraw::reference_counted_ptr<DataBufferLoader> buffer_loader;

        buffer_loader = FASTUIDRAWnew DataBufferLoader(filename);
	for(unsigned int i = 0, endi = face->num_faces; i < endi; ++i)
	  {
            fastuidraw::reference_counted_ptr<fastuidraw::GlyphSelector::FontGeneratorBase> h;
            std::ostringstream source_label;
            fastuidraw::FontProperties props;
            if (i != 0)
              {
                lib->lock();
                FT_Done_Face(face);
                FT_New_Face(lib->lib(), filename.c_str(), i, &face);
                lib->unlock();
              }
            fastuidraw::FontFreeType::compute_font_properties_from_face(face, props);
            source_label << filename << ":" << i;
            props.source_label(source_label.str().c_str());

            h = FASTUIDRAWnew FreeTypeFontGenerator(buffer_loader, lib, render_params, i, props);
	    glyph_selector->add_font_generator(h);

            //std::cout << "add font: " << props << "\n";
 	  }
      }

    lib->lock();
    if (face != nullptr)
      {
	FT_Done_Face(face);
      }
    lib->unlock();
  }

}

/////////////////////////////
// GlyphSetGenerator methods
GlyphSetGenerator::
GlyphSetGenerator(fastuidraw::GlyphRender r,
                  fastuidraw::reference_counted_ptr<const fastuidraw::FontFreeType> f,
                  fastuidraw::reference_counted_ptr<fastuidraw::FreeTypeFace> face,
                  std::vector<fastuidraw::Glyph> &dst):
  m_render(r),
  m_font(f)
{
  dst.resize(face->face()->num_glyphs);
  m_dst = fastuidraw::c_array<fastuidraw::Glyph>(&dst[0], dst.size());
  SDL_AtomicSet(&m_counter, 0);
}

int
GlyphSetGenerator::
execute(void *ptr)
{
  unsigned int idx, K;
  GlyphSetGenerator *p(static_cast<GlyphSetGenerator*>(ptr));

  for(idx = SDL_AtomicAdd(&p->m_counter, 1), K = 0;
      idx < p->m_dst.size();
      idx = SDL_AtomicAdd(&p->m_counter, 1), ++K)
    {
      p->m_dst[idx] = fastuidraw::Glyph::create_glyph(p->m_render, p->m_font, idx);
    }
  return K;
}

void
GlyphSetGenerator::
generate(unsigned int num_threads,
         fastuidraw::GlyphRender r,
         fastuidraw::reference_counted_ptr<const fastuidraw::FontFreeType> f,
         fastuidraw::reference_counted_ptr<fastuidraw::FreeTypeFace> face,
         std::vector<fastuidraw::Glyph> &dst,
         fastuidraw::reference_counted_ptr<fastuidraw::GlyphCache> glyph_cache,
         std::vector<int> &cnts)
{
  GlyphSetGenerator generator(r, f, face, dst);
  std::vector<SDL_Thread*> threads;

  cnts.clear();
  cnts.resize(fastuidraw::t_max(1u, num_threads), 0);

  if (num_threads < 2)
    {
      cnts[0] = execute(&generator);
    }
  else
    {
      for(int i = 0; i < num_threads; ++i)
        {
          threads.push_back(SDL_CreateThread(execute, "", &generator));
        }

      for(int i = 0; i < num_threads; ++i)
        {
          SDL_WaitThread(threads[i], &cnts[i]);
        }
    }

  if (glyph_cache)
    {
      for(fastuidraw::Glyph glyph : dst)
        {
          glyph_cache->add_glyph(glyph);
        }
    }
}

//////////////////////////////
// global methods
void
create_formatted_text(std::istream &istr, fastuidraw::GlyphRender renderer,
                      float pixel_size,
                      fastuidraw::reference_counted_ptr<const fastuidraw::FontBase> font,
                      fastuidraw::reference_counted_ptr<fastuidraw::GlyphSelector> glyph_selector,
                      std::vector<fastuidraw::Glyph> &glyphs,
                      std::vector<fastuidraw::vec2> &positions,
                      std::vector<uint32_t> &character_codes,
                      std::vector<LineData> *line_data,
                      std::vector<fastuidraw::range_type<float> > *glyph_extents,
		      enum fastuidraw::PainterEnums::glyph_orientation orientation)
{
  std::streampos current_position, end_position;
  unsigned int loc(0);
  fastuidraw::vec2 pen(0.0f, 0.0f);
  std::string line, original_line;
  float last_negative_tallest(0.0f);

  current_position = istr.tellg();
  istr.seekg(0, std::ios::end);
  end_position = istr.tellg();
  istr.seekg(current_position, std::ios::beg);

  glyphs.resize(end_position - current_position);
  positions.resize(end_position - current_position);
  character_codes.resize(end_position - current_position);

  if (glyph_extents)
    {
      glyph_extents->resize(end_position - current_position);
    }

  if (line_data)
    {
      line_data->clear();
    }

  fastuidraw::c_array<fastuidraw::Glyph> glyphs_ptr(cast_c_array(glyphs));
  fastuidraw::c_array<fastuidraw::vec2> pos_ptr(cast_c_array(positions));
  fastuidraw::c_array<uint32_t> char_codes_ptr(cast_c_array(character_codes));
  fastuidraw::c_array<fastuidraw::range_type<float> > extents_ptr;

  if (glyph_extents)
    {
      extents_ptr = cast_c_array(*glyph_extents);
    }

  while(getline(istr, line))
    {
      fastuidraw::c_array<fastuidraw::Glyph> sub_g;
      fastuidraw::c_array<fastuidraw::vec2> sub_p;
      fastuidraw::c_array<uint32_t> sub_ch;
      fastuidraw::c_array<fastuidraw::range_type<float> > sub_extents;
      float tallest, negative_tallest, offset;
      bool empty_line;
      LineData L;
      float pen_y_advance;

      empty_line = true;
      tallest = 0.0f;
      negative_tallest = 0.0f;

      original_line = line;
      preprocess_text(line);

      sub_g = glyphs_ptr.sub_array(loc, line.length());
      sub_p = pos_ptr.sub_array(loc, line.length());
      sub_ch = char_codes_ptr.sub_array(loc, line.length());
      if (glyph_extents)
        {
          sub_extents = extents_ptr.sub_array(loc, line.length());
        }

      glyph_selector->create_glyph_sequence(renderer, font, line.begin(), line.end(), sub_g.begin());
      for(unsigned int i = 0, endi = sub_g.size(); i < endi; ++i)
        {
          fastuidraw::Glyph g;

          g = sub_g[i];
          sub_p[i] = pen;
          sub_ch[i] = static_cast<uint32_t>(line[i]);
          if (g.valid())
            {
              float ratio;
              ratio = pixel_size / g.layout().m_units_per_EM;

              if (glyph_extents)
                {
                  sub_extents[i].m_begin = pen.x() + ratio * g.layout().m_horizontal_layout_offset.x();
                  sub_extents[i].m_end = sub_extents[i].m_begin + ratio * g.layout().m_size.x();
                }

              empty_line = false;
              pen.x() += ratio * g.layout().m_advance.x();

              tallest = std::max(tallest, ratio * (g.layout().m_horizontal_layout_offset.y() + g.layout().m_size.y()));
              negative_tallest = std::min(negative_tallest, ratio * g.layout().m_horizontal_layout_offset.y());
            }
        }

      if (empty_line)
        {
          offset = pixel_size + 1.0f;
	  pen_y_advance = offset;
        }
      else
        {
	  if (orientation == fastuidraw::PainterEnums::y_increases_downwards)
	    {
	      offset = (tallest - last_negative_tallest);
	      pen_y_advance = offset;
	    }
	  else
	    {
	      offset = -negative_tallest;
	      pen_y_advance = tallest - negative_tallest;
	    }
        }

      for(unsigned int i = 0; i < sub_p.size(); ++i)
        {
          sub_p[i].y() += offset;
        }

      L.m_range.m_begin = loc;
      L.m_range.m_end = loc + line.length();
      L.m_horizontal_spread.m_begin = 0.0f;
      L.m_horizontal_spread.m_end = pen.x();
      L.m_vertical_spread.m_begin = pen.y() + offset - tallest;
      L.m_vertical_spread.m_end = pen.y() + offset - negative_tallest;

      pen.x() = 0.0f;
      pen.y() += pen_y_advance + 1.0f;
      loc += line.length();
      last_negative_tallest = negative_tallest;

      if (line_data && !empty_line)
        {
          L.m_horizontal_spread.sanitize();
          L.m_vertical_spread.sanitize();
          line_data->push_back(L);
        }
    }

  glyphs.resize(loc);
  positions.resize(loc);
  character_codes.resize(loc);
  if (glyph_extents)
    {
      glyph_extents->resize(loc);
    }
}

void
add_fonts_from_path(const std::string &filename,
                    fastuidraw::reference_counted_ptr<fastuidraw::FreeTypeLib> lib,
                    fastuidraw::reference_counted_ptr<fastuidraw::GlyphSelector> glyph_selector,
                    fastuidraw::FontFreeType::RenderParams render_params)
{
  DIR *dir;
  struct dirent *entry;

  dir = opendir(filename.c_str());
  if (!dir)
    {
      add_fonts_from_file(filename, lib, glyph_selector, render_params);
      return;
    }

  for(entry = readdir(dir); entry != nullptr; entry = readdir(dir))
    {
      std::string file;
      file = entry->d_name;
      if (file != ".." && file != ".")
        {
          add_fonts_from_path(filename + "/" + file, lib, glyph_selector, render_params);
        }
    }
  closedir(dir);
}

fastuidraw::c_string
default_font(void)
{
  #ifdef __WIN32
    {
      return "C:/Windows/Fonts/arial.ttf";
    }
  #else
    {
      return "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf";
    }
  #endif
}

fastuidraw::c_string
default_font_path(void)
{
  #ifdef __WIN32
    {
      return "C:/Windows/Fonts";
    }
  #else
    {
      return "/usr/share/fonts/";
    }
  #endif
}
<commit_msg>demos: Correct compliation guard for WIN32<commit_after>#include <string>
#include <algorithm>
#include <mutex>
#include <sstream>
#include <dirent.h>
#include "text_helper.hpp"

namespace
{
  /* The purpose of the DaaBufferHolder is to -DELAY-
   * the loading of data until the first time the data
   * is requested.
   */
  class DataBufferLoader:public fastuidraw::reference_counted<DataBufferLoader>::default_base
  {
  public:
    explicit
    DataBufferLoader(const std::string &pfilename):
      m_filename(pfilename)
    {}

    fastuidraw::reference_counted_ptr<fastuidraw::DataBufferBase>
    buffer(void)
    {
      fastuidraw::reference_counted_ptr<fastuidraw::DataBufferBase> R;

      m_mutex.lock();
      if (!m_buffer)
        {
          m_buffer = FASTUIDRAWnew fastuidraw::DataBuffer(m_filename.c_str());
        }
      R = m_buffer;
      m_mutex.unlock();

      return R;
    }

  private:
    std::string m_filename;
    std::mutex m_mutex;
    fastuidraw::reference_counted_ptr<fastuidraw::DataBufferBase> m_buffer;
  };

  class FreeTypeFontGenerator:public fastuidraw::GlyphSelector::FontGeneratorBase
  {
  public:
    FreeTypeFontGenerator(fastuidraw::reference_counted_ptr<DataBufferLoader> buffer,
                          fastuidraw::reference_counted_ptr<fastuidraw::FreeTypeLib> lib,
                          fastuidraw::FontFreeType::RenderParams render_params,
                          int face_index,
                          const fastuidraw::FontProperties &props):
      m_buffer(buffer),
      m_lib(lib),
      m_render_params(render_params),
      m_face_index(face_index),
      m_props(props)
    {}

    virtual
    fastuidraw::reference_counted_ptr<const fastuidraw::FontBase>
    generate_font(void) const
    {
      fastuidraw::reference_counted_ptr<fastuidraw::FreeTypeFace::GeneratorBase> h;
      fastuidraw::reference_counted_ptr<fastuidraw::DataBufferBase> buffer;
      fastuidraw::reference_counted_ptr<const fastuidraw::FontBase> font;
      buffer = m_buffer->buffer();
      h = FASTUIDRAWnew fastuidraw::FreeTypeFace::GeneratorMemory(buffer, m_face_index);
      font = FASTUIDRAWnew fastuidraw::FontFreeType(h, m_props, m_render_params, m_lib);
      return font;
    }

    virtual
    const fastuidraw::FontProperties&
    font_properties(void) const
    {
      return m_props;
    }

  private:
    fastuidraw::reference_counted_ptr<DataBufferLoader> m_buffer;
    fastuidraw::reference_counted_ptr<fastuidraw::FreeTypeLib> m_lib;
    fastuidraw::FontFreeType::RenderParams m_render_params;
    int m_face_index;
    fastuidraw::FontProperties m_props;
  };

  void
  preprocess_text(std::string &text)
  {
    /* we want to change '\t' into 4 spaces
     */
    std::string v;
    v.reserve(text.size() + 4 * std::count(text.begin(), text.end(), '\t'));
    for(std::string::const_iterator iter = text.begin(); iter != text.end(); ++iter)
      {
        if (*iter != '\t')
          {
            v.push_back(*iter);
          }
        else
          {
            v.push_back(' ');
          }
      }
    text.swap(v);
  }

  void
  add_fonts_from_file(const std::string &filename,
                      fastuidraw::reference_counted_ptr<fastuidraw::FreeTypeLib> lib,
                      fastuidraw::reference_counted_ptr<fastuidraw::GlyphSelector> glyph_selector,
                      fastuidraw::FontFreeType::RenderParams render_params)
  {
    FT_Error error_code;
    FT_Face face(nullptr);

    lib->lock();
    error_code = FT_New_Face(lib->lib(), filename.c_str(), 0, &face);
    lib->unlock();

    if (error_code == 0 && face != nullptr && (face->face_flags & FT_FACE_FLAG_SCALABLE) != 0)
      {
        fastuidraw::reference_counted_ptr<DataBufferLoader> buffer_loader;

        buffer_loader = FASTUIDRAWnew DataBufferLoader(filename);
	for(unsigned int i = 0, endi = face->num_faces; i < endi; ++i)
	  {
            fastuidraw::reference_counted_ptr<fastuidraw::GlyphSelector::FontGeneratorBase> h;
            std::ostringstream source_label;
            fastuidraw::FontProperties props;
            if (i != 0)
              {
                lib->lock();
                FT_Done_Face(face);
                FT_New_Face(lib->lib(), filename.c_str(), i, &face);
                lib->unlock();
              }
            fastuidraw::FontFreeType::compute_font_properties_from_face(face, props);
            source_label << filename << ":" << i;
            props.source_label(source_label.str().c_str());

            h = FASTUIDRAWnew FreeTypeFontGenerator(buffer_loader, lib, render_params, i, props);
	    glyph_selector->add_font_generator(h);

            //std::cout << "add font: " << props << "\n";
 	  }
      }

    lib->lock();
    if (face != nullptr)
      {
	FT_Done_Face(face);
      }
    lib->unlock();
  }

}

/////////////////////////////
// GlyphSetGenerator methods
GlyphSetGenerator::
GlyphSetGenerator(fastuidraw::GlyphRender r,
                  fastuidraw::reference_counted_ptr<const fastuidraw::FontFreeType> f,
                  fastuidraw::reference_counted_ptr<fastuidraw::FreeTypeFace> face,
                  std::vector<fastuidraw::Glyph> &dst):
  m_render(r),
  m_font(f)
{
  dst.resize(face->face()->num_glyphs);
  m_dst = fastuidraw::c_array<fastuidraw::Glyph>(&dst[0], dst.size());
  SDL_AtomicSet(&m_counter, 0);
}

int
GlyphSetGenerator::
execute(void *ptr)
{
  unsigned int idx, K;
  GlyphSetGenerator *p(static_cast<GlyphSetGenerator*>(ptr));

  for(idx = SDL_AtomicAdd(&p->m_counter, 1), K = 0;
      idx < p->m_dst.size();
      idx = SDL_AtomicAdd(&p->m_counter, 1), ++K)
    {
      p->m_dst[idx] = fastuidraw::Glyph::create_glyph(p->m_render, p->m_font, idx);
    }
  return K;
}

void
GlyphSetGenerator::
generate(unsigned int num_threads,
         fastuidraw::GlyphRender r,
         fastuidraw::reference_counted_ptr<const fastuidraw::FontFreeType> f,
         fastuidraw::reference_counted_ptr<fastuidraw::FreeTypeFace> face,
         std::vector<fastuidraw::Glyph> &dst,
         fastuidraw::reference_counted_ptr<fastuidraw::GlyphCache> glyph_cache,
         std::vector<int> &cnts)
{
  GlyphSetGenerator generator(r, f, face, dst);
  std::vector<SDL_Thread*> threads;

  cnts.clear();
  cnts.resize(fastuidraw::t_max(1u, num_threads), 0);

  if (num_threads < 2)
    {
      cnts[0] = execute(&generator);
    }
  else
    {
      for(int i = 0; i < num_threads; ++i)
        {
          threads.push_back(SDL_CreateThread(execute, "", &generator));
        }

      for(int i = 0; i < num_threads; ++i)
        {
          SDL_WaitThread(threads[i], &cnts[i]);
        }
    }

  if (glyph_cache)
    {
      for(fastuidraw::Glyph glyph : dst)
        {
          glyph_cache->add_glyph(glyph);
        }
    }
}

//////////////////////////////
// global methods
void
create_formatted_text(std::istream &istr, fastuidraw::GlyphRender renderer,
                      float pixel_size,
                      fastuidraw::reference_counted_ptr<const fastuidraw::FontBase> font,
                      fastuidraw::reference_counted_ptr<fastuidraw::GlyphSelector> glyph_selector,
                      std::vector<fastuidraw::Glyph> &glyphs,
                      std::vector<fastuidraw::vec2> &positions,
                      std::vector<uint32_t> &character_codes,
                      std::vector<LineData> *line_data,
                      std::vector<fastuidraw::range_type<float> > *glyph_extents,
		      enum fastuidraw::PainterEnums::glyph_orientation orientation)
{
  std::streampos current_position, end_position;
  unsigned int loc(0);
  fastuidraw::vec2 pen(0.0f, 0.0f);
  std::string line, original_line;
  float last_negative_tallest(0.0f);

  current_position = istr.tellg();
  istr.seekg(0, std::ios::end);
  end_position = istr.tellg();
  istr.seekg(current_position, std::ios::beg);

  glyphs.resize(end_position - current_position);
  positions.resize(end_position - current_position);
  character_codes.resize(end_position - current_position);

  if (glyph_extents)
    {
      glyph_extents->resize(end_position - current_position);
    }

  if (line_data)
    {
      line_data->clear();
    }

  fastuidraw::c_array<fastuidraw::Glyph> glyphs_ptr(cast_c_array(glyphs));
  fastuidraw::c_array<fastuidraw::vec2> pos_ptr(cast_c_array(positions));
  fastuidraw::c_array<uint32_t> char_codes_ptr(cast_c_array(character_codes));
  fastuidraw::c_array<fastuidraw::range_type<float> > extents_ptr;

  if (glyph_extents)
    {
      extents_ptr = cast_c_array(*glyph_extents);
    }

  while(getline(istr, line))
    {
      fastuidraw::c_array<fastuidraw::Glyph> sub_g;
      fastuidraw::c_array<fastuidraw::vec2> sub_p;
      fastuidraw::c_array<uint32_t> sub_ch;
      fastuidraw::c_array<fastuidraw::range_type<float> > sub_extents;
      float tallest, negative_tallest, offset;
      bool empty_line;
      LineData L;
      float pen_y_advance;

      empty_line = true;
      tallest = 0.0f;
      negative_tallest = 0.0f;

      original_line = line;
      preprocess_text(line);

      sub_g = glyphs_ptr.sub_array(loc, line.length());
      sub_p = pos_ptr.sub_array(loc, line.length());
      sub_ch = char_codes_ptr.sub_array(loc, line.length());
      if (glyph_extents)
        {
          sub_extents = extents_ptr.sub_array(loc, line.length());
        }

      glyph_selector->create_glyph_sequence(renderer, font, line.begin(), line.end(), sub_g.begin());
      for(unsigned int i = 0, endi = sub_g.size(); i < endi; ++i)
        {
          fastuidraw::Glyph g;

          g = sub_g[i];
          sub_p[i] = pen;
          sub_ch[i] = static_cast<uint32_t>(line[i]);
          if (g.valid())
            {
              float ratio;
              ratio = pixel_size / g.layout().m_units_per_EM;

              if (glyph_extents)
                {
                  sub_extents[i].m_begin = pen.x() + ratio * g.layout().m_horizontal_layout_offset.x();
                  sub_extents[i].m_end = sub_extents[i].m_begin + ratio * g.layout().m_size.x();
                }

              empty_line = false;
              pen.x() += ratio * g.layout().m_advance.x();

              tallest = std::max(tallest, ratio * (g.layout().m_horizontal_layout_offset.y() + g.layout().m_size.y()));
              negative_tallest = std::min(negative_tallest, ratio * g.layout().m_horizontal_layout_offset.y());
            }
        }

      if (empty_line)
        {
          offset = pixel_size + 1.0f;
	  pen_y_advance = offset;
        }
      else
        {
	  if (orientation == fastuidraw::PainterEnums::y_increases_downwards)
	    {
	      offset = (tallest - last_negative_tallest);
	      pen_y_advance = offset;
	    }
	  else
	    {
	      offset = -negative_tallest;
	      pen_y_advance = tallest - negative_tallest;
	    }
        }

      for(unsigned int i = 0; i < sub_p.size(); ++i)
        {
          sub_p[i].y() += offset;
        }

      L.m_range.m_begin = loc;
      L.m_range.m_end = loc + line.length();
      L.m_horizontal_spread.m_begin = 0.0f;
      L.m_horizontal_spread.m_end = pen.x();
      L.m_vertical_spread.m_begin = pen.y() + offset - tallest;
      L.m_vertical_spread.m_end = pen.y() + offset - negative_tallest;

      pen.x() = 0.0f;
      pen.y() += pen_y_advance + 1.0f;
      loc += line.length();
      last_negative_tallest = negative_tallest;

      if (line_data && !empty_line)
        {
          L.m_horizontal_spread.sanitize();
          L.m_vertical_spread.sanitize();
          line_data->push_back(L);
        }
    }

  glyphs.resize(loc);
  positions.resize(loc);
  character_codes.resize(loc);
  if (glyph_extents)
    {
      glyph_extents->resize(loc);
    }
}

void
add_fonts_from_path(const std::string &filename,
                    fastuidraw::reference_counted_ptr<fastuidraw::FreeTypeLib> lib,
                    fastuidraw::reference_counted_ptr<fastuidraw::GlyphSelector> glyph_selector,
                    fastuidraw::FontFreeType::RenderParams render_params)
{
  DIR *dir;
  struct dirent *entry;

  dir = opendir(filename.c_str());
  if (!dir)
    {
      add_fonts_from_file(filename, lib, glyph_selector, render_params);
      return;
    }

  for(entry = readdir(dir); entry != nullptr; entry = readdir(dir))
    {
      std::string file;
      file = entry->d_name;
      if (file != ".." && file != ".")
        {
          add_fonts_from_path(filename + "/" + file, lib, glyph_selector, render_params);
        }
    }
  closedir(dir);
}

fastuidraw::c_string
default_font(void)
{
  #ifdef _WIN32
    {
      return "C:/Windows/Fonts/arial.ttf";
    }
  #else
    {
      return "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf";
    }
  #endif
}

fastuidraw::c_string
default_font_path(void)
{
  #ifdef _WIN32
    {
      return "C:/Windows/Fonts";
    }
  #else
    {
      return "/usr/share/fonts/";
    }
  #endif
}
<|endoftext|>


<commit_before>/*
 * Copyright 2004-2014 Cray Inc.
 * Other additional copyright holders may be indicated within.
 *
 * The entirety of this work is licensed under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "bb.h"

#include "astutil.h"
#include "bitVec.h"
#include "expr.h"
#include "stlUtil.h"
#include "stmt.h"
#include "view.h"

#include <cstdlib>

BasicBlock::BasicBlock()
  : id(nextid++) {}

#define BB_START()                              \
  basicBlock = new BasicBlock()

// The assert tests that the expression we are adding to this basic block
// has not already been deleted.
#define BB_ADD(expr)                            \
  do {                                          \
    INT_ASSERT(expr);                           \
    basicBlock->exprs.push_back(expr);          \
  } while (0)

#define BB_STOP()                               \
  fn->basicBlocks->push_back(Steal())

#define BB_RESTART()                            \
  do {                                          \
    BB_STOP();                                  \
    BB_START();                                 \
  } while (0)

#define BBB(stmt)                               \
    buildBasicBlocks(fn, stmt)

#define BB_THREAD(src, dst)                     \
  do {                                          \
    (dst)->ins.push_back(src);                  \
    (src)->outs.push_back(dst);                 \
  } while (0)

//# Statics
BasicBlock* BasicBlock::basicBlock;
Map<LabelSymbol*,std::vector<BasicBlock*>*> BasicBlock::gotoMaps;
Map<LabelSymbol*,BasicBlock*> BasicBlock::labelMaps;
int BasicBlock::nextid;

// Returns true if the class invariants have been preserved.
bool BasicBlock::isOK()
{
  // Expressions must be live (non-NULL);
  for_vector(Expr, expr, exprs)
    if (expr == 0) return false;

  // Every in edge must have a corresponding out edge in the source block.
  for_vector(BasicBlock, source, ins) {
    bool found = false;
    for_vector(BasicBlock, bb, source->outs)
      if (bb == this) { found = true; break; }
    if (!found) return false;
  }

  // Every out edge must have a corresponding in edge in the target block.
  for_vector(BasicBlock, target, outs) {
    bool found = false;
    for_vector(BasicBlock, bb, target->ins)
      if (bb == this) { found = true; break; }
    if (!found) return false;
  }

  return true;
}

void BasicBlock::clear(FnSymbol* fn)
{
  if (!fn->basicBlocks)
    return;

  for_vector(BasicBlock, bb, *fn->basicBlocks)
    delete bb, bb = 0;
  delete fn->basicBlocks; fn->basicBlocks = 0;
}

// Reset the shared statics.
void BasicBlock::reset(FnSymbol* fn)
{
  clear(fn);
  gotoMaps.clear();
  labelMaps.clear();
  fn->basicBlocks = new std::vector<BasicBlock*>();
  nextid = 0;
}

BasicBlock* BasicBlock::Steal()
{
  BasicBlock* temp = basicBlock;
  basicBlock = 0;
  return temp;
}

// This is the top-level (public) builder function.
void buildBasicBlocks(FnSymbol* fn)
{
  BasicBlock::reset(fn);
  BasicBlock::basicBlock = new BasicBlock();    // BB_START();
  BasicBlock::buildBasicBlocks(fn, fn->body);   // BBB(fn->body);
  fn->basicBlocks->push_back(BasicBlock::Steal());    // BB_STOP();

  INT_ASSERT(verifyBasicBlocks(fn));
}

void BasicBlock::buildBasicBlocks(FnSymbol* fn, Expr* stmt)
{
  if (!stmt) return;

  if (BlockStmt* s = toBlockStmt(stmt))
  {
    CallExpr* loop = toCallExpr(s->blockInfoGet());
    if (loop)
    {
      bool cForLoop = loop->isPrimitive(PRIM_BLOCK_C_FOR_LOOP);
      // for c for loops, add the init expr before the loop body
      if (cForLoop) {
        for_alist(stmt, toBlockStmt(loop->get(1))->body) { BBB(stmt); }
      }

      // mark the top of the loop
      BasicBlock* top = basicBlock;
      BB_RESTART();

      // for c for loops, add the test expr at the loop top
      if (cForLoop) {
        for_alist(stmt, toBlockStmt(loop->get(2))->body) { BBB(stmt); }
      }

      // add the CallExpr that is the loop itself and then add the loops body
      BB_ADD(loop);
      BasicBlock* loopTop = basicBlock;
      for_alist(stmt, s->body) {
        BBB(stmt);
      }

      // for c for loops, add the incr expr after the loop body
      if (cForLoop) {
        for_alist(stmt, toBlockStmt(loop->get(3))->body) { BBB(stmt); }
      }

      BasicBlock* loopBottom = basicBlock;
      BB_RESTART();
      BasicBlock* bottom = basicBlock;

      // thread the basic blocks of the pre-loop, loop, and post-loop together
      BB_THREAD(top, loopTop);
      BB_THREAD(loopBottom, bottom);
      BB_THREAD(loopBottom, loopTop);
      BB_THREAD(top, bottom);
    }
    else
    {
      for_alist(stmt, s->body)
        BBB(stmt);
    }
  }
  else if (CondStmt* s = toCondStmt(stmt))
  {
    INT_ASSERT(s->condExpr);
    BB_ADD(s->condExpr);
    BasicBlock* top = basicBlock;
    BB_RESTART();
    BB_THREAD(top, basicBlock);
    BBB(s->thenStmt);
    BasicBlock* thenBottom = basicBlock;
    BB_RESTART();
    if (s->elseStmt)
    {
      BB_THREAD(top, basicBlock);
      BBB(s->elseStmt);
      BasicBlock* elseBottom = basicBlock;
      BB_RESTART();
      BB_THREAD(elseBottom, basicBlock);
    }
    else
    {
      BB_THREAD(top, basicBlock);
    }
    BB_THREAD(thenBottom, basicBlock);
  } else if (GotoStmt* s = toGotoStmt(stmt)) {
    LabelSymbol* label = toLabelSymbol(toSymExpr(s->label)->var);
    if (BasicBlock* bb = labelMaps.get(label)) {
      BB_THREAD(basicBlock, bb);
    } else {
      std::vector<BasicBlock*>* vbb = gotoMaps.get(label);
      if (!vbb)
        vbb = new std::vector<BasicBlock*>();
      vbb->push_back(basicBlock);
      gotoMaps.put(label, vbb);
    }
    BB_ADD(s); // Put the goto at the end of its block.
    BB_RESTART();
  } else {
    DefExpr* def = toDefExpr(stmt);
    if (def && toLabelSymbol(def->sym)) {
      // If a label appears in the middle of a block,
      // we start a new block.
      if (basicBlock->exprs.size() > 0)
      {
        BasicBlock* top = basicBlock;
        BB_RESTART();
        BB_THREAD(top, basicBlock);
      }
      BB_ADD(def); // Put the label def at the start of its block.

      // OK, this statement is a label def, so get the label.
      LabelSymbol* label = toLabelSymbol(def->sym);

      // See if we have any unresolved references to this label,
      // and resolve them.
      if (std::vector<BasicBlock*>* vbb = gotoMaps.get(label)) {
        for_vector(BasicBlock, bb, *vbb) {
          BB_THREAD(bb, basicBlock);
        }
      }
      labelMaps.put(label, basicBlock);
    } else {
      BB_ADD(stmt);
    }
  }
}

// Returns true if the basic block structure is OK, false otherwise.
bool verifyBasicBlocks(FnSymbol* fn)
{
  for_vector(BasicBlock, bb, *fn->basicBlocks)
  {
    if (! bb->isOK())
      return false;
  }
  return true;
}

void buildLocalsVectorMap(FnSymbol* fn,
                          Vec<Symbol*>& locals,
                          Map<Symbol*,int>& localMap) {
  int i = 0;
  for_vector(BasicBlock, bb, *fn->basicBlocks) {
    for_vector(Expr, expr, bb->exprs) {
      if (DefExpr* def = toDefExpr(expr)) {
        if (toVarSymbol(def->sym)) {
          locals.add(def->sym);
          localMap.put(def->sym, i++);
        }
      }
    }
  }
}

//#define DEBUG_FLOW
void backwardFlowAnalysis(FnSymbol* fn,
                          std::vector<BitVec*>& GEN,
                          std::vector<BitVec*>& KILL,
                          std::vector<BitVec*>& IN,
                          std::vector<BitVec*>& OUT) {
  bool iterate = true;
  while (iterate) {
    iterate = false;
    int i = 0;
    for_vector(BasicBlock, bb, *fn->basicBlocks) {
      for (int j = 0; j < IN[i]->ndata; j++) {
        unsigned new_in = (OUT[i]->data[j] & ~KILL[i]->data[j]) | GEN[i]->data[j];
        if (new_in != IN[i]->data[j]) {
          IN[i]->data[j] = new_in;
          iterate = true;
        }
        unsigned new_out = 0;
        for_vector(BasicBlock, bbout, bb->outs) {
          new_out = new_out | IN[bbout->id]->data[j];
        }
        if (new_out != OUT[i]->data[j]) {
          OUT[i]->data[j] = new_out;
          iterate = true;
        }
      }
      i++;
    }
#ifdef DEBUG_FLOW
    printf("IN\n"); printBitVectorSets(IN);
    printf("OUT\n"); printBitVectorSets(OUT);
#endif
  }
}

void forwardFlowAnalysis(FnSymbol* fn,
                         std::vector<BitVec*>& GEN,
                         std::vector<BitVec*>& KILL,
                         std::vector<BitVec*>& IN,
                         std::vector<BitVec*>& OUT,
                         bool intersect) {
  size_t nbbq = fn->basicBlocks->size(); // size of bb queue
  std::vector<int> bbq;
  BitVec bbs(nbbq);
  int iq = -1, nq = nbbq-1;      // index to first and last bb in bbq
  for (size_t i = 0; i < nbbq; i++) {
    bbq.push_back(i);
    bbs.set(i);
  }
  while (iq != nq) {
    iq = (iq + 1) % nbbq;
    int i = bbq[iq];
    bbs.unset(i);
#ifdef DEBUG_FLOW
    if (iq == 0) {
      printf("IN\n"); printBitVectorSets(IN);
      printf("OUT\n"); printBitVectorSets(OUT);
    }
#endif
    BasicBlock* bb = (*fn->basicBlocks)[i];
    bool change = false;
    for (int j = 0; j < IN[i]->ndata; j++) {
      if (bb->ins.size() > 0) {
        unsigned new_in = (intersect) ? (unsigned)(-1) : 0;
        for_vector(BasicBlock, bbin, bb->ins) {
          if (intersect)
            new_in &= OUT[bbin->id]->data[j];
          else
            new_in |= OUT[bbin->id]->data[j];
        }
        if (new_in != IN[i]->data[j]) {
          IN[i]->data[j] = new_in;
          change = true;
        }
      }
      unsigned new_out = (IN[i]->data[j] & ~KILL[i]->data[j]) | GEN[i]->data[j];
      if (new_out != OUT[i]->data[j]) {
        OUT[i]->data[j] = new_out;
        change = true;
      }
    }
    if (change) {
      for_vector(BasicBlock, bbout, bb->outs) {
        if (!bbs.get(bbout->id)) {
          nq = (nq + 1) % nbbq;
          bbs.set(bbout->id);
          bbq[nq] = bbout->id;
        }
      }
    }
  }
}

void printBasicBlocks(FnSymbol* fn) {
  for_vector(BasicBlock, b, *fn->basicBlocks) {
    printf("%2d:  ", b->id);
    for_vector(BasicBlock, bb, b->ins) {
      printf("%d ", bb->id);
    }
    printf(" >  ");
    for_vector(BasicBlock, bc, b->outs) {
      printf("%d ", bc->id);
    }
    printf("\n");
    for_vector(Expr, expr, b->exprs) {
      if (expr)
        list_view_noline(expr);
      else
        printf("0 (null)\n");
    }
    printf("\n");
  }
}

void printLocalsVector(Vec<Symbol*> locals, Map<Symbol*,int>& localMap) {
  printf("Local Variables\n");
  forv_Vec(Symbol, local, locals) {
    printf("%2d: %s[%d]\n", localMap.get(local), local->name, local->id);
  }
  printf("\n");
}

void printDefsVector(std::vector<SymExpr*> defs, Map<SymExpr*,int>& defMap) {
  printf("Variable Definitions\n");
  for_vector(SymExpr, def, defs) {
    printf("%2d: %s[%d] in %d\n", defMap.get(def), def->var->name,
           def->var->id, def->getStmtExpr()->id);
  }
  printf("\n");
}

void printLocalsVectorSets(std::vector<BitVec*>& sets, Vec<Symbol*> locals) {
  int i = 0;
  for_vector(BitVec, set, sets) {
    printf("%2d: ", i);
    for (int j = 0; j < set->size(); j++) {
      if (set->get(j))
        printf("%s[%d] ", locals.v[j]->name, locals.v[j]->id);
    }
    printf("\n");
    i++;
  }
  printf("\n");
}

void printBitVectorSets(std::vector<BitVec*>& sets) {
  int i = 0;
  for_vector(BitVec, set, sets) {
    printf("%2d: ", i);
    for (int j = 0; j < set->size(); j++) {
      printf("%d", (set->get(j)) ? 1 : 0);
      if ((j+1) % 10 == 0) printf(" ");
    }
    printf("\n");
    i++;
  }
  printf("\n");
}
<commit_msg>When building basic blocks for loop, only put the test expression at the top of the loop body; not the entire blockInfo callExpr for C-For loops<commit_after>/*
 * Copyright 2004-2014 Cray Inc.
 * Other additional copyright holders may be indicated within.
 *
 * The entirety of this work is licensed under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "bb.h"

#include "astutil.h"
#include "bitVec.h"
#include "expr.h"
#include "stlUtil.h"
#include "stmt.h"
#include "view.h"

#include <cstdlib>

BasicBlock::BasicBlock()
  : id(nextid++) {}

#define BB_START()                              \
  basicBlock = new BasicBlock()

// The assert tests that the expression we are adding to this basic block
// has not already been deleted.
#define BB_ADD(expr)                            \
  do {                                          \
    INT_ASSERT(expr);                           \
    basicBlock->exprs.push_back(expr);          \
  } while (0)

#define BB_STOP()                               \
  fn->basicBlocks->push_back(Steal())

#define BB_RESTART()                            \
  do {                                          \
    BB_STOP();                                  \
    BB_START();                                 \
  } while (0)

#define BBB(stmt)                               \
    buildBasicBlocks(fn, stmt)

#define BB_THREAD(src, dst)                     \
  do {                                          \
    (dst)->ins.push_back(src);                  \
    (src)->outs.push_back(dst);                 \
  } while (0)

//# Statics
BasicBlock* BasicBlock::basicBlock;
Map<LabelSymbol*,std::vector<BasicBlock*>*> BasicBlock::gotoMaps;
Map<LabelSymbol*,BasicBlock*> BasicBlock::labelMaps;
int BasicBlock::nextid;

// Returns true if the class invariants have been preserved.
bool BasicBlock::isOK()
{
  // Expressions must be live (non-NULL);
  for_vector(Expr, expr, exprs)
    if (expr == 0) return false;

  // Every in edge must have a corresponding out edge in the source block.
  for_vector(BasicBlock, source, ins) {
    bool found = false;
    for_vector(BasicBlock, bb, source->outs)
      if (bb == this) { found = true; break; }
    if (!found) return false;
  }

  // Every out edge must have a corresponding in edge in the target block.
  for_vector(BasicBlock, target, outs) {
    bool found = false;
    for_vector(BasicBlock, bb, target->ins)
      if (bb == this) { found = true; break; }
    if (!found) return false;
  }

  return true;
}

void BasicBlock::clear(FnSymbol* fn)
{
  if (!fn->basicBlocks)
    return;

  for_vector(BasicBlock, bb, *fn->basicBlocks)
    delete bb, bb = 0;
  delete fn->basicBlocks; fn->basicBlocks = 0;
}

// Reset the shared statics.
void BasicBlock::reset(FnSymbol* fn)
{
  clear(fn);
  gotoMaps.clear();
  labelMaps.clear();
  fn->basicBlocks = new std::vector<BasicBlock*>();
  nextid = 0;
}

BasicBlock* BasicBlock::Steal()
{
  BasicBlock* temp = basicBlock;
  basicBlock = 0;
  return temp;
}

// This is the top-level (public) builder function.
void buildBasicBlocks(FnSymbol* fn)
{
  BasicBlock::reset(fn);
  BasicBlock::basicBlock = new BasicBlock();    // BB_START();
  BasicBlock::buildBasicBlocks(fn, fn->body);   // BBB(fn->body);
  fn->basicBlocks->push_back(BasicBlock::Steal());    // BB_STOP();

  INT_ASSERT(verifyBasicBlocks(fn));
}

void BasicBlock::buildBasicBlocks(FnSymbol* fn, Expr* stmt)
{
  if (stmt == 0)
  {

  }

  else if (BlockStmt* s = toBlockStmt(stmt))
  {
    CallExpr* loop = toCallExpr(s->blockInfoGet());

    if (loop)
    {
      bool cForLoop = loop->isPrimitive(PRIM_BLOCK_C_FOR_LOOP);

      // for c for loops, add the init expr before the loop body
      if (cForLoop) {
        for_alist(stmt, toBlockStmt(loop->get(1))->body) { BBB(stmt); }
      }

      // mark the top of the loop
      BasicBlock* top = basicBlock;

      BB_RESTART();

      // add the test expr at the loop top
      if (cForLoop) {
        for_alist(stmt, toBlockStmt(loop->get(2))->body) { BBB(stmt); }
      } else {
        BB_ADD(loop);

      }

      BasicBlock* loopTop = basicBlock;

      for_alist(stmt, s->body) {
        BBB(stmt);
      }

      // for c for loops, add the incr expr after the loop body
      if (cForLoop) {
        for_alist(stmt, toBlockStmt(loop->get(3))->body) { BBB(stmt); }
      }

      BasicBlock* loopBottom = basicBlock;

      BB_RESTART();

      BasicBlock* bottom = basicBlock;

      // thread the basic blocks of the pre-loop, loop, and post-loop together
      BB_THREAD(top,        loopTop);
      BB_THREAD(loopBottom, bottom);
      BB_THREAD(loopBottom, loopTop);
      BB_THREAD(top,        bottom);
    }
    else
    {
      for_alist(stmt, s->body)
        BBB(stmt);
    }
  }
  else if (CondStmt* s = toCondStmt(stmt))
  {
    INT_ASSERT(s->condExpr);
    BB_ADD(s->condExpr);
    BasicBlock* top = basicBlock;
    BB_RESTART();
    BB_THREAD(top, basicBlock);
    BBB(s->thenStmt);
    BasicBlock* thenBottom = basicBlock;
    BB_RESTART();
    if (s->elseStmt)
    {
      BB_THREAD(top, basicBlock);
      BBB(s->elseStmt);
      BasicBlock* elseBottom = basicBlock;
      BB_RESTART();
      BB_THREAD(elseBottom, basicBlock);
    }
    else
    {
      BB_THREAD(top, basicBlock);
    }
    BB_THREAD(thenBottom, basicBlock);
  } else if (GotoStmt* s = toGotoStmt(stmt)) {
    LabelSymbol* label = toLabelSymbol(toSymExpr(s->label)->var);
    if (BasicBlock* bb = labelMaps.get(label)) {
      BB_THREAD(basicBlock, bb);
    } else {
      std::vector<BasicBlock*>* vbb = gotoMaps.get(label);
      if (!vbb)
        vbb = new std::vector<BasicBlock*>();
      vbb->push_back(basicBlock);
      gotoMaps.put(label, vbb);
    }
    BB_ADD(s); // Put the goto at the end of its block.
    BB_RESTART();
  } else {
    DefExpr* def = toDefExpr(stmt);
    if (def && toLabelSymbol(def->sym)) {
      // If a label appears in the middle of a block,
      // we start a new block.
      if (basicBlock->exprs.size() > 0)
      {
        BasicBlock* top = basicBlock;
        BB_RESTART();
        BB_THREAD(top, basicBlock);
      }
      BB_ADD(def); // Put the label def at the start of its block.

      // OK, this statement is a label def, so get the label.
      LabelSymbol* label = toLabelSymbol(def->sym);

      // See if we have any unresolved references to this label,
      // and resolve them.
      if (std::vector<BasicBlock*>* vbb = gotoMaps.get(label)) {
        for_vector(BasicBlock, bb, *vbb) {
          BB_THREAD(bb, basicBlock);
        }
      }
      labelMaps.put(label, basicBlock);
    } else {
      BB_ADD(stmt);
    }
  }
}

// Returns true if the basic block structure is OK, false otherwise.
bool verifyBasicBlocks(FnSymbol* fn)
{
  for_vector(BasicBlock, bb, *fn->basicBlocks)
  {
    if (! bb->isOK())
      return false;
  }
  return true;
}

void buildLocalsVectorMap(FnSymbol* fn,
                          Vec<Symbol*>& locals,
                          Map<Symbol*,int>& localMap) {
  int i = 0;
  for_vector(BasicBlock, bb, *fn->basicBlocks) {
    for_vector(Expr, expr, bb->exprs) {
      if (DefExpr* def = toDefExpr(expr)) {
        if (toVarSymbol(def->sym)) {
          locals.add(def->sym);
          localMap.put(def->sym, i++);
        }
      }
    }
  }
}

//#define DEBUG_FLOW
void backwardFlowAnalysis(FnSymbol* fn,
                          std::vector<BitVec*>& GEN,
                          std::vector<BitVec*>& KILL,
                          std::vector<BitVec*>& IN,
                          std::vector<BitVec*>& OUT) {
  bool iterate = true;
  while (iterate) {
    iterate = false;
    int i = 0;
    for_vector(BasicBlock, bb, *fn->basicBlocks) {
      for (int j = 0; j < IN[i]->ndata; j++) {
        unsigned new_in = (OUT[i]->data[j] & ~KILL[i]->data[j]) | GEN[i]->data[j];
        if (new_in != IN[i]->data[j]) {
          IN[i]->data[j] = new_in;
          iterate = true;
        }
        unsigned new_out = 0;
        for_vector(BasicBlock, bbout, bb->outs) {
          new_out = new_out | IN[bbout->id]->data[j];
        }
        if (new_out != OUT[i]->data[j]) {
          OUT[i]->data[j] = new_out;
          iterate = true;
        }
      }
      i++;
    }
#ifdef DEBUG_FLOW
    printf("IN\n"); printBitVectorSets(IN);
    printf("OUT\n"); printBitVectorSets(OUT);
#endif
  }
}

void forwardFlowAnalysis(FnSymbol* fn,
                         std::vector<BitVec*>& GEN,
                         std::vector<BitVec*>& KILL,
                         std::vector<BitVec*>& IN,
                         std::vector<BitVec*>& OUT,
                         bool intersect) {
  size_t nbbq = fn->basicBlocks->size(); // size of bb queue
  std::vector<int> bbq;
  BitVec bbs(nbbq);
  int iq = -1, nq = nbbq-1;      // index to first and last bb in bbq
  for (size_t i = 0; i < nbbq; i++) {
    bbq.push_back(i);
    bbs.set(i);
  }
  while (iq != nq) {
    iq = (iq + 1) % nbbq;
    int i = bbq[iq];
    bbs.unset(i);
#ifdef DEBUG_FLOW
    if (iq == 0) {
      printf("IN\n"); printBitVectorSets(IN);
      printf("OUT\n"); printBitVectorSets(OUT);
    }
#endif
    BasicBlock* bb = (*fn->basicBlocks)[i];
    bool change = false;
    for (int j = 0; j < IN[i]->ndata; j++) {
      if (bb->ins.size() > 0) {
        unsigned new_in = (intersect) ? (unsigned)(-1) : 0;
        for_vector(BasicBlock, bbin, bb->ins) {
          if (intersect)
            new_in &= OUT[bbin->id]->data[j];
          else
            new_in |= OUT[bbin->id]->data[j];
        }
        if (new_in != IN[i]->data[j]) {
          IN[i]->data[j] = new_in;
          change = true;
        }
      }
      unsigned new_out = (IN[i]->data[j] & ~KILL[i]->data[j]) | GEN[i]->data[j];
      if (new_out != OUT[i]->data[j]) {
        OUT[i]->data[j] = new_out;
        change = true;
      }
    }
    if (change) {
      for_vector(BasicBlock, bbout, bb->outs) {
        if (!bbs.get(bbout->id)) {
          nq = (nq + 1) % nbbq;
          bbs.set(bbout->id);
          bbq[nq] = bbout->id;
        }
      }
    }
  }
}

void printBasicBlocks(FnSymbol* fn) {
  for_vector(BasicBlock, b, *fn->basicBlocks) {
    printf("%2d:  ", b->id);
    for_vector(BasicBlock, bb, b->ins) {
      printf("%d ", bb->id);
    }
    printf(" >  ");
    for_vector(BasicBlock, bc, b->outs) {
      printf("%d ", bc->id);
    }
    printf("\n");
    for_vector(Expr, expr, b->exprs) {
      if (expr)
        list_view_noline(expr);
      else
        printf("0 (null)\n");
    }
    printf("\n");
  }
}

void printLocalsVector(Vec<Symbol*> locals, Map<Symbol*,int>& localMap) {
  printf("Local Variables\n");
  forv_Vec(Symbol, local, locals) {
    printf("%2d: %s[%d]\n", localMap.get(local), local->name, local->id);
  }
  printf("\n");
}

void printDefsVector(std::vector<SymExpr*> defs, Map<SymExpr*,int>& defMap) {
  printf("Variable Definitions\n");
  for_vector(SymExpr, def, defs) {
    printf("%2d: %s[%d] in %d\n", defMap.get(def), def->var->name,
           def->var->id, def->getStmtExpr()->id);
  }
  printf("\n");
}

void printLocalsVectorSets(std::vector<BitVec*>& sets, Vec<Symbol*> locals) {
  int i = 0;
  for_vector(BitVec, set, sets) {
    printf("%2d: ", i);
    for (int j = 0; j < set->size(); j++) {
      if (set->get(j))
        printf("%s[%d] ", locals.v[j]->name, locals.v[j]->id);
    }
    printf("\n");
    i++;
  }
  printf("\n");
}

void printBitVectorSets(std::vector<BitVec*>& sets) {
  int i = 0;
  for_vector(BitVec, set, sets) {
    printf("%2d: ", i);
    for (int j = 0; j < set->size(); j++) {
      printf("%d", (set->get(j)) ? 1 : 0);
      if ((j+1) % 10 == 0) printf(" ");
    }
    printf("\n");
    i++;
  }
  printf("\n");
}
<|endoftext|>


<commit_before>#ifndef __MAPNIK_VECTOR_PROCESSOR_H__
#define __MAPNIK_VECTOR_PROCESSOR_H__

#include <mapnik/map.hpp>
#include <mapnik/layer.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/util/noncopyable.hpp>
#include <mapnik/request.hpp>
#include <mapnik/view_transform.hpp>
#include <mapnik/image_scaling.hpp>
#include <mapnik/image_compositing.hpp>
#include <mapnik/geometry.hpp>
#include "clipper.hpp"

#include "vector_tile_config.hpp"

namespace mapnik { namespace vector_tile_impl {

enum polygon_fill_type : std::uint8_t {
    even_odd_fill = 0,
    non_zero_fill,
    positive_fill,
    negative_fill
};

/*
  This processor combines concepts from mapnik's
  feature_style_processor and agg_renderer. It
  differs in that here we only process layers in
  isolation of their styles, and because of this we need
  options for clipping and simplification, for example,
  that would normally come from a style's symbolizers
*/

template <typename T>
class processor : private mapnik::util::noncopyable
{
public:
    typedef T backend_type;
private:
    backend_type & backend_;
    mapnik::Map const& m_;
    mapnik::request const& m_req_;
    double scale_factor_;
    mapnik::view_transform t_;
    double area_threshold_;
    bool strictly_simple_;
    std::string image_format_;
    scaling_method_e scaling_method_;
    bool painted_;
    double simplify_distance_;
    bool multi_polygon_union_;
    ClipperLib::PolyFillType fill_type_;
    bool process_all_mp_rings_;
public:
    MAPNIK_VECTOR_INLINE processor(T & backend,
              mapnik::Map const& map,
              mapnik::request const& m_req,
              double scale_factor=1.0,
              unsigned offset_x=0,
              unsigned offset_y=0,
              double area_threshold=0.1,
              bool strictly_simple=false,
              std::string const& image_format="jpeg",
              scaling_method_e scaling_method=SCALING_NEAR
        );

    inline void set_simplify_distance(double dist)
    {
        simplify_distance_ = dist;
    }

    inline void set_process_all_mp_rings(bool value)
    {
        process_all_mp_rings_ = value;
    }

    inline void set_multi_polygon_union(bool value)
    {
        multi_polygon_union_ = value;
    }

    inline double get_simplify_distance() const
    {
        return simplify_distance_;
    }

    inline mapnik::view_transform const& get_transform()
    {
        return t_;
    }

    MAPNIK_VECTOR_INLINE void set_fill_type(polygon_fill_type type);

    MAPNIK_VECTOR_INLINE void apply(double scale_denom=0.0);

    MAPNIK_VECTOR_INLINE bool painted() const;

    MAPNIK_VECTOR_INLINE void apply_to_layer(mapnik::layer const& lay,
                        mapnik::projection const& proj0,
                        double scale,
                        double scale_denom,
                        unsigned width,
                        unsigned height,
                        box2d<double> const& extent,
                        int buffer_size);

    template <typename T2>
    MAPNIK_VECTOR_INLINE bool handle_geometry(T2 const& vs,
                                              mapnik::feature_impl const& feature,
                                              mapnik::geometry::geometry<double> const& geom,
                                              mapnik::box2d<int> const& tile_clipping_extent,
                                              mapnik::box2d<double> const& target_clipping_extent);
};

}} // end ns

#if !defined(MAPNIK_VECTOR_TILE_LIBRARY)
#include "vector_tile_processor.ipp"
#endif

#endif // __MAPNIK_VECTOR_TILE_PROCESSOR_H__
<commit_msg>Maximum fill type value added to enum<commit_after>#ifndef __MAPNIK_VECTOR_PROCESSOR_H__
#define __MAPNIK_VECTOR_PROCESSOR_H__

#include <mapnik/map.hpp>
#include <mapnik/layer.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/util/noncopyable.hpp>
#include <mapnik/request.hpp>
#include <mapnik/view_transform.hpp>
#include <mapnik/image_scaling.hpp>
#include <mapnik/image_compositing.hpp>
#include <mapnik/geometry.hpp>
#include "clipper.hpp"

#include "vector_tile_config.hpp"

namespace mapnik { namespace vector_tile_impl {

enum polygon_fill_type : std::uint8_t {
    even_odd_fill = 0,
    non_zero_fill,
    positive_fill,
    negative_fill,
    polygon_fill_type_max
};

/*
  This processor combines concepts from mapnik's
  feature_style_processor and agg_renderer. It
  differs in that here we only process layers in
  isolation of their styles, and because of this we need
  options for clipping and simplification, for example,
  that would normally come from a style's symbolizers
*/

template <typename T>
class processor : private mapnik::util::noncopyable
{
public:
    typedef T backend_type;
private:
    backend_type & backend_;
    mapnik::Map const& m_;
    mapnik::request const& m_req_;
    double scale_factor_;
    mapnik::view_transform t_;
    double area_threshold_;
    bool strictly_simple_;
    std::string image_format_;
    scaling_method_e scaling_method_;
    bool painted_;
    double simplify_distance_;
    bool multi_polygon_union_;
    ClipperLib::PolyFillType fill_type_;
    bool process_all_mp_rings_;
public:
    MAPNIK_VECTOR_INLINE processor(T & backend,
              mapnik::Map const& map,
              mapnik::request const& m_req,
              double scale_factor=1.0,
              unsigned offset_x=0,
              unsigned offset_y=0,
              double area_threshold=0.1,
              bool strictly_simple=false,
              std::string const& image_format="jpeg",
              scaling_method_e scaling_method=SCALING_NEAR
        );

    inline void set_simplify_distance(double dist)
    {
        simplify_distance_ = dist;
    }

    inline void set_process_all_mp_rings(bool value)
    {
        process_all_mp_rings_ = value;
    }

    inline void set_multi_polygon_union(bool value)
    {
        multi_polygon_union_ = value;
    }

    inline double get_simplify_distance() const
    {
        return simplify_distance_;
    }

    inline mapnik::view_transform const& get_transform()
    {
        return t_;
    }

    MAPNIK_VECTOR_INLINE void set_fill_type(polygon_fill_type type);

    MAPNIK_VECTOR_INLINE void apply(double scale_denom=0.0);

    MAPNIK_VECTOR_INLINE bool painted() const;

    MAPNIK_VECTOR_INLINE void apply_to_layer(mapnik::layer const& lay,
                        mapnik::projection const& proj0,
                        double scale,
                        double scale_denom,
                        unsigned width,
                        unsigned height,
                        box2d<double> const& extent,
                        int buffer_size);

    template <typename T2>
    MAPNIK_VECTOR_INLINE bool handle_geometry(T2 const& vs,
                                              mapnik::feature_impl const& feature,
                                              mapnik::geometry::geometry<double> const& geom,
                                              mapnik::box2d<int> const& tile_clipping_extent,
                                              mapnik::box2d<double> const& target_clipping_extent);
};

}} // end ns

#if !defined(MAPNIK_VECTOR_TILE_LIBRARY)
#include "vector_tile_processor.ipp"
#endif

#endif // __MAPNIK_VECTOR_TILE_PROCESSOR_H__
<|endoftext|>


<commit_before><commit_msg>TBR: phajdan.jr<commit_after><|endoftext|>


<commit_before>/* string_test.cc
   Copyright (c) 2012 Datacratic.  All rights reserved.
*/

#define BOOST_TEST_MAIN
#define BOOST_TEST_DYN_LINK
#include "soa/types/string.h"
#include <boost/test/unit_test.hpp>
#include <boost/regex/icu.hpp>
#include <boost/regex.hpp>
#include "soa/jsoncpp/json.h"
#include "jml/arch/format.h"

using namespace std;
using namespace ML;
using namespace Datacratic;

BOOST_AUTO_TEST_CASE( test_print_format )
{
   	std::string raw = "saint-jérôme";
   	// Test 1 - Iterate through the raw string with normal iterators we should not find 'é'
   	unsigned numAccentedChars = 0;
   	for(string::const_iterator it = raw.begin() ; it != raw.end(); ++it)
   	{
   		if (*it ==  L'é' || *it ==  L'ô')
   			numAccentedChars++;
   	}
   	BOOST_CHECK_EQUAL(numAccentedChars, 0);
   	Utf8String utf8(raw);
   	// Now iterate through the utf8 string
   	for (Utf8String::const_iterator it = utf8.begin(); it != utf8.end(); ++it)
   	{
   		if (*it ==  L'é' || *it ==  L'ô')
   			numAccentedChars++;
   	}
   	BOOST_CHECK_EQUAL(numAccentedChars, 2);
   	// Now add another string to it
  	std::string raw2 = "saint-jérôme2";
  	utf8+=raw2;
  	numAccentedChars=0;
  	// Now iterate through the utf8 string
   	for (Utf8String::const_iterator it = utf8.begin(); it != utf8.end(); ++it)
   	{
   		if (*it ==  L'é' || *it ==  L'ô')
   			numAccentedChars++;
   	}
   	BOOST_CHECK_EQUAL(numAccentedChars, 4);
   	string theString(utf8.rawData(), utf8.rawLength());
   	size_t found = raw.find(L'é') ;
   	BOOST_CHECK_EQUAL(found, string::npos);
   	// We do a normal regex first
   	boost::regex reg("é");
   	std::string raw4 = "saint-jérôme";
   	BOOST_CHECK_EQUAL( boost::regex_search(raw4, reg), true);
   	// Please see Saint-j\xC3A9r\xC3B4me for UTF-8 character table
   	boost::u32regex withHex = boost::make_u32regex("saint-j\xc3\xa9r\xc3\xb4me");
   	boost::u32regex withoutHex = boost::make_u32regex(L"[a-z]*-jérôme");
    boost::match_results<std::string::const_iterator> matches;
    BOOST_CHECK_EQUAL(boost::u32regex_search(raw, matches, withoutHex), true);
    if (boost::u32regex_search(raw, matches, withoutHex))
    {
    	for (boost::match_results< std::string::const_iterator >::const_iterator i = matches.begin(); i != matches.end(); ++i)
    	{
    	        if (i->matched) std::cout << "matches :       [" << i->str() << "]\n";
    	        else            std::cout << "doesn't match : [" << i->str() << "]\n";
    	}
    }
    else
    {
    	cerr << "did not get a match without hex" << endl;
    }
    BOOST_CHECK_EQUAL(boost::u32regex_search(raw, matches, withHex), true);
}

template<typename Str>
static size_t count_chars(const Str &str, std::initializer_list<wchar_t> chars) {
    size_t count = std::count_if(begin(str), end(str),
            [&](typename std::iterator_traits<typename Str::iterator>::value_type c) {
            return std::find(begin(chars), end(chars), c) != end(chars);
    });

    return count;
}

BOOST_AUTO_TEST_CASE( test_u32_string )
{
    const std::string str1 { "daß auf dïch" };

    auto nonAscii = count_chars(str1, { L'ß', L'ï' });

    BOOST_CHECK_EQUAL(nonAscii, 0);

    const Utf32String u32str1 { str1 };
    nonAscii = count_chars(u32str1, { L'ß', L'ï' });

    BOOST_CHECK_EQUAL(nonAscii, 2);

    Utf32String u32str2 { "daß" };

    Utf32String u32str3 { "für" };

    auto u32str4 = u32str2 + u32str3;
    nonAscii = count_chars(u32str4, { L'ß', L'ü' });
    BOOST_CHECK_EQUAL(nonAscii, 2);

    u32str4 += "Ô Mélodie!";

    nonAscii = count_chars(u32str4, { L'ß', L'ü', L'Ô', L'é' });
    BOOST_CHECK_EQUAL(nonAscii, 4);

    std::string ascii = u32str1.extractAscii();
    BOOST_CHECK_EQUAL(ascii, "da? auf d?ch");

    Utf32String plainAscii { "Plain Ascii" };
    BOOST_CHECK_EQUAL(plainAscii.extractAscii(), "Plain Ascii");

}
<commit_msg>Add basic test for dtoa<commit_after>/* string_test.cc
   Copyright (c) 2012 Datacratic.  All rights reserved.
*/

#define BOOST_TEST_MAIN
#define BOOST_TEST_DYN_LINK
#include "soa/types/string.h"
#include <boost/test/unit_test.hpp>
#include <boost/regex/icu.hpp>
#include <boost/regex.hpp>
#include "soa/jsoncpp/json.h"
#include "soa/types/dtoa.h"
#include "jml/arch/format.h"

using namespace std;
using namespace ML;
using namespace Datacratic;

BOOST_AUTO_TEST_CASE( test_print_format )
{
   	std::string raw = "saint-jérôme";
   	// Test 1 - Iterate through the raw string with normal iterators we should not find 'é'
   	unsigned numAccentedChars = 0;
   	for(string::const_iterator it = raw.begin() ; it != raw.end(); ++it)
   	{
   		if (*it ==  L'é' || *it ==  L'ô')
   			numAccentedChars++;
   	}
   	BOOST_CHECK_EQUAL(numAccentedChars, 0);
   	Utf8String utf8(raw);
   	// Now iterate through the utf8 string
   	for (Utf8String::const_iterator it = utf8.begin(); it != utf8.end(); ++it)
   	{
   		if (*it ==  L'é' || *it ==  L'ô')
   			numAccentedChars++;
   	}
   	BOOST_CHECK_EQUAL(numAccentedChars, 2);
   	// Now add another string to it
  	std::string raw2 = "saint-jérôme2";
  	utf8+=raw2;
  	numAccentedChars=0;
  	// Now iterate through the utf8 string
   	for (Utf8String::const_iterator it = utf8.begin(); it != utf8.end(); ++it)
   	{
   		if (*it ==  L'é' || *it ==  L'ô')
   			numAccentedChars++;
   	}
   	BOOST_CHECK_EQUAL(numAccentedChars, 4);
   	string theString(utf8.rawData(), utf8.rawLength());
   	size_t found = raw.find(L'é') ;
   	BOOST_CHECK_EQUAL(found, string::npos);
   	// We do a normal regex first
   	boost::regex reg("é");
   	std::string raw4 = "saint-jérôme";
   	BOOST_CHECK_EQUAL( boost::regex_search(raw4, reg), true);
   	// Please see Saint-j\xC3A9r\xC3B4me for UTF-8 character table
   	boost::u32regex withHex = boost::make_u32regex("saint-j\xc3\xa9r\xc3\xb4me");
   	boost::u32regex withoutHex = boost::make_u32regex(L"[a-z]*-jérôme");
    boost::match_results<std::string::const_iterator> matches;
    BOOST_CHECK_EQUAL(boost::u32regex_search(raw, matches, withoutHex), true);
    if (boost::u32regex_search(raw, matches, withoutHex))
    {
    	for (boost::match_results< std::string::const_iterator >::const_iterator i = matches.begin(); i != matches.end(); ++i)
    	{
    	        if (i->matched) std::cout << "matches :       [" << i->str() << "]\n";
    	        else            std::cout << "doesn't match : [" << i->str() << "]\n";
    	}
    }
    else
    {
    	cerr << "did not get a match without hex" << endl;
    }
    BOOST_CHECK_EQUAL(boost::u32regex_search(raw, matches, withHex), true);
}

template<typename Str>
static size_t count_chars(const Str &str, std::initializer_list<wchar_t> chars) {
    size_t count = std::count_if(begin(str), end(str),
            [&](typename std::iterator_traits<typename Str::iterator>::value_type c) {
            return std::find(begin(chars), end(chars), c) != end(chars);
    });

    return count;
}

BOOST_AUTO_TEST_CASE( test_u32_string )
{
    const std::string str1 { "daß auf dïch" };

    auto nonAscii = count_chars(str1, { L'ß', L'ï' });

    BOOST_CHECK_EQUAL(nonAscii, 0);

    const Utf32String u32str1 { str1 };
    nonAscii = count_chars(u32str1, { L'ß', L'ï' });

    BOOST_CHECK_EQUAL(nonAscii, 2);

    Utf32String u32str2 { "daß" };

    Utf32String u32str3 { "für" };

    auto u32str4 = u32str2 + u32str3;
    nonAscii = count_chars(u32str4, { L'ß', L'ü' });
    BOOST_CHECK_EQUAL(nonAscii, 2);

    u32str4 += "Ô Mélodie!";

    nonAscii = count_chars(u32str4, { L'ß', L'ü', L'Ô', L'é' });
    BOOST_CHECK_EQUAL(nonAscii, 4);

    std::string ascii = u32str1.extractAscii();
    BOOST_CHECK_EQUAL(ascii, "da? auf d?ch");

    Utf32String plainAscii { "Plain Ascii" };
    BOOST_CHECK_EQUAL(plainAscii.extractAscii(), "Plain Ascii");

}

BOOST_AUTO_TEST_CASE( test_basic_dtoa )
{
    double value = 365.0;
    BOOST_CHECK_EQUAL(dtoa(value) , "365");

    value = 0.0;
    BOOST_CHECK_EQUAL(dtoa(value) , "0");

    value = 10.1;
    BOOST_CHECK_EQUAL(dtoa(value) , "10.1");

    value = -10.1;
    BOOST_CHECK_EQUAL(dtoa(value) , "-10.1");

    value = -1089000000000;
    BOOST_CHECK_EQUAL(dtoa(value) , "-1.089e12");
}
<|endoftext|>


<commit_before>/**
 * @author Parikshit Ram (pram@cc.gatech.edu)
 * @file nbc_main.cc
 *
 * This program test drives the Simple Naive Bayes Classifier
 *
 * This classifier does parametric naive bayes classification
 * assuming that the features are sampled from a Gaussian
 * distribution.
 *
 * PARAMETERS TO BE INPUT:
 *
 * --train
 * This is the file that contains the training data
 *
 * --nbc/classes
 * This is the number of classes present in the training data
 *
 * --test
 * This file contains the data points which the trained
 * classifier would classify
 *
 * --output
 * This file will contain the classes to which the corresponding
 * data points in the testing data
 *
 */
#include "simple_nbc.h"
#include <fastlib/fx/io.h>

#include <armadillo>
#include <fastlib/data/dataset.h>
#include <fastlib/base/arma_compat.h>

/*const fx_entry_doc parm_nbc_main_entries[] = {
  {"train", FX_REQUIRED, FX_STR, NULL,
   " A file containing the training set\n"},
  {"test", FX_REQUIRED, FX_STR, NULL,
   " A file containing the test set\n"},
  {"output", FX_PARAM, FX_STR, NULL,
   " The file in which the output of the test would be "
   "written (defaults to 'output.csv')\n"},
  FX_ENTRY_DOC_DONE
};*/

PARAM_STRING_REQ("train", "A file containing the training set", "nbc");
PARAM_STRING_REQ("test", "A file containing the test set", "nbc");
PARAM_STRING("output", "The file in which the output of the test would\
 be written, defaults to 'output.csv')", "nbc", "output.csv");

/*const fx_submodule_doc parm_nbc_main_submodules[] = {
  {"nbc", &parm_nbc_doc,
   " Trains on a given set and number of classes and "
   "tests them on a given set\n"},
  FX_SUBMODULE_DOC_DONE
};*/

PARAM_MODULE("nbc", "Trains on a given set and number\
 of classes and tests them on a given set");

/*const fx_module_doc parm_nbc_main_doc = {
  parm_nbc_main_entries, parm_nbc_main_submodules,
  "This program test drives the Parametric Naive Bayes \n"
  "Classifier assuming that the features are sampled \n"
  "from a Gaussian distribution.\n"
};*/

PROGRAM_INFO("Parametric Naive Bayes", "This program test drives the\
 Parametric Naive Bayes Classifier assuming that the features are\
 sampled from a Gaussian distribution.", "nbc");

using namespace mlpack;

int main(int argc, char* argv[]) {

  IO::ParseCommandLine(argc, argv);

  ////// READING PARAMETERS AND LOADING DATA //////

  const char *training_data_filename = IO::GetParam<std::string>("nbc/train").c_str();
  arma::mat training_data;
  data::Load(training_data_filename, training_data);

  const char *testing_data_filename = IO::GetParam<std::string>("nbc/test").c_str();
  arma::mat testing_data;
  data::Load(testing_data_filename, testing_data);

  ////// SIMPLE NAIVE BAYES CLASSIFICATION ASSUMING THE DATA TO BE UNIFORMLY DISTRIBUTED //////

  ////// Timing the training of the Naive Bayes Classifier //////
  IO::StartTimer("nbc/training");

  ////// Create and train the classifier
  SimpleNaiveBayesClassifier nbc = SimpleNaiveBayesClassifier(training_data);

  ////// Stop training timer //////
  IO::StopTimer("nbc/training");

  ////// Timing the testing of the Naive Bayes Classifier //////
  ////// The variable that contains the result of the classification
  arma::vec results;

  IO::StartTimer("nbc/testing");

  ////// Calling the function that classifies the test data
  nbc.Classify(testing_data, results);

  ////// Stop testing timer //////
  IO::StopTimer("nbc/testing");

  ////// OUTPUT RESULTS //////
  std::string output_filename = IO::GetParam<std::string>("nbc/output");

  data::Save(output_filename.c_str(), results);

  return 1;
}
<commit_msg>Stop using arma_compat.<commit_after>/**
 * @author Parikshit Ram (pram@cc.gatech.edu)
 * @file nbc_main.cc
 *
 * This program test drives the Simple Naive Bayes Classifier
 *
 * This classifier does parametric naive bayes classification
 * assuming that the features are sampled from a Gaussian
 * distribution.
 *
 * PARAMETERS TO BE INPUT:
 *
 * --train
 * This is the file that contains the training data
 *
 * --nbc/classes
 * This is the number of classes present in the training data
 *
 * --test
 * This file contains the data points which the trained
 * classifier would classify
 *
 * --output
 * This file will contain the classes to which the corresponding
 * data points in the testing data
 *
 */
#include "simple_nbc.h"
#include <fastlib/fx/io.h>

#include <armadillo>
#include <fastlib/data/dataset.h>

/*const fx_entry_doc parm_nbc_main_entries[] = {
  {"train", FX_REQUIRED, FX_STR, NULL,
   " A file containing the training set\n"},
  {"test", FX_REQUIRED, FX_STR, NULL,
   " A file containing the test set\n"},
  {"output", FX_PARAM, FX_STR, NULL,
   " The file in which the output of the test would be "
   "written (defaults to 'output.csv')\n"},
  FX_ENTRY_DOC_DONE
};*/

PARAM_STRING_REQ("train", "A file containing the training set", "nbc");
PARAM_STRING_REQ("test", "A file containing the test set", "nbc");
PARAM_STRING("output", "The file in which the output of the test would\
 be written, defaults to 'output.csv')", "nbc", "output.csv");

/*const fx_submodule_doc parm_nbc_main_submodules[] = {
  {"nbc", &parm_nbc_doc,
   " Trains on a given set and number of classes and "
   "tests them on a given set\n"},
  FX_SUBMODULE_DOC_DONE
};*/

PARAM_MODULE("nbc", "Trains on a given set and number\
 of classes and tests them on a given set");

/*const fx_module_doc parm_nbc_main_doc = {
  parm_nbc_main_entries, parm_nbc_main_submodules,
  "This program test drives the Parametric Naive Bayes \n"
  "Classifier assuming that the features are sampled \n"
  "from a Gaussian distribution.\n"
};*/

PROGRAM_INFO("Parametric Naive Bayes", "This program test drives the\
 Parametric Naive Bayes Classifier assuming that the features are\
 sampled from a Gaussian distribution.", "nbc");

using namespace mlpack;

int main(int argc, char* argv[]) {

  IO::ParseCommandLine(argc, argv);

  ////// READING PARAMETERS AND LOADING DATA //////

  const char *training_data_filename = IO::GetParam<std::string>("nbc/train").c_str();
  arma::mat training_data;
  data::Load(training_data_filename, training_data);

  const char *testing_data_filename = IO::GetParam<std::string>("nbc/test").c_str();
  arma::mat testing_data;
  data::Load(testing_data_filename, testing_data);

  ////// SIMPLE NAIVE BAYES CLASSIFICATION ASSUMING THE DATA TO BE UNIFORMLY DISTRIBUTED //////

  ////// Timing the training of the Naive Bayes Classifier //////
  IO::StartTimer("nbc/training");

  ////// Create and train the classifier
  SimpleNaiveBayesClassifier nbc = SimpleNaiveBayesClassifier(training_data);

  ////// Stop training timer //////
  IO::StopTimer("nbc/training");

  ////// Timing the testing of the Naive Bayes Classifier //////
  ////// The variable that contains the result of the classification
  arma::vec results;

  IO::StartTimer("nbc/testing");

  ////// Calling the function that classifies the test data
  nbc.Classify(testing_data, results);

  ////// Stop testing timer //////
  IO::StopTimer("nbc/testing");

  ////// OUTPUT RESULTS //////
  std::string output_filename = IO::GetParam<std::string>("nbc/output");

  data::Save(output_filename.c_str(), results);

  return 1;
}
<|endoftext|>


<commit_before>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

// MOOSE includes
#include "Resurrector.h"
#include "FEProblem.h"
#include "MooseUtils.h"
#include "MooseApp.h"
#include "NonlinearSystem.h"

#include <stdio.h>
#include <sys/stat.h>

const std::string Resurrector::MAT_PROP_EXT(".msmp");
const std::string Resurrector::RESTARTABLE_DATA_EXT(".rd");

Resurrector::Resurrector(FEProblemBase & fe_problem)
  : PerfGraphInterface(fe_problem.getMooseApp().perfGraph(), "Resurrector"),
    _fe_problem(fe_problem),
    _restart_file_suffix("xdr"),
    _restartable(_fe_problem),
    _restart_from_file_timer(registerTimedSection("restartFromFile", 3)),
    _restart_restartable_data_timer(registerTimedSection("restartRestartableData", 3))
{
}

void
Resurrector::setRestartFile(const std::string & file_base)
{
  _restart_file_base = file_base;
}

void
Resurrector::setRestartSuffix(const std::string & file_ext)
{
  _restart_file_suffix = file_ext;
}

void
Resurrector::restartFromFile()
{
  TIME_SECTION(_restart_from_file_timer);

  std::string file_name(_restart_file_base + '.' + _restart_file_suffix);
  MooseUtils::checkFileReadable(file_name);
  _restartable.readRestartableDataHeader(_restart_file_base + RESTARTABLE_DATA_EXT);
  unsigned int read_flags = EquationSystems::READ_DATA;
  if (!_fe_problem.skipAdditionalRestartData())
    read_flags |= EquationSystems::READ_ADDITIONAL_DATA;

  // Set libHilbert renumbering flag to false.  We don't support
  // N-to-M restarts regardless, and if we're *never* going to do
  // N-to-M restarts then libHilbert is just unnecessary computation
  // and communication.
  const bool renumber = false;

  // DECODE or READ based on suffix.
  // MOOSE doesn't currently use partition-agnostic renumbering, since
  // it can break restarts when multiple nodes are at the same point
  _fe_problem.es().read(file_name, read_flags, renumber);

  _fe_problem.getNonlinearSystemBase().update();
  Moose::perf_log.pop("restartFromFile()", "Setup");
}

void
Resurrector::restartRestartableData()
{
  TIME_SECTION(_restart_restartable_data_timer);

  _restartable.readRestartableData(_fe_problem.getMooseApp().getRestartableData(),
                                   _fe_problem.getMooseApp().getRecoverableData());
}
<commit_msg>Fix restart failure refs #11551<commit_after>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

// MOOSE includes
#include "Resurrector.h"
#include "FEProblem.h"
#include "MooseUtils.h"
#include "MooseApp.h"
#include "NonlinearSystem.h"

#include <stdio.h>
#include <sys/stat.h>

const std::string Resurrector::MAT_PROP_EXT(".msmp");
const std::string Resurrector::RESTARTABLE_DATA_EXT(".rd");

Resurrector::Resurrector(FEProblemBase & fe_problem)
  : PerfGraphInterface(fe_problem.getMooseApp().perfGraph(), "Resurrector"),
    _fe_problem(fe_problem),
    _restart_file_suffix("xdr"),
    _restartable(_fe_problem),
    _restart_from_file_timer(registerTimedSection("restartFromFile", 3)),
    _restart_restartable_data_timer(registerTimedSection("restartRestartableData", 3))
{
}

void
Resurrector::setRestartFile(const std::string & file_base)
{
  _restart_file_base = file_base;
}

void
Resurrector::setRestartSuffix(const std::string & file_ext)
{
  _restart_file_suffix = file_ext;
}

void
Resurrector::restartFromFile()
{
  TIME_SECTION(_restart_from_file_timer);

  std::string file_name(_restart_file_base + '.' + _restart_file_suffix);
  MooseUtils::checkFileReadable(file_name);
  _restartable.readRestartableDataHeader(_restart_file_base + RESTARTABLE_DATA_EXT);
  unsigned int read_flags = EquationSystems::READ_DATA;
  if (!_fe_problem.skipAdditionalRestartData())
    read_flags |= EquationSystems::READ_ADDITIONAL_DATA;

  // Set libHilbert renumbering flag to false.  We don't support
  // N-to-M restarts regardless, and if we're *never* going to do
  // N-to-M restarts then libHilbert is just unnecessary computation
  // and communication.
  const bool renumber = false;

  // DECODE or READ based on suffix.
  // MOOSE doesn't currently use partition-agnostic renumbering, since
  // it can break restarts when multiple nodes are at the same point
  _fe_problem.es().read(file_name, read_flags, renumber);

  _fe_problem.getNonlinearSystemBase().update();
}

void
Resurrector::restartRestartableData()
{
  TIME_SECTION(_restart_restartable_data_timer);

  _restartable.readRestartableData(_fe_problem.getMooseApp().getRestartableData(),
                                   _fe_problem.getMooseApp().getRecoverableData());
}
<|endoftext|>


<commit_before>#if !FEATURE_LWIP
    #error [NOT_SUPPORTED] LWIP not supported for this target
#endif
#if DEVICE_EMAC
    #error [NOT_SUPPORTED] Not supported for WiFi targets
#endif

#include "mbed.h"
#include "EthernetInterface.h"
#include "UDPSocket.h"
#include "greentea-client/test_env.h"
#include "unity/unity.h"

#ifndef MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE
#define MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE 256
#endif

#ifndef MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT
#define MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT 500
#endif

namespace {
    char tx_buffer[MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE] = {0};
    char rx_buffer[MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE] = {0};
    const char ASCII_MAX = '~' - ' ';
    const int ECHO_LOOPS = 16;
}

void prep_buffer(char *tx_buffer, size_t tx_size) {
    for (size_t i=0; i<tx_size; ++i) {
        tx_buffer[i] = (rand() % 10) + '0';
    }
}

int main() {
    GREENTEA_SETUP(60, "udp_echo");

    EthernetInterface eth;
    eth.connect();
    printf("UDP client IP Address is %s\n", eth.get_ip_address());

    greentea_send_kv("target_ip", eth.get_ip_address());

    char recv_key[] = "host_port";
    char ipbuf[60] = {0};
    char portbuf[16] = {0};
    unsigned int port = 0;

    UDPSocket sock;
    sock.open(&eth);
    sock.set_timeout(MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT);

    greentea_send_kv("host_ip", " ");
    greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf));

    greentea_send_kv("host_port", " ");
    greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf));
    sscanf(portbuf, "%u", &port);

    printf("MBED: UDP Server IP address received: %s:%d \n", ipbuf, port);
    SocketAddress udp_addr(ipbuf, port);

    int success = 0;

    for (int i=0; i < ECHO_LOOPS; ++i) {
        prep_buffer(tx_buffer, sizeof(tx_buffer));
        const int ret = sock.sendto(udp_addr, tx_buffer, sizeof(tx_buffer));
        printf("[%02d] sent...%d Bytes \n", i, ret);

        SocketAddress temp_addr;
        const int n = sock.recvfrom(&temp_addr, rx_buffer, sizeof(rx_buffer));
        printf("[%02d] recv...%d Bytes \n", i, n);

        if ((temp_addr == udp_addr &&
             n == sizeof(tx_buffer) &&
             memcmp(rx_buffer, tx_buffer, sizeof(rx_buffer)) == 0)) {
            success += 1;
        }
    }

    bool result = (success > 3*ECHO_LOOPS/4);

    sock.close();
    eth.disconnect();
    GREENTEA_TESTSUITE_RESULT(result);
}
<commit_msg>Making UDP test less strict on dropped/mismatched packets.<commit_after>#if !FEATURE_LWIP
    #error [NOT_SUPPORTED] LWIP not supported for this target
#endif
#if DEVICE_EMAC
    #error [NOT_SUPPORTED] Not supported for WiFi targets
#endif

#include "mbed.h"
#include "EthernetInterface.h"
#include "UDPSocket.h"
#include "greentea-client/test_env.h"
#include "unity/unity.h"

#ifndef MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE
#define MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE 64
#endif

#ifndef MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT
#define MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT 500
#endif

namespace {
    char tx_buffer[MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE] = {0};
    char rx_buffer[MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE] = {0};
    const char ASCII_MAX = '~' - ' ';
    const int ECHO_LOOPS = 16;
}

void prep_buffer(char *uuid_buffer, size_t uuid_len, char *tx_buffer, size_t tx_size) {
    size_t i = 0;

    for (; i<uuid_len; ++i) {
        tx_buffer[i] = uuid_buffer[i];
    }

    tx_buffer[i++] = ' ';

    for (; i<tx_size; ++i) {
        tx_buffer[i] = (rand() % 10) + '0';
    }
}

int main() {
    char uuid[48] = {0};
    GREENTEA_SETUP_UUID(60, "udp_echo", uuid, 48);
    printf("Got a uuid of %s\r\n", uuid);
    size_t uuid_len = strlen(uuid);
    EthernetInterface eth;
    eth.connect();
    printf("UDP client IP Address is %s\n", eth.get_ip_address());

    greentea_send_kv("target_ip", eth.get_ip_address());

    char recv_key[] = "host_port";
    char ipbuf[60] = {0};
    char portbuf[16] = {0};
    unsigned int port = 0;

    UDPSocket sock;
    sock.open(&eth);
    sock.set_timeout(MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT);

    greentea_send_kv("host_ip", " ");
    greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf));

    greentea_send_kv("host_port", " ");
    greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf));
    sscanf(portbuf, "%u", &port);

    printf("MBED: UDP Server IP address received: %s:%d \n", ipbuf, port);
    SocketAddress udp_addr(ipbuf, port);

    int success = 0;
    int i = 0;
    while (success < ECHO_LOOPS) {
        prep_buffer(uuid, uuid_len, tx_buffer, sizeof(tx_buffer));
        const int ret = sock.sendto(udp_addr, tx_buffer, sizeof(tx_buffer));
        printf("[%02d] sent %d Bytes - %.*s  \n", i, ret, MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE, tx_buffer);
        SocketAddress temp_addr;
        const int n = sock.recvfrom(&temp_addr, rx_buffer, sizeof(rx_buffer));
        printf("[%02d] recv %d Bytes - %.*s  \n", i, ret, MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE, rx_buffer);

        if ((temp_addr == udp_addr &&
             n == sizeof(tx_buffer) &&
             memcmp(rx_buffer, tx_buffer, sizeof(rx_buffer)) == 0)) {
            success += 1;

            printf("[%02d] success #%d\n", i, success);
        }
        i++;
    }

    bool result = success == ECHO_LOOPS;

    sock.close();
    eth.disconnect();
    GREENTEA_TESTSUITE_RESULT(result);
}
<|endoftext|>