<commit_before>/*
 * VapourSynth D2V Plugin
 *
 * Copyright (c) 2012 Derek Buitenhuis
 *
 * This file is part of d2vsource.
 *
 * d2vsource 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.1 of the License, or (at your option) any later version.
 *
 * d2vsource 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 d2vsource; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

extern "C" {
#include <stdint.h>
#include <stdlib.h>
}

#include <VapourSynth.h>
#include <VSHelper.h>

#include "d2v.hpp"
#include "d2vsource.hpp"
#include "decode.hpp"
#include "directrender.hpp"

void VS_CC d2vInit(VSMap *in, VSMap *out, void **instanceData, VSNode *node, VSCore *core, const VSAPI *vsapi)
{
    d2vData *d = (d2vData *) *instanceData;
    vsapi->setVideoInfo(&d->vi, 1, node);
}

const VSFrameRef *VS_CC d2vGetFrame(int n, int activationReason, void **instanceData, void **frameData,
                                    VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi)
{
    d2vData *d = (d2vData *) *instanceData;
    VSFrameRef *s, *f;
    string msg;
    int ret;

    /* Unreference the previously decoded frame. */
    av_frame_unref(d->frame);

    ret = decodeframe(n, d->d2v, d->dec, d->frame, msg);
    if (ret < 0) {
        vsapi->setFilterError(msg.c_str(), frameCtx);
        return NULL;
    }

    /* Grab our direct-rendered frame. */
    s = (VSFrameRef *) d->frame->opaque;

    /* If our width and height are the same, just return it. */
    if (d->vi.width == d->aligned_width && d->vi.height == d->aligned_height) {
        f = (VSFrameRef *) vsapi->cloneFrameRef(s);
        return f;
    }

    f = vsapi->newVideoFrame(d->vi.format, d->vi.width, d->vi.height, NULL, core);

    /* Copy into VS's buffers. */
    vs_bitblt(vsapi->getWritePtr(f, 0), vsapi->getStride(f, 0), vsapi->getWritePtr(s, 0), vsapi->getStride(s, 0),
              d->vi.width, d->vi.height);
    vs_bitblt(vsapi->getWritePtr(f, 1), vsapi->getStride(f, 1), vsapi->getWritePtr(s, 1), vsapi->getStride(s, 1),
              d->vi.width >> d->vi.format->subSamplingW, d->vi.height >> d->vi.format->subSamplingH);
    vs_bitblt(vsapi->getWritePtr(f, 2), vsapi->getStride(f, 2), vsapi->getWritePtr(s, 2), vsapi->getStride(s, 2),
              d->vi.width >> d->vi.format->subSamplingW, d->vi.height >> d->vi.format->subSamplingH);

    return f;
}

void VS_CC d2vFree(void *instanceData, VSCore *core, const VSAPI *vsapi)
{
    d2vData *d = (d2vData *) instanceData;
    d2vfreep(&d->d2v);
    decodefreep(&d->dec);
    av_frame_unref(d->frame);
    av_freep(&d->frame);
    free(d);
}

void VS_CC d2vCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi)
{
    d2vData *data;
    string msg;
    bool no_crop;
    int err;

    /* Allocate our private data. */
    data = (d2vData *) malloc(sizeof(*data));
    if (!data) {
        vsapi->setError(out, "Cannot allocate private data.");
        return;
    }

    data->d2v = d2vparse((char *) vsapi->propGetData(in, "input", 0, 0), msg);
    if (!data->d2v) {
        vsapi->setError(out, msg.c_str());
        free(data);
        return;
    }

    data->dec = decodeinit(data->d2v, msg);
    if (!data->dec) {
        vsapi->setError(out, msg.c_str());
        d2vfreep(&data->d2v);
        free(data);
        return;
    }

    /*
     * Make our private data available to libavcodec, and
     * set our custom get/release_buffer funcs.
     */
    data->dec->avctx->opaque         = (void *) data;
    data->dec->avctx->get_buffer2    = VSGetBuffer;

    /* Last frame is crashy right now. */
    data->vi.numFrames = data->d2v->frames.size();
    data->vi.width     = data->d2v->width;
    data->vi.height    = data->d2v->height;
    data->vi.fpsNum    = data->d2v->fps_num;
    data->vi.fpsDen    = data->d2v->fps_den;

    /* Stash the pointer to our core. */
    data->core = core;
    data->api  = (VSAPI *) vsapi;

    /*
     * Stash our aligned width and height for use with our
     * custom get_buffer, since it could require this.
     */
    data->aligned_width  = FFALIGN(data->vi.width, 16);
    data->aligned_height = FFALIGN(data->vi.height, 32);

    data->frame = avcodec_alloc_frame();
    if (!data->frame) {
        vsapi->setError(out, "Cannot allocate AVFrame.");
        d2vfreep(&data->d2v);
        decodefreep(&data->dec);
        free(data);
        return;
    }

    /*
     * Decode 1 frame to find out how the chroma is subampled.
     * The first time our custom get_buffer is called, it will
     * fill in data->vi.format.
     */
    data->format_set = false;
    err              = decodeframe(0, data->d2v, data->dec, data->frame, msg);
    if (err < 0) {
        msg.insert(0, "Failed to decode test frame: ");
        vsapi->setError(out, msg.c_str());
        d2vfreep(&data->d2v);
        decodefreep(&data->dec);
        av_frame_unref(data->frame);
        av_freep(&data->frame);
        free(data);
        return;
    }

    /* See if nocrop is enabled, and set the width/height accordingly. */
    no_crop = !!vsapi->propGetInt(in, "nocrop", 0, &err);
    if (err)
        no_crop = false;

    if (no_crop) {
        data->vi.width  = data->aligned_width;
        data->vi.height = data->aligned_height;
    }

    vsapi->createFilter(in, out, "d2vsource", d2vInit, d2vGetFrame, d2vFree, fmSerial, 0, data, core);

    int rff = !!vsapi->propGetInt(in, "rff", 0, &err);
    if (err)
        rff = 1;

    if (rff) {
        VSPlugin *d2vPlugin = vsapi->getPluginByNs("d2v", core);

        VSMap *args = vsapi->createMap();
        VSNodeRef *before = vsapi->propGetNode(out, "clip", 0, NULL);
        vsapi->propSetNode(args, "clip", before, paReplace);
        vsapi->freeNode(before);
        vsapi->propSetData(args, "d2v", vsapi->propGetData(in, "input", 0, NULL), vsapi->propGetDataSize(in, "input", 0, NULL), paReplace);

        VSMap *ret = vsapi->invoke(d2vPlugin, "ApplyRFF", args);
        vsapi->freeMap(args);

        const char *error = vsapi->getError(ret);
        if (error) {
            vsapi->setError(out, error);
            vsapi->freeMap(ret);
            d2vfreep(&data->d2v);
            decodefreep(&data->dec);
            av_frame_unref(data->frame);
            av_freep(&data->frame);
            free(data);
            return;
        }

        VSNodeRef *after = vsapi->propGetNode(ret, "clip", 0, NULL);
        vsapi->propSetNode(out, "clip", after, paReplace);
        vsapi->freeNode(after);
        vsapi->freeMap(ret);
    }
}
<commit_msg>Only declare variables at block start<commit_after>/*
 * VapourSynth D2V Plugin
 *
 * Copyright (c) 2012 Derek Buitenhuis
 *
 * This file is part of d2vsource.
 *
 * d2vsource 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.1 of the License, or (at your option) any later version.
 *
 * d2vsource 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 d2vsource; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

extern "C" {
#include <stdint.h>
#include <stdlib.h>
}

#include <VapourSynth.h>
#include <VSHelper.h>

#include "d2v.hpp"
#include "d2vsource.hpp"
#include "decode.hpp"
#include "directrender.hpp"

void VS_CC d2vInit(VSMap *in, VSMap *out, void **instanceData, VSNode *node, VSCore *core, const VSAPI *vsapi)
{
    d2vData *d = (d2vData *) *instanceData;
    vsapi->setVideoInfo(&d->vi, 1, node);
}

const VSFrameRef *VS_CC d2vGetFrame(int n, int activationReason, void **instanceData, void **frameData,
                                    VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi)
{
    d2vData *d = (d2vData *) *instanceData;
    VSFrameRef *s, *f;
    string msg;
    int ret;

    /* Unreference the previously decoded frame. */
    av_frame_unref(d->frame);

    ret = decodeframe(n, d->d2v, d->dec, d->frame, msg);
    if (ret < 0) {
        vsapi->setFilterError(msg.c_str(), frameCtx);
        return NULL;
    }

    /* Grab our direct-rendered frame. */
    s = (VSFrameRef *) d->frame->opaque;

    /* If our width and height are the same, just return it. */
    if (d->vi.width == d->aligned_width && d->vi.height == d->aligned_height) {
        f = (VSFrameRef *) vsapi->cloneFrameRef(s);
        return f;
    }

    f = vsapi->newVideoFrame(d->vi.format, d->vi.width, d->vi.height, NULL, core);

    /* Copy into VS's buffers. */
    vs_bitblt(vsapi->getWritePtr(f, 0), vsapi->getStride(f, 0), vsapi->getWritePtr(s, 0), vsapi->getStride(s, 0),
              d->vi.width, d->vi.height);
    vs_bitblt(vsapi->getWritePtr(f, 1), vsapi->getStride(f, 1), vsapi->getWritePtr(s, 1), vsapi->getStride(s, 1),
              d->vi.width >> d->vi.format->subSamplingW, d->vi.height >> d->vi.format->subSamplingH);
    vs_bitblt(vsapi->getWritePtr(f, 2), vsapi->getStride(f, 2), vsapi->getWritePtr(s, 2), vsapi->getStride(s, 2),
              d->vi.width >> d->vi.format->subSamplingW, d->vi.height >> d->vi.format->subSamplingH);

    return f;
}

void VS_CC d2vFree(void *instanceData, VSCore *core, const VSAPI *vsapi)
{
    d2vData *d = (d2vData *) instanceData;
    d2vfreep(&d->d2v);
    decodefreep(&d->dec);
    av_frame_unref(d->frame);
    av_freep(&d->frame);
    free(d);
}

void VS_CC d2vCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi)
{
    d2vData *data;
    string msg;
    bool no_crop;
    int err;

    /* Allocate our private data. */
    data = (d2vData *) malloc(sizeof(*data));
    if (!data) {
        vsapi->setError(out, "Cannot allocate private data.");
        return;
    }

    data->d2v = d2vparse((char *) vsapi->propGetData(in, "input", 0, 0), msg);
    if (!data->d2v) {
        vsapi->setError(out, msg.c_str());
        free(data);
        return;
    }

    data->dec = decodeinit(data->d2v, msg);
    if (!data->dec) {
        vsapi->setError(out, msg.c_str());
        d2vfreep(&data->d2v);
        free(data);
        return;
    }

    /*
     * Make our private data available to libavcodec, and
     * set our custom get/release_buffer funcs.
     */
    data->dec->avctx->opaque         = (void *) data;
    data->dec->avctx->get_buffer2    = VSGetBuffer;

    /* Last frame is crashy right now. */
    data->vi.numFrames = data->d2v->frames.size();
    data->vi.width     = data->d2v->width;
    data->vi.height    = data->d2v->height;
    data->vi.fpsNum    = data->d2v->fps_num;
    data->vi.fpsDen    = data->d2v->fps_den;

    /* Stash the pointer to our core. */
    data->core = core;
    data->api  = (VSAPI *) vsapi;

    /*
     * Stash our aligned width and height for use with our
     * custom get_buffer, since it could require this.
     */
    data->aligned_width  = FFALIGN(data->vi.width, 16);
    data->aligned_height = FFALIGN(data->vi.height, 32);

    data->frame = avcodec_alloc_frame();
    if (!data->frame) {
        vsapi->setError(out, "Cannot allocate AVFrame.");
        d2vfreep(&data->d2v);
        decodefreep(&data->dec);
        free(data);
        return;
    }

    /*
     * Decode 1 frame to find out how the chroma is subampled.
     * The first time our custom get_buffer is called, it will
     * fill in data->vi.format.
     */
    data->format_set = false;
    err              = decodeframe(0, data->d2v, data->dec, data->frame, msg);
    if (err < 0) {
        msg.insert(0, "Failed to decode test frame: ");
        vsapi->setError(out, msg.c_str());
        d2vfreep(&data->d2v);
        decodefreep(&data->dec);
        av_frame_unref(data->frame);
        av_freep(&data->frame);
        free(data);
        return;
    }

    /* See if nocrop is enabled, and set the width/height accordingly. */
    no_crop = !!vsapi->propGetInt(in, "nocrop", 0, &err);
    if (err)
        no_crop = false;

    if (no_crop) {
        data->vi.width  = data->aligned_width;
        data->vi.height = data->aligned_height;
    }

    vsapi->createFilter(in, out, "d2vsource", d2vInit, d2vGetFrame, d2vFree, fmSerial, 0, data, core);

    int rff = !!vsapi->propGetInt(in, "rff", 0, &err);
    if (err)
        rff = 1;

    if (rff) {
        VSPlugin *d2vPlugin = vsapi->getPluginByNs("d2v", core);
        VSNodeRef *before = vsapi->propGetNode(out, "clip", 0, NULL);
        VSNodeRef *after;
        VSMap *args = vsapi->createMap();
        VSMap *ret;
        const char *error;

        vsapi->propSetNode(args, "clip", before, paReplace);
        vsapi->freeNode(before);
        vsapi->propSetData(args, "d2v", vsapi->propGetData(in, "input", 0, NULL), vsapi->propGetDataSize(in, "input", 0, NULL), paReplace);

        ret = vsapi->invoke(d2vPlugin, "ApplyRFF", args);
        vsapi->freeMap(args);

        error = vsapi->getError(ret);
        if (error) {
            vsapi->setError(out, error);
            vsapi->freeMap(ret);
            d2vfreep(&data->d2v);
            decodefreep(&data->dec);
            av_frame_unref(data->frame);
            av_freep(&data->frame);
            free(data);
            return;
        }

        after = vsapi->propGetNode(ret, "clip", 0, NULL);

        vsapi->propSetNode(out, "clip", after, paReplace);
        vsapi->freeNode(after);
        vsapi->freeMap(ret);
    }
}
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// version: $Id$
// author:  Axel Naumann <axel@cern.ch>
//------------------------------------------------------------------------------

#include "IncrementalParser.h"
#include "ASTDumper.h"
#include "ASTNodeEraser.h"
#include "DeclCollector.h"
#include "DeclExtractor.h"
#include "DynamicLookup.h"
#include "ReturnSynthesizer.h"
#include "ValuePrinterSynthesizer.h"
#include "cling/Interpreter/CIFactory.h"
#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/InterpreterCallbacks.h"
#include "cling/Interpreter/Transaction.h"

#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclGroup.h"
#include "clang/Basic/FileManager.h"
#include "clang/CodeGen/ModuleBuilder.h"
#include "clang/Parse/Parser.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Serialization/ASTWriter.h"

#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_os_ostream.h"

#include <ctime>
#include <iostream>
#include <stdio.h>
#include <sstream>

using namespace clang;

namespace cling {
  IncrementalParser::IncrementalParser(Interpreter* interp,
                                       int argc, const char* const *argv,
                                       const char* llvmdir):
    m_Interpreter(interp), m_Consumer(0) {

    CompilerInstance* CI
      = CIFactory::createCI(llvm::MemoryBuffer::getMemBuffer("", "CLING"),
                            argc, argv, llvmdir);
    assert(CI && "CompilerInstance is (null)!");

    m_Consumer = dyn_cast<DeclCollector>(&CI->getASTConsumer());
    assert(m_Consumer && "Expected ChainedConsumer!");

    m_CI.reset(CI);

    if (CI->getFrontendOpts().ProgramAction != clang::frontend::ParseSyntaxOnly){
      m_CodeGen.reset(CreateLLVMCodeGen(CI->getDiagnostics(), "cling input",
                                        CI->getCodeGenOpts(),
                                        *m_Interpreter->getLLVMContext()
                                        ));
    }

    CreateSLocOffsetGenerator();

    // Add transformers to the IncrementalParser, which owns them
    m_TTransformers.push_back(new EvaluateTSynthesizer(&CI->getSema()));

    m_TTransformers.push_back(new DeclExtractor(&getCI()->getSema()));
    m_TTransformers.push_back(new ValuePrinterSynthesizer(&CI->getSema(), 0));
    m_TTransformers.push_back(new ReturnSynthesizer(&CI->getSema()));
    m_TTransformers.push_back(new ASTDumper());

    m_Parser.reset(new Parser(CI->getPreprocessor(), CI->getSema(),
                              false /*skipFuncBodies*/));
    CI->getPreprocessor().EnterMainSourceFile();
    // Initialize the parser after we have entered the main source file.
    m_Parser->Initialize();
    // Perform initialization that occurs after the parser has been initialized
    // but before it parses anything. Initializes the consumers too.
    CI->getSema().Initialize();
  }

  IncrementalParser::~IncrementalParser() {
     if (hasCodeGenerator()) {
       getCodeGenerator()->ReleaseModule();
     }
     for (size_t i = 0; i < m_Transactions.size(); ++i)
       delete m_Transactions[i];

     for (size_t i = 0; i < m_TTransformers.size(); ++i)
       delete m_TTransformers[i];
  }

  // pin the vtable here since there is no point to create dedicated to that
  // cpp file.
  TransactionTransformer::~TransactionTransformer() {}

  void IncrementalParser::beginTransaction(const CompilationOptions& Opts) {
    llvm::Module* M = 0;
    if (hasCodeGenerator())
      M = getCodeGenerator()->GetModule();

    Transaction* NewCurT = new Transaction(Opts, M);
    Transaction* OldCurT = m_Consumer->getTransaction();
    m_Consumer->setTransaction(NewCurT);
    // If we are in the middle of transaction and we see another begin
    // transaction - it must be nested transaction.
    if (OldCurT && !OldCurT->isCompleted()) {
      OldCurT->addNestedTransaction(NewCurT); // takes the ownership
      return;
    }

    m_Transactions.push_back(NewCurT);
  }

  void IncrementalParser::endTransaction() const {
    Transaction* CurT = m_Consumer->getTransaction();
    CurT->setCompleted();
    const DiagnosticsEngine& Diags = getCI()->getSema().getDiagnostics();

    //TODO: Make the enum orable.
    if (Diags.getNumWarnings() > 0)
      CurT->setIssuedDiags(Transaction::kWarnings);

    if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred())
      CurT->setIssuedDiags(Transaction::kErrors);

    if (CurT->isNestedTransaction()) {
      assert(!CurT->getParent()->isCompleted()
             && "Parent transaction completed!?");
      // FIXME: Not sure what I meant :) REVISIT
      //CurT = m_Consumer->getTransaction()->getParent();
    }
  }

  void IncrementalParser::commitCurrentTransaction() {
    Transaction* CurT = m_Consumer->getTransaction();
    assert(CurT->isCompleted() && "Transaction not ended!?");

    // Check for errors...
    if (CurT->getIssuedDiags() == Transaction::kErrors) {
      rollbackTransaction(CurT);
      return;
    }

    // We are sure it's safe to pipe it through the transformers
    for (size_t i = 0; i < m_TTransformers.size(); ++i)
      if (!m_TTransformers[i]->TransformTransaction(*CurT)) {
        // Roll back on error in a transformer
        rollbackTransaction(CurT);
        return;
      }

    // Pull all template instantiations in that came from the consumers.
    getCI()->getSema().PerformPendingInstantiations();

    m_Consumer->HandleTranslationUnit(getCI()->getASTContext());

    if (CurT->getCompilationOpts().CodeGeneration && hasCodeGenerator()) {
      // Reset the module builder to clean up global initializers, c'tors, d'tors
      getCodeGenerator()->Initialize(getCI()->getASTContext());

      // codegen the transaction
      for (Transaction::const_iterator I = CurT->decls_begin(),
             E = CurT->decls_end(); I != E; ++I) {
        getCodeGenerator()->HandleTopLevelDecl(*I);
      }
      getCodeGenerator()->HandleTranslationUnit(getCI()->getASTContext());
      // run the static initializers that came from codegenning
      m_Interpreter->runStaticInitializersOnce();
    }

    CurT->setState(Transaction::kCommitted);
    InterpreterCallbacks* callbacks = m_Interpreter->getCallbacks();
    if (callbacks)
      callbacks->TransactionCommitted(*CurT);
  }

  void IncrementalParser::rollbackTransaction(Transaction* T) const {
    ASTNodeEraser NodeEraser(&getCI()->getSema());

    if (NodeEraser.RevertTransaction(T))
      T->setState(Transaction::kRolledBack);
    else
      T->setState(Transaction::kRolledBackWithErrors);
  }

  // Each input line is contained in separate memory buffer. The SourceManager
  // assigns sort-of invalid FileID for each buffer, i.e there is no FileEntry
  // for the MemoryBuffer's FileID. That in turn is problem because invalid
  // SourceLocations are given to the diagnostics. Thus the diagnostics cannot
  // order the overloads, for example
  //
  // Our work-around is creating a virtual file, which doesn't exist on the disk
  // with enormous size (no allocation is done). That file has valid FileEntry
  // and so on... We use it for generating valid SourceLocations with valid
  // offsets so that it doesn't cause any troubles to the diagnostics.
  //
  // +---------------------+
  // | Main memory buffer  |
  // +---------------------+
  // |  Virtual file SLoc  |
  // |    address space    |<-----------------+
  // |         ...         |<------------+    |
  // |         ...         |             |    |
  // |         ...         |<----+       |    |
  // |         ...         |     |       |    |
  // +~~~~~~~~~~~~~~~~~~~~~+     |       |    |
  // |     input_line_1    | ....+.......+..--+
  // +---------------------+     |       |
  // |     input_line_2    | ....+.....--+
  // +---------------------+     |
  // |          ...        |     |
  // +---------------------+     |
  // |     input_line_N    | ..--+
  // +---------------------+
  //
  void IncrementalParser::CreateSLocOffsetGenerator() {
    SourceManager& SM = getCI()->getSourceManager();
    FileManager& FM = SM.getFileManager();
    const FileEntry* FE
      = FM.getVirtualFile("InteractiveInputLineIncluder.h", 1U << 15U, time(0));
    m_VirtualFileID = SM.createFileID(FE, SourceLocation(), SrcMgr::C_User);

    assert(!m_VirtualFileID.isInvalid() && "No VirtualFileID created?");
  }

  IncrementalParser::EParseResult
  IncrementalParser::Compile(llvm::StringRef input,
                             const CompilationOptions& Opts) {

    beginTransaction(Opts);
    EParseResult Result = ParseInternal(input);
    endTransaction();

    // Check for errors coming from our custom consumers.
    DiagnosticConsumer& DClient = m_CI->getDiagnosticClient();
    DClient.BeginSourceFile(getCI()->getLangOpts(),
                            &getCI()->getPreprocessor());
    commitCurrentTransaction();

    DClient.EndSourceFile();
    m_CI->getDiagnostics().Reset();

    return Result;
  }

  Transaction* IncrementalParser::Parse(llvm::StringRef input,
                                        const CompilationOptions& Opts) {
    beginTransaction(Opts);
    ParseInternal(input);
    endTransaction();

    return getLastTransaction();
  }

  // Add the input to the memory buffer, parse it, and add it to the AST.
  IncrementalParser::EParseResult
  IncrementalParser::ParseInternal(llvm::StringRef input) {
    if (input.empty()) return IncrementalParser::kSuccess;

    PrettyStackTraceParserEntry CrashInfo(*m_Parser.get());

    // Recover resources if we crash before exiting this method.
    llvm::CrashRecoveryContextCleanupRegistrar<Parser>
      CleanupParser(m_Parser.get());

    Sema& S = getCI()->getSema();
    // Recover resources if we crash before exiting this method.
    llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleanupSema(&S);

    Preprocessor& PP = m_CI->getPreprocessor();
    DiagnosticConsumer& DClient = m_CI->getDiagnosticClient();

    if (!PP.getCurrentLexer()) {
       PP.EnterSourceFile(m_CI->getSourceManager().getMainFileID(),
                          0, SourceLocation());
    }
    assert(PP.isIncrementalProcessingEnabled() && "Not in incremental mode!?");
    PP.enableIncrementalProcessing();

    DClient.BeginSourceFile(m_CI->getLangOpts(), &PP);

    std::ostringstream source_name;
    source_name << "input_line_" << (m_MemoryBuffers.size() + 1);

    // Create an uninitialized memory buffer, copy code in and append "\n"
    size_t InputSize = input.size(); // don't include trailing 0
    // MemBuffer size should *not* include terminating zero
    llvm::MemoryBuffer* MB
      = llvm::MemoryBuffer::getNewUninitMemBuffer(InputSize + 1,
                                                  source_name.str());
    char* MBStart = const_cast<char*>(MB->getBufferStart());
    memcpy(MBStart, input.data(), InputSize);
    memcpy(MBStart + InputSize, "\n", 2);

    m_MemoryBuffers.push_back(MB);
    SourceManager& SM = getCI()->getSourceManager();

    // Create SourceLocation, which will allow clang to order the overload
    // candidates for example
    SourceLocation NewLoc = SM.getLocForStartOfFile(m_VirtualFileID);
    NewLoc = NewLoc.getLocWithOffset(m_MemoryBuffers.size() + 1);

    // Create FileID for the current buffer
    FileID FID = SM.createFileIDForMemBuffer(m_MemoryBuffers.back(),
                                             /*LoadedID*/0,
                                             /*LoadedOffset*/0, NewLoc);

    PP.EnterSourceFile(FID, /*DirLookup*/0, NewLoc);

    Parser::DeclGroupPtrTy ADecl;

    while (!m_Parser->ParseTopLevelDecl(ADecl)) {
      // If we got a null return and something *was* parsed, ignore it.  This
      // is due to a top-level semicolon, an action override, or a parse error
      // skipping something.
      if (ADecl)
        m_Consumer->HandleTopLevelDecl(ADecl.getAsVal<DeclGroupRef>());
    };

    // Process any TopLevelDecls generated by #pragma weak.
    for (llvm::SmallVector<Decl*,2>::iterator I = S.WeakTopLevelDecls().begin(),
           E = S.WeakTopLevelDecls().end(); I != E; ++I) {
      m_Consumer->HandleTopLevelDecl(DeclGroupRef(*I));
    }

    S.PerformPendingInstantiations();

    DClient.EndSourceFile();

    DiagnosticsEngine& Diag = S.getDiagnostics();
    if (Diag.hasErrorOccurred())
      return IncrementalParser::kFailed;
    else if (Diag.getNumWarnings())
      return IncrementalParser::kSuccessWithWarnings;

    return IncrementalParser::kSuccess;
  }

  void IncrementalParser::unloadTransaction(Transaction* T) {
    if (!T)
      T = getLastTransaction();

    assert(T->getState() == Transaction::kCommitted &&
           "Unloading not commited transaction?");
    assert(T->getModule() &&
           "Trying to uncodegen transaction taken in syntax only mode. ");

    ASTNodeEraser NodeEraser(&getCI()->getSema());
    NodeEraser.RevertTransaction(T);

    InterpreterCallbacks* callbacks = m_Interpreter->getCallbacks();
    if (callbacks)
      callbacks->TransactionUnloaded(*T);
  }

} // namespace cling
<commit_msg>Make certain tests from the testsuite happy. The issue was assert in codegen where the DeclRefExpr was built after the declaration was extracted.<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// version: $Id$
// author:  Axel Naumann <axel@cern.ch>
//------------------------------------------------------------------------------

#include "IncrementalParser.h"
#include "ASTDumper.h"
#include "ASTNodeEraser.h"
#include "DeclCollector.h"
#include "DeclExtractor.h"
#include "DynamicLookup.h"
#include "ReturnSynthesizer.h"
#include "ValuePrinterSynthesizer.h"
#include "cling/Interpreter/CIFactory.h"
#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/InterpreterCallbacks.h"
#include "cling/Interpreter/Transaction.h"

#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclGroup.h"
#include "clang/Basic/FileManager.h"
#include "clang/CodeGen/ModuleBuilder.h"
#include "clang/Parse/Parser.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Serialization/ASTWriter.h"

#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_os_ostream.h"

#include <ctime>
#include <iostream>
#include <stdio.h>
#include <sstream>

using namespace clang;

namespace cling {
  IncrementalParser::IncrementalParser(Interpreter* interp,
                                       int argc, const char* const *argv,
                                       const char* llvmdir):
    m_Interpreter(interp), m_Consumer(0) {

    CompilerInstance* CI
      = CIFactory::createCI(llvm::MemoryBuffer::getMemBuffer("", "CLING"),
                            argc, argv, llvmdir);
    assert(CI && "CompilerInstance is (null)!");

    m_Consumer = dyn_cast<DeclCollector>(&CI->getASTConsumer());
    assert(m_Consumer && "Expected ChainedConsumer!");

    m_CI.reset(CI);

    if (CI->getFrontendOpts().ProgramAction != clang::frontend::ParseSyntaxOnly){
      m_CodeGen.reset(CreateLLVMCodeGen(CI->getDiagnostics(), "cling input",
                                        CI->getCodeGenOpts(),
                                        *m_Interpreter->getLLVMContext()
                                        ));
    }

    CreateSLocOffsetGenerator();

    // Add transformers to the IncrementalParser, which owns them
    m_TTransformers.push_back(new EvaluateTSynthesizer(&CI->getSema()));

    m_TTransformers.push_back(new ValuePrinterSynthesizer(&CI->getSema(), 0));
    m_TTransformers.push_back(new ReturnSynthesizer(&CI->getSema()));
    m_TTransformers.push_back(new ASTDumper());
    m_TTransformers.push_back(new DeclExtractor(&getCI()->getSema()));

    m_Parser.reset(new Parser(CI->getPreprocessor(), CI->getSema(),
                              false /*skipFuncBodies*/));
    CI->getPreprocessor().EnterMainSourceFile();
    // Initialize the parser after we have entered the main source file.
    m_Parser->Initialize();
    // Perform initialization that occurs after the parser has been initialized
    // but before it parses anything. Initializes the consumers too.
    CI->getSema().Initialize();
  }

  IncrementalParser::~IncrementalParser() {
     if (hasCodeGenerator()) {
       getCodeGenerator()->ReleaseModule();
     }
     for (size_t i = 0; i < m_Transactions.size(); ++i)
       delete m_Transactions[i];

     for (size_t i = 0; i < m_TTransformers.size(); ++i)
       delete m_TTransformers[i];
  }

  // pin the vtable here since there is no point to create dedicated to that
  // cpp file.
  TransactionTransformer::~TransactionTransformer() {}

  void IncrementalParser::beginTransaction(const CompilationOptions& Opts) {
    llvm::Module* M = 0;
    if (hasCodeGenerator())
      M = getCodeGenerator()->GetModule();

    Transaction* NewCurT = new Transaction(Opts, M);
    Transaction* OldCurT = m_Consumer->getTransaction();
    m_Consumer->setTransaction(NewCurT);
    // If we are in the middle of transaction and we see another begin
    // transaction - it must be nested transaction.
    if (OldCurT && !OldCurT->isCompleted()) {
      OldCurT->addNestedTransaction(NewCurT); // takes the ownership
      return;
    }

    m_Transactions.push_back(NewCurT);
  }

  void IncrementalParser::endTransaction() const {
    Transaction* CurT = m_Consumer->getTransaction();
    CurT->setCompleted();
    const DiagnosticsEngine& Diags = getCI()->getSema().getDiagnostics();

    //TODO: Make the enum orable.
    if (Diags.getNumWarnings() > 0)
      CurT->setIssuedDiags(Transaction::kWarnings);

    if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred())
      CurT->setIssuedDiags(Transaction::kErrors);

    if (CurT->isNestedTransaction()) {
      assert(!CurT->getParent()->isCompleted()
             && "Parent transaction completed!?");
      // FIXME: Not sure what I meant :) REVISIT
      //CurT = m_Consumer->getTransaction()->getParent();
    }
  }

  void IncrementalParser::commitCurrentTransaction() {
    Transaction* CurT = m_Consumer->getTransaction();
    assert(CurT->isCompleted() && "Transaction not ended!?");

    // Check for errors...
    if (CurT->getIssuedDiags() == Transaction::kErrors) {
      rollbackTransaction(CurT);
      return;
    }

    // We are sure it's safe to pipe it through the transformers
    for (size_t i = 0; i < m_TTransformers.size(); ++i)
      if (!m_TTransformers[i]->TransformTransaction(*CurT)) {
        // Roll back on error in a transformer
        rollbackTransaction(CurT);
        return;
      }

    // Pull all template instantiations in that came from the consumers.
    getCI()->getSema().PerformPendingInstantiations();

    m_Consumer->HandleTranslationUnit(getCI()->getASTContext());

    if (CurT->getCompilationOpts().CodeGeneration && hasCodeGenerator()) {
      // Reset the module builder to clean up global initializers, c'tors, d'tors
      getCodeGenerator()->Initialize(getCI()->getASTContext());

      // codegen the transaction
      for (Transaction::const_iterator I = CurT->decls_begin(),
             E = CurT->decls_end(); I != E; ++I) {
        getCodeGenerator()->HandleTopLevelDecl(*I);
      }
      getCodeGenerator()->HandleTranslationUnit(getCI()->getASTContext());
      // run the static initializers that came from codegenning
      m_Interpreter->runStaticInitializersOnce();
    }

    CurT->setState(Transaction::kCommitted);
    InterpreterCallbacks* callbacks = m_Interpreter->getCallbacks();
    if (callbacks)
      callbacks->TransactionCommitted(*CurT);
  }

  void IncrementalParser::rollbackTransaction(Transaction* T) const {
    ASTNodeEraser NodeEraser(&getCI()->getSema());

    if (NodeEraser.RevertTransaction(T))
      T->setState(Transaction::kRolledBack);
    else
      T->setState(Transaction::kRolledBackWithErrors);
  }

  // Each input line is contained in separate memory buffer. The SourceManager
  // assigns sort-of invalid FileID for each buffer, i.e there is no FileEntry
  // for the MemoryBuffer's FileID. That in turn is problem because invalid
  // SourceLocations are given to the diagnostics. Thus the diagnostics cannot
  // order the overloads, for example
  //
  // Our work-around is creating a virtual file, which doesn't exist on the disk
  // with enormous size (no allocation is done). That file has valid FileEntry
  // and so on... We use it for generating valid SourceLocations with valid
  // offsets so that it doesn't cause any troubles to the diagnostics.
  //
  // +---------------------+
  // | Main memory buffer  |
  // +---------------------+
  // |  Virtual file SLoc  |
  // |    address space    |<-----------------+
  // |         ...         |<------------+    |
  // |         ...         |             |    |
  // |         ...         |<----+       |    |
  // |         ...         |     |       |    |
  // +~~~~~~~~~~~~~~~~~~~~~+     |       |    |
  // |     input_line_1    | ....+.......+..--+
  // +---------------------+     |       |
  // |     input_line_2    | ....+.....--+
  // +---------------------+     |
  // |          ...        |     |
  // +---------------------+     |
  // |     input_line_N    | ..--+
  // +---------------------+
  //
  void IncrementalParser::CreateSLocOffsetGenerator() {
    SourceManager& SM = getCI()->getSourceManager();
    FileManager& FM = SM.getFileManager();
    const FileEntry* FE
      = FM.getVirtualFile("InteractiveInputLineIncluder.h", 1U << 15U, time(0));
    m_VirtualFileID = SM.createFileID(FE, SourceLocation(), SrcMgr::C_User);

    assert(!m_VirtualFileID.isInvalid() && "No VirtualFileID created?");
  }

  IncrementalParser::EParseResult
  IncrementalParser::Compile(llvm::StringRef input,
                             const CompilationOptions& Opts) {

    beginTransaction(Opts);
    EParseResult Result = ParseInternal(input);
    endTransaction();

    // Check for errors coming from our custom consumers.
    DiagnosticConsumer& DClient = m_CI->getDiagnosticClient();
    DClient.BeginSourceFile(getCI()->getLangOpts(),
                            &getCI()->getPreprocessor());
    commitCurrentTransaction();

    DClient.EndSourceFile();
    m_CI->getDiagnostics().Reset();

    return Result;
  }

  Transaction* IncrementalParser::Parse(llvm::StringRef input,
                                        const CompilationOptions& Opts) {
    beginTransaction(Opts);
    ParseInternal(input);
    endTransaction();

    return getLastTransaction();
  }

  // Add the input to the memory buffer, parse it, and add it to the AST.
  IncrementalParser::EParseResult
  IncrementalParser::ParseInternal(llvm::StringRef input) {
    if (input.empty()) return IncrementalParser::kSuccess;

    PrettyStackTraceParserEntry CrashInfo(*m_Parser.get());

    // Recover resources if we crash before exiting this method.
    llvm::CrashRecoveryContextCleanupRegistrar<Parser>
      CleanupParser(m_Parser.get());

    Sema& S = getCI()->getSema();
    // Recover resources if we crash before exiting this method.
    llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleanupSema(&S);

    Preprocessor& PP = m_CI->getPreprocessor();
    DiagnosticConsumer& DClient = m_CI->getDiagnosticClient();

    if (!PP.getCurrentLexer()) {
       PP.EnterSourceFile(m_CI->getSourceManager().getMainFileID(),
                          0, SourceLocation());
    }
    assert(PP.isIncrementalProcessingEnabled() && "Not in incremental mode!?");
    PP.enableIncrementalProcessing();

    DClient.BeginSourceFile(m_CI->getLangOpts(), &PP);

    std::ostringstream source_name;
    source_name << "input_line_" << (m_MemoryBuffers.size() + 1);

    // Create an uninitialized memory buffer, copy code in and append "\n"
    size_t InputSize = input.size(); // don't include trailing 0
    // MemBuffer size should *not* include terminating zero
    llvm::MemoryBuffer* MB
      = llvm::MemoryBuffer::getNewUninitMemBuffer(InputSize + 1,
                                                  source_name.str());
    char* MBStart = const_cast<char*>(MB->getBufferStart());
    memcpy(MBStart, input.data(), InputSize);
    memcpy(MBStart + InputSize, "\n", 2);

    m_MemoryBuffers.push_back(MB);
    SourceManager& SM = getCI()->getSourceManager();

    // Create SourceLocation, which will allow clang to order the overload
    // candidates for example
    SourceLocation NewLoc = SM.getLocForStartOfFile(m_VirtualFileID);
    NewLoc = NewLoc.getLocWithOffset(m_MemoryBuffers.size() + 1);

    // Create FileID for the current buffer
    FileID FID = SM.createFileIDForMemBuffer(m_MemoryBuffers.back(),
                                             /*LoadedID*/0,
                                             /*LoadedOffset*/0, NewLoc);

    PP.EnterSourceFile(FID, /*DirLookup*/0, NewLoc);

    Parser::DeclGroupPtrTy ADecl;

    while (!m_Parser->ParseTopLevelDecl(ADecl)) {
      // If we got a null return and something *was* parsed, ignore it.  This
      // is due to a top-level semicolon, an action override, or a parse error
      // skipping something.
      if (ADecl)
        m_Consumer->HandleTopLevelDecl(ADecl.getAsVal<DeclGroupRef>());
    };

    // Process any TopLevelDecls generated by #pragma weak.
    for (llvm::SmallVector<Decl*,2>::iterator I = S.WeakTopLevelDecls().begin(),
           E = S.WeakTopLevelDecls().end(); I != E; ++I) {
      m_Consumer->HandleTopLevelDecl(DeclGroupRef(*I));
    }

    S.PerformPendingInstantiations();

    DClient.EndSourceFile();

    DiagnosticsEngine& Diag = S.getDiagnostics();
    if (Diag.hasErrorOccurred())
      return IncrementalParser::kFailed;
    else if (Diag.getNumWarnings())
      return IncrementalParser::kSuccessWithWarnings;

    return IncrementalParser::kSuccess;
  }

  void IncrementalParser::unloadTransaction(Transaction* T) {
    if (!T)
      T = getLastTransaction();

    assert(T->getState() == Transaction::kCommitted &&
           "Unloading not commited transaction?");
    assert(T->getModule() &&
           "Trying to uncodegen transaction taken in syntax only mode. ");

    ASTNodeEraser NodeEraser(&getCI()->getSema());
    NodeEraser.RevertTransaction(T);

    InterpreterCallbacks* callbacks = m_Interpreter->getCallbacks();
    if (callbacks)
      callbacks->TransactionUnloaded(*T);
  }

} // namespace cling
<|endoftext|>


<commit_before>#ifdef WINDOWS
#define BITMAP dummyBITMAP
#include <windows.h>
#undef BITMAP
#endif

#include "menu/option_credits.h"
#include "menu/menu_global.h"
#include "util/token.h"
#include "globals.h"

#include "init.h"

#include "factory/collector.h"
#include "factory/object_factory.h"
#include "factory/heart_factory.h"
#include "factory/font_render.h"
#include "fonts.h"
#include "globals.h"
#include "configuration.h"
#include "level/scene.h"
#include "return_exception.h"
#include "loading.h"
#include "music.h"
#include "object/character.h"
#include "object/effect.h"
#include "object/enemy.h"
#include "object/object.h"
#include "object/object_attack.h"
#include "object/player.h"
#include "object/versus_player.h"
#include "object/versus_enemy.h"
#include "util/bitmap.h"
#include "util/funcs.h"
#include "util/load_exception.h"
#include "util/token.h"
#include "util/token_exception.h"
#include "util/font.h"
#include "util/tokenreader.h"
#include "util/timedifference.h"
#include "select_player.h"
#include "world.h"
#include "versus_world.h"
#include "menu/menu.h"

#include <pthread.h>

#include <iostream>

using namespace std;

static const char * DEFAULT_FONT = "/fonts/arial.ttf";

OptionCredits::OptionCredits(Token *token)throw( LoadException ) : MenuOption(event), background(0), music(""), color(Bitmap::makeColor(255,255,255)), title(Bitmap::makeColor(0,255,255))
{
	/* Always */
	credits.push_back("Paintown");
	credits.push_back("");
	credits.push_back("Programming");
	credits.push_back("Jon Rafkind");
	credits.push_back("");
	credits.push_back("Contributions");
	credits.push_back("Miguel Gavidia");
	credits.push_back("");
	credits.push_back("Level design");
	credits.push_back("Jon Rafkind");
	credits.push_back("Miguel Gavidia");
	credits.push_back("");
	credits.push_back("Music");
	credits.push_back("aqua.s3m - Purple Motion");
	credits.push_back("c_heaven.xm - One Man Project");
	credits.push_back("elw-sick.xm - elwood");
	credits.push_back("experience.xm - elwood");
	credits.push_back("fall.xm - elwood");
	credits.push_back("kajahtaa.xm - cube");
	credits.push_back("kilimanz.mod - ???");
	credits.push_back("");
	credits.push_back("Email: jon@rafkind.com");
	credits.push_back("");

	if ( *token != "credits" )
		throw LoadException("Not a credit menu");

	while ( token->hasTokens() )
	{
		try
		{
			Token * tok;
			*token >> tok;
			if ( *tok == "name" )
			{
				// Create an image and push it back on to vector
				std::string temp;
				*tok >> temp;
				this->setText(temp);
			}
			else if ( *tok == "music" )
			{
				// Set music for credits
				*tok >> music;
			}
			else if ( *tok == "background" )
			{
				// Create an image and push it back on to vector
				std::string temp;
				*tok >> temp;
				background = new Bitmap(Util::getDataPath() +temp);
				if(background->getError())delete background;
			}
			else if ( *tok == "additional" )
			{
				std::string str;
				while(tok->hasTokens())
				{
					*tok >> str;
					credits.push_back(str);
				}
				credits.push_back("");
			}
			else if( *tok == "titlecolor" )
			{
				int r,b,g;
				*tok >> r >> g >> b;
				title = Bitmap::makeColor( r, b, g );
			}
			else if( *tok == "color" )
			{
				int r,b,g;
				*tok >> r >> g >> b;
				color = Bitmap::makeColor( r, b, g );
			}
			else
			{
				Global::debug( 3 ) <<"Unhandled menu attribute: "<<endl;
				tok->print(" ");
			}
		}
		catch ( const TokenException & ex )
		{
			// delete current;
			string m( "Menu parse error: " );
			m += ex.getReason();
			throw LoadException( m );
		}
		catch ( const LoadException & ex )
		{
			// delete current;
			throw ex;
		}
	}

	if(getText().empty())throw LoadException("No name set, this option should have a name!");
}

OptionCredits::~OptionCredits()
{
	// Nothing
	if(background)delete background;
}

void OptionCredits::logic()
{
}

void OptionCredits::draw(Bitmap *work)
{
}

void OptionCredits::run(bool &endGame)
{
	Keyboard key;

	const int maxCredits = credits.size();

	Global::speed_counter = 0;
	int min_y = GFX_Y;
	const Font & font = Font::getFont( Util::getDataPath() + DEFAULT_FONT, 20, 20 );
	Bitmap tmp( GFX_X, GFX_Y );
	if(!music.empty())MenuGlobals::setMusic(music);
	while ( ! key[ Keyboard::Key_ESC ] ){

		key.poll();

		bool draw = false;
		if ( Global::speed_counter / 2 > 0 ){
			double think = Global::speed_counter / 2;
			draw = true;

			while ( think > 0 ){
				think--;
				min_y -= 1;
				if ( min_y < -(int)(maxCredits * font.getHeight() * 1.1) ){
					min_y = GFX_Y;
				}
			}

			Global::speed_counter = 0;
		}

		if ( draw ){
			if(background)background->Blit( tmp );
			else tmp.fill(Bitmap::makeColor(0,0,0));
			int y = min_y;
			vector<std::string>::iterator b = credits.begin();
			vector<std::string>::iterator e = credits.end();
			bool isTitle = true;
			for(;b!=e;++b)
			{
				if(isTitle)
				{
					font.printf( 100, y, title, tmp, (*b), 0 );
					isTitle = false;
				}
				else font.printf( 100, y, color, tmp, (*b), 0 );
				y += font.getHeight() + 2;
				if((*b).empty())isTitle=true;
			}

			tmp.BlitToScreen();
		} else {
			Util::rest( 1 );
		}
	}
	key.wait();
}

<commit_msg>cleanup credits<commit_after>/*
#ifdef WINDOWS
#define BITMAP dummyBITMAP
#include <windows.h>
#undef BITMAP
#endif

#include "menu/option_credits.h"
#include "menu/menu_global.h"
#include "util/token.h"
#include "globals.h"

#include "init.h"

#include "factory/collector.h"
#include "factory/object_factory.h"
#include "factory/heart_factory.h"
#include "factory/font_render.h"
#include "fonts.h"
#include "globals.h"
#include "configuration.h"
#include "level/scene.h"
#include "return_exception.h"
#include "loading.h"
#include "music.h"
#include "object/character.h"
#include "object/effect.h"
#include "object/enemy.h"
#include "object/object.h"
#include "object/object_attack.h"
#include "object/player.h"
#include "object/versus_player.h"
#include "object/versus_enemy.h"
#include "util/bitmap.h"
#include "util/funcs.h"
#include "util/load_exception.h"
#include "util/token.h"
#include "util/token_exception.h"
#include "util/font.h"
#include "util/tokenreader.h"
#include "util/timedifference.h"
#include "select_player.h"
#include "world.h"
#include "versus_world.h"
#include "menu/menu.h"

#include <pthread.h>

#include <iostream>
*/

#include "util/bitmap.h"
#include "menu/option_credits.h"
#include "menu/menu_global.h"
#include "globals.h"
#include "init.h"
#include "util/funcs.h"
#include "util/keyboard.h"
#include "util/token.h"
#include "util/token_exception.h"
#include "util/font.h"

using namespace std;

static const char * DEFAULT_FONT = "/fonts/arial.ttf";

OptionCredits::OptionCredits( Token * token ) throw( LoadException ):
MenuOption(event),
background(0),
music(""),
color(Bitmap::makeColor(255,255,255)),
title(Bitmap::makeColor(0,255,255)){
	/* Always */
	credits.push_back("Paintown");
	credits.push_back("");
	credits.push_back("Programming");
	credits.push_back("Jon Rafkind");
	credits.push_back("");
	credits.push_back("Contributions");
	credits.push_back("Miguel Gavidia");
	credits.push_back("");
	credits.push_back("Level design");
	credits.push_back("Jon Rafkind");
	credits.push_back("Miguel Gavidia");
	credits.push_back("");
	credits.push_back("Music");
	credits.push_back("aqua.s3m - Purple Motion");
	credits.push_back("c_heaven.xm - One Man Project");
	credits.push_back("elw-sick.xm - elwood");
	credits.push_back("experience.xm - elwood");
	credits.push_back("fall.xm - elwood");
	credits.push_back("kajahtaa.xm - cube");
	credits.push_back("kilimanz.mod - ???");
	credits.push_back("");
	credits.push_back("Email: jon@rafkind.com");
	credits.push_back("");

	if ( *token != "credits" )
		throw LoadException("Not a credit menu");

	while ( token->hasTokens() ){
		try{
			Token * tok;
			*token >> tok;
			if ( *tok == "name" ){
				/* Create an image and push it back on to vector */
				std::string temp;
				*tok >> temp;
				this->setText(temp);
			} else if ( *tok == "music" ) {
				/* Set music for credits */
				*tok >> music;
			} else if ( *tok == "background" ) {
				/* Create an image and push it back on to vector */
				std::string temp;
				*tok >> temp;
				if ( background ){
					delete background;
				}
				background = new Bitmap(Util::getDataPath() +temp);
				if ( background->getError() ){
					delete background;
					background = NULL;
				}
			} else if ( *tok == "additional" ) {
				std::string str;
				while ( tok->hasTokens() ){
					*tok >> str;
					credits.push_back(str);
				}
			} else if ( *tok == "titlecolor" ) {
				int r,b,g;
				*tok >> r >> g >> b;
				title = Bitmap::makeColor( r, b, g );
			} else if ( *tok == "color" ) {
				int r,b,g;
				*tok >> r >> g >> b;
				color = Bitmap::makeColor( r, b, g );
			} else {
				Global::debug( 3 ) <<"Unhandled menu attribute: "<<endl;
				tok->print(" ");
			}
		} catch ( const TokenException & ex ) {
			string m( "Menu parse error: " );
			m += ex.getReason();
			throw LoadException( m );
		} catch ( const LoadException & ex ) {
			throw ex;
		}
	}

	if ( getText().empty() ){
		throw LoadException("No name set, this option should have a name!");
	}
}

OptionCredits::~OptionCredits(){
	if ( background ){
		delete background;
	}
}

void OptionCredits::logic(){
}

void OptionCredits::draw(Bitmap *work){
}

void OptionCredits::run( bool &endGame ){
	Keyboard key;

	const int maxCredits = credits.size();

	Global::speed_counter = 0;
	int min_y = GFX_Y;
	const Font & font = Font::getFont( Util::getDataPath() + DEFAULT_FONT, 20, 20 );
	Bitmap tmp( GFX_X, GFX_Y );
	if ( ! music.empty() ){
		MenuGlobals::setMusic( music );
	}

	while ( ! key[ Keyboard::Key_ESC ] ){

		key.poll();

		bool draw = false;
		if ( Global::speed_counter / 2 > 0 ){
			double think = Global::speed_counter / 2;
			draw = true;

			while ( think > 0 ){
				think--;
				min_y -= 1;
				if ( min_y < -(int)(maxCredits * font.getHeight() * 1.1) ){
					min_y = GFX_Y;
				}
			}

			Global::speed_counter = 0;
		}

		if ( draw ){
			if ( background ){
				background->Blit( tmp );
			} else {
				tmp.fill( Bitmap::makeColor(0,0,0) );
			}

			int y = min_y;
			vector<std::string>::iterator b = credits.begin();
			vector<std::string>::iterator e = credits.end();
			bool isTitle = true;
			for ( /**/ ; b != e; b++ ){
				if ( isTitle ){
					font.printf( 100, y, title, tmp, (*b), 0 );
					isTitle = false;
				} else {
					font.printf( 100, y, color, tmp, (*b), 0 );
				}
				y += font.getHeight() + 2;

				if ( (*b).empty() ){
					isTitle = true;
				}
			}

			tmp.BlitToScreen();
		} else {
			Util::rest( 1 );
		}
	}
	key.wait();
}
<|endoftext|>


<commit_before>// -*- mode: c++; c-basic-offset:4 -*-

// This file is part of libdap, A C++ implementation of the OPeNDAP Data
// Access Protocol.

// Copyright (c) 2005,2018 OPeNDAP, Inc.
// Author: James Gallagher <jgallagher@opendap.org>
//
// 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.1 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.

#include <cppunit/TextTestRunner.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/extensions/HelperMacros.h>

#include <cstring>
#include <string>

#include <unistd.h>

#include "GNURegex.h"

#include "Array.h"
#include "Byte.h"
#include "Int16.h"
#include "Float32.h"
#include "Int64.h"
#include "D4Enum.h"
#include "D4Dimensions.h"

#include "run_tests_cppunit.h"
#include "test_config.h"

using namespace CppUnit;
using namespace std;

namespace libdap {

class ArrayTest: public TestFixture {
private:
    Array *d_cardinal = nullptr;
    Array *d_card_dap4 = nullptr;

    Array *d_cardinal_byte = nullptr;
    Array *d_card_dap4_byte = nullptr;

    Int16 *d_int16 = nullptr;
    Byte *d_uint8 = nullptr;

public:
    ArrayTest() = default;

    ~ArrayTest() = default;

    void setUp()
    {
        d_int16 = new Int16("Int16");
        DBG(cerr << "d_int16: " << d_int16 << endl);
        d_cardinal = new Array("Array_of_Int16", d_int16);
        d_cardinal->append_dim(4, "dimension");
        dods_int16 buffer[4] = { 0, 1, 2, 3 };
        d_cardinal->val2buf(buffer);

        // Added to test if Arrays with DAP4 protos will have is_dap4() == true. jhrg 7/27/22
        Int64 i64("");
        d_card_dap4 = new Array("Array_of_Int64", &i64);
        d_card_dap4->append_dim(4, "dimension");
        dods_int64 buffer64[4] = { 0, 1, 2, 3 };
        d_card_dap4->val2buf(buffer64);

        delete d_int16;
        d_int16 = 0;
    }

    void tearDown()
    {
        delete d_cardinal;
        delete d_card_dap4;
    }

    CPPUNIT_TEST_SUITE (ArrayTest);

    CPPUNIT_TEST (cons_test);
#if 0
    CPPUNIT_TEST (test_is_dap4_1);
    CPPUNIT_TEST (test_is_dap4_2);
    CPPUNIT_TEST (test_is_dap4_3);
    CPPUNIT_TEST (test_is_dap4_4);
    CPPUNIT_TEST (assignment_test_1);
    CPPUNIT_TEST (assignment_test_2);
    CPPUNIT_TEST (assignment_test_3);
    CPPUNIT_TEST (prepend_dim_test);
    CPPUNIT_TEST (prepend_dim_2_test);
    CPPUNIT_TEST (clear_dims_test);
    CPPUNIT_TEST (error_handling_test);
    CPPUNIT_TEST (error_handling_2_test);
    CPPUNIT_TEST (duplicate_cardinal_test);
#endif

    CPPUNIT_TEST_SUITE_END();

    void cons_test()
    {
        Array a1 = Array("a", "b", d_int16, true);
        CPPUNIT_ASSERT(a1.name() == "a");
    }

    void test_is_dap4_1() {
        DBG(d_card_dap4->dump(cerr));
        CPPUNIT_ASSERT_MESSAGE("This Array should register as DAP4", d_card_dap4->is_dap4());
    }

    void test_is_dap4_2() {
        DBG(d_cardinal->dump(cerr));
        CPPUNIT_ASSERT_MESSAGE("This Array should not register as DAP4", !d_cardinal->is_dap4());
    }

    void test_is_dap4_3() {
        // An array Enum is always DAP4, even when the underlying type of the enum is not
        D4Enum enum16("", dods_int16_c);
        unique_ptr<Array> enum_array_dap4(new Array("Array_of_Enum", &enum16));
        enum_array_dap4->append_dim(4, "dimension");
        dods_int16 buffer16[4] = { 0, 1, 2, 3 };
        enum_array_dap4->val2buf(buffer16);

        DBG(enum_array_dap4->dump(cerr));
        CPPUNIT_ASSERT_MESSAGE("This Array should register as DAP4", enum_array_dap4->is_dap4());
    }

    void test_is_dap4_4() {
        D4Enum enum64("", dods_int64_c);
        unique_ptr<Array> enum_array_dap4(new Array("Array_of_Enum", &enum64));
        enum_array_dap4->append_dim(4, "dimension");
        dods_int64 buffer64[4] = { 0, 1, 2, 3 };
        enum_array_dap4->val2buf(buffer64);

        DBG(enum_array_dap4->dump(cerr));
        CPPUNIT_ASSERT_MESSAGE("This Array should register as DAP4", enum_array_dap4->is_dap4());
    }

    void assignment_test_1()
    {
        // Are fields from the object copied by the assignment
        Array a1 = Array("a", d_int16);
        a1.append_dim(17, "bob");
        CPPUNIT_ASSERT(a1.dimension_size(a1.dim_begin()) == 17);
        a1 = *d_cardinal;
        CPPUNIT_ASSERT(a1.dimension_size(a1.dim_begin()) == 4);
    }

    void assignment_test_2()
    {
        // Self-assignment; are objects changed by the assignment?
        Array a1 = Array("a", d_int16);
        Array *before = &a1;
        a1 = a1;
        Array *after = &a1;
        CPPUNIT_ASSERT_MESSAGE("The pointers should be the same", before == after);
    }

    // This tests that the assignment operator defined in Array correctly copies
    // information held in a parent class (Vector). jhrg 2/9/22
    void assignment_test_3()
    {
        // Array copies the proto pointer and manages the storage
#if 0
        unique_ptr<Float32> f32(new Float32("float_proto"));
        Array a1 = Array("a", f32.get());
#endif
        auto f32_ptr = new Float32("float_proto");
        Array a1 = Array("a", f32_ptr);
	delete f32_ptr;

        CPPUNIT_ASSERT_MESSAGE("The type of a1.var() should be dods_float32", a1.var()->type() == dods_float32_c);
        a1 = *d_cardinal;
        CPPUNIT_ASSERT_MESSAGE("The type of a1.var() should now be dods_int16_c", a1.var()->type() == dods_int16_c);
    }

    void prepend_dim_test()
    {
        Array a1 = Array("a", d_int16);
        Array::Dim_iter i = a1.dim_begin();
        CPPUNIT_ASSERT(a1.dimension_size(i) == 0);
        a1.prepend_dim(2, "dim_a");
        i = a1.dim_begin();
        CPPUNIT_ASSERT(a1.dimension_size(i) == 2);
        a1.prepend_dim(3, "dim_b");
    }

    void prepend_dim_2_test()
    {
        Array a1 = Array("a", d_int16);
        string expected_name[2] = {"dim_b", "myDim"};
        int j = 0;
        D4Dimensions *dims = new D4Dimensions();
        D4Dimension *d = new D4Dimension("dim_b", 2, dims);
        a1.prepend_dim(2, "dim_a");
        a1.prepend_dim(d);
        a1.rename_dim("dim_a", "myDim");
        for (Array::Dim_iter i = a1.dim_begin(); i != a1.dim_end(); i++, j++) {
            CPPUNIT_ASSERT(a1.dimension_name(i) == expected_name[j]);
        }
        delete dims;
        delete d;
    }

    void clear_dims_test()
    {
        Array a1 = Array("a", d_int16);
        a1.prepend_dim(2, "dim_a");
        a1.prepend_dim(3, "dim_b");
        a1.clear_all_dims();
        Array::Dim_iter i = a1.dim_begin();
        CPPUNIT_ASSERT(a1.dimension_size(i) == 0);
    }

    void error_handling_test()
    {
        Array a1 = Array("a", d_int16);
        Array::Dim_iter i = a1.dim_begin();
        string msg;
        CPPUNIT_ASSERT_THROW(a1.dimension_name(i), InternalErr);
        CPPUNIT_ASSERT(!a1.check_semantics(msg));
    }

    void error_handling_2_test()
    {
        Array a1 = Array("a", d_int16);
        a1.append_dim(2, "dim_a");
        Array::Dim_iter i = a1.dim_begin();
        CPPUNIT_ASSERT(a1.dimension_size(i) == 2);
        CPPUNIT_ASSERT_THROW(a1.add_constraint(i, 2, 1, 1), Error);
        CPPUNIT_ASSERT_THROW(a1.add_constraint(i, 0, 1, 2), Error);
        CPPUNIT_ASSERT_THROW(a1.add_constraint(i, 0, 3, 1), Error);
    }

    void duplicate_cardinal_test()
    {
        Array::Dim_iter i = d_cardinal->dim_begin();
        CPPUNIT_ASSERT(d_cardinal->dimension_size(i) == 4);
        dods_int16 *b = new dods_int16[4];
        d_cardinal->buf2val((void**) &b);
        for (int i = 0; i < 4; ++i) {
            CPPUNIT_ASSERT(b[i] == i);
            DBG(cerr << "b[" << i << "]: " << b[i] << endl);
        }
        delete[] b;
        b = 0;

        Array a = *d_cardinal;
        i = a.dim_begin();
        CPPUNIT_ASSERT(a.dimension_size(i) == 4);

        dods_int16 *b2 = new dods_int16[4];
        d_cardinal->buf2val((void**) &b2);
        for (int i = 0; i < 4; ++i) {
            CPPUNIT_ASSERT(b2[i] == i);
            DBG(cerr << "b2[" << i << "]: " << b2[i] << endl);
        }
        delete[] b2;
        b2 = 0;
    }

};

CPPUNIT_TEST_SUITE_REGISTRATION (ArrayTest);

} // namespace libdap

int main(int argc, char *argv[])
{
    return run_tests<libdap::ArrayTest>(argc, argv) ? 0: 1;
}
<commit_msg>intermediate debugging stage<commit_after>// -*- mode: c++; c-basic-offset:4 -*-

// This file is part of libdap, A C++ implementation of the OPeNDAP Data
// Access Protocol.

// Copyright (c) 2005,2018 OPeNDAP, Inc.
// Author: James Gallagher <jgallagher@opendap.org>
//
// 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.1 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.

#include <cppunit/TextTestRunner.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/extensions/HelperMacros.h>

#include <cstring>
#include <string>

#include <unistd.h>

#include "GNURegex.h"

#include "Array.h"
#include "Byte.h"
#include "Int16.h"
#include "Float32.h"
#include "Int64.h"
#include "D4Enum.h"
#include "D4Dimensions.h"

#include "run_tests_cppunit.h"
#include "test_config.h"

using namespace CppUnit;
using namespace std;

namespace libdap {

class ArrayTest: public TestFixture {
private:
    Array *d_cardinal = nullptr;
    Array *d_card_dap4 = nullptr;

    Array *d_cardinal_byte = nullptr;
    Array *d_card_dap4_byte = nullptr;

    Int16 *d_int16 = nullptr;
    Byte *d_uint8 = nullptr;

public:
    ArrayTest() = default;

    ~ArrayTest() = default;

    void setUp()
    {
        d_int16 = new Int16("Int16");
        DBG(cerr << "d_int16: " << d_int16 << endl);
        d_cardinal = new Array("Array_of_Int16", d_int16);
        uint64_t num_eles=1024*1024*1024*4;
        auto d4_dim = new D4Dimension("dimension",num_eles);
        d_cardinal->append_dim(d4_dim);
        vector<short> buffer;
        buffer.resize(num_eles);
        buffer[0]=-32768;
        buffer[num_eles-1]=32767;
        d_cardinal->set_value((dods_int16*)buffer.data(),num_eles);
        delete d4_dim;
        delete d_int16;
        d_int16 = 0;

#if 0
        d_int16 = new Int16("Int16");

        DBG(cerr << "d_int16: " << d_int16 << endl);
        d_cardinal = new Array("Array_of_Int16", d_int16);
        uint64_t num_eles=1024*1024*1024*4;
        d_cardinal->append_dim(4, "dimension");
        dods_int16 buffer[4] = { 0, 1, 2, 3 };
        d_cardinal->val2buf(buffer);

        // Added to test if Arrays with DAP4 protos will have is_dap4() == true. jhrg 7/27/22
        Int64 i64("");
        d_card_dap4 = new Array("Array_of_Int64", &i64);
        d_card_dap4->append_dim(4, "dimension");
        dods_int64 buffer64[4] = { 0, 1, 2, 3 };
        d_card_dap4->val2buf(buffer64);

        delete d_int16;
        d_int16 = 0;
#endif
    }

    void tearDown()
    {
        delete d_cardinal;
        delete d_card_dap4;
    }

    CPPUNIT_TEST_SUITE (ArrayTest);

    CPPUNIT_TEST (cons_test);
#if 0
    CPPUNIT_TEST (test_is_dap4_1);
    CPPUNIT_TEST (test_is_dap4_2);
    CPPUNIT_TEST (test_is_dap4_3);
    CPPUNIT_TEST (test_is_dap4_4);
    CPPUNIT_TEST (assignment_test_1);
    CPPUNIT_TEST (assignment_test_2);
    CPPUNIT_TEST (assignment_test_3);
    CPPUNIT_TEST (prepend_dim_test);
    CPPUNIT_TEST (prepend_dim_2_test);
    CPPUNIT_TEST (clear_dims_test);
    CPPUNIT_TEST (error_handling_test);
    CPPUNIT_TEST (error_handling_2_test);
    CPPUNIT_TEST (duplicate_cardinal_test);
#endif

    CPPUNIT_TEST_SUITE_END();

    void cons_test()
    {
        Array a1 = Array("a", "b", d_int16, true);
        CPPUNIT_ASSERT(a1.name() == "a");
    }

    void test_is_dap4_1() {
        DBG(d_card_dap4->dump(cerr));
        CPPUNIT_ASSERT_MESSAGE("This Array should register as DAP4", d_card_dap4->is_dap4());
    }

    void test_is_dap4_2() {
        DBG(d_cardinal->dump(cerr));
        CPPUNIT_ASSERT_MESSAGE("This Array should not register as DAP4", !d_cardinal->is_dap4());
    }

    void test_is_dap4_3() {
        // An array Enum is always DAP4, even when the underlying type of the enum is not
        D4Enum enum16("", dods_int16_c);
        unique_ptr<Array> enum_array_dap4(new Array("Array_of_Enum", &enum16));
        enum_array_dap4->append_dim(4, "dimension");
        dods_int16 buffer16[4] = { 0, 1, 2, 3 };
        enum_array_dap4->val2buf(buffer16);

        DBG(enum_array_dap4->dump(cerr));
        CPPUNIT_ASSERT_MESSAGE("This Array should register as DAP4", enum_array_dap4->is_dap4());
    }

    void test_is_dap4_4() {
        D4Enum enum64("", dods_int64_c);
        unique_ptr<Array> enum_array_dap4(new Array("Array_of_Enum", &enum64));
        enum_array_dap4->append_dim(4, "dimension");
        dods_int64 buffer64[4] = { 0, 1, 2, 3 };
        enum_array_dap4->val2buf(buffer64);

        DBG(enum_array_dap4->dump(cerr));
        CPPUNIT_ASSERT_MESSAGE("This Array should register as DAP4", enum_array_dap4->is_dap4());
    }

    void assignment_test_1()
    {
        // Are fields from the object copied by the assignment
        Array a1 = Array("a", d_int16);
        a1.append_dim(17, "bob");
        CPPUNIT_ASSERT(a1.dimension_size(a1.dim_begin()) == 17);
        a1 = *d_cardinal;
        CPPUNIT_ASSERT(a1.dimension_size(a1.dim_begin()) == 4);
    }

    void assignment_test_2()
    {
        // Self-assignment; are objects changed by the assignment?
        Array a1 = Array("a", d_int16);
        Array *before = &a1;
        a1 = a1;
        Array *after = &a1;
        CPPUNIT_ASSERT_MESSAGE("The pointers should be the same", before == after);
    }

    // This tests that the assignment operator defined in Array correctly copies
    // information held in a parent class (Vector). jhrg 2/9/22
    void assignment_test_3()
    {
        // Array copies the proto pointer and manages the storage
#if 0
        unique_ptr<Float32> f32(new Float32("float_proto"));
        Array a1 = Array("a", f32.get());
#endif
        auto f32_ptr = new Float32("float_proto");
        Array a1 = Array("a", f32_ptr);
	delete f32_ptr;

        CPPUNIT_ASSERT_MESSAGE("The type of a1.var() should be dods_float32", a1.var()->type() == dods_float32_c);
        a1 = *d_cardinal;
        CPPUNIT_ASSERT_MESSAGE("The type of a1.var() should now be dods_int16_c", a1.var()->type() == dods_int16_c);
    }

    void prepend_dim_test()
    {
        Array a1 = Array("a", d_int16);
        Array::Dim_iter i = a1.dim_begin();
        CPPUNIT_ASSERT(a1.dimension_size(i) == 0);
        a1.prepend_dim(2, "dim_a");
        i = a1.dim_begin();
        CPPUNIT_ASSERT(a1.dimension_size(i) == 2);
        a1.prepend_dim(3, "dim_b");
    }

    void prepend_dim_2_test()
    {
        Array a1 = Array("a", d_int16);
        string expected_name[2] = {"dim_b", "myDim"};
        int j = 0;
        D4Dimensions *dims = new D4Dimensions();
        D4Dimension *d = new D4Dimension("dim_b", 2, dims);
        a1.prepend_dim(2, "dim_a");
        a1.prepend_dim(d);
        a1.rename_dim("dim_a", "myDim");
        for (Array::Dim_iter i = a1.dim_begin(); i != a1.dim_end(); i++, j++) {
            CPPUNIT_ASSERT(a1.dimension_name(i) == expected_name[j]);
        }
        delete dims;
        delete d;
    }

    void clear_dims_test()
    {
        Array a1 = Array("a", d_int16);
        a1.prepend_dim(2, "dim_a");
        a1.prepend_dim(3, "dim_b");
        a1.clear_all_dims();
        Array::Dim_iter i = a1.dim_begin();
        CPPUNIT_ASSERT(a1.dimension_size(i) == 0);
    }

    void error_handling_test()
    {
        Array a1 = Array("a", d_int16);
        Array::Dim_iter i = a1.dim_begin();
        string msg;
        CPPUNIT_ASSERT_THROW(a1.dimension_name(i), InternalErr);
        CPPUNIT_ASSERT(!a1.check_semantics(msg));
    }

    void error_handling_2_test()
    {
        Array a1 = Array("a", d_int16);
        a1.append_dim(2, "dim_a");
        Array::Dim_iter i = a1.dim_begin();
        CPPUNIT_ASSERT(a1.dimension_size(i) == 2);
        CPPUNIT_ASSERT_THROW(a1.add_constraint(i, 2, 1, 1), Error);
        CPPUNIT_ASSERT_THROW(a1.add_constraint(i, 0, 1, 2), Error);
        CPPUNIT_ASSERT_THROW(a1.add_constraint(i, 0, 3, 1), Error);
    }

    void duplicate_cardinal_test()
    {
        Array::Dim_iter i = d_cardinal->dim_begin();
        CPPUNIT_ASSERT(d_cardinal->dimension_size(i) == 4);
        dods_int16 *b = new dods_int16[4];
        d_cardinal->buf2val((void**) &b);
        for (int i = 0; i < 4; ++i) {
            CPPUNIT_ASSERT(b[i] == i);
            DBG(cerr << "b[" << i << "]: " << b[i] << endl);
        }
        delete[] b;
        b = 0;

        Array a = *d_cardinal;
        i = a.dim_begin();
        CPPUNIT_ASSERT(a.dimension_size(i) == 4);

        dods_int16 *b2 = new dods_int16[4];
        d_cardinal->buf2val((void**) &b2);
        for (int i = 0; i < 4; ++i) {
            CPPUNIT_ASSERT(b2[i] == i);
            DBG(cerr << "b2[" << i << "]: " << b2[i] << endl);
        }
        delete[] b2;
        b2 = 0;
    }

};

CPPUNIT_TEST_SUITE_REGISTRATION (ArrayTest);

} // namespace libdap

int main(int argc, char *argv[])
{
    return run_tests<libdap::ArrayTest>(argc, argv) ? 0: 1;
}
<|endoftext|>


<commit_before>//===-- LogTest.cpp ---------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Core/Log.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Host/Host.h"
#include "gtest/gtest.h"

using namespace lldb;
using namespace lldb_private;

static std::string GetLogString(uint32_t log_options, const char *format,
                                int arg) {
  std::shared_ptr<StreamString> stream_sp(new StreamString());
  Log log_(stream_sp);
  log_.GetOptions().Reset(log_options);
  Log *log = &log_;
  LLDB_LOG(log, format, arg);
  return stream_sp->GetString();
}

TEST(LogTest, LLDB_LOG_nullptr) {
  Log *log = nullptr;
  LLDB_LOG(log, "{0}", 0); // Shouldn't crash
}

TEST(LogTest, log_options) {
  EXPECT_EQ("Hello World 47\n", GetLogString(0, "Hello World {0}", 47));
  EXPECT_EQ("Hello World 47\n",
            GetLogString(LLDB_LOG_OPTION_THREADSAFE, "Hello World {0}", 47));

  {
    std::string msg =
        GetLogString(LLDB_LOG_OPTION_PREPEND_SEQUENCE, "Hello World {0}", 47);
    int seq_no;
    EXPECT_EQ(1, sscanf(msg.c_str(), "%d Hello World 47", &seq_no));
  }

  EXPECT_EQ(
      "LogTest.cpp:GetLogString                                     Hello "
      "World 47\n",
      GetLogString(LLDB_LOG_OPTION_PREPEND_FILE_FUNCTION, "Hello World {0}", 47));

  EXPECT_EQ(llvm::formatv("[{0}/{1}] Hello World 47\n",
                          Host::GetCurrentProcessID(),
                          Host::GetCurrentThreadID())
                .str(),
            GetLogString(LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD,
                         "Hello World {0}", 47));
}
<commit_msg>Fix windows build for previous commit<commit_after>//===-- LogTest.cpp ---------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "gtest/gtest.h"

#include "lldb/Core/Log.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Host/Host.h"

using namespace lldb;
using namespace lldb_private;

static std::string GetLogString(uint32_t log_options, const char *format,
                                int arg) {
  std::shared_ptr<StreamString> stream_sp(new StreamString());
  Log log_(stream_sp);
  log_.GetOptions().Reset(log_options);
  Log *log = &log_;
  LLDB_LOG(log, format, arg);
  return stream_sp->GetString();
}

TEST(LogTest, LLDB_LOG_nullptr) {
  Log *log = nullptr;
  LLDB_LOG(log, "{0}", 0); // Shouldn't crash
}

TEST(LogTest, log_options) {
  EXPECT_EQ("Hello World 47\n", GetLogString(0, "Hello World {0}", 47));
  EXPECT_EQ("Hello World 47\n",
            GetLogString(LLDB_LOG_OPTION_THREADSAFE, "Hello World {0}", 47));

  {
    std::string msg =
        GetLogString(LLDB_LOG_OPTION_PREPEND_SEQUENCE, "Hello World {0}", 47);
    int seq_no;
    EXPECT_EQ(1, sscanf(msg.c_str(), "%d Hello World 47", &seq_no));
  }

  EXPECT_EQ(
      "LogTest.cpp:GetLogString                                     Hello "
      "World 47\n",
      GetLogString(LLDB_LOG_OPTION_PREPEND_FILE_FUNCTION, "Hello World {0}", 47));

  EXPECT_EQ(llvm::formatv("[{0}/{1}] Hello World 47\n",
                          Host::GetCurrentProcessID(),
                          Host::GetCurrentThreadID())
                .str(),
            GetLogString(LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD,
                         "Hello World {0}", 47));
}
<|endoftext|>


<commit_before>#include "constants.hpp"

namespace mocc {
extern const Surface AllSurfaces[] = { Surface::EAST,
                                           Surface::NORTH,
                                           Surface::WEST,
                                           Surface::SOUTH,
                                           Surface::TOP,
                                           Surface::BOTTOM };

extern const Normal AllNormals[] = { Normal::X_NORM, Normal::Y_NORM,
    Normal::Z_NORM };
}
<commit_msg>Remove extern keywords from constants.cpp<commit_after>#include "constants.hpp"

namespace mocc {
const Surface AllSurfaces[] = { Surface::EAST,
                                           Surface::NORTH,
                                           Surface::WEST,
                                           Surface::SOUTH,
                                           Surface::TOP,
                                           Surface::BOTTOM };

const Normal AllNormals[] = { Normal::X_NORM, Normal::Y_NORM,
    Normal::Z_NORM };
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: attr.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: vg $ $Date: 2007-12-06 10:58:11 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _ATTR_HXX
#define _ATTR_HXX

#include <cppuhelper/implbase1.hxx>
#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/uno/Exception.hpp>
#include <com/sun/star/xml/dom/XNode.hpp>
#include <com/sun/star/xml/dom/XAttr.hpp>
#include "node.hxx"
#include <libxml/tree.h>

using namespace rtl;
using namespace com::sun::star::uno;
using namespace com::sun::star::xml::dom;

namespace DOM
{
    class CAttr : public cppu::ImplInheritanceHelper1< CNode, XAttr >
    {
        friend class CNode;
        friend class CElement;
    private:
        xmlAttrPtr m_aAttrPtr;

    protected:
        CAttr(const xmlAttrPtr aAttrPtr);

    public:
        /**
        Returns the name of this attribute.
        */
        virtual OUString SAL_CALL getName() throw (RuntimeException);

        /**
        The Element node this attribute is attached to or null if this
        attribute is not in use.
        */
        virtual Reference< XElement > SAL_CALL getOwnerElement() throw (RuntimeException);

        /**
        If this attribute was explicitly given a value in the original
        document, this is true; otherwise, it is false.
        */
        virtual sal_Bool SAL_CALL getSpecified()throw (RuntimeException);

        /**
        On retrieval, the value of the attribute is returned as a string.
        */
        virtual OUString SAL_CALL getValue() throw (RuntimeException);

        /**
        Sets the value of the attribute from a string.
        */

        virtual void SAL_CALL setValue(const OUString& value) throw (RuntimeException, DOMException);

        // resolve uno inheritance problems...
        // overrides for XNode base
        virtual OUString SAL_CALL getNodeName()
            throw (RuntimeException);
        virtual OUString SAL_CALL getNodeValue()
            throw (RuntimeException);

    // --- delegation for XNde base.
    virtual Reference< XNode > SAL_CALL appendChild(const Reference< XNode >& newChild)
        throw (RuntimeException, DOMException)
    {
        return CNode::appendChild(newChild);
    }
    virtual Reference< XNode > SAL_CALL cloneNode(sal_Bool deep)
        throw (RuntimeException)
    {
        return CNode::cloneNode(deep);
    }
    virtual Reference< XNamedNodeMap > SAL_CALL getAttributes()
        throw (RuntimeException)
    {
        return CNode::getAttributes();
    }
    virtual Reference< XNodeList > SAL_CALL getChildNodes()
        throw (RuntimeException)
    {
        return CNode::getChildNodes();
    }
    virtual Reference< XNode > SAL_CALL getFirstChild()
        throw (RuntimeException)
    {
        return CNode::getFirstChild();
    }
    virtual Reference< XNode > SAL_CALL getLastChild()
        throw (RuntimeException)
    {
        return CNode::getLastChild();
    }
    virtual OUString SAL_CALL getLocalName()
        throw (RuntimeException)
    {
        return CNode::getLocalName();
    }
    virtual OUString SAL_CALL getNamespaceURI()
        throw (RuntimeException)
    {
        return CNode::getNamespaceURI();
    }
    virtual Reference< XNode > SAL_CALL getNextSibling()
        throw (RuntimeException)
    {
        return CNode::getNextSibling();
    }
    virtual NodeType SAL_CALL getNodeType()
        throw (RuntimeException)
    {
        return CNode::getNodeType();
    }
    virtual Reference< XDocument > SAL_CALL getOwnerDocument()
        throw (RuntimeException)
    {
        return CNode::getOwnerDocument();
    }
    virtual Reference< XNode > SAL_CALL getParentNode()
        throw (RuntimeException)
    {
        return CNode::getParentNode();
    }
    virtual OUString SAL_CALL getPrefix()
        throw (RuntimeException)
    {
        return CNode::getPrefix();
    }
    virtual Reference< XNode > SAL_CALL getPreviousSibling()
        throw (RuntimeException)
    {
        return CNode::getPreviousSibling();
    }
    virtual sal_Bool SAL_CALL hasAttributes()
        throw (RuntimeException)
    {
        return CNode::hasAttributes();
    }
    virtual sal_Bool SAL_CALL hasChildNodes()
        throw (RuntimeException)
    {
        return CNode::hasChildNodes();
    }
    virtual Reference< XNode > SAL_CALL insertBefore(
            const Reference< XNode >& newChild, const Reference< XNode >& refChild)
        throw (RuntimeException, DOMException)
    {
        return CNode::insertBefore(newChild, refChild);
    }
    virtual sal_Bool SAL_CALL isSupported(const OUString& feature, const OUString& ver)
        throw (RuntimeException)
    {
        return CNode::isSupported(feature, ver);
    }
    virtual void SAL_CALL normalize()
        throw (RuntimeException)
    {
        CNode::normalize();
    }
    virtual Reference< XNode > SAL_CALL removeChild(const Reference< XNode >& oldChild)
        throw (RuntimeException, DOMException)
    {
        return CNode::removeChild(oldChild);
    }
    virtual Reference< XNode > SAL_CALL replaceChild(
            const Reference< XNode >& newChild, const Reference< XNode >& oldChild)
        throw (RuntimeException, DOMException)
    {
        return CNode::replaceChild(newChild, oldChild);
    }
    virtual void SAL_CALL setNodeValue(const OUString& nodeValue)
        throw (RuntimeException, DOMException)
    {
        return setValue(nodeValue);
    }
    virtual void SAL_CALL setPrefix(const OUString& prefix)
        throw (RuntimeException, DOMException)
    {
        return CNode::setPrefix(prefix);
    }

    };
}

#endif
<commit_msg>INTEGRATION: CWS custommeta (1.6.42); FILE MERGED 2008/02/01 10:36:08 mst 1.6.42.3: RESYNC: (1.7-1.8); FILE MERGED 2007/12/10 10:28:01 mst 1.6.42.2: RESYNC: (1.6-1.7); FILE MERGED 2007/12/07 14:05:56 mst 1.6.42.1: - unoxml/source/dom/document.{hxx,cxx}:   implement interface css::xml::sax::XSAXSerializable - unoxml/source/dom/*.{hxx,cxx}:   add virtual method saxify() on all subclasses of CNode   add missing implementations of getLocalName()<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: attr.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: obo $ $Date: 2008-02-26 14:46:58 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _ATTR_HXX
#define _ATTR_HXX

#include <cppuhelper/implbase1.hxx>
#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/uno/Exception.hpp>
#include <com/sun/star/xml/dom/XNode.hpp>
#include <com/sun/star/xml/dom/XAttr.hpp>
#include "node.hxx"
#include <libxml/tree.h>

using namespace rtl;
using namespace com::sun::star::uno;
using namespace com::sun::star::xml::dom;

namespace DOM
{
    class CAttr : public cppu::ImplInheritanceHelper1< CNode, XAttr >
    {
        friend class CNode;
        friend class CElement;
    private:
        xmlAttrPtr m_aAttrPtr;

    protected:
        CAttr(const xmlAttrPtr aAttrPtr);

    public:
        /**
        Returns the name of this attribute.
        */
        virtual OUString SAL_CALL getName() throw (RuntimeException);

        /**
        The Element node this attribute is attached to or null if this
        attribute is not in use.
        */
        virtual Reference< XElement > SAL_CALL getOwnerElement() throw (RuntimeException);

        /**
        If this attribute was explicitly given a value in the original
        document, this is true; otherwise, it is false.
        */
        virtual sal_Bool SAL_CALL getSpecified()throw (RuntimeException);

        /**
        On retrieval, the value of the attribute is returned as a string.
        */
        virtual OUString SAL_CALL getValue() throw (RuntimeException);

        /**
        Sets the value of the attribute from a string.
        */

        virtual void SAL_CALL setValue(const OUString& value) throw (RuntimeException, DOMException);

        // resolve uno inheritance problems...
        // overrides for XNode base
        virtual OUString SAL_CALL getNodeName()
            throw (RuntimeException);
        virtual OUString SAL_CALL getNodeValue()
            throw (RuntimeException);
        virtual OUString SAL_CALL getLocalName()
            throw (RuntimeException);

    // --- delegation for XNde base.
    virtual Reference< XNode > SAL_CALL appendChild(const Reference< XNode >& newChild)
        throw (RuntimeException, DOMException)
    {
        return CNode::appendChild(newChild);
    }
    virtual Reference< XNode > SAL_CALL cloneNode(sal_Bool deep)
        throw (RuntimeException)
    {
        return CNode::cloneNode(deep);
    }
    virtual Reference< XNamedNodeMap > SAL_CALL getAttributes()
        throw (RuntimeException)
    {
        return CNode::getAttributes();
    }
    virtual Reference< XNodeList > SAL_CALL getChildNodes()
        throw (RuntimeException)
    {
        return CNode::getChildNodes();
    }
    virtual Reference< XNode > SAL_CALL getFirstChild()
        throw (RuntimeException)
    {
        return CNode::getFirstChild();
    }
    virtual Reference< XNode > SAL_CALL getLastChild()
        throw (RuntimeException)
    {
        return CNode::getLastChild();
    }
    virtual OUString SAL_CALL getNamespaceURI()
        throw (RuntimeException)
    {
        return CNode::getNamespaceURI();
    }
    virtual Reference< XNode > SAL_CALL getNextSibling()
        throw (RuntimeException)
    {
        return CNode::getNextSibling();
    }
    virtual NodeType SAL_CALL getNodeType()
        throw (RuntimeException)
    {
        return CNode::getNodeType();
    }
    virtual Reference< XDocument > SAL_CALL getOwnerDocument()
        throw (RuntimeException)
    {
        return CNode::getOwnerDocument();
    }
    virtual Reference< XNode > SAL_CALL getParentNode()
        throw (RuntimeException)
    {
        return CNode::getParentNode();
    }
    virtual OUString SAL_CALL getPrefix()
        throw (RuntimeException)
    {
        return CNode::getPrefix();
    }
    virtual Reference< XNode > SAL_CALL getPreviousSibling()
        throw (RuntimeException)
    {
        return CNode::getPreviousSibling();
    }
    virtual sal_Bool SAL_CALL hasAttributes()
        throw (RuntimeException)
    {
        return CNode::hasAttributes();
    }
    virtual sal_Bool SAL_CALL hasChildNodes()
        throw (RuntimeException)
    {
        return CNode::hasChildNodes();
    }
    virtual Reference< XNode > SAL_CALL insertBefore(
            const Reference< XNode >& newChild, const Reference< XNode >& refChild)
        throw (RuntimeException, DOMException)
    {
        return CNode::insertBefore(newChild, refChild);
    }
    virtual sal_Bool SAL_CALL isSupported(const OUString& feature, const OUString& ver)
        throw (RuntimeException)
    {
        return CNode::isSupported(feature, ver);
    }
    virtual void SAL_CALL normalize()
        throw (RuntimeException)
    {
        CNode::normalize();
    }
    virtual Reference< XNode > SAL_CALL removeChild(const Reference< XNode >& oldChild)
        throw (RuntimeException, DOMException)
    {
        return CNode::removeChild(oldChild);
    }
    virtual Reference< XNode > SAL_CALL replaceChild(
            const Reference< XNode >& newChild, const Reference< XNode >& oldChild)
        throw (RuntimeException, DOMException)
    {
        return CNode::replaceChild(newChild, oldChild);
    }
    virtual void SAL_CALL setNodeValue(const OUString& nodeValue)
        throw (RuntimeException, DOMException)
    {
        return setValue(nodeValue);
    }
    virtual void SAL_CALL setPrefix(const OUString& prefix)
        throw (RuntimeException, DOMException)
    {
        return CNode::setPrefix(prefix);
    }

    };
}

#endif
<|endoftext|>