// Clear the list.
void ListWrapper::clear(QObject *qobj, QList<QObject *> *qlist)
{
    qlist->clear();

    ListWrapper *lw = findWrapper(qobj, qlist);

    if (!lw || PyList_SetSlice(lw->_py_list, 0, PyList_GET_SIZE(lw->_py_list), NULL) < 0)
        PyErr_Print();
}
// Append to the list.
void ListWrapper::append(QObject *qobj, QList<QObject *> *qlist, QObject *el)
{
    qlist->append(el);

    ListWrapper *lw = findWrapper(qobj, qlist);

    if (lw)
    {
        PyObject *el_obj = sipConvertFromType(el, sipType_QObject, 0);

        if (!el_obj || PyList_Append(lw->_py_list, el_obj) < 0)
        {
            PyErr_Print();
        }

        Py_XDECREF(el_obj);
    }
    else
    {
        PyErr_Print();
    }
}
Example #3
0
static int
traceProgram(trace::API api,
             char * const *argv,
             const char *output,
             bool verbose,
             bool debug)
{
    const char *wrapperFilename;
    std::vector<const char *> args;
    int status = 1;

    /*
     * TODO: simplify code
     */

    bool useInject = false;
    switch (api) {
    case trace::API_GL:
        wrapperFilename = GL_TRACE_WRAPPER;
        break;
#ifdef EGL_TRACE_WRAPPER
    case trace::API_EGL:
        wrapperFilename = EGL_TRACE_WRAPPER;
        break;
#endif
#ifdef _WIN32
    case trace::API_D3D7:
        wrapperFilename = "ddraw.dll";
        break;
    case trace::API_D3D8:
        wrapperFilename = "d3d8.dll";
        break;
    case trace::API_D3D9:
        wrapperFilename = "d3d9.dll";
        break;
    case trace::API_DXGI:
        wrapperFilename = "dxgitrace.dll";
        useInject = true;
        break;
    case trace::API_D2D1:
        wrapperFilename = "d2d1trace.dll";
        useInject = true;
        break;
#endif
    default:
        std::cerr << "error: unsupported API\n";
        return 1;
    }

    os::String wrapperPath = findWrapper(wrapperFilename, verbose);
    if (!wrapperPath.length()) {
        std::cerr << "error: failed to find " << wrapperFilename << " wrapper (rerun with -v option for more details)\n";
        goto exit;
    }

#if defined(_WIN32)
    /*
     * Use DLL injection method on Windows, even for APIs that don't stricly
     * need it.
     */
    useInject = true;

    if (useInject) {
        args.push_back("inject");
        if (debug) {
            args.push_back("-d");
        }
        args.push_back("-D");
        args.push_back(wrapperPath);
        args.push_back("--");
    } else {
        /* On Windows copy the wrapper to the program directory.
         */
        if (!copyWrapper(wrapperPath, argv[0], verbose)) {
            goto exit;
        }
    }
#else  /* !_WIN32 */
    (void)useInject;
#endif /* !_WIN32 */

#if defined(__APPLE__)
    /* On Mac OS X, using DYLD_LIBRARY_PATH, we actually set the
     * parent directory, not the file. */
    wrapperPath.trimFilename();
    wrapperPath.trimFilename();
#endif

    /*
     * Spawn child process.
     */

    {
#if defined(TRACE_VARIABLE)
        const char *oldEnvVarValue = getenv(TRACE_VARIABLE);
        if (oldEnvVarValue) {
            wrapperPath.append(OS_PATH_SEP);
            wrapperPath.append(oldEnvVarValue);
        }

        std::string ex;
        if (debug) {
#if defined(__APPLE__)
            bool lldb = true;
#else
            bool lldb = false;
#endif

            if (lldb) {
                /*
                 * Debug with LLDB.
                 *
                 * See also http://lldb.llvm.org/lldb-gdb.html
                 */

                char scriptFileName[] = "/tmp/apitrace.XXXXXX";
                int scriptFD = mkstemp(scriptFileName);
                if (scriptFD < 0) {
                    std::cerr << "error: failed to create temporary lldb script file\n";
                    exit(1);
                }

                FILE *scriptStream = fdopen(scriptFD, "w");
                fprintf(scriptStream, "env " TRACE_VARIABLE "='%s'\n", wrapperPath.str());
                fclose(scriptStream);

                args.push_back("lldb");
                args.push_back("-s");
                args.push_back(scriptFileName);
                args.push_back("--");
            } else {
                /*
                 * Debug with GDB.
                 */

                ex = "set exec-wrapper env " TRACE_VARIABLE "='";
                ex.append(wrapperPath.str());
                ex.append("'");

                args.push_back("gdb");
                args.push_back("--ex");
                args.push_back(ex.c_str());
                args.push_back("--args");
            }

            os::unsetEnvironment(TRACE_VARIABLE);
        } else {
            /* FIXME: Don't modify our (ie parent) environment */
            os::setEnvironment(TRACE_VARIABLE, wrapperPath.str());
        }

        if (verbose) {
            std::cerr << TRACE_VARIABLE << "=" << wrapperPath.str() << "\n";
        }
#endif /* TRACE_VARIABLE */

        if (output) {
            os::setEnvironment("TRACE_FILE", output);
        }

        for (char * const * arg = argv; *arg; ++arg) {
            args.push_back(*arg);
        }

        if (verbose) {
            const char *sep = "";
            for (unsigned i = 0; i < args.size(); ++i) {
                const char *quote;
                if (strchr(args[i], ' ') != NULL) {
                    quote = "\"";
                } else {
                    quote = "";
                }
                std::cerr << sep << quote << args[i] << quote;
                sep = " ";
            }
            std::cerr << "\n";
        }

        args.push_back(NULL);

        status = os::execute((char * const *)&args[0]);

#if defined(TRACE_VARIABLE)
        if (oldEnvVarValue) {
            os::setEnvironment(TRACE_VARIABLE, oldEnvVarValue);
        } else {
            os::unsetEnvironment(TRACE_VARIABLE);
        }
#endif
    }

exit:
#if defined(_WIN32)
    if (!useInject) {
        os::String tmpWrapper(argv[0]);
        tmpWrapper.trimFilename();
        tmpWrapper.join(wrapperFilename);
        os::removeFile(tmpWrapper);
    }
#endif

    if (output) {
        os::unsetEnvironment("TRACE_FILE");
    }
    
    return status;

}
Example #4
0
int
traceProgram(API api,
             char * const *argv,
             const char *output,
             bool verbose)
{
    const char *wrapperFilename;

    /*
     * TODO: simplify code
     */

    switch (api) {
    case API_GL:
        wrapperFilename = GL_TRACE_WRAPPER;
        break;
#ifdef EGL_TRACE_WRAPPER
    case API_EGL:
        wrapperFilename = EGL_TRACE_WRAPPER;
        break;
#endif
#ifdef _WIN32
    case API_D3D7:
        wrapperFilename = "ddraw.dll";
        break;
    case API_D3D8:
        wrapperFilename = "d3d8.dll";
        break;
    case API_D3D9:
        wrapperFilename = "d3d9.dll";
        break;
    case API_D3D10:
        wrapperFilename = "d3d10.dll";
        break;
    case API_D3D10_1:
        wrapperFilename = "d3d10_1.dll";
        break;
    case API_D3D11:
        wrapperFilename = "d3d11.dll";
        break;
#endif
    default:
        std::cerr << "error: unsupported API\n";
        return 1;
    }

    os::String wrapperPath = findWrapper(wrapperFilename);

    if (!wrapperPath.length()) {
        std::cerr << "error: failed to find " << wrapperFilename << "\n";
        return 1;
    }

#if defined(_WIN32)
    /* On Windows copy the wrapper to the program directory.
     */
    os::String tmpWrapper(argv[0]);
    tmpWrapper.trimFilename();
    tmpWrapper.join(wrapperFilename);

    if (verbose) {
        std::cerr << wrapperPath << " -> " << tmpWrapper << "\n";
    }

    if (tmpWrapper.exists()) {
        std::cerr << "error: not overwriting " << tmpWrapper << "\n";
        return 1;
    }

    if (!os::copyFile(wrapperPath, tmpWrapper, false)) {
        std::cerr << "error: failed to copy " << wrapperPath << " into " << tmpWrapper << "\n";
        return 1;
    }
#endif /* _WIN32 */

#if defined(__APPLE__)
    /* On Mac OS X, using DYLD_LIBRARY_PATH, we actually set the
     * directory, not the file. */
    wrapperPath.trimFilename();
#endif

#if defined(TRACE_VARIABLE)
    if (verbose) {
        std::cerr << TRACE_VARIABLE << "=" << wrapperPath.str() << "\n";
    }
    /* FIXME: Don't modify the current environment */
    os::setEnvironment(TRACE_VARIABLE, wrapperPath.str());
#endif /* TRACE_VARIABLE */

    if (output) {
        os::setEnvironment("TRACE_FILE", output);
    }

    if (verbose) {
        const char *sep = "";
        for (char * const * arg = argv; *arg; ++arg) {
            std::cerr << *arg << sep;
            sep = " ";
        }
        std::cerr << "\n";
    }

    int status = os::execute(argv);

#if defined(TRACE_VARIABLE)
    os::unsetEnvironment(TRACE_VARIABLE);
#endif
#if defined(_WIN32)
    os::removeFile(tmpWrapper);
#endif

    if (output) {
        os::unsetEnvironment("TRACE_FILE");
    }
    
    return status;

}