Exemple #1
0
static void emit_c_encoded_array_size(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    char *tn = ls->structname->lctypename;
    char *tn_ = dots_to_underscores(tn);

    emit(0,"int __%s_encoded_array_size(const %s *p, int elements)", tn_, tn_);
    emit(0,"{");
    emit(1,"int size = 0, element;");
    emit(1,    "for (element = 0; element < elements; element++) {");
    emit(0,"");
    for (unsigned int m = 0; m < g_ptr_array_size(ls->members); m++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, m);

        emit_c_array_loops_start(lcm, f, lm, "p", FLAG_NONE);

        int indent = 2+imax(0, g_ptr_array_size(lm->dimensions) - 1);
        emit(indent, "size += __%s_encoded_array_size(%s, %s);",
             dots_to_underscores (lm->type->lctypename),
             make_accessor(lm, "p", g_ptr_array_size(lm->dimensions) - 1),
             make_array_size(lm, "p", g_ptr_array_size(lm->dimensions) - 1));

        emit_c_array_loops_end(lcm, f, lm, "p", FLAG_NONE);
        emit(0,"");
    }
    emit(1,"}");
    emit(1, "return size;");
    emit(0,"}");
    emit(0,"");
}
Exemple #2
0
static void emit_c_decode_array(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    char *tn = ls->structname->lctypename;
    char *tn_ = dots_to_underscores(tn);

    emit(0,"int __%s_decode_array(const void *buf, int offset, int maxlen, %s *p, int elements)", tn_, tn_);
    emit(0,"{");
    emit(1,    "int pos = 0, thislen, element;");
    emit(0,"");
    emit(1,    "for (element = 0; element < elements; element++) {");
    emit(0,"");
    for (unsigned int m = 0; m < g_ptr_array_size(ls->members); m++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, m);

        emit_c_array_loops_start(lcm, f, lm, "p", lcm_is_constant_size_array(lm) ? FLAG_NONE : FLAG_EMIT_MALLOCS);

        int indent = 2+imax(0, g_ptr_array_size(lm->dimensions) - 1);
        emit(indent, "thislen = __%s_decode_array(buf, offset + pos, maxlen - pos, %s, %s);",
             dots_to_underscores (lm->type->lctypename),
             make_accessor(lm, "p", g_ptr_array_size(lm->dimensions) - 1),
             make_array_size(lm, "p", g_ptr_array_size(lm->dimensions) - 1));
        emit(indent, "if (thislen < 0) return thislen; else pos += thislen;");

        emit_c_array_loops_end(lcm, f, lm, "p", FLAG_NONE);
        emit(0,"");
    }
    emit(1,   "}");
    emit(1, "return pos;");
    emit(0,"}");
    emit(0,"");
}
Exemple #3
0
static void emit_c_clone_array(lcmgen_t *lcm, FILE *f, lcm_struct_t *lr)
{
    char *tn = lr->structname->lctypename;
    char *tn_ = dots_to_underscores(tn);

    emit(0,"int __%s_clone_array(const %s *p, %s *q, int elements)", tn_, tn_, tn_);
    emit(0,"{");
    emit(1,    "int element;");
    emit(1,    "for (element = 0; element < elements; element++) {");
    emit(0,"");
    for (unsigned int m = 0; m < g_ptr_array_size(lr->members); m++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(lr->members, m);

        emit_c_array_loops_start(lcm, f, lm, "q", lcm_is_constant_size_array(lm) ? FLAG_NONE : FLAG_EMIT_MALLOCS);

        int indent = 2+imax(0, g_ptr_array_size(lm->dimensions) - 1);
        emit(indent, "__%s_clone_array(%s, %s, %s);",
             dots_to_underscores (lm->type->lctypename),
             make_accessor(lm, "p", g_ptr_array_size(lm->dimensions) - 1),
             make_accessor(lm, "q", g_ptr_array_size(lm->dimensions) - 1),
             make_array_size(lm, "p", g_ptr_array_size(lm->dimensions) - 1));

        emit_c_array_loops_end(lcm, f, lm, "p", FLAG_NONE);
        emit(0,"");
    }
    emit(1,   "}");
    emit(1,   "return 0;");
    emit(0,"}");
    emit(0,"");
}
Exemple #4
0
// Some types do not have a 1:1 mapping from lcm types to native C
// storage types. Do not free the string pointers returned by this
// function.
static const char *map_type_name(const char *t)
{
	if (!strcmp(t,"boolean"))
        return "logical";

	if (!strcmp(t,"byte"))
        return "uint8";

	if (!strcmp(t, "int8_t"))
        return "int8";

	if (!strcmp(t, "int16_t"))
        return "int16";

	if (!strcmp(t, "uint16_t"))
        return "uint16";

	if (!strcmp(t, "int32_t"))
        return "int32";

	if (!strcmp(t, "uint32_t"))
        return "uint32";

	if (!strcmp(t, "int64_t"))
        return "int64";

	if (!strcmp(t,"float"))
        return "single";

    return dots_to_underscores (t);
}
Exemple #5
0
static void emit_c_struct_get_hash(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    char *tn  = ls->structname->lctypename;
    char *tn_ = dots_to_underscores(tn);

    emit(0, "static int __%s_hash_computed;", tn_);
    emit(0, "static uint64_t __%s_hash;", tn_);
    emit(0, "");

    emit(0, "uint64_t __%s_hash_recursive(const __lcm_hash_ptr *p)", tn_);
    emit(0, "{");
    emit(1,     "const __lcm_hash_ptr *fp;");
    emit(1,     "for (fp = p; fp != NULL; fp = fp->parent)");
    emit(2,         "if (fp->v == __%s_get_hash)", tn_);
    emit(3,              "return 0;");
    emit(0, "");
    emit(1, "__lcm_hash_ptr cp;");
    emit(1, "cp.parent =  p;");
    emit(1, "cp.v = (void*)__%s_get_hash;", tn_);
    emit(1, "(void) cp;");
    emit(0, "");
    emit(1, "uint64_t hash = (uint64_t)0x%016"PRIx64"LL", ls->hash);

    for (unsigned int m = 0; m < g_ptr_array_size(ls->members); m++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, m);

        emit(2, " + __%s_hash_recursive(&cp)", dots_to_underscores(lm->type->lctypename));
    }
    emit(2,";");
    emit(0, "");
    emit(1, "return (hash<<1) + ((hash>>63)&1);");
    emit(0, "}");
    emit(0, "");

    emit(0, "int64_t __%s_get_hash(void)", tn_);
    emit(0, "{");
    emit(1, "if (!__%s_hash_computed) {", tn_);
    emit(2,      "__%s_hash = (int64_t)__%s_hash_recursive(NULL);", tn_, tn_);
    emit(2,      "__%s_hash_computed = 1;", tn_);
    emit(1,      "}");
    emit(0, "");
    emit(1, "return __%s_hash;", tn_);
    emit(0, "}");
    emit(0, "");
}
Exemple #6
0
static void emit_c_decode_cleanup(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    char *tn = ls->structname->lctypename;
    char *tn_ = dots_to_underscores(tn);

    emit(0,"int %s_decode_cleanup(%s *p)", tn_, tn_);
    emit(0,"{");
    emit(1, "return __%s_decode_array_cleanup(p, 1);", tn_);
    emit(0,"}");
    emit(0,"");
}
Exemple #7
0
static void emit_c_num_fields(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    char *tn = ls->structname->lctypename;
    char *tn_ = dots_to_underscores(tn);

    emit(0,"int %s_num_fields(void)", tn_);
    emit(0,"{");
    emit(1, "return %d;", g_ptr_array_size(ls->members));
    emit(0,"}");
    emit(0,"");
}
Exemple #8
0
static void emit_c_struct_size(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    char *tn = ls->structname->lctypename;
    char *tn_ = dots_to_underscores(tn);

    emit(0,"size_t %s_struct_size(void)", tn_);
    emit(0,"{");
    emit(1, "return sizeof(%s);", tn_);
    emit(0,"}");
    emit(0,"");
}
Exemple #9
0
static void emit_c_encoded_size(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    char *tn = ls->structname->lctypename;
    char *tn_ = dots_to_underscores(tn);

    emit(0,"int %s_encoded_size(const %s *p)", tn_, tn_);
    emit(0,"{");
    emit(1, "return 8 + __%s_encoded_array_size(p, 1);", tn_);
    emit(0,"}");
    emit(0,"");
}
Exemple #10
0
static void emit_c_destroy(lcmgen_t *lcm, FILE *f, lcm_struct_t *lr)
{
    char *tn = lr->structname->lctypename;
    char *tn_ = dots_to_underscores(tn);

    emit(0,"void %s_destroy(%s *p)", tn_, tn_);
    emit(0,"{");
    emit(1,    "__%s_decode_array_cleanup(p, 1);", tn_);
    emit(1,    "free(p);");
    emit(0,"}");
    emit(0,"");
}
Exemple #11
0
// Some types do not have a 1:1 mapping from lcm types to native C
// storage types. Do not free the string pointers returned by this
// function.
static const char *map_type_name(const char *t)
{
    if (!strcmp(t,"boolean"))
        return "int8_t";

    if (!strcmp(t,"string"))
        return "char*";

    if (!strcmp(t,"byte"))
        return "uint8_t";

    return dots_to_underscores (t);
}
Exemple #12
0
static void emit_c_copy(lcmgen_t *lcm, FILE *f, lcm_struct_t *lr)
{
    char *tn = lr->structname->lctypename;
    char *tn_ = dots_to_underscores(tn);

    emit(0,"%s *%s_copy(const %s *p)", tn_, tn_, tn_);
    emit(0,"{");
    emit(1,    "%s *q = (%s*) malloc(sizeof(%s));", tn_, tn_, tn_);
    emit(1,    "__%s_clone_array(p, q, 1);", tn_);
    emit(1,    "return q;");
    emit(0,"}");
    emit(0,"");
}
Exemple #13
0
static void emit_c_struct_publish(lcmgen_t *lcm, FILE *f, lcm_struct_t *lr)
{
    char *tn = lr->structname->lctypename;
    char *tn_ = dots_to_underscores(tn);
    fprintf(f,
            "int %s_publish(lcm_t *lc, const char *channel, const %s *p)\n"
            "{\n"
            "      int max_data_size = %s_encoded_size (p);\n"
            "      uint8_t *buf = (uint8_t*) malloc (max_data_size);\n"
            "      if (!buf) return -1;\n"
            "      int data_size = %s_encode (buf, 0, max_data_size, p);\n"
            "      if (data_size < 0) {\n"
            "          free (buf);\n"
            "          return data_size;\n"
            "      }\n"
            "      int status = lcm_publish (lc, channel, buf, data_size);\n"
            "      free (buf);\n"
            "      return status;\n"
            "}\n\n", tn_, tn_, tn_, tn_);
}
Exemple #14
0
static void emit_c_encode(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    char *tn = ls->structname->lctypename;
    char *tn_ = dots_to_underscores(tn);

    emit(0,"int %s_encode(void *buf, int offset, int maxlen, const %s *p)", tn_, tn_);
    emit(0,"{");
    emit(1,    "int pos = 0, thislen;");
    emit(1,    "int64_t hash = __%s_get_hash();", tn_);
    emit(0,"");
    emit(1,    "thislen = __int64_t_encode_array(buf, offset + pos, maxlen - pos, &hash, 1);");
    emit(1,    "if (thislen < 0) return thislen; else pos += thislen;");
    emit(0,"");
    emit(1,    "thislen = __%s_encode_array(buf, offset + pos, maxlen - pos, p, 1);", tn_);
    emit(1,    "if (thislen < 0) return thislen; else pos += thislen;");
    emit(0,"");
    emit(1, "return pos;");
    emit(0,"}");
    emit(0,"");
}
Exemple #15
0
static void emit_c_get_type_info(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    char *tn = ls->structname->lctypename;
    char *tn_ = dots_to_underscores(tn);

    emit(0,"const lcm_type_info_t *%s_get_type_info(void)", tn_);
    emit(0,"{");
    emit(1,"static int init = 0;");
    emit(1,"static lcm_type_info_t typeinfo;");
    emit(1,"if (!init) {");
    emit(2,"typeinfo.encode         = (lcm_encode_t) %s_encode;", tn_);
    emit(2,"typeinfo.decode         = (lcm_decode_t) %s_decode;", tn_);
    emit(2,"typeinfo.decode_cleanup = (lcm_decode_cleanup_t) %s_decode_cleanup;", tn_);
    emit(2,"typeinfo.encoded_size   = (lcm_encoded_size_t) %s_encoded_size;", tn_);
    emit(2,"typeinfo.struct_size    = (lcm_struct_size_t)  %s_struct_size;", tn_);
    emit(2,"typeinfo.num_fields     = (lcm_num_fields_t) %s_num_fields;", tn_);
    emit(2,"typeinfo.get_field      = (lcm_get_field_t) %s_get_field;", tn_);
    emit(2,"typeinfo.get_hash       = (lcm_get_hash_t) __%s_get_hash;", tn_);
    emit(1,"}");
    emit(1,"");
    emit(1,"return &typeinfo;");
    emit(0,"}");
}
Exemple #16
0
static void emit_c_struct_subscribe(lcmgen_t *lcm, FILE *f, lcm_struct_t *lr)
{
    const char *tn = lr->structname->lctypename;
    char *tn_ = dots_to_underscores(tn);

    fprintf(f,
            "struct _%s_subscription_t {\n"
            "    %s_handler_t user_handler;\n"
            "    void *userdata;\n"
//            "    char *channel;\n"
            "    lcm_subscription_t *lc_h;\n"
            "};\n", tn_, tn_);
    fprintf(f,
            "static\n"
            "void %s_handler_stub (const lcm_recv_buf_t *rbuf,\n"
            "                            const char *channel, void *userdata)\n"
            "{\n"
            "    int status;\n"
            "    %s p;\n"
            "    memset(&p, 0, sizeof(%s));\n"
            "    status = %s_decode (rbuf->data, 0, rbuf->data_size, &p);\n"
            "    if (status < 0) {\n"
            "        fprintf (stderr, \"error %%d decoding %s!!!\\n\", status);\n"
            "        return;\n"
            "    }\n"
            "\n"
            "    %s_subscription_t *h = (%s_subscription_t*) userdata;\n"
            "    h->user_handler (rbuf, channel, &p, h->userdata);\n"
            "\n"
            "    %s_decode_cleanup (&p);\n"
            "}\n\n", tn_, tn_, tn_, tn_, tn_, tn_, tn_, tn_
        );

    fprintf(f,
            "%s_subscription_t* %s_subscribe (lcm_t *lcm,\n"
            "                    const char *channel,\n"
            "                    %s_handler_t f, void *userdata)\n"
            "{\n"
//            "    int chan_len = strlen (channel) + 1;\n"
            "    %s_subscription_t *n = (%s_subscription_t*)\n"
            "                       malloc(sizeof(%s_subscription_t));\n"
            "    n->user_handler = f;\n"
            "    n->userdata = userdata;\n"
//            "    n->channel = (char*) malloc (chan_len);\n"
//            "    memcpy (n->channel, channel, chan_len);\n"
            "    n->lc_h = lcm_subscribe (lcm, channel,\n"
            "                                 %s_handler_stub, n);\n"
            "    if (n->lc_h == NULL) {\n"
            "        fprintf (stderr,\"couldn't reg %s LCM handler!\\n\");\n"
            "        free (n);\n"
            "        return NULL;\n"
            "    }\n"
            "    return n;\n"
            "}\n\n", tn_, tn_, tn_, tn_, tn_, tn_, tn_, tn_
        );

    fprintf(f,
            "int %s_subscription_set_queue_capacity (%s_subscription_t* subs,\n"
            "                              int num_messages)\n"
            "{\n"
            "    return lcm_subscription_set_queue_capacity (subs->lc_h, num_messages);\n"
            "}\n\n", tn_, tn_);

    fprintf(f,
            "int %s_unsubscribe(lcm_t *lcm, %s_subscription_t* hid)\n"
            "{\n"
            "    int status = lcm_unsubscribe (lcm, hid->lc_h);\n"
            "    if (0 != status) {\n"
            "        fprintf(stderr,\n"
            "           \"couldn't unsubscribe %s_handler %%p!\\n\", hid);\n"
            "        return -1;\n"
            "    }\n"
//            "    free (hid->channel);\n"
            "    free (hid);\n"
            "    return 0;\n"
            "}\n\n", tn_, tn_, tn_
        );
}
Exemple #17
0
int emit_struct(lcmgen_t *lcmgen, lcm_struct_t *lr)
{
    char *tn = lr->structname->lctypename;
    char *tn_ = dots_to_underscores(tn);
    char *header_name = g_strdup_printf("%s/%s.h", getopt_get_string(lcmgen->gopt, "c-hpath"), tn_);
    char *c_name      = g_strdup_printf("%s/%s.c", getopt_get_string(lcmgen->gopt, "c-cpath"), tn_);

    if (lcm_needs_generation(lcmgen, lr->lcmfile, header_name)) {
        FILE *f = fopen(header_name, "w");
        if (f == NULL)
            return -1;

        emit_header_top(lcmgen, f, tn_);
        emit_header_struct(lcmgen, f, lr);
        emit_header_prototypes(lcmgen, f, lr);

        emit_header_bottom(lcmgen, f);
        fclose(f);
    }

    // STRUCT C file
    if (lcm_needs_generation(lcmgen, lr->lcmfile, c_name)) {
        FILE *f = fopen(c_name, "w");
        if (f == NULL)
            return -1;

        emit_auto_generated_warning(f);
        fprintf(f, "#include <string.h>\n");
        fprintf(f, "#include \"%s%s%s.h\"\n",
                getopt_get_string(lcmgen->gopt, "cinclude"),
                strlen(getopt_get_string(lcmgen->gopt, "cinclude"))>0 ? "/" : "",
                tn_);
        fprintf(f, "\n");

        emit_c_struct_get_hash(lcmgen, f, lr);
        emit_c_encode_array(lcmgen, f, lr);
        emit_c_encode(lcmgen, f, lr);
        emit_c_encoded_array_size(lcmgen, f, lr);
        emit_c_encoded_size(lcmgen, f, lr);

        if(getopt_get_bool(lcmgen->gopt, "c-typeinfo")) {
            emit_c_struct_size(lcmgen, f, lr);
            emit_c_num_fields(lcmgen, f, lr);
            emit_c_get_field(lcmgen, f, lr);
            emit_c_get_type_info(lcmgen, f, lr);
        }

        emit_c_decode_array(lcmgen, f, lr);
        emit_c_decode_array_cleanup(lcmgen, f, lr);
        emit_c_decode(lcmgen, f, lr);
        emit_c_decode_cleanup(lcmgen, f, lr);

        emit_c_clone_array(lcmgen, f, lr);
        emit_c_copy(lcmgen, f, lr);
        emit_c_destroy(lcmgen, f, lr);

        if(!getopt_get_bool(lcmgen->gopt, "c-no-pubsub")) {
            emit_c_struct_publish(lcmgen, f, lr );
            emit_c_struct_subscribe(lcmgen, f, lr );
        }

        fclose(f);
    }

    return 0;
}
Exemple #18
0
/** Emit header file output specific to a particular type of struct. **/
static void emit_header_struct(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    char *tn = ls->structname->lctypename;
    char *tn_ = dots_to_underscores(tn);
    char *tn_upper = g_utf8_strup(tn_, -1);

    // include header files required by members
    for (unsigned int i = 0; i < g_ptr_array_size(ls->members); i++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, i);

        if (!lcm_is_primitive_type(lm->type->lctypename) &&
             strcmp(lm->type->lctypename, ls->structname->lctypename)) {
            char *other_tn = dots_to_underscores (lm->type->lctypename);
            fprintf(f, "#include \"%s%s%s.h\"\n",
                    getopt_get_string(lcm->gopt, "cinclude"),
                    strlen(getopt_get_string(lcm->gopt, "cinclude"))>0 ? "/" : "",
                    other_tn);
            free (other_tn);
        }
    }

    // output constants
    for (unsigned int i = 0; i < g_ptr_array_size(ls->constants); i++) {
        lcm_constant_t *lc = (lcm_constant_t *) g_ptr_array_index(ls->constants, i);
        assert(lcm_is_legal_const_type(lc->lctypename));
        const char *suffix = "";
        if (!strcmp(lc->lctypename, "int64_t")) {
            suffix = "LL";
        }
        emit_comment(f, 0, lc->comment);
        emit(0, "#define %s_%s %s%s", tn_upper, lc->membername, lc->val_str,
                suffix);
    }
    if (g_ptr_array_size(ls->constants) > 0) {
        emit(0, "");
    }

    // define the struct
    emit_comment(f, 0, ls->comment);
    emit(0, "typedef struct _%s %s;", tn_, tn_);
    emit(0, "struct _%s", tn_);
    emit(0, "{");

    for (unsigned int m = 0; m < g_ptr_array_size(ls->members); m++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, m);

        emit_comment(f, 1, lm->comment);

        int ndim = g_ptr_array_size(lm->dimensions);
        if (ndim == 0) {
            emit(1, "%-10s %s;", map_type_name(lm->type->lctypename),
                    lm->membername);
        } else {
            if (lcm_is_constant_size_array(lm)) {
                emit_start(1, "%-10s %s", map_type_name(lm->type->lctypename), lm->membername);
                for (unsigned int d = 0; d < ndim; d++) {
                    lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, d);
                    emit_continue("[%s]", ld->size);
                }
                emit_end(";");
            } else {
                emit_start(1, "%-10s ", map_type_name(lm->type->lctypename));
                for (unsigned int d = 0; d < ndim; d++)
                    emit_continue("*");
                emit_end("%s;", lm->membername);
            }
        }
    }
    emit(0, "};");
    emit(0, "");

    free(tn_);
    g_free(tn_upper);
}
Exemple #19
0
static void emit_c_get_field(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    char *tn = ls->structname->lctypename;
    char *tn_ = dots_to_underscores(tn);

    emit(0,"int %s_get_field(const %s *p, int i, lcm_field_t *f)", tn_, tn_);
    emit(0,"{");
    emit(1,"if (0 > i || i >= %s_num_fields())", tn_);
    emit(2,"return 1;");
    emit(1,"");

    emit(1,"switch (i) {");
    emit(1,"");

    int num_fields = g_ptr_array_size(ls->members);
    for(int i = 0; i < num_fields; i++) {
        emit(2,"case %d: {", i);

        lcm_member_t *m = (lcm_member_t *)g_ptr_array_index(ls->members, i);

        const char *type_val = NULL;
        if(lcm_is_primitive_type(m->type->shortname)) {
            type_val = str_toupper(g_strdup_printf("LCM_FIELD_%s", m->type->shortname));
        } else {
            emit(3,"/* %s */", m->type->shortname);
            type_val = "LCM_FIELD_USER_TYPE";
        }

        emit(3,"f->name = \"%s\";", m->membername);
        emit(3,"f->type = %s;", type_val);
        emit(3,"f->typestr = \"%s\";", m->type->shortname);

        int num_dim = g_ptr_array_size(m->dimensions);
        emit(3,"f->num_dim = %d;", num_dim);

        if(num_dim != 0) {

            for(int j = 0; j < num_dim; j++) {
                lcm_dimension_t *d = (lcm_dimension_t*) g_ptr_array_index(m->dimensions, j);
                if(d->mode == LCM_VAR)
                    emit(3,"f->dim_size[%d] = p->%s;", j, d->size);
                else
                    emit(3,"f->dim_size[%d] = %s;", j, d->size);
            }

            for(int j = 0; j < num_dim; j++) {
                lcm_dimension_t *d = (lcm_dimension_t*) g_ptr_array_index(m->dimensions, j);
                emit(3,"f->dim_is_variable[%d] = %d;", j, d->mode == LCM_VAR);
            }

        }

        emit(3, "f->data = (void *) &p->%s;", m->membername);

        emit(3, "return 0;");
        emit(2,"}");
        emit(2,"");
    }
    emit(2,"default:");
    emit(3,"return 1;");
    emit(1,"}");
    emit(0,"}");
    emit(0,"");
}
Exemple #20
0
static void emit_header_prototypes(lcmgen_t *lcmgen, FILE *f, lcm_struct_t *ls)
{
    char *xd = getopt_get_string(lcmgen->gopt, "c-export-symbol");
    char *xd_ = add_space_or_empty(xd);
    char *tn = ls->structname->lctypename;
    char *tn_ = dots_to_underscores(tn);

    emit(0, "/**");
    emit(0, " * Create a deep copy of a %s.", tn_);
    emit(0, " * When no longer needed, destroy it with %s_destroy()", tn_);
    emit(0, " */");
    emit(0,"%s%s* %s_copy(const %s* to_copy);", xd_, tn_, tn_, tn_);
    emit(0, "");
    emit(0, "/**");
    emit(0, " * Destroy an instance of %s created by %s_copy()", tn_, tn_);
    emit(0, " */");
    emit(0,"%svoid %s_destroy(%s* to_destroy);", xd_, tn_, tn_);
    emit(0,"");

    if (!getopt_get_bool(lcmgen->gopt, "c-no-pubsub")) {
        emit(0, "/**");
        emit(0, " * Identifies a single subscription.  This is an opaque data type.");
        emit(0, " */");
        emit(0,"typedef struct _%s_subscription_t %s_subscription_t;", tn_, tn_);
        emit(0, "");
        emit(0, "/**");
        emit(0, " * Prototype for a callback function invoked when a message of type");
        emit(0, " * %s is received.", tn_);
        emit(0, " */");
        emit(0,"typedef void(*%s_handler_t)(const lcm_recv_buf_t *rbuf,\n"
               "             const char *channel, const %s *msg, void *userdata);",
               tn_, tn_);
        emit(0, "");
        emit(0, "/**");
        emit(0, " * Publish a message of type %s using LCM.", tn_);
        emit(0, " *");
        emit(0, " * @param lcm The LCM instance to publish with.");
        emit(0, " * @param channel The channel to publish on.");
        emit(0, " * @param msg The message to publish.");
        emit(0, " * @return 0 on success, <0 on error.  Success means LCM has transferred");
        emit(0, " * responsibility of the message data to the OS.");
        emit(0, " */");
        emit(0,"%sint %s_publish(lcm_t *lcm, const char *channel, const %s *msg);", xd_, tn_, tn_);
        emit(0, "");
        emit(0, "/**");
        emit(0, " * Subscribe to messages of type %s using LCM.", tn_);
        emit(0, " *");
        emit(0, " * @param lcm The LCM instance to subscribe with.");
        emit(0, " * @param channel The channel to subscribe to.");
        emit(0, " * @param handler The callback function invoked by LCM when a message is received.");
        emit(0, " *                This function is invoked by LCM during calls to lcm_handle() and");
        emit(0, " *                lcm_handle_timeout().");
        emit(0, " * @param userdata An opaque pointer passed to @p handler when it is invoked.");
        emit(0, " * @return 0 on success, <0 if an error occured");
        emit(0, " */");
        emit(0,"%s%s_subscription_t* %s_subscribe(lcm_t *lcm, const char *channel, %s_handler_t handler, void *userdata);",
                xd_, tn_, tn_, tn_);
        emit(0, "");
        emit(0, "/**");
        emit(0, " * Removes and destroys a subscription created by %s_subscribe()", tn_);
        emit(0, " */");
        emit(0,"%sint %s_unsubscribe(lcm_t *lcm, %s_subscription_t* hid);", xd_, tn_, tn_);
        emit(0, "");
        emit(0, "/**");
        emit(0, " * Sets the queue capacity for a subscription.");
        emit(0, " * Some LCM providers (e.g., the default multicast provider) are implemented");
        emit(0, " * using a background receive thread that constantly revceives messages from");
        emit(0, " * the network.  As these messages are received, they are buffered on");
        emit(0, " * per-subscription queues until dispatched by lcm_handle().  This function");
        emit(0, " * how many messages are queued before dropping messages.");
        emit(0, " *");
        emit(0, " * @param subs the subscription to modify.");
        emit(0, " * @param num_messages The maximum number of messages to queue");
        emit(0, " *  on the subscription.");
        emit(0, " * @return 0 on success, <0 if an error occured");
        emit(0, " */");
        emit(0,"%sint %s_subscription_set_queue_capacity(%s_subscription_t* subs,\n"
            "                              int num_messages);\n", xd_, tn_, tn_);
    }

    emit(0, "/**");
    emit(0, " * Encode a message of type %s into binary form.", tn_);
    emit(0, " *");
    emit(0, " * @param buf The output buffer.");
    emit(0, " * @param offset Encoding starts at this byte offset into @p buf.");
    emit(0, " * @param maxlen Maximum number of bytes to write.  This should generally");
    emit(0, " *               be equal to %s_encoded_size().", tn_);
    emit(0, " * @param msg The message to encode.");
    emit(0, " * @return The number of bytes encoded, or <0 if an error occured.");
    emit(0, " */");
    emit(0,"%sint %s_encode(void *buf, int offset, int maxlen, const %s *p);", xd_, tn_, tn_);
    emit(0, "");
    emit(0, "/**");
    emit(0, " * Decode a message of type %s from binary form.", tn_);
    emit(0, " * When decoding messages containing strings or variable-length arrays, this");
    emit(0, " * function may allocate memory.  When finished with the decoded message,");
    emit(0, " * release allocated resources with %s_decode_cleanup().", tn_);
    emit(0, " *");
    emit(0, " * @param buf The buffer containing the encoded message");
    emit(0, " * @param offset The byte offset into @p buf where the encoded message starts.");
    emit(0, " * @param maxlen The maximum number of bytes to read while decoding.");
    emit(0, " * @param msg Output parameter where the decoded message is stored");
    emit(0, " * @return The number of bytes decoded, or <0 if an error occured.");
    emit(0, " */");
    emit(0,"%sint %s_decode(const void *buf, int offset, int maxlen, %s *msg);", xd_, tn_, tn_);
    emit(0, "");
    emit(0, "/**");
    emit(0, " * Release resources allocated by %s_decode()", tn_);
    emit(0, " * @return 0");
    emit(0, " */");
    emit(0,"%sint %s_decode_cleanup(%s *p);", xd_, tn_, tn_);
    emit(0, "");
    emit(0, "/**");
    emit(0, " * Check how many bytes are required to encode a message of type %s", tn_);
    emit(0, " */");
    emit(0,"%sint %s_encoded_size(const %s *p);", xd_, tn_, tn_);
    if(getopt_get_bool(lcmgen->gopt, "c-typeinfo")) {
        emit(0,"%ssize_t %s_struct_size(void);", xd_, tn_);
        emit(0,"%sint %s_num_fields(void);", xd_, tn_);
        emit(0,"%sint %s_get_field(const %s *p, int i, lcm_field_t *f);", xd_, tn_, tn_);
        emit(0,"%sconst lcm_type_info_t *%s_get_type_info(void);", xd_, tn_);
    }
    emit(0,"");

    emit(0,"// LCM support functions. Users should not call these");
    emit(0,"%sint64_t __%s_get_hash(void);", xd_, tn_);
    emit(0,"%suint64_t __%s_hash_recursive(const __lcm_hash_ptr *p);", xd_, tn_);
    emit(0,"%sint __%s_encode_array(void *buf, int offset, int maxlen, const %s *p, int elements);", xd_, tn_, tn_);
    emit(0,"%sint __%s_decode_array(const void *buf, int offset, int maxlen, %s *p, int elements);", xd_, tn_, tn_);
    emit(0,"%sint __%s_decode_array_cleanup(%s *p, int elements);", xd_, tn_, tn_);
    emit(0,"%sint __%s_encoded_array_size(const %s *p, int elements);", xd_, tn_, tn_);
    emit(0,"%sint __%s_clone_array(const %s *p, %s *q, int elements);", xd_, tn_, tn_, tn_);
    emit(0,"");

}
Exemple #21
0
int emit_enum(lcmgen_t *lcmgen, lcm_enum_t *le)
{
    char *tn = le->enumname->lctypename;
    char *tn_ = dots_to_underscores(tn);
    char *header_name = g_strdup_printf("%s/%s.h", getopt_get_string(lcmgen->gopt, "c-hpath"), tn_);
    char *c_name      = g_strdup_printf("%s/%s.c", getopt_get_string(lcmgen->gopt, "c-cpath"), tn_);

    // ENUM header file
    if (lcm_needs_generation(lcmgen, le->lcmfile, header_name)) {
        FILE *f = fopen(header_name, "w");
        if (f == NULL)
            return -1;

        emit_header_top(lcmgen, f, tn_);

        char *tn_upper = g_ascii_strup (tn_, strlen (tn_));

        ///////////////////////////////////////////////////////////////////
        // the enum declaration itself
        emit(0, "enum _%s {", tn_);
        for (unsigned int i = 0; i < g_ptr_array_size(le->values); i++) {
            lcm_enum_value_t *lev = (lcm_enum_value_t *) g_ptr_array_index(le->values, i);
            emit(1," %s_%s = %d%s",
                    tn_upper,
                    lev->valuename,
                    lev->value, i==(g_ptr_array_size(le->values)-1) ? "" : ",");
        }

        free (tn_upper);

        emit(0, "};");
        emit(0, "");

        emit(0, "typedef enum _%s %s;", tn_, tn_);
        emit(0, "");

        emit(0, "const char * %s_name(%s val);", tn_, tn_);
        emit(0, "");

        ///////////////////////////////////////////////////////////////////

        emit(0, "static inline int64_t __%s_hash_recursive(const __lcm_hash_ptr *p)", tn_);
        emit(0, "{");
        emit(1,    "return 0x%016"PRIx64"LL;", le->hash);
        emit(0, "}");
        emit(0, "");

        emit(0, "static inline int64_t __%s_get_hash()", tn_);
        emit(0, "{");
        emit(1,    "return 0x%016"PRIx64"LL;", le->hash);
        emit(0, "}");
        emit(0, "");

        // enums are always "ints", but "ints" are not always int32_t. We
        // always store an enum as an int32_t, however. Consequently, we
        // jump through some hoops here in order to allow the compiler to
        // convert from an int32_t to whatever the native size of "int"
        // is.
        emit(0, "static inline int __%s_encode_array(void *_buf, int offset, int maxlen, const %s *p, int elements)", tn_, tn_);
        emit(0, "{");
        emit(1,    "int pos = 0, thislen, element;");
        emit(1,     "for (element = 0; element < elements; element++) {");
        emit(2,         "int32_t v = (int32_t) p[element];");
        emit(2,         "thislen = __int32_t_encode_array(_buf, offset + pos, maxlen - pos, &v, 1);");
        emit(2,         "if (thislen < 0) return thislen; else pos += thislen;");
        emit(1,     "}");
        emit(1, "return thislen;");
        emit(0, "}");
        emit(0, "");

        emit(0,"static inline int %s_encode(void *buf, int offset, int maxlen, const %s *p)", tn_, tn_);
        emit(0,"{");
        emit(1,    "int pos = 0, thislen;");
        emit(1,    "int64_t hash = 0x%016"PRIx64"LL;", le->hash);
        emit(0,"");
        emit(1,    "thislen = __int64_t_encode_array(buf, offset + pos, maxlen - pos, &hash, 1);");
        emit(1,    "if (thislen < 0) return thislen; else pos += thislen;");
        emit(0,"");
        emit(1,    "thislen = __%s_encode_array(buf, offset + pos, maxlen - pos, p, 1);", tn_);
        emit(1,    "if (thislen < 0) return thislen; else pos += thislen;");
        emit(0,"");
        emit(1, "return pos;");
        emit(0,"}");
        emit(0,"");

        emit(0, "static inline int __%s_decode_array(const void *_buf, int offset, int maxlen, %s *p, int elements)", tn_, tn_);
        emit(0, "{");
        emit(1,    "int pos = 0, thislen, element;");
        emit(1,     "for (element = 0; element < elements; element++) {");
        emit(2,         "int32_t v;");
        emit(2,         "thislen = __int32_t_decode_array(_buf, offset + pos, maxlen - pos, &v, 1);");
        emit(2,         "if (thislen < 0) return thislen; else pos += thislen;");
        emit(2,         "p[element] = (%s) v;", tn_);
        emit(1,     "}");
        emit(1, "return thislen;");
        emit(0, "}");
        emit(0, "");

        emit(0, "static inline int __%s_clone_array(const %s *p, %s *q, int elements)", tn_, tn_, tn_);
        emit(0, "{");
        emit(1,    "memcpy(q, p, elements * sizeof(%s));", tn_);
        emit(1,    "return 0;");
        emit(0, "}");
        emit(0, "");

        emit(0,"static inline int %s_decode(const void *buf, int offset, int maxlen, %s *p)", tn_, tn_);
        emit(0,"{");
        emit(1,    "int pos = 0, thislen;");
        emit(1,    "int64_t hash = 0x%016"PRIx64"LL;", le->hash);
        emit(0,"");
        emit(1,    "int64_t this_hash;");
        emit(1,    "thislen = __int64_t_decode_array(buf, offset + pos, maxlen - pos, &this_hash, 1);");
        emit(1,    "if (thislen < 0) return thislen; else pos += thislen;");
        emit(1,    "if (this_hash != hash) return -1;");
        emit(0,"");
        emit(1,    "thislen = __%s_decode_array(buf, offset + pos, maxlen - pos, p, 1);", tn_);
        emit(1,    "if (thislen < 0) return thislen; else pos += thislen;");
        emit(0,"");
        emit(1,   "return pos;");
        emit(0,"}");
        emit(0,"");

        emit(0, "static inline int __%s_decode_array_cleanup(%s *in, int elements)", tn_, tn_);
        emit(0, "{");
        emit(1,    "return 0;");
        emit(0, "}");
        emit(0, "");

        emit(0,"static inline int %s_decode_cleanup(%s *p)", tn_, tn_);
        emit(0,"{");
        emit(1,    "return 0;");
        emit(0,"}");
        emit(0,"");

        emit(0, "static inline int __%s_encoded_array_size(const %s *p, int elements)", tn_, tn_);
        emit(0, "{");
        emit(1,    "return __int32_t_encoded_array_size((const int32_t*)p, elements);");
        emit(0, "}");
        emit(0, "");

        emit(0, "static inline int %s_encoded_size(const %s *in)", tn_, tn_);
        emit(0, "{");
        emit(1,    "return int32_t_encoded_size((const int32_t*)in);");
        emit(0, "}");
        emit(0, "");

        emit_header_bottom(lcmgen, f);
        fclose(f);
    }

    // ENUM C file
    if (lcm_needs_generation(lcmgen, le->lcmfile, c_name)) {
        char *tn_upper = g_ascii_strup (tn_, strlen (tn_));

        FILE *f = fopen(c_name, "w");
        emit_auto_generated_warning(f);

        fprintf(f, "#include \"%s%s%s.h\"\n",
                getopt_get_string(lcmgen->gopt, "cinclude"),
                strlen(getopt_get_string(lcmgen->gopt, "cinclude"))>0 ? "/" : "",
                tn_);

        emit(0, "const char * %s_name(%s val)", tn_, tn_);
        emit(0, "{");
        emit(1,     "switch (val) {");
        for (unsigned int i = 0; i < g_ptr_array_size(le->values); i++) {
            lcm_enum_value_t *lev = (lcm_enum_value_t *) g_ptr_array_index(le->values, i);
            emit(2, "case %s_%s:", tn_upper, lev->valuename);
            emit(3,     "return \"%s\";", lev->valuename);
        }
        emit(2,         "default:");
        emit(3,             "return NULL;");
        emit(1,     "}");
        emit(0, "}");
        fclose(f);

        free (tn_upper);
    }

    return 0;
}
Exemple #22
0
/** Emit header file **/
static void emit_header_start(lcmgen_t *lcmgen, FILE *f, lcm_struct_t *ls)
{
    char *tn = ls->structname->lctypename;
    char *sn = ls->structname->shortname;
    char *tn_ = dots_to_underscores(tn);

    emit_auto_generated_warning(f);

    fprintf(f, "#include <lcm/lcm_coretypes.h>\n");
    fprintf(f, "\n");
    fprintf(f, "#ifndef __%s_hpp__\n", tn_);
    fprintf(f, "#define __%s_hpp__\n", tn_);
    fprintf(f, "\n");

    // do we need to #include <vector> ?
    int emit_include_vector = 0;
    for (unsigned int mind = 0; mind < g_ptr_array_size(ls->members); mind++) {
        lcm_member_t *lm = (lcm_member_t *)g_ptr_array_index(ls->members, mind);
        if (g_ptr_array_size(lm->dimensions) != 0 &&
                !lcm_is_constant_size_array(lm) && !emit_include_vector) {
            emit(0, "#include <vector>");
            emit_include_vector = 1;
        }
    }

    emit(0, "#include <cmath>\t// For fabs to compare floats");
    emit(0, "#include <string>\t// For return type of toStr()");
    emit(0, "#include <sstream>\t// For stringstream in toStr()");

    // include header files for other LCM types
    for (unsigned int mind = 0; mind < g_ptr_array_size(ls->members); mind++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, mind);

        if (!lcm_is_primitive_type(lm->type->lctypename) &&
                strcmp(lm->type->lctypename, ls->structname->lctypename)) {
            char *other_tn = dots_to_slashes (lm->type->lctypename);
            emit(0, "#include \"%s%s%s.hpp\"",
                 getopt_get_string(lcmgen->gopt, "cpp-include"),
                 strlen(getopt_get_string(lcmgen->gopt, "cpp-include"))>0 ? G_DIR_SEPARATOR_S : "",
                 other_tn);
            free(other_tn);
        }
    }

    fprintf(f, "\n");
    emit_package_namespace_start(lcmgen, f, ls);

    // define the class
    emit(0, "");
    emit_comment(f, 0, ls->comment);
    emit(0, "class %s", sn);
    emit(0, "{");

    // data members
    if(g_ptr_array_size(ls->members)) {
        emit(1, "public:");
        for (unsigned int mind = 0; mind < g_ptr_array_size(ls->members); mind++) {
            lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, mind);

            emit_comment(f, 2, lm->comment);
            char const* mapped_typename = map_type_name(lm->type->lctypename);
            int ndim = g_ptr_array_size(lm->dimensions);
            if (ndim == 0) {
                emit(2, "%-10s %s;", mapped_typename, lm->membername);
            } else {
                if (lcm_is_constant_size_array(lm)) {
                    emit_start(2, "%-10s %s", mapped_typename, lm->membername);
                    for (unsigned int d = 0; d < ndim; d++) {
                        lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, d);
                        emit_continue("[%s]", ld->size);
                    }
                    emit_end(";");
                } else {
                    emit_start(2, "");
                    for (unsigned int d = 0; d < ndim; d++)
                        emit_continue("std::vector< ");
                    emit_continue("%s", mapped_typename);
                    for (unsigned int d = 0; d < ndim; d++)
                        emit_continue(" >");
                    emit_end(" %s;", lm->membername);
                }
            }
            if (mind < g_ptr_array_size(ls->members) - 1) {
                emit(0, "");
            }
        }
        emit(0, "");
    }

    // constants
    if (g_ptr_array_size(ls->constants) > 0) {
        emit(1, "public:");
        for (unsigned int i = 0; i < g_ptr_array_size(ls->constants); i++) {
            lcm_constant_t *lc = (lcm_constant_t *) g_ptr_array_index(ls->constants, i);
            assert(lcm_is_legal_const_type(lc->lctypename));

            emit_comment(f, 2, lc->comment);
            // For int32_t only, we emit enums instead of static const
            // values because the former can be passed by reference while
            // the latter cannot.
            if (!strcmp(lc->lctypename, "int32_t")) {
                emit(2, "enum { %s = %s };", lc->membername, lc->val_str);
            } else {
                const char *suffix = "";
                if (!strcmp(lc->lctypename, "int64_t"))
                    suffix = "LL";
                char const* mapped_typename = map_type_name(lc->lctypename);
                char *cpp_std = getopt_get_string(lcmgen->gopt, "cpp-std");
                if(strcmp("c++98",cpp_std) && strcmp("c++11",cpp_std)) {
                    printf("%s is not a valid cpp_std. Use --cpp-std=c++98 or --cpp-std=c++11 instead\n\n", cpp_std);
                    fflush(stdout);
                    _exit(1);
                }

                if(!strcmp (cpp_std, "c++11")) {
                    emit(2, "static constexpr %-8s %s = %s%s;", mapped_typename,
                         lc->membername, lc->val_str, suffix);
                } else {
                    emit(2, "// If you're using C++11 and are getting compiler errors saying things like");
                    emit(2, "// ‘constexpr’ needed for in-class initialization of static data member");
                    emit(2, "// then re-run lcm-gen with '--cpp-std=c++11' to generate code that is");
                    emit(2, "// compliant with C++11");
                    emit(2, "static const %-8s %s = %s%s;", mapped_typename,
                         lc->membername, lc->val_str, suffix);
                }
            }
        }
        emit(0, "");
    }

    emit(1, "public:");
    emit(2, "/**");
    emit(2, " * Encode a message into binary form.");
    emit(2, " *");
    emit(2, " * @param buf The output buffer.");
    emit(2, " * @param offset Encoding starts at thie byte offset into @p buf.");
    emit(2, " * @param maxlen Maximum number of bytes to write.  This should generally be");
    emit(2, " *  equal to getEncodedSize().");
    emit(2, " * @return The number of bytes encoded, or <0 on error.");
    emit(2, " */");
    emit(2, "inline int encode(void *buf, int offset, int maxlen) const;");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Check how many bytes are required to encode this message.");
    emit(2, " */");
    emit(2, "inline int getEncodedSize() const;");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Decode a message from binary form into this instance.");
    emit(2, " *");
    emit(2, " * @param buf The buffer containing the encoded message.");
    emit(2, " * @param offset The byte offset into @p buf where the encoded message starts.");
    emit(2, " * @param maxlen The maximum number of bytes to reqad while decoding.");
    emit(2, " * @return The number of bytes decoded, or <0 if an error occured.");
    emit(2, " */");
    emit(2, "inline int decode(const void *buf, int offset, int maxlen);");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Compare two instances of the same type.");
    emit(2, " *");
    emit(2, " * @param[in] other The object to compare.");
    emit(2, " * @return true if all elements are equal, false otherwise.");
    emit(2, " */");
    emit(2, "inline bool operator==(%s const & other) const;", sn);
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Construct a string from the object for debugging purposes.");
    emit(2, " * Note that arrays are cropped for readability. Only the first and last elements are shown.");
    emit(2, " *");
    emit(2, " * @param[in] layout A placeholder for the tree structure.");
    emit(2, " */");
    emit(2, "inline std::string toDebugStr(std::string const & layout=\"|-\") const;");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Initialize all values of a test object to pre-defined values.");
    emit(2, " * The values used are much more informative than using 0 because");
    emit(2, " * they are type-dependant. This way, the user knows directly whether");
    emit(2, " * the type is correct or not. Typically the default values are the");
    emit(2, " * maximum value allowed by the type minus 5, and 1.0 for float and double.");
    emit(2, " * Note that for arrays only the first and last elements are considered.");
    emit(2, " *");
    emit(2, " * @return success.");
    emit(2, " */");
    emit(2, "inline bool initTestObject();");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Increment every variable in the object.");
    emit(2, " * Works well with initTestObject() and compareTestObject().");
    emit(2, " * Note that for arrays only the first and last elements are considered.");
    emit(2, " *");
    emit(2, " * @return success.");
    emit(2, " */");
    emit(2, "inline bool incTestObject();");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Compare two instances of the same type.");
    emit(2, " * Works well with initTestObject() and incTestObject().");
    emit(2, " * Note that for arrays only the first and last elements are considered.");
    emit(2, " *");
    emit(2, " * @param[in] other The object to compare.");
    emit(2, " * @return true if all elements are equal, false otherwise.");
    emit(2, " */");
    emit(2, "inline bool compareTestObject(%s const & other) const;", sn);
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Retrieve the 64-bit fingerprint identifying the structure of the message.");
    emit(2, " * Note that the fingerprint is the same for all instances of the same");
    emit(2, " * message type, and is a fingerprint on the message type definition, not on");
    emit(2, " * the message contents.");
    emit(2, " */");
    emit(2, "inline static int64_t getHash();");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Returns \"%s\"", ls->structname->shortname);
    emit(2, " */");
    emit(2, "inline static const char* getTypeName();");

    emit(0, "");
    emit(2, "// LCM support functions. Users should not call these");
    emit(2, "inline int _encodeNoHash(void *buf, int offset, int maxlen) const;");
    emit(2, "inline int _getEncodedSizeNoHash() const;");
    emit(2, "inline int _decodeNoHash(const void *buf, int offset, int maxlen);");
    emit(2, "inline static uint64_t _computeHash(const __lcm_hash_ptr *p);");
    emit(0, "};");
    emit(0, "");

    free(tn_);
}
Exemple #23
0
/** Emit header file **/
static void emit_header_start(lcmgen_t *lcmgen, FILE *f, lcm_struct_t *ls)
{
    char *tn = ls->structname->lctypename;
    char *sn = ls->structname->shortname;
    char *tn_ = dots_to_underscores(tn);

    emit_auto_generated_warning(f);

    fprintf(f, "#include <lcm/lcm_coretypes.h>\n");
    fprintf(f, "\n");
    fprintf(f, "#ifndef __%s_hpp__\n", tn_);
    fprintf(f, "#define __%s_hpp__\n", tn_);
    fprintf(f, "\n");

    // do we need to #include <vector> and/or <string>?
    int emit_include_vector = 0;
    int emit_include_string = 0;
    for (unsigned int mind = 0; mind < g_ptr_array_size(ls->members); mind++) {
        lcm_member_t *lm = (lcm_member_t *)g_ptr_array_index(ls->members, mind);
        if (g_ptr_array_size(lm->dimensions) != 0 &&
            !lcm_is_constant_size_array(lm) && !emit_include_vector) {
            emit(0, "#include <vector>");
            emit_include_vector = 1;
        }
        if(!emit_include_string &&
            !strcmp(lm->type->lctypename, "string")) {
            emit(0, "#include <string>");
            emit_include_string = 1;
        }
    }

    // include header files for other LCM types
    for (unsigned int mind = 0; mind < g_ptr_array_size(ls->members); mind++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, mind);

        if (!lcm_is_primitive_type(lm->type->lctypename) &&
            strcmp(lm->type->lctypename, ls->structname->lctypename)) {
            char *other_tn = dots_to_slashes (lm->type->lctypename);
            emit(0, "#include \"%s%s%s.hpp\"",
                    getopt_get_string(lcmgen->gopt, "cpp-include"),
                    strlen(getopt_get_string(lcmgen->gopt, "cpp-include"))>0 ? G_DIR_SEPARATOR_S : "",
                    other_tn);
            free(other_tn);
        }
    }

    fprintf(f, "\n");
    emit_package_namespace_start(lcmgen, f, ls);

    // define the class
    emit(0, "");
    emit_comment(f, 0, ls->comment);
    emit(0, "class %s", sn);
    emit(0, "{");

    // data members
    if(g_ptr_array_size(ls->members)) {
        emit(1, "public:");
        for (unsigned int mind = 0; mind < g_ptr_array_size(ls->members); mind++) {
            lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, mind);

            emit_comment(f, 2, lm->comment);
            char* mapped_typename = map_type_name(lm->type->lctypename);
            int ndim = g_ptr_array_size(lm->dimensions);
            if (ndim == 0) {
                emit(2, "%-10s %s;", mapped_typename, lm->membername);
            } else {
                if (lcm_is_constant_size_array(lm)) {
                    emit_start(2, "%-10s %s", mapped_typename, lm->membername);
                    for (unsigned int d = 0; d < ndim; d++) {
                        lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, d);
                        emit_continue("[%s]", ld->size);
                    }
                    emit_end(";");
                } else {
                    emit_start(2, "");
                    for (unsigned int d = 0; d < ndim; d++)
                        emit_continue("std::vector< ");
                    emit_continue("%s", mapped_typename);
                    for (unsigned int d = 0; d < ndim; d++)
                        emit_continue(" >");
                    emit_end(" %s;", lm->membername);
                }
            }
            free(mapped_typename);
            if (mind < g_ptr_array_size(ls->members) - 1) {
                emit(0, "");
            }
        }
        emit(0, "");
    }

    // constants
    if (g_ptr_array_size(ls->constants) > 0) {
        emit(1, "public:");
        for (unsigned int i = 0; i < g_ptr_array_size(ls->constants); i++) {
            lcm_constant_t *lc = (lcm_constant_t *) g_ptr_array_index(ls->constants, i);
            assert(lcm_is_legal_const_type(lc->lctypename));

            emit_comment(f, 2, lc->comment);
            // For int32_t only, we emit enums instead of static const
            // values because the former can be passed by reference while
            // the latter cannot.
            if (!strcmp(lc->lctypename, "int32_t")) {
              emit(2, "enum { %s = %s };", lc->membername, lc->val_str);
            } else {
              const char *suffix = "";
              if (!strcmp(lc->lctypename, "int64_t"))
                suffix = "LL";
              char* mapped_typename = map_type_name(lc->lctypename);
              emit(2, "static const %-8s %s = %s%s;", mapped_typename,
                  lc->membername, lc->val_str, suffix);
              free(mapped_typename);
            }
        }
        emit(0, "");
    }

    emit(1, "public:");
    emit(2, "/**");
    emit(2, " * Encode a message into binary form.");
    emit(2, " *");
    emit(2, " * @param buf The output buffer.");
    emit(2, " * @param offset Encoding starts at thie byte offset into @p buf.");
    emit(2, " * @param maxlen Maximum number of bytes to write.  This should generally be");
    emit(2, " *  equal to getEncodedSize().");
    emit(2, " * @return The number of bytes encoded, or <0 on error.");
    emit(2, " */");
    emit(2, "inline int encode(void *buf, int offset, int maxlen) const;");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Check how many bytes are required to encode this message.");
    emit(2, " */");
    emit(2, "inline int getEncodedSize() const;");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Decode a message from binary form into this instance.");
    emit(2, " *");
    emit(2, " * @param buf The buffer containing the encoded message.");
    emit(2, " * @param offset The byte offset into @p buf where the encoded message starts.");
    emit(2, " * @param maxlen The maximum number of bytes to reqad while decoding.");
    emit(2, " * @return The number of bytes decoded, or <0 if an error occured.");
    emit(2, " */");
    emit(2, "inline int decode(const void *buf, int offset, int maxlen);");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Retrieve the 64-bit fingerprint identifying the structure of the message.");
    emit(2, " * Note that the fingerprint is the same for all instances of the same");
    emit(2, " * message type, and is a fingerprint on the message type definition, not on");
    emit(2, " * the message contents.");
    emit(2, " */");
    emit(2, "inline static int64_t getHash();");
    emit(0, "");
    emit(2, "/**");
    emit(2, " * Returns \"%s\"", ls->structname->shortname);
    emit(2, " */");
    emit(2, "inline static const char* getTypeName();");

    emit(0, "");
    emit(2, "// LCM support functions. Users should not call these");
    emit(2, "inline int _encodeNoHash(void *buf, int offset, int maxlen) const;");
    emit(2, "inline int _getEncodedSizeNoHash() const;");
    emit(2, "inline int _decodeNoHash(const void *buf, int offset, int maxlen);");
    emit(2, "inline static int64_t _computeHash(const __lcm_hash_ptr *p);");
    emit(0, "};");
    emit(0, "");

    free(tn_);
}