<commit_before>/*************************************************************************
 *
 *  $RCSfile: canvas.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2004-11-26 20:50:53 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _CPPCANVAS_CANVAS_HXX
#define _CPPCANVAS_CANVAS_HXX

#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif

#ifndef BOOST_SHARED_PTR_HPP_INCLUDED
#include <boost/shared_ptr.hpp>
#endif

#ifndef _CPPCANVAS_FONT_HXX
#include <cppcanvas/font.hxx>
#endif
#ifndef _CPPCANVAS_COLOR_HXX
#include <cppcanvas/color.hxx>
#endif

namespace rtl
{
    class OUString;
}

namespace basegfx
{
    class B2DHomMatrix;
    class B2DPolyPolygon;
}

namespace drafts { namespace com { namespace sun { namespace star { namespace rendering
{
    class  XCanvas;
    struct ViewState;
} } } } }

/* Definition of BitmapCanvas */

namespace cppcanvas
{
    class PolyPolygon;
    class Canvas;

    // forward declaration, since PolyPolygon also references Canvas
    typedef ::boost::shared_ptr< PolyPolygon > PolyPolygonSharedPtr;

    // forward declaration, since cloneCanvas() also references Canvas
    typedef ::boost::shared_ptr< Canvas > CanvasSharedPtr;

    /** Canvas interface
     */
    class Canvas
    {
    public:
        enum
        {
            /** Extra pixel used when canvas anti-aliases.

                Enlarge the bounding box of drawing primitives by this
                amount in both dimensions, and on both sides of the
                bounds, to account for extra pixel touched outside the
                actual primitive bounding box, when the canvas
                performs anti-aliasing.
             */
            ANTIALIASING_EXTRA_SIZE=2
        };

        virtual ~Canvas() {}

        virtual void                        setTransformation( const ::basegfx::B2DHomMatrix& rMatrix ) = 0;
        virtual ::basegfx::B2DHomMatrix     getTransformation() const = 0;

        virtual void                        setClip( const PolyPolygonSharedPtr& rClipPoly ) = 0;
        virtual PolyPolygonSharedPtr        getClip() const = 0;

        virtual FontSharedPtr               createFont( const ::rtl::OUString& rFontName, const double& rCellSize ) const = 0;

        virtual ColorSharedPtr              createColor() const = 0;

        virtual CanvasSharedPtr             clone() const = 0;

        // this should be considered private. if RTTI gets enabled
        // someday, remove that to a separate interface
        virtual ::com::sun::star::uno::Reference<
            ::drafts::com::sun::star::rendering::XCanvas >          getUNOCanvas() const = 0;
        virtual ::drafts::com::sun::star::rendering::ViewState      getViewState() const = 0;
    };

}

#endif /* _CPPCANVAS_CANVAS_HXX */
<commit_msg>INTEGRATION: CWS presfixes01 (1.4.6); FILE MERGED 2005/02/16 11:14:24 fs 1.4.6.2: #i42558# drafts.com.sun.star.drawing/rendering/geometry moved to com.sun.star.* 2005/02/15 12:27:06 thb 1.4.6.1: #i42440# After moving sprite-growing functionality from canvas to slideshow, had to slightly adapt the extra size for DX canvas<commit_after>/*************************************************************************
 *
 *  $RCSfile: canvas.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: vg $ $Date: 2005-03-10 13:21:31 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _CPPCANVAS_CANVAS_HXX
#define _CPPCANVAS_CANVAS_HXX

#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif

#ifndef BOOST_SHARED_PTR_HPP_INCLUDED
#include <boost/shared_ptr.hpp>
#endif

#ifndef _CPPCANVAS_FONT_HXX
#include <cppcanvas/font.hxx>
#endif
#ifndef _CPPCANVAS_COLOR_HXX
#include <cppcanvas/color.hxx>
#endif

namespace rtl
{
    class OUString;
}

namespace basegfx
{
    class B2DHomMatrix;
    class B2DPolyPolygon;
}

namespace com { namespace sun { namespace star { namespace rendering
{
    class  XCanvas;
    struct ViewState;
} } } }

/* Definition of BitmapCanvas */

namespace cppcanvas
{
    class PolyPolygon;
    class Canvas;

    // forward declaration, since PolyPolygon also references Canvas
    typedef ::boost::shared_ptr< PolyPolygon > PolyPolygonSharedPtr;

    // forward declaration, since cloneCanvas() also references Canvas
    typedef ::boost::shared_ptr< Canvas > CanvasSharedPtr;

    /** Canvas interface
     */
    class Canvas
    {
    public:
        enum
        {
            /** Extra pixel used when canvas anti-aliases.

                Enlarge the bounding box of drawing primitives by this
                amount in both dimensions, and on both sides of the
                bounds, to account for extra pixel touched outside the
                actual primitive bounding box, when the canvas
                performs anti-aliasing.
             */
            ANTIALIASING_EXTRA_SIZE=3
        };

        virtual ~Canvas() {}

        virtual void                        setTransformation( const ::basegfx::B2DHomMatrix& rMatrix ) = 0;
        virtual ::basegfx::B2DHomMatrix     getTransformation() const = 0;

        virtual void                        setClip( const PolyPolygonSharedPtr& rClipPoly ) = 0;
        virtual PolyPolygonSharedPtr        getClip() const = 0;

        virtual FontSharedPtr               createFont( const ::rtl::OUString& rFontName, const double& rCellSize ) const = 0;

        virtual ColorSharedPtr              createColor() const = 0;

        virtual CanvasSharedPtr             clone() const = 0;

        // this should be considered private. if RTTI gets enabled
        // someday, remove that to a separate interface
        virtual ::com::sun::star::uno::Reference<
            ::com::sun::star::rendering::XCanvas >          getUNOCanvas() const = 0;
        virtual ::com::sun::star::rendering::ViewState      getViewState() const = 0;
    };

}

#endif /* _CPPCANVAS_CANVAS_HXX */
<|endoftext|>


<commit_before>/*
 *  This file is part of Poedit (http://poedit.net)
 *
 *  Copyright (C) 2003 Christophe Hermier
 *  Copyright (C) 2013-2015 Vaclav Slavik
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a
 *  copy of this software and associated documentation files (the "Software"),
 *  to deal in the Software without restriction, including without limitation
 *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
 *  and/or sell copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 *  DEALINGS IN THE SOFTWARE.
 *
 */

#include "catalog.h"
#include "utility.h"
#include "str_helpers.h"

#include <wx/intl.h>

namespace
{

inline std::string fmt_trans(const wxString& s)
{
    wxString out = EscapeMarkup(s);
    out.Replace("\n", "\n
");
    return str::to_utf8(out);
}

template<typename T1, typename T2>
inline void TableRow(std::ostream& f, const T1& col1, const T2& col2)
{
    f << "
"
      << "" << str::to_utf8(col1) << "	"
      << "" << str::to_utf8(col2) << "	"
      << "
\n";
}

extern const char *CSS_STYLE;

} // anonymous namespace

void Catalog::ExportToHTML(std::ostream& f)
{
    f << "<!DOCTYPE html>\n"
         "\n"
         "\n"
         "  <title>" << str::to_utf8(m_header.Project) << "</title>\n"
         "  <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>\n"
         "  \n"
         "\n"
         "\n"
         "
\n";

    // Metadata section:

    f << "
\n";
    if (!m_header.Project.empty())
        TableRow(f, _("Project:"), m_header.Project);
    if (m_header.Lang.IsValid())
        TableRow(f, _("Language:"), m_header.Lang.DisplayName());
    f << "
\n";

    // Statistics:

    int all = 0;
    int fuzzy = 0;
    int untranslated = 0;
    int unfinished = 0;
    GetStatistics(&all, &fuzzy, nullptr, &untranslated, &unfinished);
    int percent = (all == 0 ) ? 0 : (100 * (all - unfinished) / all);

    f << "
\n"
      << "
\n";
    if (all > unfinished)
      f << "    <div class='percent-done' style='width: " << 100.0 * (all - unfinished) / all << "%'>
\n";
    if (fuzzy > 0)
      f << "    <div class='percent-fuzzy' style='width: " << 100.0 * fuzzy / all << "%'>
\n";
    if (untranslated > 0)
      f << "    <div class='percent-untrans' style='width: " << 100.0 * untranslated / all << "%'>
\n";
    f << "
\n"
      << "
";
    f << str::to_utf8(wxString::Format(_("Translated: %d of %d (%d %%)"), all - unfinished, all, percent));
    if (unfinished > 0)
        f << str::to_utf8(L"  •  ") << str::to_utf8(wxString::Format(_("Remaining: %d"), unfinished));
    f << "
\n"
      << "
\n";

    // Translations:

    std::string lang_src, lang_tra;
    if (m_sourceLanguage.IsValid())
        lang_src = " lang='" + m_sourceLanguage.RFC3066() + "'";
    if (m_header.Lang.IsValid())
    {
        lang_tra = " lang='" + m_header.Lang.RFC3066() + "'";
        if (m_header.Lang.IsRTL())
            lang_tra += " dir='rtl'";
    }

    auto thead_src = m_sourceLanguage.IsValid()
                     ? (wxString::Format(_(L"Source text — %s"), m_sourceLanguage.DisplayName()))
                     : _("Source text");
    auto thead_tra = wxString::Format(_(L"Translation — %s"),
                                      m_header.Lang.IsValid() ? m_header.Lang.DisplayName() : _("unknown language"));

    f << "
\n"
         "
\n"
         "
\n"
         "      " << str::to_utf8(thead_src) << "	\n"
         "      " << str::to_utf8(thead_tra) << "	\n"
         "
\n"
         "
\n"
         "
\n";

    for (auto& item: items())
    {
        bool hasComments = item->HasComment() || item->HasExtractedComments();

        std::string klass("i");
        if (!item->IsTranslated())
            klass += " untrans";
        if (item->IsFuzzy())
            klass += " fuzzy";
        if (hasComments)
            klass += " with-comments";
        f << "<tr class='" << klass << "'>\n";

        // Source string:
        f << "<td class='src' " << lang_src << ">\n";
        if (item->HasPlural())
        {
            f << "
\n"
              << "
" << fmt_trans(item->GetString()) << "
\n"
              << "
" << fmt_trans(item->GetPluralString()) << "
\n"
              << "
\n";
        }
        else
        {
            f << fmt_trans(item->GetString());
        }
        if (item->HasContext())
            f << " [" << fmt_trans(item->GetContext()) << "]";
        f << "	\n";

        // Translation:
        f << "<td class='tra' " << lang_tra << ">\n";
        if (item->HasPlural())
        {
            if (item->IsTranslated())
            {
                f << "
\n";
                for (auto t: item->GetTranslations())
                    f << "
" << fmt_trans(t) << "
\n";
                f << "
\n";
            }
        }
        else
        {
            f << fmt_trans(item->GetTranslation());
        }
        f << "	\n";

        // Notes, if present:
        if (hasComments)
        {
            f << "
\n"
              << "
\n"
              << "
";
            if (item->HasExtractedComments())
            {
                f << "
\n";
                for (auto& n: item->GetExtractedComments())
                    f << fmt_trans(n) << "
\n";
                f << "
\n";
            }
            if (item->HasComment())
            {
                f << "
\n"
                  << fmt_trans(item->GetComment())
                  << "
\n";
            }
            f << "
	\n";
        }

        f << "
\n";
    }

    f << "
\n"
         "
\n"
         "
\n"
         "\n"
         "\n";
}

namespace
{

const char *CSS_STYLE = R"(

/*
Based on Minimal CSS (minimalcss.com) under the MIT license.
*/

/* Reset */
* { margin: 0; padding: 0; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }

/* Layout */
body { background-color: #fff; color: #333;	font: 14px/20px "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; }

header { width: 100%; margin: 0 auto; position: relative; padding: 20px 0; margin-bottom: 20px; }

nav ul { margin: 0; }
nav ul li { display: inline; margin-right: 20px; font-size: 16px; line-height: 28px; color: #333; }
nav ul li a { color: #333; }

.container { position: relative; max-width: 90%; margin: 0 auto; }

footer { border-top:1px solid #ccc; font-size:11px; line-height:26px; color:#999; }
footer a { color:#999999; }
footer a:hover { color:#105CB6; }
footer ul li { display:inline; list-style:none; padding-left:20px; }

/* Typography */
a { color: #105CB6; text-decoration: none; }
a:hover, a:focus { color: #105CB6; text-decoration: underline; }
a:active { color: #105CB6; }

h1 { font-size: 24px; line-height: 20px; margin: 10px 0; }
h2 { font-size: 20px; line-height: 20px; margin: 10px 0; }
h3 { font-size: 16px; line-height: 20px; margin: 10px 0; }
h4 { font-size: 14px; line-height: 20px; margin: 10px 0; }
h5 { font-size: 12px; line-height: 20px; margin: 10px 0; }
h5 { font-size: 10px; line-height: 20px; margin: 10px 0; }
h1,h2,h3,h4,h5,h6 { color: #333; }

p { margin-bottom: 10px; }

.float-left     { float: left; }
.float-right    { float: right; }
img.float-left  { float: left; margin: 0 20px 20px 0; }
img.float-right { float: right; margin: 0 0 20px 20px; }
img.center      { margin: 0 auto; display: block; }

.text-left    { text-align: left; }
.text-center  { text-align: center; }
.text-right   { text-align: right; }
.text-justify { text-align: justify; }

/* Misc */
hr { background-color: #ccc; border: 0px; color: #ccc; height: 1px; margin: 8px 0 20px 0; }
pre, code { background:#E0ECF6; display:block; margin-bottom: 20px; padding:10px; }

blockquote { margin: 10px 10px 20px; padding: 9px; background-color: #f8f8f8; color: #666; border-left: 5px solid #ddd; font: 14px/20px Georgia, Times, serif; quotes: "\201C" "\201D"; }
blockquote p { margin: 0; }
blockquote:before { content: open-quote; font-weight: bold; }
blockquote:after  { content: close-quote; font-weight: bold; }

/* List */
ul { list-style-position:inside; }
ol { list-style-position:inside; }

/* Table */
table {
  border-collapse: collapse;
  border-spacing: 0;
}
th { font-weight: bold; }
tfoot { font-style: italic; }

/* Metadata part */

.metadata {
  margin-top: 15px;
  margin-bottom: 10px;
  font-size: 90%;
}
table.metadata td {
  padding-right: 20px;
}

.stats {
  padding-top: 5px;
  padding-bottom: 20px;
}
.graph {
  width: 100%;
}
.graph div { float: left; }
.graph div:first-child { border-radius: 3px 0 0 3px; }
.graph div:last-child { border-radius: 0 3px 3px 0; }
.percent-done    { background-color: #BFEE3F; height: 10px; }
.percent-fuzzy   { background-color: #FEEE43; height: 10px; }
.percent-untrans { background-color: #F1F5F5; height: 10px; }
.legend {
  font-size: smaller;
  color: #aaa;
  padding-top: 12px;
  text-align: center;
}

/* Translations */
table.translations {
  width: 100%;
  table-layout: fixed;
}
table.translations th, table.translations td {
  padding: 5px 10px;
  vertical-align: top;
  border-bottom: 1px solid #E1E1E1;
}
table.translations th {
  text-align: left;
}
table.translations th:first-child, table.translations td:first-child { padding-left: 0; }
table.translations th:last-child, table.translations td:last-child { padding-right: 0; }

.with-comments td {
  border-bottom: none !important;
}
tr.comments div {
  float: right;
  max-width: 75%;
  font-size: smaller;
  color: #aaa;
}
tr.comments div p:last-child { margin-bottom: 0; }

.fuzzy .tra {
  color: #a9861b;
}

.msgctxt {
  font-size: smaller;
  color: #6d8e13;
}

)";

} // anonymous namespace
<commit_msg>Don't show translation col in HTML export of POTs<commit_after>/*
 *  This file is part of Poedit (http://poedit.net)
 *
 *  Copyright (C) 2003 Christophe Hermier
 *  Copyright (C) 2013-2015 Vaclav Slavik
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a
 *  copy of this software and associated documentation files (the "Software"),
 *  to deal in the Software without restriction, including without limitation
 *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
 *  and/or sell copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 *  DEALINGS IN THE SOFTWARE.
 *
 */

#include "catalog.h"
#include "utility.h"
#include "str_helpers.h"

#include <wx/intl.h>

namespace
{

inline std::string fmt_trans(const wxString& s)
{
    wxString out = EscapeMarkup(s);
    out.Replace("\n", "\n
");
    return str::to_utf8(out);
}

template<typename T1, typename T2>
inline void TableRow(std::ostream& f, const T1& col1, const T2& col2)
{
    f << "
"
      << "" << str::to_utf8(col1) << "	"
      << "" << str::to_utf8(col2) << "	"
      << "
\n";
}

extern const char *CSS_STYLE;

} // anonymous namespace

void Catalog::ExportToHTML(std::ostream& f)
{
    const bool translated = HasCapability(Catalog::Cap::Translations);

    f << "<!DOCTYPE html>\n"
         "\n"
         "\n"
         "  <title>" << str::to_utf8(m_header.Project) << "</title>\n"
         "  <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>\n"
         "  \n"
         "\n"
         "\n"
         "
\n";

    // Metadata section:

    f << "
\n";
    if (!m_header.Project.empty())
        TableRow(f, _("Project:"), m_header.Project);
    if (translated && m_header.Lang.IsValid())
        TableRow(f, _("Language:"), m_header.Lang.DisplayName());
    f << "
\n";

    // Statistics:
    if (translated)
    {
        int all = 0;
        int fuzzy = 0;
        int untranslated = 0;
        int unfinished = 0;
        GetStatistics(&all, &fuzzy, nullptr, &untranslated, &unfinished);
        int percent = (all == 0 ) ? 0 : (100 * (all - unfinished) / all);

        f << "
\n"
          << "
\n";
        if (all > unfinished)
          f << "    <div class='percent-done' style='width: " << 100.0 * (all - unfinished) / all << "%'>
\n";
        if (fuzzy > 0)
          f << "    <div class='percent-fuzzy' style='width: " << 100.0 * fuzzy / all << "%'>
\n";
        if (untranslated > 0)
          f << "    <div class='percent-untrans' style='width: " << 100.0 * untranslated / all << "%'>
\n";
        f << "
\n"
          << "
";
        f << str::to_utf8(wxString::Format(_("Translated: %d of %d (%d %%)"), all - unfinished, all, percent));
        if (unfinished > 0)
            f << str::to_utf8(L"  •  ") << str::to_utf8(wxString::Format(_("Remaining: %d"), unfinished));
        f << "
\n"
          << "
\n";
    }
    else
    {
        int all = (int)items().size();
        f << "
\n"
          << "
\n"
          << "

\n"
          << "
\n"
          << "
"
          << str::to_utf8(wxString::Format(wxPLURAL(_("%d entry"), _("%d entries"), all), all))
          << "
\n"
          << "
\n";
    }

    // Translations:

    std::string lang_src, lang_tra;
    if (m_sourceLanguage.IsValid())
        lang_src = " lang='" + m_sourceLanguage.RFC3066() + "'";
    if (m_header.Lang.IsValid())
    {
        lang_tra = " lang='" + m_header.Lang.RFC3066() + "'";
        if (m_header.Lang.IsRTL())
            lang_tra += " dir='rtl'";
    }

    auto thead_src = m_sourceLanguage.IsValid()
                     ? (wxString::Format(_(L"Source text — %s"), m_sourceLanguage.DisplayName()))
                     : _("Source text");
    auto thead_tra = wxString::Format(_(L"Translation — %s"),
                                      m_header.Lang.IsValid() ? m_header.Lang.DisplayName() : _("unknown language"));

    f << "
\n"
         "
\n"
         "
\n"
         "      " << str::to_utf8(thead_src) << "	\n";
    if (translated)
    {
        f << "      " << str::to_utf8(thead_tra) << "	\n";
    }
    f << "
\n"
         "
\n"
         "
\n";

    for (auto& item: items())
    {
        bool hasComments = item->HasComment() || item->HasExtractedComments();

        std::string klass("i");
        if (!item->IsTranslated())
            klass += " untrans";
        if (item->IsFuzzy())
            klass += " fuzzy";
        if (hasComments)
            klass += " with-comments";
        f << "<tr class='" << klass << "'>\n";

        // Source string:
        f << "<td class='src' " << lang_src << ">\n";
        if (item->HasPlural())
        {
            f << "
\n"
              << "
" << fmt_trans(item->GetString()) << "
\n"
              << "
" << fmt_trans(item->GetPluralString()) << "
\n"
              << "
\n";
        }
        else
        {
            f << fmt_trans(item->GetString());
        }
        if (item->HasContext())
            f << " [" << fmt_trans(item->GetContext()) << "]";
        f << "	\n";

        // Translation:
        if (translated)
        {
            f << "<td class='tra' " << lang_tra << ">\n";
            if (item->HasPlural())
            {
                if (item->IsTranslated())
                {
                    f << "
\n";
                    for (auto t: item->GetTranslations())
                        f << "
" << fmt_trans(t) << "
\n";
                    f << "
\n";
                }
            }
            else
            {
                f << fmt_trans(item->GetTranslation());
            }
            f << "	\n";
        }

        // Notes, if present:
        if (hasComments)
        {
            f << "
\n"
              << "
\n"
              << "  <td colspan='" << (translated ? 2 : 1) << "'>
";
            if (item->HasExtractedComments())
            {
                f << "
\n";
                for (auto& n: item->GetExtractedComments())
                    f << fmt_trans(n) << "
\n";
                f << "
\n";
            }
            if (item->HasComment())
            {
                f << "
\n"
                  << fmt_trans(item->GetComment())
                  << "
\n";
            }
            f << "
	\n";
        }

        f << "
\n";
    }

    f << "
\n"
         "
\n"
         "
\n"
         "\n"
         "\n";
}

namespace
{

const char *CSS_STYLE = R"(

/*
Based on Minimal CSS (minimalcss.com) under the MIT license.
*/

/* Reset */
* { margin: 0; padding: 0; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }

/* Layout */
body { background-color: #fff; color: #333;	font: 14px/20px "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; }

header { width: 100%; margin: 0 auto; position: relative; padding: 20px 0; margin-bottom: 20px; }

nav ul { margin: 0; }
nav ul li { display: inline; margin-right: 20px; font-size: 16px; line-height: 28px; color: #333; }
nav ul li a { color: #333; }

.container { position: relative; max-width: 90%; margin: 0 auto; }

footer { border-top:1px solid #ccc; font-size:11px; line-height:26px; color:#999; }
footer a { color:#999999; }
footer a:hover { color:#105CB6; }
footer ul li { display:inline; list-style:none; padding-left:20px; }

/* Typography */
a { color: #105CB6; text-decoration: none; }
a:hover, a:focus { color: #105CB6; text-decoration: underline; }
a:active { color: #105CB6; }

h1 { font-size: 24px; line-height: 20px; margin: 10px 0; }
h2 { font-size: 20px; line-height: 20px; margin: 10px 0; }
h3 { font-size: 16px; line-height: 20px; margin: 10px 0; }
h4 { font-size: 14px; line-height: 20px; margin: 10px 0; }
h5 { font-size: 12px; line-height: 20px; margin: 10px 0; }
h5 { font-size: 10px; line-height: 20px; margin: 10px 0; }
h1,h2,h3,h4,h5,h6 { color: #333; }

p { margin-bottom: 10px; }

.float-left     { float: left; }
.float-right    { float: right; }
img.float-left  { float: left; margin: 0 20px 20px 0; }
img.float-right { float: right; margin: 0 0 20px 20px; }
img.center      { margin: 0 auto; display: block; }

.text-left    { text-align: left; }
.text-center  { text-align: center; }
.text-right   { text-align: right; }
.text-justify { text-align: justify; }

/* Misc */
hr { background-color: #ccc; border: 0px; color: #ccc; height: 1px; margin: 8px 0 20px 0; }
pre, code { background:#E0ECF6; display:block; margin-bottom: 20px; padding:10px; }

blockquote { margin: 10px 10px 20px; padding: 9px; background-color: #f8f8f8; color: #666; border-left: 5px solid #ddd; font: 14px/20px Georgia, Times, serif; quotes: "\201C" "\201D"; }
blockquote p { margin: 0; }
blockquote:before { content: open-quote; font-weight: bold; }
blockquote:after  { content: close-quote; font-weight: bold; }

/* List */
ul { list-style-position:inside; }
ol { list-style-position:inside; }

/* Table */
table {
  border-collapse: collapse;
  border-spacing: 0;
}
th { font-weight: bold; }
tfoot { font-style: italic; }

/* Metadata part */

.metadata {
  margin-top: 15px;
  margin-bottom: 10px;
  font-size: 90%;
}
table.metadata td {
  padding-right: 20px;
}

.stats {
  padding-top: 5px;
  padding-bottom: 20px;
}
.graph {
  width: 100%;
}
.graph div { float: left; }
.graph div:first-child { border-radius: 3px 0 0 3px; }
.graph div:last-child { border-radius: 0 3px 3px 0; }
.percent-done    { background-color: #BFEE3F; height: 10px; }
.percent-fuzzy   { background-color: #FEEE43; height: 10px; }
.percent-untrans { background-color: #F1F5F5; height: 10px; }
.legend {
  font-size: smaller;
  color: #aaa;
  padding-top: 12px;
  text-align: center;
}

/* Translations */
table.translations {
  width: 100%;
  table-layout: fixed;
}
table.translations th, table.translations td {
  padding: 5px 10px;
  vertical-align: top;
  border-bottom: 1px solid #E1E1E1;
}
table.translations th {
  text-align: left;
}
table.translations th:first-child, table.translations td:first-child { padding-left: 0; }
table.translations th:last-child, table.translations td:last-child { padding-right: 0; }

.with-comments td {
  border-bottom: none !important;
}
tr.comments div {
  float: right;
  max-width: 75%;
  font-size: smaller;
  color: #aaa;
}
tr.comments div p:last-child { margin-bottom: 0; }

.fuzzy .tra {
  color: #a9861b;
}

.msgctxt {
  font-size: smaller;
  color: #6d8e13;
}

)";

} // anonymous namespace
<|endoftext|>


<commit_before>#include <iomanip>
#include <sstream>
#include <zlib.h>

#include "fingerprint.h"

#include "enroll.h"
#include "verify.h"
#include "identify.h"

#define container_of(ptr, type, member) ({			\
	const typeof( ((type *)0)->member ) *__mptr = (ptr);	\
	(type *)( (char *)__mptr - offsetof(type,member) );})

using namespace v8;
using namespace std;
using v8::FunctionTemplate;

typedef struct __POLL_DATA__ {
    uv_thread_t thread;
    bool exit;
} POLL_DATA;

Nan::Persistent<Object> module_handle;

int initalized = -1;
static POLL_DATA *polldata = NULL;

unsigned int fromFPDev(struct fp_dev *dev)
{
    union {
        struct fp_dev *dev;
        unsigned int value;
    } fpDevice;

    fpDevice.dev = dev;
    return fpDevice.value;
}

struct fp_dev* toFPDev(unsigned int value)
{
    union {
        struct fp_dev *dev;
        unsigned int value;
    } fpDevice;

    fpDevice.value = value;
    return fpDevice.dev;
}

#define UNCOMPRESSED_SIZE 12050
unsigned char* fromString(std::string hex, unsigned long *size)
{
	unsigned char *buffer = NULL;
	unsigned char *uncompressed = NULL;
	unsigned long length;
	unsigned long i = 0;
	int tmp;

	if(!size)
		return NULL;

	if(hex.length() % 2 != 0 || !size)
		goto error;

	length = hex.length() / 2;
	*size = UNCOMPRESSED_SIZE;
	buffer = (unsigned char*)malloc(length * sizeof(unsigned char));
	uncompressed = (unsigned char*)malloc(*size * sizeof(unsigned char));

	for(std::string::iterator it=hex.begin(); it!=hex.end(); it++) {
		std::string data;

		if(i >= length)
			goto error;

		data += *it++;
		if(it==hex.end())
			goto error;

		data += *it;

		std::stringstream converter(data);
		converter >> std::hex >> tmp;
		buffer[i++] = (unsigned char)tmp;
	}

	if(uncompress(uncompressed, size, buffer, length) == Z_OK) {
		free(buffer);
		return uncompressed;
	}

error:
	if(buffer != NULL)
		free(buffer);

	if(uncompressed != NULL)
		free(uncompressed);

	*size = 0;
	return NULL;
}

std::string toString(unsigned char* buffer, unsigned long size)
{
    std::stringstream converter;
	unsigned long compressedLength = 0;

	compressedLength = compressBound(size);
	unsigned char *compressed = (unsigned char*)malloc(compressedLength);

	if(compressed && compress(compressed, &compressedLength, buffer, size) == Z_OK) {
		converter << std::setfill('0');
		for(unsigned long l = 0; l < compressedLength; l++) {
			converter << std::hex << std::setw(2) << static_cast<int>(compressed[l]);
		}

		free(compressed);
		return converter.str();
	}
	return "";
}

NAN_METHOD(setDebug)
{
    int debug;

    if(info.Length() == 1) {
        debug = info[0]->ToInteger()->Value();

        if(initalized != 0)
            return;

        if(debug > 0)
            fp_set_debug(debug);
    }
}

NAN_METHOD(getEnrollStages) {
    struct fp_dev *dev;

    if(info.Length() != 1)
        return;

    dev = toFPDev(info[0]->ToNumber()->Value());
    if(initalized != 0 || dev == NULL)
        return;

    info.GetReturnValue().Set(fp_dev_get_nr_enroll_stages(dev));
}

NAN_METHOD(discoverDevices)
{
    struct fp_dscv_dev **discovered_devs;
    struct fp_driver *drv;
    int devCount = 0;

    if(initalized != 0)
        return;

    discovered_devs = fp_discover_devs();
    for(int i = 0; discovered_devs[i] != NULL; i++)
        devCount++;

    v8::Local<v8::Array> arr = Nan::New<v8::Array>(devCount);
    for(int i = 0; discovered_devs[i] != NULL; i++) {
        drv = fp_dscv_dev_get_driver(discovered_devs[i]);
        Nan::Set(arr, i, Nan::New(fp_driver_get_full_name(drv)).ToLocalChecked());
    }
    fp_dscv_devs_free(discovered_devs);
    info.GetReturnValue().Set(arr);
}

NAN_METHOD(openDevice)
{
    if(info.Length() == 1) {
        struct fp_dscv_dev **discovered_devs;
        struct fp_driver *drv;
        struct fp_dev *dev = NULL;
        string drivername;

        drivername = string(*v8::String::Utf8Value(info[0]->ToString()));
        if(initalized != 0)
            return;

        discovered_devs = fp_discover_devs();
        for(int i = 0; discovered_devs[i] != NULL; i++) {
            drv = fp_dscv_dev_get_driver(discovered_devs[i]);
            if(drivername.compare(fp_driver_get_full_name(drv)) == 0) {
                dev = fp_dev_open(discovered_devs[i]);
                break;
            }
        }
        fp_dscv_devs_free(discovered_devs);
        if(dev) {
            info.GetReturnValue().Set(fromFPDev(dev));
			return;
        }
    }
    info.GetReturnValue().Set(Nan::Null());
}

NAN_METHOD(closeDevice)
{
    if(info.Length() == 1) {
        struct fp_dev *dev;
        dev = toFPDev(info[0]->ToNumber()->Value());
        if(initalized != 0)
            return;

        if(dev)
            fp_dev_close(dev);
    }
}

void poll_fp(void *d)
{
    POLL_DATA *polldata = (POLL_DATA*)d;
    struct timeval zerotimeout = {
        .tv_sec = 0,
        .tv_usec = 0,
    };

    if(!polldata)
        return;

    while(!polldata->exit) {
        fp_handle_events_timeout(&zerotimeout);
    }
    delete polldata;
    polldata = NULL;
}

NAN_METHOD(init)
{
    initalized = fp_init();

    if(initalized == 0) {
        polldata = new POLL_DATA;
        polldata->exit = false;
        uv_thread_create(&polldata->thread, poll_fp, (void*)polldata);
    }
    info.GetReturnValue().Set(initalized == 0);
}

NAN_METHOD(exit)
{
    if(polldata)
        polldata->exit = true;

    fp_exit();
    initalized = -1;
}

NAN_MODULE_INIT(module_init) {
    module_handle.Reset(Nan::New(target));

    NAN_EXPORT(target, init);
    NAN_EXPORT(target, exit);
    NAN_EXPORT(target, discoverDevices);
    NAN_EXPORT(target, openDevice);
    NAN_EXPORT(target, closeDevice);
    NAN_EXPORT(target, getEnrollStages);
    NAN_EXPORT(target, enrollStart);
    NAN_EXPORT(target, enrollStop);
	NAN_EXPORT(target, verifyStart);
	NAN_EXPORT(target, verifyStop);
	NAN_EXPORT(target, identifyStart);
	NAN_EXPORT(target, identifyStop);
    NAN_EXPORT(target, setDebug);
}

NODE_MODULE(fingerprint, module_init)
<commit_msg>have a timeout of 10 msec for the fp_handle_events_timeout call, to relax the cpu usage a bit<commit_after>#include <iomanip>
#include <sstream>
#include <zlib.h>

#include "fingerprint.h"

#include "enroll.h"
#include "verify.h"
#include "identify.h"

#define container_of(ptr, type, member) ({			\
	const typeof( ((type *)0)->member ) *__mptr = (ptr);	\
	(type *)( (char *)__mptr - offsetof(type,member) );})

using namespace v8;
using namespace std;
using v8::FunctionTemplate;

typedef struct __POLL_DATA__ {
    uv_thread_t thread;
    bool exit;
} POLL_DATA;

Nan::Persistent<Object> module_handle;

int initalized = -1;
static POLL_DATA *polldata = NULL;

unsigned int fromFPDev(struct fp_dev *dev)
{
    union {
        struct fp_dev *dev;
        unsigned int value;
    } fpDevice;

    fpDevice.dev = dev;
    return fpDevice.value;
}

struct fp_dev* toFPDev(unsigned int value)
{
    union {
        struct fp_dev *dev;
        unsigned int value;
    } fpDevice;

    fpDevice.value = value;
    return fpDevice.dev;
}

#define UNCOMPRESSED_SIZE 12050
unsigned char* fromString(std::string hex, unsigned long *size)
{
	unsigned char *buffer = NULL;
	unsigned char *uncompressed = NULL;
	unsigned long length;
	unsigned long i = 0;
	int tmp;

	if(!size)
		return NULL;

	if(hex.length() % 2 != 0 || !size)
		goto error;

	length = hex.length() / 2;
	*size = UNCOMPRESSED_SIZE;
	buffer = (unsigned char*)malloc(length * sizeof(unsigned char));
	uncompressed = (unsigned char*)malloc(*size * sizeof(unsigned char));

	for(std::string::iterator it=hex.begin(); it!=hex.end(); it++) {
		std::string data;

		if(i >= length)
			goto error;

		data += *it++;
		if(it==hex.end())
			goto error;

		data += *it;

		std::stringstream converter(data);
		converter >> std::hex >> tmp;
		buffer[i++] = (unsigned char)tmp;
	}

	if(uncompress(uncompressed, size, buffer, length) == Z_OK) {
		free(buffer);
		return uncompressed;
	}

error:
	if(buffer != NULL)
		free(buffer);

	if(uncompressed != NULL)
		free(uncompressed);

	*size = 0;
	return NULL;
}

std::string toString(unsigned char* buffer, unsigned long size)
{
    std::stringstream converter;
	unsigned long compressedLength = 0;

	compressedLength = compressBound(size);
	unsigned char *compressed = (unsigned char*)malloc(compressedLength);

	if(compressed && compress(compressed, &compressedLength, buffer, size) == Z_OK) {
		converter << std::setfill('0');
		for(unsigned long l = 0; l < compressedLength; l++) {
			converter << std::hex << std::setw(2) << static_cast<int>(compressed[l]);
		}

		free(compressed);
		return converter.str();
	}
	return "";
}

NAN_METHOD(setDebug)
{
    int debug;

    if(info.Length() == 1) {
        debug = info[0]->ToInteger()->Value();

        if(initalized != 0)
            return;

        if(debug > 0)
            fp_set_debug(debug);
    }
}

NAN_METHOD(getEnrollStages) {
    struct fp_dev *dev;

    if(info.Length() != 1)
        return;

    dev = toFPDev(info[0]->ToNumber()->Value());
    if(initalized != 0 || dev == NULL)
        return;

    info.GetReturnValue().Set(fp_dev_get_nr_enroll_stages(dev));
}

NAN_METHOD(discoverDevices)
{
    struct fp_dscv_dev **discovered_devs;
    struct fp_driver *drv;
    int devCount = 0;

    if(initalized != 0)
        return;

    discovered_devs = fp_discover_devs();
    for(int i = 0; discovered_devs[i] != NULL; i++)
        devCount++;

    v8::Local<v8::Array> arr = Nan::New<v8::Array>(devCount);
    for(int i = 0; discovered_devs[i] != NULL; i++) {
        drv = fp_dscv_dev_get_driver(discovered_devs[i]);
        Nan::Set(arr, i, Nan::New(fp_driver_get_full_name(drv)).ToLocalChecked());
    }
    fp_dscv_devs_free(discovered_devs);
    info.GetReturnValue().Set(arr);
}

NAN_METHOD(openDevice)
{
    if(info.Length() == 1) {
        struct fp_dscv_dev **discovered_devs;
        struct fp_driver *drv;
        struct fp_dev *dev = NULL;
        string drivername;

        drivername = string(*v8::String::Utf8Value(info[0]->ToString()));
        if(initalized != 0)
            return;

        discovered_devs = fp_discover_devs();
        for(int i = 0; discovered_devs[i] != NULL; i++) {
            drv = fp_dscv_dev_get_driver(discovered_devs[i]);
            if(drivername.compare(fp_driver_get_full_name(drv)) == 0) {
                dev = fp_dev_open(discovered_devs[i]);
                break;
            }
        }
        fp_dscv_devs_free(discovered_devs);
        if(dev) {
            info.GetReturnValue().Set(fromFPDev(dev));
			return;
        }
    }
    info.GetReturnValue().Set(Nan::Null());
}

NAN_METHOD(closeDevice)
{
    if(info.Length() == 1) {
        struct fp_dev *dev;
        dev = toFPDev(info[0]->ToNumber()->Value());
        if(initalized != 0)
            return;

        if(dev)
            fp_dev_close(dev);
    }
}

void poll_fp(void *d)
{
    POLL_DATA *polldata = (POLL_DATA*)d;
    struct timeval zerotimeout = {
        .tv_sec = 0,
        .tv_usec = 10000,
    };

    if(!polldata)
        return;

    while(!polldata->exit) {
        fp_handle_events_timeout(&zerotimeout);
    }
    delete polldata;
    polldata = NULL;
}

NAN_METHOD(init)
{
    initalized = fp_init();

    if(initalized == 0) {
        polldata = new POLL_DATA;
        polldata->exit = false;
        uv_thread_create(&polldata->thread, poll_fp, (void*)polldata);
    }
    info.GetReturnValue().Set(initalized == 0);
}

NAN_METHOD(exit)
{
    if(polldata)
        polldata->exit = true;

    fp_exit();
    initalized = -1;
}

NAN_MODULE_INIT(module_init) {
    module_handle.Reset(Nan::New(target));

    NAN_EXPORT(target, init);
    NAN_EXPORT(target, exit);
    NAN_EXPORT(target, discoverDevices);
    NAN_EXPORT(target, openDevice);
    NAN_EXPORT(target, closeDevice);
    NAN_EXPORT(target, getEnrollStages);
    NAN_EXPORT(target, enrollStart);
    NAN_EXPORT(target, enrollStop);
	NAN_EXPORT(target, verifyStart);
	NAN_EXPORT(target, verifyStop);
	NAN_EXPORT(target, identifyStart);
	NAN_EXPORT(target, identifyStop);
    NAN_EXPORT(target, setDebug);
}

NODE_MODULE(fingerprint, module_init)
<|endoftext|>


<commit_before>#include "dynasm-helper.h"

#include "gram_x64.h"

#include "gram_bc.h"

#include <iostream>
#include <iomanip>
#include <list>

#include <stdint.h>
#include <stdio.h>

#define DELN(x) do {\
	if (x[strlen(x)-1] == '\n') x[strlen(x)-1]='\0'; \
	if (x[strlen(x)-1] == '\r') x[strlen(x)-1]='\0'; \
} while(0)

#define fatal(xxx) do { \
	std::cerr << "\n\nG_RAM MACHINE 2.0:\n\tERROR: " << std::endl; \
	std::cerr << xxx << std::endl; \
	exit (0); \
} while(0)

size_t n; // number of instructions
size_t maxMemAccess;
uint32_t lineNo;
uint64_t* machineMem;

int gatoi(char **buf, unsigned long *a) {
	char *x;
	unsigned long t;
	t=strtoul(*buf, &x, 10);
	if (x == *buf) return (1);
	*a=t;
	*buf = x;
	return (0);
}

// instruction type, op1, op2, op3, stats
//space for bytecode
Instr *ginstructions;

int parseInstruction(Instr* instructions, char *s) {
	char *k;
	char comm[10] = "zZsStTjJ";
	int pars[4] = { 1, 1, 2, 3 }, i;

#define SKIPBLANKS \
	do {\
		while (strchr("\t ", *k)) { \
			if (!*k) {\
				fatal("unexpected EOL " << lineNo << ":" << (k-s)); \
			} else { \
					k++; \
			} \
		} \
	} while(0)

#define set_instruction(instType) do {\
	instructions[n].opcode = instType; \
	} while (0)

#define set_operand(idx,operand) do {\
	instructions[n].op[idx-1] = operand; \
	} while (0)

#define push_instruction() n++

	lineNo++;

	if (!s)
		return 0;

	k=strchr(s, ':');
	k=k?k+1:s;
	if (!k || !strlen(k))
		return 0;

	SKIPBLANKS;
	if (!*k)
		return 0;

	if (*k == 'i' || *k=='I') *k='j';
	if (!strchr(comm, *k)) {
		fatal("while parsing line " << lineNo << (k-s) << " sign " << (*k));
	}

	int curInstr = (int)((strchr(comm, *k)-comm)/2);
	set_instruction(curInstr);
	k++;
	if (!*k) {
		fatal("unexpected EOL " << lineNo << ":" << (k-s));
	}
	SKIPBLANKS;
	if (*k != '(') {
		fatal("'(' expected  " << lineNo << ":" << (k-s) << "but '" << (*k) << "' found");
	}
	k++;
	if (!*k) {
		fatal("unexpected EOL " << lineNo << ":" << (k-s));
	}

	for (i=0; i<pars[curInstr]; i++)
	{
		unsigned long operVal;
		if (gatoi(&k, &operVal)) {
			fatal("while parsing line " << lineNo << ":" << (k-s) << " sign" << (*k) << ",  bad or missing argument");
		}
		set_operand(i+1, operVal);
		maxMemAccess = std::max<size_t>((size_t)operVal, maxMemAccess);

		SKIPBLANKS;
		if (i != pars[curInstr]-1) {
			if (*k != ',') {
				fatal("',' expected  " << lineNo << ":" << (k-s) << "but '" << (*k) << "' found");

			} else {
				k++;
			}
		}
	}

	SKIPBLANKS;
	if (*k != ')') {
		fatal("')' expected  " << lineNo << ":" << (k-s) << "but '" << (*k) << "' found");
	}

	// fix unconditional jump:
	// CJ x x y  ->  J y
	if (curInstr == Op_Conditional_Jump && GETOP(1,n) == GETOP(2, n))
	{
		std::cout << "patching jump" << std::endl;
		set_instruction(Op_Jump);
		set_operand(1, 0);
		set_operand(2, 0);
		// leave jump destination untouched
		//set_operand(3, );
	}

	k++;
	std::cerr << "..";
	push_instruction();
	return 0;
}

void parseInput(char * fileName) {
	FILE* fp;
	char buf[0x400];

	if ((fp = fopen(fileName, "r")) == NULL) {
		fatal("Cannot open input file: " << fileName);
	}

	while (fgets(buf, sizeof(buf), fp) != NULL) {
		n++;
	}

	fseek(fp, 0L, SEEK_SET);

	ginstructions = new Instr[n * sizeof(Instr)]();

	std::cerr << "parsing input...";
	n=0;
	while (fgets(buf, sizeof(buf), fp) != NULL)
	{
		DELN(buf);
		parseInstruction(ginstructions, buf);
	}
	std::cerr << "  DONE\n\n";

	fclose(fp);

	// here 'n' has REAL instruction count
}

void dumpInstructions(Instr* instructions, int start /* = 0 */, int end /* = 0*/) {

#define mnem(x) ("ZSTJg"[x])

	for (size_t i = start; i < (end?end:n); ++i) {
		std::cerr << std::setw(3) << i << ": ";
		std::cerr << std::setw(3) << mnem(instructions[i].opcode) << " ";
		std::cerr << std::setw(5) << instructions[i].op[0] << " ";
		std::cerr << std::setw(5) << instructions[i].op[1] << " ";
		std::cerr << std::setw(5) << instructions[i].op[2] << "  | ";
		std::cerr << std::setw(5) << instructions[i].statsCounter << " " << instructions[i].statsIdx;
		std::cerr << std::endl;
	}
}

int verbose = 0;

#define printq(xxx) do { if(verbose) std::cerr << xxx; } while(0)

#define MAXRUN (1000*1000*10)

void executeInstructions(Instr* instructions, size_t n, uint64_t* machineMem, size_t maxMemAccess) {
	DynAsm da(actions, GLOB__MAX);

	size_t gpc=0; // program counter
	unsigned long lc=0;
	while (1)
	{
		//if (GETOP(1, gpc) > maxMemAccess)
		//	fatal("");
		//if ((GETCD(gpc) == Op_Transfer || GETCD(gpc) == Op_Conditional_Jump) && (GETOP(2, gpc) > maxMemAccess))
		//	fatal("");

		printq(std::setw(9) << lc << " ");
		switch (GETCD(gpc))
		{
		case Op_Zero:
			printq("EIP("<< gpc <<") Z("<< GETOP(1, gpc) <<")\n");
			machineMem[GETOP(1, gpc)] = 0;
			STATSCNT(gpc)++;
			STATSIDX(gpc, lc);
			gpc++; break;
		case Op_Increment:
			machineMem[GETOP(1, gpc)]++;
			printq("EIP("<< gpc <<") S("<< GETOP(1, gpc) <<") = " << machineMem[GETOP(1, gpc)]<<"\n");
			STATSCNT(gpc)++;
			STATSIDX(gpc, lc);
			gpc++; break;
		case Op_Transfer:
			machineMem[GETOP(2, gpc)]=machineMem[GETOP(1, gpc)];
			printq("EIP("<< gpc <<") T("<< GETOP(1, gpc) <<") -> (" << GETOP(2, gpc) << ") = " << machineMem[GETOP(2, gpc)]<<"\n");
			STATSCNT(gpc)++;
			STATSIDX(gpc, lc);
			gpc++; break;
		case Op_Jump:
		case Op_Conditional_Jump:
			if (GETCD(gpc) == Op_Jump) {
				printq("EIP("<< gpc <<") goto ("<<GETOP(3, gpc)<<"\n");
			} else {
				printq("EIP("<< gpc <<") (");
				printq(GETOP(1, gpc) <<")"<<machineMem[GETOP(1, gpc)]<<" == (");
				printq(GETOP(2, gpc) <<")"<<machineMem[GETOP(2, gpc)]<<" then goto ");
				printq(GETOP(3, gpc)<<"\n");
			}
			STATSCNT(gpc)++;
			STATSIDX(gpc, lc);
			if (GETCD(gpc) == Op_Jump || machineMem[GETOP(2, gpc)] == machineMem[GETOP(1, gpc)]) {
				size_t jmpEip = gpc;
				gpc = GETOP(3, gpc);

				// it's sooooo hot here...
				if (STATSCNT(gpc) == 4) {
					// if we were at 'jump destination' more times than at jump itself
					// (so hopefully there's a path in code from GPC -> JMPEIP)
					if (STATSCNT(jmpEip) <= STATSCNT(gpc)) {
						printq("let's generate hoties! " << gpc << " c("<<STATSCNT(gpc)<< ") to " << jmpEip << " c("<<STATSCNT(jmpEip)<<")\n");
						dynasmGenerator(&da, instructions, gpc, jmpEip, machineMem, maxMemAccess);

					} else {
						// ignore for now?
					}
				}
			} else {
				gpc++;
			}
			break;
		}
		if (gpc>=n)
			break;
		lc++;
		if (lc == MAXRUN)
			break;
	}
	printq("\n");

	if (lc == MAXRUN) {
		std::cerr << "program exceeded maximum number of instruction executions\n";

	} else {
		std::cerr << "value in cell number 0: " << machineMem[0] << "\n";
		std::cerr << "program exited...\n";
	}
}

int main(int argc, char *argv[])
{
	std::ios_base::sync_with_stdio(false);
	std::cout << "compiled for x64" << std::endl;

	if (argc < 2) {
		fatal("syntax: gram <input file>");
	}

	parseInput(argv[1]);
	dumpInstructions(ginstructions);

	maxMemAccess += 1;
	machineMem = new uint64_t[maxMemAccess]();

	machineMem[1] = 5;

	try {
		executeInstructions(ginstructions, n, machineMem, maxMemAccess);

	} catch(std::exception& e) {
		std::cout << "exception occurred" << std::endl;
		std::cout << e.what() << std::endl;
	}
	dumpInstructions(ginstructions);

	return 0;
}
<commit_msg>rename n -> instructionsCount<commit_after>#include "dynasm-helper.h"

#include "gram_x64.h"

#include "gram_bc.h"

#include <iostream>
#include <iomanip>
#include <list>

#include <stdint.h>
#include <stdio.h>

#define DELN(x) do {\
	if (x[strlen(x)-1] == '\n') x[strlen(x)-1]='\0'; \
	if (x[strlen(x)-1] == '\r') x[strlen(x)-1]='\0'; \
} while(0)

#define fatal(xxx) do { \
	std::cerr << "\n\nG_RAM MACHINE 2.0:\n\tERROR: " << std::endl; \
	std::cerr << xxx << std::endl; \
	exit (0); \
} while(0)

size_t instructionsCount; // number of instructions
size_t maxMemAccess;
uint32_t lineNo;
uint64_t* machineMem;

int gatoi(char **buf, unsigned long *a) {
	char *x;
	unsigned long t;
	t=strtoul(*buf, &x, 10);
	if (x == *buf) return (1);
	*a=t;
	*buf = x;
	return (0);
}

// instruction type, op1, op2, op3, stats
//space for bytecode
Instr *ginstructions;

int parseInstruction(Instr* instructions, char *s) {
	char *k;
	char comm[10] = "zZsStTjJ";
	int pars[4] = { 1, 1, 2, 3 }, i;

#define SKIPBLANKS \
	do {\
		while (strchr("\t ", *k)) { \
			if (!*k) {\
				fatal("unexpected EOL " << lineNo << ":" << (k-s)); \
			} else { \
					k++; \
			} \
		} \
	} while(0)

#define set_instruction(instType) do {\
	instructions[instructionsCount].opcode = instType; \
	} while (0)

#define set_operand(idx,operand) do {\
	instructions[instructionsCount].op[idx-1] = operand; \
	} while (0)

#define push_instruction() instructionsCount++

	lineNo++;

	if (!s)
		return 0;

	k=strchr(s, ':');
	k=k?k+1:s;
	if (!k || !strlen(k))
		return 0;

	SKIPBLANKS;
	if (!*k)
		return 0;

	if (*k == 'i' || *k=='I') *k='j';
	if (!strchr(comm, *k)) {
		fatal("while parsing line " << lineNo << (k-s) << " sign " << (*k));
	}

	int curInstr = (int)((strchr(comm, *k)-comm)/2);
	set_instruction(curInstr);
	k++;
	if (!*k) {
		fatal("unexpected EOL " << lineNo << ":" << (k-s));
	}
	SKIPBLANKS;
	if (*k != '(') {
		fatal("'(' expected  " << lineNo << ":" << (k-s) << "but '" << (*k) << "' found");
	}
	k++;
	if (!*k) {
		fatal("unexpected EOL " << lineNo << ":" << (k-s));
	}

	for (i=0; i<pars[curInstr]; i++)
	{
		unsigned long operVal;
		if (gatoi(&k, &operVal)) {
			fatal("while parsing line " << lineNo << ":" << (k-s) << " sign" << (*k) << ",  bad or missing argument");
		}
		set_operand(i+1, operVal);
		maxMemAccess = std::max<size_t>((size_t)operVal, maxMemAccess);

		SKIPBLANKS;
		if (i != pars[curInstr]-1) {
			if (*k != ',') {
				fatal("',' expected  " << lineNo << ":" << (k-s) << "but '" << (*k) << "' found");

			} else {
				k++;
			}
		}
	}

	SKIPBLANKS;
	if (*k != ')') {
		fatal("')' expected  " << lineNo << ":" << (k-s) << "but '" << (*k) << "' found");
	}

	// fix unconditional jump:
	// CJ x x y  ->  J y
	if (curInstr == Op_Conditional_Jump && GETOP(1,instructionsCount) == GETOP(2, instructionsCount))
	{
		std::cout << "patching jump" << std::endl;
		set_instruction(Op_Jump);
		set_operand(1, 0);
		set_operand(2, 0);
		// leave jump destination untouched
		//set_operand(3, );
	}

	k++;
	std::cerr << "..";
	push_instruction();
	return 0;
}

void parseInput(char * fileName) {
	FILE* fp;
	char buf[0x400];

	if ((fp = fopen(fileName, "r")) == NULL) {
		fatal("Cannot open input file: " << fileName);
	}

	while (fgets(buf, sizeof(buf), fp) != NULL) {
		instructionsCount++;
	}

	fseek(fp, 0L, SEEK_SET);

	ginstructions = new Instr[instructionsCount * sizeof(Instr)]();

	std::cerr << "parsing input...";
	instructionsCount=0;
	while (fgets(buf, sizeof(buf), fp) != NULL)
	{
		DELN(buf);
		parseInstruction(ginstructions, buf);
	}
	std::cerr << "  DONE\n\n";

	fclose(fp);

	// here 'n' has REAL instruction count
}

void dumpInstructions(Instr* instructions, int start /* = 0 */, int end /* = 0*/) {

#define mnem(x) ("ZSTJg"[x])

	for (size_t i = start; i < (end?end:instructionsCount); ++i) {
		std::cerr << std::setw(3) << i << ": ";
		std::cerr << std::setw(3) << mnem(instructions[i].opcode) << " ";
		std::cerr << std::setw(5) << instructions[i].op[0] << " ";
		std::cerr << std::setw(5) << instructions[i].op[1] << " ";
		std::cerr << std::setw(5) << instructions[i].op[2] << "  | ";
		std::cerr << std::setw(5) << instructions[i].statsCounter << " " << instructions[i].statsIdx;
		std::cerr << std::endl;
	}
}

int verbose = 0;

#define printq(xxx) do { if(verbose) std::cerr << xxx; } while(0)

#define MAXRUN (1000*1000*10)

void executeInstructions(Instr* instructions, size_t n, uint64_t* machineMem, size_t maxMemAccess) {
	DynAsm da(actions, GLOB__MAX);

	size_t gpc=0; // program counter
	unsigned long lc=0;
	while (1)
	{
		//if (GETOP(1, gpc) > maxMemAccess)
		//	fatal("");
		//if ((GETCD(gpc) == Op_Transfer || GETCD(gpc) == Op_Conditional_Jump) && (GETOP(2, gpc) > maxMemAccess))
		//	fatal("");

		printq(std::setw(9) << lc << " ");
		switch (GETCD(gpc))
		{
		case Op_Zero:
			printq("EIP("<< gpc <<") Z("<< GETOP(1, gpc) <<")\n");
			machineMem[GETOP(1, gpc)] = 0;
			STATSCNT(gpc)++;
			STATSIDX(gpc, lc);
			gpc++; break;
		case Op_Increment:
			machineMem[GETOP(1, gpc)]++;
			printq("EIP("<< gpc <<") S("<< GETOP(1, gpc) <<") = " << machineMem[GETOP(1, gpc)]<<"\n");
			STATSCNT(gpc)++;
			STATSIDX(gpc, lc);
			gpc++; break;
		case Op_Transfer:
			machineMem[GETOP(2, gpc)]=machineMem[GETOP(1, gpc)];
			printq("EIP("<< gpc <<") T("<< GETOP(1, gpc) <<") -> (" << GETOP(2, gpc) << ") = " << machineMem[GETOP(2, gpc)]<<"\n");
			STATSCNT(gpc)++;
			STATSIDX(gpc, lc);
			gpc++; break;
		case Op_Jump:
		case Op_Conditional_Jump:
			if (GETCD(gpc) == Op_Jump) {
				printq("EIP("<< gpc <<") goto ("<<GETOP(3, gpc)<<"\n");
			} else {
				printq("EIP("<< gpc <<") (");
				printq(GETOP(1, gpc) <<")"<<machineMem[GETOP(1, gpc)]<<" == (");
				printq(GETOP(2, gpc) <<")"<<machineMem[GETOP(2, gpc)]<<" then goto ");
				printq(GETOP(3, gpc)<<"\n");
			}
			STATSCNT(gpc)++;
			STATSIDX(gpc, lc);
			if (GETCD(gpc) == Op_Jump || machineMem[GETOP(2, gpc)] == machineMem[GETOP(1, gpc)]) {
				size_t jmpEip = gpc;
				gpc = GETOP(3, gpc);

				// it's sooooo hot here...
				if (STATSCNT(gpc) == 4) {
					// if we were at 'jump destination' more times than at jump itself
					// (so hopefully there's a path in code from GPC -> JMPEIP)
					if (STATSCNT(jmpEip) <= STATSCNT(gpc)) {
						printq("let's generate hoties! " << gpc << " c("<<STATSCNT(gpc)<< ") to " << jmpEip << " c("<<STATSCNT(jmpEip)<<")\n");
						dynasmGenerator(&da, instructions, gpc, jmpEip, machineMem, maxMemAccess);

					} else {
						// ignore for now?
					}
				}
			} else {
				gpc++;
			}
			break;
		}
		if (gpc>=n)
			break;
		lc++;
		if (lc == MAXRUN)
			break;
	}
	printq("\n");

	if (lc == MAXRUN) {
		std::cerr << "program exceeded maximum number of instruction executions\n";

	} else {
		std::cerr << "value in cell number 0: " << machineMem[0] << "\n";
		std::cerr << "program exited...\n";
	}
}

int main(int argc, char *argv[])
{
	std::ios_base::sync_with_stdio(false);
	std::cout << "compiled for x64" << std::endl;

	if (argc < 2) {
		fatal("syntax: gram <input file>");
	}

	parseInput(argv[1]);
	dumpInstructions(ginstructions);

	maxMemAccess += 1;
	machineMem = new uint64_t[maxMemAccess]();

	machineMem[1] = 5;

	try {
		executeInstructions(ginstructions, instructionsCount, machineMem, maxMemAccess);

	} catch(std::exception& e) {
		std::cout << "exception occurred" << std::endl;
		std::cout << e.what() << std::endl;
	}
	dumpInstructions(ginstructions);

	return 0;
}
<|endoftext|>


<commit_before>#include "dynasm-helper.h"

#include "gram_x64.h"

#include "gram_bc.h"

#include <iostream>
#include <iomanip>
#include <list>

#include <stdint.h>
#include <stdio.h>

#define DELN(x) do {\
	if (x[strlen(x)-1] == '\n') x[strlen(x)-1]='\0'; \
	if (x[strlen(x)-1] == '\r') x[strlen(x)-1]='\0'; \
} while(0)

#define fatal(xxx) do { \
	std::cerr << "\n\nG_RAM MACHINE 2.0:\n\tERROR: " << std::endl; \
	std::cerr << xxx << std::endl; \
	exit (0); \
} while(0)

size_t n; // number of instructions
size_t maxMemAccess;
uint32_t lineNo;
uint64_t* machineMem;

int gatoi(char **buf, unsigned long *a) {
	char *x;
	unsigned long t;
	t=strtoul(*buf, &x, 10);
	if (x == *buf) return (1);
	*a=t;
	*buf = x;
	return (0);
}

// instruction type, op1, op2, op3, stats
//space for bytecode
Instr *ginstructions;

int parseInstruction(Instr* instructions, char *s) {
	char *k;
	char comm[10] = "zZsStTjJ";
	int pars[4] = { 1, 1, 2, 3 }, i;

#define SKIPBLANKS \
	do {\
		while (strchr("\t ", *k)) { \
			if (!*k) {\
				fatal("unexpected EOL " << lineNo << ":" << (k-s)); \
			} else { \
					k++; \
			} \
		} \
	} while(0)

#define set_instruction(instType) do {\
	instructions[n].opcode = instType; \
	} while (0)

#define set_operand(idx,operand) do {\
	instructions[n].op[idx-1] = operand; \
	} while (0)

#define push_instruction() n++

	lineNo++;

	if (!s)
		return 0;

	k=strchr(s, ':');
	k=k?k+1:s;
	if (!k || !strlen(k))
		return 0;

	SKIPBLANKS;
	if (!*k)
		return 0;

	if (*k == 'i' || *k=='I') *k='j';
	if (!strchr(comm, *k)) {
		fatal("while parsing line " << lineNo << (k-s) << " sign " << (*k));
	}

	int curInstr = (int)((strchr(comm, *k)-comm)/2);
	set_instruction(curInstr);
	k++;
	if (!*k) {
		fatal("unexpected EOL " << lineNo << ":" << (k-s));
	}
	SKIPBLANKS;
	if (*k != '(') {
		fatal("'(' expected  " << lineNo << ":" << (k-s) << "but '" << (*k) << "' found");
	}
	k++;
	if (!*k) {
		fatal("unexpected EOL " << lineNo << ":" << (k-s));
	}

	for (i=0; i<pars[curInstr]; i++)
	{
		unsigned long operVal;
		if (gatoi(&k, &operVal)) {
			fatal("while parsing line " << lineNo << ":" << (k-s) << " sign" << (*k) << ",  bad or missing argument");
		}
		set_operand(i+1, operVal);
		maxMemAccess = std::max<size_t>((size_t)operVal, maxMemAccess);

		SKIPBLANKS;
		if (i != pars[curInstr]-1) {
			if (*k != ',') {
				fatal("',' expected  " << lineNo << ":" << (k-s) << "but '" << (*k) << "' found");

			} else {
				k++;
			}
		}
	}

	SKIPBLANKS;
	if (*k != ')') {
		fatal("')' expected  " << lineNo << ":" << (k-s) << "but '" << (*k) << "' found");
	}

	// fix unconditional jump:
	// CJ x x y  ->  J y
	if (curInstr == Op_Conditional_Jump && GETOP(1,n) == GETOP(2, n))
	{
		std::cout << "patching jump" << std::endl;
		set_instruction(Op_Jump);
		set_operand(1, GETOP(3, n));
		set_operand(2, 0);
		set_operand(3, 0);
	}

	k++;
	std::cerr << "..";
	push_instruction();
	return 0;
}

void parseInput(char * fileName) {
	FILE* fp;
	char buf[0x400];

	if ((fp = fopen(fileName, "r")) == NULL) {
		fatal("Cannot open input file: " << fileName);
	}

	while (fgets(buf, sizeof(buf), fp) != NULL) {
		n++;
	}

	fseek(fp, 0L, SEEK_SET);

	ginstructions = new Instr[n * sizeof(Instr)]();

	std::cerr << "parsing input...";
	n=0;
	while (fgets(buf, sizeof(buf), fp) != NULL)
	{
		DELN(buf);
		parseInstruction(ginstructions, buf);
	}
	std::cerr << "  DONE\n\n";

	fclose(fp);

	// here 'n' has REAL instruction count
}

void dumpInstructions(Instr* instructions, int start /* = 0 */, int end /* = 0*/) {

#define mnem(x) ("ZSTJg"[x])

	for (size_t i = start; i < (end?end:n); ++i) {
		std::cerr << std::setw(3) << i << ": ";
		std::cerr << std::setw(3) << mnem(instructions[i].opcode) << " ";
		std::cerr << std::setw(5) << instructions[i].op[0] << " ";
		std::cerr << std::setw(5) << instructions[i].op[1] << " ";
		std::cerr << std::setw(5) << instructions[i].op[2] << "  | ";
		std::cerr << std::setw(5) << instructions[i].statsCounter << " " << instructions[i].statsIdx;
		std::cerr << std::endl;
	}
}

int verbose = 0;

#define printq(xxx) do { if(verbose) std::cerr << xxx; } while(0)

#define MAXRUN (1000*1000*10)

void executeInstructions(Instr* instructions, size_t n, uint64_t* machineMem, size_t maxMemAccess) {
	DynAsm da(actions, GLOB__MAX);

	size_t gpc=0; // program counter
	unsigned long lc=0;
	while (1)
	{
		//if (GETOP(1, gpc) > maxMemAccess)
		//	fatal("");
		//if ((GETCD(gpc) == Op_Transfer || GETCD(gpc) == Op_Conditional_Jump) && (GETOP(2, gpc) > maxMemAccess))
		//	fatal("");

		printq(std::setw(9) << lc << " ");
		switch (GETCD(gpc))
		{
		case Op_Zero:
			printq("EIP("<< gpc <<") Z("<< GETOP(1, gpc) <<")\n");
			machineMem[GETOP(1, gpc)] = 0;
			STATSCNT(gpc)++;
			STATSIDX(gpc, lc);
			gpc++; break;
		case Op_Increment:
			machineMem[GETOP(1, gpc)]++;
			printq("EIP("<< gpc <<") S("<< GETOP(1, gpc) <<") = " << machineMem[GETOP(1, gpc)]<<"\n");
			STATSCNT(gpc)++;
			STATSIDX(gpc, lc);
			gpc++; break;
		case Op_Transfer:
			machineMem[GETOP(2, gpc)]=machineMem[GETOP(1, gpc)];
			printq("EIP("<< gpc <<") T("<< GETOP(1, gpc) <<") -> (" << GETOP(2, gpc) << ") = " << machineMem[GETOP(2, gpc)]<<"\n");
			STATSCNT(gpc)++;
			STATSIDX(gpc, lc);
			gpc++; break;
		case Op_Jump:
		case Op_Conditional_Jump:
			if (GETCD(gpc) == Op_Jump) {
				printq("EIP("<< gpc <<") goto ("<<GETOP(3, gpc)<<"\n");
			} else {
				printq("EIP("<< gpc <<") (");
				printq(GETOP(1, gpc) <<")"<<machineMem[GETOP(1, gpc)]<<" == (");
				printq(GETOP(2, gpc) <<")"<<machineMem[GETOP(2, gpc)]<<" then goto ");
				printq(GETOP(3, gpc)<<"\n");
			}
			STATSCNT(gpc)++;
			STATSIDX(gpc, lc);
			if (GETCD(gpc) == Op_Jump || machineMem[GETOP(2, gpc)] == machineMem[GETOP(1, gpc)]) {
				size_t jmpEip = gpc;
				if (GETCD(gpc) == Op_Jump) {
					gpc = GETOP(1, gpc);
				} else {
					gpc = GETOP(3, gpc);
				}

				// it's sooooo hot here...
				if (STATSCNT(gpc) == 4) {
					// if we were at 'jump destination' more times than at jump itself
					// (so hopefully there's a path in code from GPC -> JMPEIP)
					if (STATSCNT(jmpEip) <= STATSCNT(gpc)) {
						printq("let's generate hoties! " << gpc << " c("<<STATSCNT(gpc)<< ") to " << jmpEip << " c("<<STATSCNT(jmpEip)<<")\n");
						dynasmGenerator(&da, instructions, gpc, jmpEip, machineMem, maxMemAccess);

					} else {
						// ignore for now?
					}
				}
			} else {
				gpc++;
			}
			break;
		}
		if (gpc>=n)
			break;
		lc++;
		if (lc == MAXRUN)
			break;
	}
	printq("\n");

	if (lc == MAXRUN) {
		std::cerr << "program exceeded maximum number of instruction executions\n";

	} else {
		std::cerr << "value in cell number 0: " << machineMem[0] << "\n";
		std::cerr << "program exited...\n";
	}
}

int main(int argc, char *argv[])
{
	std::ios_base::sync_with_stdio(false);
	std::cout << "compiled for x64" << std::endl;

	if (argc < 2) {
		fatal("syntax: gram <input file>");
	}

	parseInput(argv[1]);
	dumpInstructions(ginstructions);

	maxMemAccess += 1;
	machineMem = new uint64_t[maxMemAccess]();

	machineMem[1] = 3;

	try {
		executeInstructions(ginstructions, n, machineMem, maxMemAccess);

	} catch(std::exception& e) {
		std::cout << "exception occurred" << std::endl;
		std::cout << e.what() << std::endl;
	}
	dumpInstructions(ginstructions);

	return 0;
}
<commit_msg>don't move operand for Op_Jump, this will make code simpler<commit_after>#include "dynasm-helper.h"

#include "gram_x64.h"

#include "gram_bc.h"

#include <iostream>
#include <iomanip>
#include <list>

#include <stdint.h>
#include <stdio.h>

#define DELN(x) do {\
	if (x[strlen(x)-1] == '\n') x[strlen(x)-1]='\0'; \
	if (x[strlen(x)-1] == '\r') x[strlen(x)-1]='\0'; \
} while(0)

#define fatal(xxx) do { \
	std::cerr << "\n\nG_RAM MACHINE 2.0:\n\tERROR: " << std::endl; \
	std::cerr << xxx << std::endl; \
	exit (0); \
} while(0)

size_t n; // number of instructions
size_t maxMemAccess;
uint32_t lineNo;
uint64_t* machineMem;

int gatoi(char **buf, unsigned long *a) {
	char *x;
	unsigned long t;
	t=strtoul(*buf, &x, 10);
	if (x == *buf) return (1);
	*a=t;
	*buf = x;
	return (0);
}

// instruction type, op1, op2, op3, stats
//space for bytecode
Instr *ginstructions;

int parseInstruction(Instr* instructions, char *s) {
	char *k;
	char comm[10] = "zZsStTjJ";
	int pars[4] = { 1, 1, 2, 3 }, i;

#define SKIPBLANKS \
	do {\
		while (strchr("\t ", *k)) { \
			if (!*k) {\
				fatal("unexpected EOL " << lineNo << ":" << (k-s)); \
			} else { \
					k++; \
			} \
		} \
	} while(0)

#define set_instruction(instType) do {\
	instructions[n].opcode = instType; \
	} while (0)

#define set_operand(idx,operand) do {\
	instructions[n].op[idx-1] = operand; \
	} while (0)

#define push_instruction() n++

	lineNo++;

	if (!s)
		return 0;

	k=strchr(s, ':');
	k=k?k+1:s;
	if (!k || !strlen(k))
		return 0;

	SKIPBLANKS;
	if (!*k)
		return 0;

	if (*k == 'i' || *k=='I') *k='j';
	if (!strchr(comm, *k)) {
		fatal("while parsing line " << lineNo << (k-s) << " sign " << (*k));
	}

	int curInstr = (int)((strchr(comm, *k)-comm)/2);
	set_instruction(curInstr);
	k++;
	if (!*k) {
		fatal("unexpected EOL " << lineNo << ":" << (k-s));
	}
	SKIPBLANKS;
	if (*k != '(') {
		fatal("'(' expected  " << lineNo << ":" << (k-s) << "but '" << (*k) << "' found");
	}
	k++;
	if (!*k) {
		fatal("unexpected EOL " << lineNo << ":" << (k-s));
	}

	for (i=0; i<pars[curInstr]; i++)
	{
		unsigned long operVal;
		if (gatoi(&k, &operVal)) {
			fatal("while parsing line " << lineNo << ":" << (k-s) << " sign" << (*k) << ",  bad or missing argument");
		}
		set_operand(i+1, operVal);
		maxMemAccess = std::max<size_t>((size_t)operVal, maxMemAccess);

		SKIPBLANKS;
		if (i != pars[curInstr]-1) {
			if (*k != ',') {
				fatal("',' expected  " << lineNo << ":" << (k-s) << "but '" << (*k) << "' found");

			} else {
				k++;
			}
		}
	}

	SKIPBLANKS;
	if (*k != ')') {
		fatal("')' expected  " << lineNo << ":" << (k-s) << "but '" << (*k) << "' found");
	}

	// fix unconditional jump:
	// CJ x x y  ->  J y
	if (curInstr == Op_Conditional_Jump && GETOP(1,n) == GETOP(2, n))
	{
		std::cout << "patching jump" << std::endl;
		set_instruction(Op_Jump);
		set_operand(1, 0);
		set_operand(2, 0);
		// leave jump destination untouched
		//set_operand(3, );
	}

	k++;
	std::cerr << "..";
	push_instruction();
	return 0;
}

void parseInput(char * fileName) {
	FILE* fp;
	char buf[0x400];

	if ((fp = fopen(fileName, "r")) == NULL) {
		fatal("Cannot open input file: " << fileName);
	}

	while (fgets(buf, sizeof(buf), fp) != NULL) {
		n++;
	}

	fseek(fp, 0L, SEEK_SET);

	ginstructions = new Instr[n * sizeof(Instr)]();

	std::cerr << "parsing input...";
	n=0;
	while (fgets(buf, sizeof(buf), fp) != NULL)
	{
		DELN(buf);
		parseInstruction(ginstructions, buf);
	}
	std::cerr << "  DONE\n\n";

	fclose(fp);

	// here 'n' has REAL instruction count
}

void dumpInstructions(Instr* instructions, int start /* = 0 */, int end /* = 0*/) {

#define mnem(x) ("ZSTJg"[x])

	for (size_t i = start; i < (end?end:n); ++i) {
		std::cerr << std::setw(3) << i << ": ";
		std::cerr << std::setw(3) << mnem(instructions[i].opcode) << " ";
		std::cerr << std::setw(5) << instructions[i].op[0] << " ";
		std::cerr << std::setw(5) << instructions[i].op[1] << " ";
		std::cerr << std::setw(5) << instructions[i].op[2] << "  | ";
		std::cerr << std::setw(5) << instructions[i].statsCounter << " " << instructions[i].statsIdx;
		std::cerr << std::endl;
	}
}

int verbose = 0;

#define printq(xxx) do { if(verbose) std::cerr << xxx; } while(0)

#define MAXRUN (1000*1000*10)

void executeInstructions(Instr* instructions, size_t n, uint64_t* machineMem, size_t maxMemAccess) {
	DynAsm da(actions, GLOB__MAX);

	size_t gpc=0; // program counter
	unsigned long lc=0;
	while (1)
	{
		//if (GETOP(1, gpc) > maxMemAccess)
		//	fatal("");
		//if ((GETCD(gpc) == Op_Transfer || GETCD(gpc) == Op_Conditional_Jump) && (GETOP(2, gpc) > maxMemAccess))
		//	fatal("");

		printq(std::setw(9) << lc << " ");
		switch (GETCD(gpc))
		{
		case Op_Zero:
			printq("EIP("<< gpc <<") Z("<< GETOP(1, gpc) <<")\n");
			machineMem[GETOP(1, gpc)] = 0;
			STATSCNT(gpc)++;
			STATSIDX(gpc, lc);
			gpc++; break;
		case Op_Increment:
			machineMem[GETOP(1, gpc)]++;
			printq("EIP("<< gpc <<") S("<< GETOP(1, gpc) <<") = " << machineMem[GETOP(1, gpc)]<<"\n");
			STATSCNT(gpc)++;
			STATSIDX(gpc, lc);
			gpc++; break;
		case Op_Transfer:
			machineMem[GETOP(2, gpc)]=machineMem[GETOP(1, gpc)];
			printq("EIP("<< gpc <<") T("<< GETOP(1, gpc) <<") -> (" << GETOP(2, gpc) << ") = " << machineMem[GETOP(2, gpc)]<<"\n");
			STATSCNT(gpc)++;
			STATSIDX(gpc, lc);
			gpc++; break;
		case Op_Jump:
		case Op_Conditional_Jump:
			if (GETCD(gpc) == Op_Jump) {
				printq("EIP("<< gpc <<") goto ("<<GETOP(3, gpc)<<"\n");
			} else {
				printq("EIP("<< gpc <<") (");
				printq(GETOP(1, gpc) <<")"<<machineMem[GETOP(1, gpc)]<<" == (");
				printq(GETOP(2, gpc) <<")"<<machineMem[GETOP(2, gpc)]<<" then goto ");
				printq(GETOP(3, gpc)<<"\n");
			}
			STATSCNT(gpc)++;
			STATSIDX(gpc, lc);
			if (GETCD(gpc) == Op_Jump || machineMem[GETOP(2, gpc)] == machineMem[GETOP(1, gpc)]) {
				size_t jmpEip = gpc;
				gpc = GETOP(3, gpc);

				// it's sooooo hot here...
				if (STATSCNT(gpc) == 4) {
					// if we were at 'jump destination' more times than at jump itself
					// (so hopefully there's a path in code from GPC -> JMPEIP)
					if (STATSCNT(jmpEip) <= STATSCNT(gpc)) {
						printq("let's generate hoties! " << gpc << " c("<<STATSCNT(gpc)<< ") to " << jmpEip << " c("<<STATSCNT(jmpEip)<<")\n");
						dynasmGenerator(&da, instructions, gpc, jmpEip, machineMem, maxMemAccess);

					} else {
						// ignore for now?
					}
				}
			} else {
				gpc++;
			}
			break;
		}
		if (gpc>=n)
			break;
		lc++;
		if (lc == MAXRUN)
			break;
	}
	printq("\n");

	if (lc == MAXRUN) {
		std::cerr << "program exceeded maximum number of instruction executions\n";

	} else {
		std::cerr << "value in cell number 0: " << machineMem[0] << "\n";
		std::cerr << "program exited...\n";
	}
}

int main(int argc, char *argv[])
{
	std::ios_base::sync_with_stdio(false);
	std::cout << "compiled for x64" << std::endl;

	if (argc < 2) {
		fatal("syntax: gram <input file>");
	}

	parseInput(argv[1]);
	dumpInstructions(ginstructions);

	maxMemAccess += 1;
	machineMem = new uint64_t[maxMemAccess]();

	machineMem[1] = 3;

	try {
		executeInstructions(ginstructions, n, machineMem, maxMemAccess);

	} catch(std::exception& e) {
		std::cout << "exception occurred" << std::endl;
		std::cout << e.what() << std::endl;
	}
	dumpInstructions(ginstructions);

	return 0;
}
<|endoftext|>


<commit_before><commit_msg>coverity#703955 Unchecked return value<commit_after><|endoftext|>


<commit_before>#pragma once

struct ScreenMessage {
	enum Action {Push, Pop, Clear}

	static ScreenMessage Push(int id) {
		action = Push;
		screen = id;
	}

	static ScreenMessage Pop() {
		action = Pop;
		screen = -1;
	}

	static ScreenMessage Clear() {
		action = Clear;
		screen = -1;
	}

	int screen;
	Action action;
};
<commit_msg>Fix syntax.<commit_after>#pragma once

struct ScreenMessage {
	enum Action {Push, Pop, Clear};

	static ScreenMessage Push(int id) {
		action = Push;
		screen = id;
	}

	static ScreenMessage Pop() {
		action = Pop;
		screen = -1;
	}

	static ScreenMessage Clear() {
		action = Clear;
		screen = -1;
	}

	int screen;
	Action action;
};
<|endoftext|>


<commit_before>//
//  heTextUtils.cpp
//  StartupsViz
//
//  Created by Mathur, Arpit on 7/18/13.
//
//

#include "heTextUtils.h"

string wrapString(string text, int width, ofxTrueTypeFontUC* font) {

    string typeWrapped = "";
    string tempString = "";
    vector <string> words = ofSplitString(text, " ");

    for(int i=0; i<words.size(); i++) {

        string wrd = words[i];
        cout << wrd << endl;

        tempString += wrd + " ";
        int stringwidth = font->stringWidth(tempString);
        if(stringwidth >= width) {
            tempString = "";
            typeWrapped += "\n";
        }

        typeWrapped += wrd + " ";
    }

    return typeWrapped;

}

void heDrawBitmapStringHighlight(string text, int x, int y, const ofColor& background, const ofColor& foreground) {
	vector<string> lines = ofSplitString(text, "\n");
	int maxLineLength = 0;
	for(int i = 0; i < lines.size(); i++) {
		// tabs are not rendered
		const string & line(lines[i]);
		int currentLineLength = 0;
		for(int j = 0; j < line.size(); j++) {
			if (line[j] == '\t') {
				currentLineLength += 8 - (currentLineLength % 8);
			} else {
				currentLineLength++;
			}
		}
		maxLineLength = MAX(maxLineLength, currentLineLength);
	}

	int padding = 4;
	int fontSize = 8;
	float leading = 1.7;
	int height = lines.size() * fontSize * leading - 1;

    int width = maxLineLength * fontSize;

	ofPushStyle();
	glDepthMask(false);
	ofSetColor(background);
	ofFill();
	ofPushMatrix();

//	if(currentStyle.drawBitmapMode == OF_BITMAPMODE_MODEL) {
//		ofTranslate(x,y,0);
//		ofScale(1,-1,0);
//		ofTranslate(-(padding), + padding - fontSize - 2,0);
//	} else {
		ofTranslate(x-(padding), y-(padding + fontSize + 2), 0);

//	}

	ofRect(0, 0, width + 2 * padding, height + 2 * padding);
	ofPopMatrix();
	ofSetColor(foreground);
	ofNoFill();
	ofDrawBitmapString(text, x, y);
	glDepthMask(true);
	ofPopStyle();
}<commit_msg>removed excess logging<commit_after>//
//  heTextUtils.cpp
//  StartupsViz
//
//  Created by Mathur, Arpit on 7/18/13.
//
//

#include "heTextUtils.h"

string wrapString(string text, int width, ofxTrueTypeFontUC* font) {

    string typeWrapped = "";
    string tempString = "";
    vector <string> words = ofSplitString(text, " ");

    for(int i=0; i<words.size(); i++) {

        string wrd = words[i];

        tempString += wrd + " ";
        int stringwidth = font->stringWidth(tempString);
        if(stringwidth >= width) {
            tempString = "";
            typeWrapped += "\n";
        }

        typeWrapped += wrd + " ";
    }

    return typeWrapped;

}

void heDrawBitmapStringHighlight(string text, int x, int y, const ofColor& background, const ofColor& foreground) {
	vector<string> lines = ofSplitString(text, "\n");
	int maxLineLength = 0;
	for(int i = 0; i < lines.size(); i++) {
		// tabs are not rendered
		const string & line(lines[i]);
		int currentLineLength = 0;
		for(int j = 0; j < line.size(); j++) {
			if (line[j] == '\t') {
				currentLineLength += 8 - (currentLineLength % 8);
			} else {
				currentLineLength++;
			}
		}
		maxLineLength = MAX(maxLineLength, currentLineLength);
	}

	int padding = 4;
	int fontSize = 8;
	float leading = 1.7;
	int height = lines.size() * fontSize * leading - 1;

    int width = maxLineLength * fontSize;

	ofPushStyle();
	glDepthMask(false);
	ofSetColor(background);
	ofFill();
	ofPushMatrix();

//	if(currentStyle.drawBitmapMode == OF_BITMAPMODE_MODEL) {
//		ofTranslate(x,y,0);
//		ofScale(1,-1,0);
//		ofTranslate(-(padding), + padding - fontSize - 2,0);
//	} else {
		ofTranslate(x-(padding), y-(padding + fontSize + 2), 0);

//	}

	ofRect(0, 0, width + 2 * padding, height + 2 * padding);
	ofPopMatrix();
	ofSetColor(foreground);
	ofNoFill();
	ofDrawBitmapString(text, x, y);
	glDepthMask(true);
	ofPopStyle();
}<|endoftext|>