<commit_before>#include <stdio.h>
#include "../SynCommonLib/RelationsIterator.h"
#include "../common/SyntaxHolder.h"

void GetAnanlytForms(const CSentence& Sentence, string& Res)
{
    for( int WordNo = 0; WordNo<Sentence.m_Words.size(); WordNo++ )
    {
       const CSynWord& W = Sentence.m_Words[WordNo];
       if (!W.m_MainVerbs.empty())
        {
            Res += string("\t<analyt> ")+  W.m_strWord.c_str();
            for (size_t i=0; i< W.m_MainVerbs.size(); i++)
		    {
                Res += string(" ") + Sentence.m_Words[W.m_MainVerbs[i]].m_strWord;

			    const CSynWord& W_1 = Sentence.m_Words[W.m_MainVerbs[i]];
			    for (size_t j=0; j< W_1.m_MainVerbs.size(); j++)
				    Res += string(" ") + Sentence.m_Words[W_1.m_MainVerbs[j]].m_strWord;
		    };
            Res += "</analyt>\n";
       }
    }
}
string GetWords(const CSentence& Sentence, const CPeriod& P)
{
    string S;
    for (int WordNo = P.m_iFirstWord; WordNo <= P.m_iLastWord; WordNo++)
    {
        S += Sentence.m_Words[WordNo].m_strWord;
        if (WordNo < P.m_iLastWord)
            S += " ";
    };
    return S;
}

void GetGroups(const CSentence& Sentence, const CAgramtab& A, string& Res)
{
    int nClausesCount = Sentence.GetClausesCount();

    for( int ClauseNo = 0; ClauseNo<nClausesCount; ClauseNo++ )
    {
        const CClause& Clause = Sentence.GetClause(ClauseNo);
        int nCvar = Clause.m_SynVariants.size();

        if (Clause.m_SynVariants.empty()) continue;

        int nVmax = Clause.m_SynVariants.begin()->m_iWeight;
        for( CSVI pSynVar=Clause.m_SynVariants.begin(); pSynVar != Clause.m_SynVariants.end(); pSynVar++ )
        {
            if( pSynVar->m_iWeight < nVmax ) break;

            const CMorphVariant& V = *pSynVar;
            Res += Format("\t<synvar>\n");

            // print the clause
            {
                int ClauseType = (V.m_ClauseTypeNo == -1) ? UnknownSyntaxElement  :  Clause.m_vectorTypes[V.m_ClauseTypeNo].m_Type;;
                string Type;
                if (ClauseType != UnknownSyntaxElement)
                    Type = (const char*)A.GetClauseNameByType(ClauseType);
                else
                    Type = "EMPTY";
                Res += Format("\t\t<clause type=\"%s\">%s</clause>\n", Type.c_str(), GetWords(Sentence, Clause).c_str());
            }

            for (int GroupNo = 0; GroupNo < V.m_vectorGroups.GetGroups().size(); GroupNo++)
            {
                const CGroup& G  = V.m_vectorGroups.GetGroups()[GroupNo];
                Res += Format("\t\t<group type=\"%s\">%s</group>\n",
                    Sentence.GetOpt()->GetGroupNameByIndex(G.m_GroupType),
                    GetWords(Sentence, G).c_str());
            };
            Res += Format("\t</synvar>\n");
        }
    }

}

string GetNodeStr(const CSentence& Sentence, const CRelationsIterator& RelIt, int GroupNo, int WordNo)
{
    if (GroupNo != -1)
        return GetWords(Sentence, RelIt.GetFirmGroups()[GroupNo]);
    else
        return Sentence.m_Words[WordNo].m_strWord;
}

void GetRelations(const CSentence& Sentence, string& Result)
{
    CRelationsIterator RelIt;
	RelIt.SetSentence(&Sentence);
    for( int i = 0; i<Sentence.m_vectorPrClauseNo.size(); i++ )
		RelIt.AddClauseNoAndVariantNo(Sentence.m_vectorPrClauseNo[i], 0);
    RelIt.BuildRelations();
   	for(long RelNo = 0 ; RelNo < RelIt.GetRelations().size() ; RelNo++ )
	{
		const CSynOutputRelation& piRel = RelIt.GetRelations()[RelNo];
		string RelName = Sentence.GetOpt()->GetGroupNameByIndex(piRel.m_Relation.type);
        string Src = GetNodeStr(Sentence, RelIt,piRel.m_iSourceGroup, piRel.m_Relation.m_iFirstWord);
        string Trg = GetNodeStr(Sentence, RelIt,piRel.m_iTargetGroup, piRel.m_Relation.m_iLastWord);
        string GramRel = Sentence.GetOpt()->GetGramTab()->GrammemsToStr(piRel.m_Relation.m_iGrammems);
        Result += Format("\t<rel name=\"%s\" gram=\"%s\"> %s -> %s </rel>\n", RelName.c_str(), GramRel.c_str(), Src.c_str(),  Trg.c_str() );
    }
}

string GetStringBySyntax(const CSentencesCollection& SC, const CAgramtab& A, string input)
{
    string Result;
    Result += Format("<chunk>\n");
    Result += Format("<input>%s</input>\n",input.c_str());
    for (size_t nSent=0;  nSent < SC.m_vectorSents.size(); nSent++)
    {
	    const CSentence& Sentence = *SC.m_vectorSents[nSent];
	    int iWord=0,iClau=0,iCvar=0;
        Result += "<sent>\n";
        GetAnanlytForms(Sentence, Result);
        GetGroups(Sentence, A, Result);
        GetRelations(Sentence, Result);
        Result += "</sent>\n";
    }
    Result += Format("</chunk>\n");

    fprintf (stderr, "sentences count: %i\n", SC.m_vectorSents.size());
	return Result;
};

void PrintUsage()
{
		printf ("Dialing DWDS Command Line Syntax Parser(www.aot.ru, www.dwds.de)\n");
		printf ("Usage: TestSynan (RUSSIAN|GERMAN) [filename.txt] - \n");
		printf ("Example: TestSynan Russian\n");
		exit(1);
};

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

	MorphLanguageEnum langua = morphUnknown;
    string  FileName;
	for (size_t i=1; i<argc; i++)
	{
		string s = argv[i];
		EngMakeLower(s);
		if (		(s == "-help")
				||	(s == "--help")
				||	(s == "/?")
			)
			PrintUsage();
        else {
            if (langua == morphUnknown) {
                if (!GetLanguageByString(s, langua))
                        PrintUsage();
            }
            else {
                FileName = argv[i];
                if (!FileExists(FileName.c_str()))
                {
                    fprintf (stderr, "cannot open file %s\n",  FileName.c_str());
                    exit(1);
                }
            }
        }

    }
	if ((langua == morphUnknown)) PrintUsage();

	CSyntaxHolder H;

	if (!H.LoadSyntax(langua))
	{
		fprintf (stderr, "initialization error\n");
		return 1;
	};

	fprintf (stderr, "ok\n");
    if (!FileName.empty())
    {
        vector<string> Files;
        if ((FileName.length() > 4) && FileName.substr(FileName.length() -4) == ".lst")
        {
            FILE* fp = fopen(FileName.c_str(), "r");
            if (!fp)
            {
                fprintf( stderr, "cannot open %s\n", FileName.c_str());
                return 1;
            }
            char buffer[1024];
            while (fgets (buffer, 1024, fp))
            {
                rtrim (buffer);
                Files.push_back(buffer);
            }
            fclose (fp);

        }
        else
            Files.push_back(FileName);
        for (size_t i=0; i < Files.size(); i++)
        {
            fprintf( stderr, "File %s\n", Files[i].c_str());
            fflush (stderr);
            H.m_bTimeStatis = true;
            H.GetSentencesFromSynAn(Files[i], true);
	    	string s = GetStringBySyntax(H.m_Synan, *H.m_pGramTab, Files[i].c_str());
		    printf  ("%s\n\n", s.c_str());
        }
        return 0;
    }

	// ===============  WORKING ===============
    char buffer[10000] ;
	while  (fgets(buffer, 10000, stdin))
	{
		string s = buffer;
		Trim(s);
		if (s.empty()) continue;

		H.GetSentencesFromSynAn(s, false);
		s = GetStringBySyntax(H.m_Synan, *H.m_pGramTab, s);
		printf  ("%s", s.c_str());
        fflush(stdout);
	};
}
catch(...)
{
 	fprintf (stderr, "an exception occurred!\n");
	return 1;
};

	return 0;
};

<commit_msg>output gram info<commit_after>#include <stdio.h>
#include "../SynCommonLib/RelationsIterator.h"
#include "../common/SyntaxHolder.h"

void GetAnanlytForms(const CSentence& Sentence, string& Res)
{
    for( int WordNo = 0; WordNo<Sentence.m_Words.size(); WordNo++ )
    {
       const CSynWord& W = Sentence.m_Words[WordNo];
       if (!W.m_MainVerbs.empty())
        {
            Res += string("\t<analyt> ")+  W.m_strWord.c_str();
            for (size_t i=0; i< W.m_MainVerbs.size(); i++)
		    {
                Res += string(" ") + Sentence.m_Words[W.m_MainVerbs[i]].m_strWord;

			    const CSynWord& W_1 = Sentence.m_Words[W.m_MainVerbs[i]];
			    for (size_t j=0; j< W_1.m_MainVerbs.size(); j++)
				    Res += string(" ") + Sentence.m_Words[W_1.m_MainVerbs[j]].m_strWord;
		    };
            Res += "</analyt>\n";
       }
    }
}
string GetWords(const CSentence& Sentence, const CPeriod& P)
{
    string S;
    for (int WordNo = P.m_iFirstWord; WordNo <= P.m_iLastWord; WordNo++)
    {
        S += Sentence.m_Words[WordNo].m_strWord;
        if (WordNo < P.m_iLastWord)
            S += " ";
    };
    return S;
}

void GetGroups(const CSentence& Sentence, const CAgramtab& A, string& Res)
{
    int nClausesCount = Sentence.GetClausesCount();

    for( int ClauseNo = 0; ClauseNo<nClausesCount; ClauseNo++ )
    {
        const CClause& Clause = Sentence.GetClause(ClauseNo);
        int nCvar = Clause.m_SynVariants.size();

        if (Clause.m_SynVariants.empty()) continue;

        int nVmax = Clause.m_SynVariants.begin()->m_iWeight;
        for( CSVI pSynVar=Clause.m_SynVariants.begin(); pSynVar != Clause.m_SynVariants.end(); pSynVar++ )
        {
            if( pSynVar->m_iWeight < nVmax ) break;

            const CMorphVariant& V = *pSynVar;
            Res += Format("\t<synvar>\n");

            // print the clause
            {
                int ClauseType = (V.m_ClauseTypeNo == -1) ? UnknownSyntaxElement  :  Clause.m_vectorTypes[V.m_ClauseTypeNo].m_Type;;
                string Type;
                if (ClauseType != UnknownSyntaxElement)
                    Type = (const char*)A.GetClauseNameByType(ClauseType);
                else
                    Type = "EMPTY";
                Res += Format("\t\t<clause type=\"%s\">%s</clause>\n", Type.c_str(), GetWords(Sentence, Clause).c_str());
            }

            for (int GroupNo = 0; GroupNo < V.m_vectorGroups.GetGroups().size(); GroupNo++)
            {
                const CGroup& G  = V.m_vectorGroups.GetGroups()[GroupNo];
                Res += Format("\t\t<group type=\"%s\">%s</group>\n",
                    Sentence.GetOpt()->GetGroupNameByIndex(G.m_GroupType),
                    GetWords(Sentence, G).c_str());
            };
            Res += Format("\t</synvar>\n");
        }
    }

}

string GetNodeStr(const CSentence& Sentence, const CRelationsIterator& RelIt, int GroupNo, int WordNo)
{
    if (GroupNo != -1)
        return GetWords(Sentence, RelIt.GetFirmGroups()[GroupNo]);
    else
        return Sentence.m_Words[WordNo].m_strWord;
}

string GetNodeGrmStr(const CSentence& Sentence, const CRelationsIterator& RelIt, int GroupNo, int WordNo, string& Lemma)
{
    Lemma =  "";
    if (GroupNo != -1)
        return "";
    else {
        size_t ClauseNo = Sentence.GetMinClauseByWordNo(WordNo);
        const CClause& Clause = Sentence.GetClause(ClauseNo);
        const CMorphVariant* pSynVar  = &*Clause.GetSynVariantByNo(0);
        int UnitNo = pSynVar->UnitNoByWordNo(WordNo);
        const CSynUnit& U = pSynVar->m_SynUnits[UnitNo];
        Lemma = Sentence.GetWords()[WordNo].GetHomonym(U.m_iHomonymNum)->m_strLemma;
        return Sentence.GetOpt()->GetGramTab()->GrammemsToStr(U.m_iGrammems|U.m_TypeGrammems);
    }
}

void GetRelations(const CSentence& Sentence, string& Result)
{
    CRelationsIterator RelIt;
	RelIt.SetSentence(&Sentence);
    for( int i = 0; i<Sentence.m_vectorPrClauseNo.size(); i++ )
		RelIt.AddClauseNoAndVariantNo(Sentence.m_vectorPrClauseNo[i], 0);
    RelIt.BuildRelations();
   	for(long RelNo = 0 ; RelNo < RelIt.GetRelations().size() ; RelNo++ )
	{
		const CSynOutputRelation& piRel = RelIt.GetRelations()[RelNo];
		string RelName = Sentence.GetOpt()->GetGroupNameByIndex(piRel.m_Relation.type);
        string Src = GetNodeStr(Sentence, RelIt,piRel.m_iSourceGroup, piRel.m_Relation.m_iFirstWord);
        string Trg = GetNodeStr(Sentence, RelIt,piRel.m_iTargetGroup, piRel.m_Relation.m_iLastWord);
        string SrcLemma, TrgLemma;
        string SrcGrm = GetNodeGrmStr(Sentence, RelIt,piRel.m_iSourceGroup, piRel.m_Relation.m_iFirstWord, SrcLemma);
        string TrgGrm = GetNodeGrmStr(Sentence, RelIt,piRel.m_iTargetGroup, piRel.m_Relation.m_iLastWord, TrgLemma);
        string GramRel = Sentence.GetOpt()->GetGramTab()->GrammemsToStr(piRel.m_Relation.m_iGrammems);

        Result += Format("\t<rel name=\"%s\" gramrel=\"%s\" lemmprnt=\"%s\" grmprnt=\"%s\" lemmchld=\"%s\" grmchld=\"%s\" > %s -> %s </rel>\n",
            RelName.c_str(), GramRel.c_str(), SrcLemma.c_str(), SrcGrm.c_str(), TrgLemma.c_str(), TrgGrm.c_str(), Src.c_str(),  Trg.c_str() );
    }
}

string GetStringBySyntax(const CSentencesCollection& SC, const CAgramtab& A, string input)
{
    string Result;
    Result += Format("<chunk>\n");
    Result += Format("<input>%s</input>\n",input.c_str());
    for (size_t nSent=0;  nSent < SC.m_vectorSents.size(); nSent++)
    {
	    const CSentence& Sentence = *SC.m_vectorSents[nSent];
	    int iWord=0,iClau=0,iCvar=0;
        Result += "<sent>\n";
        GetAnanlytForms(Sentence, Result);
        GetGroups(Sentence, A, Result);
        GetRelations(Sentence, Result);
        Result += "</sent>\n";
    }
    Result += Format("</chunk>\n");

    fprintf (stderr, "sentences count: %i\n", SC.m_vectorSents.size());
	return Result;
};

void PrintUsage()
{
		printf ("Dialing DWDS Command Line Syntax Parser(www.aot.ru, www.dwds.de)\n");
		printf ("Usage: TestSynan (RUSSIAN|GERMAN) [filename.txt] - \n");
		printf ("Example: TestSynan Russian\n");
		exit(1);
};

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

	MorphLanguageEnum langua = morphUnknown;
    string  FileName;
	for (size_t i=1; i<argc; i++)
	{
		string s = argv[i];
		EngMakeLower(s);
		if (		(s == "-help")
				||	(s == "--help")
				||	(s == "/?")
			)
			PrintUsage();
        else {
            if (langua == morphUnknown) {
                if (!GetLanguageByString(s, langua))
                        PrintUsage();
            }
            else {
                FileName = argv[i];
                if (!FileExists(FileName.c_str()))
                {
                    fprintf (stderr, "cannot open file %s\n",  FileName.c_str());
                    exit(1);
                }
            }
        }

    }
	if ((langua == morphUnknown)) PrintUsage();

	CSyntaxHolder H;

	if (!H.LoadSyntax(langua))
	{
		fprintf (stderr, "initialization error\n");
		return 1;
	};

	fprintf (stderr, "ok\n");
    if (!FileName.empty())
    {
        vector<string> Files;
        if ((FileName.length() > 4) && FileName.substr(FileName.length() -4) == ".lst")
        {
            FILE* fp = fopen(FileName.c_str(), "r");
            if (!fp)
            {
                fprintf( stderr, "cannot open %s\n", FileName.c_str());
                return 1;
            }
            char buffer[1024];
            while (fgets (buffer, 1024, fp))
            {
                rtrim (buffer);
                Files.push_back(buffer);
            }
            fclose (fp);

        }
        else
            Files.push_back(FileName);
        for (size_t i=0; i < Files.size(); i++)
        {
            fprintf( stderr, "File %s\n", Files[i].c_str());
            fflush (stderr);
            H.m_bTimeStatis = true;
            H.GetSentencesFromSynAn(Files[i], true);
	    	string s = GetStringBySyntax(H.m_Synan, *H.m_pGramTab, Files[i].c_str());
		    printf  ("%s\n\n", s.c_str());
        }
        return 0;
    }

	// ===============  WORKING ===============
    char buffer[10000] ;
	while  (fgets(buffer, 10000, stdin))
	{
		string s = buffer;
		Trim(s);
		if (s.empty()) continue;

		H.GetSentencesFromSynAn(s, false);
		s = GetStringBySyntax(H.m_Synan, *H.m_pGramTab, s);
		printf  ("%s", s.c_str());
        fflush(stdout);
	};
}
catch(...)
{
 	fprintf (stderr, "an exception occurred!\n");
	return 1;
};

	return 0;
};

<|endoftext|>


<commit_before>#include "WebPage.h"
#include "JavascriptInvocation.h"
#include "NetworkAccessManager.h"
#include "NetworkCookieJar.h"
#include "UnsupportedContentHandler.h"
#include <QResource>
#include <QtNetwork>
#include <iostream>

WebPage::WebPage(QObject *parent) : QWebPage(parent) {
  setForwardUnsupportedContent(true);
  loadJavascript();
  setUserStylesheet();

  m_loading = false;
  this->setCustomNetworkAccessManager();

  connect(this, SIGNAL(loadStarted()), this, SLOT(loadStarted()));
  connect(this, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool)));
  connect(this, SIGNAL(frameCreated(QWebFrame *)),
          this, SLOT(frameCreated(QWebFrame *)));
  connect(this, SIGNAL(unsupportedContent(QNetworkReply*)),
      this, SLOT(handleUnsupportedContent(QNetworkReply*)));
  this->setViewportSize(QSize(1680, 1050));
}

void WebPage::setCustomNetworkAccessManager() {
  NetworkAccessManager *manager = new NetworkAccessManager();
  manager->setCookieJar(new NetworkCookieJar());
  this->setNetworkAccessManager(manager);
  connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(replyFinished(QNetworkReply *)));
  connect(manager, SIGNAL(sslErrors(QNetworkReply *, QList<QSslError>)), this, SLOT(ignoreSslErrors(QNetworkReply *, QList<QSslError>)));
}

void WebPage::loadJavascript() {
  QResource javascript(":/capybara.js");
  if (javascript.isCompressed()) {
    QByteArray uncompressedBytes(qUncompress(javascript.data(), javascript.size()));
    m_capybaraJavascript = QString(uncompressedBytes);
  } else {
    char * javascriptString =  new char[javascript.size() + 1];
    strcpy(javascriptString, (const char *)javascript.data());
    javascriptString[javascript.size()] = 0;
    m_capybaraJavascript = javascriptString;
  }
}

void WebPage::setUserStylesheet() {
  QString data = QString("* { font-family: 'Arial' ! important; }").toUtf8().toBase64();
  QUrl url = QUrl(QString("data:text/css;charset=utf-8;base64,") + data);
  settings()->setUserStyleSheetUrl(url);
}

QString WebPage::userAgentForUrl(const QUrl &url ) const {
  if (!m_userAgent.isEmpty()) {
    return m_userAgent;
  } else {
    return QWebPage::userAgentForUrl(url);
  }
}

QString WebPage::consoleMessages() {
  return m_consoleMessages.join("\n");
}

void WebPage::setUserAgent(QString userAgent) {
  m_userAgent = userAgent;
}

void WebPage::frameCreated(QWebFrame * frame) {
  connect(frame, SIGNAL(javaScriptWindowObjectCleared()),
          this,  SLOT(injectJavascriptHelpers()));
}

void WebPage::injectJavascriptHelpers() {
  QWebFrame* frame = qobject_cast<QWebFrame *>(QObject::sender());
  frame->evaluateJavaScript(m_capybaraJavascript);
}

bool WebPage::shouldInterruptJavaScript() {
  return false;
}

QVariant WebPage::invokeCapybaraFunction(const char *name, QStringList &arguments) {
  QString qname(name);
  QString objectName("CapybaraInvocation");
  JavascriptInvocation invocation(qname, arguments);
  currentFrame()->addToJavaScriptWindowObject(objectName, &invocation);
  QString javascript = QString("Capybara.invoke()");
  return currentFrame()->evaluateJavaScript(javascript);
}

QVariant WebPage::invokeCapybaraFunction(QString &name, QStringList &arguments) {
  return invokeCapybaraFunction(name.toAscii().data(), arguments);
}

void WebPage::javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID) {
  QString fullMessage = QString::number(lineNumber) + "|" + message;
  if (!sourceID.isEmpty())
    fullMessage = sourceID + "|" + fullMessage;
  m_consoleMessages.append(fullMessage);
  std::cout << qPrintable(fullMessage) << std::endl;
}

void WebPage::javaScriptAlert(QWebFrame *frame, const QString &message) {
  Q_UNUSED(frame);
  std::cout << "ALERT: " << qPrintable(message) << std::endl;
}

bool WebPage::javaScriptConfirm(QWebFrame *frame, const QString &message) {
  Q_UNUSED(frame);
  Q_UNUSED(message);
  return true;
}

bool WebPage::javaScriptPrompt(QWebFrame *frame, const QString &message, const QString &defaultValue, QString *result) {
  Q_UNUSED(frame)
  Q_UNUSED(message)
  Q_UNUSED(defaultValue)
  Q_UNUSED(result)
  return false;
}

void WebPage::loadStarted() {
  m_loading = true;
}

void WebPage::loadFinished(bool success) {
  m_loading = false;
  emit pageFinished(success);
}

bool WebPage::isLoading() const {
  return m_loading;
}

QString WebPage::failureString() {
  return QString("Unable to load URL: ") + currentFrame()->requestedUrl().toString();
}

bool WebPage::render(const QString &fileName) {
  QFileInfo fileInfo(fileName);
  QDir dir;
  dir.mkpath(fileInfo.absolutePath());

  QSize viewportSize = this->viewportSize();
  QSize pageSize = this->mainFrame()->contentsSize();
  if (pageSize.isEmpty()) {
    return false;
  }

  QImage buffer(pageSize, QImage::Format_ARGB32);
  buffer.fill(qRgba(255, 255, 255, 0));

  QPainter p(&buffer);
  p.setRenderHint( QPainter::Antialiasing,          true);
  p.setRenderHint( QPainter::TextAntialiasing,      true);
  p.setRenderHint( QPainter::SmoothPixmapTransform, true);

  this->setViewportSize(pageSize);
  this->mainFrame()->render(&p);
  p.end();
  this->setViewportSize(viewportSize);

  return buffer.save(fileName);
}

QString WebPage::chooseFile(QWebFrame *parentFrame, const QString &suggestedFile) {
  Q_UNUSED(parentFrame);
  Q_UNUSED(suggestedFile);

  return getLastAttachedFileName();
}

bool WebPage::extension(Extension extension, const ExtensionOption *option, ExtensionReturn *output) {
  Q_UNUSED(option);
  if (extension == ChooseMultipleFilesExtension) {
    QStringList names = QStringList() << getLastAttachedFileName();
    static_cast<ChooseMultipleFilesExtensionReturn*>(output)->fileNames = names;
    return true;
  }
  return false;
}

QString WebPage::getLastAttachedFileName() {
  return currentFrame()->evaluateJavaScript(QString("Capybara.lastAttachedFile")).toString();
}

void WebPage::replyFinished(QNetworkReply *reply) {
  if (reply->url() == this->currentFrame()->url()) {
    QStringList headers;
    m_lastStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    QList<QByteArray> list = reply->rawHeaderList();

    int length = list.size();
    for(int i = 0; i < length; i++) {
      headers << list.at(i)+": "+reply->rawHeader(list.at(i));
    }

    m_pageHeaders = headers.join("\n");
  }
}

void WebPage::ignoreSslErrors(QNetworkReply *reply, const QList<QSslError> &errors) {
  if (m_ignoreSslErrors)
    reply->ignoreSslErrors(errors);
}

void WebPage::setIgnoreSslErrors(bool ignore) {
  m_ignoreSslErrors = ignore;
}

bool WebPage::ignoreSslErrors() {
  return m_ignoreSslErrors;
}

int WebPage::getLastStatus() {
  return m_lastStatus;
}

void WebPage::resetResponseHeaders() {
  m_lastStatus = 0;
  m_pageHeaders = QString();
}

void WebPage::resetConsoleMessages() {
  m_consoleMessages.clear();
}

QString WebPage::pageHeaders() {
  return m_pageHeaders;
}

void WebPage::handleUnsupportedContent(QNetworkReply *reply) {
  UnsupportedContentHandler *handler = new UnsupportedContentHandler(this, reply);
  Q_UNUSED(handler);
}
<commit_msg>Move the include to a header file<commit_after>#include "WebPage.h"
#include "JavascriptInvocation.h"
#include "NetworkAccessManager.h"
#include "NetworkCookieJar.h"
#include "UnsupportedContentHandler.h"
#include <QResource>
#include <iostream>

WebPage::WebPage(QObject *parent) : QWebPage(parent) {
  setForwardUnsupportedContent(true);
  loadJavascript();
  setUserStylesheet();

  m_loading = false;
  this->setCustomNetworkAccessManager();

  connect(this, SIGNAL(loadStarted()), this, SLOT(loadStarted()));
  connect(this, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool)));
  connect(this, SIGNAL(frameCreated(QWebFrame *)),
          this, SLOT(frameCreated(QWebFrame *)));
  connect(this, SIGNAL(unsupportedContent(QNetworkReply*)),
      this, SLOT(handleUnsupportedContent(QNetworkReply*)));
  this->setViewportSize(QSize(1680, 1050));
}

void WebPage::setCustomNetworkAccessManager() {
  NetworkAccessManager *manager = new NetworkAccessManager();
  manager->setCookieJar(new NetworkCookieJar());
  this->setNetworkAccessManager(manager);
  connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(replyFinished(QNetworkReply *)));
  connect(manager, SIGNAL(sslErrors(QNetworkReply *, QList<QSslError>)), this, SLOT(ignoreSslErrors(QNetworkReply *, QList<QSslError>)));
}

void WebPage::loadJavascript() {
  QResource javascript(":/capybara.js");
  if (javascript.isCompressed()) {
    QByteArray uncompressedBytes(qUncompress(javascript.data(), javascript.size()));
    m_capybaraJavascript = QString(uncompressedBytes);
  } else {
    char * javascriptString =  new char[javascript.size() + 1];
    strcpy(javascriptString, (const char *)javascript.data());
    javascriptString[javascript.size()] = 0;
    m_capybaraJavascript = javascriptString;
  }
}

void WebPage::setUserStylesheet() {
  QString data = QString("* { font-family: 'Arial' ! important; }").toUtf8().toBase64();
  QUrl url = QUrl(QString("data:text/css;charset=utf-8;base64,") + data);
  settings()->setUserStyleSheetUrl(url);
}

QString WebPage::userAgentForUrl(const QUrl &url ) const {
  if (!m_userAgent.isEmpty()) {
    return m_userAgent;
  } else {
    return QWebPage::userAgentForUrl(url);
  }
}

QString WebPage::consoleMessages() {
  return m_consoleMessages.join("\n");
}

void WebPage::setUserAgent(QString userAgent) {
  m_userAgent = userAgent;
}

void WebPage::frameCreated(QWebFrame * frame) {
  connect(frame, SIGNAL(javaScriptWindowObjectCleared()),
          this,  SLOT(injectJavascriptHelpers()));
}

void WebPage::injectJavascriptHelpers() {
  QWebFrame* frame = qobject_cast<QWebFrame *>(QObject::sender());
  frame->evaluateJavaScript(m_capybaraJavascript);
}

bool WebPage::shouldInterruptJavaScript() {
  return false;
}

QVariant WebPage::invokeCapybaraFunction(const char *name, QStringList &arguments) {
  QString qname(name);
  QString objectName("CapybaraInvocation");
  JavascriptInvocation invocation(qname, arguments);
  currentFrame()->addToJavaScriptWindowObject(objectName, &invocation);
  QString javascript = QString("Capybara.invoke()");
  return currentFrame()->evaluateJavaScript(javascript);
}

QVariant WebPage::invokeCapybaraFunction(QString &name, QStringList &arguments) {
  return invokeCapybaraFunction(name.toAscii().data(), arguments);
}

void WebPage::javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID) {
  QString fullMessage = QString::number(lineNumber) + "|" + message;
  if (!sourceID.isEmpty())
    fullMessage = sourceID + "|" + fullMessage;
  m_consoleMessages.append(fullMessage);
  std::cout << qPrintable(fullMessage) << std::endl;
}

void WebPage::javaScriptAlert(QWebFrame *frame, const QString &message) {
  Q_UNUSED(frame);
  std::cout << "ALERT: " << qPrintable(message) << std::endl;
}

bool WebPage::javaScriptConfirm(QWebFrame *frame, const QString &message) {
  Q_UNUSED(frame);
  Q_UNUSED(message);
  return true;
}

bool WebPage::javaScriptPrompt(QWebFrame *frame, const QString &message, const QString &defaultValue, QString *result) {
  Q_UNUSED(frame)
  Q_UNUSED(message)
  Q_UNUSED(defaultValue)
  Q_UNUSED(result)
  return false;
}

void WebPage::loadStarted() {
  m_loading = true;
}

void WebPage::loadFinished(bool success) {
  m_loading = false;
  emit pageFinished(success);
}

bool WebPage::isLoading() const {
  return m_loading;
}

QString WebPage::failureString() {
  return QString("Unable to load URL: ") + currentFrame()->requestedUrl().toString();
}

bool WebPage::render(const QString &fileName) {
  QFileInfo fileInfo(fileName);
  QDir dir;
  dir.mkpath(fileInfo.absolutePath());

  QSize viewportSize = this->viewportSize();
  QSize pageSize = this->mainFrame()->contentsSize();
  if (pageSize.isEmpty()) {
    return false;
  }

  QImage buffer(pageSize, QImage::Format_ARGB32);
  buffer.fill(qRgba(255, 255, 255, 0));

  QPainter p(&buffer);
  p.setRenderHint( QPainter::Antialiasing,          true);
  p.setRenderHint( QPainter::TextAntialiasing,      true);
  p.setRenderHint( QPainter::SmoothPixmapTransform, true);

  this->setViewportSize(pageSize);
  this->mainFrame()->render(&p);
  p.end();
  this->setViewportSize(viewportSize);

  return buffer.save(fileName);
}

QString WebPage::chooseFile(QWebFrame *parentFrame, const QString &suggestedFile) {
  Q_UNUSED(parentFrame);
  Q_UNUSED(suggestedFile);

  return getLastAttachedFileName();
}

bool WebPage::extension(Extension extension, const ExtensionOption *option, ExtensionReturn *output) {
  Q_UNUSED(option);
  if (extension == ChooseMultipleFilesExtension) {
    QStringList names = QStringList() << getLastAttachedFileName();
    static_cast<ChooseMultipleFilesExtensionReturn*>(output)->fileNames = names;
    return true;
  }
  return false;
}

QString WebPage::getLastAttachedFileName() {
  return currentFrame()->evaluateJavaScript(QString("Capybara.lastAttachedFile")).toString();
}

void WebPage::replyFinished(QNetworkReply *reply) {
  if (reply->url() == this->currentFrame()->url()) {
    QStringList headers;
    m_lastStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    QList<QByteArray> list = reply->rawHeaderList();

    int length = list.size();
    for(int i = 0; i < length; i++) {
      headers << list.at(i)+": "+reply->rawHeader(list.at(i));
    }

    m_pageHeaders = headers.join("\n");
  }
}

void WebPage::ignoreSslErrors(QNetworkReply *reply, const QList<QSslError> &errors) {
  if (m_ignoreSslErrors)
    reply->ignoreSslErrors(errors);
}

void WebPage::setIgnoreSslErrors(bool ignore) {
  m_ignoreSslErrors = ignore;
}

bool WebPage::ignoreSslErrors() {
  return m_ignoreSslErrors;
}

int WebPage::getLastStatus() {
  return m_lastStatus;
}

void WebPage::resetResponseHeaders() {
  m_lastStatus = 0;
  m_pageHeaders = QString();
}

void WebPage::resetConsoleMessages() {
  m_consoleMessages.clear();
}

QString WebPage::pageHeaders() {
  return m_pageHeaders;
}

void WebPage::handleUnsupportedContent(QNetworkReply *reply) {
  UnsupportedContentHandler *handler = new UnsupportedContentHandler(this, reply);
  Q_UNUSED(handler);
}
<|endoftext|>


<commit_before>#include <stdarg.h>
#include <string.h>
#include <sys/time.h>

#include "misc.h"

#include "threading.h"
#include "logging.h"

namespace base {

int Log::level_s = Log::DEBUG;
FILE* Log::fp_s = stdout;
Mutex Log::m_s;

void Log::set_level(int level) {
    ScopedLock sl(&m_s);
    level_s = level;
}

void Log::set_file(FILE* fp) {
    verify(fp != NULL);
    ScopedLock sl(&m_s);
    fp_s = fp;
}

static const char* basename(const char* fpath) {
    if (fpath == nullptr) {
        return nullptr;
    }
    const char sep = '/';
    int len = strlen(fpath);
    int idx = len - 1;
    while (idx > 0) {
        if (fpath[idx - 1] == sep) {
            break;
        }
        idx--;
    }
    verify(idx >= 0 && idx < len);
    return &fpath[idx];
}

void Log::log_v(int level, int line, const char* file, const char* fmt, va_list args) {
    static char indicator[] = { 'F', 'E', 'W', 'I', 'D' };
    assert(level <= Log::DEBUG);
    if (level <= level_s) {
        const char* filebase = basename(file);

        char now_str[TIME_NOW_STR_SIZE];
        time_now_str(now_str);

        m_s.lock();
        fprintf(fp_s, "%c ", indicator[level]);
        if (filebase != nullptr) {
            fprintf(fp_s, "[%s:%d] ", filebase, line);
        }
        fprintf(fp_s, "%s | ", now_str);
        vfprintf(fp_s, fmt, args);
        fprintf(fp_s, "\n");
        m_s.unlock();
        fflush(fp_s);
    }
}

void Log::log(int level, int line, const char* file, const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(level, line, file, fmt, args);
    va_end(args);
}

void Log::fatal(int line, const char* file, const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::FATAL, line, file, fmt, args);
    va_end(args);
    abort();
}

void Log::error(int line, const char* file, const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::ERROR, line, file, fmt, args);
    va_end(args);
}

void Log::warn(int line, const char* file, const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::WARN, line, file, fmt, args);
    va_end(args);
}

void Log::info(int line, const char* file, const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::INFO, line, file, fmt, args);
    va_end(args);
}

void Log::debug(int line, const char* file, const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::DEBUG, line, file, fmt, args);
    va_end(args);
}

void Log::fatal(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::FATAL, 0, nullptr, fmt, args);
    va_end(args);
    abort();
}

void Log::error(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::ERROR, 0, nullptr, fmt, args);
    va_end(args);
}

void Log::warn(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::WARN, 0, nullptr, fmt, args);
    va_end(args);
}

void Log::info(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::INFO, 0, nullptr, fmt, args);
    va_end(args);
}

void Log::debug(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::DEBUG, 0, nullptr, fmt, args);
    va_end(args);
}

} // namespace base
<commit_msg>prevent reordered log entry time<commit_after>#include <stdarg.h>
#include <string.h>
#include <sys/time.h>

#include "misc.h"

#include "threading.h"
#include "logging.h"

namespace base {

int Log::level_s = Log::DEBUG;
FILE* Log::fp_s = stdout;
Mutex Log::m_s;

void Log::set_level(int level) {
    ScopedLock sl(&m_s);
    level_s = level;
}

void Log::set_file(FILE* fp) {
    verify(fp != NULL);
    ScopedLock sl(&m_s);
    fp_s = fp;
}

static const char* basename(const char* fpath) {
    if (fpath == nullptr) {
        return nullptr;
    }
    const char sep = '/';
    int len = strlen(fpath);
    int idx = len - 1;
    while (idx > 0) {
        if (fpath[idx - 1] == sep) {
            break;
        }
        idx--;
    }
    verify(idx >= 0 && idx < len);
    return &fpath[idx];
}

void Log::log_v(int level, int line, const char* file, const char* fmt, va_list args) {
    static char indicator[] = { 'F', 'E', 'W', 'I', 'D' };
    assert(level <= Log::DEBUG);
    if (level <= level_s) {
        const char* filebase = basename(file);
        char now_str[TIME_NOW_STR_SIZE];
        m_s.lock();
        time_now_str(now_str);
        fprintf(fp_s, "%c ", indicator[level]);
        if (filebase != nullptr) {
            fprintf(fp_s, "[%s:%d] ", filebase, line);
        }
        fprintf(fp_s, "%s | ", now_str);
        vfprintf(fp_s, fmt, args);
        fprintf(fp_s, "\n");
        m_s.unlock();
        fflush(fp_s);
    }
}

void Log::log(int level, int line, const char* file, const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(level, line, file, fmt, args);
    va_end(args);
}

void Log::fatal(int line, const char* file, const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::FATAL, line, file, fmt, args);
    va_end(args);
    abort();
}

void Log::error(int line, const char* file, const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::ERROR, line, file, fmt, args);
    va_end(args);
}

void Log::warn(int line, const char* file, const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::WARN, line, file, fmt, args);
    va_end(args);
}

void Log::info(int line, const char* file, const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::INFO, line, file, fmt, args);
    va_end(args);
}

void Log::debug(int line, const char* file, const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::DEBUG, line, file, fmt, args);
    va_end(args);
}

void Log::fatal(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::FATAL, 0, nullptr, fmt, args);
    va_end(args);
    abort();
}

void Log::error(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::ERROR, 0, nullptr, fmt, args);
    va_end(args);
}

void Log::warn(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::WARN, 0, nullptr, fmt, args);
    va_end(args);
}

void Log::info(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::INFO, 0, nullptr, fmt, args);
    va_end(args);
}

void Log::debug(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::DEBUG, 0, nullptr, fmt, args);
    va_end(args);
}

} // namespace base
<|endoftext|>


<commit_before>// Copyright © 2016 by Donald King <chronos@chronos-tachyon.net>
// Available under the MIT License. See LICENSE for details.

#include "base/logging.h"

#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#include <condition_variable>
#include <cstdint>
#include <cstring>
#include <deque>
#include <map>
#include <memory>
#include <mutex>
#include <thread>
#include <vector>

#include "base/concat.h"
#include "base/debug.h"
#include "base/mutex.h"
#include "base/result.h"

namespace base {

static pid_t my_gettid() { return syscall(SYS_gettid); }

namespace {
struct Key {
  const char* file;
  unsigned int line;

  Key(const char* file, unsigned int line) noexcept : file(file), line(line) {}
};

static bool operator==(Key a, Key b) noexcept __attribute__((unused));
static bool operator==(Key a, Key b) noexcept {
  return a.line == b.line && ::strcmp(a.file, b.file) == 0;
}

static bool operator<(Key a, Key b) noexcept {
  int cmp = ::strcmp(a.file, b.file);
  return cmp < 0 || (cmp == 0 && a.line < b.line);
}

using Map = std::map<Key, std::size_t>;
using Vec = std::vector<LogTarget*>;
using Queue = std::deque<LogEntry>;

enum ThreadState {
  kThreadNotStarted = 0,
  kThreadStarted = 1,
  kSingleThreaded = 2,
};

static std::once_flag g_once;
static std::mutex g_mu;
static std::mutex g_queue_mu;
static level_t g_flush = LOG_LEVEL_ERROR;         // protected by g_mu
static level_t g_stderr = LOG_LEVEL_INFO;         // protected by g_mu
static GetTidFunc g_gtid = nullptr;               // protected by g_mu
static GetTimeOfDayFunc g_gtod = nullptr;         // protected by g_mu
static Map* g_map = nullptr;                      // protected by g_mu
static Vec* g_vec = nullptr;                      // protected by g_mu
static int g_thread_state = kThreadNotStarted;    // protected by g_queue_mu
static std::condition_variable g_queue_put_cv;    // protected by g_queue_mu
static std::condition_variable g_queue_empty_cv;  // protected by g_queue_mu
static Queue* g_queue = nullptr;                  // protected by g_queue_mu

class LogSTDERR : public LogTarget {
 public:
  LogSTDERR() noexcept = default;
  bool want(const char* file, unsigned int line, level_t level) const override {
    // g_mu held by base::want()
    return level >= g_stderr;
  }
  void log(const LogEntry& entry) override {
    // g_mu held by base::thread_body()
    auto str = entry.as_string();
    ::write(2, str.data(), str.size());
  }
  void flush() override { ::fdatasync(2); }
};

static base::LogTarget* make_stderr() {
  static base::LogTarget* const ptr = new LogSTDERR;
  return ptr;
}

template <typename F, typename... Args>
static void ignore_exceptions(F func, Args&&... args) {
  try {
    func(std::forward<Args>(args)...);
  } catch (...) {
    // discard exception
  }
}

static void process(base::Lock& main_lock, const LogEntry& entry) {
  if (entry) {
    for (LogTarget* target : *g_vec) {
      ignore_exceptions([&entry, target] {
        if (target->want(entry.file, entry.line, entry.level)) {
          target->log(entry);
        }
      });
    }
  }
  if (entry.level >= g_flush) {
    for (LogTarget* target : *g_vec) {
      ignore_exceptions([target] { target->flush(); });
    }
  }
  if (entry.level >= LOG_LEVEL_DFATAL) {
    if (entry.level >= LOG_LEVEL_FATAL || debug()) {
      std::terminate();
    }
  }
}

static void thread_body() noexcept {
  auto queue_lock = base::acquire_lock(g_queue_mu);
  while (true) {
    if (g_queue->empty()) {
      g_queue_empty_cv.notify_all();
      while (g_queue->empty()) g_queue_put_cv.wait(queue_lock);
    }
    auto entry = std::move(g_queue->front());
    g_queue->pop_front();
    auto main_lock = base::acquire_lock(g_mu);
    process(main_lock, entry);
  }
}

static void log_wait(base::Lock& queue_lock) {
  while (!g_queue->empty()) g_queue_empty_cv.wait(queue_lock);
}

static void init() {
  auto queue_lock = acquire_lock(g_queue_mu);
  auto main_lock = acquire_lock(g_mu);

  if (!g_gtid) g_gtid = my_gettid;
  if (!g_gtod) g_gtod = gettimeofday;
  if (!g_map) g_map = new Map;
  if (!g_vec) g_vec = new Vec{make_stderr()};
  if (!g_queue) g_queue = new Queue;

  if (g_thread_state == kThreadNotStarted) {
    g_thread_state = kThreadStarted;
    std::thread(thread_body).detach();
  }
}

}  // anonymous namespace

LogEntry::LogEntry(const char* file, unsigned int line, level_t level,
                   std::string message) noexcept : file(file),
                                                   line(line),
                                                   level(level),
                                                   message(std::move(message)) {
  std::call_once(g_once, [] { init(); });
  auto main_lock = acquire_lock(g_mu);
  ::bzero(&time, sizeof(time));
  (*g_gtod)(&time, nullptr);
  tid = (*g_gtid)();
}

void LogEntry::append_to(std::string* out) const {
  char ch;
  if (level >= LOG_LEVEL_DFATAL) {
    ch = 'F';
  } else if (level >= LOG_LEVEL_ERROR) {
    ch = 'E';
  } else if (level >= LOG_LEVEL_WARN) {
    ch = 'W';
  } else if (level >= LOG_LEVEL_INFO) {
    ch = 'I';
  } else {
    ch = 'D';
  }

  struct tm tm;
  ::gmtime_r(&time.tv_sec, &tm);

  // "[IWEF]<mm><dd> <hh>:<mm>:<ss>.<uuuuuu>  <tid> <file>:<line>] <message>"

  std::array<char, 24> buf;
  ::snprintf(buf.data(), buf.size(), "%c%02u%02u %02u:%02u:%02u.%06lu  ", ch,
             tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
             time.tv_usec);

  concat_to(out, std::string(buf.data()), tid, ' ', file, ':', line, "] ",
            message, '\n');
}

std::string LogEntry::as_string() const {
  std::string out;
  append_to(&out);
  return out;
}

static std::unique_ptr<std::ostringstream> make_ss(const char* file,
                                                   unsigned int line,
                                                   unsigned int n,
                                                   level_t level) {
  if (file == nullptr) std::terminate();
  if (line == 0) std::terminate();
  if (n == 0) std::terminate();

  std::unique_ptr<std::ostringstream> ptr;
  if (want(file, line, n, level)) ptr.reset(new std::ostringstream);
  return ptr;
}

Logger::Logger(const char* file, unsigned int line, unsigned int every_n,
               level_t level)
    : file_(file),
      line_(line),
      n_(every_n),
      level_(level),
      ss_(make_ss(file, line, every_n, level)) {}

bool want(const char* file, unsigned int line, unsigned int n, level_t level) {
  std::call_once(g_once, [] { init(); });
  if (level >= LOG_LEVEL_DFATAL) return true;
  auto main_lock = base::acquire_lock(g_mu);
  if (n > 1) {
    Key key(file, line);
    auto pair = g_map->insert(std::make_pair(key, 0));
    auto& count = pair.first->second;
    bool x = (count == 0);
    count = (count + 1) % n;
    if (!x) return false;
  }
  bool result = false;
  for (const LogTarget* target : *g_vec) {
    ignore_exceptions([file, line, level, target, &result] {
      result = target->want(file, line, level);
    });
    if (result) break;
  }
  return result;
}

void log(const LogEntry& entry) {
  std::call_once(g_once, [] { init(); });
  auto queue_lock = base::acquire_lock(g_queue_mu);
  if (g_thread_state == kSingleThreaded) {
    auto main_lock = base::acquire_lock(g_mu);
    process(main_lock, entry);
    return;
  }
  g_queue->push_back(entry);
  g_queue_put_cv.notify_one();
  if (entry.level >= LOG_LEVEL_DFATAL) log_wait(queue_lock);
}

void log_single_threaded() {
  auto queue_lock = acquire_lock(g_queue_mu);
  if (g_thread_state == kThreadStarted)
    throw std::logic_error("logging thread is already running!");
  g_thread_state = kSingleThreaded;
}

void log_flush() {
  auto queue_lock = base::acquire_lock(g_queue_mu);
  log_wait(queue_lock);
  auto main_lock = base::acquire_lock(g_mu);
  for (LogTarget* target : *g_vec) {
    ignore_exceptions([target] { target->flush(); });
  }
}

void log_flush_set_level(level_t level) {
  auto main_lock = acquire_lock(g_mu);
  g_flush = level;
}

void log_stderr_set_level(level_t level) {
  auto main_lock = acquire_lock(g_mu);
  g_stderr = level;
}

void log_target_add(LogTarget* target) {
  auto main_lock = acquire_lock(g_mu);
  g_vec->push_back(target);
}

void log_target_remove(LogTarget* target) {
  auto queue_lock = base::acquire_lock(g_queue_mu);
  log_wait(queue_lock);
  auto main_lock = acquire_lock(g_mu);
  auto& v = *g_vec;
  for (auto it = v.begin(), end = v.end(); it != end; ++it) {
    if (*it == target) {
      v.erase(it);
      break;
    }
  }
}

void log_set_gettid(GetTidFunc func) {
  auto main_lock = acquire_lock(g_mu);
  if (func)
    g_gtid = func;
  else
    g_gtid = my_gettid;
}

void log_set_gettimeofday(GetTimeOfDayFunc func) {
  auto main_lock = acquire_lock(g_mu);
  if (func)
    g_gtod = func;
  else
    g_gtod = gettimeofday;
}

namespace internal {

void log_exception(const char* file, unsigned int line, std::exception_ptr e) {
  Logger logger(file, line, 1, LOG_LEVEL_ERROR);
  try {
    std::rethrow_exception(e);
  } catch (const std::system_error& e) {
    const auto& ecode = e.code();
    logger << "caught std::system_error\n"
           << "\t" << ecode.category().name() << "(" << ecode.value()
           << "): " << e.what();
  } catch (const std::exception& e) {
    logger << "caught std::exception\n"
           << "\t[" << typeid(e).name() << "]\n"
           << "\t" << e.what();
  } catch (...) {
    logger << "caught unclassifiable exception!";
  }
}

Logger log_check(const char* file, unsigned int line, const char* expr,
                 bool cond) {
  if (cond) return Logger();
  Logger logger(file, line, 1, LOG_LEVEL_DFATAL);
  logger << "CHECK FAILED: " << expr;
  return logger;
}

Logger log_check_ok(const char* file, unsigned int line, const char* expr,
                    const Result& rslt) {
  if (rslt) return Logger();
  Logger logger(file, line, 1, LOG_LEVEL_DFATAL);
  logger << "CHECK FAILED: " << expr << ": " << rslt.as_string();
  return logger;
}

}  // namespace internal

}  // namespace base
<commit_msg>Call std::terminate from within the stack frame that provoked it.<commit_after>// Copyright © 2016 by Donald King <chronos@chronos-tachyon.net>
// Available under the MIT License. See LICENSE for details.

#include "base/logging.h"

#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#include <condition_variable>
#include <cstdint>
#include <cstring>
#include <deque>
#include <map>
#include <memory>
#include <mutex>
#include <thread>
#include <vector>

#include "base/concat.h"
#include "base/debug.h"
#include "base/mutex.h"
#include "base/result.h"

namespace base {

static pid_t my_gettid() { return syscall(SYS_gettid); }

inline namespace implementation {
struct Key {
  const char* file;
  unsigned int line;

  Key(const char* file, unsigned int line) noexcept : file(file), line(line) {}
};

static bool operator==(Key a, Key b) noexcept __attribute__((unused));
static bool operator==(Key a, Key b) noexcept {
  return a.line == b.line && ::strcmp(a.file, b.file) == 0;
}

static bool operator<(Key a, Key b) noexcept {
  int cmp = ::strcmp(a.file, b.file);
  return cmp < 0 || (cmp == 0 && a.line < b.line);
}

using Map = std::map<Key, std::size_t>;
using Vec = std::vector<LogTarget*>;
using Queue = std::deque<LogEntry>;

enum ThreadState {
  kThreadNotStarted = 0,
  kThreadStarted = 1,
  kSingleThreaded = 2,
};

static std::once_flag g_once;
static std::mutex g_mu;
static std::mutex g_queue_mu;
static level_t g_flush = LOG_LEVEL_ERROR;         // protected by g_mu
static level_t g_stderr = LOG_LEVEL_INFO;         // protected by g_mu
static GetTidFunc g_gtid = nullptr;               // protected by g_mu
static GetTimeOfDayFunc g_gtod = nullptr;         // protected by g_mu
static Map* g_map = nullptr;                      // protected by g_mu
static Vec* g_vec = nullptr;                      // protected by g_mu
static int g_thread_state = kThreadNotStarted;    // protected by g_queue_mu
static std::condition_variable g_queue_put_cv;    // protected by g_queue_mu
static std::condition_variable g_queue_empty_cv;  // protected by g_queue_mu
static Queue* g_queue = nullptr;                  // protected by g_queue_mu

class LogSTDERR : public LogTarget {
 public:
  LogSTDERR() noexcept = default;
  bool want(const char* file, unsigned int line, level_t level) const override {
    // g_mu held by base::want()
    return level >= g_stderr;
  }
  void log(const LogEntry& entry) override {
    // g_mu held by base::thread_body()
    auto str = entry.as_string();
    ::write(2, str.data(), str.size());
  }
  void flush() override { ::fdatasync(2); }
};

static base::LogTarget* make_stderr() {
  static base::LogTarget* const ptr = new LogSTDERR;
  return ptr;
}

template <typename F, typename... Args>
static void ignore_exceptions(F func, Args&&... args) {
  try {
    func(std::forward<Args>(args)...);
  } catch (...) {
    // discard exception
  }
}

static void process(base::Lock& main_lock, const LogEntry& entry) {
  if (entry) {
    for (LogTarget* target : *g_vec) {
      ignore_exceptions([&entry, target] {
        if (target->want(entry.file, entry.line, entry.level)) {
          target->log(entry);
        }
      });
    }
  }
  if (entry.level >= g_flush) {
    for (LogTarget* target : *g_vec) {
      ignore_exceptions([target] { target->flush(); });
    }
  }
}

static void thread_body() noexcept {
  auto queue_lock = base::acquire_lock(g_queue_mu);
  while (true) {
    if (g_queue->empty()) {
      g_queue_empty_cv.notify_all();
      while (g_queue->empty()) g_queue_put_cv.wait(queue_lock);
    }
    auto entry = std::move(g_queue->front());
    g_queue->pop_front();
    auto main_lock = base::acquire_lock(g_mu);
    process(main_lock, entry);
  }
}

static void log_wait(base::Lock& queue_lock) {
  while (!g_queue->empty()) g_queue_empty_cv.wait(queue_lock);
}

static void init() {
  auto queue_lock = acquire_lock(g_queue_mu);
  auto main_lock = acquire_lock(g_mu);

  if (!g_gtid) g_gtid = my_gettid;
  if (!g_gtod) g_gtod = gettimeofday;
  if (!g_map) g_map = new Map;
  if (!g_vec) g_vec = new Vec{make_stderr()};
  if (!g_queue) g_queue = new Queue;

  if (g_thread_state == kThreadNotStarted) {
    g_thread_state = kThreadStarted;
    std::thread(thread_body).detach();
  }
}

static void maybe_terminate(const LogEntry& entry) {
  if (entry.level >= LOG_LEVEL_DFATAL) {
    if (entry.level >= LOG_LEVEL_FATAL || debug()) {
      std::terminate();
    }
  }
}

}  // inline namespace implementation

LogEntry::LogEntry(const char* file, unsigned int line, level_t level,
                   std::string message) noexcept : file(file),
                                                   line(line),
                                                   level(level),
                                                   message(std::move(message)) {
  std::call_once(g_once, [] { init(); });
  auto main_lock = acquire_lock(g_mu);
  ::bzero(&time, sizeof(time));
  (*g_gtod)(&time, nullptr);
  tid = (*g_gtid)();
}

void LogEntry::append_to(std::string* out) const {
  char ch;
  if (level >= LOG_LEVEL_DFATAL) {
    ch = 'F';
  } else if (level >= LOG_LEVEL_ERROR) {
    ch = 'E';
  } else if (level >= LOG_LEVEL_WARN) {
    ch = 'W';
  } else if (level >= LOG_LEVEL_INFO) {
    ch = 'I';
  } else {
    ch = 'D';
  }

  struct tm tm;
  ::gmtime_r(&time.tv_sec, &tm);

  // "[IWEF]<mm><dd> <hh>:<mm>:<ss>.<uuuuuu>  <tid> <file>:<line>] <message>"

  std::array<char, 24> buf;
  ::snprintf(buf.data(), buf.size(), "%c%02u%02u %02u:%02u:%02u.%06lu  ", ch,
             tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
             time.tv_usec);

  concat_to(out, std::string(buf.data()), tid, ' ', file, ':', line, "] ",
            message, '\n');
}

std::string LogEntry::as_string() const {
  std::string out;
  append_to(&out);
  return out;
}

static std::unique_ptr<std::ostringstream> make_ss(const char* file,
                                                   unsigned int line,
                                                   unsigned int n,
                                                   level_t level) {
  if (file == nullptr) std::terminate();
  if (line == 0) std::terminate();
  if (n == 0) std::terminate();

  std::unique_ptr<std::ostringstream> ptr;
  if (want(file, line, n, level)) ptr.reset(new std::ostringstream);
  return ptr;
}

Logger::Logger(const char* file, unsigned int line, unsigned int every_n,
               level_t level)
    : file_(file),
      line_(line),
      n_(every_n),
      level_(level),
      ss_(make_ss(file, line, every_n, level)) {}

bool want(const char* file, unsigned int line, unsigned int n, level_t level) {
  std::call_once(g_once, [] { init(); });
  if (level >= LOG_LEVEL_DFATAL) return true;
  auto main_lock = base::acquire_lock(g_mu);
  if (n > 1) {
    Key key(file, line);
    auto pair = g_map->insert(std::make_pair(key, 0));
    auto& count = pair.first->second;
    bool x = (count == 0);
    count = (count + 1) % n;
    if (!x) return false;
  }
  bool result = false;
  for (const LogTarget* target : *g_vec) {
    ignore_exceptions([file, line, level, target, &result] {
      result = target->want(file, line, level);
    });
    if (result) break;
  }
  return result;
}

void log(const LogEntry& entry) {
  std::call_once(g_once, [] { init(); });
  auto queue_lock = base::acquire_lock(g_queue_mu);
  if (g_thread_state == kSingleThreaded) {
    auto main_lock = base::acquire_lock(g_mu);
    process(main_lock, entry);
    maybe_terminate(entry);
    return;
  }
  g_queue->push_back(entry);
  g_queue_put_cv.notify_one();
  if (entry.level >= LOG_LEVEL_DFATAL) {
    log_wait(queue_lock);
    maybe_terminate(entry);
  }
}

void log_single_threaded() {
  auto queue_lock = acquire_lock(g_queue_mu);
  if (g_thread_state == kThreadStarted)
    throw std::logic_error("logging thread is already running!");
  g_thread_state = kSingleThreaded;
}

void log_flush() {
  auto queue_lock = base::acquire_lock(g_queue_mu);
  log_wait(queue_lock);
  auto main_lock = base::acquire_lock(g_mu);
  for (LogTarget* target : *g_vec) {
    ignore_exceptions([target] { target->flush(); });
  }
}

void log_flush_set_level(level_t level) {
  auto main_lock = acquire_lock(g_mu);
  g_flush = level;
}

void log_stderr_set_level(level_t level) {
  auto main_lock = acquire_lock(g_mu);
  g_stderr = level;
}

void log_target_add(LogTarget* target) {
  auto main_lock = acquire_lock(g_mu);
  g_vec->push_back(target);
}

void log_target_remove(LogTarget* target) {
  auto queue_lock = base::acquire_lock(g_queue_mu);
  log_wait(queue_lock);
  auto main_lock = acquire_lock(g_mu);
  auto& v = *g_vec;
  for (auto it = v.begin(), end = v.end(); it != end; ++it) {
    if (*it == target) {
      v.erase(it);
      break;
    }
  }
}

void log_set_gettid(GetTidFunc func) {
  auto main_lock = acquire_lock(g_mu);
  if (func)
    g_gtid = func;
  else
    g_gtid = my_gettid;
}

void log_set_gettimeofday(GetTimeOfDayFunc func) {
  auto main_lock = acquire_lock(g_mu);
  if (func)
    g_gtod = func;
  else
    g_gtod = gettimeofday;
}

namespace internal {

void log_exception(const char* file, unsigned int line, std::exception_ptr e) {
  Logger logger(file, line, 1, LOG_LEVEL_ERROR);
  try {
    std::rethrow_exception(e);
  } catch (const std::system_error& e) {
    const auto& ecode = e.code();
    logger << "caught std::system_error\n"
           << "\t" << ecode.category().name() << "(" << ecode.value()
           << "): " << e.what();
  } catch (const std::exception& e) {
    logger << "caught std::exception\n"
           << "\t[" << typeid(e).name() << "]\n"
           << "\t" << e.what();
  } catch (...) {
    logger << "caught unclassifiable exception!";
  }
}

Logger log_check(const char* file, unsigned int line, const char* expr,
                 bool cond) {
  if (cond) return Logger();
  Logger logger(file, line, 1, LOG_LEVEL_DFATAL);
  logger << "CHECK FAILED: " << expr;
  return logger;
}

Logger log_check_ok(const char* file, unsigned int line, const char* expr,
                    const Result& rslt) {
  if (rslt) return Logger();
  Logger logger(file, line, 1, LOG_LEVEL_DFATAL);
  logger << "CHECK FAILED: " << expr << ": " << rslt.as_string();
  return logger;
}

}  // namespace internal

}  // namespace base
<|endoftext|>


<commit_before>
#include <cantera/Cantera.h>
#include <cantera/IdealGasMix.h>    // defines class IdealGasMix

#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include <numeric>
#include <string>
#include <algorithm>

using namespace std;
using namespace Cantera;

// The program is put into a function so that error handling code can
// be conveniently put around the whole thing. See main() below.

void demoprog() {

    printf("\n\n**** Testing modifying NASA polynomial coefficients ****\n\n");

    IdealGasMix gas("h2o2.cti","ohmech");
    int nsp = gas.nSpecies();

    int type;
    doublereal c[15];
    doublereal minTemp, maxTemp, refPressure;

    // get a reference to the species thermo property manager
    SpeciesThermo& sp = gas.speciesThermo();

    int n, j;

    // these constants define the location of coefficient "a6" in the
    // cofficient array c. The c array contains Tmid in the first
    // location, followed by the 7 low-temperature coefficients, then
    // the seven high-temperature ones.
    const int LOW_A6 = 6;
    //const int HIGH_A6 = 13;

    for (n = 0; n < nsp; n++) {

        printf("\n\n %s (original):", gas.speciesName(n).c_str());

        // get the NASA coefficients in array c
        sp.reportParams(n, type, c, minTemp, maxTemp, refPressure);

        // print the unmodified NASA coefficients
        printf("\n      ");
        for (j = 1; j < 8; j++) printf("     A%d     ", j);
        printf("\n  low:");
        for (j = 1; j < 8; j++) printf(" %10.4E ", c[j]);

        printf("\n high:");
        for (j = 8; j < 15; j++) printf(" %10.4E ", c[j]);
        printf("\n      ");

        // modify coefficient A6 of the low-temperature polynomial
        // Note that since we are not modifying the high-temperature
        // polynomial, a warning will be printed about a discontinuity
        // in enthalpy at Tmid.
        c[LOW_A6] += 1.0e4;
        sp.modifyParams(n, c);

        sp.reportParams(n, type, c, minTemp, maxTemp, refPressure);

        // print the modified NASA coefficients
        printf("\n\n %s (modified):", gas.speciesName(n).c_str());
        printf("\n      ");
        for (j = 1; j < 8; j++) printf("     A%d     ", j);
        printf("\n  low:");
        for (j = 1; j < 8; j++) printf(" %10.4E ", c[j]);

        printf("\n high:");
        for (j = 8; j < 15; j++) printf(" %10.4E ", c[j]);
        printf("\n      ");
    }
}

int main() {

    try {
        demoprog();
    }
    catch (CanteraError) {
        showErrors(cout);
    }
}

<commit_msg>Added namespace to get it to compile<commit_after>
#include <cantera/Cantera.h>
#include <cantera/IdealGasMix.h>    // defines class IdealGasMix

#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include <numeric>
#include <string>
#include <algorithm>

using namespace std;
using namespace Cantera;
using namespace Cantera_CXX;

// The program is put into a function so that error handling code can
// be conveniently put around the whole thing. See main() below.

void demoprog() {

    printf("\n\n**** Testing modifying NASA polynomial coefficients ****\n\n");

    IdealGasMix gas("h2o2.cti","ohmech");
    int nsp = gas.nSpecies();

    int type;
    doublereal c[15];
    doublereal minTemp, maxTemp, refPressure;

    // get a reference to the species thermo property manager
    SpeciesThermo& sp = gas.speciesThermo();

    int n, j;

    // these constants define the location of coefficient "a6" in the
    // cofficient array c. The c array contains Tmid in the first
    // location, followed by the 7 low-temperature coefficients, then
    // the seven high-temperature ones.
    const int LOW_A6 = 6;
    //const int HIGH_A6 = 13;

    for (n = 0; n < nsp; n++) {

        printf("\n\n %s (original):", gas.speciesName(n).c_str());

        // get the NASA coefficients in array c
        sp.reportParams(n, type, c, minTemp, maxTemp, refPressure);

        // print the unmodified NASA coefficients
        printf("\n      ");
        for (j = 1; j < 8; j++) printf("     A%d     ", j);
        printf("\n  low:");
        for (j = 1; j < 8; j++) printf(" %10.4E ", c[j]);

        printf("\n high:");
        for (j = 8; j < 15; j++) printf(" %10.4E ", c[j]);
        printf("\n      ");

        // modify coefficient A6 of the low-temperature polynomial
        // Note that since we are not modifying the high-temperature
        // polynomial, a warning will be printed about a discontinuity
        // in enthalpy at Tmid.
        c[LOW_A6] += 1.0e4;
        sp.modifyParams(n, c);

        sp.reportParams(n, type, c, minTemp, maxTemp, refPressure);

        // print the modified NASA coefficients
        printf("\n\n %s (modified):", gas.speciesName(n).c_str());
        printf("\n      ");
        for (j = 1; j < 8; j++) printf("     A%d     ", j);
        printf("\n  low:");
        for (j = 1; j < 8; j++) printf(" %10.4E ", c[j]);

        printf("\n high:");
        for (j = 8; j < 15; j++) printf(" %10.4E ", c[j]);
        printf("\n      ");
    }
}

int main() {

    try {
        demoprog();
    }
    catch (CanteraError) {
        showErrors(cout);
    }
}

<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2012 - 2013 Jolla Ltd.
** Contact: http://jolla.com/
**
** This file is part of Qt Creator.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Digia.
**
****************************************************************************/

#include "mertargetkitinformation.h"
#include "mersdkkitinformation.h"
#include "merconstants.h"
#include "merdevicefactory.h"
#include "mersdk.h"
#include "mersdkmanager.h"
#include "meroptionspage.h"
#include <projectexplorer/projectexplorerconstants.h>
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/icore.h>
#include <QPushButton>
#include <QComboBox>

namespace Mer {
namespace Internal {

MerTargetKitInformation::MerTargetKitInformation()
{
}

Core::Id MerTargetKitInformation::dataId() const
{
    return Core::Id(Constants::MER_TARGET_KIT_INFORMATION);
}

unsigned int MerTargetKitInformation::priority() const
{
    return 23;
}

QVariant MerTargetKitInformation::defaultValue(ProjectExplorer::Kit *kit) const
{
    return MerTargetKitInformation::targetName(kit);
}

QList<ProjectExplorer::Task> MerTargetKitInformation::validate(const ProjectExplorer::Kit *kit) const
{
    if (MerDeviceFactory::canCreate(ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(kit))) {
        const MerSdk *sdk = MerSdkKitInformation::sdk(kit);
        const QString &target = kit->value(Core::Id(Constants::TARGET)).toString();
        if (sdk && !sdk->targetNames().contains(target)) {
            const QString message = QCoreApplication::translate("MerTarget",
                                                                "No valid MerTarget for %1 sdk found").arg(sdk->virtualMachineName());
            return QList<ProjectExplorer::Task>() << ProjectExplorer::Task(ProjectExplorer::Task::Error, message, Utils::FileName(), -1,
                                                                           Core::Id(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
        }
    }
    return QList<ProjectExplorer::Task>();
}

QString MerTargetKitInformation::targetName(const ProjectExplorer::Kit *kit)
{
    if (!kit)
        return QString();
    return kit->value(Core::Id(Constants::TARGET)).toString();
}

ProjectExplorer::KitInformation::ItemList MerTargetKitInformation::toUserOutput(const ProjectExplorer::Kit *kit) const
{
    if (MerDeviceFactory::canCreate(ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(kit))) {
        QString targetName = MerTargetKitInformation::targetName(kit);
        return ProjectExplorer::KitInformation::ItemList()
                << qMakePair(tr("MerTarget"),targetName);
    }
    return ProjectExplorer::KitInformation::ItemList();
}

ProjectExplorer::KitConfigWidget *MerTargetKitInformation::createConfigWidget(ProjectExplorer::Kit *kit) const
{
    return new MerTargetKitInformationWidget(kit);
}

void MerTargetKitInformation::setTargetName(ProjectExplorer::Kit *kit, const QString& targetName)
{
    if(kit->value(Core::Id(Constants::TARGET)) != targetName)
        kit->setValue(Core::Id(Constants::TARGET),targetName);
}

void MerTargetKitInformation::addToEnvironment(const ProjectExplorer::Kit *kit, Utils::Environment &env) const
{
    const QString targetName = MerTargetKitInformation::targetName(kit);
        env.appendOrSet(QLatin1String(Constants::MER_SSH_TARGET_NAME),targetName);
}

////////////////////////////////////////////////////////////////////////////////////////////

MerTargetKitInformationWidget::MerTargetKitInformationWidget(ProjectExplorer::Kit *kit, bool sticky)
    : ProjectExplorer::KitConfigWidget(kit,sticky),
      m_combo(new QComboBox),
      m_manageButton(new QPushButton(tr("Manage...")))
{
    refresh();
    connect(m_combo, SIGNAL(currentIndexChanged(int)), this, SLOT(handleCurrentIndexChanged()));
    connect(m_manageButton, SIGNAL(clicked()), this, SLOT(handleManageClicked()));
    connect(MerSdkManager::instance(), SIGNAL(sdksUpdated()), this, SLOT(handleSdksUpdated()));
}

QString MerTargetKitInformationWidget::displayName() const
{
    return tr("Mer Target:");
}

QString MerTargetKitInformationWidget::toolTip() const
{
    return tr("Name of traget used by sb2.");
}

void MerTargetKitInformationWidget::makeReadOnly()
{
    m_combo->setEnabled(false);
}

void MerTargetKitInformationWidget::refresh()
{
    const MerSdk* sdk = MerSdkKitInformation::sdk(m_kit);
    QString targetName = MerTargetKitInformation::targetName(m_kit);
    int i = -1;
    m_combo->blockSignals(true);
    m_combo->clear();
    if (sdk && !targetName.isEmpty()) {
        foreach (const QString& targetName, sdk->targetNames()) {
            m_combo->addItem(targetName);
        }
    }

    for (i = m_combo->count() - 1; i >= 0; --i) {
        if (targetName == m_combo->itemText(i))
            break;
    }

    if(m_combo->count() == 0) {
        m_combo->addItem(tr("None"));
        i=0;
    }

    m_combo->blockSignals(false);
    m_combo->setCurrentIndex(i);
}

bool MerTargetKitInformationWidget::visibleInKit()
{
    return MerDeviceFactory::canCreate(ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(m_kit));
}

QWidget *MerTargetKitInformationWidget::mainWidget() const
{
    return m_combo;
}

QWidget *MerTargetKitInformationWidget::buttonWidget() const
{
    return m_manageButton;
}

void MerTargetKitInformationWidget::handleManageClicked()
{
    MerOptionsPage *page = ExtensionSystem::PluginManager::getObject<MerOptionsPage>();
    if (page) {
        const MerSdk* sdk = MerSdkKitInformation::sdk(m_kit);
        if(sdk)
            page->setSdk(m_combo->currentText());
    }
    Core::ICore::showOptionsDialog(Constants::MER_OPTIONS_CATEGORY,Constants::MER_OPTIONS_ID);
}

void MerTargetKitInformationWidget::handleCurrentIndexChanged()
{
    const MerSdk* sdk = MerSdkKitInformation::sdk(m_kit);
    if (sdk && sdk->targetNames().contains(m_combo->currentText()))
        MerTargetKitInformation::setTargetName(m_kit,m_combo->currentText());
}

void MerTargetKitInformationWidget::handleSdksUpdated()
{
    refresh();
}

}
}
<commit_msg>Fix typo<commit_after>/****************************************************************************
**
** Copyright (C) 2012 - 2013 Jolla Ltd.
** Contact: http://jolla.com/
**
** This file is part of Qt Creator.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Digia.
**
****************************************************************************/

#include "mertargetkitinformation.h"
#include "mersdkkitinformation.h"
#include "merconstants.h"
#include "merdevicefactory.h"
#include "mersdk.h"
#include "mersdkmanager.h"
#include "meroptionspage.h"
#include <projectexplorer/projectexplorerconstants.h>
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/icore.h>
#include <QPushButton>
#include <QComboBox>

namespace Mer {
namespace Internal {

MerTargetKitInformation::MerTargetKitInformation()
{
}

Core::Id MerTargetKitInformation::dataId() const
{
    return Core::Id(Constants::MER_TARGET_KIT_INFORMATION);
}

unsigned int MerTargetKitInformation::priority() const
{
    return 23;
}

QVariant MerTargetKitInformation::defaultValue(ProjectExplorer::Kit *kit) const
{
    return MerTargetKitInformation::targetName(kit);
}

QList<ProjectExplorer::Task> MerTargetKitInformation::validate(const ProjectExplorer::Kit *kit) const
{
    if (MerDeviceFactory::canCreate(ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(kit))) {
        const MerSdk *sdk = MerSdkKitInformation::sdk(kit);
        const QString &target = kit->value(Core::Id(Constants::TARGET)).toString();
        if (sdk && !sdk->targetNames().contains(target)) {
            const QString message = QCoreApplication::translate("MerTarget",
                                                                "No valid MerTarget for %1 sdk found").arg(sdk->virtualMachineName());
            return QList<ProjectExplorer::Task>() << ProjectExplorer::Task(ProjectExplorer::Task::Error, message, Utils::FileName(), -1,
                                                                           Core::Id(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
        }
    }
    return QList<ProjectExplorer::Task>();
}

QString MerTargetKitInformation::targetName(const ProjectExplorer::Kit *kit)
{
    if (!kit)
        return QString();
    return kit->value(Core::Id(Constants::TARGET)).toString();
}

ProjectExplorer::KitInformation::ItemList MerTargetKitInformation::toUserOutput(const ProjectExplorer::Kit *kit) const
{
    if (MerDeviceFactory::canCreate(ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(kit))) {
        QString targetName = MerTargetKitInformation::targetName(kit);
        return ProjectExplorer::KitInformation::ItemList()
                << qMakePair(tr("MerTarget"),targetName);
    }
    return ProjectExplorer::KitInformation::ItemList();
}

ProjectExplorer::KitConfigWidget *MerTargetKitInformation::createConfigWidget(ProjectExplorer::Kit *kit) const
{
    return new MerTargetKitInformationWidget(kit);
}

void MerTargetKitInformation::setTargetName(ProjectExplorer::Kit *kit, const QString& targetName)
{
    if(kit->value(Core::Id(Constants::TARGET)) != targetName)
        kit->setValue(Core::Id(Constants::TARGET),targetName);
}

void MerTargetKitInformation::addToEnvironment(const ProjectExplorer::Kit *kit, Utils::Environment &env) const
{
    const QString targetName = MerTargetKitInformation::targetName(kit);
        env.appendOrSet(QLatin1String(Constants::MER_SSH_TARGET_NAME),targetName);
}

////////////////////////////////////////////////////////////////////////////////////////////

MerTargetKitInformationWidget::MerTargetKitInformationWidget(ProjectExplorer::Kit *kit, bool sticky)
    : ProjectExplorer::KitConfigWidget(kit,sticky),
      m_combo(new QComboBox),
      m_manageButton(new QPushButton(tr("Manage...")))
{
    refresh();
    connect(m_combo, SIGNAL(currentIndexChanged(int)), this, SLOT(handleCurrentIndexChanged()));
    connect(m_manageButton, SIGNAL(clicked()), this, SLOT(handleManageClicked()));
    connect(MerSdkManager::instance(), SIGNAL(sdksUpdated()), this, SLOT(handleSdksUpdated()));
}

QString MerTargetKitInformationWidget::displayName() const
{
    return tr("Mer Target:");
}

QString MerTargetKitInformationWidget::toolTip() const
{
    return tr("Name of target used by sb2.");
}

void MerTargetKitInformationWidget::makeReadOnly()
{
    m_combo->setEnabled(false);
}

void MerTargetKitInformationWidget::refresh()
{
    const MerSdk* sdk = MerSdkKitInformation::sdk(m_kit);
    QString targetName = MerTargetKitInformation::targetName(m_kit);
    int i = -1;
    m_combo->blockSignals(true);
    m_combo->clear();
    if (sdk && !targetName.isEmpty()) {
        foreach (const QString& targetName, sdk->targetNames()) {
            m_combo->addItem(targetName);
        }
    }

    for (i = m_combo->count() - 1; i >= 0; --i) {
        if (targetName == m_combo->itemText(i))
            break;
    }

    if(m_combo->count() == 0) {
        m_combo->addItem(tr("None"));
        i=0;
    }

    m_combo->blockSignals(false);
    m_combo->setCurrentIndex(i);
}

bool MerTargetKitInformationWidget::visibleInKit()
{
    return MerDeviceFactory::canCreate(ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(m_kit));
}

QWidget *MerTargetKitInformationWidget::mainWidget() const
{
    return m_combo;
}

QWidget *MerTargetKitInformationWidget::buttonWidget() const
{
    return m_manageButton;
}

void MerTargetKitInformationWidget::handleManageClicked()
{
    MerOptionsPage *page = ExtensionSystem::PluginManager::getObject<MerOptionsPage>();
    if (page) {
        const MerSdk* sdk = MerSdkKitInformation::sdk(m_kit);
        if(sdk)
            page->setSdk(m_combo->currentText());
    }
    Core::ICore::showOptionsDialog(Constants::MER_OPTIONS_CATEGORY,Constants::MER_OPTIONS_ID);
}

void MerTargetKitInformationWidget::handleCurrentIndexChanged()
{
    const MerSdk* sdk = MerSdkKitInformation::sdk(m_kit);
    if (sdk && sdk->targetNames().contains(m_combo->currentText()))
        MerTargetKitInformation::setTargetName(m_kit,m_combo->currentText());
}

void MerTargetKitInformationWidget::handleSdksUpdated()
{
    refresh();
}

}
}
<|endoftext|>


<commit_before>#include "qmlcodecompletion.h"
#include "qmleditor.h"
#include "qmlmodelmanagerinterface.h"
#include "qmlexpressionundercursor.h"
#include "qmllookupcontext.h"
#include "qmlresolveexpression.h"
#include "qmlsymbol.h"

#include <texteditor/basetexteditor.h>
#include <QtDebug>

using namespace QmlEditor::Internal;

QmlCodeCompletion::QmlCodeCompletion(QmlModelManagerInterface *modelManager,QObject *parent)
    : TextEditor::ICompletionCollector(parent),
      m_modelManager(modelManager),
      m_editor(0),
      m_startPosition(0),
      m_caseSensitivity(Qt::CaseSensitive)
{
    Q_ASSERT(modelManager);
}

QmlCodeCompletion::~QmlCodeCompletion()
{ }

Qt::CaseSensitivity QmlCodeCompletion::caseSensitivity() const
{ return m_caseSensitivity; }

void QmlCodeCompletion::setCaseSensitivity(Qt::CaseSensitivity caseSensitivity)
{ m_caseSensitivity = caseSensitivity; }

bool QmlCodeCompletion::supportsEditor(TextEditor::ITextEditable *editor)
{
    if (qobject_cast<ScriptEditor *>(editor->widget()))
        return true;

    return false;
}

bool QmlCodeCompletion::triggersCompletion(TextEditor::ITextEditable *)
{ return false; }

int QmlCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
{
    m_editor = editor;

    ScriptEditor *edit = qobject_cast<ScriptEditor *>(m_editor->widget());
    if (! edit)
        return -1;

    int pos = editor->position();

    while (editor->characterAt(pos - 1).isLetterOrNumber() || editor->characterAt(pos - 1) == QLatin1Char('_'))
        --pos;

    m_startPosition = pos;
    m_completions.clear();

//    foreach (const QString &word, edit->keywords()) {
//        TextEditor::CompletionItem item(this);
//        item.m_text = word;
//        m_completions.append(item);
//    }
//
//    foreach (const QString &word, edit->words()) {
//        TextEditor::CompletionItem item(this);
//        item.m_text = word;
//        m_completions.append(item);
//    }

    QmlDocument::Ptr qmlDocument = edit->qmlDocument();
//    qDebug() << "*** document:" << qmlDocument;
    if (qmlDocument.isNull())
        return pos;

    if (!qmlDocument->program())
        qmlDocument = m_modelManager->snapshot().value(qmlDocument->fileName());

    if (qmlDocument->program()) {
         QmlJS::AST::UiProgram *program = qmlDocument->program();
//        qDebug() << "*** program:" << program;

         if (program) {
            QmlExpressionUnderCursor expressionUnderCursor;
            QTextCursor cursor(edit->document());
            cursor.setPosition(pos);
            expressionUnderCursor(cursor, qmlDocument);

            QmlLookupContext context(expressionUnderCursor.expressionScopes(), qmlDocument, m_modelManager->snapshot());
            QmlResolveExpression resolver(context);
            QList<QmlSymbol*> symbols = resolver.visibleSymbols(expressionUnderCursor.expressionNode());

            foreach (QmlSymbol *symbol, symbols) {
                QString word;

                if (symbol->isIdSymbol()) {
                    word = symbol->asIdSymbol()->id();
                } else {
                    word = symbol->name();
                }

                if (word.isEmpty())
                    continue;

                TextEditor::CompletionItem item(this);
                item.m_text = word;
                m_completions.append(item);
            }
        }
    }

    return pos;
}

void QmlCodeCompletion::completions(QList<TextEditor::CompletionItem> *completions)
{
    // ### FIXME: this code needs to be generalized.

    const int length = m_editor->position() - m_startPosition;

    if (length == 0)
        *completions = m_completions;
    else if (length > 0) {
        const QString key = m_editor->textAt(m_startPosition, length);

        /*
         * This code builds a regular expression in order to more intelligently match
         * camel-case style. This means upper-case characters will be rewritten as follows:
         *
         *   A => [a-z0-9_]*A (for any but the first capital letter)
         *
         * Meaning it allows any sequence of lower-case characters to preceed an
         * upper-case character. So for example gAC matches getActionController.
         */
        QString keyRegExp;
        keyRegExp += QLatin1Char('^');
        bool first = true;
        foreach (const QChar &c, key) {
            if (c.isUpper() && !first) {
                keyRegExp += QLatin1String("[a-z0-9_]*");
                keyRegExp += c;
            } else if (m_caseSensitivity == Qt::CaseInsensitive && c.isLower()) {
                keyRegExp += QLatin1Char('[');
                keyRegExp += c;
                keyRegExp += c.toUpper();
                keyRegExp += QLatin1Char(']');
            } else {
                keyRegExp += QRegExp::escape(c);
            }
            first = false;
        }
        const QRegExp regExp(keyRegExp, Qt::CaseSensitive);

        foreach (TextEditor::CompletionItem item, m_completions) {
            if (regExp.indexIn(item.m_text) == 0) {
                item.m_relevance = (key.length() > 0 &&
                                    item.m_text.startsWith(key, Qt::CaseInsensitive)) ? 1 : 0;
                (*completions) << item;
            }
        }
    }
}

void QmlCodeCompletion::complete(const TextEditor::CompletionItem &item)
{
    const QString toInsert = item.m_text;
    const int length = m_editor->position() - m_startPosition;
    m_editor->setCurPos(m_startPosition);
    m_editor->replace(length, toInsert);
}

bool QmlCodeCompletion::partiallyComplete(const QList<TextEditor::CompletionItem> &completionItems)
{
    if (completionItems.count() == 1) {
        complete(completionItems.first());
        return true;
    } else {
        // Compute common prefix
        QString firstKey = completionItems.first().m_text;
        QString lastKey = completionItems.last().m_text;
        const int length = qMin(firstKey.length(), lastKey.length());
        firstKey.truncate(length);
        lastKey.truncate(length);

        while (firstKey != lastKey) {
            firstKey.chop(1);
            lastKey.chop(1);
        }

        int typedLength = m_editor->position() - m_startPosition;
        if (!firstKey.isEmpty() && firstKey.length() > typedLength) {
            m_editor->setCurPos(m_startPosition);
            m_editor->replace(typedLength, firstKey);
        }
    }
    return false;
}

void QmlCodeCompletion::cleanup()
{
    m_editor = 0;
    m_startPosition = 0;
    m_completions.clear();
}

<commit_msg>QmlEditor: Fix compilation on Windows.<commit_after>#include "qmlcodecompletion.h"
#include "qmleditor.h"
#include "qmlmodelmanagerinterface.h"
#include "qmlexpressionundercursor.h"
#include "qmllookupcontext.h"
#include "qmlresolveexpression.h"
#include "qmlsymbol.h"

#include <texteditor/basetexteditor.h>
#include <QtDebug>

using namespace QmlEditor;
using namespace QmlEditor::Internal;

QmlCodeCompletion::QmlCodeCompletion(QmlModelManagerInterface *modelManager,QObject *parent)
    : TextEditor::ICompletionCollector(parent),
      m_modelManager(modelManager),
      m_editor(0),
      m_startPosition(0),
      m_caseSensitivity(Qt::CaseSensitive)
{
    Q_ASSERT(modelManager);
}

QmlCodeCompletion::~QmlCodeCompletion()
{ }

Qt::CaseSensitivity QmlCodeCompletion::caseSensitivity() const
{ return m_caseSensitivity; }

void QmlCodeCompletion::setCaseSensitivity(Qt::CaseSensitivity caseSensitivity)
{ m_caseSensitivity = caseSensitivity; }

bool QmlCodeCompletion::supportsEditor(TextEditor::ITextEditable *editor)
{
    if (qobject_cast<ScriptEditor *>(editor->widget()))
        return true;

    return false;
}

bool QmlCodeCompletion::triggersCompletion(TextEditor::ITextEditable *)
{ return false; }

int QmlCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
{
    m_editor = editor;

    ScriptEditor *edit = qobject_cast<ScriptEditor *>(m_editor->widget());
    if (! edit)
        return -1;

    int pos = editor->position();

    while (editor->characterAt(pos - 1).isLetterOrNumber() || editor->characterAt(pos - 1) == QLatin1Char('_'))
        --pos;

    m_startPosition = pos;
    m_completions.clear();

//    foreach (const QString &word, edit->keywords()) {
//        TextEditor::CompletionItem item(this);
//        item.m_text = word;
//        m_completions.append(item);
//    }
//
//    foreach (const QString &word, edit->words()) {
//        TextEditor::CompletionItem item(this);
//        item.m_text = word;
//        m_completions.append(item);
//    }

    QmlDocument::Ptr qmlDocument = edit->qmlDocument();
//    qDebug() << "*** document:" << qmlDocument;
    if (qmlDocument.isNull())
        return pos;

    if (!qmlDocument->program())
        qmlDocument = m_modelManager->snapshot().value(qmlDocument->fileName());

    if (qmlDocument->program()) {
         QmlJS::AST::UiProgram *program = qmlDocument->program();
//        qDebug() << "*** program:" << program;

         if (program) {
            QmlExpressionUnderCursor expressionUnderCursor;
            QTextCursor cursor(edit->document());
            cursor.setPosition(pos);
            expressionUnderCursor(cursor, qmlDocument);

            QmlLookupContext context(expressionUnderCursor.expressionScopes(), qmlDocument, m_modelManager->snapshot());
            QmlResolveExpression resolver(context);
            QList<QmlSymbol*> symbols = resolver.visibleSymbols(expressionUnderCursor.expressionNode());

            foreach (QmlSymbol *symbol, symbols) {
                QString word;

                if (symbol->isIdSymbol()) {
                    word = symbol->asIdSymbol()->id();
                } else {
                    word = symbol->name();
                }

                if (word.isEmpty())
                    continue;

                TextEditor::CompletionItem item(this);
                item.m_text = word;
                m_completions.append(item);
            }
        }
    }

    return pos;
}

void QmlCodeCompletion::completions(QList<TextEditor::CompletionItem> *completions)
{
    // ### FIXME: this code needs to be generalized.

    const int length = m_editor->position() - m_startPosition;

    if (length == 0)
        *completions = m_completions;
    else if (length > 0) {
        const QString key = m_editor->textAt(m_startPosition, length);

        /*
         * This code builds a regular expression in order to more intelligently match
         * camel-case style. This means upper-case characters will be rewritten as follows:
         *
         *   A => [a-z0-9_]*A (for any but the first capital letter)
         *
         * Meaning it allows any sequence of lower-case characters to preceed an
         * upper-case character. So for example gAC matches getActionController.
         */
        QString keyRegExp;
        keyRegExp += QLatin1Char('^');
        bool first = true;
        foreach (const QChar &c, key) {
            if (c.isUpper() && !first) {
                keyRegExp += QLatin1String("[a-z0-9_]*");
                keyRegExp += c;
            } else if (m_caseSensitivity == Qt::CaseInsensitive && c.isLower()) {
                keyRegExp += QLatin1Char('[');
                keyRegExp += c;
                keyRegExp += c.toUpper();
                keyRegExp += QLatin1Char(']');
            } else {
                keyRegExp += QRegExp::escape(c);
            }
            first = false;
        }
        const QRegExp regExp(keyRegExp, Qt::CaseSensitive);

        foreach (TextEditor::CompletionItem item, m_completions) {
            if (regExp.indexIn(item.m_text) == 0) {
                item.m_relevance = (key.length() > 0 &&
                                    item.m_text.startsWith(key, Qt::CaseInsensitive)) ? 1 : 0;
                (*completions) << item;
            }
        }
    }
}

void QmlCodeCompletion::complete(const TextEditor::CompletionItem &item)
{
    const QString toInsert = item.m_text;
    const int length = m_editor->position() - m_startPosition;
    m_editor->setCurPos(m_startPosition);
    m_editor->replace(length, toInsert);
}

bool QmlCodeCompletion::partiallyComplete(const QList<TextEditor::CompletionItem> &completionItems)
{
    if (completionItems.count() == 1) {
        complete(completionItems.first());
        return true;
    } else {
        // Compute common prefix
        QString firstKey = completionItems.first().m_text;
        QString lastKey = completionItems.last().m_text;
        const int length = qMin(firstKey.length(), lastKey.length());
        firstKey.truncate(length);
        lastKey.truncate(length);

        while (firstKey != lastKey) {
            firstKey.chop(1);
            lastKey.chop(1);
        }

        int typedLength = m_editor->position() - m_startPosition;
        if (!firstKey.isEmpty() && firstKey.length() > typedLength) {
            m_editor->setCurPos(m_startPosition);
            m_editor->replace(typedLength, firstKey);
        }
    }
    return false;
}

void QmlCodeCompletion::cleanup()
{
    m_editor = 0;
    m_startPosition = 0;
    m_completions.clear();
}

<|endoftext|>