<commit_before>//  tinygettext - A gettext replacement that works directly on .po files
//  Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
//
//  This program is free software; you can redistribute it and/or
//  modify it under the terms of the GNU General Public License
//  as published by the Free Software Foundation; either version 2
//  of the License, or (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

#include "po_parser.hpp"

#include <iostream>
#include <ctype.h>
#include <string>
#include <istream>
#include <string.h>
#include <map>
#include <stddef.h>   // for size_t
#include <stdlib.h>

#include "language.hpp"
#include "log_stream.hpp"
#include "iconv.hpp"
#include "dictionary.hpp"
#include "plural_forms.hpp"

namespace tinygettext {
bool POParser::pedantic = true;

void
POParser::parse(const std::string& filename, std::istream& in, Dictionary& dict)
{
  POParser parser(filename, in, dict);
  parser.parse();
}

class POParserError {};

POParser::POParser(const std::string& filename_, std::istream& in_, Dictionary& dict_, bool use_fuzzy_) :
  filename(filename_),
  in(in_),
  dict(dict_),
  use_fuzzy(use_fuzzy_),
  running(false),
  eof(false),
  big5(false),
  line_number(0),
  current_line(),
  conv()
{
}

POParser::~POParser()
{
}

void
POParser::warning(const std::string& msg)
{
  log_warning << filename << ":" << line_number << ": warning: " << msg << ": " << current_line << std::endl;
  //log_warning << "Line: " << current_line << std::endl;
}

void
POParser::error(const std::string& msg)
{
  log_error << filename << ":" << line_number << ": error: " << msg  << ": " << current_line << std::endl;

  // Try to recover from an error by searching for start of another entry
  do
    next_line();
  while(!eof && !is_empty_line());

  throw POParserError();
}

void
POParser::next_line()
{
  line_number += 1;
  if (!std::getline(in, current_line))
    eof = true;
}

void
POParser::get_string_line(std::ostringstream& out,unsigned int skip)
{
  if (skip+1 >= static_cast<unsigned int>(current_line.size()))
    error("unexpected end of line");

  if (current_line[skip] != '"')
    error("expected start of string '\"'");

  std::string::size_type i;
  for(i = skip+1; current_line[i] != '\"'; ++i)
  {
    if (big5 && static_cast<unsigned char>(current_line[i]) >= 0x81 && static_cast<unsigned char>(current_line[i]) <= 0xfe)
    {
      out << current_line[i];

      i += 1;

      if (i >= current_line.size())
        error("invalid big5 encoding");

      out << current_line[i];
    }
    else if (i >= current_line.size())
    {
      error("unexpected end of string");
    }
    else if (current_line[i] == '\\')
    {
      i += 1;

      if (i >= current_line.size())
        error("unexpected end of string in handling '\\'");

      switch (current_line[i])
      {
        case 'a':  out << '\a'; break;
        case 'b':  out << '\b'; break;
        case 'v':  out << '\v'; break;
        case 'n':  out << '\n'; break;
        case 't':  out << '\t'; break;
        case 'r':  out << '\r'; break;
        case '"':  out << '"'; break;
        case '\\': out << '\\'; break;
        default:
          std::ostringstream err;
          err << "unhandled escape '\\" << current_line[i] << "'";
          warning(err.str());

          out << current_line[i-1] << current_line[i];
          break;
      }
    }
    else
    {
      out << current_line[i];
    }
  }

  // process trailing garbage in line and warn if there is any
  for(i = i+1; i < current_line.size(); ++i)
    if (!isspace(current_line[i]))
    {
      warning("unexpected garbage after string ignoren");
      break;
    }
}

std::string
POParser::get_string(unsigned int skip)
{
  std::ostringstream out;

  if (skip+1 >= static_cast<unsigned int>(current_line.size()))
    error("unexpected end of line");

  if (current_line[skip] == ' ' && current_line[skip+1] == '"')
  {
    get_string_line(out, skip+1);
  }
  else
  {
    if (pedantic)
      warning("keyword and string must be seperated by a single space");

    for(;;)
    {
      if (skip >= static_cast<unsigned int>(current_line.size()))
        error("unexpected end of line");
      else if (current_line[skip] == '\"')
      {
        get_string_line(out, skip);
        break;
      }
      else if (!isspace(current_line[skip]))
      {
        error("string must start with '\"'");
      }
      else
      {
        // skip space
      }

      skip += 1;
    }
  }

next:
  next_line();
  for(std::string::size_type i = 0; i < current_line.size(); ++i)
  {
    if (current_line[i] == '"')
    {
      if (i == 1)
        if (pedantic)
          warning("leading whitespace before string");

      get_string_line(out, i);
      goto next;
    }
    else if (isspace(current_line[i]))
    {
      // skip
    }
    else
    {
      break;
    }
  }

  return out.str();
}

static bool has_prefix(const std::string& lhs, const std::string rhs)
{
  if (lhs.length() < rhs.length())
    return false;
  else
    return lhs.compare(0, rhs.length(), rhs) == 0;
}

void
POParser::parse_header(const std::string& header)
{
  std::string from_charset;
  std::string::size_type start = 0;
  for(std::string::size_type i = 0; i < header.length(); ++i)
  {
    if (header[i] == '\n')
    {
      std::string line = header.substr(start, i - start);

      if (has_prefix(line, "Content-Type:"))
      {
        // from_charset = line.substr(len);
        size_t len = strlen("Content-Type: text/plain; charset=");
        if (line.compare(0, len, "Content-Type: text/plain; charset=") == 0)
        {
          from_charset = line.substr(len);

          for(std::string::iterator ch = from_charset.begin(); ch != from_charset.end(); ++ch)
            *ch = static_cast<char>(toupper(*ch));
        }
        else
        {
          warning("malformed Content-Type header");
        }
      }
      else if (has_prefix(line, "Plural-Forms:"))
      {
        PluralForms plural_forms = PluralForms::from_string(line);
        if (!plural_forms)
        {
          warning("unknown Plural-Forms given");
        }
        else
        {
          if (!dict.get_plural_forms())
          {
            dict.set_plural_forms(plural_forms);
          }
          else
          {
            if (dict.get_plural_forms() != plural_forms)
            {
              warning("Plural-Forms missmatch between .po file and dictionary");
            }
          }
        }
      }
      start = i+1;
    }
  }

  if (from_charset.empty() || from_charset == "CHARSET")
  {
    warning("charset not specified for .po, fallback to utf-8");
    from_charset = "UTF-8";
  }
  else if (from_charset == "BIG5")
  {
    big5 = true;
  }

  conv.set_charsets(from_charset, dict.get_charset());
}

bool
POParser::is_empty_line()
{
  if (current_line.empty())
  {
    return true;
  }
  else if (current_line[0] == '#')
  { // handle comments as empty lines
    if (current_line.size() == 1 || (current_line.size() >= 2 && isspace(current_line[1])))
      return true;
    else
      return false;
  }
  else
  {
    for(std::string::iterator i = current_line.begin(); i != current_line.end(); ++i)
    {
      if (!isspace(*i))
        return false;
    }
  }
  return true;
}

bool
POParser::prefix(const char* prefix_str)
{
  return current_line.compare(0, strlen(prefix_str), prefix_str) == 0;
}

void
POParser::parse()
{
  next_line();

  // skip UTF-8 intro that some text editors produce
  // see http://en.wikipedia.org/wiki/Byte-order_mark
  if (current_line.size() >= 3 &&
      current_line[0] == '\xef' &&
      current_line[1] == '\xbb' &&
      current_line[2] == '\xbf')
  {
    current_line = current_line.substr(3);
  }

  // Parser structure
  while(!eof)
  {
    try
    {
      bool fuzzy =  false;
      bool has_msgctxt = false;
      std::string msgctxt;
      std::string msgid;

      while(prefix("#"))
      {
        if (current_line.size() >= 2 && current_line[1] == ',')
        {
          // FIXME: Rather simplistic hunt for fuzzy flag
          if (current_line.find("fuzzy", 2) != std::string::npos)
            fuzzy = true;
        }

        next_line();
      }

      if (!is_empty_line())
      {
        if (prefix("msgctxt"))
        {
          has_msgctxt = true;
          msgctxt = get_string(7);
        }

        if (prefix("msgid"))
          msgid = get_string(5);
        else
          error("expected 'msgid'");

        if (prefix("msgid_plural"))
        {
          std::string msgid_plural = get_string(12);
          std::vector<std::string> msgstr_num;
	  bool saw_nonempty_msgstr = false;

        next:
          if (is_empty_line())
          {
            if (msgstr_num.empty())
              error("expected 'msgstr[N] (0 <= N <= 9)'");
          }
          else if (prefix("msgstr[") &&
                   current_line.size() > 8 &&
                   isdigit(current_line[7]) && current_line[8] == ']')
          {
            unsigned int number = static_cast<unsigned int>(current_line[7] - '0');
	    std::string msgstr = get_string(9);

	    if(!msgstr.empty())
	      saw_nonempty_msgstr = true;

            if (number >= msgstr_num.size())
              msgstr_num.resize(number+1);

            msgstr_num[number] = conv.convert(msgstr);
            goto next;
          }
          else
          {
            error("expected 'msgstr[N]'");
          }

          if (!is_empty_line())
            error("expected 'msgstr[N]' or empty line");

	  if (saw_nonempty_msgstr)
	  {
	    if (use_fuzzy || !fuzzy)
            {
	      if (!dict.get_plural_forms())
	      {
		warning("msgstr[N] seen, but no Plural-Forms given");
	      }
	      else
	      {
		if (msgstr_num.size() != dict.get_plural_forms().get_nplural())
		{
		  warning("msgstr[N] count doesn't match Plural-Forms.nplural");
		}
	      }

	      if (has_msgctxt)
		dict.add_translation(msgctxt, msgid, msgid_plural, msgstr_num);
	      else
		dict.add_translation(msgid, msgid_plural, msgstr_num);
	    }

	    if (0)
	    {
	      std::cout << (fuzzy?"fuzzy":"not-fuzzy") << std::endl;
	      std::cout << "msgid \"" << msgid << "\"" << std::endl;
	      std::cout << "msgid_plural \"" << msgid_plural << "\"" << std::endl;
	      for(std::vector<std::string>::size_type i = 0; i < msgstr_num.size(); ++i)
		std::cout << "msgstr[" << i << "] \"" << conv.convert(msgstr_num[i]) << "\"" << std::endl;
	      std::cout << std::endl;
	    }
	  }
        }
        else if (prefix("msgstr"))
        {
          std::string msgstr = get_string(6);

          if (msgid.empty())
          {
            parse_header(msgstr);
          }
          else if(!msgstr.empty())
          {
            if (use_fuzzy || !fuzzy)
            {
              if (has_msgctxt)
                dict.add_translation(msgctxt, msgid, conv.convert(msgstr));
              else
                dict.add_translation(msgid, conv.convert(msgstr));
            }

            if (0)
            {
              std::cout << (fuzzy?"fuzzy":"not-fuzzy") << std::endl;
              std::cout << "msgid \"" << msgid << "\"" << std::endl;
              std::cout << "msgstr \"" << conv.convert(msgstr) << "\"" << std::endl;
              std::cout << std::endl;
            }
          }
        }
        else
        {
          error("expected 'msgstr' or 'msgid_plural'");
        }
      }

      if (!is_empty_line())
        error("expected empty line");

      next_line();
    }
    catch(POParserError&)
    {
    }
  }
}
} // namespace tinygettext

/* EOF */
<commit_msg>[tinygettext] Precache string length in loop (DEBUG builds optimization)<commit_after>//  tinygettext - A gettext replacement that works directly on .po files
//  Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
//
//  This program is free software; you can redistribute it and/or
//  modify it under the terms of the GNU General Public License
//  as published by the Free Software Foundation; either version 2
//  of the License, or (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

#include "po_parser.hpp"

#include <iostream>
#include <ctype.h>
#include <string>
#include <istream>
#include <string.h>
#include <map>
#include <stddef.h>   // for size_t
#include <stdlib.h>

#include "language.hpp"
#include "log_stream.hpp"
#include "iconv.hpp"
#include "dictionary.hpp"
#include "plural_forms.hpp"

namespace tinygettext {
bool POParser::pedantic = true;

void
POParser::parse(const std::string& filename, std::istream& in, Dictionary& dict)
{
  POParser parser(filename, in, dict);
  parser.parse();
}

class POParserError {};

POParser::POParser(const std::string& filename_, std::istream& in_, Dictionary& dict_, bool use_fuzzy_) :
  filename(filename_),
  in(in_),
  dict(dict_),
  use_fuzzy(use_fuzzy_),
  running(false),
  eof(false),
  big5(false),
  line_number(0),
  current_line(),
  conv()
{
}

POParser::~POParser()
{
}

void
POParser::warning(const std::string& msg)
{
  log_warning << filename << ":" << line_number << ": warning: " << msg << ": " << current_line << std::endl;
  //log_warning << "Line: " << current_line << std::endl;
}

void
POParser::error(const std::string& msg)
{
  log_error << filename << ":" << line_number << ": error: " << msg  << ": " << current_line << std::endl;

  // Try to recover from an error by searching for start of another entry
  do
    next_line();
  while(!eof && !is_empty_line());

  throw POParserError();
}

void
POParser::next_line()
{
  line_number += 1;
  if (!std::getline(in, current_line))
    eof = true;
}

void
POParser::get_string_line(std::ostringstream& out,unsigned int skip)
{
  if (skip+1 >= static_cast<unsigned int>(current_line.size()))
    error("unexpected end of line");

  if (current_line[skip] != '"')
    error("expected start of string '\"'");

  std::string::size_type i;
  for(i = skip+1; current_line[i] != '\"'; ++i)
  {
    if (big5 && static_cast<unsigned char>(current_line[i]) >= 0x81 && static_cast<unsigned char>(current_line[i]) <= 0xfe)
    {
      out << current_line[i];

      i += 1;

      if (i >= current_line.size())
        error("invalid big5 encoding");

      out << current_line[i];
    }
    else if (i >= current_line.size())
    {
      error("unexpected end of string");
    }
    else if (current_line[i] == '\\')
    {
      i += 1;

      if (i >= current_line.size())
        error("unexpected end of string in handling '\\'");

      switch (current_line[i])
      {
        case 'a':  out << '\a'; break;
        case 'b':  out << '\b'; break;
        case 'v':  out << '\v'; break;
        case 'n':  out << '\n'; break;
        case 't':  out << '\t'; break;
        case 'r':  out << '\r'; break;
        case '"':  out << '"'; break;
        case '\\': out << '\\'; break;
        default:
          std::ostringstream err;
          err << "unhandled escape '\\" << current_line[i] << "'";
          warning(err.str());

          out << current_line[i-1] << current_line[i];
          break;
      }
    }
    else
    {
      out << current_line[i];
    }
  }

  // process trailing garbage in line and warn if there is any
  for(i = i+1; i < current_line.size(); ++i)
    if (!isspace(current_line[i]))
    {
      warning("unexpected garbage after string ignoren");
      break;
    }
}

std::string
POParser::get_string(unsigned int skip)
{
  std::ostringstream out;

  if (skip+1 >= static_cast<unsigned int>(current_line.size()))
    error("unexpected end of line");

  if (current_line[skip] == ' ' && current_line[skip+1] == '"')
  {
    get_string_line(out, skip+1);
  }
  else
  {
    if (pedantic)
      warning("keyword and string must be seperated by a single space");

    for(;;)
    {
      if (skip >= static_cast<unsigned int>(current_line.size()))
        error("unexpected end of line");
      else if (current_line[skip] == '\"')
      {
        get_string_line(out, skip);
        break;
      }
      else if (!isspace(current_line[skip]))
      {
        error("string must start with '\"'");
      }
      else
      {
        // skip space
      }

      skip += 1;
    }
  }

next:
  next_line();
  for(std::string::size_type i = 0; i < current_line.size(); ++i)
  {
    if (current_line[i] == '"')
    {
      if (i == 1)
        if (pedantic)
          warning("leading whitespace before string");

      get_string_line(out, i);
      goto next;
    }
    else if (isspace(current_line[i]))
    {
      // skip
    }
    else
    {
      break;
    }
  }

  return out.str();
}

static bool has_prefix(const std::string& lhs, const std::string rhs)
{
  if (lhs.length() < rhs.length())
    return false;
  else
    return lhs.compare(0, rhs.length(), rhs) == 0;
}

void
POParser::parse_header(const std::string& header)
{
  std::string from_charset;
  std::string::size_type start = 0;
  const char content_type[] = "Content-Type: text/plain; charset=";
  const size_t content_type_len = strlen(content_type);
  for(std::string::size_type i = 0; i < header.length(); ++i)
  {
    if (header[i] == '\n')
    {
      std::string line = header.substr(start, i - start);

      if (has_prefix(line, "Content-Type:"))
      {
        // from_charset = line.substr(len);
        if (line.compare(0, content_type_len, content_type) == 0)
        {
          from_charset = line.substr(content_type_len);

          for(std::string::iterator ch = from_charset.begin(); ch != from_charset.end(); ++ch)
            *ch = static_cast<char>(toupper(*ch));
        }
        else
        {
          warning("malformed Content-Type header");
        }
      }
      else if (has_prefix(line, "Plural-Forms:"))
      {
        PluralForms plural_forms = PluralForms::from_string(line);
        if (!plural_forms)
        {
          warning("unknown Plural-Forms given");
        }
        else
        {
          if (!dict.get_plural_forms())
          {
            dict.set_plural_forms(plural_forms);
          }
          else
          {
            if (dict.get_plural_forms() != plural_forms)
            {
              warning("Plural-Forms missmatch between .po file and dictionary");
            }
          }
        }
      }
      start = i+1;
    }
  }

  if (from_charset.empty() || from_charset == "CHARSET")
  {
    warning("charset not specified for .po, fallback to utf-8");
    from_charset = "UTF-8";
  }
  else if (from_charset == "BIG5")
  {
    big5 = true;
  }

  conv.set_charsets(from_charset, dict.get_charset());
}

bool
POParser::is_empty_line()
{
  if (current_line.empty())
  {
    return true;
  }
  else if (current_line[0] == '#')
  { // handle comments as empty lines
    if (current_line.size() == 1 || (current_line.size() >= 2 && isspace(current_line[1])))
      return true;
    else
      return false;
  }
  else
  {
    for(std::string::iterator i = current_line.begin(); i != current_line.end(); ++i)
    {
      if (!isspace(*i))
        return false;
    }
  }
  return true;
}

bool
POParser::prefix(const char* prefix_str)
{
  return current_line.compare(0, strlen(prefix_str), prefix_str) == 0;
}

void
POParser::parse()
{
  next_line();

  // skip UTF-8 intro that some text editors produce
  // see http://en.wikipedia.org/wiki/Byte-order_mark
  if (current_line.size() >= 3 &&
      current_line[0] == '\xef' &&
      current_line[1] == '\xbb' &&
      current_line[2] == '\xbf')
  {
    current_line = current_line.substr(3);
  }

  // Parser structure
  while(!eof)
  {
    try
    {
      bool fuzzy =  false;
      bool has_msgctxt = false;
      std::string msgctxt;
      std::string msgid;

      while(prefix("#"))
      {
        if (current_line.size() >= 2 && current_line[1] == ',')
        {
          // FIXME: Rather simplistic hunt for fuzzy flag
          if (current_line.find("fuzzy", 2) != std::string::npos)
            fuzzy = true;
        }

        next_line();
      }

      if (!is_empty_line())
      {
        if (prefix("msgctxt"))
        {
          has_msgctxt = true;
          msgctxt = get_string(7);
        }

        if (prefix("msgid"))
          msgid = get_string(5);
        else
          error("expected 'msgid'");

        if (prefix("msgid_plural"))
        {
          std::string msgid_plural = get_string(12);
          std::vector<std::string> msgstr_num;
	  bool saw_nonempty_msgstr = false;

        next:
          if (is_empty_line())
          {
            if (msgstr_num.empty())
              error("expected 'msgstr[N] (0 <= N <= 9)'");
          }
          else if (prefix("msgstr[") &&
                   current_line.size() > 8 &&
                   isdigit(current_line[7]) && current_line[8] == ']')
          {
            unsigned int number = static_cast<unsigned int>(current_line[7] - '0');
	    std::string msgstr = get_string(9);

	    if(!msgstr.empty())
	      saw_nonempty_msgstr = true;

            if (number >= msgstr_num.size())
              msgstr_num.resize(number+1);

            msgstr_num[number] = conv.convert(msgstr);
            goto next;
          }
          else
          {
            error("expected 'msgstr[N]'");
          }

          if (!is_empty_line())
            error("expected 'msgstr[N]' or empty line");

	  if (saw_nonempty_msgstr)
	  {
	    if (use_fuzzy || !fuzzy)
            {
	      if (!dict.get_plural_forms())
	      {
		warning("msgstr[N] seen, but no Plural-Forms given");
	      }
	      else
	      {
		if (msgstr_num.size() != dict.get_plural_forms().get_nplural())
		{
		  warning("msgstr[N] count doesn't match Plural-Forms.nplural");
		}
	      }

	      if (has_msgctxt)
		dict.add_translation(msgctxt, msgid, msgid_plural, msgstr_num);
	      else
		dict.add_translation(msgid, msgid_plural, msgstr_num);
	    }

	    if (0)
	    {
	      std::cout << (fuzzy?"fuzzy":"not-fuzzy") << std::endl;
	      std::cout << "msgid \"" << msgid << "\"" << std::endl;
	      std::cout << "msgid_plural \"" << msgid_plural << "\"" << std::endl;
	      for(std::vector<std::string>::size_type i = 0; i < msgstr_num.size(); ++i)
		std::cout << "msgstr[" << i << "] \"" << conv.convert(msgstr_num[i]) << "\"" << std::endl;
	      std::cout << std::endl;
	    }
	  }
        }
        else if (prefix("msgstr"))
        {
          std::string msgstr = get_string(6);

          if (msgid.empty())
          {
            parse_header(msgstr);
          }
          else if(!msgstr.empty())
          {
            if (use_fuzzy || !fuzzy)
            {
              if (has_msgctxt)
                dict.add_translation(msgctxt, msgid, conv.convert(msgstr));
              else
                dict.add_translation(msgid, conv.convert(msgstr));
            }

            if (0)
            {
              std::cout << (fuzzy?"fuzzy":"not-fuzzy") << std::endl;
              std::cout << "msgid \"" << msgid << "\"" << std::endl;
              std::cout << "msgstr \"" << conv.convert(msgstr) << "\"" << std::endl;
              std::cout << std::endl;
            }
          }
        }
        else
        {
          error("expected 'msgstr' or 'msgid_plural'");
        }
      }

      if (!is_empty_line())
        error("expected empty line");

      next_line();
    }
    catch(POParserError&)
    {
    }
  }
}
} // namespace tinygettext

/* EOF */
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: chips/p9/procedures/hwp/initfiles/p9_fbc_cd_hp_scom.C $       */
/*                                                                        */
/* IBM CONFIDENTIAL                                                       */
/*                                                                        */
/* EKB Project                                                            */
/*                                                                        */
/* COPYRIGHT 2016                                                         */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* The source code for this program is not published or otherwise         */
/* divested of its trade secrets, irrespective of what has been           */
/* deposited with the U.S. Copyright Office.                              */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
#include "p9_fbc_cd_hp_scom.H"
#include <stdint.h>
#include <stddef.h>
#include <fapi2.H>
#include <attribute_ids.H>
#include <target_types.H>
#include <fapi2_attribute_service.H>
using namespace fapi2;

fapi2::ReturnCode p9_fbc_cd_hp_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& TGT0,
                                    const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& TGT1)
{
    fapi2::ReturnCode l_rc = 0;

    do
    {

    }
    while(0);

    return l_rc;
}

<commit_msg>initCompiler: update all initfile procedures with latest initCompiler<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: chips/p9/procedures/hwp/initfiles/p9_fbc_cd_hp_scom.C $       */
/*                                                                        */
/* IBM CONFIDENTIAL                                                       */
/*                                                                        */
/* EKB Project                                                            */
/*                                                                        */
/* COPYRIGHT 2016                                                         */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* The source code for this program is not published or otherwise         */
/* divested of its trade secrets, irrespective of what has been           */
/* deposited with the U.S. Copyright Office.                              */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
#include "p9_fbc_cd_hp_scom.H"
#include <stdint.h>
#include <stddef.h>
#include <fapi2.H>

using namespace fapi2;

fapi2::ReturnCode p9_fbc_cd_hp_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& TGT0,
                                    const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& TGT1)
{
    fapi2::ReturnCode l_rc = 0;

    do
    {
        fapi2::buffer<uint64_t> l_scom_buffer;

    }
    while (0);

    return l_rc;
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/pm/p9_pm_recovery_ffdc_cppm.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2017,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
// *INDENT-OFF*

///
/// @file   p9_pm_recovery_ffdc_cppm.C
/// @brief  PPM FFDC collection of PM complex
///
/// *HWP HWP Owner:      Greg Still <stillgs@us.ibm.com>
/// *HWP FW Owner:       Prasad Bg Ranganath <prasadbgr@in.ibm.com>
/// *HWP Team:           PM
/// *HWP Level:          2
/// *HWP Consumed by:    Hostboot
//
// *INDENT-OFF*
//--------------------------------------------------------------------------
// Includes
//--------------------------------------------------------------------------

#include <p9_quad_scom_addresses.H>
#include <p9_pm_recovery_ffdc_cppm.H>
#include <collect_reg_ffdc.H>
#include <stddef.h>
#include <endian.h>

 namespace p9_stop_recov_ffdc
 {
    CppmRegs::CppmRegs( const fapi2::Target< fapi2::TARGET_TYPE_PROC_CHIP > i_procChipTgt )
      : PlatPmComplex ( i_procChipTgt, PLAT_CPPM )
    { }

    //----------------------------------------------------------------------

    void CppmRegs::initRegList()
    {
        std::vector < uint32_t> l_scomRegList;
        l_scomRegList.push_back( C_PPM_SSHSRC );
        l_scomRegList.push_back( C_PPM_VDMCR );
        PlatPmComplex::updateSummaryList( l_scomRegList );
    }

    //----------------------------------------------------------------------

    fapi2::ReturnCode CppmRegs::init ( void* i_pHomerBuf )
    {
        FAPI_DBG (">> CppmRegs::init" );
        FAPI_TRY ( collectFfdc( i_pHomerBuf, INIT),
                   "Failed To Init CPPM REGS FFDC" );

    fapi_try_exit:
        FAPI_DBG ("<< CppmRegs::init" );
        return fapi2::current_err;
    }

    //----------------------------------------------------------------------

    fapi2::ReturnCode CppmRegs::collectFfdc( void*   i_pHomerBuf,
                                             uint8_t i_ffdcType )
    {
        FAPI_DBG(">> CppmRegs::collectFfdc");
        fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;

        uint8_t l_quadPos = 0;
        uint8_t l_corePos   = 0;
        uint8_t* l_pCppmFfdcLoc = NULL;
        uint8_t* l_pQuadFfdcLoc = NULL;
        uint16_t l_cppmFfdcValid = 0;
        uint16_t l_quadFfdcValid = 0;

        HomerFfdcRegion * l_pHomerFfdc =
                ( HomerFfdcRegion *)( (uint8_t *)i_pHomerBuf + FFDC_REGION_HOMER_BASE_OFFSET );

        auto l_quadList = getProcChip().getChildren<fapi2::TARGET_TYPE_EQ> (fapi2::TARGET_STATE_PRESENT);

        for (auto& quad : l_quadList)
        {
            // @TODO via RTC 153978: define bitsets for quad sub-section validity
            l_quadFfdcValid = 0;
            FAPI_TRY( FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS, quad, l_quadPos),
                                  "FAPI_ATTR_GET Failed To Read QUAD Position" );

            l_pQuadFfdcLoc = &l_pHomerFfdc->iv_quadFfdc[l_quadPos].iv_quadFfdcHeader[0];

            // @note: INIT applies to all present units, and is handled as default flow
            // @note: CPPM headers for EQs that are not functionals will not be initialized
            if (quad.isFunctional())
            {
                l_quadFfdcValid = 1;
                auto l_coreList =
                     quad.getChildren< fapi2::TARGET_TYPE_CORE > ( fapi2::TARGET_STATE_PRESENT );

                for (auto& core : l_coreList)
                {
                    FAPI_TRY( FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS, core, l_corePos ),
                              "FAPI_ATTR_GET Failed To Read CORE Position" );
                    l_cppmFfdcValid = 0;

                    l_pCppmFfdcLoc = &l_pHomerFfdc->iv_quadFfdc[l_quadPos].iv_quadCppmRegion[l_corePos%MAX_CORES_PER_QUAD][0];

                    // Note: ( i_ffdcType & INIT ) is the default case, for all present cores
                    if( core.isFunctional() )
                    {
                        FAPI_INF("CPPM FFDC: Quad#%d Core#%d ", l_quadPos, (l_corePos%MAX_CORES_PER_QUAD));

                        if (i_ffdcType & SCOM_REG)
                        {
                            l_rc = collectRegisterData <fapi2::TARGET_TYPE_CORE> (core,
                                                            l_pCppmFfdcLoc + sizeof (PpmFfdcHeader),
                                                            fapi2::CPPM_FFDC_REGISTERS);
                            if (l_rc == fapi2::FAPI2_RC_SUCCESS)
                            {
                                l_cppmFfdcValid = 1;
                            }
                        }
                    }

                    FAPI_TRY( updateCppmFfdcHeader( l_pCppmFfdcLoc, l_corePos, l_cppmFfdcValid),
                              "Failed To Update CPPM FFDC Header for QUAD#%d CORE#%d", l_quadPos, (l_corePos%MAX_CORES_PER_QUAD));
                }
            }
            FAPI_TRY( updateQuadFfdcHeader( l_pQuadFfdcLoc,l_quadPos, l_quadFfdcValid),
                               "Failed To Update Quad FFDC Header for EQ 0x%0d", l_quadPos );

            setPmFfdcSectionValid ( i_pHomerBuf, (PM_FFDC_QUAD0_VALID << l_quadPos), l_quadFfdcValid);

        }

        if( !(i_ffdcType & INIT) )
        {
            generateSummary( i_pHomerBuf );
        }

    fapi_try_exit:
        FAPI_DBG("<< CppmRegs::collectFfdc");
        return fapi2::current_err;
    }

    //-----------------------------------------------------------------------

    fapi2::ReturnCode CppmRegs::updateCppmFfdcHeader( uint8_t * i_pHomerBuf,
                                                      const uint8_t i_corePos,
                                                      const uint16_t i_ffdcValid)
    {
        FAPI_DBG(">> updateCppmFfdcHeader" );

        PpmFfdcHeader * l_CppmFfdcHdr       =   (PpmFfdcHeader *) i_pHomerBuf ;
        l_CppmFfdcHdr->iv_ppmMagicWord      =  htobe32(FFDC_CPPM_MAGIC_NUM);
        l_CppmFfdcHdr->iv_versionMajor      =  1;
        l_CppmFfdcHdr->iv_versionMinor      =  0;
        l_CppmFfdcHdr->iv_Instance          =  i_corePos; // CHIP_UNIT_POS
        l_CppmFfdcHdr->iv_ppmHeaderSize     =  htobe16 (sizeof(PpmFfdcHeader));
        l_CppmFfdcHdr->iv_sectionSize       =  htobe16 (FFDC_CPPM_REGION_SIZE);
        l_CppmFfdcHdr->iv_ffdcValid         =  htobe16 (i_ffdcValid);

        FAPI_DBG("<< updateCppmFfdcHeader" );
        return fapi2::FAPI2_RC_SUCCESS;
    }

    //-----------------------------------------------------------------------

    fapi2::ReturnCode CppmRegs::updateQuadFfdcHeader( uint8_t* i_pHomerBuf,
                                                      const uint8_t i_eqPos,
                                                      const uint16_t i_ffdcValid)
    {
        FAPI_DBG(">> updateQuadFfdcHeader" );

        QuadFfdcHeader* l_QuadFfdcHdr       =  (QuadFfdcHeader*) i_pHomerBuf ;
        l_QuadFfdcHdr->iv_quadMagicWord     =  htobe32(FFDC_QUAD_MAGIC_NUM);
        l_QuadFfdcHdr->iv_versionMajor      =  1;
        l_QuadFfdcHdr->iv_versionMinor      =  0;
        l_QuadFfdcHdr->iv_quadInstance      =  i_eqPos;
        l_QuadFfdcHdr->iv_quadHeaderSize    =  htobe16 (sizeof(QuadFfdcHeader));
        l_QuadFfdcHdr->iv_sectionSize       =  htobe16 (sizeof(HomerQuadFfdcRegion));
        l_QuadFfdcHdr->iv_offsetCppm0       =  htobe16(offsetof (struct HomerQuadFfdcRegion,
                                                                iv_quadCppmRegion[0][0]));
        l_QuadFfdcHdr->iv_offsetCppm1       =  htobe16(offsetof (struct HomerQuadFfdcRegion,
                                                                iv_quadCppmRegion[1][0]));
        l_QuadFfdcHdr->iv_offsetCppm2       =  htobe16(offsetof (struct HomerQuadFfdcRegion,
                                                                iv_quadCppmRegion[2][0]));
        l_QuadFfdcHdr->iv_offsetCppm3       =  htobe16(offsetof (struct HomerQuadFfdcRegion,
                                                                iv_quadCppmRegion[3][0]));
        l_QuadFfdcHdr->iv_offsetCme0        =  htobe16(offsetof(struct HomerQuadFfdcRegion,
                                                                iv_quadCmeBlock[0][0]));
        l_QuadFfdcHdr->iv_offsetCme1        =  htobe16(offsetof(struct HomerQuadFfdcRegion,
                                                                iv_quadCmeBlock[1][0]));
        l_QuadFfdcHdr->iv_offsetQppm        =  htobe16(offsetof(struct HomerQuadFfdcRegion,
                                                                iv_quadQppmRegion[0]));
        l_QuadFfdcHdr->iv_sectionsValid     =  htobe16 (i_ffdcValid);

        FAPI_DBG("<< updateQuadFfdcHeader" );
        return fapi2::FAPI2_RC_SUCCESS;
    }

    //-----------------------------------------------------------------------

    fapi2::ReturnCode CppmRegs::generateSummary( void * i_pHomer )
    {
        HomerFfdcRegion * l_pHomerFfdc =
                ( HomerFfdcRegion *)( (uint8_t *)i_pHomer + FFDC_REGION_HOMER_BASE_OFFSET );
        uint8_t* l_pCppmFfdcLoc    = NULL;
        PpmFfdcHeader * l_pCppmHdr = NULL;
        uint8_t * l_pCppmSummary   = NULL;
        uint8_t l_quadPos          = 0;
        uint8_t l_relCorePos       = 0;

        initRegList();
        uint32_t l_sizeLimit = FFDC_CPPM_REGION_SIZE - sizeof( PpmFfdcHeader );

        for( uint8_t l_ppmPos = 0; l_ppmPos < MAX_CORES_PER_CHIP; l_ppmPos++ )
        {
            l_relCorePos    =   l_ppmPos % MAX_CORES_PER_QUAD;
            l_quadPos       =   l_ppmPos >> 2;
            l_pCppmFfdcLoc  =
                &l_pHomerFfdc->iv_quadFfdc[l_quadPos].iv_quadCppmRegion[l_relCorePos][0];
            l_pCppmSummary  =   &l_pHomerFfdc->iv_ffdcSummaryRegion.iv_cpmmRegSummary[l_ppmPos][FFDC_SUMMARY_SEC_HDR_SIZE];
            l_pCppmHdr      =   ( PpmFfdcHeader *) &l_pHomerFfdc->iv_quadFfdc[l_quadPos].iv_quadCppmRegion[l_relCorePos][0];
            FfdcSummSubSectHdr * l_pCppmSummaryHdr   =
                        (FfdcSummSubSectHdr *)&l_pHomerFfdc->iv_ffdcSummaryRegion.iv_cpmmRegSummary[l_ppmPos][0];
            l_pCppmSummaryHdr->iv_subSectnId    =   PLAT_CPPM;
            l_pCppmSummaryHdr->iv_majorNum      =   1;
            l_pCppmSummaryHdr->iv_minorNum      =   0;
            l_pCppmSummaryHdr->iv_secValid      =   htobe16( l_pCppmHdr->iv_ffdcValid );

            if( !l_pCppmSummaryHdr->iv_secValid )
            {
                continue;
            }

            PlatPmComplex::extractScomSummaryReg( l_pCppmFfdcLoc + sizeof(PpmFfdcHeader),
                                                  l_sizeLimit, l_pCppmSummary );
        }

        return fapi2::FAPI2_RC_SUCCESS;
    }

    //-----------------------------------------------------------------------

extern "C"
{
    fapi2::ReturnCode p9_pm_recovery_ffdc_cppm( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP >& i_procChip, void * i_pFfdcBuf )
    {
        FAPI_IMP(">> p9_pm_recovery_ffdc_cppm" );
        CppmRegs l_cppmFfdc( i_procChip );
        FAPI_TRY( l_cppmFfdc.collectFfdc( i_pFfdcBuf, SCOM_REG ),
                  "Failed To Collect CPPM FFDC" );

        fapi_try_exit:
        FAPI_IMP("<< p9_pm_recovery_ffdc_cppm" );
        return fapi2::current_err;
    }

}

 }//namespace p9_stop_recov_ffdc ends
<commit_msg>Extend PM Reset flow to collect PM FFDC to HOMER<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/pm/p9_pm_recovery_ffdc_cppm.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2017,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
// *INDENT-OFF*

///
/// @file   p9_pm_recovery_ffdc_cppm.C
/// @brief  PPM FFDC collection of PM complex
///
/// *HWP HWP Owner:      Greg Still <stillgs@us.ibm.com>
/// *HWP FW Owner:       Prasad Bg Ranganath <prasadbgr@in.ibm.com>
/// *HWP Team:           PM
/// *HWP Level:          2
/// *HWP Consumed by:    Hostboot
//
// *INDENT-OFF*
//--------------------------------------------------------------------------
// Includes
//--------------------------------------------------------------------------

#include <p9_quad_scom_addresses.H>
#include <p9_pm_recovery_ffdc_cppm.H>
#include <collect_reg_ffdc.H>
#include <stddef.h>
#include <endian.h>

 namespace p9_stop_recov_ffdc
 {
    CppmRegs::CppmRegs( const fapi2::Target< fapi2::TARGET_TYPE_PROC_CHIP > i_procChipTgt )
      : PlatPmComplex ( i_procChipTgt, PLAT_CPPM )
    { }

    //----------------------------------------------------------------------

    void CppmRegs::initRegList()
    {
        std::vector < uint32_t> l_scomRegList;
        l_scomRegList.push_back( C_PPM_SSHSRC );
        l_scomRegList.push_back( C_PPM_VDMCR );
        PlatPmComplex::updateSummaryList( l_scomRegList );
    }

    //----------------------------------------------------------------------

    fapi2::ReturnCode CppmRegs::init ( void* i_pHomerBuf )
    {
        FAPI_DBG (">> CppmRegs::init" );
        FAPI_TRY ( collectFfdc( i_pHomerBuf, INIT),
                   "Failed To Init CPPM REGS FFDC" );

    fapi_try_exit:
        FAPI_DBG ("<< CppmRegs::init" );
        return fapi2::current_err;
    }

    //----------------------------------------------------------------------

    fapi2::ReturnCode CppmRegs::collectFfdc( void*   i_pHomerBuf,
                                             uint8_t i_ffdcType )
    {
        FAPI_DBG(">> CppmRegs::collectFfdc");
        fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;

        uint8_t l_quadPos = 0;
        uint8_t l_corePos   = 0;
        uint8_t* l_pCppmFfdcLoc = NULL;
        uint8_t* l_pQuadFfdcLoc = NULL;
        uint16_t l_cppmFfdcValid = 0;
        uint16_t l_quadFfdcValid = 0;

        HomerFfdcRegion * l_pHomerFfdc =
                ( HomerFfdcRegion *)( (uint8_t *)i_pHomerBuf + FFDC_REGION_HOMER_BASE_OFFSET );

        auto l_quadList = getProcChip().getChildren<fapi2::TARGET_TYPE_EQ> (fapi2::TARGET_STATE_PRESENT);

        for (auto& quad : l_quadList)
        {
            // @TODO via RTC 153978: define bitsets for quad sub-section validity
            l_quadFfdcValid = 0;
            FAPI_TRY( FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS, quad, l_quadPos),
                                  "FAPI_ATTR_GET Failed To Read QUAD Position" );

            l_pQuadFfdcLoc = &l_pHomerFfdc->iv_quadFfdc[l_quadPos].iv_quadFfdcHeader[0];

            // @note: INIT applies to all present units, and is handled as default flow
            // @note: CPPM headers for EQs that are not functionals will not be initialized
            if (quad.isFunctional())
            {
                l_quadFfdcValid = 1;
                auto l_coreList =
                     quad.getChildren< fapi2::TARGET_TYPE_CORE > ( fapi2::TARGET_STATE_PRESENT );

                for (auto& core : l_coreList)
                {
                    FAPI_TRY( FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS, core, l_corePos ),
                              "FAPI_ATTR_GET Failed To Read CORE Position" );
                    l_cppmFfdcValid = 0;

                    l_pCppmFfdcLoc = &l_pHomerFfdc->iv_quadFfdc[l_quadPos].iv_quadCppmRegion[l_corePos%MAX_CORES_PER_QUAD][0];

                    // Note: ( i_ffdcType & INIT ) is the default case, for all present cores
                    if( core.isFunctional() )
                    {
                        FAPI_INF("CPPM FFDC: Quad#%d Core#%d ", l_quadPos, (l_corePos%MAX_CORES_PER_QUAD));

                        if (i_ffdcType & SCOM_REG)
                        {
                            l_rc = collectRegisterData <fapi2::TARGET_TYPE_CORE> (core,
                                                            l_pCppmFfdcLoc + sizeof (PpmFfdcHeader),
                                                            fapi2::CPPM_FFDC_REGISTERS);
                            if (l_rc == fapi2::FAPI2_RC_SUCCESS)
                            {
                                l_cppmFfdcValid = 1;
                            }
                        }
                    }

                    FAPI_TRY( updateCppmFfdcHeader( l_pCppmFfdcLoc, l_corePos, l_cppmFfdcValid),
                              "Failed To Update CPPM FFDC Header for QUAD#%d CORE#%d", l_quadPos, (l_corePos%MAX_CORES_PER_QUAD));
                }
            }
            FAPI_TRY( updateQuadFfdcHeader( l_pQuadFfdcLoc,l_quadPos, l_quadFfdcValid),
                               "Failed To Update Quad FFDC Header for EQ 0x%0d", l_quadPos );

            setPmFfdcSectionValid ( i_pHomerBuf, (PM_FFDC_QUAD0_VALID << l_quadPos), l_quadFfdcValid);

        }

        if( !(i_ffdcType & INIT) )
        {
            generateSummary( i_pHomerBuf );
        }

    fapi_try_exit:
        logPmResetPhase (i_pHomerBuf);
        FAPI_DBG("<< CppmRegs::collectFfdc");
        return fapi2::current_err;
    }

    //-----------------------------------------------------------------------

    fapi2::ReturnCode CppmRegs::updateCppmFfdcHeader( uint8_t * i_pHomerBuf,
                                                      const uint8_t i_corePos,
                                                      const uint16_t i_ffdcValid)
    {
        FAPI_DBG(">> updateCppmFfdcHeader" );

        PpmFfdcHeader * l_CppmFfdcHdr       =   (PpmFfdcHeader *) i_pHomerBuf ;
        l_CppmFfdcHdr->iv_ppmMagicWord      =  htobe32(FFDC_CPPM_MAGIC_NUM);
        l_CppmFfdcHdr->iv_versionMajor      =  1;
        l_CppmFfdcHdr->iv_versionMinor      =  0;
        l_CppmFfdcHdr->iv_Instance          =  i_corePos; // CHIP_UNIT_POS
        l_CppmFfdcHdr->iv_ppmHeaderSize     =  htobe16 (sizeof(PpmFfdcHeader));
        l_CppmFfdcHdr->iv_sectionSize       =  htobe16 (FFDC_CPPM_REGION_SIZE);
        l_CppmFfdcHdr->iv_ffdcValid         =  htobe16 (i_ffdcValid);

        FAPI_DBG("<< updateCppmFfdcHeader" );
        return fapi2::FAPI2_RC_SUCCESS;
    }

    //-----------------------------------------------------------------------

    fapi2::ReturnCode CppmRegs::updateQuadFfdcHeader( uint8_t* i_pHomerBuf,
                                                      const uint8_t i_eqPos,
                                                      const uint16_t i_ffdcValid)
    {
        FAPI_DBG(">> updateQuadFfdcHeader" );

        QuadFfdcHeader* l_QuadFfdcHdr       =  (QuadFfdcHeader*) i_pHomerBuf ;
        l_QuadFfdcHdr->iv_quadMagicWord     =  htobe32(FFDC_QUAD_MAGIC_NUM);
        l_QuadFfdcHdr->iv_versionMajor      =  1;
        l_QuadFfdcHdr->iv_versionMinor      =  0;
        l_QuadFfdcHdr->iv_quadInstance      =  i_eqPos;
        l_QuadFfdcHdr->iv_quadHeaderSize    =  htobe16 (sizeof(QuadFfdcHeader));
        l_QuadFfdcHdr->iv_sectionSize       =  htobe16 (sizeof(HomerQuadFfdcRegion));
        l_QuadFfdcHdr->iv_offsetCppm0       =  htobe16(offsetof (struct HomerQuadFfdcRegion,
                                                                iv_quadCppmRegion[0][0]));
        l_QuadFfdcHdr->iv_offsetCppm1       =  htobe16(offsetof (struct HomerQuadFfdcRegion,
                                                                iv_quadCppmRegion[1][0]));
        l_QuadFfdcHdr->iv_offsetCppm2       =  htobe16(offsetof (struct HomerQuadFfdcRegion,
                                                                iv_quadCppmRegion[2][0]));
        l_QuadFfdcHdr->iv_offsetCppm3       =  htobe16(offsetof (struct HomerQuadFfdcRegion,
                                                                iv_quadCppmRegion[3][0]));
        l_QuadFfdcHdr->iv_offsetCme0        =  htobe16(offsetof(struct HomerQuadFfdcRegion,
                                                                iv_quadCmeBlock[0][0]));
        l_QuadFfdcHdr->iv_offsetCme1        =  htobe16(offsetof(struct HomerQuadFfdcRegion,
                                                                iv_quadCmeBlock[1][0]));
        l_QuadFfdcHdr->iv_offsetQppm        =  htobe16(offsetof(struct HomerQuadFfdcRegion,
                                                                iv_quadQppmRegion[0]));
        l_QuadFfdcHdr->iv_sectionsValid     =  htobe16 (i_ffdcValid);

        FAPI_DBG("<< updateQuadFfdcHeader" );
        return fapi2::FAPI2_RC_SUCCESS;
    }

    //-----------------------------------------------------------------------

    fapi2::ReturnCode CppmRegs::generateSummary( void * i_pHomer )
    {
        HomerFfdcRegion * l_pHomerFfdc =
                ( HomerFfdcRegion *)( (uint8_t *)i_pHomer + FFDC_REGION_HOMER_BASE_OFFSET );
        uint8_t* l_pCppmFfdcLoc    = NULL;
        PpmFfdcHeader * l_pCppmHdr = NULL;
        uint8_t * l_pCppmSummary   = NULL;
        uint8_t l_quadPos          = 0;
        uint8_t l_relCorePos       = 0;

        initRegList();
        uint32_t l_sizeLimit = FFDC_CPPM_REGION_SIZE - sizeof( PpmFfdcHeader );

        for( uint8_t l_ppmPos = 0; l_ppmPos < MAX_CORES_PER_CHIP; l_ppmPos++ )
        {
            l_relCorePos    =   l_ppmPos % MAX_CORES_PER_QUAD;
            l_quadPos       =   l_ppmPos >> 2;
            l_pCppmFfdcLoc  =
                &l_pHomerFfdc->iv_quadFfdc[l_quadPos].iv_quadCppmRegion[l_relCorePos][0];
            l_pCppmSummary  =   &l_pHomerFfdc->iv_ffdcSummaryRegion.iv_cpmmRegSummary[l_ppmPos][FFDC_SUMMARY_SEC_HDR_SIZE];
            l_pCppmHdr      =   ( PpmFfdcHeader *) &l_pHomerFfdc->iv_quadFfdc[l_quadPos].iv_quadCppmRegion[l_relCorePos][0];
            FfdcSummSubSectHdr * l_pCppmSummaryHdr   =
                        (FfdcSummSubSectHdr *)&l_pHomerFfdc->iv_ffdcSummaryRegion.iv_cpmmRegSummary[l_ppmPos][0];
            l_pCppmSummaryHdr->iv_subSectnId    =   PLAT_CPPM;
            l_pCppmSummaryHdr->iv_majorNum      =   1;
            l_pCppmSummaryHdr->iv_minorNum      =   0;
            l_pCppmSummaryHdr->iv_secValid      =   htobe16( l_pCppmHdr->iv_ffdcValid );

            if( !l_pCppmSummaryHdr->iv_secValid )
            {
                continue;
            }

            PlatPmComplex::extractScomSummaryReg( l_pCppmFfdcLoc + sizeof(PpmFfdcHeader),
                                                  l_sizeLimit, l_pCppmSummary );
        }

        return fapi2::FAPI2_RC_SUCCESS;
    }

    //-----------------------------------------------------------------------

extern "C"
{
    fapi2::ReturnCode p9_pm_recovery_ffdc_cppm( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP >& i_procChip, void * i_pFfdcBuf )
    {
        FAPI_IMP(">> p9_pm_recovery_ffdc_cppm" );
        CppmRegs l_cppmFfdc( i_procChip );
        FAPI_TRY( l_cppmFfdc.collectFfdc( i_pFfdcBuf, SCOM_REG ),
                  "Failed To Collect CPPM FFDC" );

        fapi_try_exit:
        FAPI_IMP("<< p9_pm_recovery_ffdc_cppm" );
        return fapi2::current_err;
    }

}

 }//namespace p9_stop_recov_ffdc ends
<|endoftext|>


<commit_before>/// \file ConfigureAndGetEventTriggerMaskAndCaloTriggerString.C
/// \ingroup CaloTrackCorrMacros
/// \brief Configuration of the event trigger
///
/// Configuration macro of the task event trigger, depending on trigger name,
/// specially for EMCal triggers.
/// The trigger event settings depend on special trigger names:
///  * default: Min bias like triggers, kMB or kINT7
///  * EMCAL_L0, DCAL_L0: EMCAL or DCAL L0 triggers kEMC7, kEMC8, kEMC1
///  * EMCAL_L1, DCAL_L1: EMCAL or DCAL L1 triggers, kEMCEGA, with name EG1 or EGA
///  * EMCAL_L2, DCAL_L2: EMCAL or DCAL L2 triggers, kEMCEGA, with name EG2
///
/// \author Gustavo Conesa Balbastre <Gustavo.Conesa.Balbastre@cern.ch>, (LPSC-CNRS)

#if !defined(__CINT__) || defined(__MAKECINT__)

#include <TString.h>

#include "AliVEvent.h"

#endif

///
/// Main method
///
/// The options that can be passed to the macro are:
/// \param trigger       : name of the desired trigger. Special names depending on Calo triggers.
/// \param year          : year
/// \param triggerString : specific trigger name string to select at analysis level
///
UInt_t ConfigureAndGetEventTriggerMaskAndCaloTriggerString
(TString trigger, Int_t year, TString & triggerString)
{
  //printf("ConfigureAndGetEventTriggerCaloTrackCorr - Set event trigger class for %s in year %d\n",
  //       trigger.Data(),year);

  triggerString = "";

  if( trigger.Contains("INT") || trigger.Contains("MB") || trigger.Contains("default") )
  {
    return ( AliVEvent::kINT7 | AliVEvent::kMB );
  }
  else if(trigger.Contains("EMCAL_L0"))
  {
    triggerString = "EMC";
    return ( AliVEvent::kEMC7 | AliVEvent::kEMC8 | AliVEvent::kEMC1 );
  }
  else if(trigger.Contains("DCAL_L0"))
  {
    triggerString = "DMC";
    return ( AliVEvent::kEMC7 | AliVEvent::kEMC8 | AliVEvent::kEMC1 );
  }
  else if(trigger.Contains("EMCAL_L1"))
  {
    if(year > 2012) triggerString = "EG1";
    // before 2013 only one kind of L1 trigger

    return ( AliVEvent::kEMCEGA );
  }
  else if(trigger.Contains("DCAL_L1"))
  {
    triggerString = "DG1";
    return ( AliVEvent::kEMCEGA );
  }
  else if(trigger.Contains("EMCAL_L2"))
  {
    triggerString = "EG2";
    return ( AliVEvent::kEMCEGA );
  }
  else if(trigger.Contains("DCAL_L2"))
  {
    triggerString = "DG2";
    return ( AliVEvent::kEMCEGA );
  }

  return 0;
}

<commit_msg>fix comment<commit_after>/// \file ConfigureAndGetEventTriggerMaskAndCaloTriggerString.C
/// \ingroup CaloTrackCorrMacros
/// \brief Configuration of the event trigger
///
/// Configuration macro of the task event trigger, depending on trigger name,
/// specially for EMCal triggers.
/// The trigger event settings depend on special trigger names:
///  * default: Min bias like triggers, kMB or kINT7
///  * EMCAL_L0, DCAL_L0: EMCal or DCal L0 triggers kEMC7, kEMC8, kEMC1
///  * EMCAL_L1, DCAL_L1: EMCal or DCal L1 triggers, kEMCEGA, with name EG1 or EGA
///  * EMCAL_L2, DCAL_L2: EMCal or DCal L1 triggers, kEMCEGA, with name EG2
///
/// \author Gustavo Conesa Balbastre <Gustavo.Conesa.Balbastre@cern.ch>, (LPSC-CNRS)

#if !defined(__CINT__) || defined(__MAKECINT__)

#include <TString.h>

#include "AliVEvent.h"

#endif

///
/// Main method
///
/// The options that can be passed to the macro are:
/// \param trigger       : name of the desired trigger. Special names depending on Calo triggers.
/// \param year          : year
/// \param triggerString : specific trigger name string to select at analysis level
///
UInt_t ConfigureAndGetEventTriggerMaskAndCaloTriggerString
(TString trigger, Int_t year, TString & triggerString)
{
  //printf("ConfigureAndGetEventTriggerCaloTrackCorr - Set event trigger class for %s in year %d\n",
  //       trigger.Data(),year);

  triggerString = "";

  if( trigger.Contains("INT") || trigger.Contains("MB") || trigger.Contains("default") )
  {
    return ( AliVEvent::kINT7 | AliVEvent::kMB );
  }
  else if(trigger.Contains("EMCAL_L0"))
  {
    triggerString = "EMC";
    return ( AliVEvent::kEMC7 | AliVEvent::kEMC8 | AliVEvent::kEMC1 );
  }
  else if(trigger.Contains("DCAL_L0"))
  {
    triggerString = "DMC";
    return ( AliVEvent::kEMC7 | AliVEvent::kEMC8 | AliVEvent::kEMC1 );
  }
  else if(trigger.Contains("EMCAL_L1"))
  {
    if(year > 2012) triggerString = "EG1";
    // before 2013 only one kind of L1 trigger

    return ( AliVEvent::kEMCEGA );
  }
  else if(trigger.Contains("DCAL_L1"))
  {
    triggerString = "DG1";
    return ( AliVEvent::kEMCEGA );
  }
  else if(trigger.Contains("EMCAL_L2"))
  {
    triggerString = "EG2";
    return ( AliVEvent::kEMCEGA );
  }
  else if(trigger.Contains("DCAL_L2"))
  {
    triggerString = "DG2";
    return ( AliVEvent::kEMCEGA );
  }

  return 0;
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016 Zubax, zubax.com
 * Distributed under the MIT License, available in the file LICENSE.
 * Author: Pavel Kirienko <pavel.kirienko@zubax.com>
 */

/*
 * Simple command shell designed as a more versatile replacement to the ChibiOS embedded shell.
 */

#pragma once

#include <ch.hpp>
#include <chprintf.h>
#include <memstreams.h>
#include <cstring>
#include <cstdint>
#include <cstdarg>
#include <cassert>
#include <zubax_chibios/os.hpp>

namespace os
{
namespace shell
{
/**
 * This class wraps the underlying OS primitive used to access the shell communication channel.
 */
class BaseChannelWrapper
{
    BaseChannel* channel_;

    std::size_t writeExpandingCrLf(unsigned character_timeout_msec, const char* str)
    {
        std::size_t ret = 0;

        for (const char* pc = str; *pc != '\0'; pc++)
        {
            if (*pc == '\n')
            {
                if (MSG_OK != chnPutTimeout(channel_, '\r', MS2ST(character_timeout_msec)))
                {
                    break;
                }
                ret++;
            }
            if (MSG_OK != chnPutTimeout(channel_, *pc, MS2ST(character_timeout_msec)))
            {
                break;
            }
            ret++;
        }

        return ret;
    }

public:
    static constexpr unsigned DefaultWriteCharacterTimeoutMSec = 2;

    BaseChannelWrapper(BaseChannel* chan) :
        channel_(chan)
    { }

    BaseChannel* getChannel()  const { return channel_; }
    void setChannel(BaseChannel* chan) { channel_ = chan; }

    template <unsigned BufferSize = 200, unsigned CharacterTimeoutMSec = DefaultWriteCharacterTimeoutMSec>
    std::size_t vprint(const char* format, va_list vl)
    {
        MemoryStream ms;
        char buffer[BufferSize];
        msObjectInit(&ms, reinterpret_cast<std::uint8_t*>(buffer), BufferSize, 0);

        auto chp = reinterpret_cast<::BaseSequentialStream*>(&ms);
        chvprintf(chp, format, vl);

        chSequentialStreamPut(chp, 0);

        return writeExpandingCrLf(CharacterTimeoutMSec, buffer);
    }

    template <typename... ReferToVPrintForArgs>
    std::size_t print(const char* format, ...)
    {
        va_list vl;
        va_start(vl, format);
        const auto ret = vprint<ReferToVPrintForArgs...>(format, vl);
        va_end(vl);
        return ret;
    }

    int getChar(unsigned timeout_msec)
    {
        return chnGetTimeout(channel_, MS2ST(timeout_msec));
    }

    int putChar(char chr, unsigned timeout_msec = DefaultWriteCharacterTimeoutMSec)
    {
        return chnPutTimeout(channel_, chr, MS2ST(timeout_msec));
    }

    // More methods may be added in the future
};

/**
 * Inherit this interface to implement a command handler.
 */
class ICommandHandler
{
    ICommandHandler(const ICommandHandler&) = delete;
    ICommandHandler& operator=(const ICommandHandler&) = delete;

protected:
    ICommandHandler() { }

public:
    virtual ~ICommandHandler() { }

    virtual const char* getName() const = 0;

    virtual void execute(BaseChannelWrapper& ios, int argc, char** argv) = 0;
};

/**
 * Implementation details, do not use directly.
 */
namespace impl_
{

class Tokenizer         // A la strtok()
{
    char* token_ptr_ = nullptr;

public:
    char* tokenize(char* str)
    {
        if (str)
        {
            token_ptr_ = str;
        }
        char* token = token_ptr_;
        if (!token)
        {
            return NULL;
        }
        static const char* const Delims = " \t";
        token += std::strspn(token, Delims);
        token_ptr_ = std::strpbrk(token, Delims);
        if (token_ptr_)
        {
            *token_ptr_++ = '\0';
        }
        return *token ? token : NULL;
    }
};

class HelpCommandHandler : public ICommandHandler
{
    const ICommandHandler* const* const command_handlers_;
    const unsigned max_handlers_;

    const char* getName() const override { return "help"; }

    void execute(BaseChannelWrapper& ios, int, char**) override
    {
        ios.print("Available commands:\n");
        auto x = command_handlers_;
        for (unsigned i = 0; i < max_handlers_; i++)
        {
            if (*x != nullptr)
            {
                ios.print("\t%s\n", (*x)->getName());
            }
            x++;
        }
    }

public:
    HelpCommandHandler(const ICommandHandler* const* handlers, unsigned max_handlers) :
        command_handlers_(handlers),
        max_handlers_(max_handlers)
    { }
};

}

/**
 * Operating mode of the shell.
 */
enum class Mode
{
    Normal,     //!< Normal mode, regular shell behavior
    Silent      //!< No echo unless the command is recognized; no prompt. Useful for bootloaders etc.
};

/**
 * Shell command processor class.
 */
template <unsigned MaxCommandHandlers = 10,
          unsigned MaxLineLength = 200,
          unsigned MaxCommandArguments = 8>
class Shell
{
    ICommandHandler* command_handlers_[MaxCommandHandlers] = {};

    char line_buffer_[MaxLineLength + 1] = {};
    unsigned pos_ = 0;

    bool need_prompt_ = true;
    Mode mode_;

    impl_::HelpCommandHandler help_command_handler_;

    void echo(BaseChannelWrapper& ios, char chr) const
    {
        if (mode_ != Mode::Silent)
        {
            (void)ios.putChar(chr);
        }
    }

    void processCommand(BaseChannelWrapper& ios, const char* line) const
    {
        // Creating a mutable copy of the line, as the original needs to be retained for silent mode
        char mutable_copy_of_line[MaxLineLength + 1];
        std::strncpy(mutable_copy_of_line, line, sizeof(mutable_copy_of_line));

        // Tokenizing
        char* argv[MaxCommandArguments] = {};
        std::uint8_t argc = 0;
        impl_::Tokenizer tokenizer;
        {
            char* token = tokenizer.tokenize(mutable_copy_of_line);
            while (token != nullptr)
            {
                argv[argc++] = token;
                if (argc >= MaxCommandArguments)
                {
                    break;
                }
                token = tokenizer.tokenize(nullptr);
            }
        }

        if (argc == 0)
        {
            return;     // No command provided, ignore
        }

        // Command lookup, exit on success
        for (auto x : command_handlers_)
        {
            if ((x != nullptr) && (std::strcmp(x->getName(), argv[0]) == 0))
            {
                // In silent mode we only echo if the command is recognized
                if (mode_ == Mode::Silent)
                {
                    (void)ios.print("%s\n", line);
                }
                x->execute(ios, argc, argv);
                return;
            }
        }

        // No such command
        if (mode_ != Mode::Silent)
        {
            (void)ios.print("! ERROR: \"%s\"?\n", argv[0]);
        }
    }

public:
    Shell(Mode mode = Mode::Normal) :
        mode_(mode),
        help_command_handler_(command_handlers_, MaxCommandHandlers)
    {
        addCommandHandler(&help_command_handler_);
    }

    Mode getMode()    const { return mode_; }
    void setMode(Mode mode) { mode_ = mode; }

    bool addCommandHandler(ICommandHandler* chr)
    {
        for (auto& x : command_handlers_)
        {
            if (x == nullptr)
            {
                x = chr;
                return true;
            }
        }
        return false;
    }

    void runFor(BaseChannelWrapper& ios, unsigned run_duration_msec)
    {
        const auto run_duration_st = MS2ST(run_duration_msec);
        const auto started_at_st = chVTGetSystemTime();

        do
        {
            if (need_prompt_)
            {
                need_prompt_ = false;
                if (mode_ != Mode::Silent)
                {
                    (void)ios.print("> ");
                }
            }

            // Reading new character
            const auto elapsed = chVTTimeElapsedSinceX(started_at_st);
            const auto read_timeout_st = (run_duration_st > elapsed) ? (run_duration_st - elapsed) : 1;
            const auto chr = ios.getChar(std::max(1U, unsigned(ST2MS(read_timeout_st))));
            if (chr < 0)
            {
                continue;
            }

            // Processing the character
            if (chr == '\r')                            // End of command
            {
                echo(ios, '\r');
                echo(ios, '\n');
                line_buffer_[pos_] = '\0';
                if (pos_ > 0)
                {
                    processCommand(ios, line_buffer_);
                }
                reset();
            }
            else if (chr == 8 || chr == 127)            // DEL or BS (backspace)
            {
                if (pos_ > 0)
                {
                    echo(ios, 8);       // Erase last char and move caret back
                    echo(ios, ' ');     // Put space on top of the erased character
                    echo(ios, 8);       // Move the caret back again
                    pos_ -= 1;
                }
            }
            else if (chr >= 32)                         // Normal printable ASCII character and everything above ASCII
            {
                if (pos_ < MaxLineLength)
                {
                    echo(ios, chr);
                    line_buffer_[pos_++] = char(chr);
                }
            }
            else                                        // This also includes Ctrl+C, Ctrl+D, and LF
            {
                ;                                       // Invalid byte - ignore
            }

            // Invariants
            assert(pos_ <= MaxLineLength);
        }
        while (chVTTimeElapsedSinceX(started_at_st) <= run_duration_st);
    }

    void reset()
    {
        assert(pos_ <= MaxLineLength);
        pos_ = 0;
        need_prompt_ = true;
    }
};

}
}
<commit_msg>Warning fix in CLI<commit_after>/*
 * Copyright (c) 2016 Zubax, zubax.com
 * Distributed under the MIT License, available in the file LICENSE.
 * Author: Pavel Kirienko <pavel.kirienko@zubax.com>
 */

/*
 * Simple command shell designed as a more versatile replacement to the ChibiOS embedded shell.
 */

#pragma once

#include <ch.hpp>
#include <chprintf.h>
#include <memstreams.h>
#include <cstring>
#include <cstdint>
#include <cstdarg>
#include <cassert>
#include <zubax_chibios/os.hpp>

namespace os
{
namespace shell
{
/**
 * This class wraps the underlying OS primitive used to access the shell communication channel.
 */
class BaseChannelWrapper
{
    BaseChannel* channel_;

    std::size_t writeExpandingCrLf(unsigned character_timeout_msec, const char* str)
    {
        std::size_t ret = 0;

        for (const char* pc = str; *pc != '\0'; pc++)
        {
            if (*pc == '\n')
            {
                if (MSG_OK != chnPutTimeout(channel_, '\r', MS2ST(character_timeout_msec)))
                {
                    break;
                }
                ret++;
            }
            if (MSG_OK != chnPutTimeout(channel_, *pc, MS2ST(character_timeout_msec)))
            {
                break;
            }
            ret++;
        }

        return ret;
    }

public:
    static constexpr unsigned DefaultWriteCharacterTimeoutMSec = 2;

    BaseChannelWrapper(BaseChannel* chan) :
        channel_(chan)
    { }

    BaseChannel* getChannel()  const { return channel_; }
    void setChannel(BaseChannel* chan) { channel_ = chan; }

    template <unsigned BufferSize = 200, unsigned CharacterTimeoutMSec = DefaultWriteCharacterTimeoutMSec>
    std::size_t vprint(const char* format, va_list vl)
    {
        MemoryStream ms;
        char buffer[BufferSize];
        msObjectInit(&ms, reinterpret_cast<std::uint8_t*>(buffer), BufferSize, 0);

        auto chp = reinterpret_cast<::BaseSequentialStream*>(&ms);
        chvprintf(chp, format, vl);

        chSequentialStreamPut(chp, 0);

        return writeExpandingCrLf(CharacterTimeoutMSec, buffer);
    }

    template <typename... ReferToVPrintForArgs>
    std::size_t print(const char* format, ...)
    {
        va_list vl;
        va_start(vl, format);
        const auto ret = vprint<ReferToVPrintForArgs...>(format, vl);
        va_end(vl);
        return ret;
    }

    int getChar(unsigned timeout_msec)
    {
        return chnGetTimeout(channel_, MS2ST(timeout_msec));
    }

    int putChar(char chr, unsigned timeout_msec = DefaultWriteCharacterTimeoutMSec)
    {
        return chnPutTimeout(channel_, chr, MS2ST(timeout_msec));
    }

    // More methods may be added in the future
};

/**
 * Inherit this interface to implement a command handler.
 */
class ICommandHandler
{
    ICommandHandler(const ICommandHandler&) = delete;
    ICommandHandler& operator=(const ICommandHandler&) = delete;

protected:
    ICommandHandler() { }

public:
    virtual ~ICommandHandler() { }

    virtual const char* getName() const = 0;

    virtual void execute(BaseChannelWrapper& ios, int argc, char** argv) = 0;
};

/**
 * Implementation details, do not use directly.
 */
namespace impl_
{

class Tokenizer         // A la strtok()
{
    char* token_ptr_ = nullptr;

public:
    char* tokenize(char* str)
    {
        if (str)
        {
            token_ptr_ = str;
        }
        char* token = token_ptr_;
        if (!token)
        {
            return NULL;
        }
        static const char* const Delims = " \t";
        token += std::strspn(token, Delims);
        token_ptr_ = std::strpbrk(token, Delims);
        if (token_ptr_)
        {
            *token_ptr_++ = '\0';
        }
        return *token ? token : NULL;
    }
};

class HelpCommandHandler : public ICommandHandler
{
    const ICommandHandler* const* const command_handlers_;
    const unsigned max_handlers_;

    const char* getName() const override { return "help"; }

    void execute(BaseChannelWrapper& ios, int, char**) override
    {
        ios.print("Available commands:\n");
        auto x = command_handlers_;
        for (unsigned i = 0; i < max_handlers_; i++)
        {
            if (*x != nullptr)
            {
                ios.print("\t%s\n", (*x)->getName());
            }
            x++;
        }
    }

public:
    HelpCommandHandler(const ICommandHandler* const* handlers, unsigned max_handlers) :
        command_handlers_(handlers),
        max_handlers_(max_handlers)
    { }
};

}

/**
 * Operating mode of the shell.
 */
enum class Mode
{
    Normal,     //!< Normal mode, regular shell behavior
    Silent      //!< No echo unless the command is recognized; no prompt. Useful for bootloaders etc.
};

/**
 * Shell command processor class.
 */
template <unsigned MaxCommandHandlers = 10,
          unsigned MaxLineLength = 200,
          unsigned MaxCommandArguments = 8>
class Shell
{
    ICommandHandler* command_handlers_[MaxCommandHandlers] = {};

    char line_buffer_[MaxLineLength + 1] = {};
    unsigned pos_ = 0;

    bool need_prompt_ = true;
    Mode mode_;

    impl_::HelpCommandHandler help_command_handler_;

    void echo(BaseChannelWrapper& ios, char chr) const
    {
        if (mode_ != Mode::Silent)
        {
            (void)ios.putChar(chr);
        }
    }

    void processCommand(BaseChannelWrapper& ios, const char* line) const
    {
        // Creating a mutable copy of the line, as the original needs to be retained for silent mode
        char mutable_copy_of_line[MaxLineLength + 1];
        std::strncpy(mutable_copy_of_line, line, sizeof(mutable_copy_of_line));

        // Tokenizing
        char* argv[MaxCommandArguments] = {};
        std::uint8_t argc = 0;
        impl_::Tokenizer tokenizer;
        {
            char* token = tokenizer.tokenize(mutable_copy_of_line);
            while (token != nullptr)
            {
                argv[argc++] = token;
                if (argc >= MaxCommandArguments)
                {
                    break;
                }
                token = tokenizer.tokenize(nullptr);
            }
        }

        if (argc == 0)
        {
            return;     // No command provided, ignore
        }

        // Command lookup, exit on success
        for (auto x : command_handlers_)
        {
            if ((x != nullptr) && (std::strcmp(x->getName(), argv[0]) == 0))
            {
                // In silent mode we only echo if the command is recognized
                if (mode_ == Mode::Silent)
                {
                    (void)ios.print("%s\n", line);
                }
                x->execute(ios, argc, argv);
                return;
            }
        }

        // No such command
        if (mode_ != Mode::Silent)
        {
            (void)ios.print("! ERROR: \"%s\"?\n", argv[0]);
        }
    }

public:
    Shell(Mode mode = Mode::Normal) :
        mode_(mode),
        help_command_handler_(command_handlers_, MaxCommandHandlers)
    {
        addCommandHandler(&help_command_handler_);
    }

    Mode getMode()    const { return mode_; }
    void setMode(Mode mode) { mode_ = mode; }

    bool addCommandHandler(ICommandHandler* chr)
    {
        for (auto& x : command_handlers_)
        {
            if (x == nullptr)
            {
                x = chr;
                return true;
            }
        }
        return false;
    }

    void runFor(BaseChannelWrapper& ios, unsigned run_duration_msec)
    {
        const auto run_duration_st = MS2ST(run_duration_msec);
        const auto started_at_st = chVTGetSystemTime();

        do
        {
            if (need_prompt_)
            {
                need_prompt_ = false;
                if (mode_ != Mode::Silent)
                {
                    (void)ios.print("> ");
                }
            }

            // Reading new character
            const auto elapsed = chVTTimeElapsedSinceX(started_at_st);
            const auto read_timeout_st = (run_duration_st > elapsed) ? (run_duration_st - elapsed) : 1;
            const auto chr = ios.getChar(std::max(1U, unsigned(ST2MS(read_timeout_st))));
            if (chr < 0)
            {
                continue;
            }

            // Processing the character
            if (chr == '\r')                            // End of command
            {
                echo(ios, '\r');
                echo(ios, '\n');
                line_buffer_[pos_] = '\0';
                if (pos_ > 0)
                {
                    processCommand(ios, line_buffer_);
                }
                reset();
            }
            else if (chr == 8 || chr == 127)            // DEL or BS (backspace)
            {
                if (pos_ > 0)
                {
                    echo(ios, 8);       // Erase last char and move caret back
                    echo(ios, ' ');     // Put space on top of the erased character
                    echo(ios, 8);       // Move the caret back again
                    pos_ -= 1;
                }
            }
            else if (chr >= 32)                         // Normal printable ASCII character and everything above ASCII
            {
                if (pos_ < MaxLineLength)
                {
                    echo(ios, char(chr));
                    line_buffer_[pos_++] = char(chr);
                }
            }
            else                                        // This also includes Ctrl+C, Ctrl+D, and LF
            {
                ;                                       // Invalid byte - ignore
            }

            // Invariants
            assert(pos_ <= MaxLineLength);
        }
        while (chVTTimeElapsedSinceX(started_at_st) <= run_duration_st);
    }

    void reset()
    {
        assert(pos_ <= MaxLineLength);
        pos_ = 0;
        need_prompt_ = true;
    }
};

}
}
<|endoftext|>


<commit_before>#include "HelloPolycodeApp.h"

HelloPolycodeApp::HelloPolycodeApp(PolycodeView *view) {

	core = new POLYCODE_CORE(view, 640,480,false,false,0,0,90);

	CoreServices::getInstance()->getResourceManager()->addArchive("Resources/default.pak");
	CoreServices::getInstance()->getResourceManager()->addDirResource("default", false);

	scene = new CollisionScene();

	ScenePrimitive *ground = new ScenePrimitive(ScenePrimitive::TYPE_PLANE, 10, 10);
	ground->loadTexture("Resources/green_texture.png");
	scene->addEntity(ground);

	box = new ScenePrimitive(ScenePrimitive::TYPE_BOX, 0.5,0.5,0.5);
	box->loadTexture("Resources/pink_texture.png");
	box->setPosition(0,1,0);
	scene->addCollisionChild(box, CollisionSceneEntity::SHAPE_BOX);

	bigBox = new ScenePrimitive(ScenePrimitive::TYPE_BOX, 2,2,2);
	bigBox->loadTexture("Resources/pink_texture.png");
	bigBox->setColor(0.0,1.0,1.0,0.5);
	bigBox->setPosition(0,1,0);
	scene->addCollisionChild(bigBox, CollisionSceneEntity::SHAPE_BOX);

	scene->getDefaultCamera()->setPosition(7,7,7);
	scene->getDefaultCamera()->lookAt(Vector3(0,0,0));

	swingValue = 0;
}

HelloPolycodeApp::~HelloPolycodeApp() {
}

bool HelloPolycodeApp::Update() {
	Number elapsed = core->getElapsed();
	swingValue += elapsed;
	box->setPosition(sin(swingValue) * 5,1,0);

	CollisionResult res = scene->testCollision(box, bigBox);
	if(res.collided) {
		bigBox->setColor(1.0,1.0,0.0,0.5);
	} else {
		bigBox->setColor(0.0,1.0,1.0,0.5);
	}

    return core->updateAndRender();
}
<commit_msg>Rebased 3DPhysics_CollisionOnly on Screenrewrite<commit_after>#include "HelloPolycodeApp.h"

HelloPolycodeApp::HelloPolycodeApp(PolycodeView *view) {

	core = new POLYCODE_CORE(view, 640,480,false,false,0,0,90);

	CoreServices::getInstance()->getResourceManager()->addArchive("Resources/default.pak");
	CoreServices::getInstance()->getResourceManager()->addDirResource("default", false);

	scene = new CollisionScene();

	ScenePrimitive *ground = new ScenePrimitive(ScenePrimitive::TYPE_PLANE, 10, 10);
	ground->loadTexture("Resources/green_texture.png");
	scene->addEntity(ground);

	box = new ScenePrimitive(ScenePrimitive::TYPE_BOX, 0.5,0.5,0.5);
	box->loadTexture("Resources/pink_texture.png");
	box->setPosition(0,1,0);
	scene->addCollisionChild(box, CollisionEntity::SHAPE_BOX);

	bigBox = new ScenePrimitive(ScenePrimitive::TYPE_BOX, 2,2,2);
	bigBox->loadTexture("Resources/pink_texture.png");
	bigBox->setColor(0.0,1.0,1.0,0.5);
	bigBox->setPosition(0,1,0);
	scene->addCollisionChild(bigBox, CollisionEntity::SHAPE_BOX);

	scene->getDefaultCamera()->setPosition(7,7,7);
	scene->getDefaultCamera()->lookAt(Vector3(0,0,0));

	swingValue = 0;
}

HelloPolycodeApp::~HelloPolycodeApp() {
}

bool HelloPolycodeApp::Update() {
	Number elapsed = core->getElapsed();
	swingValue += elapsed;
	box->setPosition(sin(swingValue) * 5,1,0);

	CollisionResult res = scene->testCollision(box, bigBox);
	if(res.collided) {
		bigBox->setColor(1.0,1.0,0.0,0.5);
	} else {
		bigBox->setColor(0.0,1.0,1.0,0.5);
	}

    return core->updateAndRender();
}
<|endoftext|>