Exemple #1
0
int ApiGen::genDecoderHeader(const std::string &filename)
{
    FILE *fp = fopen(filename.c_str(), "wt");
    if (fp == NULL) {
        perror(filename.c_str());
        return -1;
    }

    printHeader(fp);
    std::string classname = m_basename + "_decoder_context_t";

    fprintf(fp, "\n#ifndef GUARD_%s\n", classname.c_str());
    fprintf(fp, "#define GUARD_%s\n\n", classname.c_str());

    fprintf(fp, "#include \"IOStream.h\" \n");
    fprintf(fp, "#include \"%s_%s_context.h\"\n\n\n", m_basename.c_str(), sideString(SERVER_SIDE));

    for (size_t i = 0; i < m_decoderHeaders.size(); i++) {
        fprintf(fp, "#include %s\n", m_decoderHeaders[i].c_str());
    }
    fprintf(fp, "\n");

    fprintf(fp, "struct %s : public %s_%s_context_t {\n\n",
            classname.c_str(), m_basename.c_str(), sideString(SERVER_SIDE));
    fprintf(fp, "\tsize_t decode(void *buf, size_t bufsize, IOStream *stream);\n");
    fprintf(fp, "\n};\n\n");
    fprintf(fp, "#endif  // GUARD_%s\n", classname.c_str());

    fclose(fp);
    return 0;
}
Exemple #2
0
int ApiGen::genContextImpl(const std::string &filename, SideType side)
{
    FILE *fp = fopen(filename.c_str(), "wt");
    if (fp == NULL) {
        perror(filename.c_str());
        return -1;
    }
    printHeader(fp);

    std::string classname = m_basename + "_" + sideString(side) + "_context_t";
    size_t n = size();
    fprintf(fp, "\n\n#include <string.h>\n");
    fprintf(fp, "#include \"%s_%s_context.h\"\n\n\n", m_basename.c_str(), sideString(side));
    fprintf(fp, "#include <stdio.h>\n\n");

    // init function;
    fprintf(fp, "int %s::initDispatchByName(void *(*getProc)(const char *, void *userData), void *userData)\n{\n", classname.c_str());
    for (size_t i = 0; i < n; i++) {
        EntryPoint *e = &at(i);
        fprintf(fp, "\t%s = (%s_%s_proc_t) getProc(\"%s\", userData);\n",
                e->name().c_str(),
                e->name().c_str(),
                sideString(side),
                e->name().c_str());
    }
    fprintf(fp, "\treturn 0;\n");
    fprintf(fp, "}\n\n");
    fclose(fp);
    return 0;
}
Exemple #3
0
int ApiGen::genFuncTable(const std::string &filename, SideType side)
{
    FILE *fp = fopen(filename.c_str(), "wt");
    if (fp == NULL) {
        perror(filename.c_str());
        return -1;
    }
    printHeader(fp);

    fprintf(fp, "#ifndef __%s_%s_ftable_t_h\n", m_basename.c_str(), sideString(side));
    fprintf(fp, "#define __%s_%s_ftable_t_h\n", m_basename.c_str(), sideString(side));
    fprintf(fp, "\n\n");
    fprintf(fp, "static const struct _%s_funcs_by_name {\n", m_basename.c_str());
    fprintf(fp,
            "\tconst char *name;\n" \
            "\tvoid *proc;\n" \
            "} %s_funcs_by_name[] = {\n", m_basename.c_str());


    for (size_t i = 0; i < size(); i++) {
        EntryPoint *e = &at(i);
        if (e->notApi()) continue;
        fprintf(fp, "\t{\"%s\", (void*)%s},\n", e->name().c_str(), e->name().c_str());
    }
    fprintf(fp, "};\n");
    fprintf(fp, "static const int %s_num_funcs = sizeof(%s_funcs_by_name) / sizeof(struct _%s_funcs_by_name);\n",
            m_basename.c_str(), m_basename.c_str(), m_basename.c_str());
    fprintf(fp, "\n\n#endif\n");
    return 0;
}
Exemple #4
0
int ApiGen::genProcTypes(const std::string &filename, SideType side)
{
    FILE *fp = fopen(filename.c_str(), "wt");
    if (fp == NULL) {
        perror(filename.c_str());
        return -1;
    }
    printHeader(fp);

    const char* basename = m_basename.c_str();

    fprintf(fp, "#ifndef __%s_%s_proc_t_h\n", basename, sideString(side));
    fprintf(fp, "#define __%s_%s_proc_t_h\n", basename, sideString(side));
    fprintf(fp, "\n\n");
    fprintf(fp, "\n#include \"%s_types.h\"\n",basename);
    fprintf(fp, "#ifndef %s_APIENTRY\n",basename);
    fprintf(fp, "#define %s_APIENTRY \n",basename);
    fprintf(fp, "#endif\n");


    for (size_t i = 0; i < size(); i++) {
        EntryPoint *e = &at(i);

        fprintf(fp, "typedef ");
        e->retval().printType(fp);
        fprintf(fp, " (%s_APIENTRY *%s_%s_proc_t) (", basename, e->name().c_str(), sideString(side));
        if (side == CLIENT_SIDE) {
            fprintf(fp, "void * ctx");
        }
        if (e->customDecoder() && side == SERVER_SIDE) {
            fprintf(fp, "void *ctx");
        }

        VarsArray & evars = e->vars();
        size_t n = evars.size();

        for (size_t j = 0; j < n; j++) {
            if (!evars[j].isVoid()) {
                if (j != 0 || side == CLIENT_SIDE || (side == SERVER_SIDE && e->customDecoder())) fprintf(fp, ", ");
                evars[j].printType(fp);
            }
        }
        fprintf(fp, ");\n");
    }
    fprintf(fp, "\n\n#endif\n");
    return 0;
}
Exemple #5
0
/// Add BC_PRESSURE boundary conditions to all faces on a given side.
/// The grid must have a logical cartesian structure, and grid
/// faces must be tagged (i.e. grid.cell_facetag must be
/// non-null). Only the set of faces adjacent to cells with
/// minimum/maximum I/J/K coordinate (depending on side) are
/// considered.
void FlowBCManager::pressureSide(const UnstructuredGrid& grid,
                                 const Side side,
                                 const double pressure)
{
    std::vector<int> faces;
    findSideFaces(grid, side, faces);
    int ok = flow_conditions_append_multi(BC_PRESSURE, faces.size(), &faces[0], pressure, bc_);
    if (!ok) {
        THROW("Failed to append pressure boundary conditions for side " << sideString(side));
    }
}
Exemple #6
0
int ApiGen::genContext(const std::string & filename, SideType side)
{
    FILE *fp = fopen(filename.c_str(), "wt");
    if (fp == NULL) {
        perror(filename.c_str());
        return -1;
    }
    printHeader(fp);

    fprintf(fp, "#ifndef __%s_%s_context_t_h\n", m_basename.c_str(), sideString(side));
    fprintf(fp, "#define __%s_%s_context_t_h\n", m_basename.c_str(), sideString(side));

    //  fprintf(fp, "\n#include \"%s_types.h\"\n", m_basename.c_str());
    fprintf(fp, "\n#include \"%s_%s_proc.h\"\n", m_basename.c_str(), sideString(side));

    StringVec & contextHeaders = side == CLIENT_SIDE ? m_clientContextHeaders : m_serverContextHeaders;
    for (size_t i = 0; i < contextHeaders.size(); i++) {
        fprintf(fp, "#include %s\n", contextHeaders[i].c_str());
    }
    fprintf(fp, "\n");

    fprintf(fp, "\nstruct %s_%s_context_t {\n\n", m_basename.c_str(), sideString(side));
    for (size_t i = 0; i < size(); i++) {
        EntryPoint *e = &at(i);
        fprintf(fp, "\t%s_%s_proc_t %s;\n", e->name().c_str(), sideString(side), e->name().c_str());
    }

    // virtual destructor
    fprintf(fp, "\t virtual ~%s_%s_context_t() {}\n", m_basename.c_str(), sideString(side));
    // accessor
    if (side == CLIENT_SIDE || side == WRAPPER_SIDE) {
        fprintf(fp, "\n\ttypedef %s_%s_context_t *CONTEXT_ACCESSOR_TYPE(void);\n",
                m_basename.c_str(), sideString(side));
        fprintf(fp, "\tstatic void setContextAccessor(CONTEXT_ACCESSOR_TYPE *f);\n");
    }

    // init function
    fprintf(fp, "\tint initDispatchByName( void *(*getProc)(const char *name, void *userData), void *userData);\n");

    //client site set error virtual func
    if (side == CLIENT_SIDE) {
        fprintf(fp, "\tvirtual void setError(unsigned int  error){ (void)error; };\n");
        fprintf(fp, "\tvirtual unsigned int getError(){ return 0; };\n");
    }

    fprintf(fp, "};\n");

    fprintf(fp, "\n#endif\n");
    fclose(fp);
    return 0;
}
Exemple #7
0
/// Add BC_FLUX_TOTVOL boundary conditions to all faces on a given side.
/// The grid must have a logical cartesian structure, and grid
/// faces must be tagged (i.e. grid.cell_facetag must be
/// non-null). Only the set of faces adjacent to cells with
/// minimum/maximum I/J/K coordinate (depending on side) are
/// considered.
/// The flux specified is taken to be the total flux through
/// the side, each individual face receiving a part of the
/// total flux in proportion to its area, so that all faces
/// will have identical normal velocities.
void FlowBCManager::fluxSide(const UnstructuredGrid& grid,
                             const Side side,
                             const double flux)
{
    // Find side faces.
    std::vector<int> faces;
    findSideFaces(grid, side, faces);

    // Compute total area of faces.
    double tot_area = 0.0;
    for (int fi = 0; fi < int(faces.size()); ++fi) {
        tot_area += grid.face_areas[faces[fi]];
    }

    // Append flux conditions for all the faces individually.
    for (int fi = 0; fi < int(faces.size()); ++fi) {
        const double face_flux = flux * grid.face_areas[faces[fi]] / tot_area;
        int ok = flow_conditions_append(BC_FLUX_TOTVOL, faces[fi], face_flux, bc_);
        if (!ok) {
            THROW("Failed to append flux boundary conditions for face " << faces[fi] << " on side " << sideString(side));
        }
    }
}
Exemple #8
0
int ApiGen::genEncoderImpl(const std::string &filename)
{
    FILE *fp = fopen(filename.c_str(), "wt");
    if (fp == NULL) {
        perror(filename.c_str());
        return -1;
    }

    printHeader(fp);
    fprintf(fp, "\n\n#include <string.h>\n");
    fprintf(fp, "#include \"%s_opcodes.h\"\n\n", m_basename.c_str());
    fprintf(fp, "#include \"%s_enc.h\"\n\n\n", m_basename.c_str());
    fprintf(fp, "#include <stdio.h>\n\n");
    fprintf(fp, "namespace {\n\n");

    // unsupport printout
    fprintf(fp,
            "void enc_unsupported()\n"
            "{\n"
            "\tALOGE(\"Function is unsupported\\n\");\n"
            "}\n\n");

    // entry points;
    std::string classname = m_basename + "_encoder_context_t";

    size_t n = size();
    for (size_t i = 0; i < n; i++) {
        EntryPoint *e = &at(i);

        if (e->unsupported()) continue;


        e->print(fp, true, "_enc", /* classname + "::" */"", "void *self");
        fprintf(fp, "{\n");

//      fprintf(fp, "\n\tDBG(\">>>> %s\\n\");\n", e->name().c_str());
        fprintf(fp, "\n\t%s *ctx = (%s *)self;\n",
                classname.c_str(),
                classname.c_str());
        fprintf(fp, "\tIOStream *stream = ctx->m_stream;\n\n");
        VarsArray & evars = e->vars();
        size_t  maxvars = evars.size();
        size_t  j;

        char    buff[256];

        // Define the __size_XXX variables that contain the size of data
        // associated with pointers.
        for (j = 0; j < maxvars; j++) {
            Var& var = evars[j];

            if (!var.isPointer())
                continue;

            const char* varname = var.name().c_str();
            fprintf(fp, "\tconst unsigned int __size_%s = ", varname);

            getVarEncodingSizeExpression(var, e, buff, sizeof(buff));
            fprintf(fp, "%s;\n", buff);
        }

#if WITH_LARGE_SUPPORT
        // We need to take care of 'isLarge' variable in a special way
        // Anything before an isLarge variable can be packed into a single
        // buffer, which is then commited. Each isLarge variable is a pointer
        // to data that can be written to directly through the pipe, which
        // will be instant when using a QEMU pipe

        size_t  nvars   = 0;
        size_t  npointers = 0;

        // First, compute the total size, 8 bytes for the opcode + payload size
        fprintf(fp, "\t unsigned char *ptr;\n");
        fprintf(fp, "\t const size_t packetSize = 8");

        for (j = 0; j < maxvars; j++) {
            fprintf(fp, " + ");
            npointers += writeVarEncodingSize(evars[j], fp);
        }
        if (npointers > 0) {
            fprintf(fp, " + %zu*4", npointers);
        }
        fprintf(fp, ";\n");

        // We need to divide the packet into fragments. Each fragment contains
        // either copied arguments to a temporary buffer, or direct writes for
        // large variables.
        //
        // The first fragment must also contain the opcode+payload_size
        //
        nvars = 0;
        while (nvars < maxvars || maxvars == 0) {

            // Skip over non-large fields
            for (j = nvars; j < maxvars; j++) {
                if (evars[j].isLarge())
                    break;
            }

            // Write a fragment if needed.
            if (nvars == 0 || j > nvars) {
                const char* plus = "";

                if (nvars == 0 && j == maxvars) {
                    // Simple shortcut for the common case where we don't have large variables;
                    fprintf(fp, "\tptr = stream->alloc(packetSize);\n");

                } else {
                    // allocate buffer from the stream until the first large variable
                    fprintf(fp, "\tptr = stream->alloc(");
                    plus = "";

                    if (nvars == 0) {
                        fprintf(fp,"8");
                        plus = " + ";
                    }
                    if (j > nvars) {
                        npointers = 0;
                        for (j = nvars; j < maxvars && !evars[j].isLarge(); j++) {
                            fprintf(fp, "%s", plus);
                            plus = " + ";
                            npointers += writeVarEncodingSize(evars[j], fp);
                        }
                        if (npointers > 0) {
                            fprintf(fp, "%s%zu*4", plus, npointers);
                            plus = " + ";
                        }
                    }
                    fprintf(fp,");\n");
                }

                // encode packet header if needed.
                if (nvars == 0) {
                    fprintf(fp, "\tint tmp = OP_%s;memcpy(ptr, &tmp, 4); ptr += 4;\n",  e->name().c_str());
                    fprintf(fp, "\tmemcpy(ptr, &packetSize, 4);  ptr += 4;\n\n");
                }

                if (maxvars == 0)
                    break;

                // encode non-large fields in this fragment
                for (j = nvars; j < maxvars && !evars[j].isLarge(); j++) {
                    writeVarEncodingExpression(evars[j],fp);
                }

                // Ensure the fragment is commited if it is followed by a large variable
                if (j < maxvars) {
                    fprintf(fp, "\tstream->flush();\n");
                }
            }

            // If we have one or more large variables, write them directly.
            // As size + data
            for ( ; j < maxvars && evars[j].isLarge(); j++) {
                writeVarLargeEncodingExpression(evars[j], fp);
            }

            nvars = j;
        }

#else /* !WITH_LARGE_SUPPORT */
        size_t nvars = evars.size();
        size_t npointers = 0;
        fprintf(fp, "\t const size_t packetSize = 8");
        for (size_t j = 0; j < nvars; j++) {
            npointers += getVarEncodingSizeExpression(evars[j],e,buff,sizeof(buff));
            fprintf(fp, " + %s", buff);
        }
        fprintf(fp, " + %u * 4;\n", (unsigned int) npointers);

        // allocate buffer from the stream;
        fprintf(fp, "\t unsigned char *ptr = stream->alloc(packetSize);\n\n");

        // encode into the stream;
        fprintf(fp, "\tint tmp = OP_%s; memcpy(ptr, &tmp, 4); ptr += 4;\n",  e->name().c_str());
        fprintf(fp, "\tmemcpy(ptr, &packetSize, 4);  ptr += 4;\n\n");

        // out variables
        for (size_t j = 0; j < nvars; j++) {
            writeVarEncodingExpression(evars[j], fp);
        }
#endif /* !WITH_LARGE_SUPPORT */

        // in variables;
        for (size_t j = 0; j < nvars; j++) {
            if (evars[j].isPointer()) {
                Var::PointerDir dir = evars[j].pointerDir();
                if (dir == Var::POINTER_INOUT || dir == Var::POINTER_OUT) {
                    const char* varname = evars[j].name().c_str();
                    if (evars[j].nullAllowed()) {
                        fprintf(fp, "\tif (%s != NULL) ",varname);
                    } else {
                        fprintf(fp, "\t");
                    }
                    fprintf(fp, "stream->readback(%s, __size_%s);\n",
                            varname, varname);
                }
            }
        }
//XXX       fprintf(fp, "\n\tDBG(\"<<<< %s\\n\");\n", e->name().c_str());

        // todo - return value for pointers
        if (e->retval().isPointer()) {
            fprintf(stderr, "WARNING: %s : return value of pointer is unsupported\n",
                    e->name().c_str());
            if (e->flushOnEncode()) {
                fprintf(fp, "\tstream->flush();\n");
            }
            fprintf(fp, "\t return NULL;\n");
        } else if (e->retval().type()->name() != "void") {
            fprintf(fp, "\n\t%s retval;\n", e->retval().type()->name().c_str());
            fprintf(fp, "\tstream->readback(&retval, %u);\n",(unsigned) e->retval().type()->bytes());
            fprintf(fp, "\treturn retval;\n");
        } else if (e->flushOnEncode()) {
            fprintf(fp, "\tstream->flush();\n");
        }
        fprintf(fp, "}\n\n");
    }

    fprintf(fp, "}  // namespace\n\n");

    // constructor
    fprintf(fp, "%s::%s(IOStream *stream)\n{\n", classname.c_str(), classname.c_str());
    fprintf(fp, "\tm_stream = stream;\n\n");

    for (size_t i = 0; i < n; i++) {
        EntryPoint *e = &at(i);
        if (e->unsupported()) {
            fprintf(fp,
                    "\tthis->%s = (%s_%s_proc_t) &enc_unsupported;\n",
                    e->name().c_str(),
                    e->name().c_str(),
                    sideString(CLIENT_SIDE));
        } else {
            fprintf(fp,
                    "\tthis->%s = &%s_enc;\n",
                    e->name().c_str(),
                    e->name().c_str());
        }
    }
    fprintf(fp, "}\n\n");

    fclose(fp);
    return 0;
}
Exemple #9
0
int ApiGen::genEntryPoints(const std::string & filename, SideType side)
{

    if (side != CLIENT_SIDE && side != WRAPPER_SIDE) {
        fprintf(stderr, "Entry points are only defined for Client and Wrapper components\n");
        return -999;
    }


    FILE *fp = fopen(filename.c_str(), "wt");
    if (fp == NULL) {
        perror(filename.c_str());
        return errno;
    }

    printHeader(fp);
    fprintf(fp, "#include <stdio.h>\n");
    fprintf(fp, "#include <stdlib.h>\n");
    fprintf(fp, "#include \"%s_%s_context.h\"\n", m_basename.c_str(), sideString(side));
    fprintf(fp, "\n");

    fprintf(fp, "#ifndef GL_TRUE\n");
    fprintf(fp, "extern \"C\" {\n");

    for (size_t i = 0; i < size(); i++) {
        fprintf(fp, "\t");
        at(i).print(fp, false);
        fprintf(fp, ";\n");
    }
    fprintf(fp, "};\n\n");
    fprintf(fp, "#endif\n");

    fprintf(fp, "#ifndef GET_CONTEXT\n");
    fprintf(fp, "static %s_%s_context_t::CONTEXT_ACCESSOR_TYPE *getCurrentContext = NULL;\n",
            m_basename.c_str(), sideString(side));

    fprintf(fp,
            "void %s_%s_context_t::setContextAccessor(CONTEXT_ACCESSOR_TYPE *f) { getCurrentContext = f; }\n",
            m_basename.c_str(), sideString(side));
    fprintf(fp, "#define GET_CONTEXT %s_%s_context_t * ctx = getCurrentContext()\n",
            m_basename.c_str(), sideString(side));
    fprintf(fp, "#endif\n\n");


    for (size_t i = 0; i < size(); i++) {
        EntryPoint *e = &at(i);
        e->print(fp);
        fprintf(fp, "{\n");
        fprintf(fp, "\tGET_CONTEXT;\n");

        bool shouldReturn = !e->retval().isVoid();
        bool shouldCallWithContext = (side == CLIENT_SIDE);
        //param check
        if (shouldCallWithContext) {
            for (size_t j=0; j<e->vars().size(); j++) {
                if (e->vars()[j].paramCheckExpression() != "")
                    fprintf(fp, "\t%s\n", e->vars()[j].paramCheckExpression().c_str());
            }
        }
        fprintf(fp, "\t%sctx->%s(%s",
                shouldReturn ? "return " : "",
                e->name().c_str(),
                shouldCallWithContext ? "ctx" : "");
        size_t nvars = e->vars().size();

        for (size_t j = 0; j < nvars; j++) {
            if (!e->vars()[j].isVoid()) {
                fprintf(fp, "%s %s",
                        j != 0 || shouldCallWithContext ? "," : "",
                        e->vars()[j].name().c_str());
            }
        }
        fprintf(fp, ");\n");
        fprintf(fp, "}\n\n");
    }
    fclose(fp);
    return 0;
}