<commit_before>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2008 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  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
//
//  Current versions can be found at www.libavg.de
//

#include "WrapHelper.h"

#include "../player/KeyEvent.h"
#include "../player/MouseEvent.h"
#include "../player/TouchEvent.h"
#include "../player/Node.h"
#include "../player/TrackerEventSource.h"

using namespace boost::python;
using namespace avg;
using namespace std;

void export_event()
{
    boost::python::to_python_converter<vector<TouchEvent*>,
        to_tuple<vector<TouchEvent *> > >();

    boost::python::to_python_converter<ContourSeq,
        to_list<ContourSeq> >();

    from_python_sequence<ContourSeq, variable_capacity_policy>();

    class_<Event, boost::noncopyable>("Event",
            "Base class for user input events.\n",
            no_init)
        .add_property("type", &Event::getType,
                "One of KEYUP, KEYDOWN, CURSORMOTION, CURSORUP,\n"
                "CURSORDOWN, CURSOROVER, CURSOROUT, RESIZE or QUIT.\n")
        .add_property("when", &Event::getWhen,
                "The timestamp of the event in milliseconds.\n")
    ;

    enum_<Event::Type>("Type")
        .value("KEYUP", Event::KEYUP)
        .value("KEYDOWN", Event::KEYDOWN)
        .value("CURSORMOTION", Event::CURSORMOTION)
        .value("CURSORUP", Event::CURSORUP)
        .value("CURSORDOWN", Event::CURSORDOWN)
        .value("CURSOROVER", Event::CURSOROVER)
        .value("CURSOROUT", Event::CURSOROUT)
        .value("RESIZE", Event::RESIZE)
        .value("QUIT", Event::QUIT)
        .export_values()
    ;

    enum_<CursorEvent::Source>("Source")
        .value("MOUSE", CursorEvent::MOUSE)
        .value("TOUCH", CursorEvent::TOUCH)
        .value("TRACK", CursorEvent::TRACK)
        .value("NONE", Event::NONE)
        .export_values()
    ;

    enum_<int>("KeyModifier")
        .value("KEYMOD_NONE", key::KEYMOD_NONE)
        .value("KEYMOD_LSHIFT", key::KEYMOD_LSHIFT)
        .value("KEYMOD_RSHIFT", key::KEYMOD_RSHIFT)
        .value("KEYMOD_LCTRL", key::KEYMOD_LCTRL)
        .value("KEYMOD_RCTRL", key::KEYMOD_RCTRL)
        .value("KEYMOD_LALT", key::KEYMOD_LALT)
        .value("KEYMOD_RALT", key::KEYMOD_RALT)
        .value("KEYMOD_LMETA", key::KEYMOD_LMETA)
        .value("KEYMOD_RMETA", key::KEYMOD_RMETA)
        .value("KEYMOD_NUM", key::KEYMOD_NUM)
        .value("KEYMOD_CAPS", key::KEYMOD_CAPS)
        .value("KEYMOD_MODE", key::KEYMOD_MODE)
        .value("KEYMOD_RESERVED", key::KEYMOD_RESERVED)
        .value("KEYMOD_CTRL", key::KEYMOD_CTRL)
        .value("KEYMOD_SHIFT", key::KEYMOD_SHIFT)
        .value("KEYMOD_ALT", key::KEYMOD_ALT)
        .value("KEYMOD_META", key::KEYMOD_META)
        .export_values()
    ;

    class_<KeyEvent, bases<Event> >("KeyEvent",
            "Raised when a key is pressed or released.\n",
            no_init)
        .add_property("scancode", &KeyEvent::getScanCode,
            "The untranslated (hardware-dependent) scancode of the key pressed (ro).\n")
        .add_property("keycode", &KeyEvent::getKeyCode,
            "The keycode of the key according to US keyboard layout (ro).\n")
        .add_property("keystring", make_function(&KeyEvent::getKeyString,
                return_value_policy<copy_const_reference>()),
            "A character or word describing the key pressed (ro).\n")
        .add_property("unicode", &KeyEvent::getUnicode,
            "Unicode index of the character. Transparentyl dependent to modifiers,\n"
            "issued only on KEYDOWN event (ro).\n")
        .add_property("modifiers", &KeyEvent::getModifiers,
            "Any modifiers (shift, ctrl,...) pressed as well (ro).\n")
    ;

    class_<MouseEvent, bases<Event> >("MouseEvent",
            "Raised when a mouse-related event occurs.\n",
            no_init)
        .add_property("source", &MouseEvent::getSource,
                "Always MOUSE")
        .add_property("leftbuttonstate", &MouseEvent::getLeftButtonState)
        .add_property("middlebuttonstate", &MouseEvent::getMiddleButtonState)
        .add_property("rightbuttonstate", &MouseEvent::getRightButtonState)
        .add_property("x", &MouseEvent::getXPosition,
                "x position in the global coordinate system (ro).\n")
        .add_property("y", &MouseEvent::getYPosition,
                "y position in the global coordinate system (ro).\n")
        .add_property("cursorid", &MouseEvent::getCursorID,
                "Always -1 for mouse events, but can be used to handle mouse and \n"
                "tracking events at once (ro).\n")
        .add_property("button", &MouseEvent::getButton,
                "The button that caused the event (ro).\n")
        .add_property("node", &MouseEvent::getElement,
                "The node that the event handler was declared in (ro).\n")
        .add_property("lastdownpos", &CursorEvent::getLastDownPos,
                "The position of the last mouse down event with the same button.\n"
                "Useful for implementing dragging (ro).\n")
        ;

    class_<TouchEvent, bases<Event> >("TouchEvent",
            "Raised when a touch or other tracking event occurs. Touch events happen \n"
            "only when a multi-touch sensitive surface or other camera tracker is \n"
            "active. For each touch event, statistical data based on moments are \n"
            "calculated.",
            no_init)
        .add_property("source", &TouchEvent::getSource,
                "TOUCH for actual touches, TRACK for hands above the surface or\n"
                "generic tracking.\n")
        .add_property("area", &TouchEvent::getArea,
                "Size of the blob found in pixels (ro).\n")
        .add_property("orientation", &TouchEvent::getOrientation,
                "Angle of the blob. For hovering hands, this is roughly the direction \n"
                "of the hand (ro).\n")
        .add_property("inertia", &TouchEvent::getInertia)
        .add_property("eccentricity", &TouchEvent::getInertia)
        .add_property("x", &TouchEvent::getXPosition,
                "x position in the global coordinate system (ro).\n")
        .add_property("y", &TouchEvent::getYPosition,
                "y position in the global coordinate system (ro).\n")
        .add_property("cursorid", &TouchEvent::getCursorID)
        .add_property("node", &TouchEvent::getElement,
                "The node that the event handler was declared in (ro).\n")
        .add_property("center", make_function(&TouchEvent::getCenter,
                return_value_policy<copy_const_reference>()),
                "Position as double. Used for calibration (ro).\n")
        .add_property("majoraxis", make_function(&TouchEvent::getMajorAxis,
                return_value_policy<copy_const_reference>()),
                "Major axis of an ellipse that is similar to the blob (ro).\n")
        .add_property("minoraxis", make_function(&TouchEvent::getMinorAxis,
                return_value_policy<copy_const_reference>()),
                "Minor axis of an ellipse that is similar to the blob (ro).\n")
        .add_property("speed", make_function(&TouchEvent::getSpeed,
                return_value_policy<copy_const_reference>()),
                "Current speed of the blob in pixels per millisecond as a\n"
                "2-component vector (ro).\n")
        .def("getRelatedEvents", &TouchEvent::getRelatedEvents,
                "getRelatedEvents() -> events\n"
                "Returns a python tuple containing the events 'related' to this one.\n"
                "For TOUCH events (fingers), the tuple contains one element: the\n"
                "corresponding TRACK event (hand). For TRACK events, the tuple contains\n"
                "all TOUCH events that belong to the same hand.\n")
        .def("getContour", &TouchEvent::getContour,
                "getContour()\n"
                "Extracts contour envelope sequence for the event\n")
        .add_property("lastdownpos", &CursorEvent::getLastDownPos,
                "The initial position of the cursor. Useful for implementing dragging.\n")
        ;

    enum_<TrackerImageID>("TrackerImageID")
        .value("IMG_CAMERA", TRACKER_IMG_CAMERA)
        .value("IMG_DISTORTED", TRACKER_IMG_DISTORTED)
        .value("IMG_NOHISTORY", TRACKER_IMG_NOHISTORY)
        .value("IMG_HISTOGRAM", TRACKER_IMG_HISTOGRAM)
        .value("IMG_FINGERS", TRACKER_IMG_FINGERS)
        .value("IMG_HIGHPASS", TRACKER_IMG_HIGHPASS)
        .export_values()
    ;

    class_<TrackerEventSource, boost::noncopyable>("Tracker",
            "A tracker that uses a camera to track moving objects\n"
            "(e.g. fingers) and delivers them to the player as avg events.\n"
            "Create a tracker by using Player::addTracker(). The properties\n"
            "of this class are explained under U{https://www.libavg.de/wiki/index.php/Tracker_Setup}.",
            no_init)
        .def("getImage", &TrackerEventSource::getImage,
            return_value_policy<manage_new_object>(),
            "getImage(imageid) -> bitmap\n"
            "Returns one of the intermediate images necessary for tracking.\n"
            "These images are only available if setDebugImages was called before\n"
            "with appropriate parameters.\n"
            "@param imageid: One of IMG_CAMERA, IMG_DISTORTED, IMG_NOHISTORY,\n"
            "IMG_HISTOGRAM, IMG_FINGERS or IMG_HIGHPASS.\n")
        .def("saveConfig", &TrackerEventSource::saveConfig,
            "saveConfig(filename)\n"
            "Saves the current tracker configuration to the filename given. If filename\n"
            "is empty, the file used to construct the tracker is used.\n")
        .def("resetHistory", &TrackerEventSource::resetHistory,
            "resetHistory()\n"
            "Throws away the current history image and generates a new one from\n"
            "the next second of images.\n")
        .def("setDebugImages", &TrackerEventSource::setDebugImages,
            "setDebugImages(img, finger)\n"
            "Controls whether debug images of intermediate tracking results\n"
            "and detected finger positions are generated and exported to\n"
            "python. Generating the debug images takes a moderate amount of\n"
            "time, so it is turned off by default.\n"
            "@param img: Whether to generate intermediate result images.\n")
        .def("startCalibration", &TrackerEventSource::startCalibration,
            return_value_policy<reference_existing_object>(),
            "startCalibration(displayextents) -> trackercalibrator\n"
            "Starts coordinate calibration session. The returned TrackerCalibrator\n"
            "exists until endCalibration or abortCalibration is called.\n"
            "@param displayextents: The width and height of the display area.\n")
        .def("endCalibration", &TrackerEventSource::endCalibration,
            "endCalibration()\n"
            "Ends coordinate calibration session and activates the coordinate\n"
            "transformer generated.\n")
        .def("abortCalibration", &TrackerEventSource::abortCalibration,
            "abortCalibration()\n"
            "Aborts coordinate calibration session and restores the previous\n"
            "coordinate transformer.\n")

        .def("setParam", &TrackerEventSource::setParam,
            "setParam()\n"
            "Updates an arbitrary parameter of tracker configuration.\n")
        .def("getParam", &TrackerEventSource::getParam,
            "getParam()\n"
            "Retrieves an arbitrary parameter of tracker configuration.\n")

        ;

class_<TrackerCalibrator, boost::noncopyable>("TrackerCalibrator",
            "Used to map display points to camera points by mapping a set of reference\n"
            "points. Python code should display reference points that the user must\n"
            "touch to establish a mapping. Created by Tracker::startCalibration.\n",
            no_init)
        .def("nextPoint", &TrackerCalibrator::nextPoint,
            "nextPoint() -> done\n"
            "Advances to the next point. Returns False and ends calibration if\n"
            "all points have been set.\n")
        .def("getDisplayPoint", &TrackerCalibrator::getDisplayPoint,
            "getDisplayPoint() -> pos\n")
        .def("setCamPoint", &TrackerCalibrator::setCamPoint,
            "setCamPoint(pt)\n")
        ;
}
<commit_msg>Fixed docstring typo<commit_after>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2008 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  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
//
//  Current versions can be found at www.libavg.de
//

#include "WrapHelper.h"

#include "../player/KeyEvent.h"
#include "../player/MouseEvent.h"
#include "../player/TouchEvent.h"
#include "../player/Node.h"
#include "../player/TrackerEventSource.h"

using namespace boost::python;
using namespace avg;
using namespace std;

void export_event()
{
    boost::python::to_python_converter<vector<TouchEvent*>,
        to_tuple<vector<TouchEvent *> > >();

    boost::python::to_python_converter<ContourSeq,
        to_list<ContourSeq> >();

    from_python_sequence<ContourSeq, variable_capacity_policy>();

    class_<Event, boost::noncopyable>("Event",
            "Base class for user input events.\n",
            no_init)
        .add_property("type", &Event::getType,
                "One of KEYUP, KEYDOWN, CURSORMOTION, CURSORUP,\n"
                "CURSORDOWN, CURSOROVER, CURSOROUT, RESIZE or QUIT.\n")
        .add_property("when", &Event::getWhen,
                "The timestamp of the event in milliseconds.\n")
    ;

    enum_<Event::Type>("Type")
        .value("KEYUP", Event::KEYUP)
        .value("KEYDOWN", Event::KEYDOWN)
        .value("CURSORMOTION", Event::CURSORMOTION)
        .value("CURSORUP", Event::CURSORUP)
        .value("CURSORDOWN", Event::CURSORDOWN)
        .value("CURSOROVER", Event::CURSOROVER)
        .value("CURSOROUT", Event::CURSOROUT)
        .value("RESIZE", Event::RESIZE)
        .value("QUIT", Event::QUIT)
        .export_values()
    ;

    enum_<CursorEvent::Source>("Source")
        .value("MOUSE", CursorEvent::MOUSE)
        .value("TOUCH", CursorEvent::TOUCH)
        .value("TRACK", CursorEvent::TRACK)
        .value("NONE", Event::NONE)
        .export_values()
    ;

    enum_<int>("KeyModifier")
        .value("KEYMOD_NONE", key::KEYMOD_NONE)
        .value("KEYMOD_LSHIFT", key::KEYMOD_LSHIFT)
        .value("KEYMOD_RSHIFT", key::KEYMOD_RSHIFT)
        .value("KEYMOD_LCTRL", key::KEYMOD_LCTRL)
        .value("KEYMOD_RCTRL", key::KEYMOD_RCTRL)
        .value("KEYMOD_LALT", key::KEYMOD_LALT)
        .value("KEYMOD_RALT", key::KEYMOD_RALT)
        .value("KEYMOD_LMETA", key::KEYMOD_LMETA)
        .value("KEYMOD_RMETA", key::KEYMOD_RMETA)
        .value("KEYMOD_NUM", key::KEYMOD_NUM)
        .value("KEYMOD_CAPS", key::KEYMOD_CAPS)
        .value("KEYMOD_MODE", key::KEYMOD_MODE)
        .value("KEYMOD_RESERVED", key::KEYMOD_RESERVED)
        .value("KEYMOD_CTRL", key::KEYMOD_CTRL)
        .value("KEYMOD_SHIFT", key::KEYMOD_SHIFT)
        .value("KEYMOD_ALT", key::KEYMOD_ALT)
        .value("KEYMOD_META", key::KEYMOD_META)
        .export_values()
    ;

    class_<KeyEvent, bases<Event> >("KeyEvent",
            "Raised when a key is pressed or released.\n",
            no_init)
        .add_property("scancode", &KeyEvent::getScanCode,
            "The untranslated (hardware-dependent) scancode of the key pressed (ro).\n")
        .add_property("keycode", &KeyEvent::getKeyCode,
            "The keycode of the key according to US keyboard layout (ro).\n")
        .add_property("keystring", make_function(&KeyEvent::getKeyString,
                return_value_policy<copy_const_reference>()),
            "A character or word describing the key pressed (ro).\n")
        .add_property("unicode", &KeyEvent::getUnicode,
            "Unicode index of the character. Transparently dependent to modifiers,\n"
            "issued only on KEYDOWN event (ro).\n")
        .add_property("modifiers", &KeyEvent::getModifiers,
            "Any modifiers (shift, ctrl,...) pressed as well (ro).\n")
    ;

    class_<MouseEvent, bases<Event> >("MouseEvent",
            "Raised when a mouse-related event occurs.\n",
            no_init)
        .add_property("source", &MouseEvent::getSource,
                "Always MOUSE")
        .add_property("leftbuttonstate", &MouseEvent::getLeftButtonState)
        .add_property("middlebuttonstate", &MouseEvent::getMiddleButtonState)
        .add_property("rightbuttonstate", &MouseEvent::getRightButtonState)
        .add_property("x", &MouseEvent::getXPosition,
                "x position in the global coordinate system (ro).\n")
        .add_property("y", &MouseEvent::getYPosition,
                "y position in the global coordinate system (ro).\n")
        .add_property("cursorid", &MouseEvent::getCursorID,
                "Always -1 for mouse events, but can be used to handle mouse and \n"
                "tracking events at once (ro).\n")
        .add_property("button", &MouseEvent::getButton,
                "The button that caused the event (ro).\n")
        .add_property("node", &MouseEvent::getElement,
                "The node that the event handler was declared in (ro).\n")
        .add_property("lastdownpos", &CursorEvent::getLastDownPos,
                "The position of the last mouse down event with the same button.\n"
                "Useful for implementing dragging (ro).\n")
        ;

    class_<TouchEvent, bases<Event> >("TouchEvent",
            "Raised when a touch or other tracking event occurs. Touch events happen \n"
            "only when a multi-touch sensitive surface or other camera tracker is \n"
            "active. For each touch event, statistical data based on moments are \n"
            "calculated.",
            no_init)
        .add_property("source", &TouchEvent::getSource,
                "TOUCH for actual touches, TRACK for hands above the surface or\n"
                "generic tracking.\n")
        .add_property("area", &TouchEvent::getArea,
                "Size of the blob found in pixels (ro).\n")
        .add_property("orientation", &TouchEvent::getOrientation,
                "Angle of the blob. For hovering hands, this is roughly the direction \n"
                "of the hand (ro).\n")
        .add_property("inertia", &TouchEvent::getInertia)
        .add_property("eccentricity", &TouchEvent::getInertia)
        .add_property("x", &TouchEvent::getXPosition,
                "x position in the global coordinate system (ro).\n")
        .add_property("y", &TouchEvent::getYPosition,
                "y position in the global coordinate system (ro).\n")
        .add_property("cursorid", &TouchEvent::getCursorID)
        .add_property("node", &TouchEvent::getElement,
                "The node that the event handler was declared in (ro).\n")
        .add_property("center", make_function(&TouchEvent::getCenter,
                return_value_policy<copy_const_reference>()),
                "Position as double. Used for calibration (ro).\n")
        .add_property("majoraxis", make_function(&TouchEvent::getMajorAxis,
                return_value_policy<copy_const_reference>()),
                "Major axis of an ellipse that is similar to the blob (ro).\n")
        .add_property("minoraxis", make_function(&TouchEvent::getMinorAxis,
                return_value_policy<copy_const_reference>()),
                "Minor axis of an ellipse that is similar to the blob (ro).\n")
        .add_property("speed", make_function(&TouchEvent::getSpeed,
                return_value_policy<copy_const_reference>()),
                "Current speed of the blob in pixels per millisecond as a\n"
                "2-component vector (ro).\n")
        .def("getRelatedEvents", &TouchEvent::getRelatedEvents,
                "getRelatedEvents() -> events\n"
                "Returns a python tuple containing the events 'related' to this one.\n"
                "For TOUCH events (fingers), the tuple contains one element: the\n"
                "corresponding TRACK event (hand). For TRACK events, the tuple contains\n"
                "all TOUCH events that belong to the same hand.\n")
        .def("getContour", &TouchEvent::getContour,
                "getContour()\n"
                "Extracts contour envelope sequence for the event\n")
        .add_property("lastdownpos", &CursorEvent::getLastDownPos,
                "The initial position of the cursor. Useful for implementing dragging.\n")
        ;

    enum_<TrackerImageID>("TrackerImageID")
        .value("IMG_CAMERA", TRACKER_IMG_CAMERA)
        .value("IMG_DISTORTED", TRACKER_IMG_DISTORTED)
        .value("IMG_NOHISTORY", TRACKER_IMG_NOHISTORY)
        .value("IMG_HISTOGRAM", TRACKER_IMG_HISTOGRAM)
        .value("IMG_FINGERS", TRACKER_IMG_FINGERS)
        .value("IMG_HIGHPASS", TRACKER_IMG_HIGHPASS)
        .export_values()
    ;

    class_<TrackerEventSource, boost::noncopyable>("Tracker",
            "A tracker that uses a camera to track moving objects\n"
            "(e.g. fingers) and delivers them to the player as avg events.\n"
            "Create a tracker by using Player::addTracker(). The properties\n"
            "of this class are explained under U{https://www.libavg.de/wiki/index.php/Tracker_Setup}.",
            no_init)
        .def("getImage", &TrackerEventSource::getImage,
            return_value_policy<manage_new_object>(),
            "getImage(imageid) -> bitmap\n"
            "Returns one of the intermediate images necessary for tracking.\n"
            "These images are only available if setDebugImages was called before\n"
            "with appropriate parameters.\n"
            "@param imageid: One of IMG_CAMERA, IMG_DISTORTED, IMG_NOHISTORY,\n"
            "IMG_HISTOGRAM, IMG_FINGERS or IMG_HIGHPASS.\n")
        .def("saveConfig", &TrackerEventSource::saveConfig,
            "saveConfig(filename)\n"
            "Saves the current tracker configuration to the filename given. If filename\n"
            "is empty, the file used to construct the tracker is used.\n")
        .def("resetHistory", &TrackerEventSource::resetHistory,
            "resetHistory()\n"
            "Throws away the current history image and generates a new one from\n"
            "the next second of images.\n")
        .def("setDebugImages", &TrackerEventSource::setDebugImages,
            "setDebugImages(img, finger)\n"
            "Controls whether debug images of intermediate tracking results\n"
            "and detected finger positions are generated and exported to\n"
            "python. Generating the debug images takes a moderate amount of\n"
            "time, so it is turned off by default.\n"
            "@param img: Whether to generate intermediate result images.\n")
        .def("startCalibration", &TrackerEventSource::startCalibration,
            return_value_policy<reference_existing_object>(),
            "startCalibration(displayextents) -> trackercalibrator\n"
            "Starts coordinate calibration session. The returned TrackerCalibrator\n"
            "exists until endCalibration or abortCalibration is called.\n"
            "@param displayextents: The width and height of the display area.\n")
        .def("endCalibration", &TrackerEventSource::endCalibration,
            "endCalibration()\n"
            "Ends coordinate calibration session and activates the coordinate\n"
            "transformer generated.\n")
        .def("abortCalibration", &TrackerEventSource::abortCalibration,
            "abortCalibration()\n"
            "Aborts coordinate calibration session and restores the previous\n"
            "coordinate transformer.\n")

        .def("setParam", &TrackerEventSource::setParam,
            "setParam()\n"
            "Updates an arbitrary parameter of tracker configuration.\n")
        .def("getParam", &TrackerEventSource::getParam,
            "getParam()\n"
            "Retrieves an arbitrary parameter of tracker configuration.\n")

        ;

class_<TrackerCalibrator, boost::noncopyable>("TrackerCalibrator",
            "Used to map display points to camera points by mapping a set of reference\n"
            "points. Python code should display reference points that the user must\n"
            "touch to establish a mapping. Created by Tracker::startCalibration.\n",
            no_init)
        .def("nextPoint", &TrackerCalibrator::nextPoint,
            "nextPoint() -> done\n"
            "Advances to the next point. Returns False and ends calibration if\n"
            "all points have been set.\n")
        .def("getDisplayPoint", &TrackerCalibrator::getDisplayPoint,
            "getDisplayPoint() -> pos\n")
        .def("setCamPoint", &TrackerCalibrator::setCamPoint,
            "setCamPoint(pt)\n")
        ;
}
<|endoftext|>


<commit_before>/* <x0/mod_vhost_basic.cpp>
 *
 * This file is part of the x0 web server project and is released under LGPL-3.
 *
 * (c) 2009 Chrisitan Parpart <trapni@gentoo.org>
 */

#include <x0/server.hpp>
#include <x0/request.hpp>
#include <x0/response.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/signal.hpp>
#include <boost/bind.hpp>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

/**
 * \ingroup modules
 * \brief provides a basic config-file based virtual hosting facility.
 *
 *

 * -- example configuration
 *
 * BindAddress = '0::0';             -- default bind address
 * Listen = 80;                      -- default listening port
 * DefaultHost = 'www.example.com';  -- default vhost to choose when we receive an unknown Host-request-header.
 *
 * Hosts = {
 *     ['www.example.com'] = {
 *         ServerAliases = { 'www.example.net', 'example.com', 'example.net' };
 *         DocumentRoot = '/var/www/example.com/htdocs';
 *     };
 *     ['localhost:8080'] = {
 *         DocumentRoot = '/var/www/example.com/htdocs';
 *         BindAddress = 'localhost';
 *     };
 * };
 *

 */
class vhost_basic_plugin :
	public x0::plugin
{
private:
	boost::signals::connection c;

	struct vhost_config
	{
		std::string docroot;
	};

	struct server_config
	{
		std::string default_host;
		std::map<std::string, vhost_config *> mappings;
	};

public:
	vhost_basic_plugin(x0::server& srv, const std::string& name) :
		x0::plugin(srv, name)
	{
		c = server_.resolve_document_root.connect(boost::bind(&vhost_basic_plugin::resolve_document_root, this, _1));
	}

	~vhost_basic_plugin()
	{
		server_.resolve_document_root.disconnect(c);
	}

	virtual void configure()
	{
		auto hostnames = server_.config()["Hosts"].keys<std::string>();
		if (hostnames.empty())
			return;

		std::string default_bind("0::0");
		server_.config().load("BindAddress", default_bind);

		int default_port(80);
		server_.config().load("Listen", default_port);

		server_config& srvcfg = server_.create_context<server_config>(this);

		server_.config().load("DefaultHost", srvcfg.default_host);
		if (srvcfg.default_host.find(":") == std::string::npos && default_port != 80)
		{
			srvcfg.default_host = srvcfg.default_host + ":" + boost::lexical_cast<std::string>(default_port);
		}

		for (auto i = hostnames.begin(), e = hostnames.end(); i != e; ++i)
		{
			std::string hostname(*i);

			auto aliases = server_.config()["Hosts"][hostname]["ServerAliases"].as<std::vector<std::string>>();

			std::string docroot = server_.config()["Hosts"][hostname]["DocumentRoot"].as<std::string>();

			std::string bind = server_.config()["Hosts"][hostname]["BindAddress"].as<std::string>();
			if (bind.empty())
				bind = default_bind;

			int port = extract_port(hostname);
			if (!port)
			{
				port = default_port;

				if (port != 80)
				{
					hostname = hostname + ":" + boost::lexical_cast<std::string>(port);
				}
			}

//			server_.log(x0::severity::debug, "port=%d: hostname[%s]: docroot[%s], alias-count=%d",
//				port, hostname.c_str(), docroot.c_str(), aliases.size());

			vhost_config& cfg = server_.create_context<vhost_config>(this, hostname);
			cfg.docroot = docroot;

			for (auto k = aliases.begin(), m = aliases.end(); k != m; ++k)
			{
				std::string name(*k);
				if (name.find(":") == std::string::npos && port != 80)
				{
					name = name + ":" + boost::lexical_cast<std::string>(port);
				}

				auto f = srvcfg.mappings.find(name);
				if (f == srvcfg.mappings.end())
				{
					srvcfg.mappings[name] = &cfg;
				}
				else
				{
					server_.log(x0::severity::warn, "Server alias '%s' already in use.", name.c_str());
				}
			}

			server_.setup_listener(port, bind);
		}
	}

private:
	int extract_port(const std::string& hostname)
	{
		static std::string delim(":");
		std::size_t n = hostname.find(delim);

		if (n == std::string::npos)
			return 0;

		return boost::lexical_cast<int>(hostname.substr(n + 1));
	}

	void resolve_document_root(x0::request& in)
	{
		try
		{
			static std::string hostkey("Host");
			std::string name(in.header(hostkey));

			server_config& srvcfg = server_.context<server_config>(this);
			auto i = srvcfg.mappings.find(name);
			if (i != srvcfg.mappings.end())
			{
				in.document_root = i->second->docroot;
			}
			else
			{
				in.document_root = server_.context<vhost_config>(this, name).docroot;
			}
		}
		catch (const x0::host_not_found&)
		{
			try
			{
				// resolve to default host's document root
				std::string default_host(server_.context<server_config>(this).default_host);
				in.document_root = server_.context<vhost_config>(this, default_host).docroot;
				// XXX we could instead auto-redirect them.
			}
			catch (...) {}
		}
	}
};

X0_EXPORT_PLUGIN(vhost_basic);
<commit_msg>vhost_basic: remove default Listen global config var and enforce explicit specification of port number in Hosts map<commit_after>/* <x0/mod_vhost_basic.cpp>
 *
 * This file is part of the x0 web server project and is released under LGPL-3.
 *
 * (c) 2009 Chrisitan Parpart <trapni@gentoo.org>
 */

#include <x0/server.hpp>
#include <x0/request.hpp>
#include <x0/response.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/signal.hpp>
#include <boost/bind.hpp>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

/**
 * \ingroup modules
 * \brief provides a basic config-file based virtual hosting facility.
 *
 *

 * -- example configuration
 *
 * BindAddress = '0::0';             -- default bind address
 * Listen = 80;                      -- default listening port
 * DefaultHost = 'www.example.com';  -- default vhost to choose when we receive an unknown Host-request-header.
 *
 * Hosts = {
 *     ['www.example.com'] = {
 *         ServerAliases = { 'www.example.net', 'example.com', 'example.net' };
 *         DocumentRoot = '/var/www/example.com/htdocs';
 *     };
 *     ['localhost:8080'] = {
 *         DocumentRoot = '/var/www/example.com/htdocs';
 *         BindAddress = 'localhost';
 *     };
 * };
 *

 */
class vhost_basic_plugin :
	public x0::plugin
{
private:
	boost::signals::connection c;

	struct vhost_config
	{
		std::string docroot;
	};

	struct server_config
	{
		std::string default_hostid;
		std::map<std::string, vhost_config *> mappings;
	};

public:
	vhost_basic_plugin(x0::server& srv, const std::string& name) :
		x0::plugin(srv, name)
	{
		c = server_.resolve_document_root.connect(boost::bind(&vhost_basic_plugin::resolve_document_root, this, _1));
	}

	~vhost_basic_plugin()
	{
		server_.resolve_document_root.disconnect(c);
	}

	virtual void configure()
	{
		auto hosts = server_.config()["Hosts"].keys<std::string>();
		if (hosts.empty())
			return;

		std::string default_bind("0::0");
		server_.config().load("BindAddress", default_bind);

		server_config& srvcfg = server_.create_context<server_config>(this);

		server_.config().load("DefaultHost", srvcfg.default_hostid);

		for (auto i = hosts.begin(), e = hosts.end(); i != e; ++i)
		{
			std::string hostid = x0::make_hostid(*i);
			int port = x0::extract_port_from_hostid(hostid);

			auto aliases = server_.config()["Hosts"][hostid]["ServerAliases"].as<std::vector<std::string>>();
			std::string docroot = server_.config()["Hosts"][hostid]["DocumentRoot"].as<std::string>();
			std::string bind = server_.config()["Hosts"][hostid]["BindAddress"].get<std::string>(default_bind);

//			server_.log(x0::severity::debug, "port=%d: hostid[%s]: docroot[%s], alias-count=%d",
//				port, hostid.c_str(), docroot.c_str(), aliases.size());

			vhost_config& cfg = server_.create_context<vhost_config>(this, hostid);
			cfg.docroot = docroot;

			srvcfg.mappings.insert({ {hostid, &cfg} });
			for (auto k = aliases.begin(), m = aliases.end(); k != m; ++k)
			{
				std::string hid(x0::make_hostid(*k, port));

				auto f = srvcfg.mappings.find(hid);
				if (f == srvcfg.mappings.end())
				{
					srvcfg.mappings[hid] = &cfg;

					int aport = x0::extract_port_from_hostid(hid);
					server_.setup_listener(aport, bind);
				}
				else
				{
					server_.log(x0::severity::warn, "Server alias '%s' already in use.", hid.c_str());
				}
			}

			server_.setup_listener(port, bind);
		}
	}

private:
	void resolve_document_root(x0::request& in)
	{
		try
		{
			static std::string hostkey("Host");
			std::string hostid(x0::make_hostid(in.header(hostkey)));

			server_config& srvcfg = server_.context<server_config>(this);
			auto i = srvcfg.mappings.find(hostid);
			if (i != srvcfg.mappings.end())
			{
				in.document_root = i->second->docroot;
				server_.log(x0::severity::debug, "vhost_basic[%s]: resolved to %s", hostid.c_str(), in.document_root.c_str());
			}
			else
			{
				in.document_root = server_.context<vhost_config>(this, hostid).docroot;
			}
		}
		catch (const x0::host_not_found&)
		{
			try
			{
				// resolve to default host's document root
				std::string default_hostid(server_.context<server_config>(this).default_hostid);
				in.document_root = server_.context<vhost_config>(this, default_hostid).docroot;
				// XXX we could instead auto-redirect them.
			}
			catch (...) {}
		}
	}
};

X0_EXPORT_PLUGIN(vhost_basic);
<|endoftext|>


<commit_before>

// This file contains definition of C++ new/delete operators

#include <stddef.h>
#include <malloc.h>
#include "stdexcept.h"

void * operator new(size_t size) {
    void * mem = malloc(size);
    if(mem == NULL) {
        throw std::bad_alloc();
    }

    return mem;
}

void operator delete(void * ptr) {
    free(ptr);
}

<commit_msg>Array new/delete operators were implemented. Weak attribute was added for new/delete operators.<commit_after>

// This file contains definition of C++ new/delete operators

#include <stddef.h>
#include <malloc.h>
#include "stdexcept.h"

__attribute__((weak))
void * operator new(size_t size) {
    void * mem = malloc(size);
    if(mem == NULL) {
        throw std::bad_alloc();
    }

    return mem;
}

__attribute__((weak))
void operator delete(void * ptr) {
    free(ptr);
}

__attribute__((weak))
void * operator new[](size_t size) {
    return ::operator new(size);
}

__attribute__((weak))
void operator delete[](void * ptr) {
    ::operator delete(ptr);
}

<|endoftext|>


<commit_before>// Copyright 2013, Rolf Meyer
// See LICENCE for more information

#include <nan.h>
#include <node_buffer.h>
#include <vector>
#include <iostream>
#include <cstring>

#include "reader.h"
#include "utils.h"

/**
 * plugin global secure card context
 **/
#ifndef USE_LIBNFC
static pcsc_context *context;
#else
#include <signal.h>
static nfc_context *context = NULL;
void deinitialize_nfc_context(int p) {
  if (context)
    nfc_exit(context);
}
#endif
static std::vector<reader_data *> readers_data;
static Nan::Persistent<v8::Object> readers_global(Nan::New<v8::Object>());

/**
 * Get Names of the Readers connected to the computer
 * @param hContext The SCard Context used to search
 * @return An Array of Strings with reader names
 **/
void getReader(const Nan::FunctionCallbackInfo<v8::Value>& info) {
#ifndef USE_LIBNFC
  LONG res;
  char *reader_names;
#else
  size_t numDevices;
  const size_t MAX_READERS = 16;
  nfc_connstring reader_names[MAX_READERS];
#endif
  char *reader_iter = NULL;
  int   reader_count = 0;
  // Allocate buffer. We assume autoallocate is not present (on Mac OS X anyway)
  v8::Local<v8::Object> readers_local = Nan::New<v8::Object>(readers_global);

  if(info.Length() > 0){
    Nan::ThrowError("This function does not take any arguments");
    return;
  }

#ifndef USE_LIBNFC
  res = pcsc_list_devices(context, &reader_names);
  if(res != SCARD_S_SUCCESS || reader_names[0] == '\0') {
    v8::Local<v8::Object> global = v8::Context::GetCurrent()->Global();
    v8::Local<v8::Object> JSON = v8::Local<v8::Object>::Cast(global->Get(Nan::New("JSON").ToLocalChecked()));
    v8::Local<v8::Function> stringify = v8::Local<v8::Function>::Cast(JSON->Get(Nan::New("stringify").ToLocalChecked()));
    v8::Local<v8::Object> error = Nan::New<v8::Object>();

    error->Set(Nan::New("code").ToLocalChecked(), Nan::New(res));
    error->Set(Nan::New("msg").ToLocalChecked(), Nan::New("Unable to list readers").ToLocalChecked());
    v8::Local<v8::Value> args[] = { error };
    v8::Local<v8::String> result = v8::Local<v8::String>::Cast(stringify->Call(JSON, 1, args));
    Nan::ThrowError(result);
    return;
  }
#else
  numDevices = nfc_list_devices(context, reader_names, MAX_READERS);
  if(numDevices == 0) {
    info.GetReturnValue().Set(Nan::New<v8::Object>(readers_global));
    return;
  }
#endif

  // Clean before use
  for(std::vector<reader_data *>::iterator iter = readers_data.begin();iter!=readers_data.end();iter++) {
    reader_data *data = *iter;
    if(data) {
      delete data;
    }
    *iter = NULL;
  }
  readers_data.clear();

  // Get number of readers from null separated string
#ifndef USE_LIBNFC
  reader_iter = reader_names;
  while(*reader_iter != '\0') {
    readers_data.push_back(new reader_data(reader_iter, context));
#else
  reader_iter = reader_names[0];
  char *names_end = reader_names[0] + (MAX_READERS * sizeof(nfc_connstring));
  while(reader_iter <= names_end) {
    // see if we can claim it
    nfc_device *dev = NULL;
    dev = nfc_open(context, reader_iter);
    if (dev == NULL) {
      // XXX: failed to open connstring
      reader_iter += sizeof(nfc_connstring);
      continue;
    }
    std::cout << "Found device: " << nfc_device_get_name(dev) << std::endl;
    nfc_close(dev);
    readers_data.push_back(new reader_data(reader_iter, context, NULL));
#endif
    // Node Object:
    v8::Local<v8::External> data = Nan::New<v8::External>(readers_data.back());
    v8::Local<v8::Object> reader = Nan::New<v8::Object>();
    reader->Set(Nan::New("name").ToLocalChecked(), Nan::New(reader_iter).ToLocalChecked());
    reader->Set(Nan::New("listen").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(ReaderListen)->GetFunction());
    reader->Set(Nan::New("setLed").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(ReaderSetLed)->GetFunction());
    reader->Set(Nan::New("release").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(ReaderRelease)->GetFunction());
    reader->SetHiddenValue(Nan::New("data").ToLocalChecked(), data);
    readers_local->Set(Nan::New(reader_iter).ToLocalChecked(), reader);
#ifndef USE_LIBNFC
    reader_iter += strlen(reader_iter)+1;
    reader_count++;
#else
    reader_iter += sizeof(nfc_connstring);
#endif
  }
  //delete [] reader_names;

  info.GetReturnValue().Set(readers_local);
  return;
}

/**
 * Node.js initialization function
 * @param exports The Commonjs module exports object
 **/

void init(v8::Local<v8::Object> exports) {
#ifndef USE_LIBNFC
  pcsc_init(&context);
#else
  nfc_init(&context);
#endif
  if(!context) {
    Nan::ThrowError("Cannot establish context");
    return;
  }

  exports->Set(Nan::New("getReader").ToLocalChecked(),
      Nan::New<v8::FunctionTemplate>(getReader)->GetFunction());
  exports->Set(Nan::New("setSleep").ToLocalChecked(),
      Nan::New<v8::FunctionTemplate>(mifare_set_sleep)->GetFunction());
	// AtExit(&PCSC::close);
}

NODE_MODULE(node_mifare, init)
<commit_msg>Windows still does not like to recall getReaders so we reetablish the context<commit_after>// Copyright 2013, Rolf Meyer
// See LICENCE for more information

#include <nan.h>
#include <node_buffer.h>
#include <vector>
#include <iostream>
#include <cstring>

#include "reader.h"
#include "utils.h"

/**
 * plugin global secure card context
 **/
#ifndef USE_LIBNFC
static pcsc_context *context;
#else
#include <signal.h>
static nfc_context *context = NULL;
void deinitialize_nfc_context(int p) {
  if (context)
    nfc_exit(context);
}
#endif
static std::vector<reader_data *> readers_data;
static Nan::Persistent<v8::Object> readers_global(Nan::New<v8::Object>());

/**
 * Get Names of the Readers connected to the computer
 * @param hContext The SCard Context used to search
 * @return An Array of Strings with reader names
 **/
void getReader(const Nan::FunctionCallbackInfo<v8::Value>& info) {
#ifndef USE_LIBNFC
  LONG res;
  char *reader_names;
#else
  size_t numDevices;
  const size_t MAX_READERS = 16;
  nfc_connstring reader_names[MAX_READERS];
#endif
  char *reader_iter = NULL;
  int   reader_count = 0;
  // Allocate buffer. We assume autoallocate is not present (on Mac OS X anyway)
  v8::Local<v8::Object> readers_local = Nan::New<v8::Object>(readers_global);

  if(info.Length() > 0){
    Nan::ThrowError("This function does not take any arguments");
    return;
  }

#ifndef USE_LIBNFC
  if(context) { // For the moment we need to reeterblish context.
                // Otherwise windows will not allow us to recall getReaders
    pcsc_exit(context);
  }
  pcsc_init(&context);
  if(!context) {
    Nan::ThrowError("Cannot establish context");
    return;
  }
  res = pcsc_list_devices(context, &reader_names);
  if(res != SCARD_S_SUCCESS || reader_names[0] == '\0') {
    v8::Local<v8::Object> global = v8::Context::GetCurrent()->Global();
    v8::Local<v8::Object> JSON = v8::Local<v8::Object>::Cast(global->Get(Nan::New("JSON").ToLocalChecked()));
    v8::Local<v8::Function> stringify = v8::Local<v8::Function>::Cast(JSON->Get(Nan::New("stringify").ToLocalChecked()));
    v8::Local<v8::Object> error = Nan::New<v8::Object>();

    error->Set(Nan::New("code").ToLocalChecked(), Nan::New(res));
    error->Set(Nan::New("msg").ToLocalChecked(), Nan::New("Unable to list readers").ToLocalChecked());
    v8::Local<v8::Value> args[] = { error };
    v8::Local<v8::String> result = v8::Local<v8::String>::Cast(stringify->Call(JSON, 1, args));
    Nan::ThrowError(result);
    return;
  }
#else
  if(context) {
    nfc_exit(context);
  }
  nfc_init(&context);
  if(!context) {
    Nan::ThrowError("Cannot establish context");
    return;
  }
  numDevices = nfc_list_devices(context, reader_names, MAX_READERS);
  if(numDevices == 0) {
    info.GetReturnValue().Set(Nan::New<v8::Object>(readers_global));
    return;
  }
#endif

  // Clean before use
  for(std::vector<reader_data *>::iterator iter = readers_data.begin();iter!=readers_data.end();iter++) {
    reader_data *data = *iter;
    if(data) {
      delete data;
    }
    *iter = NULL;
  }
  readers_data.clear();

  // Get number of readers from null separated string
#ifndef USE_LIBNFC
  reader_iter = reader_names;
  while(*reader_iter != '\0') {
    readers_data.push_back(new reader_data(reader_iter, context));
#else
  reader_iter = reader_names[0];
  char *names_end = reader_names[0] + (MAX_READERS * sizeof(nfc_connstring));
  while(reader_iter <= names_end) {
    // see if we can claim it
    nfc_device *dev = NULL;
    dev = nfc_open(context, reader_iter);
    if (dev == NULL) {
      // XXX: failed to open connstring
      reader_iter += sizeof(nfc_connstring);
      continue;
    }
    std::cout << "Found device: " << nfc_device_get_name(dev) << std::endl;
    nfc_close(dev);
    readers_data.push_back(new reader_data(reader_iter, context, NULL));
#endif
    // Node Object:
    v8::Local<v8::External> data = Nan::New<v8::External>(readers_data.back());
    v8::Local<v8::Object> reader = Nan::New<v8::Object>();
    reader->Set(Nan::New("name").ToLocalChecked(), Nan::New(reader_iter).ToLocalChecked());
    reader->Set(Nan::New("listen").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(ReaderListen)->GetFunction());
    reader->Set(Nan::New("setLed").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(ReaderSetLed)->GetFunction());
    reader->Set(Nan::New("release").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(ReaderRelease)->GetFunction());
    reader->SetHiddenValue(Nan::New("data").ToLocalChecked(), data);
    readers_local->Set(Nan::New(reader_iter).ToLocalChecked(), reader);
#ifndef USE_LIBNFC
    reader_iter += strlen(reader_iter)+1;
    reader_count++;
#else
    reader_iter += sizeof(nfc_connstring);
#endif
  }
  //delete [] reader_names;

  info.GetReturnValue().Set(readers_local);
  return;
}

/**
 * Node.js initialization function
 * @param exports The Commonjs module exports object
 **/

void init(v8::Local<v8::Object> exports) {
  context = NULL;

  exports->Set(Nan::New("getReader").ToLocalChecked(),
      Nan::New<v8::FunctionTemplate>(getReader)->GetFunction());
  exports->Set(Nan::New("setSleep").ToLocalChecked(),
      Nan::New<v8::FunctionTemplate>(mifare_set_sleep)->GetFunction());
	// AtExit(&PCSC::close);
}

NODE_MODULE(node_mifare, init)
<|endoftext|>


<commit_before>#include "command.hh"
#include "store-api.hh"
#include "fs-accessor.hh"
#include "nar-accessor.hh"

using namespace nix;

struct MixLs : virtual Args
{
    std::string path;

    bool recursive = false;
    bool verbose = false;
    bool showDirectory = false;

    MixLs()
    {
        mkFlag('R', "recursive", "list subdirectories recursively", &recursive);
        mkFlag('l', "long", "show more file information", &verbose);
        mkFlag('d', "directory", "show directories rather than their contents", &showDirectory);
    }

    void list(ref<FSAccessor> accessor)
    {
        std::function<void(const FSAccessor::Stat &, const Path &, const std::string &, bool)> doPath;

        auto showFile = [&](const Path & curPath, const std::string & relPath) {
            if (verbose) {
                auto st = accessor->stat(curPath);
                std::string tp =
                    st.type == FSAccessor::Type::tRegular ?
                        (st.isExecutable ? "-r-xr-xr-x" : "-r--r--r--") :
                    st.type == FSAccessor::Type::tSymlink ? "lrwxrwxrwx" :
                    "dr-xr-xr-x";
                std::cout <<
                    (format("%s %20d %s") % tp % st.fileSize % relPath);
                if (st.type == FSAccessor::Type::tSymlink)
                    std::cout << " -> " << accessor->readLink(curPath)
                    ;
                std::cout << "\n";
                if (recursive && st.type == FSAccessor::Type::tDirectory)
                    doPath(st, curPath, relPath, false);
            } else {
                std::cout << relPath << "\n";
                if (recursive) {
                    auto st = accessor->stat(curPath);
                    if (st.type == FSAccessor::Type::tDirectory)
                        doPath(st, curPath, relPath, false);
                }
            }
        };

        doPath = [&](const FSAccessor::Stat & st , const Path & curPath,
            const std::string & relPath, bool showDirectory)
        {
            if (st.type == FSAccessor::Type::tDirectory && !showDirectory) {
                auto names = accessor->readDirectory(curPath);
                for (auto & name : names)
                    showFile(curPath + "/" + name, relPath + "/" + name);
            } else
                showFile(curPath, relPath);
        };

        auto st = accessor->stat(path);
        if (st.type == FSAccessor::Type::tMissing)
            throw Error(format("path ‘%1%’ does not exist") % path);
        doPath(st, path,
            st.type == FSAccessor::Type::tDirectory ? "." : baseNameOf(path),
            showDirectory);
    }
};

struct CmdLsStore : StoreCommand, MixLs
{
    CmdLsStore()
    {
        expectArg("path", &path);
    }

    std::string name() override
    {
        return "ls-store";
    }

    std::string description() override
    {
        return "show information about a store path";
    }

    void run(ref<Store> store) override
    {
        list(store->getFSAccessor());
    }
};

struct CmdLsNar : Command, MixLs
{
    Path narPath;

    CmdLsNar()
    {
        expectArg("nar", &narPath);
        expectArg("path", &path);
    }

    std::string name() override
    {
        return "ls-nar";
    }

    std::string description() override
    {
        return "show information about the contents of a NAR file";
    }

    void run() override
    {
        list(makeNarAccessor(make_ref<std::string>(readFile(narPath))));
    }
};

static RegisterCommand r1(make_ref<CmdLsStore>());
static RegisterCommand r2(make_ref<CmdLsNar>());
<commit_msg>nix ls: support '/' for the root directory<commit_after>#include "command.hh"
#include "store-api.hh"
#include "fs-accessor.hh"
#include "nar-accessor.hh"

using namespace nix;

struct MixLs : virtual Args
{
    std::string path;

    bool recursive = false;
    bool verbose = false;
    bool showDirectory = false;

    MixLs()
    {
        mkFlag('R', "recursive", "list subdirectories recursively", &recursive);
        mkFlag('l', "long", "show more file information", &verbose);
        mkFlag('d', "directory", "show directories rather than their contents", &showDirectory);
    }

    void list(ref<FSAccessor> accessor)
    {
        std::function<void(const FSAccessor::Stat &, const Path &, const std::string &, bool)> doPath;

        auto showFile = [&](const Path & curPath, const std::string & relPath) {
            if (verbose) {
                auto st = accessor->stat(curPath);
                std::string tp =
                    st.type == FSAccessor::Type::tRegular ?
                        (st.isExecutable ? "-r-xr-xr-x" : "-r--r--r--") :
                    st.type == FSAccessor::Type::tSymlink ? "lrwxrwxrwx" :
                    "dr-xr-xr-x";
                std::cout <<
                    (format("%s %20d %s") % tp % st.fileSize % relPath);
                if (st.type == FSAccessor::Type::tSymlink)
                    std::cout << " -> " << accessor->readLink(curPath)
                    ;
                std::cout << "\n";
                if (recursive && st.type == FSAccessor::Type::tDirectory)
                    doPath(st, curPath, relPath, false);
            } else {
                std::cout << relPath << "\n";
                if (recursive) {
                    auto st = accessor->stat(curPath);
                    if (st.type == FSAccessor::Type::tDirectory)
                        doPath(st, curPath, relPath, false);
                }
            }
        };

        doPath = [&](const FSAccessor::Stat & st , const Path & curPath,
            const std::string & relPath, bool showDirectory)
        {
            if (st.type == FSAccessor::Type::tDirectory && !showDirectory) {
                auto names = accessor->readDirectory(curPath);
                for (auto & name : names)
                    showFile(curPath + "/" + name, relPath + "/" + name);
            } else
                showFile(curPath, relPath);
        };

        if (path == "/") {
            path = "";
        }

        auto st = accessor->stat(path);
        if (st.type == FSAccessor::Type::tMissing)
            throw Error(format("path ‘%1%’ does not exist") % path);
        doPath(st, path,
            st.type == FSAccessor::Type::tDirectory ? "." : baseNameOf(path),
            showDirectory);
    }
};

struct CmdLsStore : StoreCommand, MixLs
{
    CmdLsStore()
    {
        expectArg("path", &path);
    }

    std::string name() override
    {
        return "ls-store";
    }

    std::string description() override
    {
        return "show information about a store path";
    }

    void run(ref<Store> store) override
    {
        list(store->getFSAccessor());
    }
};

struct CmdLsNar : Command, MixLs
{
    Path narPath;

    CmdLsNar()
    {
        expectArg("nar", &narPath);
        expectArg("path", &path);
    }

    std::string name() override
    {
        return "ls-nar";
    }

    std::string description() override
    {
        return "show information about the contents of a NAR file";
    }

    void run() override
    {
        list(makeNarAccessor(make_ref<std::string>(readFile(narPath))));
    }
};

static RegisterCommand r1(make_ref<CmdLsStore>());
static RegisterCommand r2(make_ref<CmdLsNar>());
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2003-2009, John Wiegley.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * - Neither the name of New Artisans LLC nor the names of its
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "option.h"

namespace ledger {

namespace {
  typedef std::pair<expr_t::ptr_op_t, bool> op_bool_tuple;

  op_bool_tuple find_option(scope_t& scope, const string& name)
  {
    char buf[128];
    std::strcpy(buf, "opt_");
    char * p = &buf[4];
    foreach (char ch, name) {
      if (ch == '-')
	*p++ = '_';
      else
	*p++ = ch;
    }
    *p++ = '_';
    *p = '\0';

    if (expr_t::ptr_op_t op = scope.lookup(buf))
      return op_bool_tuple(op, true);

    *--p = '\0';

    return op_bool_tuple(scope.lookup(buf), false);
  }

  op_bool_tuple find_option(scope_t& scope, const char letter)
  {
    char buf[10];
    std::strcpy(buf, "opt_");
    buf[4] = letter;
    buf[5] = '_';
    buf[6] = '\0';

    if (expr_t::ptr_op_t op = scope.lookup(buf))
      return op_bool_tuple(op, true);

    buf[5] = '\0';

    return op_bool_tuple(scope.lookup(buf), false);
  }

  void process_option(const function_t& opt, scope_t& scope,
		      const char * arg, const string& name)
  {
    try {
      call_scope_t args(scope);
      if (arg)
	args.push_back(string_value(arg));

      opt(args);
    }
    catch (const std::exception& err) {
      if (name[0] == '-')
	add_error_context("While parsing option '" << name << "':");

      else
	add_error_context("While parsing environent variable '"
			  << name << "':");
      throw;
    }
  }
}

void process_option(const string& name, scope_t& scope,
		    const char * arg, const string& varname)
{
  op_bool_tuple opt(find_option(scope, name));
  if (opt.first)
    process_option(opt.first->as_function(), scope, arg, varname);
}

void process_environment(const char ** envp, const string& tag,
			 scope_t& scope)
{
  const char * tag_p   = tag.c_str();
  std::size_t  tag_len = tag.length();

  for (const char ** p = envp; *p; p++) {
    if (! tag_p || std::strncmp(*p, tag_p, tag_len) == 0) {
      char   buf[128];
      char * r = buf;
      const char * q;
      for (q = *p + tag_len;
	   *q && *q != '=' && r - buf < 128;
	   q++)
	if (*q == '_')
	  *r++ = '-';
	else
	  *r++ = std::tolower(*q);
      *r = '\0';

      if (*q == '=') {
	try {
	  string value = string(*p, q - *p);
	  if (! value.empty())
	    process_option(string(buf), scope, q + 1, value);
	}
	catch (const std::exception& err) {
	  add_error_context("While parsing environment variable option '"
			    << *p << "':");
	  throw;
	}
      }
    }
  }
}

namespace {
  struct op_bool_char_tuple {
    expr_t::ptr_op_t op;
    bool truth;
    char ch;

    op_bool_char_tuple(expr_t::ptr_op_t _op, bool _truth, char _ch)
      : op(_op), truth(_truth), ch(_ch) {}
  };
}

strings_list process_arguments(strings_list args, scope_t& scope)
{
  bool anywhere = true;

  strings_list remaining;

  for (strings_list::iterator i = args.begin();
       i != args.end();
       i++) {
    DEBUG("option.args", "Examining argument '" << *i << "'");

    if (! anywhere || (*i)[0] != '-') {
      DEBUG("option.args", "  adding to list of real args");
      remaining.push_back(*i);
      continue;
    }

    // --long-option or -s
    if ((*i)[1] == '-') {
      if ((*i)[2] == '\0') {
	DEBUG("option.args", "  it's a --, ending options processing");
	anywhere = false;
	continue;
      }

      DEBUG("option.args", "  it's an option string");

      string       opt_name;
      const char * name  = (*i).c_str() + 2;
      const char * value = NULL;

      if (const char * p = std::strchr(name, '=')) {
	opt_name = string(name, p - name);
	value = ++p;
	DEBUG("option.args", "  read option value from option: " << value);
      } else {
	opt_name = name;
      }

      op_bool_tuple opt(find_option(scope, opt_name));
      if (! opt.first)
	throw_(option_error, "illegal option --" << name);

      if (opt.second && ! value && ++i != args.end() && value == NULL) {
	value = (*i).c_str();
	DEBUG("option.args", "  read option value from arg: " << value);
	if (value == NULL)
	  throw_(option_error, "missing option argument for --" << name);
      }
      process_option(opt.first->as_function(), scope, value,
		     string("--") + name);
    }
    else if ((*i)[1] == '\0') {
      throw_(option_error, "illegal option -");
    }
    else {
      DEBUG("option.args", "  single-char option");

      std::list<op_bool_char_tuple> option_queue;

      int x = 1;
      for (char c = (*i)[x]; c != '\0'; x++, c = (*i)[x]) {
	op_bool_tuple opt(find_option(scope, c));
	if (! opt.first)
	  throw_(option_error, "illegal option -" << c);

	option_queue.push_back(op_bool_char_tuple(opt.first, opt.second, c));
      }

      foreach (op_bool_char_tuple& o, option_queue) {
	const char * value = NULL;
	if (o.truth && ++i != args.end()) {
	  value = (*i).c_str();
	  DEBUG("option.args", "  read option value from arg: " << value);
	  if (value == NULL)
	    throw_(option_error,
		   "missing option argument for -" << o.ch);
	}
	process_option(o.op->as_function(), scope, value, string("-") + o.ch);
      }
    }
  }

  return remaining;
}

} // namespace ledger
<commit_msg>Fixed the spelling of some option exceptions<commit_after>/*
 * Copyright (c) 2003-2009, John Wiegley.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * - Neither the name of New Artisans LLC nor the names of its
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "option.h"

namespace ledger {

namespace {
  typedef std::pair<expr_t::ptr_op_t, bool> op_bool_tuple;

  op_bool_tuple find_option(scope_t& scope, const string& name)
  {
    char buf[128];
    std::strcpy(buf, "opt_");
    char * p = &buf[4];
    foreach (char ch, name) {
      if (ch == '-')
	*p++ = '_';
      else
	*p++ = ch;
    }
    *p++ = '_';
    *p = '\0';

    if (expr_t::ptr_op_t op = scope.lookup(buf))
      return op_bool_tuple(op, true);

    *--p = '\0';

    return op_bool_tuple(scope.lookup(buf), false);
  }

  op_bool_tuple find_option(scope_t& scope, const char letter)
  {
    char buf[10];
    std::strcpy(buf, "opt_");
    buf[4] = letter;
    buf[5] = '_';
    buf[6] = '\0';

    if (expr_t::ptr_op_t op = scope.lookup(buf))
      return op_bool_tuple(op, true);

    buf[5] = '\0';

    return op_bool_tuple(scope.lookup(buf), false);
  }

  void process_option(const function_t& opt, scope_t& scope,
		      const char * arg, const string& name)
  {
    try {
      call_scope_t args(scope);
      if (arg)
	args.push_back(string_value(arg));

      opt(args);
    }
    catch (const std::exception& err) {
      if (name[0] == '-')
	add_error_context("While parsing option '" << name << "':");

      else
	add_error_context("While parsing environent variable '"
			  << name << "':");
      throw;
    }
  }
}

void process_option(const string& name, scope_t& scope,
		    const char * arg, const string& varname)
{
  op_bool_tuple opt(find_option(scope, name));
  if (opt.first)
    process_option(opt.first->as_function(), scope, arg, varname);
}

void process_environment(const char ** envp, const string& tag,
			 scope_t& scope)
{
  const char * tag_p   = tag.c_str();
  std::size_t  tag_len = tag.length();

  for (const char ** p = envp; *p; p++) {
    if (! tag_p || std::strncmp(*p, tag_p, tag_len) == 0) {
      char   buf[128];
      char * r = buf;
      const char * q;
      for (q = *p + tag_len;
	   *q && *q != '=' && r - buf < 128;
	   q++)
	if (*q == '_')
	  *r++ = '-';
	else
	  *r++ = std::tolower(*q);
      *r = '\0';

      if (*q == '=') {
	try {
	  string value = string(*p, q - *p);
	  if (! value.empty())
	    process_option(string(buf), scope, q + 1, value);
	}
	catch (const std::exception& err) {
	  add_error_context("While parsing environment variable option '"
			    << *p << "':");
	  throw;
	}
      }
    }
  }
}

namespace {
  struct op_bool_char_tuple {
    expr_t::ptr_op_t op;
    bool truth;
    char ch;

    op_bool_char_tuple(expr_t::ptr_op_t _op, bool _truth, char _ch)
      : op(_op), truth(_truth), ch(_ch) {}
  };
}

strings_list process_arguments(strings_list args, scope_t& scope)
{
  bool anywhere = true;

  strings_list remaining;

  for (strings_list::iterator i = args.begin();
       i != args.end();
       i++) {
    DEBUG("option.args", "Examining argument '" << *i << "'");

    if (! anywhere || (*i)[0] != '-') {
      DEBUG("option.args", "  adding to list of real args");
      remaining.push_back(*i);
      continue;
    }

    // --long-option or -s
    if ((*i)[1] == '-') {
      if ((*i)[2] == '\0') {
	DEBUG("option.args", "  it's a --, ending options processing");
	anywhere = false;
	continue;
      }

      DEBUG("option.args", "  it's an option string");

      string       opt_name;
      const char * name  = (*i).c_str() + 2;
      const char * value = NULL;

      if (const char * p = std::strchr(name, '=')) {
	opt_name = string(name, p - name);
	value = ++p;
	DEBUG("option.args", "  read option value from option: " << value);
      } else {
	opt_name = name;
      }

      op_bool_tuple opt(find_option(scope, opt_name));
      if (! opt.first)
	throw_(option_error, "Illegal option --" << name);

      if (opt.second && ! value && ++i != args.end() && value == NULL) {
	value = (*i).c_str();
	DEBUG("option.args", "  read option value from arg: " << value);
	if (value == NULL)
	  throw_(option_error, "Missing option argument for --" << name);
      }
      process_option(opt.first->as_function(), scope, value,
		     string("--") + name);
    }
    else if ((*i)[1] == '\0') {
      throw_(option_error, "illegal option -");
    }
    else {
      DEBUG("option.args", "  single-char option");

      std::list<op_bool_char_tuple> option_queue;

      int x = 1;
      for (char c = (*i)[x]; c != '\0'; x++, c = (*i)[x]) {
	op_bool_tuple opt(find_option(scope, c));
	if (! opt.first)
	  throw_(option_error, "Illegal option -" << c);

	option_queue.push_back(op_bool_char_tuple(opt.first, opt.second, c));
      }

      foreach (op_bool_char_tuple& o, option_queue) {
	const char * value = NULL;
	if (o.truth && ++i != args.end()) {
	  value = (*i).c_str();
	  DEBUG("option.args", "  read option value from arg: " << value);
	  if (value == NULL)
	    throw_(option_error,
		   "Missing option argument for -" << o.ch);
	}
	process_option(o.op->as_function(), scope, value, string("-") + o.ch);
      }
    }
  }

  return remaining;
}

} // namespace ledger
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: XMLIndexBibliographyEntryContext.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 15:56:31 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"

#ifndef _XMLOFF_XMLINDEXBIBLIOGRAPHYENTRYCONTEXT_HXX_
#include "XMLIndexBibliographyEntryContext.hxx"
#endif

#ifndef _XMLOFF_XMLINDEXTEMPLATECONTEXT_HXX_
#include "XMLIndexTemplateContext.hxx"
#endif

#ifndef _XMLOFF_XMLICTXT_HXX
#include <xmloff/xmlictxt.hxx>
#endif

#ifndef _XMLOFF_XMLIMP_HXX
#include <xmloff/xmlimp.hxx>
#endif

#ifndef _XMLOFF_TEXTIMP_HXX_
#include <xmloff/txtimp.hxx>
#endif

#ifndef _XMLOFF_NMSPMAP_HXX
#include <xmloff/nmspmap.hxx>
#endif

#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif

#ifndef _XMLOFF_XMLTOKEN_HXX
#include <xmloff/xmltoken.hxx>
#endif

#ifndef _XMLOFF_XMLUCONV_HXX
#include <xmloff/xmluconv.hxx>
#endif

#ifndef _COM_SUN_STAR_TEXT_BIBLIOGRAPHYDATAFIELD_HPP_
#include <com/sun/star/text/BibliographyDataField.hpp>
#endif

using namespace ::com::sun::star::text;
using namespace ::xmloff::token;

using ::rtl::OUString;
using ::com::sun::star::beans::PropertyValue;
using ::com::sun::star::beans::PropertyValues;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Any;
using ::com::sun::star::xml::sax::XAttributeList;

const sal_Char sAPI_TokenType[] = "TokenType";
const sal_Char sAPI_CharacterStyleName[] = "CharacterStyleName";

TYPEINIT1( XMLIndexBibliographyEntryContext, XMLIndexSimpleEntryContext);

XMLIndexBibliographyEntryContext::XMLIndexBibliographyEntryContext(
    SvXMLImport& rImport,
    XMLIndexTemplateContext& rTemplate,
    sal_uInt16 nPrfx,
    const OUString& rLocalName ) :
        XMLIndexSimpleEntryContext(rImport,
                                   rTemplate.sTokenBibliographyDataField,
                                   rTemplate,
                                   nPrfx, rLocalName),
        nBibliographyInfo(BibliographyDataField::IDENTIFIER),
        bBibliographyInfoOK(sal_False)
{
}

XMLIndexBibliographyEntryContext::~XMLIndexBibliographyEntryContext()
{
}

const SvXMLEnumMapEntry aBibliographyDataFieldMap[] =
{
    { XML_ADDRESS,              BibliographyDataField::ADDRESS },
    { XML_ANNOTE,               BibliographyDataField::ANNOTE },
    { XML_AUTHOR,               BibliographyDataField::AUTHOR },
    { XML_BIBLIOGRAPHY_TYPE,    BibliographyDataField::BIBILIOGRAPHIC_TYPE },
    // #96658#: also read old documents (bib*i*liographic...)
    { XML_BIBILIOGRAPHIC_TYPE,  BibliographyDataField::BIBILIOGRAPHIC_TYPE },
    { XML_BOOKTITLE,            BibliographyDataField::BOOKTITLE },
    { XML_CHAPTER,              BibliographyDataField::CHAPTER },
    { XML_CUSTOM1,              BibliographyDataField::CUSTOM1 },
    { XML_CUSTOM2,              BibliographyDataField::CUSTOM2 },
    { XML_CUSTOM3,              BibliographyDataField::CUSTOM3 },
    { XML_CUSTOM4,              BibliographyDataField::CUSTOM4 },
    { XML_CUSTOM5,              BibliographyDataField::CUSTOM5 },
    { XML_EDITION,              BibliographyDataField::EDITION },
    { XML_EDITOR,               BibliographyDataField::EDITOR },
    { XML_HOWPUBLISHED,         BibliographyDataField::HOWPUBLISHED },
    { XML_IDENTIFIER,           BibliographyDataField::IDENTIFIER },
    { XML_INSTITUTION,          BibliographyDataField::INSTITUTION },
    { XML_ISBN,                 BibliographyDataField::ISBN },
    { XML_JOURNAL,              BibliographyDataField::JOURNAL },
    { XML_MONTH,                BibliographyDataField::MONTH },
    { XML_NOTE,                 BibliographyDataField::NOTE },
    { XML_NUMBER,               BibliographyDataField::NUMBER },
    { XML_ORGANIZATIONS,        BibliographyDataField::ORGANIZATIONS },
    { XML_PAGES,                BibliographyDataField::PAGES },
    { XML_PUBLISHER,            BibliographyDataField::PUBLISHER },
    { XML_REPORT_TYPE,          BibliographyDataField::REPORT_TYPE },
    { XML_SCHOOL,               BibliographyDataField::SCHOOL },
    { XML_SERIES,               BibliographyDataField::SERIES },
    { XML_TITLE,                BibliographyDataField::TITLE },
    { XML_URL,                  BibliographyDataField::URL },
    { XML_VOLUME,               BibliographyDataField::VOLUME },
    { XML_YEAR,                 BibliographyDataField::YEAR },
    { XML_TOKEN_INVALID, 0 }
};

void XMLIndexBibliographyEntryContext::StartElement(
    const Reference<XAttributeList> & xAttrList)
{
    // handle both, style name and bibliography info
    sal_Int16 nLength = xAttrList->getLength();
    for(sal_Int16 nAttr = 0; nAttr < nLength; nAttr++)
    {
        OUString sLocalName;
        sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
            GetKeyByAttrName( xAttrList->getNameByIndex(nAttr),
                              &sLocalName );
        if (XML_NAMESPACE_TEXT == nPrefix)
        {
            if ( IsXMLToken( sLocalName, XML_STYLE_NAME ) )
            {
                sCharStyleName = xAttrList->getValueByIndex(nAttr);
                bCharStyleNameOK = sal_True;
            }
            else if ( IsXMLToken( sLocalName, XML_BIBLIOGRAPHY_DATA_FIELD ) )
            {
                sal_uInt16 nTmp;
                if (SvXMLUnitConverter::convertEnum(
                    nTmp, xAttrList->getValueByIndex(nAttr),
                    aBibliographyDataFieldMap))
                {
                    nBibliographyInfo = nTmp;
                    bBibliographyInfoOK = sal_True;
                }
            }
        }
    }

    // if we have a style name, set it!
    if (bCharStyleNameOK)
    {
        nValues++;
    }

    // always bibliography; else element is not valid
    nValues++;
}

void XMLIndexBibliographyEntryContext::EndElement()
{
    // only valid, if we have bibliography info
    if (bBibliographyInfoOK)
    {
        XMLIndexSimpleEntryContext::EndElement();
    }
}

void XMLIndexBibliographyEntryContext::FillPropertyValues(
    ::com::sun::star::uno::Sequence<
        ::com::sun::star::beans::PropertyValue> & rValues)
{
    // entry name and (optionally) style name in parent class
    XMLIndexSimpleEntryContext::FillPropertyValues(rValues);

    // bibliography data field
    sal_Int32 nIndex = bCharStyleNameOK ? 2 : 1;
    rValues[nIndex].Name = rTemplateContext.sBibliographyDataField;
    Any aAny;
    aAny <<= nBibliographyInfo;
    rValues[nIndex].Value = aAny;
}
<commit_msg>INTEGRATION: CWS changefileheader (1.10.162); FILE MERGED 2008/04/01 13:05:23 thb 1.10.162.2: #i85898# Stripping all external header guards 2008/03/31 16:28:33 rt 1.10.162.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: XMLIndexBibliographyEntryContext.cxx,v $
 * $Revision: 1.11 $
 *
 * 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.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"

#include "XMLIndexBibliographyEntryContext.hxx"
#include "XMLIndexTemplateContext.hxx"
#include <xmloff/xmlictxt.hxx>
#include <xmloff/xmlimp.hxx>
#include <xmloff/txtimp.hxx>
#include <xmloff/nmspmap.hxx>
#include "xmlnmspe.hxx"
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmluconv.hxx>
#include <com/sun/star/text/BibliographyDataField.hpp>

using namespace ::com::sun::star::text;
using namespace ::xmloff::token;

using ::rtl::OUString;
using ::com::sun::star::beans::PropertyValue;
using ::com::sun::star::beans::PropertyValues;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Any;
using ::com::sun::star::xml::sax::XAttributeList;

const sal_Char sAPI_TokenType[] = "TokenType";
const sal_Char sAPI_CharacterStyleName[] = "CharacterStyleName";

TYPEINIT1( XMLIndexBibliographyEntryContext, XMLIndexSimpleEntryContext);

XMLIndexBibliographyEntryContext::XMLIndexBibliographyEntryContext(
    SvXMLImport& rImport,
    XMLIndexTemplateContext& rTemplate,
    sal_uInt16 nPrfx,
    const OUString& rLocalName ) :
        XMLIndexSimpleEntryContext(rImport,
                                   rTemplate.sTokenBibliographyDataField,
                                   rTemplate,
                                   nPrfx, rLocalName),
        nBibliographyInfo(BibliographyDataField::IDENTIFIER),
        bBibliographyInfoOK(sal_False)
{
}

XMLIndexBibliographyEntryContext::~XMLIndexBibliographyEntryContext()
{
}

const SvXMLEnumMapEntry aBibliographyDataFieldMap[] =
{
    { XML_ADDRESS,              BibliographyDataField::ADDRESS },
    { XML_ANNOTE,               BibliographyDataField::ANNOTE },
    { XML_AUTHOR,               BibliographyDataField::AUTHOR },
    { XML_BIBLIOGRAPHY_TYPE,    BibliographyDataField::BIBILIOGRAPHIC_TYPE },
    // #96658#: also read old documents (bib*i*liographic...)
    { XML_BIBILIOGRAPHIC_TYPE,  BibliographyDataField::BIBILIOGRAPHIC_TYPE },
    { XML_BOOKTITLE,            BibliographyDataField::BOOKTITLE },
    { XML_CHAPTER,              BibliographyDataField::CHAPTER },
    { XML_CUSTOM1,              BibliographyDataField::CUSTOM1 },
    { XML_CUSTOM2,              BibliographyDataField::CUSTOM2 },
    { XML_CUSTOM3,              BibliographyDataField::CUSTOM3 },
    { XML_CUSTOM4,              BibliographyDataField::CUSTOM4 },
    { XML_CUSTOM5,              BibliographyDataField::CUSTOM5 },
    { XML_EDITION,              BibliographyDataField::EDITION },
    { XML_EDITOR,               BibliographyDataField::EDITOR },
    { XML_HOWPUBLISHED,         BibliographyDataField::HOWPUBLISHED },
    { XML_IDENTIFIER,           BibliographyDataField::IDENTIFIER },
    { XML_INSTITUTION,          BibliographyDataField::INSTITUTION },
    { XML_ISBN,                 BibliographyDataField::ISBN },
    { XML_JOURNAL,              BibliographyDataField::JOURNAL },
    { XML_MONTH,                BibliographyDataField::MONTH },
    { XML_NOTE,                 BibliographyDataField::NOTE },
    { XML_NUMBER,               BibliographyDataField::NUMBER },
    { XML_ORGANIZATIONS,        BibliographyDataField::ORGANIZATIONS },
    { XML_PAGES,                BibliographyDataField::PAGES },
    { XML_PUBLISHER,            BibliographyDataField::PUBLISHER },
    { XML_REPORT_TYPE,          BibliographyDataField::REPORT_TYPE },
    { XML_SCHOOL,               BibliographyDataField::SCHOOL },
    { XML_SERIES,               BibliographyDataField::SERIES },
    { XML_TITLE,                BibliographyDataField::TITLE },
    { XML_URL,                  BibliographyDataField::URL },
    { XML_VOLUME,               BibliographyDataField::VOLUME },
    { XML_YEAR,                 BibliographyDataField::YEAR },
    { XML_TOKEN_INVALID, 0 }
};

void XMLIndexBibliographyEntryContext::StartElement(
    const Reference<XAttributeList> & xAttrList)
{
    // handle both, style name and bibliography info
    sal_Int16 nLength = xAttrList->getLength();
    for(sal_Int16 nAttr = 0; nAttr < nLength; nAttr++)
    {
        OUString sLocalName;
        sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
            GetKeyByAttrName( xAttrList->getNameByIndex(nAttr),
                              &sLocalName );
        if (XML_NAMESPACE_TEXT == nPrefix)
        {
            if ( IsXMLToken( sLocalName, XML_STYLE_NAME ) )
            {
                sCharStyleName = xAttrList->getValueByIndex(nAttr);
                bCharStyleNameOK = sal_True;
            }
            else if ( IsXMLToken( sLocalName, XML_BIBLIOGRAPHY_DATA_FIELD ) )
            {
                sal_uInt16 nTmp;
                if (SvXMLUnitConverter::convertEnum(
                    nTmp, xAttrList->getValueByIndex(nAttr),
                    aBibliographyDataFieldMap))
                {
                    nBibliographyInfo = nTmp;
                    bBibliographyInfoOK = sal_True;
                }
            }
        }
    }

    // if we have a style name, set it!
    if (bCharStyleNameOK)
    {
        nValues++;
    }

    // always bibliography; else element is not valid
    nValues++;
}

void XMLIndexBibliographyEntryContext::EndElement()
{
    // only valid, if we have bibliography info
    if (bBibliographyInfoOK)
    {
        XMLIndexSimpleEntryContext::EndElement();
    }
}

void XMLIndexBibliographyEntryContext::FillPropertyValues(
    ::com::sun::star::uno::Sequence<
        ::com::sun::star::beans::PropertyValue> & rValues)
{
    // entry name and (optionally) style name in parent class
    XMLIndexSimpleEntryContext::FillPropertyValues(rValues);

    // bibliography data field
    sal_Int32 nIndex = bCharStyleNameOK ? 2 : 1;
    rValues[nIndex].Name = rTemplateContext.sBibliographyDataField;
    Any aAny;
    aAny <<= nBibliographyInfo;
    rValues[nIndex].Value = aAny;
}
<|endoftext|>


<commit_before>#include "ten/task/rendez.hh"
#include "proc.hh"
#include <mutex>

namespace ten {

void rendez::sleep(std::unique_lock<qutex> &lk) {
    DCHECK(lk.owns_lock()) << "must own lock before calling rendez::sleep";
    task *t = this_proc()->ctask;

    {
        std::lock_guard<std::timed_mutex> ll(_m);
        DCHECK(std::find(_waiting.begin(), _waiting.end(), t) == _waiting.end())
            << "BUG: " << t << " already waiting on rendez " << this;
        DVLOG(5) << "RENDEZ[" << this << "] PUSH BACK: " << t;
        _waiting.push_back(t);
    }
    // must hold the lock until we're in the waiting list
    // otherwise another thread might modify the condition and
    // call wakeup() and waiting would be empty so we'd sleep forever
    lk.unlock();
    try {
        try
        {
            {
                task::cancellation_point cancellable;
                t->swap();
            }
            lk.lock();
        } catch (...) {
            {
                std::lock_guard<std::timed_mutex> ll(_m);
                auto i = std::find(_waiting.begin(), _waiting.end(), t);
                if (i != _waiting.end()) {
                    _waiting.erase(i);
                }
            }
            lk.lock();
            throw;
        }
        DCHECK(lk.owns_lock()) << "BUG: rendez::sleep exiting without holding lock";
    } catch (...) {
        DCHECK(lk.owns_lock()) << "BUG: rendez::sleep exiting without holding lock";
    }
}

void rendez::wakeup() {
    task *t = nullptr;
    {
        std::lock_guard<std::timed_mutex> lk(_m);
        if (!_waiting.empty()) {
            t = _waiting.front();
            _waiting.pop_front();
        }
    }

    DVLOG(5) << "RENDEZ[" << this << "] " << this_proc()->ctask << " wakeup: " << t;
    if (t) t->ready();
}

void rendez::wakeupall() {
    tasklist waiting;
    {
        std::lock_guard<std::timed_mutex> lk(_m);
        std::swap(waiting, _waiting);
    }

    for (auto t : waiting) {
        DVLOG(5) << "RENDEZ[" << this << "] " << this_proc()->ctask << " wakeupall: " << t;
        t->ready();
    }
}

#if 0
bool rendez::sleep_for(unique_lock<qutex> &lk, unsigned int ms) {
    task *t = this_proc()->ctask;
    if (find(waiting.begin(), waiting.end(), t) == waiting.end()) {
        DVLOG(5) << "RENDEZ SLEEP PUSH BACK: " << t;
        waiting.push_back(t);
    }
    lk.unlock();
    this_proc()->sched().add_timeout(t, ms);
    t->swap();
    lk.lock();
    this_proc()->sched().del_timeout(t);
    // if we're not in the waiting list then we were signaled to wakeup
    return find(waiting.begin(), waiting.end(), t) == waiting.end();
}
#endif

rendez::~rendez() {
    using ::operator<<;
    std::lock_guard<std::timed_mutex> lk(_m);
    DCHECK(_waiting.empty()) << "BUG: still waiting: " << _waiting;
}

} // namespace
<commit_msg>forgot to remove debugging code<commit_after>#include "ten/task/rendez.hh"
#include "proc.hh"
#include <mutex>

namespace ten {

void rendez::sleep(std::unique_lock<qutex> &lk) {
    DCHECK(lk.owns_lock()) << "must own lock before calling rendez::sleep";
    task *t = this_proc()->ctask;

    {
        std::lock_guard<std::timed_mutex> ll(_m);
        DCHECK(std::find(_waiting.begin(), _waiting.end(), t) == _waiting.end())
            << "BUG: " << t << " already waiting on rendez " << this;
        DVLOG(5) << "RENDEZ[" << this << "] PUSH BACK: " << t;
        _waiting.push_back(t);
    }
    // must hold the lock until we're in the waiting list
    // otherwise another thread might modify the condition and
    // call wakeup() and waiting would be empty so we'd sleep forever
    lk.unlock();
    try
    {
        {
            task::cancellation_point cancellable;
            t->swap();
        }
        lk.lock();
    } catch (...) {
        {
            std::lock_guard<std::timed_mutex> ll(_m);
            auto i = std::find(_waiting.begin(), _waiting.end(), t);
            if (i != _waiting.end()) {
                _waiting.erase(i);
            }
        }
        lk.lock();
        throw;
    }
}

void rendez::wakeup() {
    task *t = nullptr;
    {
        std::lock_guard<std::timed_mutex> lk(_m);
        if (!_waiting.empty()) {
            t = _waiting.front();
            _waiting.pop_front();
        }
    }

    DVLOG(5) << "RENDEZ[" << this << "] " << this_proc()->ctask << " wakeup: " << t;
    if (t) t->ready();
}

void rendez::wakeupall() {
    tasklist waiting;
    {
        std::lock_guard<std::timed_mutex> lk(_m);
        std::swap(waiting, _waiting);
    }

    for (auto t : waiting) {
        DVLOG(5) << "RENDEZ[" << this << "] " << this_proc()->ctask << " wakeupall: " << t;
        t->ready();
    }
}

#if 0
bool rendez::sleep_for(unique_lock<qutex> &lk, unsigned int ms) {
    task *t = this_proc()->ctask;
    if (find(waiting.begin(), waiting.end(), t) == waiting.end()) {
        DVLOG(5) << "RENDEZ SLEEP PUSH BACK: " << t;
        waiting.push_back(t);
    }
    lk.unlock();
    this_proc()->sched().add_timeout(t, ms);
    t->swap();
    lk.lock();
    this_proc()->sched().del_timeout(t);
    // if we're not in the waiting list then we were signaled to wakeup
    return find(waiting.begin(), waiting.end(), t) == waiting.end();
}
#endif

rendez::~rendez() {
    using ::operator<<;
    std::lock_guard<std::timed_mutex> lk(_m);
    DCHECK(_waiting.empty()) << "BUG: still waiting: " << _waiting;
}

} // namespace
<|endoftext|>


<commit_before>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "matchview.h"
#include "searchcontext.h"
#include <vespa/searchcore/proton/matching/matcher.h>
#include <vespa/searchlib/engine/searchrequest.h>
#include <vespa/searchlib/engine/searchreply.h>
#include <vespa/vespalib/util/stringfmt.h>

#include <vespa/log/log.h>
LOG_SETUP(".proton.server.matchview");

using proton::matching::MatchContext;
using proton::matching::SearchSession;
using search::AttributeGuard;
using search::AttributeVector;
using search::attribute::IAttributeContext;
using search::engine::SearchReply;
using search::engine::SearchRequest;
using search::queryeval::Blueprint;
using search::queryeval::FieldSpec;
using search::queryeval::FieldSpecList;
using search::queryeval::Searchable;
using searchcorespi::IndexSearchable;
using vespalib::make_string;
using vespalib::ThreadBundle;

namespace proton {

using matching::ISearchContext;
using matching::Matcher;
using matching::SessionManager;

MatchView::MatchView(Matchers::SP matchers,
                     IndexSearchable::SP indexSearchable,
                     IAttributeManager::SP attrMgr,
                     SessionManagerSP sessionMgr,
                     IDocumentMetaStoreContext::SP metaStore,
                     DocIdLimit &docIdLimit)
    : _matchers(std::move(matchers)),
      _indexSearchable(std::move(indexSearchable)),
      _attrMgr(std::move(attrMgr)),
      _sessionMgr(std::move(sessionMgr)),
      _metaStore(std::move(metaStore)),
      _docIdLimit(docIdLimit)
{ }

MatchView::~MatchView() = default;

Matcher::SP
MatchView::getMatcher(const vespalib::string & rankProfile) const
{
    Matcher::SP retval = _matchers->lookup(rankProfile);
    if ( ! retval) {
        throw std::runtime_error(make_string("Failed locating Matcher for rank profile '%s'", rankProfile.c_str()));
    }
    LOG(debug, "Rankprofile = %s has termwise_limit=%f", rankProfile.c_str(), retval->get_termwise_limit());
    return retval;
}

MatchContext::UP
MatchView::createContext() const {
    IAttributeContext::UP attrCtx = _attrMgr->createContext();
    auto searchCtx = std::make_unique<SearchContext>(_indexSearchable, _docIdLimit.get());
    return std::make_unique<MatchContext>(std::move(attrCtx), std::move(searchCtx));
}

std::unique_ptr<SearchReply>
MatchView::match(std::shared_ptr<const ISearchHandler> searchHandler, const SearchRequest &req,
                 vespalib::ThreadBundle &threadBundle) const
{
    Matcher::SP matcher = getMatcher(req.ranking);
    SearchSession::OwnershipBundle owned_objects;
    owned_objects.search_handler = std::move(searchHandler);
    owned_objects.context = createContext();
    owned_objects.readGuard = _metaStore->getReadGuard();;
    MatchContext *ctx = owned_objects.context.get();
    const search::IDocumentMetaStore & dms = owned_objects.readGuard->get();
    return matcher->match(req, threadBundle, ctx->getSearchContext(), ctx->getAttributeContext(),
                          *_sessionMgr, dms, std::move(owned_objects));
}

} // namespace proton
<commit_msg>Take read guard before creating match context.<commit_after>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "matchview.h"
#include "searchcontext.h"
#include <vespa/searchcore/proton/matching/matcher.h>
#include <vespa/searchlib/engine/searchrequest.h>
#include <vespa/searchlib/engine/searchreply.h>
#include <vespa/vespalib/util/stringfmt.h>

#include <vespa/log/log.h>
LOG_SETUP(".proton.server.matchview");

using proton::matching::MatchContext;
using proton::matching::SearchSession;
using search::AttributeGuard;
using search::AttributeVector;
using search::attribute::IAttributeContext;
using search::engine::SearchReply;
using search::engine::SearchRequest;
using search::queryeval::Blueprint;
using search::queryeval::FieldSpec;
using search::queryeval::FieldSpecList;
using search::queryeval::Searchable;
using searchcorespi::IndexSearchable;
using vespalib::make_string;
using vespalib::ThreadBundle;

namespace proton {

using matching::ISearchContext;
using matching::Matcher;
using matching::SessionManager;

MatchView::MatchView(Matchers::SP matchers,
                     IndexSearchable::SP indexSearchable,
                     IAttributeManager::SP attrMgr,
                     SessionManagerSP sessionMgr,
                     IDocumentMetaStoreContext::SP metaStore,
                     DocIdLimit &docIdLimit)
    : _matchers(std::move(matchers)),
      _indexSearchable(std::move(indexSearchable)),
      _attrMgr(std::move(attrMgr)),
      _sessionMgr(std::move(sessionMgr)),
      _metaStore(std::move(metaStore)),
      _docIdLimit(docIdLimit)
{ }

MatchView::~MatchView() = default;

Matcher::SP
MatchView::getMatcher(const vespalib::string & rankProfile) const
{
    Matcher::SP retval = _matchers->lookup(rankProfile);
    if ( ! retval) {
        throw std::runtime_error(make_string("Failed locating Matcher for rank profile '%s'", rankProfile.c_str()));
    }
    LOG(debug, "Rankprofile = %s has termwise_limit=%f", rankProfile.c_str(), retval->get_termwise_limit());
    return retval;
}

MatchContext::UP
MatchView::createContext() const {
    IAttributeContext::UP attrCtx = _attrMgr->createContext();
    auto searchCtx = std::make_unique<SearchContext>(_indexSearchable, _docIdLimit.get());
    return std::make_unique<MatchContext>(std::move(attrCtx), std::move(searchCtx));
}

std::unique_ptr<SearchReply>
MatchView::match(std::shared_ptr<const ISearchHandler> searchHandler, const SearchRequest &req,
                 vespalib::ThreadBundle &threadBundle) const
{
    Matcher::SP matcher = getMatcher(req.ranking);
    SearchSession::OwnershipBundle owned_objects;
    owned_objects.search_handler = std::move(searchHandler);
    owned_objects.readGuard = _metaStore->getReadGuard();
    owned_objects.context = createContext();
    MatchContext *ctx = owned_objects.context.get();
    const search::IDocumentMetaStore & dms = owned_objects.readGuard->get();
    return matcher->match(req, threadBundle, ctx->getSearchContext(), ctx->getAttributeContext(),
                          *_sessionMgr, dms, std::move(owned_objects));
}

} // namespace proton
<|endoftext|>