<commit_before>#include "popupwidget.h"
#include "ui_popupwidget.h"
#include <QDebug>
#include <QCloseEvent>
#include <QWebFrame>
#include <QTimer>

const int PopupWidget::weblioPosition = 330;

PopupWidget::PopupWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::PopupWidget)
{
    ui->setupUi(this);

    isScrolled = false;
    canToggle  = true;
    shortcut = new QxtGlobalShortcut(this);
    if (!shortcut->setShortcut(QKeySequence("Ctrl+F12"))) {
        qWarning() << "Ctrl+12 is already assigned!";
    } else {
        connect(shortcut, SIGNAL(activated()),
                this,     SLOT(toggleShowUp()));\
        setupTray();
    }
}

PopupWidget::~PopupWidget()
{
    delete ui;
}

void PopupWidget::toggleShowUp()
{
    if (!canToggle) return;

    if (isVisible()) {
//        qDebug() << "hide";
        hide();
        canToggle = false;
        QTimer::singleShot(500, this, SLOT(enableToggle()));
    } else {
//        qDebug() << "show";
        // Open Display
        setWindowFlags(Qt::WindowStaysOnTopHint);
        activateWindow(); //qApp->setActiveWindow()も必要
        qApp->setActiveWindow(this); //activateWindow()も必要
        showNormal();

        ui->lineEdit->setFocus();
        canToggle = false;
        QTimer::singleShot(500, this, SLOT(enableToggle()));
    }
}

void PopupWidget::setupTray()
{
    setupTrayMenu();
    trayIcon = new QSystemTrayIcon(this);
    trayIcon->setContextMenu(trayMenu);
    trayIcon->setIcon(QIcon(":/img/icon.svg"));
    trayIcon->show();
}

void PopupWidget::setupTrayMenu()
{
    quitAction = new QAction(tr("&Quit"), this);
    connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
    trayMenu = new QMenu(this);
    trayMenu->addAction(quitAction);
}

void PopupWidget::closeEvent(QCloseEvent *event)
{
    if (trayIcon->isVisible()) {
        hide();
        event->ignore();
    }
}

void PopupWidget::search(QString word)
{
    QUrl url = QUrl(QString("http://ejje.weblio.jp/content/") + word);
    qDebug() << url;
    ui->webView->load(url);
    emit urlChanged(url);
}

void PopupWidget::search()
{
    QString word = ui->lineEdit->text();
    QUrl url = QUrl(QString("http://ejje.weblio.jp/content/") + word);
    qDebug() << url;
    ui->webView->load(url);
    emit urlChanged(url);
}

void PopupWidget::on_webView_loadProgress(int progress)
{
    Q_UNUSED(progress)
    if (!isScrolled) {
        QWebFrame *frame = ui->webView->page()->mainFrame();
        int min = frame->scrollBarMinimum(Qt::Vertical);
        int max = frame->scrollBarMaximum(Qt::Vertical);
        qDebug() << "Max=" << max << " Min=" << min;
        if (max > weblioPosition) {
            frame->setScrollBarValue(Qt::Vertical, weblioPosition);
//            qDebug() << "Scroll";
            isScrolled = true;
        }
    }
}

void PopupWidget::on_webView_loadStarted()
{
    isScrolled = false;
}

void PopupWidget::on_actionSearch_triggered()
{
    search();
}

<commit_msg>commentouted unncessary messages<commit_after>#include "popupwidget.h"
#include "ui_popupwidget.h"
#include <QDebug>
#include <QCloseEvent>
#include <QWebFrame>
#include <QTimer>

const int PopupWidget::weblioPosition = 330;

PopupWidget::PopupWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::PopupWidget)
{
    ui->setupUi(this);

    isScrolled = false;
    canToggle  = true;
    shortcut = new QxtGlobalShortcut(this);
    if (!shortcut->setShortcut(QKeySequence("Ctrl+F12"))) {
        qWarning() << "Ctrl+12 is already assigned!";
    } else {
        connect(shortcut, SIGNAL(activated()),
                this,     SLOT(toggleShowUp()));\
        setupTray();
    }
}

PopupWidget::~PopupWidget()
{
    delete ui;
}

void PopupWidget::toggleShowUp()
{
    if (!canToggle) return;

    if (isVisible()) {
//        qDebug() << "hide";
        hide();
        canToggle = false;
        QTimer::singleShot(500, this, SLOT(enableToggle()));
    } else {
//        qDebug() << "show";
        // Open Display
        setWindowFlags(Qt::WindowStaysOnTopHint);
        activateWindow(); //qApp->setActiveWindow()も必要
        qApp->setActiveWindow(this); //activateWindow()も必要
        showNormal();

        ui->lineEdit->setFocus();
        canToggle = false;
        QTimer::singleShot(500, this, SLOT(enableToggle()));
    }
}

void PopupWidget::setupTray()
{
    setupTrayMenu();
    trayIcon = new QSystemTrayIcon(this);
    trayIcon->setContextMenu(trayMenu);
    trayIcon->setIcon(QIcon(":/img/icon.svg"));
    trayIcon->show();
}

void PopupWidget::setupTrayMenu()
{
    quitAction = new QAction(tr("&Quit"), this);
    connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
    trayMenu = new QMenu(this);
    trayMenu->addAction(quitAction);
}

void PopupWidget::closeEvent(QCloseEvent *event)
{
    if (trayIcon->isVisible()) {
        hide();
        event->ignore();
    }
}

void PopupWidget::search(QString word)
{
    QUrl url = QUrl(QString("http://ejje.weblio.jp/content/") + word);
//    qDebug() << url;
    ui->webView->load(url);
    emit urlChanged(url);
}

void PopupWidget::search()
{
    QString word = ui->lineEdit->text();
    QUrl url = QUrl(QString("http://ejje.weblio.jp/content/") + word);
//    qDebug() << url;
    ui->webView->load(url);
    emit urlChanged(url);
}

void PopupWidget::on_webView_loadProgress(int progress)
{
    Q_UNUSED(progress)
    if (!isScrolled) {
        QWebFrame *frame = ui->webView->page()->mainFrame();
//        int min = frame->scrollBarMinimum(Qt::Vertical);
        int max = frame->scrollBarMaximum(Qt::Vertical);
//        qDebug() << "Max=" << max << " Min=" << min;
        if (max > weblioPosition) {
            frame->setScrollBarValue(Qt::Vertical, weblioPosition);
//            qDebug() << "Scroll";
            isScrolled = true;
        }
    }
}

void PopupWidget::on_webView_loadStarted()
{
    isScrolled = false;
}

void PopupWidget::on_actionSearch_triggered()
{
    search();
}

<|endoftext|>


<commit_before>#include "encoder.hh"
#include "../format/format-stream.hh"

namespace mimosa
{
  namespace json
  {
    Encoder::Encoder(stream::Stream::Ptr output)
      : output_(output)
    {
    }

    bool
    Encoder::startObject()
    {
      if (!state_.empty() && state_.back() == kObjectKey)
        throw SyntaxError();

      if (!pushSeparator())
        return false;

      if (output_->loopWrite("{", 1) != 1)
        return false;
      state_.push_back(kObjectKey);
      return true;
    }

    bool
    Encoder::endObject()
    {
      if (state_.empty() ||
          (state_.back() != kObjectKey && state_.back() != kObjectNext))
        throw SyntaxError();

      if (output_->loopWrite("}", 1) != 1)
        return false;

      state_.pop_back();
      nextState();
      return true;
    }

    bool
    Encoder::startArray()
    {
      if (!state_.empty() && state_.back() == kObjectKey)
        throw SyntaxError();

      if (!pushSeparator())
        return false;

      if (output_->loopWrite("[", 1) != 1)
        return false;

      state_.push_back(kArray);
      return true;
    }

    bool
    Encoder::endArray()
    {
      if (state_.empty() || (state_.back() != kArray && state_.back() != kArrayNext))
        throw SyntaxError();

      if (output_->loopWrite("]", 1) != 1)
        return false;

      state_.pop_back();
      nextState();
      return true;
    }

    bool
    Encoder::pushBoolean(bool value)
    {
      if (!state_.empty() && state_.back() == kObjectKey)
        throw SyntaxError();

      if (!pushSeparator())
        return false;

      if ((value && output_->loopWrite("true", 4) != 4) ||
          (!value && output_->loopWrite("false", 5) != 5))
        return false;

      nextState();
      return true;
    }

    bool
    Encoder::pushNull()
    {
      if (!state_.empty() && state_.back() == kObjectKey)
        throw SyntaxError();

      if (!pushSeparator())
        return false;

      if (output_->loopWrite("null", 4) != 4)
        return false;

      nextState();
      return true;
    }

    bool
    Encoder::pushString(const std::string & data)
    {
      if (!pushSeparator())
        return false;

      if (output_->loopWrite("\"", 1) != 1)
        return false;

      // XXX do it better
      for (auto it = data.begin(); it != data.end(); ++it) {
        if (*it == '\\' || *it == '"')
          if (output_->loopWrite("\\", 1) != 1)
            return false;

        switch (*it) {
        case '\r':
          if (output_->loopWrite("\\r", 2) != 2)
            return false;
          break;

        case '\n':
          if (output_->loopWrite("\\n", 2) != 2)
            return false;
          break;

        case '\t':
          if (output_->loopWrite("\\t", 2) != 2)
            return false;
          break;

        case '\v':
          if (output_->loopWrite("\\v", 2) != 2)
            return false;
          break;

        case '\\':
        case '"':
          if (output_->loopWrite("\\", 1) != 1)
            return false;
          /* fall through */

        default:
          if (output_->loopWrite(&*it, 1) != 1)
            return false;
        }
      }

      if (output_->loopWrite("\"", 1) != 1)
        return false;

      nextState();
      return true;
    }

    bool
    Encoder::pushNumber(int64_t value)
    {
      if (!state_.empty() && state_.back() == kObjectKey)
        throw SyntaxError();

      if (!pushSeparator())
        return false;

      if (!format::format(*output_, "%d", value))
        return false;

      nextState();
      return true;
    }

    bool
    Encoder::pushFloat(double value)
    {
      if (!state_.empty() && state_.back() == kObjectKey)
        throw SyntaxError();

      if (!pushSeparator())
        return false;

      if (!format::format(*output_, "%v", value))
        return false;

      nextState();
      return true;
    }

    bool
    Encoder::pushSeparator()
    {
      if (state_.empty())
        return true;

      switch (state_.back()) {
      case kArray:
      case kObjectKey:
        return true;

      case kArrayNext:
        if (output_->loopWrite(",", 1) != 1)
          return false;
        state_.back() = kArray;
        return true;

      case kObjectNext:
        if (output_->loopWrite(",", 1) != 1)
          return false;
        state_.back() = kObjectKey;
        return true;

      case kObjectValue:
        return output_->loopWrite(":", 1) == 1;

      default:
        return true;
      }
    }

    void
    Encoder::nextState()
    {
      if (state_.empty())
        return;

      switch (state_.back()) {
      case kArray:
        state_.back() = kArrayNext;
        break;

      case kArrayNext:
        break;

      case kObjectKey:
        state_.back() = kObjectValue;
        break;

      case kObjectValue:
        state_.back() = kObjectNext;
        break;

      case kObjectNext:
        state_.back() = kObjectKey;
        break;

      default:
        break;
      }
    }
  }
}
<commit_msg>json:encoder: \b support<commit_after>#include "encoder.hh"
#include "../format/format-stream.hh"

namespace mimosa
{
  namespace json
  {
    Encoder::Encoder(stream::Stream::Ptr output)
      : output_(output)
    {
    }

    bool
    Encoder::startObject()
    {
      if (!state_.empty() && state_.back() == kObjectKey)
        throw SyntaxError();

      if (!pushSeparator())
        return false;

      if (output_->loopWrite("{", 1) != 1)
        return false;
      state_.push_back(kObjectKey);
      return true;
    }

    bool
    Encoder::endObject()
    {
      if (state_.empty() ||
          (state_.back() != kObjectKey && state_.back() != kObjectNext))
        throw SyntaxError();

      if (output_->loopWrite("}", 1) != 1)
        return false;

      state_.pop_back();
      nextState();
      return true;
    }

    bool
    Encoder::startArray()
    {
      if (!state_.empty() && state_.back() == kObjectKey)
        throw SyntaxError();

      if (!pushSeparator())
        return false;

      if (output_->loopWrite("[", 1) != 1)
        return false;

      state_.push_back(kArray);
      return true;
    }

    bool
    Encoder::endArray()
    {
      if (state_.empty() || (state_.back() != kArray && state_.back() != kArrayNext))
        throw SyntaxError();

      if (output_->loopWrite("]", 1) != 1)
        return false;

      state_.pop_back();
      nextState();
      return true;
    }

    bool
    Encoder::pushBoolean(bool value)
    {
      if (!state_.empty() && state_.back() == kObjectKey)
        throw SyntaxError();

      if (!pushSeparator())
        return false;

      if ((value && output_->loopWrite("true", 4) != 4) ||
          (!value && output_->loopWrite("false", 5) != 5))
        return false;

      nextState();
      return true;
    }

    bool
    Encoder::pushNull()
    {
      if (!state_.empty() && state_.back() == kObjectKey)
        throw SyntaxError();

      if (!pushSeparator())
        return false;

      if (output_->loopWrite("null", 4) != 4)
        return false;

      nextState();
      return true;
    }

    bool
    Encoder::pushString(const std::string & data)
    {
      if (!pushSeparator())
        return false;

      if (output_->loopWrite("\"", 1) != 1)
        return false;

      for (auto it = data.begin(); it != data.end(); ++it) {
        if (*it == '\\' || *it == '"')
          if (output_->loopWrite("\\", 1) != 1)
            return false;

        switch (*it) {
        case '\r':
          if (output_->loopWrite("\\r", 2) != 2)
            return false;
          break;

        case '\n':
          if (output_->loopWrite("\\n", 2) != 2)
            return false;
          break;

        case '\t':
          if (output_->loopWrite("\\t", 2) != 2)
            return false;
          break;

        case '\v':
          if (output_->loopWrite("\\v", 2) != 2)
            return false;
          break;

        case '\b':
          if (output_->loopWrite("\\b", 2) != 2)
            return false;
          break;

        case '\\':
        case '"':
          if (output_->loopWrite("\\", 1) != 1)
            return false;
          /* fall through */

        default:
          if (output_->loopWrite(&*it, 1) != 1)
            return false;
        }
      }

      if (output_->loopWrite("\"", 1) != 1)
        return false;

      nextState();
      return true;
    }

    bool
    Encoder::pushNumber(int64_t value)
    {
      if (!state_.empty() && state_.back() == kObjectKey)
        throw SyntaxError();

      if (!pushSeparator())
        return false;

      if (!format::format(*output_, "%d", value))
        return false;

      nextState();
      return true;
    }

    bool
    Encoder::pushFloat(double value)
    {
      if (!state_.empty() && state_.back() == kObjectKey)
        throw SyntaxError();

      if (!pushSeparator())
        return false;

      if (!format::format(*output_, "%v", value))
        return false;

      nextState();
      return true;
    }

    bool
    Encoder::pushSeparator()
    {
      if (state_.empty())
        return true;

      switch (state_.back()) {
      case kArray:
      case kObjectKey:
        return true;

      case kArrayNext:
        if (output_->loopWrite(",", 1) != 1)
          return false;
        state_.back() = kArray;
        return true;

      case kObjectNext:
        if (output_->loopWrite(",", 1) != 1)
          return false;
        state_.back() = kObjectKey;
        return true;

      case kObjectValue:
        return output_->loopWrite(":", 1) == 1;

      default:
        return true;
      }
    }

    void
    Encoder::nextState()
    {
      if (state_.empty())
        return;

      switch (state_.back()) {
      case kArray:
        state_.back() = kArrayNext;
        break;

      case kArrayNext:
        break;

      case kObjectKey:
        state_.back() = kObjectValue;
        break;

      case kObjectValue:
        state_.back() = kObjectNext;
        break;

      case kObjectNext:
        state_.back() = kObjectKey;
        break;

      default:
        break;
      }
    }
  }
}
<|endoftext|>


<commit_before>/*
 *  main.cpp
 *  Program:  kalarm
 *  (C) 2001 - 2004 by David Jarvie <software@astrojar.org.uk>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 *  In addition, as a special exception, the copyright holders give permission
 *  to link the code of this program with any edition of the Qt library by
 *  Trolltech AS, Norway (or with modified versions of Qt that use the same
 *  license as Qt), and distribute linked combinations including the two.
 *  You must obey the GNU General Public License in all respects for all of
 *  the code used other than Qt.  If you modify this file, you may extend
 *  this exception to your version of the file, but you are not obligated to
 *  do so. If you do not wish to do so, delete this exception statement from
 *  your version.
 */

#include "kalarm.h"

#include <stdlib.h>

#include <kcmdlineargs.h>
#include <kaboutdata.h>
#include <klocale.h>
#include <kdebug.h>

#include "kalarmapp.h"

#define PROGRAM_NAME "kalarm"

static KCmdLineOptions options[] =
{
	{ "a", 0, 0 },
	{ "ack-confirm", I18N_NOOP("Prompt for confirmation when alarm is acknowledged"), 0 },
	{ "A", 0, 0 },
	{ "attach <url>", I18N_NOOP("Attach file to email (repeat as needed)"), 0 },
	{ "bcc", I18N_NOOP("Blind copy email to self"), 0 },
	{ "b", 0, 0 },
	{ "beep", I18N_NOOP("Beep when message is displayed"), 0 },
	{ "colour", 0, 0 },
	{ "c", 0, 0 },
	{ "color <color>", I18N_NOOP("Message background color (name or hex 0xRRGGBB)"), 0 },
	{ "colourfg", 0, 0 },
	{ "C", 0, 0 },
	{ "colorfg <color>", I18N_NOOP("Message foreground color (name or hex 0xRRGGBB)"), 0 },
	{ "calendarURL <url>", I18N_NOOP("URL of calendar file"), 0 },
	{ "cancelEvent <eventID>", I18N_NOOP("Cancel alarm with the specified event ID"), 0 },
	{ "e", 0, 0 },
	{ "exec <commandline>", I18N_NOOP("Execute a shell command line"), 0 },
	{ "f", 0, 0 },
	{ "file <url>", I18N_NOOP("File to display"), 0 },
	{ "handleEvent <eventID>", I18N_NOOP("Trigger or cancel alarm with the specified event ID"), 0 },
	{ "i", 0, 0 },
	{ "interval <period>", I18N_NOOP("Interval between alarm recurrences"), 0 },
	{ "l", 0, 0 },
	{ "late-cancel", I18N_NOOP("Cancel alarm if it cannot be triggered on time"), 0 },
#if 0
	{ "auto-close", I18N_NOOP("Auto-close alarm window after --late-cancel period"), 0 },
	{ "disable", I18N_NOOP("Disable the alarm"), 0 },
	{ "late-cancel <period>", I18N_NOOP("Cancel alarm if more than 'period' late when triggered"), "1" },
#endif
	{ "L", 0, 0 },
	{ "login", I18N_NOOP("Repeat alarm at every login"), 0 },
	{ "m", 0, 0 },
	{ "mail <address>", I18N_NOOP("Send an email to the given address (repeat as needed)"), 0 },
	{ "p", 0, 0 },
	{ "play <url>", I18N_NOOP("Audio file to play once"), 0 },
#ifndef WITHOUT_ARTS
	{ "P", 0, 0 },
	{ "play-repeat <url>", I18N_NOOP("Audio file to play repeatedly"), 0 },
#endif
	{ "recurrence <spec>", I18N_NOOP("Specify alarm recurrence using iCalendar syntax"), 0 },
	{ "R", 0, 0 },
	{ "reminder <period>", I18N_NOOP("Display reminder in advance of alarm"), 0 },
	{ "reminder-once <period>", I18N_NOOP("Display reminder once, before first alarm recurrence"), 0 },
	{ "r", 0, 0 },
	{ "repeat <count>", I18N_NOOP("Number of times to repeat alarm (after the initial occasion)"), 0 },
	{ "reset", I18N_NOOP("Reset the alarm scheduling daemon"), 0 },
	{ "stop", I18N_NOOP("Stop the alarm scheduling daemon"), 0 },
	{ "S", 0, 0 },
	{ "subject ", I18N_NOOP("Email subject line"), 0 },
	{ "t", 0, 0 },
	{ "time <time>", I18N_NOOP("Trigger alarm at time [[[yyyy-]mm-]dd-]hh:mm, or date yyyy-mm-dd"), 0 },
	{ "tray", I18N_NOOP("Display system tray icon"), 0 },
	{ "triggerEvent <eventID>", I18N_NOOP("Trigger alarm with the specified event ID"), 0 },
	{ "u", 0, 0 },
	{ "until <time>", I18N_NOOP("Repeat until time [[[yyyy-]mm-]dd-]hh:mm, or date yyyy-mm-dd"), 0 },
#ifndef WITHOUT_ARTS
	{ "v", 0, 0 },
	{ "volume <percent>", I18N_NOOP("Volume to play audio file"), 0 },
#endif
	{ "+[message]", I18N_NOOP("Message text to display"), 0 },
	KCmdLineLastOption
};

int main(int argc, char *argv[])
{
	KAboutData aboutData(PROGRAM_NAME, I18N_NOOP("KAlarm"), KALARM_VERSION,
		I18N_NOOP("Personal alarm message, command and email scheduler for KDE"),
		KAboutData::License_GPL,
		"(c) 2001 - 2004, David Jarvie", 0, "http://www.astrojar.org.uk/linux/kalarm.html");
	aboutData.addAuthor("David Jarvie", 0, "software@astrojar.org.uk");

	// Fetch all command line options/arguments after --exec and
	// concatenate them into a single argument.
	// This is necessary because the "!" indicator in the 'options'
	// array above doesn't work (on KDE2, at least)
	int    newargc = argc;
	char** newargv = argv;
	for (int i = 0;  i < argc;  ++i)
	{
		if (!strcmp(argv[i], "-e") || !strcmp(argv[i], "--exec"))
		{
			// --exec has been found. Create a new args list.
			newargc = i + 1;
			newargv = (char**)malloc(newargc * sizeof(char*));
			for (int j = 0;  j < newargc;  ++j)
				newargv[j] = argv[j];
			// Concatenate the --exec arguments into one
			QCString execArguments;
			while (++i < argc)
			{
				execArguments += argv[i];
				if (i < argc - 1)
					execArguments += ' ';
			}
			i = execArguments.length();
			newargv[newargc] = (char*)malloc(i + 1);
			memcpy(newargv[newargc], static_cast<const char*>(execArguments), i);
			newargv[newargc][i] = 0;
			++newargc;
			break;
		}
	}
	KCmdLineArgs::init(newargc, newargv, &aboutData);
	KCmdLineArgs::addCmdLineOptions(options);
	KUniqueApplication::addCmdLineOptions();

	if (!KAlarmApp::start())
	{
		// An instance of the application is already running
		exit(0);
	}

	// This is the first time through
	kdDebug(5950) << "main(): initialising\n";
	KAlarmApp* app = KAlarmApp::getInstance();
	app->restoreSession();
	return app->exec();
}
<commit_msg>Fix option descriptions<commit_after>/*
 *  main.cpp
 *  Program:  kalarm
 *  (C) 2001 - 2004 by David Jarvie <software@astrojar.org.uk>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include "kalarm.h"

#include <stdlib.h>

#include <kcmdlineargs.h>
#include <kaboutdata.h>
#include <klocale.h>
#include <kdebug.h>

#include "kalarmapp.h"

#define PROGRAM_NAME "kalarm"

static KCmdLineOptions options[] =
{
	{ "a", 0, 0 },
	{ "ack-confirm", I18N_NOOP("Prompt for confirmation when alarm is acknowledged"), 0 },
	{ "A", 0, 0 },
	{ "attach <url>", I18N_NOOP("Attach file to email (repeat as needed)"), 0 },
	{ "bcc", I18N_NOOP("Blind copy email to self"), 0 },
	{ "b", 0, 0 },
	{ "beep", I18N_NOOP("Beep when message is displayed"), 0 },
	{ "colour", 0, 0 },
	{ "c", 0, 0 },
	{ "color <color>", I18N_NOOP("Message background color (name or hex 0xRRGGBB)"), 0 },
	{ "colourfg", 0, 0 },
	{ "C", 0, 0 },
	{ "colorfg <color>", I18N_NOOP("Message foreground color (name or hex 0xRRGGBB)"), 0 },
	{ "calendarURL <url>", I18N_NOOP("URL of calendar file"), 0 },
	{ "cancelEvent <eventID>", I18N_NOOP("Cancel alarm with the specified event ID"), 0 },
	{ "e", 0, 0 },
	{ "exec <commandline>", I18N_NOOP("Execute a shell command line"), 0 },
	{ "f", 0, 0 },
	{ "file <url>", I18N_NOOP("File to display"), 0 },
	{ "handleEvent <eventID>", I18N_NOOP("Trigger or cancel alarm with the specified event ID"), 0 },
	{ "i", 0, 0 },
	{ "interval <period>", I18N_NOOP("Interval between alarm repetitions"), 0 },
	{ "l", 0, 0 },
	{ "late-cancel", I18N_NOOP("Cancel alarm if it cannot be triggered on time"), 0 },
#if 0
	{ "auto-close", I18N_NOOP("Auto-close alarm window after --late-cancel period"), 0 },
	{ "disable", I18N_NOOP("Disable the alarm"), 0 },
	{ "late-cancel <period>", I18N_NOOP("Cancel alarm if more than 'period' late when triggered"), "1" },
#endif
	{ "L", 0, 0 },
	{ "login", I18N_NOOP("Repeat alarm at every login"), 0 },
	{ "m", 0, 0 },
	{ "mail <address>", I18N_NOOP("Send an email to the given address (repeat as needed)"), 0 },
	{ "p", 0, 0 },
	{ "play <url>", I18N_NOOP("Audio file to play once"), 0 },
#ifndef WITHOUT_ARTS
	{ "P", 0, 0 },
	{ "play-repeat <url>", I18N_NOOP("Audio file to play repeatedly"), 0 },
#endif
	{ "recurrence <spec>", I18N_NOOP("Specify alarm recurrence using iCalendar syntax"), 0 },
	{ "R", 0, 0 },
	{ "reminder <period>", I18N_NOOP("Display reminder in advance of alarm"), 0 },
	{ "reminder-once <period>", I18N_NOOP("Display reminder once, before first alarm recurrence"), 0 },
	{ "r", 0, 0 },
	{ "repeat <count>", I18N_NOOP("Number of times to repeat alarm (including initial occasion)"), 0 },
	{ "reset", I18N_NOOP("Reset the alarm scheduling daemon"), 0 },
	{ "stop", I18N_NOOP("Stop the alarm scheduling daemon"), 0 },
	{ "S", 0, 0 },
	{ "subject ", I18N_NOOP("Email subject line"), 0 },
	{ "t", 0, 0 },
	{ "time <time>", I18N_NOOP("Trigger alarm at time [[[yyyy-]mm-]dd-]hh:mm, or date yyyy-mm-dd"), 0 },
	{ "tray", I18N_NOOP("Display system tray icon"), 0 },
	{ "triggerEvent <eventID>", I18N_NOOP("Trigger alarm with the specified event ID"), 0 },
	{ "u", 0, 0 },
	{ "until <time>", I18N_NOOP("Repeat until time [[[yyyy-]mm-]dd-]hh:mm, or date yyyy-mm-dd"), 0 },
#ifndef WITHOUT_ARTS
	{ "v", 0, 0 },
	{ "volume <percent>", I18N_NOOP("Volume to play audio file"), 0 },
#endif
	{ "+[message]", I18N_NOOP("Message text to display"), 0 },
	KCmdLineLastOption
};

int main(int argc, char *argv[])
{
	KAboutData aboutData(PROGRAM_NAME, I18N_NOOP("KAlarm"), KALARM_VERSION,
		I18N_NOOP("Personal alarm message, command and email scheduler for KDE"),
		KAboutData::License_GPL,
		"(c) 2001 - 2004, David Jarvie", 0, "http://www.astrojar.org.uk/linux/kalarm.html");
	aboutData.addAuthor("David Jarvie", 0, "software@astrojar.org.uk");

	// Fetch all command line options/arguments after --exec and
	// concatenate them into a single argument.
	// This is necessary because the "!" indicator in the 'options'
	// array above doesn't work (on KDE2, at least)
	int    newargc = argc;
	char** newargv = argv;
	for (int i = 0;  i < argc;  ++i)
	{
		if (!strcmp(argv[i], "-e") || !strcmp(argv[i], "--exec"))
		{
			// --exec has been found. Create a new args list.
			newargc = i + 1;
			newargv = (char**)malloc(newargc * sizeof(char*));
			for (int j = 0;  j < newargc;  ++j)
				newargv[j] = argv[j];
			// Concatenate the --exec arguments into one
			QCString execArguments;
			while (++i < argc)
			{
				execArguments += argv[i];
				if (i < argc - 1)
					execArguments += ' ';
			}
			i = execArguments.length();
			newargv[newargc] = (char*)malloc(i + 1);
			memcpy(newargv[newargc], static_cast<const char*>(execArguments), i);
			newargv[newargc][i] = 0;
			++newargc;
			break;
		}
	}
	KCmdLineArgs::init(newargc, newargv, &aboutData);
	KCmdLineArgs::addCmdLineOptions(options);
	KUniqueApplication::addCmdLineOptions();

	if (!KAlarmApp::start())
	{
		// An instance of the application is already running
		exit(0);
	}

	// This is the first time through
	kdDebug(5950) << "main(): initialising\n";
	KAlarmApp* app = KAlarmApp::getInstance();
	app->restoreSession();
	return app->exec();
}
<|endoftext|>


<commit_before>#include <scheduler/pthread-coro.hh>

#if defined SCHEDULER_CORO_OSTHREAD

#  include <cerrno>

#  include <libport/config.h>
#  include <libport/assert.hh>
#  include <libport/compiler.hh>
#  include <libport/semaphore.hh>
#  include <libport/thread.hh>

#  include <kernel/kernconf.hh>
#  include <scheduler/coroutine.hh>

/* Os-thread implementation of coroutines, using semaphores to ensure
   that only one coroutine is running at the same time.  */

Coro::Coro()
  : die_(false)
{}

Coro*
coroutine_new(size_t)
{
  return new Coro;
}

void
coroutine_free(Coro* c)
{
  c->die_ = true;
  c->sem_++;
}

void
coroutine_start(Coro* self, Coro* other,
                void (*callback)(void*), void* context)
{
#if defined WIN32
  unsigned long id;
  void* r =
    CreateThread(NULL, 0,
                 reinterpret_cast<void* (*)(void*)>(callback), context,
                 0, &id);
#else
  // Adjust to the requested stack size.
  static pthread_attr_t attr;
  static bool first = true;
  if (first)
  {
    first = false;
    if (pthread_attr_init(&attr))
      errabort("pthread_attr_init");

    if (pthread_attr_setstacksize(&attr, kernconf.default_stack_size))
      errabort("pthread_attr_setstacksize");
  }

  if (pthread_create(&other->thread_, &attr,
		     reinterpret_cast<void* (*)(void*)>(callback), context))
    errabort("pthread_create");
#endif
  self->sem_--;
}

void
coroutine_switch_to(Coro* self, Coro* next)
{
  next->sem_++;
  self->sem_--;
  if (self->die_)
  {
    delete self;
    pthread_exit(0);
  }
}

bool
coroutine_stack_space_almost_gone(Coro*)
{
  return false;
}

void
coroutine_initialize_main(Coro*)
{
}

#endif //! SCHEDULER_CORO_OSTHREAD
<commit_msg>Terminate job synchronously even in pthreads mode.<commit_after>#include <scheduler/pthread-coro.hh>

#if defined SCHEDULER_CORO_OSTHREAD

#  include <cerrno>

#  include <libport/config.h>
#  include <libport/assert.hh>
#  include <libport/compiler.hh>
#  include <libport/semaphore.hh>
#  include <libport/thread.hh>

#  include <kernel/kernconf.hh>
#  include <scheduler/coroutine.hh>

/* Os-thread implementation of coroutines, using semaphores to ensure
   that only one coroutine is running at the same time.  */

Coro::Coro()
  : die_(false)
{}

Coro*
coroutine_new(size_t)
{
  return new Coro;
}

void
coroutine_free(Coro* c)
{
  void *status;
  c->die_ = true;
  c->sem_++;
  if (pthread_join(c->thread_, &status))
    errabort("pthread_join");
}

void
coroutine_start(Coro* self, Coro* other,
                void (*callback)(void*), void* context)
{
#if defined WIN32
  unsigned long id;
  void* r =
    CreateThread(NULL, 0,
                 reinterpret_cast<void* (*)(void*)>(callback), context,
                 0, &id);
#else
  // Adjust to the requested stack size.
  static pthread_attr_t attr;
  static bool first = true;
  if (first)
  {
    first = false;
    if (pthread_attr_init(&attr))
      errabort("pthread_attr_init");

    if (pthread_attr_setstacksize(&attr, kernconf.default_stack_size))
      errabort("pthread_attr_setstacksize");
  }

  if (pthread_create(&other->thread_, &attr,
		     reinterpret_cast<void* (*)(void*)>(callback), context))
    errabort("pthread_create");
#endif
  self->sem_--;
}

void
coroutine_switch_to(Coro* self, Coro* next)
{
  next->sem_++;
  self->sem_--;
  if (self->die_)
  {
    delete self;
    pthread_exit(0);
  }
}

bool
coroutine_stack_space_almost_gone(Coro*)
{
  return false;
}

void
coroutine_initialize_main(Coro*)
{
}

#endif //! SCHEDULER_CORO_OSTHREAD
<|endoftext|>


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

#include <thrift/lib/cpp2/util/ScopedServerInterfaceThread.h>

#include <folly/SocketAddress.h>
#include <thrift/lib/cpp2/server/BaseThriftServer.h>
#include <thrift/lib/cpp2/server/ThriftServer.h>

using namespace std;
using namespace folly;
using namespace apache::thrift::concurrency;

namespace apache { namespace thrift {

ScopedServerInterfaceThread::ScopedServerInterfaceThread(
    shared_ptr<AsyncProcessorFactory> apf,
    SocketAddress const& addr,
    ServerConfigCb configCb) {
  auto tm = ThreadManager::newSimpleThreadManager(1, false);
  tm->threadFactory(make_shared<PosixThreadFactory>());
  tm->start();
  auto ts = make_shared<ThriftServer>();
  ts->setAddress(addr);
  ts->setProcessorFactory(move(apf));
  ts->setNumIOWorkerThreads(1);
  ts->setThreadManager(tm);
  if (configCb) {
    configCb(*ts);
  }
  ts_ = move(ts);
  sst_.start(ts_);
}

ScopedServerInterfaceThread::ScopedServerInterfaceThread(
    shared_ptr<AsyncProcessorFactory> apf,
    const string& host,
    uint16_t port,
    ServerConfigCb configCb)
    : ScopedServerInterfaceThread(
          move(apf),
          SocketAddress(host, port),
          move(configCb)) {}

ScopedServerInterfaceThread::ScopedServerInterfaceThread(
    shared_ptr<BaseThriftServer> ts) {
  ts_ = move(ts);
  sst_.start(ts_);
}

BaseThriftServer& ScopedServerInterfaceThread::getThriftServer() const {
  return *ts_;
}

const SocketAddress& ScopedServerInterfaceThread::getAddress() const {
  return *sst_.getAddress();
}

uint16_t ScopedServerInterfaceThread::getPort() const {
  return getAddress().getPort();
}

}}
<commit_msg>Let ScopedServerInterfaceThread not detach threads<commit_after>/*
 * Copyright 2014-present Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <thrift/lib/cpp2/util/ScopedServerInterfaceThread.h>

#include <folly/SocketAddress.h>
#include <thrift/lib/cpp2/server/BaseThriftServer.h>
#include <thrift/lib/cpp2/server/ThriftServer.h>

using namespace std;
using namespace folly;
using namespace apache::thrift::concurrency;

namespace apache { namespace thrift {

ScopedServerInterfaceThread::ScopedServerInterfaceThread(
    shared_ptr<AsyncProcessorFactory> apf,
    SocketAddress const& addr,
    ServerConfigCb configCb) {
  auto tf = make_shared<PosixThreadFactory>(PosixThreadFactory::ATTACHED);
  auto tm = ThreadManager::newSimpleThreadManager(1, false);
  tm->threadFactory(move(tf));
  tm->start();
  auto ts = make_shared<ThriftServer>();
  ts->setAddress(addr);
  ts->setProcessorFactory(move(apf));
  ts->setNumIOWorkerThreads(1);
  ts->setThreadManager(tm);
  if (configCb) {
    configCb(*ts);
  }
  ts_ = move(ts);
  sst_.start(ts_);
}

ScopedServerInterfaceThread::ScopedServerInterfaceThread(
    shared_ptr<AsyncProcessorFactory> apf,
    const string& host,
    uint16_t port,
    ServerConfigCb configCb)
    : ScopedServerInterfaceThread(
          move(apf),
          SocketAddress(host, port),
          move(configCb)) {}

ScopedServerInterfaceThread::ScopedServerInterfaceThread(
    shared_ptr<BaseThriftServer> ts) {
  ts_ = move(ts);
  sst_.start(ts_);
}

BaseThriftServer& ScopedServerInterfaceThread::getThriftServer() const {
  return *ts_;
}

const SocketAddress& ScopedServerInterfaceThread::getAddress() const {
  return *sst_.getAddress();
}

uint16_t ScopedServerInterfaceThread::getPort() const {
  return getAddress().getPort();
}

}}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: unocontrolcontainer.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: ihi $ $Date: 2006-11-14 12:28:12 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _TOOLKIT_CONTROLS_UNOCONTROLCONTAINER_HXX_
#define _TOOLKIT_CONTROLS_UNOCONTROLCONTAINER_HXX_

#ifndef _COM_SUN_STAR_AWT_XCONTROLCONTAINER_HPP_
#include <com/sun/star/awt/XControlContainer.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XUNOCONTROLCONTAINER_HPP_
#include <com/sun/star/awt/XUnoControlContainer.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XCONTAINER_HPP_
#include <com/sun/star/container/XContainer.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XIDENTIFIERCONTAINER_HPP_
#include <com/sun/star/container/XIdentifierContainer.hpp>
#endif

#include <toolkit/controls/unocontrol.hxx>
#include <toolkit/controls/unocontrolbase.hxx>
#include <toolkit/helper/macros.hxx>
#include <toolkit/helper/servicenames.hxx>

#include <cppuhelper/implbase4.hxx>

class UnoControlHolderList;

//  ----------------------------------------------------
//  class UnoControlContainer
//  ----------------------------------------------------
typedef ::cppu::AggImplInheritanceHelper4   <   UnoControlBase
                                            ,   ::com::sun::star::awt::XUnoControlContainer
                                            ,   ::com::sun::star::awt::XControlContainer
                                            ,   ::com::sun::star::container::XContainer
                                            ,   ::com::sun::star::container::XIdentifierContainer
                                            >   UnoControlContainer_Base;

class UnoControlContainer : public UnoControlContainer_Base
{
private:
    UnoControlHolderList*                   mpControls;
    ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTabController > >    maTabControllers;
    ContainerListenerMultiplexer            maCListeners;

protected:
    void                                    ImplActivateTabControllers();

public:
                UnoControlContainer();
                UnoControlContainer( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >  xPeer );
                ~UnoControlContainer();

    // ::com::sun::star::lang::XComponent
    void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException);

    // ::com::sun::star::lang::XEventListener
    void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException);

    // ::com::sun::star::container::XContainer
    void SAL_CALL addContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& xListener ) throw(::com::sun::star::uno::RuntimeException);
    void SAL_CALL removeContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& xListener ) throw(::com::sun::star::uno::RuntimeException);

    // ::com::sun::star::container::XIdentifierContainer
    virtual ::sal_Int32 SAL_CALL insert( const ::com::sun::star::uno::Any& aElement ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    // ::com::sun::star::container::XIdentifierReplace
    virtual void SAL_CALL removeByIdentifier( ::sal_Int32 Identifier ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL replaceByIdentifer( ::sal_Int32 Identifier, const ::com::sun::star::uno::Any& aElement ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    // ::com::sun::star::container::XIdentifierAccess
    virtual ::com::sun::star::uno::Any SAL_CALL getByIdentifier( ::sal_Int32 Identifierr ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::sal_Int32 > SAL_CALL getIdentifiers(  ) throw (::com::sun::star::uno::RuntimeException);

    // ::com::sun::star::container::XElementAccess
    virtual ::com::sun::star::uno::Type SAL_CALL getElementType(  ) throw (::com::sun::star::uno::RuntimeException);
    virtual ::sal_Bool SAL_CALL hasElements(  ) throw (::com::sun::star::uno::RuntimeException);

    // ::com::sun::star::awt::XControlContainer
    void SAL_CALL setStatusText( const ::rtl::OUString& StatusText ) throw(::com::sun::star::uno::RuntimeException);
    ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl > > SAL_CALL getControls(  ) throw(::com::sun::star::uno::RuntimeException);
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl > SAL_CALL getControl( const ::rtl::OUString& aName ) throw(::com::sun::star::uno::RuntimeException);
    void SAL_CALL addControl( const ::rtl::OUString& Name, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >& Control ) throw(::com::sun::star::uno::RuntimeException);
    void SAL_CALL removeControl( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >& Control ) throw(::com::sun::star::uno::RuntimeException);

    // ::com::sun::star::awt::XUnoControlContainer
    void SAL_CALL setTabControllers( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTabController > >& TabControllers ) throw(::com::sun::star::uno::RuntimeException);
    ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTabController > > SAL_CALL getTabControllers(  ) throw(::com::sun::star::uno::RuntimeException);
    void SAL_CALL addTabController( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTabController >& TabController ) throw(::com::sun::star::uno::RuntimeException);
    void SAL_CALL removeTabController( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTabController >& TabController ) throw(::com::sun::star::uno::RuntimeException);

    // ::com::sun::star::awt::XControl
    void SAL_CALL createPeer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit >& Toolkit, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >& Parent ) throw(::com::sun::star::uno::RuntimeException);

    // ::com::sun::star::awt::XWindow
    void SAL_CALL setVisible( sal_Bool Visible ) throw(::com::sun::star::uno::RuntimeException);

    DECLIMPL_SERVICEINFO_DERIVED( UnoControlContainer, UnoControlBase, szServiceName2_UnoControlContainer )

protected:
    virtual void removingControl( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >& _rxControl );
    virtual void addingControl( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >& _rxControl );

private:
    /** adds the control to the container, does necessary notifications, and the like
        @param _rxControl
            the control to add. Must not be <NULL/>
        @param _pName
            Pointer to a name for the control. Might be <NULL/>, in this case an auotmatic name is generated
        @return
            the ID of the newly added control
    */
    sal_Int32 impl_addControl(
        const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >& _rxControl,
        const ::rtl::OUString* _pName = NULL
    );

    /** removes the given control from the container, including necessary notifications and the like
        @param  _nId
            the ID of the control to remove
        @param  _rxControl
            the control itself. Must be the one which is stored under the given ID. This parameter could also be
            obtained inside the method, but callers usually have obtained it, anyway.
        @param  _pNameAccessor
            the name which the control was registered for. Might be <NULL/>, in this case
            container event broadcasts use the ID as accessor.
    */
    void      impl_removeControl(
        sal_Int32 _nId,
        const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >& _rxControl,
        const ::rtl::OUString* _pNameAccessor
    );

    /** ensures that the given control has a peer, if necessary and possible
        @param _rxControl
            an ->XControl which has just been inserted into the container. Must not be <NULL/>.
        @precond
            our mutex is locked
    */
    void    impl_createControlPeerIfNecessary(
        const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >& _rxControl
    );
};

#endif // _TOOLKIT_CONTROLS_UNOCONTROLCONTAINER_HXX_

<commit_msg>INTEGRATION: CWS changefileheader (1.9.190); FILE MERGED 2008/04/01 12:56:44 thb 1.9.190.2: #i85898# Stripping all external header guards 2008/03/28 15:40:07 rt 1.9.190.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: unocontrolcontainer.hxx,v $
 * $Revision: 1.10 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _TOOLKIT_CONTROLS_UNOCONTROLCONTAINER_HXX_
#define _TOOLKIT_CONTROLS_UNOCONTROLCONTAINER_HXX_

#include <com/sun/star/awt/XControlContainer.hpp>
#include <com/sun/star/awt/XUnoControlContainer.hpp>
#include <com/sun/star/container/XContainer.hpp>
#include <com/sun/star/container/XIdentifierContainer.hpp>

#include <toolkit/controls/unocontrol.hxx>
#include <toolkit/controls/unocontrolbase.hxx>
#include <toolkit/helper/macros.hxx>
#include <toolkit/helper/servicenames.hxx>

#include <cppuhelper/implbase4.hxx>

class UnoControlHolderList;

//  ----------------------------------------------------
//  class UnoControlContainer
//  ----------------------------------------------------
typedef ::cppu::AggImplInheritanceHelper4   <   UnoControlBase
                                            ,   ::com::sun::star::awt::XUnoControlContainer
                                            ,   ::com::sun::star::awt::XControlContainer
                                            ,   ::com::sun::star::container::XContainer
                                            ,   ::com::sun::star::container::XIdentifierContainer
                                            >   UnoControlContainer_Base;

class UnoControlContainer : public UnoControlContainer_Base
{
private:
    UnoControlHolderList*                   mpControls;
    ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTabController > >    maTabControllers;
    ContainerListenerMultiplexer            maCListeners;

protected:
    void                                    ImplActivateTabControllers();

public:
                UnoControlContainer();
                UnoControlContainer( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >  xPeer );
                ~UnoControlContainer();

    // ::com::sun::star::lang::XComponent
    void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException);

    // ::com::sun::star::lang::XEventListener
    void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException);

    // ::com::sun::star::container::XContainer
    void SAL_CALL addContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& xListener ) throw(::com::sun::star::uno::RuntimeException);
    void SAL_CALL removeContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& xListener ) throw(::com::sun::star::uno::RuntimeException);

    // ::com::sun::star::container::XIdentifierContainer
    virtual ::sal_Int32 SAL_CALL insert( const ::com::sun::star::uno::Any& aElement ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    // ::com::sun::star::container::XIdentifierReplace
    virtual void SAL_CALL removeByIdentifier( ::sal_Int32 Identifier ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL replaceByIdentifer( ::sal_Int32 Identifier, const ::com::sun::star::uno::Any& aElement ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    // ::com::sun::star::container::XIdentifierAccess
    virtual ::com::sun::star::uno::Any SAL_CALL getByIdentifier( ::sal_Int32 Identifierr ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::sal_Int32 > SAL_CALL getIdentifiers(  ) throw (::com::sun::star::uno::RuntimeException);

    // ::com::sun::star::container::XElementAccess
    virtual ::com::sun::star::uno::Type SAL_CALL getElementType(  ) throw (::com::sun::star::uno::RuntimeException);
    virtual ::sal_Bool SAL_CALL hasElements(  ) throw (::com::sun::star::uno::RuntimeException);

    // ::com::sun::star::awt::XControlContainer
    void SAL_CALL setStatusText( const ::rtl::OUString& StatusText ) throw(::com::sun::star::uno::RuntimeException);
    ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl > > SAL_CALL getControls(  ) throw(::com::sun::star::uno::RuntimeException);
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl > SAL_CALL getControl( const ::rtl::OUString& aName ) throw(::com::sun::star::uno::RuntimeException);
    void SAL_CALL addControl( const ::rtl::OUString& Name, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >& Control ) throw(::com::sun::star::uno::RuntimeException);
    void SAL_CALL removeControl( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >& Control ) throw(::com::sun::star::uno::RuntimeException);

    // ::com::sun::star::awt::XUnoControlContainer
    void SAL_CALL setTabControllers( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTabController > >& TabControllers ) throw(::com::sun::star::uno::RuntimeException);
    ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTabController > > SAL_CALL getTabControllers(  ) throw(::com::sun::star::uno::RuntimeException);
    void SAL_CALL addTabController( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTabController >& TabController ) throw(::com::sun::star::uno::RuntimeException);
    void SAL_CALL removeTabController( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTabController >& TabController ) throw(::com::sun::star::uno::RuntimeException);

    // ::com::sun::star::awt::XControl
    void SAL_CALL createPeer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit >& Toolkit, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >& Parent ) throw(::com::sun::star::uno::RuntimeException);

    // ::com::sun::star::awt::XWindow
    void SAL_CALL setVisible( sal_Bool Visible ) throw(::com::sun::star::uno::RuntimeException);

    DECLIMPL_SERVICEINFO_DERIVED( UnoControlContainer, UnoControlBase, szServiceName2_UnoControlContainer )

protected:
    virtual void removingControl( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >& _rxControl );
    virtual void addingControl( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >& _rxControl );

private:
    /** adds the control to the container, does necessary notifications, and the like
        @param _rxControl
            the control to add. Must not be <NULL/>
        @param _pName
            Pointer to a name for the control. Might be <NULL/>, in this case an auotmatic name is generated
        @return
            the ID of the newly added control
    */
    sal_Int32 impl_addControl(
        const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >& _rxControl,
        const ::rtl::OUString* _pName = NULL
    );

    /** removes the given control from the container, including necessary notifications and the like
        @param  _nId
            the ID of the control to remove
        @param  _rxControl
            the control itself. Must be the one which is stored under the given ID. This parameter could also be
            obtained inside the method, but callers usually have obtained it, anyway.
        @param  _pNameAccessor
            the name which the control was registered for. Might be <NULL/>, in this case
            container event broadcasts use the ID as accessor.
    */
    void      impl_removeControl(
        sal_Int32 _nId,
        const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >& _rxControl,
        const ::rtl::OUString* _pNameAccessor
    );

    /** ensures that the given control has a peer, if necessary and possible
        @param _rxControl
            an ->XControl which has just been inserted into the container. Must not be <NULL/>.
        @precond
            our mutex is locked
    */
    void    impl_createControlPeerIfNecessary(
        const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >& _rxControl
    );
};

#endif // _TOOLKIT_CONTROLS_UNOCONTROLCONTAINER_HXX_

<|endoftext|>


<commit_before>#include <algorithm>
#include <sstream>
#include <stdexcept>

#include "File.h"
#include "KeyValueFile.h"
#include "String.h"
#include "StringView.h"
#include "../debug/Debug.h"

void KeyValueFile::Section::init(std::string &&name)
{
	this->name = std::move(name);
}

const std::string &KeyValueFile::Section::getName() const
{
	return this->name;
}

int KeyValueFile::Section::getPairCount() const
{
	return static_cast<int>(this->pairs.size());
}

const std::pair<std::string, std::string> &KeyValueFile::Section::getPair(int index) const
{
	DebugAssertIndex(this->pairs, index);
	return this->pairs[index];
}

bool KeyValueFile::Section::tryGetValue(const std::string &key, std::string_view &value) const
{
	const std::pair<std::string, std::string> searchPair(key, std::string());
	const auto iter = std::lower_bound(this->pairs.begin(), this->pairs.end(), searchPair,
		[](const auto &pairA, const auto &pairB)
	{
		return pairA.first < pairB.first;
	});

	if (iter != this->pairs.end())
	{
		value = iter->second;
		return true;
	}
	else
	{
		return false;
	}
}

bool KeyValueFile::Section::tryGetBoolean(const std::string &key, bool &value) const
{
	std::string_view str;
	if (!this->tryGetValue(key, str))
	{
		return false;
	}
	else
	{
		// Convert to lowercase for easier comparison.
		const std::string lowerStr = String::toLowercase(std::string(str));

		if (lowerStr == "true")
		{
			value = true;
			return true;
		}
		else if (lowerStr == "false")
		{
			value = false;
			return true;
		}
		else
		{
			return false;
		}
	}
}

bool KeyValueFile::Section::tryGetInteger(const std::string &key, int &value) const
{
	std::string_view str;
	if (!this->tryGetValue(key, str))
	{
		return false;
	}
	else
	{
		try
		{
			size_t index = 0;
			value = std::stoi(std::string(str), &index);
			return index == str.size();
		}
		catch (std::exception)
		{
			return false;
		}
	}
}

bool KeyValueFile::Section::tryGetDouble(const std::string &key, double &value) const
{
	std::string_view str;
	if (!this->tryGetValue(key, str))
	{
		return false;
	}
	else
	{
		try
		{
			size_t index = 0;
			value = std::stod(std::string(str), &index);
			return index == str.size();
		}
		catch (std::exception)
		{
			return false;
		}
	}
}

bool KeyValueFile::Section::tryGetString(const std::string &key, std::string_view &value) const
{
	return this->tryGetValue(key, value);
}

void KeyValueFile::Section::add(std::string &&key, std::string &&value)
{
	this->pairs.push_back(std::make_pair(std::move(key), std::move(value)));
	std::sort(this->pairs.begin(), this->pairs.end(),
		[](const auto &pairA, const auto &pairB)
	{
		const std::string &strA = pairA.first;
		const std::string &strB = pairB.first;
		return strA < strB;
	});
}

void KeyValueFile::Section::clear()
{
	this->pairs.clear();
}

const char KeyValueFile::COMMENT = '#';
const char KeyValueFile::PAIR_SEPARATOR = '=';
const char KeyValueFile::SECTION_FRONT = '[';
const char KeyValueFile::SECTION_BACK = ']';

bool KeyValueFile::init(const char *filename)
{
	const std::string text = File::readAllText(filename);
	std::istringstream iss(text);

	// Check each line for a valid section or key-value pair. Start the line numbers at 1
	// since most users aren't programmers.
	std::string line;
	Section *activeSection = nullptr;
	for (int lineNumber = 1; std::getline(iss, line); lineNumber++)
	{
		// Get a filtered version of the current line so it can be parsed. If the filtered
		// string is empty, then skip to the next line.
		const std::string_view filteredLine = [&line]()
		{
			std::string_view str = line;

			// Skip empty strings.
			if ((str.size() == 0) || ((str.size() == 1) && (str.front() == '\r')))
			{
				return std::string_view();
			}

			// Remove carriage return at the end (if any).
			if (str.back() == '\r')
			{
				str.remove_suffix(1);
			}

			// Extract left-most comment (if any).
			const size_t commentIndex = str.find(KeyValueFile::COMMENT);
			if (commentIndex == 0)
			{
				// Comment covers the entire line.
				return std::string_view();
			}
			else if (commentIndex != std::string_view::npos)
			{
				// Comment is somewhere in the line, so only work with the left substring.
				str = str.substr(0, commentIndex);
			}

			// Trim leading and trailing whitespace (i.e., in case the key has whitespace
			// before it, or a comment had whitespace before it).
			return StringView::trimFront(StringView::trimBack(str));
		}();

		if (filteredLine.empty())
		{
			// It became an empty string after whitespace was removed.
			continue;
		}
		else if (filteredLine.size() < 3)
		{
			// Not long enough to be a section or key-value pair.
			DebugLogError("Syntax error \"" + std::string(filteredLine) + "\" (line " +
				std::to_string(lineNumber) + ") in " + filename + ".");
			return false;
		}

		// See if it's a section line or key-value pair line.
		const size_t sectionFrontIndex = filteredLine.find(KeyValueFile::SECTION_FRONT);
		if (sectionFrontIndex != std::string_view::npos)
		{
			// Section line. There must be a closing character with enough space between it
			// and the front character for at least one section character.
			const size_t sectionBackIndex = filteredLine.find(
				KeyValueFile::SECTION_BACK, sectionFrontIndex);

			if ((sectionBackIndex != std::string_view::npos) &&
				(sectionBackIndex > (sectionFrontIndex + 1)))
			{
				// Get the string that's between the section characters and trim any
				// leading or trailing whitespace.
				std::string_view sectionName = filteredLine.substr(
					sectionFrontIndex + 1, sectionBackIndex - sectionFrontIndex - 1);
				sectionName = StringView::trimFront(StringView::trimBack(sectionName));

				const auto sectionIter = std::find_if(this->sections.begin(), this->sections.end(),
					[&sectionName](const Section &section)
				{
					return section.getName() == sectionName;
				});

				// If the section is new, add it to the section maps.
				if (sectionIter == this->sections.end())
				{
					Section section;
					section.init(std::string(sectionName));
					this->sections.push_back(std::move(section));
					activeSection = &this->sections.back();
				}
				else
				{
					DebugLogError("Section \"" + std::string(sectionName) + "\" (line " +
						std::to_string(lineNumber) + ") already defined in " + filename + ".");
					return false;
				}
			}
			else
			{
				DebugLogError("Invalid section \"" + std::string(filteredLine) + "\" (line " +
					std::to_string(lineNumber) + ") in " + filename + ".");
				return false;
			}
		}
		else if (filteredLine.find(KeyValueFile::PAIR_SEPARATOR) != std::string::npos)
		{
			// Key-value pair line. There must be two tokens: key and value.
			std::array<std::string_view, 2> tokens;
			if (!StringView::splitExpected(filteredLine, KeyValueFile::PAIR_SEPARATOR, tokens))
			{
				DebugLogError("Invalid pair \"" + std::string(filteredLine) + "\" (line " +
					std::to_string(lineNumber) + ") in " + filename + ".");
				return false;
			}

			// Trim whitespace from the key and leading whitespace from the value.
			const std::string_view key = StringView::trimFront(StringView::trimBack(tokens[0]));
			const std::string_view value = StringView::trimFront(tokens[1]);

			if (key.size() == 0)
			{
				DebugLogError("Empty key in \"" + std::string(filteredLine) + "\" (line " +
					std::to_string(lineNumber) + ") in " + filename + ".");
				return false;
			}

			// Add the key-value pair to the active section map.
			if (activeSection != nullptr)
			{
				activeSection->add(std::string(key), std::string(value));
			}
			else
			{
				// If no active section map, print a warning and ignore the current pair.
				// All key-value pairs must be in a section.
				DebugLogWarning("Ignoring \"" + std::string(filteredLine) + "\" (line " +
					std::to_string(lineNumber) + "), no active section in " + filename);
			}
		}
		else
		{
			// Filtered line is not a section or key-value pair.
			DebugLogError("Invalid line \"" + line + "\" (line " +
				std::to_string(lineNumber) + ") in " + filename + ".");
			return false;
		}
	}

	// Sort for binary search.
	std::sort(this->sections.begin(), this->sections.end(),
		[](const Section &sectionA, const Section &sectionB)
	{
		return sectionA.getName() < sectionB.getName();
	});

	return true;
}

int KeyValueFile::getSectionCount() const
{
	return static_cast<int>(this->sections.size());
}

const KeyValueFile::Section &KeyValueFile::getSection(int index) const
{
	DebugAssertIndex(this->sections, index);
	return this->sections[index];
}

const KeyValueFile::Section *KeyValueFile::getSectionByName(const std::string &name) const
{
	const auto iter = std::lower_bound(this->sections.begin(), this->sections.end(), name,
		[](const Section &section, const std::string &str)
	{
		return section.getName() < str;
	});

	return (iter != this->sections.end()) ? &(*iter) : nullptr;
}
<commit_msg>Added file exists check to KeyValueFile::init().<commit_after>#include <algorithm>
#include <sstream>
#include <stdexcept>

#include "File.h"
#include "KeyValueFile.h"
#include "String.h"
#include "StringView.h"
#include "../debug/Debug.h"

void KeyValueFile::Section::init(std::string &&name)
{
	this->name = std::move(name);
}

const std::string &KeyValueFile::Section::getName() const
{
	return this->name;
}

int KeyValueFile::Section::getPairCount() const
{
	return static_cast<int>(this->pairs.size());
}

const std::pair<std::string, std::string> &KeyValueFile::Section::getPair(int index) const
{
	DebugAssertIndex(this->pairs, index);
	return this->pairs[index];
}

bool KeyValueFile::Section::tryGetValue(const std::string &key, std::string_view &value) const
{
	const std::pair<std::string, std::string> searchPair(key, std::string());
	const auto iter = std::lower_bound(this->pairs.begin(), this->pairs.end(), searchPair,
		[](const auto &pairA, const auto &pairB)
	{
		return pairA.first < pairB.first;
	});

	if (iter != this->pairs.end())
	{
		value = iter->second;
		return true;
	}
	else
	{
		return false;
	}
}

bool KeyValueFile::Section::tryGetBoolean(const std::string &key, bool &value) const
{
	std::string_view str;
	if (!this->tryGetValue(key, str))
	{
		return false;
	}
	else
	{
		// Convert to lowercase for easier comparison.
		const std::string lowerStr = String::toLowercase(std::string(str));

		if (lowerStr == "true")
		{
			value = true;
			return true;
		}
		else if (lowerStr == "false")
		{
			value = false;
			return true;
		}
		else
		{
			return false;
		}
	}
}

bool KeyValueFile::Section::tryGetInteger(const std::string &key, int &value) const
{
	std::string_view str;
	if (!this->tryGetValue(key, str))
	{
		return false;
	}
	else
	{
		try
		{
			size_t index = 0;
			value = std::stoi(std::string(str), &index);
			return index == str.size();
		}
		catch (std::exception)
		{
			return false;
		}
	}
}

bool KeyValueFile::Section::tryGetDouble(const std::string &key, double &value) const
{
	std::string_view str;
	if (!this->tryGetValue(key, str))
	{
		return false;
	}
	else
	{
		try
		{
			size_t index = 0;
			value = std::stod(std::string(str), &index);
			return index == str.size();
		}
		catch (std::exception)
		{
			return false;
		}
	}
}

bool KeyValueFile::Section::tryGetString(const std::string &key, std::string_view &value) const
{
	return this->tryGetValue(key, value);
}

void KeyValueFile::Section::add(std::string &&key, std::string &&value)
{
	this->pairs.push_back(std::make_pair(std::move(key), std::move(value)));
	std::sort(this->pairs.begin(), this->pairs.end(),
		[](const auto &pairA, const auto &pairB)
	{
		const std::string &strA = pairA.first;
		const std::string &strB = pairB.first;
		return strA < strB;
	});
}

void KeyValueFile::Section::clear()
{
	this->pairs.clear();
}

const char KeyValueFile::COMMENT = '#';
const char KeyValueFile::PAIR_SEPARATOR = '=';
const char KeyValueFile::SECTION_FRONT = '[';
const char KeyValueFile::SECTION_BACK = ']';

bool KeyValueFile::init(const char *filename)
{
	if (!File::exists(filename))
	{
		DebugLogError("Could not find \"" + std::string(filename) + "\".");
		return false;
	}

	const std::string text = File::readAllText(filename);
	std::istringstream iss(text);

	// Check each line for a valid section or key-value pair. Start the line numbers at 1
	// since most users aren't programmers.
	std::string line;
	Section *activeSection = nullptr;
	for (int lineNumber = 1; std::getline(iss, line); lineNumber++)
	{
		// Get a filtered version of the current line so it can be parsed. If the filtered
		// string is empty, then skip to the next line.
		const std::string_view filteredLine = [&line]()
		{
			std::string_view str = line;

			// Skip empty strings.
			if ((str.size() == 0) || ((str.size() == 1) && (str.front() == '\r')))
			{
				return std::string_view();
			}

			// Remove carriage return at the end (if any).
			if (str.back() == '\r')
			{
				str.remove_suffix(1);
			}

			// Extract left-most comment (if any).
			const size_t commentIndex = str.find(KeyValueFile::COMMENT);
			if (commentIndex == 0)
			{
				// Comment covers the entire line.
				return std::string_view();
			}
			else if (commentIndex != std::string_view::npos)
			{
				// Comment is somewhere in the line, so only work with the left substring.
				str = str.substr(0, commentIndex);
			}

			// Trim leading and trailing whitespace (i.e., in case the key has whitespace
			// before it, or a comment had whitespace before it).
			return StringView::trimFront(StringView::trimBack(str));
		}();

		if (filteredLine.empty())
		{
			// It became an empty string after whitespace was removed.
			continue;
		}
		else if (filteredLine.size() < 3)
		{
			// Not long enough to be a section or key-value pair.
			DebugLogError("Syntax error \"" + std::string(filteredLine) + "\" (line " +
				std::to_string(lineNumber) + ") in " + filename + ".");
			return false;
		}

		// See if it's a section line or key-value pair line.
		const size_t sectionFrontIndex = filteredLine.find(KeyValueFile::SECTION_FRONT);
		if (sectionFrontIndex != std::string_view::npos)
		{
			// Section line. There must be a closing character with enough space between it
			// and the front character for at least one section character.
			const size_t sectionBackIndex = filteredLine.find(
				KeyValueFile::SECTION_BACK, sectionFrontIndex);

			if ((sectionBackIndex != std::string_view::npos) &&
				(sectionBackIndex > (sectionFrontIndex + 1)))
			{
				// Get the string that's between the section characters and trim any
				// leading or trailing whitespace.
				std::string_view sectionName = filteredLine.substr(
					sectionFrontIndex + 1, sectionBackIndex - sectionFrontIndex - 1);
				sectionName = StringView::trimFront(StringView::trimBack(sectionName));

				const auto sectionIter = std::find_if(this->sections.begin(), this->sections.end(),
					[&sectionName](const Section &section)
				{
					return section.getName() == sectionName;
				});

				// If the section is new, add it to the section maps.
				if (sectionIter == this->sections.end())
				{
					Section section;
					section.init(std::string(sectionName));
					this->sections.push_back(std::move(section));
					activeSection = &this->sections.back();
				}
				else
				{
					DebugLogError("Section \"" + std::string(sectionName) + "\" (line " +
						std::to_string(lineNumber) + ") already defined in " + filename + ".");
					return false;
				}
			}
			else
			{
				DebugLogError("Invalid section \"" + std::string(filteredLine) + "\" (line " +
					std::to_string(lineNumber) + ") in " + filename + ".");
				return false;
			}
		}
		else if (filteredLine.find(KeyValueFile::PAIR_SEPARATOR) != std::string::npos)
		{
			// Key-value pair line. There must be two tokens: key and value.
			std::array<std::string_view, 2> tokens;
			if (!StringView::splitExpected(filteredLine, KeyValueFile::PAIR_SEPARATOR, tokens))
			{
				DebugLogError("Invalid pair \"" + std::string(filteredLine) + "\" (line " +
					std::to_string(lineNumber) + ") in " + filename + ".");
				return false;
			}

			// Trim whitespace from the key and leading whitespace from the value.
			const std::string_view key = StringView::trimFront(StringView::trimBack(tokens[0]));
			const std::string_view value = StringView::trimFront(tokens[1]);

			if (key.size() == 0)
			{
				DebugLogError("Empty key in \"" + std::string(filteredLine) + "\" (line " +
					std::to_string(lineNumber) + ") in " + filename + ".");
				return false;
			}

			// Add the key-value pair to the active section map.
			if (activeSection != nullptr)
			{
				activeSection->add(std::string(key), std::string(value));
			}
			else
			{
				// If no active section map, print a warning and ignore the current pair.
				// All key-value pairs must be in a section.
				DebugLogWarning("Ignoring \"" + std::string(filteredLine) + "\" (line " +
					std::to_string(lineNumber) + "), no active section in " + filename);
			}
		}
		else
		{
			// Filtered line is not a section or key-value pair.
			DebugLogError("Invalid line \"" + line + "\" (line " +
				std::to_string(lineNumber) + ") in " + filename + ".");
			return false;
		}
	}

	// Sort for binary search.
	std::sort(this->sections.begin(), this->sections.end(),
		[](const Section &sectionA, const Section &sectionB)
	{
		return sectionA.getName() < sectionB.getName();
	});

	return true;
}

int KeyValueFile::getSectionCount() const
{
	return static_cast<int>(this->sections.size());
}

const KeyValueFile::Section &KeyValueFile::getSection(int index) const
{
	DebugAssertIndex(this->sections, index);
	return this->sections[index];
}

const KeyValueFile::Section *KeyValueFile::getSectionByName(const std::string &name) const
{
	const auto iter = std::lower_bound(this->sections.begin(), this->sections.end(), name,
		[](const Section &section, const std::string &str)
	{
		return section.getName() < str;
	});

	return (iter != this->sections.end()) ? &(*iter) : nullptr;
}
<|endoftext|>


<commit_before>// Copyright (c) 2015-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <test/fuzz/fuzz.h>
#include <test/fuzz/FuzzedDataProvider.h>

#include <vector>
#include <prevector.h>

#include <reverse_iterator.h>
#include <serialize.h>
#include <streams.h>

namespace {

template<unsigned int N, typename T>
class prevector_tester {
    typedef std::vector<T> realtype;
    realtype real_vector;
    realtype real_vector_alt;

    typedef prevector<N, T> pretype;
    pretype pre_vector;
    pretype pre_vector_alt;

    typedef typename pretype::size_type Size;

    void test() {
        const pretype& const_pre_vector = pre_vector;
        assert(real_vector.size() == pre_vector.size());
        assert(real_vector.empty() == pre_vector.empty());
        for (Size s = 0; s < real_vector.size(); s++) {
             assert(real_vector[s] == pre_vector[s]);
             assert(&(pre_vector[s]) == &(pre_vector.begin()[s]));
             assert(&(pre_vector[s]) == &*(pre_vector.begin() + s));
             assert(&(pre_vector[s]) == &*((pre_vector.end() + s) - real_vector.size()));
        }
        // assert(realtype(pre_vector) == real_vector);
        assert(pretype(real_vector.begin(), real_vector.end()) == pre_vector);
        assert(pretype(pre_vector.begin(), pre_vector.end()) == pre_vector);
        size_t pos = 0;
        for (const T& v : pre_vector) {
             assert(v == real_vector[pos]);
             ++pos;
        }
        for (const T& v : reverse_iterate(pre_vector)) {
             --pos;
             assert(v == real_vector[pos]);
        }
        for (const T& v : const_pre_vector) {
             assert(v == real_vector[pos]);
             ++pos;
        }
        for (const T& v : reverse_iterate(const_pre_vector)) {
             --pos;
             assert(v == real_vector[pos]);
        }
        CDataStream ss1(SER_DISK, 0);
        CDataStream ss2(SER_DISK, 0);
        ss1 << real_vector;
        ss2 << pre_vector;
        assert(ss1.size() == ss2.size());
        for (Size s = 0; s < ss1.size(); s++) {
            assert(ss1[s] == ss2[s]);
        }
    }

public:
    void resize(Size s) {
        real_vector.resize(s);
        assert(real_vector.size() == s);
        pre_vector.resize(s);
        assert(pre_vector.size() == s);
        test();
    }

    void reserve(Size s) {
        real_vector.reserve(s);
        assert(real_vector.capacity() >= s);
        pre_vector.reserve(s);
        assert(pre_vector.capacity() >= s);
        test();
    }

    void insert(Size position, const T& value) {
        real_vector.insert(real_vector.begin() + position, value);
        pre_vector.insert(pre_vector.begin() + position, value);
        test();
    }

    void insert(Size position, Size count, const T& value) {
        real_vector.insert(real_vector.begin() + position, count, value);
        pre_vector.insert(pre_vector.begin() + position, count, value);
        test();
    }

    template<typename I>
    void insert_range(Size position, I first, I last) {
        real_vector.insert(real_vector.begin() + position, first, last);
        pre_vector.insert(pre_vector.begin() + position, first, last);
        test();
    }

    void erase(Size position) {
        real_vector.erase(real_vector.begin() + position);
        pre_vector.erase(pre_vector.begin() + position);
        test();
    }

    void erase(Size first, Size last) {
        real_vector.erase(real_vector.begin() + first, real_vector.begin() + last);
        pre_vector.erase(pre_vector.begin() + first, pre_vector.begin() + last);
        test();
    }

    void update(Size pos, const T& value) {
        real_vector[pos] = value;
        pre_vector[pos] = value;
        test();
    }

    void push_back(const T& value) {
        real_vector.push_back(value);
        pre_vector.push_back(value);
        test();
    }

    void pop_back() {
        real_vector.pop_back();
        pre_vector.pop_back();
        test();
    }

    void clear() {
        real_vector.clear();
        pre_vector.clear();
    }

    void assign(Size n, const T& value) {
        real_vector.assign(n, value);
        pre_vector.assign(n, value);
    }

    Size size() const {
        return real_vector.size();
    }

    Size capacity() const {
        return pre_vector.capacity();
    }

    void shrink_to_fit() {
        pre_vector.shrink_to_fit();
        test();
    }

    void swap() {
        real_vector.swap(real_vector_alt);
        pre_vector.swap(pre_vector_alt);
        test();
    }

    void move() {
        real_vector = std::move(real_vector_alt);
        real_vector_alt.clear();
        pre_vector = std::move(pre_vector_alt);
        pre_vector_alt.clear();
    }

    void copy() {
        real_vector = real_vector_alt;
        pre_vector = pre_vector_alt;
    }

    void resize_uninitialized(realtype values) {
        size_t r = values.size();
        size_t s = real_vector.size() / 2;
        if (real_vector.capacity() < s + r) {
            real_vector.reserve(s + r);
        }
        real_vector.resize(s);
        pre_vector.resize_uninitialized(s);
        for (auto v : values) {
            real_vector.push_back(v);
        }
        auto p = pre_vector.size();
        pre_vector.resize_uninitialized(p + r);
        for (auto v : values) {
            pre_vector[p] = v;
            ++p;
        }
        test();
    }
};

}

void test_one_input(const std::vector<uint8_t>& buffer)
{
    FuzzedDataProvider prov(buffer.data(), buffer.size());
    prevector_tester<8, int> test;

    while (prov.remaining_bytes()) {
        switch (prov.ConsumeIntegralInRange<int>(0, 14 + 3 * (test.size() > 0))) {
        case 0:
            test.insert(prov.ConsumeIntegralInRange<size_t>(0, test.size()), prov.ConsumeIntegral<int>());
            break;
        case 15:
            test.erase(prov.ConsumeIntegralInRange<size_t>(0, test.size() - 1));
            break;
        case 1:
            test.resize(std::max(0, std::min(30, (int)test.size() + prov.ConsumeIntegralInRange<int>(0, 4) - 2)));
            break;
        case 2:
            test.insert(prov.ConsumeIntegralInRange<size_t>(0, test.size()), 1 + prov.ConsumeBool(), prov.ConsumeIntegral<int>());
            break;
        case 3: {
            int del = std::min<int>(test.size(), 1 + prov.ConsumeBool());
            int beg = prov.ConsumeIntegralInRange<int>(0, test.size() - del);
            test.erase(beg, beg + del);
            break;
        }
        case 4:
            test.push_back(prov.ConsumeIntegral<int>());
            break;
        case 16:
            test.pop_back();
            break;
        case 5: {
            int values[4];
            int num = 1 + prov.ConsumeIntegralInRange<int>(0, 3);
            for (int k = 0; k < num; ++k) {
                values[k] = prov.ConsumeIntegral<int>();
            }
            test.insert_range(prov.ConsumeIntegralInRange<size_t>(0, test.size()), values, values + num);
            break;
        }
        case 6: {
            int del = std::min<int>(test.size(), 1 + prov.ConsumeIntegralInRange<int>(0, 3));
            int beg = prov.ConsumeIntegralInRange<int>(0, test.size() - del);
            test.erase(beg, beg + del);
            break;
        }
        case 7:
            test.reserve(prov.ConsumeIntegralInRange<size_t>(0, 32767));
            break;
        case 8:
            test.shrink_to_fit();
            break;
        case 17:
            test.update(prov.ConsumeIntegralInRange<size_t>(0, test.size() - 1), prov.ConsumeIntegral<int>());
            break;
        case 9:
            test.clear();
            break;
        case 10:
            test.assign(prov.ConsumeIntegralInRange<size_t>(0, 32767), prov.ConsumeIntegral<int>());
            break;
        case 11:
            test.swap();
            break;
        case 12:
            test.copy();
            break;
        case 13:
            test.move();
            break;
        case 14: {
            int num = 1 + prov.ConsumeIntegralInRange<int>(0, 15);
            std::vector<int> values(num);
            for (auto& v : values) {
                v = prov.ConsumeIntegral<int>();
            }
            test.resize_uninitialized(values);
            break;
        }
        }
    }
}
<commit_msg>Only run sanity check once at the end<commit_after>// Copyright (c) 2015-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <test/fuzz/fuzz.h>
#include <test/fuzz/FuzzedDataProvider.h>

#include <vector>
#include <prevector.h>

#include <reverse_iterator.h>
#include <serialize.h>
#include <streams.h>

namespace {

template<unsigned int N, typename T>
class prevector_tester {
    typedef std::vector<T> realtype;
    realtype real_vector;
    realtype real_vector_alt;

    typedef prevector<N, T> pretype;
    pretype pre_vector;
    pretype pre_vector_alt;

    typedef typename pretype::size_type Size;

public:
    void test() const {
        const pretype& const_pre_vector = pre_vector;
        assert(real_vector.size() == pre_vector.size());
        assert(real_vector.empty() == pre_vector.empty());
        for (Size s = 0; s < real_vector.size(); s++) {
             assert(real_vector[s] == pre_vector[s]);
             assert(&(pre_vector[s]) == &(pre_vector.begin()[s]));
             assert(&(pre_vector[s]) == &*(pre_vector.begin() + s));
             assert(&(pre_vector[s]) == &*((pre_vector.end() + s) - real_vector.size()));
        }
        // assert(realtype(pre_vector) == real_vector);
        assert(pretype(real_vector.begin(), real_vector.end()) == pre_vector);
        assert(pretype(pre_vector.begin(), pre_vector.end()) == pre_vector);
        size_t pos = 0;
        for (const T& v : pre_vector) {
             assert(v == real_vector[pos]);
             ++pos;
        }
        for (const T& v : reverse_iterate(pre_vector)) {
             --pos;
             assert(v == real_vector[pos]);
        }
        for (const T& v : const_pre_vector) {
             assert(v == real_vector[pos]);
             ++pos;
        }
        for (const T& v : reverse_iterate(const_pre_vector)) {
             --pos;
             assert(v == real_vector[pos]);
        }
        CDataStream ss1(SER_DISK, 0);
        CDataStream ss2(SER_DISK, 0);
        ss1 << real_vector;
        ss2 << pre_vector;
        assert(ss1.size() == ss2.size());
        for (Size s = 0; s < ss1.size(); s++) {
            assert(ss1[s] == ss2[s]);
        }
    }

    void resize(Size s) {
        real_vector.resize(s);
        assert(real_vector.size() == s);
        pre_vector.resize(s);
        assert(pre_vector.size() == s);
    }

    void reserve(Size s) {
        real_vector.reserve(s);
        assert(real_vector.capacity() >= s);
        pre_vector.reserve(s);
        assert(pre_vector.capacity() >= s);
    }

    void insert(Size position, const T& value) {
        real_vector.insert(real_vector.begin() + position, value);
        pre_vector.insert(pre_vector.begin() + position, value);
    }

    void insert(Size position, Size count, const T& value) {
        real_vector.insert(real_vector.begin() + position, count, value);
        pre_vector.insert(pre_vector.begin() + position, count, value);
    }

    template<typename I>
    void insert_range(Size position, I first, I last) {
        real_vector.insert(real_vector.begin() + position, first, last);
        pre_vector.insert(pre_vector.begin() + position, first, last);
    }

    void erase(Size position) {
        real_vector.erase(real_vector.begin() + position);
        pre_vector.erase(pre_vector.begin() + position);
    }

    void erase(Size first, Size last) {
        real_vector.erase(real_vector.begin() + first, real_vector.begin() + last);
        pre_vector.erase(pre_vector.begin() + first, pre_vector.begin() + last);
    }

    void update(Size pos, const T& value) {
        real_vector[pos] = value;
        pre_vector[pos] = value;
    }

    void push_back(const T& value) {
        real_vector.push_back(value);
        pre_vector.push_back(value);
    }

    void pop_back() {
        real_vector.pop_back();
        pre_vector.pop_back();
    }

    void clear() {
        real_vector.clear();
        pre_vector.clear();
    }

    void assign(Size n, const T& value) {
        real_vector.assign(n, value);
        pre_vector.assign(n, value);
    }

    Size size() const {
        return real_vector.size();
    }

    Size capacity() const {
        return pre_vector.capacity();
    }

    void shrink_to_fit() {
        pre_vector.shrink_to_fit();
    }

    void swap() {
        real_vector.swap(real_vector_alt);
        pre_vector.swap(pre_vector_alt);
    }

    void move() {
        real_vector = std::move(real_vector_alt);
        real_vector_alt.clear();
        pre_vector = std::move(pre_vector_alt);
        pre_vector_alt.clear();
    }

    void copy() {
        real_vector = real_vector_alt;
        pre_vector = pre_vector_alt;
    }

    void resize_uninitialized(realtype values) {
        size_t r = values.size();
        size_t s = real_vector.size() / 2;
        if (real_vector.capacity() < s + r) {
            real_vector.reserve(s + r);
        }
        real_vector.resize(s);
        pre_vector.resize_uninitialized(s);
        for (auto v : values) {
            real_vector.push_back(v);
        }
        auto p = pre_vector.size();
        pre_vector.resize_uninitialized(p + r);
        for (auto v : values) {
            pre_vector[p] = v;
            ++p;
        }
    }
};

}

void test_one_input(const std::vector<uint8_t>& buffer)
{
    FuzzedDataProvider prov(buffer.data(), buffer.size());
    prevector_tester<8, int> test;

    while (prov.remaining_bytes()) {
        switch (prov.ConsumeIntegralInRange<int>(0, 14 + 3 * (test.size() > 0))) {
        case 0:
            test.insert(prov.ConsumeIntegralInRange<size_t>(0, test.size()), prov.ConsumeIntegral<int>());
            break;
        case 15:
            test.erase(prov.ConsumeIntegralInRange<size_t>(0, test.size() - 1));
            break;
        case 1:
            test.resize(std::max(0, std::min(30, (int)test.size() + prov.ConsumeIntegralInRange<int>(0, 4) - 2)));
            break;
        case 2:
            test.insert(prov.ConsumeIntegralInRange<size_t>(0, test.size()), 1 + prov.ConsumeBool(), prov.ConsumeIntegral<int>());
            break;
        case 3: {
            int del = std::min<int>(test.size(), 1 + prov.ConsumeBool());
            int beg = prov.ConsumeIntegralInRange<int>(0, test.size() - del);
            test.erase(beg, beg + del);
            break;
        }
        case 4:
            test.push_back(prov.ConsumeIntegral<int>());
            break;
        case 16:
            test.pop_back();
            break;
        case 5: {
            int values[4];
            int num = 1 + prov.ConsumeIntegralInRange<int>(0, 3);
            for (int k = 0; k < num; ++k) {
                values[k] = prov.ConsumeIntegral<int>();
            }
            test.insert_range(prov.ConsumeIntegralInRange<size_t>(0, test.size()), values, values + num);
            break;
        }
        case 6: {
            int del = std::min<int>(test.size(), 1 + prov.ConsumeIntegralInRange<int>(0, 3));
            int beg = prov.ConsumeIntegralInRange<int>(0, test.size() - del);
            test.erase(beg, beg + del);
            break;
        }
        case 7:
            test.reserve(prov.ConsumeIntegralInRange<size_t>(0, 32767));
            break;
        case 8:
            test.shrink_to_fit();
            break;
        case 17:
            test.update(prov.ConsumeIntegralInRange<size_t>(0, test.size() - 1), prov.ConsumeIntegral<int>());
            break;
        case 9:
            test.clear();
            break;
        case 10:
            test.assign(prov.ConsumeIntegralInRange<size_t>(0, 32767), prov.ConsumeIntegral<int>());
            break;
        case 11:
            test.swap();
            break;
        case 12:
            test.copy();
            break;
        case 13:
            test.move();
            break;
        case 14: {
            int num = 1 + prov.ConsumeIntegralInRange<int>(0, 15);
            std::vector<int> values(num);
            for (auto& v : values) {
                v = prov.ConsumeIntegral<int>();
            }
            test.resize_uninitialized(values);
            break;
        }
        }
    }

    test.test();
}
<|endoftext|>