<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <BasCodeTagger.hxx>

LibXmlTreeWalker::LibXmlTreeWalker( xmlDocPtr doc )
{
    if ( doc == NULL )
        throw BasicCodeTagger::NULL_DOCUMENT;
    m_pCurrentNode = xmlDocGetRootElement( doc );
    if ( m_pCurrentNode == NULL )
        throw BasicCodeTagger::EMPTY_DOCUMENT;
    else if ( m_pCurrentNode->xmlChildrenNode != NULL )
        m_Queue.push_back( m_pCurrentNode->xmlChildrenNode );
    nextNode();
}

void LibXmlTreeWalker::nextNode()
{

      //next node
    if ( m_pCurrentNode->next == NULL )
    {
        m_pCurrentNode = m_Queue.front();
        m_Queue.pop_front();
    }
    else
        m_pCurrentNode = m_pCurrentNode->next;
    //queue chiledren if they exist
    if ( m_pCurrentNode->xmlChildrenNode != NULL )
        m_Queue.push_back( m_pCurrentNode->xmlChildrenNode );
}

void LibXmlTreeWalker::ignoreCurrNodesChildren()
{
    if ( m_pCurrentNode->xmlChildrenNode != NULL )
          m_Queue.pop_back();
}

bool LibXmlTreeWalker::end()
{
    return m_pCurrentNode->next == NULL && m_Queue.empty();
}

xmlNodePtr LibXmlTreeWalker::currentNode()
{
    return m_pCurrentNode;
}

//======================================================

BasicCodeTagger::BasicCodeTagger( xmlDocPtr rootDoc ):
    m_Highlighter(HIGHLIGHT_BASIC)
{
      if ( rootDoc == NULL )
          throw NULL_DOCUMENT;
      m_pDocument = rootDoc;
    m_pXmlTreeWalker = NULL;
    m_bTaggingCompleted = false;

}

BasicCodeTagger::~BasicCodeTagger()
{
    if ( m_pXmlTreeWalker != NULL )
      delete m_pXmlTreeWalker;
}
//!Gathers all the <bascode> tag nodes from xml tree.
/*!
 *    Assumes m_pDocument is valid. Handles m_pXmlTreeWalker and m_BasicCodeContainerTags members.
 */
void BasicCodeTagger::getBasicCodeContainerNodes()
{
      xmlNodePtr currentNode;

    m_BasicCodeContainerTags.clear();

    if ( m_pXmlTreeWalker != NULL )
      delete m_pXmlTreeWalker;
    m_pXmlTreeWalker = new LibXmlTreeWalker( m_pDocument );

    currentNode = m_pXmlTreeWalker->currentNode();
    if ( !( xmlStrcmp( currentNode->name, (const xmlChar*) "bascode" ) ) )
    { //Found <bascode>
        m_BasicCodeContainerTags.push_back( currentNode ); //it goes to the end of the list
    }
    while ( !m_pXmlTreeWalker->end() )
    {
          m_pXmlTreeWalker->nextNode();
        if ( !( xmlStrcmp( m_pXmlTreeWalker->currentNode()->name, (const xmlChar*) "bascode" ) ) )
        { //Found <bascode>
            m_BasicCodeContainerTags.push_back( m_pXmlTreeWalker->currentNode() ); //it goes to the end of the list
            m_pXmlTreeWalker->ignoreCurrNodesChildren();
        }
    }
}

//! Extracts Basic Codes containted in <bascode> tags.
/*!
 *  For each <bascode> this method iterates trough it's <paragraph> tags and "inserts" <item> tags according
 *  to the Basic code syntax found in that paragraph.
 */
void BasicCodeTagger::tagBasCodeParagraphs()
{
    //helper variables
    xmlNodePtr currBascodeNode;
    xmlNodePtr currParagraph;
    while ( !m_BasicCodeContainerTags.empty() )
    {
        currBascodeNode = m_BasicCodeContainerTags.front();
        currParagraph = currBascodeNode->xmlChildrenNode; //first <paragraph>
        while ( currParagraph != NULL )
        {
            tagParagraph( currParagraph );
            currParagraph=currParagraph->next;
        }
        m_BasicCodeContainerTags.pop_front(); //next element
    }
}

//! Used by tagBasCodeParagraphs(). It does the work on the current paragraph containing Basic code.
void BasicCodeTagger::tagParagraph( xmlNodePtr paragraph )
{
    //1. get paragraph text
    xmlChar* codeSnippet;
    codeSnippet = xmlNodeListGetString( m_pDocument, paragraph->xmlChildrenNode, 1 );
    if ( codeSnippet == NULL )
    {
        return; //no text, nothing more to do here
    }
    //2. delete every child from paragraph (except attributes)
    xmlNodePtr curNode = paragraph->xmlChildrenNode;
    xmlNodePtr sibling;
    while ( curNode != NULL )
    {
        sibling = curNode->next;
        xmlUnlinkNode( curNode );
        xmlFreeNode( curNode );
        curNode = sibling;
    }

    //3. create new paragraph content
    OUString strLine( reinterpret_cast<const sal_Char*>(codeSnippet),
                                strlen(reinterpret_cast<const char*>(codeSnippet)),
                                RTL_TEXTENCODING_UTF8 );
    std::vector<HighlightPortion> portions;
    m_Highlighter.getHighlightPortions( strLine, portions );
    for (std::vector<HighlightPortion>::iterator i(portions.begin());
         i != portions.end(); ++i)
    {
        OString sToken(OUStringToOString(strLine.copy(i->nBegin, i->nEnd-i->nBegin), RTL_TEXTENCODING_UTF8));
        xmlNodePtr text = xmlNewText((const xmlChar*)sToken.getStr());
        if ( i->tokenType != TT_WHITESPACE )
        {
            xmlChar* typeStr = getTypeString( i->tokenType );
            curNode = xmlNewTextChild( paragraph, 0, (xmlChar*)"item", 0 );
            xmlNewProp( curNode, (xmlChar*)"type", typeStr );
            xmlAddChild( curNode, text );
            xmlFree( typeStr );
        }
        else
            xmlAddChild( paragraph, text );
    }
    xmlFree( codeSnippet );
}

//! Manages tagging process.
/*!
 *    This is the "main" function of BasicCodeTagger.
 */
void BasicCodeTagger::tagBasicCodes()
{
      if ( m_bTaggingCompleted )
        return;
    //gather <bascode> nodes
    try
    {
        getBasicCodeContainerNodes();
    }
    catch (TaggerException &ex)
    {
          std::cout << "BasCodeTagger error occured. Error code:" << ex << std::endl;
    }

    //tag basic code paragraphs in <bascode> tag
    tagBasCodeParagraphs();
    m_bTaggingCompleted = true;
}

//! Converts SyntaxHighlighter's TokenTypes enum to a type string for <item type=... >
xmlChar* BasicCodeTagger::getTypeString( TokenTypes tokenType )
{
    const char* str;
    switch ( tokenType )
    {
        case TT_UNKNOWN :
            str = "unknown";
            break;
        case TT_IDENTIFIER :
            str = "identifier";
            break;
        case TT_WHITESPACE :
            str = "whitespace";
            break;
        case TT_NUMBER :
            str = "number";
            break;
        case TT_STRING :
            str = "string";
            break;
        case TT_EOL :
            str = "eol";
            break;
        case TT_COMMENT :
            str = "comment";
            break;
        case TT_ERROR :
            str = "error";
            break;
        case TT_OPERATOR :
            str = "operator";
            break;
        case TT_KEYWORDS :
            str = "keyword";
            break;
        case TT_PARAMETER :
            str = "parameter";
            break;
        default :
            str = "unknown";
            break;
    }
    return xmlCharStrdup( str );
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Remove visual noise from helpcompiler<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <BasCodeTagger.hxx>

LibXmlTreeWalker::LibXmlTreeWalker( xmlDocPtr doc )
{
    if ( doc == NULL )
        throw BasicCodeTagger::NULL_DOCUMENT;
    m_pCurrentNode = xmlDocGetRootElement( doc );
    if ( m_pCurrentNode == NULL )
        throw BasicCodeTagger::EMPTY_DOCUMENT;
    else if ( m_pCurrentNode->xmlChildrenNode != NULL )
        m_Queue.push_back( m_pCurrentNode->xmlChildrenNode );
    nextNode();
}

void LibXmlTreeWalker::nextNode()
{

      //next node
    if ( m_pCurrentNode->next == NULL )
    {
        m_pCurrentNode = m_Queue.front();
        m_Queue.pop_front();
    }
    else
        m_pCurrentNode = m_pCurrentNode->next;
    //queue chiledren if they exist
    if ( m_pCurrentNode->xmlChildrenNode != NULL )
        m_Queue.push_back( m_pCurrentNode->xmlChildrenNode );
}

void LibXmlTreeWalker::ignoreCurrNodesChildren()
{
    if ( m_pCurrentNode->xmlChildrenNode != NULL )
          m_Queue.pop_back();
}

bool LibXmlTreeWalker::end()
{
    return m_pCurrentNode->next == NULL && m_Queue.empty();
}

xmlNodePtr LibXmlTreeWalker::currentNode()
{
    return m_pCurrentNode;
}

BasicCodeTagger::BasicCodeTagger( xmlDocPtr rootDoc ):
    m_Highlighter(HIGHLIGHT_BASIC)
{
      if ( rootDoc == NULL )
          throw NULL_DOCUMENT;
      m_pDocument = rootDoc;
    m_pXmlTreeWalker = NULL;
    m_bTaggingCompleted = false;

}

BasicCodeTagger::~BasicCodeTagger()
{
    if ( m_pXmlTreeWalker != NULL )
      delete m_pXmlTreeWalker;
}
//!Gathers all the <bascode> tag nodes from xml tree.
/*!
 *    Assumes m_pDocument is valid. Handles m_pXmlTreeWalker and m_BasicCodeContainerTags members.
 */
void BasicCodeTagger::getBasicCodeContainerNodes()
{
      xmlNodePtr currentNode;

    m_BasicCodeContainerTags.clear();

    if ( m_pXmlTreeWalker != NULL )
      delete m_pXmlTreeWalker;
    m_pXmlTreeWalker = new LibXmlTreeWalker( m_pDocument );

    currentNode = m_pXmlTreeWalker->currentNode();
    if ( !( xmlStrcmp( currentNode->name, (const xmlChar*) "bascode" ) ) )
    { //Found <bascode>
        m_BasicCodeContainerTags.push_back( currentNode ); //it goes to the end of the list
    }
    while ( !m_pXmlTreeWalker->end() )
    {
          m_pXmlTreeWalker->nextNode();
        if ( !( xmlStrcmp( m_pXmlTreeWalker->currentNode()->name, (const xmlChar*) "bascode" ) ) )
        { //Found <bascode>
            m_BasicCodeContainerTags.push_back( m_pXmlTreeWalker->currentNode() ); //it goes to the end of the list
            m_pXmlTreeWalker->ignoreCurrNodesChildren();
        }
    }
}

//! Extracts Basic Codes containted in <bascode> tags.
/*!
 *  For each <bascode> this method iterates trough it's <paragraph> tags and "inserts" <item> tags according
 *  to the Basic code syntax found in that paragraph.
 */
void BasicCodeTagger::tagBasCodeParagraphs()
{
    //helper variables
    xmlNodePtr currBascodeNode;
    xmlNodePtr currParagraph;
    while ( !m_BasicCodeContainerTags.empty() )
    {
        currBascodeNode = m_BasicCodeContainerTags.front();
        currParagraph = currBascodeNode->xmlChildrenNode; //first <paragraph>
        while ( currParagraph != NULL )
        {
            tagParagraph( currParagraph );
            currParagraph=currParagraph->next;
        }
        m_BasicCodeContainerTags.pop_front(); //next element
    }
}

//! Used by tagBasCodeParagraphs(). It does the work on the current paragraph containing Basic code.
void BasicCodeTagger::tagParagraph( xmlNodePtr paragraph )
{
    //1. get paragraph text
    xmlChar* codeSnippet;
    codeSnippet = xmlNodeListGetString( m_pDocument, paragraph->xmlChildrenNode, 1 );
    if ( codeSnippet == NULL )
    {
        return; //no text, nothing more to do here
    }
    //2. delete every child from paragraph (except attributes)
    xmlNodePtr curNode = paragraph->xmlChildrenNode;
    xmlNodePtr sibling;
    while ( curNode != NULL )
    {
        sibling = curNode->next;
        xmlUnlinkNode( curNode );
        xmlFreeNode( curNode );
        curNode = sibling;
    }

    //3. create new paragraph content
    OUString strLine( reinterpret_cast<const sal_Char*>(codeSnippet),
                                strlen(reinterpret_cast<const char*>(codeSnippet)),
                                RTL_TEXTENCODING_UTF8 );
    std::vector<HighlightPortion> portions;
    m_Highlighter.getHighlightPortions( strLine, portions );
    for (std::vector<HighlightPortion>::iterator i(portions.begin());
         i != portions.end(); ++i)
    {
        OString sToken(OUStringToOString(strLine.copy(i->nBegin, i->nEnd-i->nBegin), RTL_TEXTENCODING_UTF8));
        xmlNodePtr text = xmlNewText((const xmlChar*)sToken.getStr());
        if ( i->tokenType != TT_WHITESPACE )
        {
            xmlChar* typeStr = getTypeString( i->tokenType );
            curNode = xmlNewTextChild( paragraph, 0, (xmlChar*)"item", 0 );
            xmlNewProp( curNode, (xmlChar*)"type", typeStr );
            xmlAddChild( curNode, text );
            xmlFree( typeStr );
        }
        else
            xmlAddChild( paragraph, text );
    }
    xmlFree( codeSnippet );
}

//! Manages tagging process.
/*!
 *    This is the "main" function of BasicCodeTagger.
 */
void BasicCodeTagger::tagBasicCodes()
{
      if ( m_bTaggingCompleted )
        return;
    //gather <bascode> nodes
    try
    {
        getBasicCodeContainerNodes();
    }
    catch (TaggerException &ex)
    {
          std::cout << "BasCodeTagger error occured. Error code:" << ex << std::endl;
    }

    //tag basic code paragraphs in <bascode> tag
    tagBasCodeParagraphs();
    m_bTaggingCompleted = true;
}

//! Converts SyntaxHighlighter's TokenTypes enum to a type string for <item type=... >
xmlChar* BasicCodeTagger::getTypeString( TokenTypes tokenType )
{
    const char* str;
    switch ( tokenType )
    {
        case TT_UNKNOWN :
            str = "unknown";
            break;
        case TT_IDENTIFIER :
            str = "identifier";
            break;
        case TT_WHITESPACE :
            str = "whitespace";
            break;
        case TT_NUMBER :
            str = "number";
            break;
        case TT_STRING :
            str = "string";
            break;
        case TT_EOL :
            str = "eol";
            break;
        case TT_COMMENT :
            str = "comment";
            break;
        case TT_ERROR :
            str = "error";
            break;
        case TT_OPERATOR :
            str = "operator";
            break;
        case TT_KEYWORDS :
            str = "keyword";
            break;
        case TT_PARAMETER :
            str = "parameter";
            break;
        default :
            str = "unknown";
            break;
    }
    return xmlCharStrdup( str );
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>89047ea1-ad5b-11e7-887b-ac87a332f658<commit_msg>Nope, didn't work, now it does<commit_after>8961cd9e-ad5b-11e7-8492-ac87a332f658<|endoftext|>


<commit_before>// Copyright (c) 2017 David Mak. All rights reserved.
// Licensed under MIT.
//
// This file parses the program argument, and inflates the Gui class.
//

#include <fstream>
#include <iostream>
#include <memory>
#include <string>
#include <vector>

#include "gui.h"
#include "packages.h"
#include "packages_legacy.h"

using std::cout;
using std::endl;
using std::ifstream;
using std::make_unique;
using std::move;
using std::string;
using std::unique_ptr;
using std::vector;

namespace {
const string kBuildString = "0.6.0";

auto ReadArgs(const vector<string>&, string& filename) -> Gui::PackageVer;
void OutputVersionInfo();
void OutputHelp(const string& s);

void OutputHelp(const string& s) {
  string message{""};
  message += "Usage: " + s + " [OPTION]...\n";
  message += "  -f, --file=[FILE]\tread Packages.txt from [FILE]\n";
  message += "      --legacy\t\tread file with legacy format\n";
  message += "      --help\t\tdisplay this help and exit\n";
  message += "      --version\t\toutput version information and exit\n\n";

  cout << message << endl;
}

void OutputVersionInfo() {
  string message{""};
  message += "Warframe Package Deparser " + kBuildString + "\n";
  message += "Copyright (C) 2017 David Mak\n";
  message += "Licensed under MIT.";

  cout << message << endl;
}

auto ReadArgs(const vector<string>& args, string& filename) -> Gui::PackageVer {
  string file = "../Packages.txt";
  Gui::PackageVer package_ver = Gui::PackageVer::kCurrent;

  for (auto it = args.begin() + 1; it != args.end(); ++it) {
    if (*it == "--help") {
      OutputHelp(args.at(0));
      exit(0);
    } else if (*it == "--version") {
      OutputVersionInfo();
      exit(0);
    } else if (*it == "-f") {
      file = *++it;
    } else if (it->substr(0, 7) == "--file=") {
      file = it->substr(7);
    } else if (*it == "--legacy") {
      package_ver = Gui::PackageVer::kLegacy;
    } else if (it->substr(0, 2) == "--") {
      cout << "Warning: Unrecognized option " << *it << endl;
    }
  }

  if (file.at(0) != '.' && file.at(1) != '.') {
    file.insert(0, "./");
  }

  unique_ptr<ifstream> file_stream = make_unique<ifstream>(file);
  if (!file_stream->good()) {
    cout << file << ": File not found. Exiting." << endl;
    exit(0);
  }

  filename = file;
  return package_ver;
}
}  // namespace

auto main(int argc, char* argv[]) -> int {
  // read input arguments
  vector<string> argvec(argv, argv + argc);

  string filename{};
  Gui::PackageVer ver = ReadArgs(argvec, filename);
  unique_ptr<ifstream> file_stream = make_unique<ifstream>(filename);
  unique_ptr<Packages> package = nullptr;
  unique_ptr<PackagesLegacy> package_legacy = nullptr;

  if (!file_stream->good()) {
    cout << filename << ": File not found. Exiting." << endl;
    exit(0);
  }

  switch (ver) {
    case Gui::PackageVer::kCurrent:
      package = make_unique<Packages>(filename, move(file_stream));
      break;
    case Gui::PackageVer::kLegacy:
      package_legacy = make_unique<PackagesLegacy>(filename, move(file_stream));
      break;
    default:
      // all cases covered
      break;
  }

  unique_ptr<Gui> g = nullptr;
  if (package != nullptr) {
    g = make_unique<Gui>(package.get());
  } else if (package_legacy != nullptr) {
    g = make_unique<Gui>(package_legacy.get());
  } else {
    cout << "Error when initializing packages!" << endl;
    exit(0);
  }

  g->MainMenu();

  return 0;
}<commit_msg>Add non-interactive mode to argument parser<commit_after>// Copyright (c) 2017 David Mak. All rights reserved.
// Licensed under MIT.
//
// This file parses the program argument, and inflates the Gui class.
//

#include <fstream>
#include <iostream>
#include <memory>
#include <string>
#include <vector>

#include "gui.h"
#include "packages.h"
#include "packages_legacy.h"

using std::cout;
using std::endl;
using std::ifstream;
using std::make_unique;
using std::move;
using std::string;
using std::unique_ptr;
using std::vector;

namespace {
const string kBuildString = "0.7.0-alpha";

struct {
  Gui::PackageVer package_ver = Gui::PackageVer::kCurrent;
  bool is_interactive = true;
  vector<string> ni_args;
} program_args;

void ReadArgs(const vector<string>&, string& filename);
void OutputVersionInfo();
void OutputHelp(const string& s);

void OutputHelp(const string& s) {
  string message{""};
  message += "Usage: " + s + " [OPTION]... [MODE] [MODE_ARGS]...\n";
  message += "  -f, --file=[FILE]\tread Packages.txt from [FILE]\n";
  message += "      --no-interactive\tdisable interactive mode\n";
  message += "      --legacy\t\tread file with legacy format\n";
  message += "      --help\t\tdisplay this help and exit\n";
  message += "      --version\t\toutput version information and exit\n\n";

  cout << message << endl;
}

void OutputVersionInfo() {
  string message{""};
  message += "Warframe Package Deparser " + kBuildString + "\n";
  message += "Copyright (C) 2017 David Mak\n";
  message += "Licensed under MIT.";

  cout << message << endl;
}

void ReadArgs(const vector<string>& args, string& filename) {
  string file = "../Packages.txt";

  for (auto it = args.begin() + 1; it != args.end(); ++it) {
    if (*it == "--help") {
      OutputHelp(args.at(0));
      exit(0);
    } else if (*it == "--version") {
      OutputVersionInfo();
      exit(0);
    } else if (*it == "-f") {
      file = *++it;
    } else if (it->substr(0, 7) == "--file=") {
      file = it->substr(7);
    } else if (*it == "--legacy") {
      program_args.package_ver = Gui::PackageVer::kLegacy;
    } else if (*it == "--no-interactive") {
      program_args.is_interactive = false;
    } else if (!program_args.is_interactive) {
      program_args.ni_args.push_back(*it);
    } else if (it->substr(0, 2) == "--") {
      cout << "Warning: Unrecognized option " << *it << endl;
    }
  }

  if (file.at(0) != '.' && file.at(1) != '.') {
    file.insert(0, "./");
  }

  unique_ptr<ifstream> file_stream = make_unique<ifstream>(file);
  if (!file_stream->good()) {
    cout << file << ": File not found. Exiting." << endl;
    exit(0);
  }

  filename = file;
}
}  // namespace

auto main(int argc, char* argv[]) -> int {
  // read input arguments
  vector<string> argvec(argv, argv + argc);

  string filename{};
  ReadArgs(argvec, filename);
  unique_ptr<ifstream> file_stream = make_unique<ifstream>(filename);
  unique_ptr<Packages> package = nullptr;
  unique_ptr<PackagesLegacy> package_legacy = nullptr;

  if (!file_stream->good()) {
    cout << filename << ": File not found. Exiting." << endl;
    exit(0);
  }

  switch (program_args.package_ver) {
    case Gui::PackageVer::kCurrent:
      package = make_unique<Packages>(filename, move(file_stream));
      break;
    case Gui::PackageVer::kLegacy:
      package_legacy = make_unique<PackagesLegacy>(filename, move(file_stream));
      break;
    default:
      // all cases covered
      break;
  }

  if (!program_args.is_interactive) {
    cout << "Non-interactive mode is currently not supported." << endl;
    // TODO(Derppening): Parse arguments and run functions

    return 0;
  }

  unique_ptr<Gui> g = nullptr;
  if (package != nullptr) {
    g = make_unique<Gui>(package.get());
  } else if (package_legacy != nullptr) {
    g = make_unique<Gui>(package_legacy.get());
  } else {
    cout << "Error when initializing packages!" << endl;
    exit(0);
  }

  g->MainMenu();

  return 0;
}<|endoftext|>


<commit_before>61e17863-2749-11e6-810c-e0f84713e7b8<commit_msg>add file<commit_after>61eb9538-2749-11e6-96f3-e0f84713e7b8<|endoftext|>


<commit_before>#include "Logger.hpp"
#include "CAmxDebugManager.hpp"
#include "LogManager.hpp"
#include "amx/amx2.h"

#include <fmt/format.h>

Logger::Logger(std::string modulename) :
	_module_name(std::move(modulename)),
	_loglevel(LogLevel::ERROR | LogLevel::WARNING)
{
	LogManager::Get()->IncreasePluginCounter();
}

Logger::~Logger()
{
	LogManager::Get()->DecreasePluginCounter();
}

bool Logger::Log(LogLevel level, const char *msg,
	std::vector<samplog::AmxFuncCallInfo> const &call_info)
{
	if (!IsLogLevel(level))
		return false;

	LogManager::Get()->QueueLogMessage(std::unique_ptr<CMessage>(new CMessage(
		_module_name, level, msg ? msg : "", std::vector<samplog::AmxFuncCallInfo>(call_info))));
	return true;
}

bool Logger::Log(LogLevel level, const char *msg)
{
	if (!IsLogLevel(level))
		return false;

	LogManager::Get()->QueueLogMessage(std::unique_ptr<CMessage>(new CMessage(
		_module_name, level, msg ? msg : "", { })));
	return true;
}

bool Logger::LogNativeCall(AMX * const amx, cell * const params,
	const char *name, const char *params_format)
{
	if (amx == nullptr)
		return false;

	if (params == nullptr)
		return false;

	if (name == nullptr || strlen(name) == 0)
		return false;

	if (params_format == nullptr) // params_format == "" is valid (no parameters)
		return false;

	size_t format_len = strlen(params_format);

	fmt::MemoryWriter fmt_msg;
	fmt_msg << name << '(';

	for (int i = 0; i != format_len; ++i)
	{
		if (i != 0)
			fmt_msg << ", ";

		cell current_param = params[i + 1];
		switch (params_format[i])
		{
			case 'd': //decimal
			case 'i': //integer
				fmt_msg << static_cast<int>(current_param);
				break;
			case 'f': //float
				fmt_msg << amx_ctof(current_param);
				break;
			case 'h': //hexadecimal
			case 'x': //
				fmt_msg << fmt::hex(current_param);
				break;
			case 'b': //binary
				fmt_msg << fmt::bin(current_param);
				break;
			case 's': //string
				fmt_msg << '"' << amx_GetCppString(amx, current_param) << '"';
				break;
			case '*': //censored output
				fmt_msg << "\"*****\"";
				break;
			case 'r': //reference
			{
				cell *addr_dest = nullptr;
				amx_GetAddr(amx, current_param, &addr_dest);
				fmt_msg << "0x" << fmt::pad(fmt::hexu(reinterpret_cast<unsigned int>(addr_dest)), 8, '0');
			}	break;
			case 'p': //pointer-value
				fmt_msg << "0x" << fmt::pad(fmt::hexu(current_param), 8, '0');
				break;
			default:
				return false; //unrecognized format specifier
		}
	}
	fmt_msg << ')';

	std::vector<samplog::AmxFuncCallInfo> call_info;
	CAmxDebugManager::Get()->GetFunctionCallTrace(amx, call_info);

	LogManager::Get()->QueueLogMessage(std::unique_ptr<CMessage>(new CMessage(
		_module_name, LogLevel::DEBUG, fmt_msg.str(), std::move(call_info))));
	return true;
}
<commit_msg>implement logger create function<commit_after>#include "Logger.hpp"
#include "CAmxDebugManager.hpp"
#include "LogManager.hpp"
#include "amx/amx2.h"

#include <fmt/format.h>

Logger::Logger(std::string modulename) :
	_module_name(std::move(modulename)),
	_loglevel(LogLevel::ERROR | LogLevel::WARNING)
{
	LogManager::Get()->IncreasePluginCounter();
}

Logger::~Logger()
{
	LogManager::Get()->DecreasePluginCounter();
}

bool Logger::Log(LogLevel level, const char *msg,
	std::vector<samplog::AmxFuncCallInfo> const &call_info)
{
	if (!IsLogLevel(level))
		return false;

	LogManager::Get()->QueueLogMessage(std::unique_ptr<CMessage>(new CMessage(
		_module_name, level, msg ? msg : "", std::vector<samplog::AmxFuncCallInfo>(call_info))));
	return true;
}

bool Logger::Log(LogLevel level, const char *msg)
{
	if (!IsLogLevel(level))
		return false;

	LogManager::Get()->QueueLogMessage(std::unique_ptr<CMessage>(new CMessage(
		_module_name, level, msg ? msg : "", { })));
	return true;
}

bool Logger::LogNativeCall(AMX * const amx, cell * const params,
	const char *name, const char *params_format)
{
	if (amx == nullptr)
		return false;

	if (params == nullptr)
		return false;

	if (name == nullptr || strlen(name) == 0)
		return false;

	if (params_format == nullptr) // params_format == "" is valid (no parameters)
		return false;

	size_t format_len = strlen(params_format);

	fmt::MemoryWriter fmt_msg;
	fmt_msg << name << '(';

	for (int i = 0; i != format_len; ++i)
	{
		if (i != 0)
			fmt_msg << ", ";

		cell current_param = params[i + 1];
		switch (params_format[i])
		{
			case 'd': //decimal
			case 'i': //integer
				fmt_msg << static_cast<int>(current_param);
				break;
			case 'f': //float
				fmt_msg << amx_ctof(current_param);
				break;
			case 'h': //hexadecimal
			case 'x': //
				fmt_msg << fmt::hex(current_param);
				break;
			case 'b': //binary
				fmt_msg << fmt::bin(current_param);
				break;
			case 's': //string
				fmt_msg << '"' << amx_GetCppString(amx, current_param) << '"';
				break;
			case '*': //censored output
				fmt_msg << "\"*****\"";
				break;
			case 'r': //reference
			{
				cell *addr_dest = nullptr;
				amx_GetAddr(amx, current_param, &addr_dest);
				fmt_msg << "0x" << fmt::pad(fmt::hexu(reinterpret_cast<unsigned int>(addr_dest)), 8, '0');
			}	break;
			case 'p': //pointer-value
				fmt_msg << "0x" << fmt::pad(fmt::hexu(current_param), 8, '0');
				break;
			default:
				return false; //unrecognized format specifier
		}
	}
	fmt_msg << ')';

	std::vector<samplog::AmxFuncCallInfo> call_info;
	CAmxDebugManager::Get()->GetFunctionCallTrace(amx, call_info);

	LogManager::Get()->QueueLogMessage(std::unique_ptr<CMessage>(new CMessage(
		_module_name, LogLevel::DEBUG, fmt_msg.str(), std::move(call_info))));
	return true;
}

samplog::ILogger *samplog_CreateLogger(const char *module)
{
	return new Logger(module);
}
<|endoftext|>


<commit_before>#include <iostream>
#include "Player.h"
#include"PlayerHuman.h"
#include"PlayerRandom.h"
using namespace std;
void manvsman();
void computervscomputer();
void humanvscomputer();
int main() {
	cout << "Welcome to Tic-Tac-Toe" << endl
		<< " X go first" << endl
		<< "press 1 for man vs man," << endl
		<< "press 2 for man vs computer" << endl
		<< "press 3 for computer vs computer" << endl;
	int dd=0;
	cin >> dd;
	while (dd != 1 && dd != 2 && dd != 3) {//reject not valid input and let user input again
		cin >> dd;
		cout << "not valid enter again" << endl;
	}
	if (dd == 1)
		manvsman();
	else if (dd == 2)
		humanvscomputer();
	else if (dd == 3)
		computervscomputer();
	else {
		cout << "invalid input" << endl;
	}
	return 0;
}

void computervscomputer()
{int q = 1, w = 2;int count = 0;
	Board *k = new Board;
	Player *objA = new PlayerRandom(&q);	//objA->setposition(&q);
	Player *objB = new PlayerRandom(&w);	//objB->setposition(&w);
     k->PrintBoard();
	while (k->DetermineWinner() != true && count <= 8) {
		objA->NextMove(*k);
		k->PrintBoard();
		count++;
		if (k->DetermineWinner() != true && count <= 8) {
			objB->NextMove(*k);
			k->PrintBoard();
			count++;
		}
	}
	if (k->printwinner(count, k) == 0)
		cout << "No winner." << endl;
	else if (k->printwinner(count, k) == 1)
		cout << "winner is:" << objB->getsymbol() << endl;
	else if (k->printwinner(count, k) == 2)
		cout << "winner is:" << objA->getsymbol() << endl;
	k->PrintBoard();
	delete k;
	delete objA;
	delete objB;
}

void humanvscomputer()
{
	Board *k = new Board;
	Player *objA ;
	Player *objB;
	k->PrintBoard();
	int q , w ;
	int count = 0;
	cout << "Do you want play X or O ?" << endl
		<< "1 for X, 2 for O" << endl;
	cin >> q;
	while (q!=1 && q!=2) {
		cout << "Invalid input. Please try again: ";
		cin >> q;
	}
	if (q == 1) {
		w = 2;
		 objA = new PlayerHuman(&q);
		 objB = new PlayerRandom(&w);
	}
	else if(q==2) {
		w = 1;
		objA = new PlayerRandom(&q);
		objB = new PlayerHuman(&w);
	}
	while (k->DetermineWinner() != true && count <= 8) {
		objA->NextMove(*k);
		k->PrintBoard();
		count++;
		if (k->DetermineWinner() != true && count <= 8) {
			objB->NextMove(*k);
			k->PrintBoard();
			count++;
		}
	}
	if (k->printwinner(count, k) == 0)
		cout << "No winner." << endl;
	else if (k->printwinner(count, k) == 1)
		cout << "winner is:" << objB->getsymbol() << endl;
	else if (k->printwinner(count, k) == 2)
		cout << "winner is:" << objA->getsymbol() << endl;
	k->PrintBoard();
	delete k;
	delete objA;
	delete objB;
}

void manvsman() {
	Board *k = new Board;
	k->PrintBoard();
	int q = 1, w = 2;
	int count = 0;
	Player *objA = new PlayerHuman(&q);	//objA->setposition(&q);
	Player *objB = new PlayerHuman(&w);	//objB->setposition(&w);
	while (k->DetermineWinner() != true && count <= 8) {
		objA->NextMove(*k);
		k->PrintBoard();
		count++;
		if (k->DetermineWinner() != true && count <= 8) {
			objB->NextMove(*k);
			k->PrintBoard();
			count++;
		}
	}
	if (k->printwinner(count, k) == 0)
		cout << "No winner." << endl;
	else if (k->printwinner(count, k) == 1)
		cout << "winner is:" << objB->getsymbol() << endl;
	else if (k->printwinner(count, k) == 2)
		cout << "winner is:" << objA->getsymbol() << endl;
	k->PrintBoard();
	delete k;
	delete objA;
	delete objB;
}

<commit_msg>Delete main.cpp<commit_after><|endoftext|>


<commit_before>0f752414-2748-11e6-852b-e0f84713e7b8<commit_msg>That didn't fix it<commit_after>0f821cdc-2748-11e6-8eaf-e0f84713e7b8<|endoftext|>


<commit_before>
#include <iostream>
#include <cstring>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <direct.h>
#include <fcntl.h>
#include <math.h>
#include <errno.h>
#include <time.h>
#include <sys/types.h>
//#include <sys/wait.h>
//#include <unistd.h>
#include <io.h>
using namespace std;

#define WORDLEN 10

int main()
{
/*	char *word[50];
    char buf[500] = "\0";
    int i, k=0;
    cin.getline(buf, 500);

    word[k] = strtok(buf, " ");

    while (word[k++] != NULL) {
        word[k] = strtok(NULL, " ");
    }
 	char checking_first = *word[0];
	pid_t pid;
	pid = fork();
	if(pid == 0)
	{
		if(k<=3  && word[0] != "exit"){
			string cmd("./src./single_command.sh ");
			cmd += word[0];
			cmd += " ";
			cmd += word[1];
			system(cmd.c_str());
			perror("invalid input");
		}								//run for single_command.sh
		else if(checking_first == '#'){
			string cmd("./src./comment_command.sh ");
			system(cmd.c_str());		//run for comment_command.sh
			perror("invalid input");
		}
		else if(word[0] == "exit"){
			string cmd("./src./exit.sh ");
			cmd += word[0];
			system(cmd.c_str());
			perror("invalid input");
		}								//run for exit.sh
		else	{
			int initial = 0;
			int hold_number = 0;
			int hold_other_number = 0;
			int ret[20];
			int v[20];

			while(initial <= k){
			string cmd("./src./multi_command.sh ");
				if(word[initial] == "|"|| word[initial] == "&" || word[initial][strlen(word[initial]-1)] == ';'){
					if(hold_number < initial){
						while(hold_number <initial){
						cmd += word[hold_number];
						hold_number++;
						}
						ret[hold_other_number] = system(cmd.c_str());
						v[hold_other_number] = WEXITSTATUS(ret[hold_other_number]);
					}
				}
				initial++;
			}
		}
		int status = 0;
		waitpid(pid, status, WNOHANG);
		if(status != 1){
			perror("fail to close child process");
		}

	}
	else if(pid == -1){
		cout<<"fork error!"<<endl;
	}
	else{
		cout<<"Should not be in parents"<<endl;
	}
*/
//top of part is for homework 01 which does not working so i made it as comment
	system("./test.sh");//this variable goes into src-> test.sh to test

		system("pause");
	return 0;
}
<commit_msg>201511191729<commit_after>#include <iostream>
#include <cstring>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <direct.h>
#include <fcntl.h>
#include <math.h>
#include <errno.h>
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <io.h>
using namespace std;
int main()
{
	char *word[50];
    char buf[500] = "\0";
	while(word[0] != "exit"){
    int i, k=0;
	cin.getline(buf, 500);

    word[k] = strtok(buf, " ");

    while (word[k++] != NULL) {
        word[k] = strtok(NULL, " ");
    }
 	char checking_first = *word[0];
/*	pid_t pid;
	pid = fork();
	if(pid == 0)
	{
		if(k<=3  && word[0] != "exit"){
			string cmd("./src./single_command.sh ");
			cmd += word[0];
			cmd += " ";
			cmd += word[1];
			system(cmd.c_str());
			perror("invalid input");
		}								//run for single_command.sh
		else if(checking_first == '#'){
			string cmd("./src./comment_command.sh ");
			system(cmd.c_str());		//run for comment_command.sh
			perror("invalid input");
		}
		else if(word[0] == "exit"){
			string cmd("./src./exit.sh ");
			cmd += word[0];
			system(cmd.c_str());
			perror("invalid input");
		}								//run for exit.sh
		else	{
			int initial = 0;
			int hold_number = 0;
			int hold_other_number = 0;
			int ret[20];
			int v[20];

			while(initial <= k){
			string cmd("./src./multi_command.sh ");
				if(word[initial] == "|"|| word[initial] == "&" || word[initial][strlen(word[initial]-1)] == ';'){
					if(hold_number < initial){
						while(hold_number <initial){
						cmd += word[hold_number];
						hold_number++;
						}
						ret[hold_other_number] = system(cmd.c_str());
						v[hold_other_number] = WEXITSTATUS(ret[hold_other_number]);
					}
				}
				initial++;
			}
		}
		int status = 0;
		waitpid(pid, status, WNOHANG);
		if(status != 1){
			perror("fail to close child process");
		}

	}
	else if(pid == -1){
		cout<<"fork error!"<<endl;
	}
	else{
		cout<<"Should not be in parents"<<endl;
	}
*/
//top of part is for homework 01 which does not working so i made it as comment
		if(checking_first == '[' || word[0] =="test"){
			checking_first = *word[1];
			if(checking_first == '-'){
				//All functions need that file exist
					if(word[1] == "-a" || word[1] == "-e"){ //True if <file> exist
						cout<<"file exist"<<endl;
					}
					else if(word[1] == "-f"){//True if <file> exist and is regular file
						info_RF(*word[2]);
					}
					else if(word[1] == "-d"){//True if <file> exist and is a directory
						info_D(*word[2]);
					}
					else if(word[1] == "-c"){//True if <file> exist and is character special file
						info_CS(*word[2]);
					}
					else if(word[1] == "-b"){//True if <file> exist and is block special file
						info_BS(*word[2]);
					}
					else if(word[1] == "-p"){//True if <file> exist and is named pipe
						// need to
					}
					else if(word[1] == "-S"){//True if <file> exist and is socket file
						info_S(*word[2]);
					}
					else if(word[1] == "-L" || word[1] =="-h"){//True if <file> exist and is symbolic link
						info_SL(*word[2]);
					}
					else if(word[1] == "-g"){//True if <file> exist and is sgid bit set
						// need to
					}
					else if(word[1] == "-u"){//True if <file> exist and is suid bit set
						// need to
					}
					else if(word[1] == "-r"){//True if <file> exist and is readable
						info_R(*word[2]);
					}
					else if(word[1] == "-w"){//True if <file> exist and is writeable
						info_W(*word[2]);
					}
					else if(word[1] == "-x"){//True if <file> exist and is excutable
						info_X(*word[2]);
					}
					else if(word[1] == "-s"){//True if <file> exist and size of file is bigger than 0 (not empty)
						//need to
					}
					else if(word[1] == "-t"){//True if file descriptor <fd> is open and refers to a terminal
						//need to
					}
			}
			checking_first = *word[2];
			if(checking_first == '-'){ // there is two files to compare
				if(word[2] == "-nt"){// True if <file1> is newer than <file2>

				}
				else if(word[2] == "-ot"){// True if <file1> is older than <file2>

				}
				else if(word[2] == "-ef"){// True if <file1> and <file2> refer to the same device and inode numbers.

				}
			}
		}
	}
	return 0;
}
int info_RF(const char * dirName){//regular file
	struct stat sb;
	if((sb.st_mode & S_IFREG)){
		return 1;
	}
	return 0;
}
int info_D(const char * dirName){
	struct stat sb;
	if((sb.st_mode & S_ISDIR)){
		return 1;
	}
	return 0;
}
int info_CS(const char * dirName){
	struct stat sb;
	if((sb.st_mode & S_IFCHR)){
		return 1;
	}
	return 0;
}
int info_BS(const char * dirName){
	struct stat sb;
	if((sb.st_mode & S_IFBLK)){
		return 1;
	}
	return 0;
}
int info_S(const char * dirName){
	struct stat sb;
	if((sb.st_mode & S_IFSOCK)){
		return 1;
	}
	return 0;
}
int info_SL(const char * dirName){
	struct stat sb;
	if((sb.st_mode & S_IFKNK)){
		return 1;
	}
	return 0;
}
 int info_R(const char * dirName){//read
	 struct stat sb;
	 if((sb.st_mode & S_IRUSR)){
		return 1;
	 }
	 return 0;
 }
int info_W(const char * dirName){
	struct stat sb;
	if((sb.st_mode & S_IWUSR)){
		return 1;
	}
	return 0;
}
int info_X(const char * dirName){
	struct stat sb;
	if((sb.st_mode & S_IXUSR)){
		return 1;
	}
	return 0;
}<|endoftext|>


<commit_before>/*
 * George 'papanikge' Papanikolaou
 * CEID Advance Algorithm Design Course 2014
 * Benchmarking of Shortest Augmenting Path MF Algorithm with Boost & LEDA
 */

#include <iostream>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <utility>
#include <LEDA/graph/graph.h>
#include <LEDA/graph/graph_gen.h>
#include <LEDA/graph/max_flow.h>
#include <LEDA/system/timer.h>
#include "boost-types.h"

/* Prototypes */
void generate_random_capacities(const leda::graph& G, leda::edge_array<int>& capacities);
std::pair<BoostVertex, BoostVertex> leda2boost(const leda::graph& LG, BoostGraph& BG, const leda::edge_array<int>& capacities, leda::node s, leda::node t);
int shortest_aug_path(BoostGraph& BG, const BoostVertex& source, const BoostVertex& target);

/*
 * Runs benchmarks for a given graph.
 * We are printing directly to cerr in this function to avoid flush() pollution
 */
static void benchmark(const leda::graph& G, leda::edge_array<int>& capacities)
{
    float T;
    int leda_flow, my_flow;
    BoostGraph BG;
    leda::node s, t;
    leda::edge_array<int> flow(G);

    /* Pick random source/sink nodes. */
    s = G.choose_node();
    do {
        t = G.choose_node();
    } while (s == t);

    /* Initial obligations */
    std::cerr << "\t  Preparing graphs... ";
    std::pair <BoostVertex, BoostVertex> Bst = leda2boost(G, BG, capacities, s, t);
    std::cerr << "Done." << std::endl;

    /* LEDA's internal implementation */
    T = leda::used_time();
    leda_flow = leda::MAX_FLOW(G, s, t, capacities, flow);
    std::cerr << "\t\tLEDA's Calculation time: " << leda::used_time(T);
    if (CHECK_MAX_FLOW(G, s, t, capacities, flow))
        std::cerr << "... [Correct]" << std::endl;
    else
        std::cerr << "... [Wrong]" << std::endl;

    /* My implementation */
    T = leda::used_time();
    my_flow = shortest_aug_path(BG, Bst.first, Bst.second);
    std::cerr << "\t\tCustom SAP Algorithm implementation time: " << leda::used_time(T) << std::endl;

    /* Testing & final errands */
    if (my_flow == leda_flow)
        std::cerr << "\t\t[Return values match!]" << std::endl;
    else
        std::cerr << "\t\t[Return values do NOT match!]" << std::endl;
    return;
}

int main(int argc, char **argv)
{
    int i, n;
    leda::graph G;
    leda::node s, u, t;
    leda::edge_array<int> capacities;
    unsigned int N[] = { 1000, 3000, 5000 };

    std::cout << "\n-=-=-=-=- Shortest Augmenting Path MF Algorithm Benchmarking -=-=-=-=-\n";
    if (argc > 2 && !strcmp(argv[1], "-n")) {
        /* Custom nodes from the command line */
        n = atoi(argv[2]);
        leda::random_simple_loopfree_graph(G, n, n*log10(n));
        generate_random_capacities(G, capacities);

        /* Safety check */
        if (G.is_undirected())
            std::cerr << "BUG! Graph is undirected!" << std::endl;

        benchmark(G, capacities);
    } else {
        s = G.new_node();
        u = G.new_node();
        t = G.new_node();
        G.new_edge(s, u);
        G.new_edge(u, t);
        G.new_edge(s, t);
        generate_random_capacities(G, capacities);
        benchmark(G, capacities);
    }
    return 0;
}
<commit_msg>Revert "testing code, custom graph. Revert"<commit_after>/*
 * George 'papanikge' Papanikolaou
 * CEID Advance Algorithm Design Course 2014
 * Benchmarking of Shortest Augmenting Path MF Algorithm with Boost & LEDA
 */

#include <iostream>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <utility>
#include <LEDA/graph/graph.h>
#include <LEDA/graph/graph_gen.h>
#include <LEDA/graph/max_flow.h>
#include <LEDA/system/timer.h>
#include "boost-types.h"

/* Prototypes */
void generate_random_capacities(const leda::graph& G, leda::edge_array<int>& capacities);
std::pair<BoostVertex, BoostVertex> leda2boost(const leda::graph& LG, BoostGraph& BG, const leda::edge_array<int>& capacities, leda::node s, leda::node t);
int shortest_aug_path(BoostGraph& BG, const BoostVertex& source, const BoostVertex& target);

/*
 * Runs benchmarks for a given graph.
 * We are printing directly to cerr in this function to avoid flush() pollution
 */
static void benchmark(const leda::graph& G, leda::edge_array<int>& capacities)
{
    float T;
    int leda_flow, my_flow;
    BoostGraph BG;
    leda::node s, t;
    leda::edge_array<int> flow(G);

    /* Pick random source/sink nodes. */
    s = G.choose_node();
    do {
        t = G.choose_node();
    } while (s == t);

    /* Initial obligations */
    std::cerr << "\t  Preparing graphs... ";
    std::pair <BoostVertex, BoostVertex> Bst = leda2boost(G, BG, capacities, s, t);
    std::cerr << "Done." << std::endl;

    /* LEDA's internal implementation */
    T = leda::used_time();
    leda_flow = leda::MAX_FLOW(G, s, t, capacities, flow);
    std::cerr << "\t\tLEDA's Calculation time: " << leda::used_time(T);
    if (CHECK_MAX_FLOW(G, s, t, capacities, flow))
        std::cerr << "... [Correct]" << std::endl;
    else
        std::cerr << "... [Wrong]" << std::endl;

    /* My implementation */
    T = leda::used_time();
    my_flow = shortest_aug_path(BG, Bst.first, Bst.second);
    std::cerr << "\t\tCustom SAP Algorithm implementation time: " << leda::used_time(T) << std::endl;

    /* Testing & final errands */
    if (my_flow == leda_flow)
        std::cerr << "\t\t[Return values match!]" << std::endl;
    else
        std::cerr << "\t\t[Return values do NOT match!]" << std::endl;
    return;
}

int main(int argc, char **argv)
{
    int i, n;
    leda::graph G;
    leda::edge_array<int> capacities;
    unsigned int N[] = { 1000, 3000, 5000 };

    std::cout << "\n-=-=-=-=- Shortest Augmenting Path MF Algorithm Benchmarking -=-=-=-=-\n";
    if (argc > 2 && !strcmp(argv[1], "-n")) {
        /* Custom nodes from the command line */
        n = atoi(argv[2]);
        leda::random_simple_loopfree_graph(G, n, n*log10(n));
        generate_random_capacities(G, capacities);

        /* Safety check */
        if (G.is_undirected())
            std::cerr << "BUG! Graph is undirected!" << std::endl;

        benchmark(G, capacities);
    } else {
        /* Default values in the nodes */
        std::cout << "Give -n <number of nodes> if you want a custom amount\n";
        std::cout << "Moving on with the default values...\n\n";

        std::cout << ">>> Random graphs...\n";
        for (i = 0; i < 3; i++) {
            std::cout << "\tGenerating random graph with " << N[i] << " nodes... ";
            std::cout.flush();
            leda::random_simple_loopfree_graph(G, N[i], N[i]*log10(N[i]));
            generate_random_capacities(G, capacities);
            std::cout << "Done." << std::endl;

            benchmark(G, capacities);

            /* cleaning up for the next iteration */
            G.clear();
        }
    }
    return 0;
}
<|endoftext|>


<commit_before>#include <Disp.h>
#include <GPIO.h>
#include <IRadio.h>

#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <sstream>
#include <string>

// FUNCTION PROTOTYPING
void msleep( unsigned milisec );
void sig_handler( int sig );

// GLOBAL VARIABLES
bool ctrl_c_pressed = false;

int main()
{
	if( signal(SIGINT, sig_handler) == SIG_ERR )
		std::cout << "Can't catch SIGINT" << std::endl;

	GPIO* led1 = new GPIO(4, OUT);
	GPIO* led2 = new GPIO(3, OUT);
	GPIO* led3 = new GPIO(2, OUT);

	GPIO* button1 = new GPIO(17, IN, 0.5);
	GPIO* button2 = new GPIO(27, IN, 0.5);
	GPIO* button3 = new GPIO(22, IN, 0.5);

	Disp* lcd = new Disp{14,15,18,11,23,24,9,25,8,7,10};
	std::string line1{}, line2{}, str{};

	IRadio* rstream = new IRadio();
	rstream->startStream();

	std::chrono::time_point<std::chrono::system_clock> start_1, start_2;
	std::chrono::duration<double> elapsed_time;
	start_1 = start_2 = std::chrono::system_clock::now();

	while(1)
	{
		led1->setValue( button1->getValue() );
		led2->setValue( button2->getValue() );
		led3->setValue( button3->getValue() );

		elapsed_time = std::chrono::system_clock::now() - start_1;
		if( (elapsed_time.count() >= 15.0) || rstream->streamHasChanged() )
		{
			start_1 = std::chrono::system_clock::now();
			rstream->getStreamInfos();

			line1 = "[" + std::to_string(rstream->getStreamNr()) + "] " + rstream->getStreamName() + "   ";
			line2 = rstream->getInterpret() + " - " + rstream->getTitle()  + "   ";
		}

		elapsed_time = std::chrono::system_clock::now() - start_2;
		if( elapsed_time.count() >= 1.0 )
		{
			start_2 = std::chrono::system_clock::now();
			if( lcd->disp_job==lcd->no_job )
			{
				if( !line1.empty() )
				{
					if( line1.size()<DISP_LINE_LENGTH+3 )
					{
						str = line1.substr(0,DISP_LINE_LENGTH);
						lcd->writeText( &str, 1 );
					}
					else
					{
						str = line1.substr(0,DISP_LINE_LENGTH);
						line1 = line1.substr(1) + line1.at(0);
						lcd->writeText( &str, 1 );
					}
				}
				if( !line2.empty() )
				{
					if( line2.size()<DISP_LINE_LENGTH+3 )
					{
						str = line2.substr(0,DISP_LINE_LENGTH);
						lcd->writeText( &str, 2 );
					}
					else
					{
						str = line2.substr(0,DISP_LINE_LENGTH);
						line2 = line2.substr(1) + line2.at(0);
						lcd->writeText( &str, 2 );
					}
				}
			}
		}

		lcd->process();

		if( !button1->getDebouncedValue() )
			rstream->decreaseStreamNr();
		if( !button2->getDebouncedValue() )
			rstream->stopStream();
		if( !button3->getDebouncedValue() )
			rstream->increaseStreamNr();

		if( ctrl_c_pressed )
			break;
	}

	delete lcd;
	delete led1; delete led2; delete led3;
	delete button1; delete button2; delete button3;
	delete rstream;
}

void msleep( unsigned milisec )
{
	for(unsigned i=0; i<milisec; ++i)
		usleep( 1000 );
}

void sig_handler( int sig )
{
	if (sig == SIGINT)
		ctrl_c_pressed = true;
}
<commit_msg>Correct usage of streamHasChanged()<commit_after>#include <Disp.h>
#include <GPIO.h>
#include <IRadio.h>

#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <sstream>
#include <string>

// FUNCTION PROTOTYPING
void msleep( unsigned milisec );
void sig_handler( int sig );

// GLOBAL VARIABLES
bool ctrl_c_pressed = false;

int main()
{
	if( signal(SIGINT, sig_handler) == SIG_ERR )
		std::cout << "Can't catch SIGINT" << std::endl;

	GPIO* led1 = new GPIO(4, OUT);
	GPIO* led2 = new GPIO(3, OUT);
	GPIO* led3 = new GPIO(2, OUT);

	GPIO* button1 = new GPIO(17, IN, 0.5);
	GPIO* button2 = new GPIO(27, IN, 0.5);
	GPIO* button3 = new GPIO(22, IN, 0.5);

	Disp* lcd = new Disp{14,15,18,11,23,24,9,25,8,7,10};
	std::string line1{}, line2{}, str{};

	IRadio* rstream = new IRadio();
	rstream->startStream();

	std::chrono::time_point<std::chrono::system_clock> start_1, start_2;
	std::chrono::duration<double> elapsed_time;
	start_1 = start_2 = std::chrono::system_clock::now();

	while(1)
	{
		led1->setValue( button1->getValue() );
		led2->setValue( button2->getValue() );
		led3->setValue( button3->getValue() );

		elapsed_time = std::chrono::system_clock::now() - start_1;
		if( elapsed_time.count() >= 15.0 )
		{
			start_1 = std::chrono::system_clock::now();
			rstream->getStreamInfos();

			if( rstream->streamHasChanged() )
			{
				line1 = "[" + std::to_string(rstream->getStreamNr()) + "] " + rstream->getStreamName() + "   ";
				line2 = rstream->getInterpret() + " - " + rstream->getTitle()  + "   ";
			}
		}

		elapsed_time = std::chrono::system_clock::now() - start_2;
		if( elapsed_time.count() >= 1.0 )
		{
			start_2 = std::chrono::system_clock::now();
			if( lcd->disp_job==lcd->no_job )
			{
				if( !line1.empty() )
				{
					if( line1.size()<DISP_LINE_LENGTH+3 )
					{
						str = line1.substr(0,DISP_LINE_LENGTH);
						lcd->writeText( &str, 1 );
					}
					else
					{
						str = line1.substr(0,DISP_LINE_LENGTH);
						line1 = line1.substr(1) + line1.at(0);
						lcd->writeText( &str, 1 );
					}
				}
				if( !line2.empty() )
				{
					if( line2.size()<DISP_LINE_LENGTH+3 )
					{
						str = line2.substr(0,DISP_LINE_LENGTH);
						lcd->writeText( &str, 2 );
					}
					else
					{
						str = line2.substr(0,DISP_LINE_LENGTH);
						line2 = line2.substr(1) + line2.at(0);
						lcd->writeText( &str, 2 );
					}
				}
			}
		}

		lcd->process();

		if( !button1->getDebouncedValue() )
			rstream->decreaseStreamNr();
		if( !button2->getDebouncedValue() )
			rstream->stopStream();
		if( !button3->getDebouncedValue() )
			rstream->increaseStreamNr();

		if( ctrl_c_pressed )
			break;
	}

	delete lcd;
	delete led1; delete led2; delete led3;
	delete button1; delete button2; delete button3;
	delete rstream;
}

void msleep( unsigned milisec )
{
	for(unsigned i=0; i<milisec; ++i)
		usleep( 1000 );
}

void sig_handler( int sig )
{
	if (sig == SIGINT)
		ctrl_c_pressed = true;
}
<|endoftext|>


<commit_before>d284266e-ad5a-11e7-9dbf-ac87a332f658<commit_msg>No longer crashes if X<commit_after>d362574a-ad5a-11e7-87b6-ac87a332f658<|endoftext|>


<commit_before>f616abb3-2747-11e6-a94d-e0f84713e7b8<commit_msg>Fixed that one bug<commit_after>f6201154-2747-11e6-88f0-e0f84713e7b8<|endoftext|>


<commit_before>//
// Copyright (C) 2010 SIPez LLC.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// Copyright (C) 2010 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// $$
///////////////////////////////////////////////////////////////////////////////

// Author: Alexander Chemeris <Alexander DOT Chemeris AT SIPez DOT com>

#define LOG_NDEBUG 0
#define LOG_TAG "MpodAndroid"
//#define ENABLE_FRAME_TIME_LOGGING
//#define ENABLE_FILE_LOGGING

// SIPX INCLUDES
#include "mp/MpodAndroid.h"
#include <os/OsCallback.h>

// SYSTEM INCLUDES
#include <stdio.h>
#include <math.h>
#include <utils/Log.h>
#include <media/AudioSystem.h>

//#define RTL_ENABLED
//#define RTL_AUDIO_ENABLED
#ifdef RTL_ENABLED // [
#  include "rtl_macro.h"
#else  // RTL_ENABLED ][
#  define RTL_BLOCK(x)
#  define RTL_EVENT(x, y)
#endif // RTL_ENABLED ]

// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STATIC VARIABLE INITIALIZATIONS

#ifdef ENABLE_FILE_LOGGING
static FILE *sgOutFile=NULL;
class OutFileInit
{
public:
   OutFileInit()
   {
      sgOutFile = fopen("/sdcard/out.raw", "w");
      LOGI("Openned file for audio debug: %x", sgOutFile);
   }

   ~OutFileInit()
   {
      fclose(sgOutFile);
   }
};

static OutFileInit sgOutFileInit;
#endif // ENABLE_FILE_LOGGING

/* //////////////////////////// PUBLIC //////////////////////////////////// */

/* ============================ CREATORS ================================== */
// Default constructor
MpodAndroid::MpodAndroid(StreamType streamType)
: MpOutputDeviceDriver("")
, mStreamType(streamType)
, mState(DRIVER_IDLE)
, mpAudioTrack(NULL)
, mpNotifier(NULL)
, mpSampleBuffer(NULL)
, mSampleBufferIndex(0)
{
   int frameCount;
   uint32_t outputLatency;
   int samplingRate;

   LOGV("MpodAndroid constructor: streamType=%d\n", streamType);

   if (AudioSystem::getOutputSamplingRate(&samplingRate, streamType) != NO_ERROR) {
      LOGE("Unable to marshal AudioFlinger");
      return;
   } else {
      LOGV("AudioFlinger default sampling rate for the stream is %d\n", samplingRate);
   }
   if (AudioSystem::getOutputFrameCount(&frameCount, streamType) != NO_ERROR) {
      LOGE("Unable to marshal AudioFlinger");
      return;
   } else {
      LOGV("AudioFlinger default frame count for the stream is %d\n", frameCount);
   }
   if (AudioSystem::getOutputLatency(&outputLatency, streamType) != NO_ERROR) {
      LOGE("Unable to marshal AudioFlinger");
      return;
   } else {
      LOGV("AudioFlinger default output latency for the stream is %d\n", outputLatency);
   }
}

MpodAndroid::~MpodAndroid()
{
   if (isEnabled())
   {
      LOGV("MpodAndroid::~MpodAndroid calling disableDevice\n");
      disableDevice();
   }
}

/* ============================ MANIPULATORS ============================== */

OsStatus MpodAndroid::enableDevice(unsigned samplesPerFrame,
                                   unsigned samplesPerSec,
                                   MpFrameTime currentFrameTime,
                                   OsCallback &frameTicker)
{
   LOGV("MpodAndroid::enableDevice(samplesPerFrame=%d, samplesPerSec=%d, currentFrameTime=%d, frameTicker=%p) mState=%d, mIsEnabled=%s\n",
        samplesPerFrame, samplesPerSec, currentFrameTime, (void*)&frameTicker, (int)mState, ((mIsEnabled != FALSE) ? "true" : "false"));

   if (isEnabled())
   {
      return OS_FAILED;
   }

   // Start accessing non-atomic member variables
   AutoMutex autoLock(mLock);

   mSamplesPerFrame = samplesPerFrame;
   mSamplesPerSec = samplesPerSec;
   mCurFrameTime = currentFrameTime;
   mpTickerNotification = &frameTicker;
   mpSampleBuffer = new MpAudioSample[mSamplesPerFrame];
   memset(mpSampleBuffer, 0, mSamplesPerFrame*sizeof(MpAudioSample));
   mSampleBufferIndex = 0;

   if (mState == DRIVER_IDLE) {
      LOGV("MpodAndroid::enableDevice() trying to init AudioTrack");
      if (!initAudioTrack()) {
         LOGE("MpodAndroid::enableDevice() init failed!");
         return OS_FAILED;
      }
   }

   if (mState != DRIVER_INIT) {
      LOGV("MpodAndroid::enableDevice() Wrong MpodAndroid state: %d\n", mState.load());
      return OS_FAILED;
   }

   mIsEnabled = TRUE;

   LOGV("MpodAndroid::enableDevice() starting, time %d\n", (unsigned int)(systemTime()/1000000));
   mState = DRIVER_STARTING;
   mpAudioTrack->dumpAudioTrack("MpodAndroid::enableDevice");
   mLock.unlock();
   mpAudioTrack->start();
   mLock.lock();
   if (mState == DRIVER_STARTING) {
      LOGV("MpodAndroid::enableDevice() waiting for start callback");
      int /*status_t*/ lStatus = mWaitCbkCond.waitRelative(mLock, seconds(3));
      if (lStatus != NO_ERROR) {
         LOGE("MpodAndroid::enableDevice() callback timed out, status %d", lStatus);
         mState = DRIVER_IDLE;
         mIsEnabled = FALSE;
         return OS_FAILED;
      }
   } else {
      LOGW("MpodAndroid::enableDevice() state %d\n", mState.load());
   }
   LOGV("MpodAndroid::enableDevice() started, time %d\n", (unsigned int)(systemTime()/1000000));

   return OS_SUCCESS;
}

OsStatus MpodAndroid::disableDevice()
{
   LOGV("MpodAndroid::disableDevice()");

   // If the device is not enabled,
   // then don't do anything and return failure.
   if ( !isEnabled() )
   {
      LOGV("Device already disabled\n");
      return OS_FAILED;
   }

   // Start accessing non-atomic member variables
   AutoMutex autoLock(mLock);

   if (mState == DRIVER_PLAYING || mState == DRIVER_STARTING) {
      mState = DRIVER_STOPPING;
      LOGV("MpodAndroid::disableDevice() waiting cond");
      int /*status_t*/ lStatus = mWaitCbkCond.waitRelative(mLock, seconds(3));
      if (lStatus == NO_ERROR) {
         LOGV("MpodAndroid::disableDevice() track stop complete, time %d", (unsigned int)(systemTime()/1000000));
      } else {
         LOGE("MpodAndroid::disableDevice() Stop timed out");
         mState = DRIVER_IDLE;
         mpAudioTrack->stop();
      }
   }

   mpAudioTrack->dumpAudioTrack("MpodAndroid::disableDevice");
   LOGV("MpodAndroid::disableDevice() Delete Track: %p\n", mpAudioTrack);
   delete mpAudioTrack;
   mpAudioTrack = NULL;
   LOGV("MpodAndroid::disableDevice() Deleted Track\n");

   // Clear out stream information.
   mSamplesPerFrame = 0;
   mSamplesPerSec = 0;
   mCurFrameTime = 0;
   mpTickerNotification = NULL;
   delete[] mpSampleBuffer;
   LOGV("MpodAndroid::disableDevice() Deleted mpSampleBuffer\n");

   // Indicate we are no longer enabled
   mIsEnabled = FALSE;

   return OS_SUCCESS;
}

OsStatus MpodAndroid::pushFrame(unsigned int numSamples,
                                const MpAudioSample* samples,
                                MpFrameTime frameTime)
{
   RTL_BLOCK("MpodAndroid::pushFrame");

   if (!isEnabled())
   {
      return OS_FAILED;
   }

   // Only full frames are supported right now.
//   LOGV("MpodAndroid::pushFrame(numSamples=%d, samples=%p)", numSamples, samples);
   assert((mSamplesPerFrame == numSamples) ||
          (numSamples == 0 && samples== NULL));

   // This pushFrame() is actually just a hack to adopt Android's AudioTrack
   // for use with our driver framework. We know that this function will be
   // called from ticker callback, so we assume that mpSampleBuffer points
   // to a buffer, passed to us by AudioTrack and we can simply memcpy to it.

   // If samples == NULL, then silent (full) frame should be inserted.
   if (samples != NULL)
   {
      // We have data
#ifdef RTL_AUDIO_ENABLED
      RTL_RAW_AUDIO("MpodAndroid_pushFrame", mSamplesPerSec, numSamples, samples,
                    frameTime*(mSamplesPerSec/1000)/mSamplesPerFrame);
#endif

      if (mpSampleBuffer != NULL)
      {
         memcpy(mpSampleBuffer, samples, mSamplesPerFrame*sizeof(MpAudioSample));
      }
   } else {
      // No data, fill with silence
      if (mpSampleBuffer != NULL)
      {
         memset(mpSampleBuffer, 0, mSamplesPerFrame*sizeof(MpAudioSample));
#ifdef RTL_AUDIO_ENABLED
         RTL_RAW_AUDIO("MpodAndroid_pushFrame", mSamplesPerSec, mSamplesPerFrame, mpSampleBuffer,
                       frameTime*(mSamplesPerSec/1000)/mSamplesPerFrame);
#endif
      }
   }

   return OS_SUCCESS;
}

/* ============================ ACCESSORS ================================= */

/* ============================ INQUIRY =================================== */

/* //////////////////////////// PROTECTED ///////////////////////////////// */

UtlBoolean MpodAndroid::initAudioTrack()
{
   LOGV("MpodAndroid::initAudioTrack");
   int /*status_t*/ initRes;

   if (mpAudioTrack) {
      LOGV("MpodAndroid::initAudioTrack deleting mpAudioTrack");
      delete mpAudioTrack;
      LOGV("MpodAndroid::initAudioTrack deleted mpAudioTrack");
      mpAudioTrack = NULL;
   }

   // Open audio track
   mpAudioTrack = MpAndroidAudioTrack::spAudioTrackCreate(mStreamType,  // streamType
                                 mSamplesPerSec,  // sampleRate
                                 AudioSystem::PCM_16_BIT,  // format
#ifdef ANDROID_1_6
                                 1,  // channels
#else
                                 AudioSystem::CHANNEL_OUT_MONO,
#endif
                                 0,  // frameCount
                                 0,  // flags
                                 audioCallback,  // cbf
                                 this,  // user
                                 mSamplesPerFrame);  // notificationFrames
   if (mpAudioTrack == NULL) {
      LOGE("MpodAndroid::initAudioTrack() AudioTrack allocation failed\n");
      goto initAudioTrack_exit;
   }
   mpAudioTrack->dumpAudioTrack("MpodAndroid::initAudioTrack");
   LOGV("MpodAndroid::initAudioTrack() Create Track: %p\n", mpAudioTrack);

   initRes = mpAudioTrack->initCheck();
   if (initRes != NO_ERROR) {
      LOGE("MpodAndroid::initAudioTrack() AudioTrack->initCheck() returned %d\n", initRes);
      goto initAudioTrack_exit;
   }

   LOGV("MpodAndroid::initAudioTrack() AudioTrack->initCheck() returned %d, NO_ERROR=%p\n", initRes, NO_ERROR);
   mpAudioTrack->dumpAudioTrack("MpodAndroid::initAudioTrack after initCheck");
   LOGD("initAudioTrack AudioTrack sampleRate: %d frameSize: %d frameCount: %d latency: %d",
        (int)mpAudioTrack->getSampleRate(), mpAudioTrack->frameSize(), (int)mpAudioTrack->frameCount(), (int)mpAudioTrack->latency());

   mpAudioTrack->setVolume(1.0, 1.0);

   mState = DRIVER_INIT;

   return true;

initAudioTrack_exit:

   // Cleanup
   if (mpAudioTrack) {
      LOGV("Delete Track: %p\n", mpAudioTrack);
      delete mpAudioTrack;
      mpAudioTrack = NULL;
   }

   return false;
}

void MpodAndroid::audioCallback(int event, void* user, void *info)
{
   RTL_BLOCK("MpodAndroid::audioCallback");
   bool lSignal = false;
   if (event != MpAndroidAudioTrack::EVENT_MORE_DATA)
   {
      LOGV("MpodAndroid::audioCallback(event=%d)\n", event);
      return;
   }

   MpAndroidAudioTrack::Buffer *buffer = static_cast<MpAndroidAudioTrack::Buffer *>(info);
   MpodAndroid *pDriver = static_cast<MpodAndroid *>(user);

   // Start accessing non-atomic member variables
   AutoMutex autoLock(pDriver->mLock);

   int samplesToCopy = sipx_min(buffer->frameCount,
                                pDriver->mSamplesPerFrame-pDriver->mSampleBufferIndex);
#ifdef ENABLE_FRAME_TIME_LOGGING
   LOGV("MpodAndroid::audioCallback() buffer=%p samples=%d size=%d toCopy=%d\n",
        buffer->i16, buffer->frameCount, buffer->size, samplesToCopy);
#endif
   RTL_EVENT("MpodAndroid::audioCallback_bufsize", samplesToCopy);
   // Copy data to buffer
   memcpy(buffer->i16, pDriver->mpSampleBuffer+pDriver->mSampleBufferIndex, samplesToCopy*sizeof(short));
   buffer->frameCount = samplesToCopy;
   buffer->size = samplesToCopy*sizeof(short);
   pDriver->mSampleBufferIndex += samplesToCopy;

#ifdef ENABLE_FILE_LOGGING
   fwrite(buffer->i16, 1, buffer->frameCount*sizeof(short), sgOutFile);
#endif // ENABLE_FILE_LOGGING

   if (pDriver->mSampleBufferIndex >= pDriver->mSamplesPerFrame)
   {
      RTL_BLOCK("MpodAndroid::audioCallback_tick");
      if(pDriver->mSampleBufferIndex > pDriver->mSamplesPerFrame)
      {
         LOGE("MpodAndroid::audioCallback() sample index (%d) > samples/frame (%d)\n", (int)pDriver->mSampleBufferIndex, (int)pDriver->mSamplesPerFrame);
      }

      // Return index to the beginning
      pDriver->mSampleBufferIndex = 0;

      // Fire callback. It will call our pushFrame() in turn.
#ifdef ENABLE_FRAME_TIME_LOGGING
      LOGV("MpodAndroid::audioCallback() signal ticker, time %"PRIi64"ns\n", systemTime(SYSTEM_TIME_REALTIME));
#endif
      pDriver->mpTickerNotification->signal(pDriver->mSamplesPerFrame);

      // Update frame time.
      pDriver->mCurFrameTime += pDriver->mSamplesPerFrame;
   }

   // Step forward state
   switch (pDriver->mState) {
    case DRIVER_STARTING:
       pDriver->mState = DRIVER_PLAYING;
       lSignal = true;
       break;
    case DRIVER_STOPPING:
//       pDriver->mState = DRIVER_STOPPED;
//       break;
    case DRIVER_STOPPED:
       LOGV("MpodAndroid::audioCallback() stopping Track\n");
       pDriver->mpAudioTrack->stop();
       LOGV("MpodAndroid::audioCallback() stopped Track\n");
       buffer->size = 0;
       pDriver->mState = DRIVER_IDLE;
       lSignal = true;
       break;
    default:
       break;
   }

   if (lSignal)
   {
      LOGV("MpodAndroid::audioCallback signalling\n");
      pDriver->mWaitCbkCond.signal();
      LOGV("MpodAndroid::audioCallback signalled\n");
   }
}

/* //////////////////////////// PRIVATE /////////////////////////////////// */
<commit_msg>Some additonal logging for Android output driver.<commit_after>//
// Copyright (C) 2010 SIPez LLC.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// Copyright (C) 2010 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// $$
///////////////////////////////////////////////////////////////////////////////

// Author: Alexander Chemeris <Alexander DOT Chemeris AT SIPez DOT com>

#define LOG_NDEBUG 0
#define LOG_TAG "MpodAndroid"
//#define ENABLE_FRAME_TIME_LOGGING
//#define ENABLE_FILE_LOGGING

// SIPX INCLUDES
#include "mp/MpodAndroid.h"
#include <os/OsCallback.h>

// SYSTEM INCLUDES
#include <stdio.h>
#include <math.h>
#include <utils/Log.h>
#include <media/AudioSystem.h>

//#define RTL_ENABLED
//#define RTL_AUDIO_ENABLED
#ifdef RTL_ENABLED // [
#  include "rtl_macro.h"
#else  // RTL_ENABLED ][
#  define RTL_BLOCK(x)
#  define RTL_EVENT(x, y)
#endif // RTL_ENABLED ]

// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STATIC VARIABLE INITIALIZATIONS

#ifdef ENABLE_FILE_LOGGING
static FILE *sgOutFile=NULL;
class OutFileInit
{
public:
   OutFileInit()
   {
      sgOutFile = fopen("/sdcard/out.raw", "w");
      LOGI("Openned file for audio debug: %x", sgOutFile);
   }

   ~OutFileInit()
   {
      fclose(sgOutFile);
   }
};

static OutFileInit sgOutFileInit;
#endif // ENABLE_FILE_LOGGING

/* //////////////////////////// PUBLIC //////////////////////////////////// */

/* ============================ CREATORS ================================== */
// Default constructor
MpodAndroid::MpodAndroid(StreamType streamType)
: MpOutputDeviceDriver("")
, mStreamType(streamType)
, mState(DRIVER_IDLE)
, mpAudioTrack(NULL)
, mpNotifier(NULL)
, mpSampleBuffer(NULL)
, mSampleBufferIndex(0)
{
   int frameCount;
   uint32_t outputLatency;
   int samplingRate;

   LOGV("MpodAndroid constructor: streamType=%d\n", streamType);

   if (AudioSystem::getOutputSamplingRate(&samplingRate, streamType) != NO_ERROR) {
      LOGE("Unable to marshal AudioFlinger");
      return;
   } else {
      LOGV("AudioFlinger default sampling rate for the stream is %d\n", samplingRate);
   }
   if (AudioSystem::getOutputFrameCount(&frameCount, streamType) != NO_ERROR) {
      LOGE("Unable to marshal AudioFlinger");
      return;
   } else {
      LOGV("AudioFlinger default frame count for the stream is %d\n", frameCount);
   }
   if (AudioSystem::getOutputLatency(&outputLatency, streamType) != NO_ERROR) {
      LOGE("Unable to marshal AudioFlinger");
      return;
   } else {
      LOGV("AudioFlinger default output latency for the stream is %d\n", outputLatency);
   }
}

MpodAndroid::~MpodAndroid()
{
   if (isEnabled())
   {
      LOGV("MpodAndroid::~MpodAndroid calling disableDevice\n");
      disableDevice();
   }
}

/* ============================ MANIPULATORS ============================== */

OsStatus MpodAndroid::enableDevice(unsigned samplesPerFrame,
                                   unsigned samplesPerSec,
                                   MpFrameTime currentFrameTime,
                                   OsCallback &frameTicker)
{
   LOGV("MpodAndroid::enableDevice(samplesPerFrame=%d, samplesPerSec=%d, currentFrameTime=%d, frameTicker=%p) mState=%d, mIsEnabled=%s\n",
        samplesPerFrame, samplesPerSec, currentFrameTime, (void*)&frameTicker, (int)mState, ((mIsEnabled != FALSE) ? "true" : "false"));

   if (isEnabled())
   {
      LOGE("MpodAndroid::enableDevice() already enabled");
      return OS_FAILED;
   }

   // Start accessing non-atomic member variables
   AutoMutex autoLock(mLock);

   mSamplesPerFrame = samplesPerFrame;
   mSamplesPerSec = samplesPerSec;
   mCurFrameTime = currentFrameTime;
   mpTickerNotification = &frameTicker;
   mpSampleBuffer = new MpAudioSample[mSamplesPerFrame];
   memset(mpSampleBuffer, 0, mSamplesPerFrame*sizeof(MpAudioSample));
   mSampleBufferIndex = 0;

   if (mState == DRIVER_IDLE) {
      LOGV("MpodAndroid::enableDevice() trying to init AudioTrack");
      if (!initAudioTrack()) {
         LOGE("MpodAndroid::enableDevice() init failed!");
         return OS_FAILED;
      }
   }

   if (mState != DRIVER_INIT) {
      LOGV("MpodAndroid::enableDevice() Wrong MpodAndroid state: %d\n", mState.load());
      return OS_FAILED;
   }

   mIsEnabled = TRUE;

   LOGV("MpodAndroid::enableDevice() starting, time %d\n", (unsigned int)(systemTime()/1000000));
   mState = DRIVER_STARTING;
   mpAudioTrack->dumpAudioTrack("MpodAndroid::enableDevice");
   mLock.unlock();
   mpAudioTrack->start();
   mpAudioTrack->dumpAudioTrack("MpodAndroid::enableDevice after start");
   mLock.lock();
   if (mState == DRIVER_STARTING) {
      LOGV("MpodAndroid::enableDevice() waiting for start callback");
      int /*status_t*/ lStatus = mWaitCbkCond.waitRelative(mLock, seconds(3));
      if (lStatus != NO_ERROR) {
         LOGE("MpodAndroid::enableDevice() callback timed out, status %d", lStatus);
         mState = DRIVER_IDLE;
         mIsEnabled = FALSE;
         return OS_FAILED;
      }
   } else {
      LOGW("MpodAndroid::enableDevice() state %d\n", mState.load());
   }
   LOGV("MpodAndroid::enableDevice() started, time %d\n", (unsigned int)(systemTime()/1000000));

   return OS_SUCCESS;
}

OsStatus MpodAndroid::disableDevice()
{
   LOGV("MpodAndroid::disableDevice()");

   // If the device is not enabled,
   // then don't do anything and return failure.
   if ( !isEnabled() )
   {
      LOGV("Device already disabled\n");
      return OS_FAILED;
   }

   // Start accessing non-atomic member variables
   AutoMutex autoLock(mLock);

   if (mState == DRIVER_PLAYING || mState == DRIVER_STARTING) {
      mState = DRIVER_STOPPING;
      LOGV("MpodAndroid::disableDevice() waiting cond");
      int /*status_t*/ lStatus = mWaitCbkCond.waitRelative(mLock, seconds(3));
      if (lStatus == NO_ERROR) {
         LOGV("MpodAndroid::disableDevice() track stop complete, time %d", (unsigned int)(systemTime()/1000000));
      } else {
         LOGE("MpodAndroid::disableDevice() Stop timed out");
         mState = DRIVER_IDLE;
         mpAudioTrack->stop();
      }
   }

   mpAudioTrack->dumpAudioTrack("MpodAndroid::disableDevice");
   LOGV("MpodAndroid::disableDevice() Delete Track: %p\n", mpAudioTrack);
   delete mpAudioTrack;
   mpAudioTrack = NULL;
   LOGV("MpodAndroid::disableDevice() Deleted Track\n");

   // Clear out stream information.
   mSamplesPerFrame = 0;
   mSamplesPerSec = 0;
   mCurFrameTime = 0;
   mpTickerNotification = NULL;
   delete[] mpSampleBuffer;
   LOGV("MpodAndroid::disableDevice() Deleted mpSampleBuffer\n");

   // Indicate we are no longer enabled
   mIsEnabled = FALSE;

   return OS_SUCCESS;
}

OsStatus MpodAndroid::pushFrame(unsigned int numSamples,
                                const MpAudioSample* samples,
                                MpFrameTime frameTime)
{
   RTL_BLOCK("MpodAndroid::pushFrame");

   if (!isEnabled())
   {
      return OS_FAILED;
   }

   // Only full frames are supported right now.
//   LOGV("MpodAndroid::pushFrame(numSamples=%d, samples=%p)", numSamples, samples);
   assert((mSamplesPerFrame == numSamples) ||
          (numSamples == 0 && samples== NULL));

   // This pushFrame() is actually just a hack to adopt Android's AudioTrack
   // for use with our driver framework. We know that this function will be
   // called from ticker callback, so we assume that mpSampleBuffer points
   // to a buffer, passed to us by AudioTrack and we can simply memcpy to it.

   // If samples == NULL, then silent (full) frame should be inserted.
   if (samples != NULL)
   {
      // We have data
#ifdef RTL_AUDIO_ENABLED
      RTL_RAW_AUDIO("MpodAndroid_pushFrame", mSamplesPerSec, numSamples, samples,
                    frameTime*(mSamplesPerSec/1000)/mSamplesPerFrame);
#endif

      if (mpSampleBuffer != NULL)
      {
         memcpy(mpSampleBuffer, samples, mSamplesPerFrame*sizeof(MpAudioSample));
      }
   } else {
      // No data, fill with silence
      if (mpSampleBuffer != NULL)
      {
         memset(mpSampleBuffer, 0, mSamplesPerFrame*sizeof(MpAudioSample));
#ifdef RTL_AUDIO_ENABLED
         RTL_RAW_AUDIO("MpodAndroid_pushFrame", mSamplesPerSec, mSamplesPerFrame, mpSampleBuffer,
                       frameTime*(mSamplesPerSec/1000)/mSamplesPerFrame);
#endif
      }
   }

   return OS_SUCCESS;
}

/* ============================ ACCESSORS ================================= */

/* ============================ INQUIRY =================================== */

/* //////////////////////////// PROTECTED ///////////////////////////////// */

UtlBoolean MpodAndroid::initAudioTrack()
{
   LOGV("MpodAndroid::initAudioTrack");
   int /*status_t*/ initRes;

   if (mpAudioTrack) {
      LOGV("MpodAndroid::initAudioTrack deleting mpAudioTrack");
      delete mpAudioTrack;
      LOGV("MpodAndroid::initAudioTrack deleted mpAudioTrack");
      mpAudioTrack = NULL;
   }

   // Open audio track
   mpAudioTrack = MpAndroidAudioTrack::spAudioTrackCreate(mStreamType,  // streamType
                                 mSamplesPerSec,  // sampleRate
                                 AudioSystem::PCM_16_BIT,  // format
#ifdef ANDROID_1_6
                                 1,  // channels
#else
                                 AudioSystem::CHANNEL_OUT_MONO,
#endif
                                 0,  // frameCount
                                 0,  // flags
                                 audioCallback,  // cbf
                                 this,  // user
                                 mSamplesPerFrame);  // notificationFrames
   if (mpAudioTrack == NULL) {
      LOGE("MpodAndroid::initAudioTrack() AudioTrack allocation failed\n");
      goto initAudioTrack_exit;
   }
   mpAudioTrack->dumpAudioTrack("MpodAndroid::initAudioTrack");
   LOGV("MpodAndroid::initAudioTrack() Create Track: %p\n", mpAudioTrack);

   initRes = mpAudioTrack->initCheck();
   if (initRes != NO_ERROR) {
      LOGE("MpodAndroid::initAudioTrack() AudioTrack->initCheck() returned %d\n", initRes);
      goto initAudioTrack_exit;
   }

   LOGV("MpodAndroid::initAudioTrack() AudioTrack->initCheck() returned %d, NO_ERROR=%p\n", initRes, NO_ERROR);
   mpAudioTrack->dumpAudioTrack("MpodAndroid::initAudioTrack after initCheck");
   LOGD("initAudioTrack AudioTrack sampleRate: %d frameSize: %d frameCount: %d latency: %d",
        (int)mpAudioTrack->getSampleRate(), mpAudioTrack->frameSize(), (int)mpAudioTrack->frameCount(), (int)mpAudioTrack->latency());

   mpAudioTrack->setVolume(1.0, 1.0);

   mState = DRIVER_INIT;

   return true;

initAudioTrack_exit:

   // Cleanup
   if (mpAudioTrack) {
      LOGV("Delete Track: %p\n", mpAudioTrack);
      delete mpAudioTrack;
      mpAudioTrack = NULL;
   }

   return false;
}

void MpodAndroid::audioCallback(int event, void* user, void *info)
{
   //LOGV("MpodAndroid::audioCallback(event=%d)\n", event);
   RTL_BLOCK("MpodAndroid::audioCallback");
   bool lSignal = false;
   if (event != MpAndroidAudioTrack::EVENT_MORE_DATA)
   {
      LOGV("MpodAndroid::audioCallback(event=%d)\n", event);
      return;
   }

   MpAndroidAudioTrack::Buffer *buffer = static_cast<MpAndroidAudioTrack::Buffer *>(info);
   MpodAndroid *pDriver = static_cast<MpodAndroid *>(user);

   // Start accessing non-atomic member variables
   AutoMutex autoLock(pDriver->mLock);

   int samplesToCopy = sipx_min(buffer->frameCount,
                                pDriver->mSamplesPerFrame-pDriver->mSampleBufferIndex);
#ifdef ENABLE_FRAME_TIME_LOGGING
   LOGV("MpodAndroid::audioCallback() buffer=%p samples=%d size=%d toCopy=%d\n",
        buffer->i16, buffer->frameCount, buffer->size, samplesToCopy);
#endif
   RTL_EVENT("MpodAndroid::audioCallback_bufsize", samplesToCopy);
   // Copy data to buffer
   memcpy(buffer->i16, pDriver->mpSampleBuffer+pDriver->mSampleBufferIndex, samplesToCopy*sizeof(short));
   buffer->frameCount = samplesToCopy;
   buffer->size = samplesToCopy*sizeof(short);
   pDriver->mSampleBufferIndex += samplesToCopy;

#ifdef ENABLE_FILE_LOGGING
   fwrite(buffer->i16, 1, buffer->frameCount*sizeof(short), sgOutFile);
#endif // ENABLE_FILE_LOGGING

   if (pDriver->mSampleBufferIndex >= pDriver->mSamplesPerFrame)
   {
      RTL_BLOCK("MpodAndroid::audioCallback_tick");
      if(pDriver->mSampleBufferIndex > pDriver->mSamplesPerFrame)
      {
         LOGE("MpodAndroid::audioCallback() sample index (%d) > samples/frame (%d)\n", (int)pDriver->mSampleBufferIndex, (int)pDriver->mSamplesPerFrame);
      }

      // Return index to the beginning
      pDriver->mSampleBufferIndex = 0;

      // Fire callback. It will call our pushFrame() in turn.
#ifdef ENABLE_FRAME_TIME_LOGGING
      LOGV("MpodAndroid::audioCallback() signal ticker, time %"PRIi64"ns\n", systemTime(SYSTEM_TIME_REALTIME));
#endif
      pDriver->mpTickerNotification->signal(pDriver->mSamplesPerFrame);

      // Update frame time.
      pDriver->mCurFrameTime += pDriver->mSamplesPerFrame;
   }

   // Step forward state
   switch (pDriver->mState) {
    case DRIVER_STARTING:
       pDriver->mState = DRIVER_PLAYING;
       lSignal = true;
       break;
    case DRIVER_STOPPING:
//       pDriver->mState = DRIVER_STOPPED;
//       break;
    case DRIVER_STOPPED:
       LOGV("MpodAndroid::audioCallback() stopping Track\n");
       pDriver->mpAudioTrack->stop();
       LOGV("MpodAndroid::audioCallback() stopped Track\n");
       buffer->size = 0;
       pDriver->mState = DRIVER_IDLE;
       lSignal = true;
       break;
    default:
       break;
   }

   if (lSignal)
   {
      LOGV("MpodAndroid::audioCallback signalling\n");
      pDriver->mWaitCbkCond.signal();
      LOGV("MpodAndroid::audioCallback signalled\n");
   }
}

/* //////////////////////////// PRIVATE /////////////////////////////////// */
<|endoftext|>


<commit_before>/*
    This file is part of Akregator.

    Copyright (C) 2004 Stanislav Karchebny <Stanislav.Karchebny@kdemail.net>

    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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "feed.h"
#include "propertiesdialog.h"

#include <kcombobox.h>
#include <klineedit.h>
#include <kpassdlg.h>
#include <klocale.h>
#include <knuminput.h>

#include <qcheckbox.h>
#include <qbuttongroup.h>
#include <qradiobutton.h>

using namespace Akregator;

FeedPropertiesWidget::FeedPropertiesWidget(QWidget *parent, const char *name)
        : FeedPropertiesWidgetBase(parent, name)
{
}

FeedPropertiesWidget::~FeedPropertiesWidget()
{}

void FeedPropertiesWidget::slotUpdateComboBoxActivated( int index )
{
    if ( index == 3 ) // "never"
        updateSpinBox->setEnabled(false);
    else
        updateSpinBox->setEnabled(true);
}

void FeedPropertiesWidget::slotUpdateCheckBoxToggled( bool enabled )
{
    if (enabled && updateComboBox->currentItem() != 3 ) // "never"
        updateSpinBox->setEnabled(true);
    else
        updateSpinBox->setEnabled(false);
}

FeedPropertiesDialog::FeedPropertiesDialog(QWidget *parent, const char *name)
        : KDialogBase(KDialogBase::Swallow, Qt::WStyle_DialogBorder, parent, name, true, i18n("Feed Properties"), KDialogBase::Ok|KDialogBase::Cancel)
{
    widget=new FeedPropertiesWidget(this);
    setMainWidget(widget);
    widget->feedNameEdit->setFocus();

    connect(widget->feedNameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(slotSetCaption(const QString&)));
}

FeedPropertiesDialog::~FeedPropertiesDialog()
{}

void FeedPropertiesDialog::slotOk()
{
     m_feed->setNotificationMode(false);
     m_feed->setTitle( feedName() );
     m_feed->setXmlUrl( url() );
     m_feed->setCustomFetchIntervalEnabled(autoFetch());
     m_feed->setFetchInterval(fetchInterval());
     m_feed->setArchiveMode(archiveMode());
     m_feed->setMaxArticleAge(maxArticleAge());
     m_feed->setMaxArticleNumber(maxArticleNumber());
     m_feed->setMarkImmediatelyAsRead(markImmediatelyAsRead());
     m_feed->setUseNotification(useNotification());
     m_feed->setLoadLinkedWebsite(loadLinkedWebsite());
     m_feed->setNotificationMode(true, true);

     KDialogBase::slotOk();
}

void FeedPropertiesDialog::slotSetCaption(const QString& c)
{
    if(c.isEmpty())
        setCaption(i18n("Feed Properties"));
    else
        setCaption(i18n("Properties of %1").arg(c));

}

void FeedPropertiesDialog::setFeed(Feed* feed)
{
    m_feed = feed;
    if (!feed)
        return;

    setFeedName( feed->title() );
    setUrl( feed->xmlUrl() );
    setAutoFetch(feed->useCustomFetchInterval());
    setFetchInterval(feed->fetchInterval());
    setArchiveMode(feed->archiveMode());
    setMaxArticleAge(feed->maxArticleAge());
    setMaxArticleNumber(feed->maxArticleNumber());
    setMarkImmediatelyAsRead(feed->markImmediatelyAsRead());
    setUseNotification(feed->useNotification());
    setLoadLinkedWebsite(feed->loadLinkedWebsite());
    slotSetCaption(feedName());
}

const QString FeedPropertiesDialog::feedName() const
{
   return widget->feedNameEdit->text();
}

const QString FeedPropertiesDialog::url() const
{
   return widget->urlEdit->text();
}

bool FeedPropertiesDialog::autoFetch() const
{
   return widget->upChkbox->isChecked();
}

int FeedPropertiesDialog::fetchInterval() const
{
    switch (widget->updateComboBox->currentItem() )
    {
        case 0: // minutes
            return widget->updateSpinBox->value();
        case 1: // hours
            return widget->updateSpinBox->value()*60;
        case 2: // days
            return widget->updateSpinBox->value()*60*24;
        default:
            return -1; // never
    }
}

Feed::ArchiveMode FeedPropertiesDialog::archiveMode() const
{
    // i could check the button group's int, but order could change...
    if ( widget->rb_globalDefault->isChecked() )
        return Feed::globalDefault;

   if ( widget->rb_keepAllArticles->isChecked() )
        return Feed::keepAllArticles;

   if ( widget->rb_limitArticleAge->isChecked() )
        return Feed::limitArticleAge;

   if ( widget->rb_limitArticleNumber->isChecked() )
        return Feed::limitArticleNumber;

   if ( widget->rb_disableArchiving->isChecked() )
        return Feed::disableArchiving;

    // in a perfect world, this is never reached

    return Feed::globalDefault;
}

int FeedPropertiesDialog::maxArticleAge() const
{
    return widget->sb_maxArticleAge->value();
}

int FeedPropertiesDialog::maxArticleNumber() const
{
    return widget->sb_maxArticleNumber->value();
}

void FeedPropertiesDialog::setArchiveMode(Feed::ArchiveMode mode)
 {
    switch (mode)
    {
         case Feed::globalDefault:
            widget->rb_globalDefault->setChecked(true);
            break;
         case Feed::keepAllArticles:
            widget->rb_keepAllArticles->setChecked(true);
            break;
         case Feed::disableArchiving:
            widget->rb_disableArchiving->setChecked(true);
            break;
         case Feed::limitArticleAge:
            widget->rb_limitArticleAge->setChecked(true);
            break;
         case Feed::limitArticleNumber:
            widget->rb_limitArticleNumber->setChecked(true);
    }
}
void FeedPropertiesDialog::setFeedName(const QString& title)
{
   widget->feedNameEdit->setText(title);
}

void FeedPropertiesDialog::setUrl(const QString& url)
{
   widget->urlEdit->setText(url);
}

void FeedPropertiesDialog::setAutoFetch(bool w)
{
   widget->upChkbox->setChecked(w);
   widget->updateSpinBox->setEnabled(w);
}

void FeedPropertiesDialog::setFetchInterval(int i)
{
    if (i == -1)
    {
        widget->updateSpinBox->setValue(0);
        widget->updateComboBox->setCurrentItem(3); // never
        return;
    }

    if (i == 0)
    {
        widget->updateSpinBox->setValue(0);
        widget->updateComboBox->setCurrentItem(0); // minutes
        return;
    }

   if (i % (60*24) == 0)
   {
       widget->updateSpinBox->setValue(i / (60*24) );
       widget->updateComboBox->setCurrentItem(2); // days
       return;
   }

   if (i % 60 == 0)
   {
       widget->updateSpinBox->setValue(i / 60 );
       widget->updateComboBox->setCurrentItem(1); // hours
       return;
   }

   widget->updateSpinBox->setValue(i);
   widget->updateComboBox->setCurrentItem(0); // minutes
}

void FeedPropertiesDialog::setMaxArticleAge(int age)
 {
    widget->sb_maxArticleAge->setValue(age);
}

void FeedPropertiesDialog::setMaxArticleNumber(int number)
{
    widget->sb_maxArticleNumber->setValue(number);
}

void FeedPropertiesDialog::setMarkImmediatelyAsRead(bool enabled)
{
    widget->checkBox_markRead->setChecked(enabled);
}

bool FeedPropertiesDialog::markImmediatelyAsRead() const
{
    return widget->checkBox_markRead->isChecked();
}

void FeedPropertiesDialog::setUseNotification(bool enabled)
{
    widget->checkBox_useNotification->setChecked(enabled);
}

bool FeedPropertiesDialog::useNotification() const
{
    return widget->checkBox_useNotification->isChecked();
}

bool FeedPropertiesDialog::loadLinkedWebsite() const
{
    return widget->checkBox_loadWebsite->isChecked();
}

void FeedPropertiesDialog::setLoadLinkedWebsite(bool enabled)
{
    widget->checkBox_loadWebsite->setChecked(enabled);
}

void FeedPropertiesDialog::selectFeedName()
{
   widget->feedNameEdit->selectAll();
}

#include "propertiesdialog.moc"
// vim: ts=4 sw=4 et
<commit_msg>show the global update interval in the (disabled) spinbox when custom update interval is disabled<commit_after>/*
    This file is part of Akregator.

    Copyright (C) 2004 Stanislav Karchebny <Stanislav.Karchebny@kdemail.net>

    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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "akregatorconfig.h"
#include "feed.h"
#include "propertiesdialog.h"

#include <kcombobox.h>
#include <klineedit.h>
#include <kpassdlg.h>
#include <klocale.h>
#include <knuminput.h>

#include <qcheckbox.h>
#include <qbuttongroup.h>
#include <qradiobutton.h>

using namespace Akregator;

FeedPropertiesWidget::FeedPropertiesWidget(QWidget *parent, const char *name)
        : FeedPropertiesWidgetBase(parent, name)
{
}

FeedPropertiesWidget::~FeedPropertiesWidget()
{}

void FeedPropertiesWidget::slotUpdateComboBoxActivated( int index )
{
    if ( index == 3 ) // "never"
        updateSpinBox->setEnabled(false);
    else
        updateSpinBox->setEnabled(true);
}

void FeedPropertiesWidget::slotUpdateCheckBoxToggled( bool enabled )
{
    if (enabled && updateComboBox->currentItem() != 3 ) // "never"
        updateSpinBox->setEnabled(true);
    else
        updateSpinBox->setEnabled(false);
}

FeedPropertiesDialog::FeedPropertiesDialog(QWidget *parent, const char *name)
        : KDialogBase(KDialogBase::Swallow, Qt::WStyle_DialogBorder, parent, name, true, i18n("Feed Properties"), KDialogBase::Ok|KDialogBase::Cancel)
{
    widget=new FeedPropertiesWidget(this);
    setMainWidget(widget);
    widget->feedNameEdit->setFocus();

    connect(widget->feedNameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(slotSetCaption(const QString&)));
}

FeedPropertiesDialog::~FeedPropertiesDialog()
{}

void FeedPropertiesDialog::slotOk()
{
     m_feed->setNotificationMode(false);
     m_feed->setTitle( feedName() );
     m_feed->setXmlUrl( url() );
     m_feed->setCustomFetchIntervalEnabled(autoFetch());
     if (autoFetch())
        m_feed->setFetchInterval(fetchInterval());
     m_feed->setArchiveMode(archiveMode());
     m_feed->setMaxArticleAge(maxArticleAge());
     m_feed->setMaxArticleNumber(maxArticleNumber());
     m_feed->setMarkImmediatelyAsRead(markImmediatelyAsRead());
     m_feed->setUseNotification(useNotification());
     m_feed->setLoadLinkedWebsite(loadLinkedWebsite());
     m_feed->setNotificationMode(true, true);

     KDialogBase::slotOk();
}

void FeedPropertiesDialog::slotSetCaption(const QString& c)
{
    if(c.isEmpty())
        setCaption(i18n("Feed Properties"));
    else
        setCaption(i18n("Properties of %1").arg(c));

}

void FeedPropertiesDialog::setFeed(Feed* feed)
{
    m_feed = feed;
    if (!feed)
        return;

    setFeedName( feed->title() );
    setUrl( feed->xmlUrl() );
    setAutoFetch(feed->useCustomFetchInterval());
    if (feed->useCustomFetchInterval())
        setFetchInterval(feed->fetchInterval());
    else
        setFetchInterval(Settings::autoFetchInterval());
    setArchiveMode(feed->archiveMode());
    setMaxArticleAge(feed->maxArticleAge());
    setMaxArticleNumber(feed->maxArticleNumber());
    setMarkImmediatelyAsRead(feed->markImmediatelyAsRead());
    setUseNotification(feed->useNotification());
    setLoadLinkedWebsite(feed->loadLinkedWebsite());
    slotSetCaption(feedName());
}

const QString FeedPropertiesDialog::feedName() const
{
   return widget->feedNameEdit->text();
}

const QString FeedPropertiesDialog::url() const
{
   return widget->urlEdit->text();
}

bool FeedPropertiesDialog::autoFetch() const
{
   return widget->upChkbox->isChecked();
}

int FeedPropertiesDialog::fetchInterval() const
{
    switch (widget->updateComboBox->currentItem() )
    {
        case 0: // minutes
            return widget->updateSpinBox->value();
        case 1: // hours
            return widget->updateSpinBox->value()*60;
        case 2: // days
            return widget->updateSpinBox->value()*60*24;
        default:
            return -1; // never
    }
}

Feed::ArchiveMode FeedPropertiesDialog::archiveMode() const
{
    // i could check the button group's int, but order could change...
    if ( widget->rb_globalDefault->isChecked() )
        return Feed::globalDefault;

   if ( widget->rb_keepAllArticles->isChecked() )
        return Feed::keepAllArticles;

   if ( widget->rb_limitArticleAge->isChecked() )
        return Feed::limitArticleAge;

   if ( widget->rb_limitArticleNumber->isChecked() )
        return Feed::limitArticleNumber;

   if ( widget->rb_disableArchiving->isChecked() )
        return Feed::disableArchiving;

    // in a perfect world, this is never reached

    return Feed::globalDefault;
}

int FeedPropertiesDialog::maxArticleAge() const
{
    return widget->sb_maxArticleAge->value();
}

int FeedPropertiesDialog::maxArticleNumber() const
{
    return widget->sb_maxArticleNumber->value();
}

void FeedPropertiesDialog::setArchiveMode(Feed::ArchiveMode mode)
 {
    switch (mode)
    {
         case Feed::globalDefault:
            widget->rb_globalDefault->setChecked(true);
            break;
         case Feed::keepAllArticles:
            widget->rb_keepAllArticles->setChecked(true);
            break;
         case Feed::disableArchiving:
            widget->rb_disableArchiving->setChecked(true);
            break;
         case Feed::limitArticleAge:
            widget->rb_limitArticleAge->setChecked(true);
            break;
         case Feed::limitArticleNumber:
            widget->rb_limitArticleNumber->setChecked(true);
    }
}
void FeedPropertiesDialog::setFeedName(const QString& title)
{
   widget->feedNameEdit->setText(title);
}

void FeedPropertiesDialog::setUrl(const QString& url)
{
   widget->urlEdit->setText(url);
}

void FeedPropertiesDialog::setAutoFetch(bool w)
{
   widget->upChkbox->setChecked(w);
   widget->updateSpinBox->setEnabled(w);
}

void FeedPropertiesDialog::setFetchInterval(int i)
{
    if (i == -1)
    {
        widget->updateSpinBox->setValue(0);
        widget->updateComboBox->setCurrentItem(3); // never
        return;
    }

    if (i == 0)
    {
        widget->updateSpinBox->setValue(0);
        widget->updateComboBox->setCurrentItem(0); // minutes
        return;
    }

   if (i % (60*24) == 0)
   {
       widget->updateSpinBox->setValue(i / (60*24) );
       widget->updateComboBox->setCurrentItem(2); // days
       return;
   }

   if (i % 60 == 0)
   {
       widget->updateSpinBox->setValue(i / 60 );
       widget->updateComboBox->setCurrentItem(1); // hours
       return;
   }

   widget->updateSpinBox->setValue(i);
   widget->updateComboBox->setCurrentItem(0); // minutes
}

void FeedPropertiesDialog::setMaxArticleAge(int age)
 {
    widget->sb_maxArticleAge->setValue(age);
}

void FeedPropertiesDialog::setMaxArticleNumber(int number)
{
    widget->sb_maxArticleNumber->setValue(number);
}

void FeedPropertiesDialog::setMarkImmediatelyAsRead(bool enabled)
{
    widget->checkBox_markRead->setChecked(enabled);
}

bool FeedPropertiesDialog::markImmediatelyAsRead() const
{
    return widget->checkBox_markRead->isChecked();
}

void FeedPropertiesDialog::setUseNotification(bool enabled)
{
    widget->checkBox_useNotification->setChecked(enabled);
}

bool FeedPropertiesDialog::useNotification() const
{
    return widget->checkBox_useNotification->isChecked();
}

bool FeedPropertiesDialog::loadLinkedWebsite() const
{
    return widget->checkBox_loadWebsite->isChecked();
}

void FeedPropertiesDialog::setLoadLinkedWebsite(bool enabled)
{
    widget->checkBox_loadWebsite->setChecked(enabled);
}

void FeedPropertiesDialog::selectFeedName()
{
   widget->feedNameEdit->selectAll();
}

#include "propertiesdialog.moc"
// vim: ts=4 sw=4 et
<|endoftext|>


<commit_before>/*
	This file is part of cpp-ethereum.

	cpp-ethereum 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 3 of the License, or
	(at your option) any later version.

	cpp-ethereum 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 cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file main.cpp
 * @author Yann yann@ethdev.com
 * @date 2014
 * Ethereum IDE client.
 */

#include <iostream>
#include <stdlib.h>
#include "MixApplication.h"
#include "Exceptions.h"
using namespace dev::mix;

int main(int _argc, char* _argv[])
{
#if __linux
	//work around ubuntu appmenu-qt5 bug
	//https://bugs.launchpad.net/ubuntu/+source/appmenu-qt5/+bug/1323853
	putenv("QT_QPA_PLATFORMTHEME=");
#endif

	try
	{
		MixApplication app(_argc, _argv);
		return app.exec();
	}
	catch (boost::exception const& _e)
	{
		std::cerr << boost::diagnostic_information(_e);
	}
	catch (std::exception const& _e)
	{
		std::cerr << _e.what();
	}
}
<commit_msg>fixed warning<commit_after>/*
	This file is part of cpp-ethereum.

	cpp-ethereum 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 3 of the License, or
	(at your option) any later version.

	cpp-ethereum 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 cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file main.cpp
 * @author Yann yann@ethdev.com
 * @date 2014
 * Ethereum IDE client.
 */

#include <iostream>
#include <stdlib.h>
#include "MixApplication.h"
#include "Exceptions.h"
using namespace dev::mix;

int main(int _argc, char* _argv[])
{
#if __linux
	//work around ubuntu appmenu-qt5 bug
	//https://bugs.launchpad.net/ubuntu/+source/appmenu-qt5/+bug/1323853
	putenv((char*)"QT_QPA_PLATFORMTHEME=");
#endif

	try
	{
		MixApplication app(_argc, _argv);
		return app.exec();
	}
	catch (boost::exception const& _e)
	{
		std::cerr << boost::diagnostic_information(_e);
	}
	catch (std::exception const& _e)
	{
		std::cerr << _e.what();
	}
}
<|endoftext|>