예제 #1
0
파일: emit_lua.c 프로젝트: GArlington/lcm
static void
emit_member_initializer(const lcmgen_t* lcm, FILE *f, lcm_member_t* lm,
        int dim_num)
{
	if(dim_num == lm->dimensions->len) {
		emit_end("%s", nil_initializer_string(lm->type));
		return;
	}

	lcm_dimension_t *dim =
		(lcm_dimension_t *) g_ptr_array_index (lm->dimensions, dim_num);

	if(dim->mode == LCM_VAR) {
		emit_end("{}");
	} else {
		emit_end("{}");
		emit(dim_num + 1, "for d%d = 1, %s do", dim_num, dim->size);
		emit_start(dim_num + 2, "obj.%s", lm->membername);
		for(int i = 0; i < dim_num + 1; i++){
			emit_continue("[d%d]", i);
		}
		emit_continue(" = ");
		emit_member_initializer(lcm, f, lm, dim_num + 1);
		emit(dim_num + 1, "end");
	}
}
예제 #2
0
파일: emit_m.c 프로젝트: cd127/lcm-1
static int emit_encoded_size_nohash(lcmgen_t *lcm, lcm_struct_t *ls)
{
	start_file("_encodedSize_nohash");

    emit(0, "function s = %s_encodedSize_nohash(S)", sn);
    emit(1,   "s = uint32(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);
		char* lm_tnc = dots_to_double_colons(lm->type->lctypename);

		int const encsize = encoded_size(lm_tnc);
		int const dimensions = g_ptr_array_size(lm->dimensions);

		if (encsize > -1) {//known constant size
			emit_start(1, "s = s + %d", encsize);
			for (int dx = 0; dx < dimensions; ++dx) {
				lcm_dimension_t *dim = (lcm_dimension_t*) g_ptr_array_index(lm->dimensions, dx);
				emit_continue(" * %s", dim->size);
			}
			emit_end(";");
		}
		else {
			if (0 == dimensions) {
				emit(1, "s = s + %s_encodedSize_nohash(S.%s);", map_type_name(lm_tnc), lm->membername);
			}
			else {
				//emit: for each dimension
				for (int dx = 0; dx < dimensions; ++dx) {
					lcm_dimension_t *dim = (lcm_dimension_t*) g_ptr_array_index(lm->dimensions, dx);
					emit(1 + dx, "for dx%d = 1:%s", dx, dim->size);
				}

				{//do
					emit_start(1 + dimensions, "s = s + %s_encodedSize_nohash(S.%s(", map_type_name(lm_tnc), lm->membername);
					for (int dx = 0; dx < dimensions - 1; ++dx) {
						emit_continue("dx%d,", dx);
					}
					emit_end("dx%d));", dimensions - 1);
				}

				//end
				for (int dx = dimensions; dx > 0; --dx) {
					emit(dx, "end");
				}
			}
		}
	
		free(lm_tnc);
	}
    emit(0, "%%endfunction");
    emit(0, "");

	end_file();
}
예제 #3
0
파일: emit_cpp.c 프로젝트: cd127/lcm-1
static void emit_encoded_size_nohash(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    const char *sn = ls->structname->shortname;
    emit(0, "int %s::_getEncodedSizeNoHash() const", sn);
    emit(0, "{");
    if(0 == g_ptr_array_size(ls->members)) {
        emit(1,     "return 0;");
        emit(0,"}");
        emit(0,"");
        return;
    }
    emit(1,     "int enc_size = 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);
        int ndim = g_ptr_array_size(lm->dimensions);

        if(lcm_is_primitive_type(lm->type->lctypename) &&
                strcmp(lm->type->lctypename, "string")) {
            emit_start(1, "enc_size += ");
            for(int n=0; n < ndim - 1; n++) {
                lcm_dimension_t *dim = (lcm_dimension_t*) g_ptr_array_index(lm->dimensions, n);
                emit_continue("%s%s * ", dim_size_prefix(dim->size), dim->size);
            }
            if(ndim > 0) {
                lcm_dimension_t *dim = (lcm_dimension_t*) g_ptr_array_index(lm->dimensions, ndim - 1);
                emit_end("__%s_encoded_array_size(NULL, %s%s);",
                         lm->type->lctypename, dim_size_prefix(dim->size), dim->size);
            } else {
                emit_end("__%s_encoded_array_size(NULL, 1);", lm->type->lctypename);
            }
        } else {
            for(int n=0; n < ndim; n++) {
                lcm_dimension_t *dim = (lcm_dimension_t*) g_ptr_array_index(lm->dimensions, n);
                emit(1+n, "for (int a%d = 0; a%d < %s%s; a%d++) {",
                     n, n, dim_size_prefix(dim->size), dim->size, n);
            }
            emit_start(ndim + 1, "enc_size += this->%s", lm->membername);
            for(int i=0; i<ndim; i++)
                emit_continue("[a%d]", i);
            if(!strcmp(lm->type->lctypename, "string")) {
                emit_end(".size() + 4 + 1;");
            } else {
                emit_end("._getEncodedSizeNoHash();");
            }
            for(int n=ndim-1; n >= 0; n--) {
                emit(1 + n, "}");
            }
        }
    }
    emit(1, "return enc_size;");
    emit(0,"}");
    emit(0,"");
}
예제 #4
0
파일: emit_m.c 프로젝트: cd127/lcm-1
static int emit_decode_nohash(lcmgen_t *lcm, lcm_struct_t *ls)
{
	start_file("_decode_nohash");

    emit(0, "function [pos, S] = %s_decode_nohash(buf, pos, maxlen, S, elems)", sn);
	emit(1,   "for ix = 1:elems");
    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);
		char* lm_tnc = dots_to_double_colons(lm->type->lctypename);

		int const dimensions = g_ptr_array_size(lm->dimensions);
		if (0 == dimensions) {
			emit(2, "[pos, t] = %s_decode_nohash(buf, pos, maxlen, S(ix).%s, 1);", map_type_name(lm_tnc), lm->membername);
			emit(2, "S(ix).%s = t(1);", lm->membername);
		}
		else {
			//emit: for each dimension
			for (int dx = 0; dx < dimensions - 1; ++dx) {
				lcm_dimension_t *dim = (lcm_dimension_t*) g_ptr_array_index(lm->dimensions, dx);
				emit(2 + dx, "for dx%d = 1:%s", dx, dim->size);
			}

			{//do
				emit_start(1 + (dimensions > 1 ? dimensions : 1), "[pos, t] = %s_decode_nohash(buf, pos, maxlen, S(ix).%s(", map_type_name(lm_tnc), lm->membername);
				for (int dx = 0; dx < dimensions - 1; ++dx) {
					emit_continue("dx%d,", dx);
				}
				lcm_dimension_t *dim = (lcm_dimension_t*) g_ptr_array_index(lm->dimensions, dimensions - 1);
				emit_end(":), %s);", dim->size);

				emit_start(1 + (dimensions > 1 ? dimensions : 1), "S(ix).%s(", lm->membername);
				for (int dx = 0; dx < dimensions - 1; ++dx) {
					emit_continue("dx%d,", dx);
				}
				emit_end(":) = t(1:%s);", dim->size);
			}

			//end
			for (int dx = dimensions - 1; dx > 0; --dx) {
				emit(1 + dx, "end");
			}
		}
		free(lm_tnc);
	}
    emit(1,   "end");
    emit(0, "%%endfunction");
	end_file();
}
예제 #5
0
파일: emit_lua.c 프로젝트: GArlington/lcm
static void
_flush_read_struct_fmt (const lcmgen_t *lcm, FILE *f, 
        GQueue *formats, GQueue *members)
{
    int nfmts = g_queue_get_length(formats);
    assert (nfmts == g_queue_get_length (members));
    if(nfmts == 0) 
        return;

    emit_start(1, ""); // for indent
    int fmtsize = 0;
    while (! g_queue_is_empty (members)) {
        lcm_member_t *lm = (lcm_member_t*) g_queue_pop_head (members);
        emit_continue ("obj.%s", lm->membername);
        if (! g_queue_is_empty (members)) {
            emit_continue (", ");
        }
        fmtsize += _primitive_type_size (lm->type->lctypename);
    }
    emit_continue (" = lcm._pack.unpack('>");
    while (! g_queue_is_empty (formats)) {
        emit_continue ("%c", GPOINTER_TO_INT (g_queue_pop_head (formats)));
    }
    emit_end ("', data:read(%d))", fmtsize);
}
예제 #6
0
 void Prepreprocess::exact_quote(const std::string &line)  
 {
   int end=line.length();
   state=START;
   for (int pos=0; pos<end; ++pos) emit_char(line[pos]);
   emit_end();
 }
예제 #7
0
파일: emit_python.c 프로젝트: OxDuke/lcm
static void
_flush_read_struct_fmt (const lcmgen_t *lcm, FILE *f, 
        GQueue *formats, GQueue *members)
{
    int nfmts = g_queue_get_length(formats);
    assert (nfmts == g_queue_get_length (members));
    if(nfmts == 0) 
        return;

    fprintf (f, "        ");
    int fmtsize = 0;
    while (! g_queue_is_empty (members)) {
        lcm_member_t *lm = (lcm_member_t*) g_queue_pop_head (members);
        emit_continue ("self.%s", lm->membername);
        if (! g_queue_is_empty (members)) {
            emit_continue (", ");
        }
        fmtsize += _primitive_type_size (lm->type->lctypename);
    }
    emit_continue (" = struct.unpack(\">");
    while (! g_queue_is_empty (formats)) {
        emit_continue ("%c", GPOINTER_TO_INT (g_queue_pop_head (formats)));
    }
    emit_end ("\", buf.read(%d))%s", fmtsize, nfmts == 1 ? "[0]" : "");
}
예제 #8
0
파일: emit_cpp.c 프로젝트: cd127/lcm-1
static void _encode_recursive(lcmgen_t* lcm, FILE* f, lcm_member_t* lm, int depth, int extra_indent)
{
    int indent = extra_indent + 1 + depth;
    // primitive array
    if (depth+1 == g_ptr_array_size(lm->dimensions) &&
            lcm_is_primitive_type(lm->type->lctypename) &&
            strcmp(lm->type->lctypename, "string")) {
        lcm_dimension_t *dim = (lcm_dimension_t*) g_ptr_array_index(lm->dimensions, depth);
        emit_start(indent, "tlen = __%s_encode_array(buf, offset + pos, maxlen - pos, &this->%s",
                   lm->type->lctypename, lm->membername);
        for(int i=0; i<depth; i++)
            emit_continue("[a%d]", i);
        emit_end("[0], %s%s);", dim_size_prefix(dim->size), dim->size);

        emit(indent, "if(tlen < 0) return tlen; else pos += tlen;");
        return;
    }
    //
    if(depth == g_ptr_array_size(lm->dimensions)) {
        if(!strcmp(lm->type->lctypename, "string")) {
            emit_start(indent, "char* __cstr = (char*) this->%s", lm->membername);
            for(int i=0; i<depth; i++)
                emit_continue("[a%d]", i);
            emit_end(".c_str();");
            emit(indent, "tlen = __string_encode_array(buf, offset + pos, maxlen - pos, &__cstr, 1);");
        } else {
            emit_start(indent, "tlen = this->%s", lm->membername);
            for(int i=0; i<depth; i++)
                emit_continue("[a%d]", i);
            emit_end("._encodeNoHash(buf, offset + pos, maxlen - pos);");
        }
        emit(indent, "if(tlen < 0) return tlen; else pos += tlen;");
        return;
    }

    lcm_dimension_t *dim = (lcm_dimension_t*) g_ptr_array_index(lm->dimensions, depth);

    emit(indent, "for (int a%d = 0; a%d < %s%s; a%d++) {",
         depth, depth, dim_size_prefix(dim->size), dim->size, depth);

    _encode_recursive(lcm, f, lm, depth+1, extra_indent);

    emit(indent, "}");
}
예제 #9
0
파일: emit_m.c 프로젝트: cd127/lcm-1
static int emit_header(lcmgen_t *lcm, lcm_struct_t *ls)
{
	start_file("_new");

    // define the class
    emit(0, "function S = %s_new()", sn);
    emit(1,   "S = struct(...");

    // data members
	int const members = g_ptr_array_size(ls->members);

	for (unsigned int mx = 0; mx < members; mx++) {
		lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, mx);
		char* lm_tnc = dots_to_double_colons(lm->type->lctypename);

		emit_start(2, "'%s', ", lm->membername);
		int const dimensions = g_ptr_array_size(lm->dimensions);
		int const primitive = lcm_is_primitive_type(lm->type->lctypename);
		if (0 == dimensions) {
			emit_continue("%s%s", map_type_name(lm_tnc) , primitive ? "(0)" : "_new()");
		} else {
			emit_continue("repmat( %s%s, [", map_type_name(lm_tnc), primitive ? "(0)" : "_new()");
			for (int dx = 0; dx < dimensions - 1; ++dx) {
				lcm_dimension_t *dim = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, dx);
				emit_continue("%s, ", dim->size);
			}
			lcm_dimension_t *dim = (lcm_dimension_t*) g_ptr_array_index(lm->dimensions, dimensions - 1);
			emit_continue("%s%s] )", dim->size, dimensions == 1 ? ", 1" : "");
		}
		emit_end("%s", (members == mx + 1 ? " );" : ",..."));
	}
	emit(0, "%%endfunction");
	emit(0, "");

//    // constants TODO
//    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));
//
//            const char *suffix = "";
//            if (!strcmp(lc->lctypename, "int64_t"))
//              suffix = "LL";
//            char const * 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(9, "};");
//
//    free(tn_);
	end_file();
}
예제 #10
0
int dec64_to_string(
    dec64_string_state state,
    dec64 number,
    dec64_string_char string[]
) {
/*
    dec64_to_string converts a dec64 number into a string. The caller provides
    the memory in which to deposit the string. The string must have sufficient
    capacity to hold 32 characters. If NULL is passed in as the string, then
    no characters will be deposited, but a character count will be returned.

    dec64_to_string returns the number of characters actually deposited in the
    string (not including the trailing \0). If the number is nan, then it
    returns 0 indicating an empty string.

    In standard mode, the number will be formatted conventionally unless it
    would require more than 17 digits, which would be due to excessive
    trailing zeros or zeros immediately after the decimal point. In that
    case scientific notation will be used instead.
*/
    if (state == NULL || state->valid != confirmed) {
        return 0;
    }

    state->length = 0;
    state->string = string;
    if (dec64_is_any_nan(number) != DEC64_TRUE) {
        if (dec64_is_zero(number) == DEC64_TRUE) {
            emit(state, '0');
        } else {
            if (number != state->number) {
                state->number = number;
                digitize(state);
            }
            if (number < 0) {
                emit(state, '-');
            }
            switch (state->mode) {
            case engineering_mode:
                engineering(state);
                break;
            case scientific_mode:
                scientific(state);
                break;
            case standard_mode:
                standard(state);
                break;
            }
        }
    }
    emit_end(state);
    state->string = NULL;
    return state->length;
}
예제 #11
0
파일: emit_java.c 프로젝트: gizatt/zcm
void encode_recursive(zcmgen_t *zcm, zcm_member_t *lm, FILE *f, primitive_info_t *pinfo, char *accessor, int depth)
{
    // base case: primitive array
    if (depth+1 == g_ptr_array_size(lm->dimensions) && pinfo != NULL) {
        char accessor_array[1024];
        make_accessor_array(lm, "", accessor_array);

        if (!strcmp(pinfo->storage, "byte")) {
            zcm_dimension_t *dim = (zcm_dimension_t*) g_ptr_array_index(lm->dimensions, depth);
            if (dim->mode == ZCM_VAR) {
                emit(2+depth, "if (this.%s > 0)", dim->size);
                emit(3+depth, "outs.write(this.%s, 0, %s);", accessor_array, dim->size);
            } else {
                emit(2+depth, "outs.write(this.%s, 0, %s);", accessor_array, dim->size);
            }
            return;
        }

        // some other kind of primitive array.
        // This seems to be slower than the default (and is untested for correctness), hence it is disabled.
        if (0 && !strcmp(pinfo->storage, "float")) {

            zcm_dimension_t *dim = (zcm_dimension_t*) g_ptr_array_index(lm->dimensions, depth);

            emit(2+depth, "{ ByteBuffer bbuf = ByteBuffer.allocate(%s%s*4); bbuf.order(ByteOrder.BIG_ENDIAN); ", dim_size_prefix(dim->size), dim->size);
            emit(2+depth, "  bbuf.asFloatBuffer().put(this.%s);", accessor_array);
            emit(2+depth, "  outs.write(bbuf.array()); }");
            return;
        }
    }


    // base case: generic
    if (depth == g_ptr_array_size(lm->dimensions)) {
        emit_start(2 + g_ptr_array_size(lm->dimensions),"");
        if (pinfo != NULL)
            freplace(f, pinfo->encode, accessor);
        else
            freplace(f, "#._encodeRecursive(outs);", accessor);
        emit_end(" ");

        return;
    }

    zcm_dimension_t *dim = (zcm_dimension_t*) g_ptr_array_index(lm->dimensions, depth);

    emit(2+depth, "for (int %c = 0; %c < %s%s; %c++) {",
         'a'+depth, 'a'+depth, dim_size_prefix(dim->size), dim->size, 'a'+depth);

    encode_recursive(zcm, lm, f, pinfo, accessor, depth+1);

    emit(2+depth, "}");
}
예제 #12
0
파일: emit_java.c 프로젝트: gizatt/zcm
void decode_recursive(zcmgen_t *zcm, zcm_member_t *lm, FILE *f, primitive_info_t *pinfo, char *accessor, int depth)
{
    // base case: primitive array
    if (depth+1 == g_ptr_array_size(lm->dimensions) && pinfo != NULL) {

        char accessor_array[1024];
        make_accessor_array(lm, "", accessor_array);

        // byte array
        if (!strcmp(pinfo->storage, "byte")) {
            zcm_dimension_t *dim = (zcm_dimension_t*) g_ptr_array_index(lm->dimensions, depth);
            emit_start(2+depth, "ins.readFully(this.%s, 0, %s);", accessor_array, dim->size);
            return;
        }

        // some other kind of primitive array.
        // This seems to be slower than the default (and is untested for correctness), hence it is disabled.
        if (0 && !strcmp(pinfo->storage, "float")) {
            zcm_dimension_t *dim = (zcm_dimension_t*) g_ptr_array_index(lm->dimensions, depth);

            emit(2+depth, "{ byte bb[] = new byte[%s%s*4]; ins.readFully(bb); ByteBuffer bbuf = ByteBuffer.wrap(bb); bbuf.order(ByteOrder.BIG_ENDIAN); ", dim_size_prefix(dim->size), dim->size);
            emit(2+depth, "  bbuf.asFloatBuffer().get(this.%s); }", accessor_array);
            return;
        }
  }

    // base case: generic
    if (depth == g_ptr_array_size(lm->dimensions)) {
        emit_start(2 + g_ptr_array_size(lm->dimensions),"");
        if (pinfo != NULL)
            freplace(f, pinfo->decode, accessor);
        else {
            emit_continue("%s = %s._decodeRecursiveFactory(ins);", accessor, make_fqn(zcm, lm->type->lctypename));
        }
        emit_end("");

        return;
    }

    zcm_dimension_t *dim = (zcm_dimension_t*) g_ptr_array_index(lm->dimensions, depth);

    emit(2+depth, "for (int %c = 0; %c < %s%s; %c++) {",
         'a'+depth, 'a'+depth, dim_size_prefix(dim->size), dim->size, 'a'+depth);

    decode_recursive(zcm, lm, f, pinfo, accessor, depth+1);

    emit(2+depth, "}");
}
예제 #13
0
static void
emit_python_fingerprint (const lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    const char *sn = ls->structname->shortname;
    emit (1, "_hash = None");

    emit (1, "def _get_hash_recursive(parents):");
    emit (2,     "if %s in parents: return 0", sn);
    for (unsigned int m = 0; m < ls->members->len; m++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, m);
        if (! lcm_is_primitive_type (lm->type->lctypename)) {
            emit (2,     "newparents = parents + [%s]", sn);
            break;
        }
    }
    emit_start (2, "tmphash = (0x%"PRIx64, ls->hash);
    for (unsigned int m = 0; m < ls->members->len; m++) {
        lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index(ls->members, m);
        const char *msn = lm->type->shortname;
        if (! lcm_is_primitive_type (lm->type->lctypename)) {
            const char *ghr = "_get_hash_recursive(newparents)";
            if (is_same_type (lm->type, ls->structname)) {
                emit_continue ("+ %s.%s", msn, ghr);
            } else if (is_same_package (lm->type, ls->structname)) {
                emit_continue ("+ %s.%s.%s", msn, msn, ghr);
            } else {
                emit_continue ("+ %s.%s", lm->type->lctypename, ghr);
            }
        }
    }
    emit_end (") & 0xffffffffffffffff");
    emit (2, "tmphash  = (((tmphash<<1)&0xffffffffffffffff)  + "
            "(tmphash>>63)) & 0xffffffffffffffff");
    emit (2,     "return tmphash");
    emit (1, "_get_hash_recursive = staticmethod(_get_hash_recursive)");

    emit (1, "_packed_fingerprint = None");
    emit (0, "");
    emit (1, "def _get_packed_fingerprint():");
    emit (2,     "if %s._packed_fingerprint is None:", sn);
    emit (3,         "%s._packed_fingerprint = struct.pack(\">Q\", "
            "%s._get_hash_recursive([]))", sn, sn);
    emit (2,     "return %s._packed_fingerprint", sn);
    emit (1, "_get_packed_fingerprint = staticmethod(_get_packed_fingerprint)");
    fprintf (f, "\n");

}
예제 #14
0
파일: emit_python.c 프로젝트: OxDuke/lcm
static void
_flush_write_struct_fmt (FILE *f, GQueue *formats, GQueue *members)
{
    assert (g_queue_get_length (formats) == g_queue_get_length (members));
    if (g_queue_is_empty (formats)) return;
    emit_start (2, "buf.write(struct.pack(\">");
    while (! g_queue_is_empty (formats)) {
        emit_continue ("%c", GPOINTER_TO_INT (g_queue_pop_head (formats)));
    }
    emit_continue ("\", ");
    while (! g_queue_is_empty (members)) {
        lcm_member_t *lm = (lcm_member_t*) g_queue_pop_head (members);
        emit_continue ("self.%s", lm->membername);
        if (! g_queue_is_empty (members)) {
            emit_continue (", ");
        }
    }
    emit_end ("))");
}
예제 #15
0
  void Prepreprocess::magic_quote(const std::string &line)
  {
    int end=line.length();
    bool use_suffix=true;

    state=START;

    for (int pos=0; pos<end; ++pos) {
      if (line[pos]=='$') {
	if (pos == end-1) {
	  use_suffix=false;
	  break;
	} else {
	  if (id0(line[pos+1])) {
	    ++pos;
	    int begin=pos;
	    while (pos < end && id1(line[pos])) ++pos;
	    emit_expression(line.substr(begin,(pos-begin)));
	    --pos;
	    continue;
	  }
	  if (line[pos+1] == '(') {
	    ++pos;
	    int begin=pos;
	    int parens=0;
	    while (pos < end) {
	      if (line[pos]=='(') ++parens;
	      if (line[pos]==')') {--parens; if (parens==0) { ++pos; break; } }
	      ++pos;
	    }
	    emit_expression(line.substr(begin,(pos-begin)));
	    --pos;
	    continue;
	  }
	  if (line[pos+1]=='$') {
	    ++pos;
	  }
	}
      }
      emit_char(line[pos]);
    }
    emit_end(use_suffix);
  }
예제 #16
0
파일: emit_lua.c 프로젝트: GArlington/lcm
static void
_flush_write_struct_fmt (FILE *f, GQueue *formats, GQueue *members)
{
	// XXX encode primitive members in one line
    assert (g_queue_get_length (formats) == g_queue_get_length (members));
    if (g_queue_is_empty (formats)) return;
    emit_start (1, "table.insert(buf_table, lcm._pack.pack('>");
    while (! g_queue_is_empty (formats)) {
        emit_continue ("%c", GPOINTER_TO_INT (g_queue_pop_head (formats)));
    }
    emit_continue ("', ");
    while (! g_queue_is_empty (members)) {
        lcm_member_t *lm = (lcm_member_t*) g_queue_pop_head (members);
        emit_continue ("self.%s", lm->membername);
        if (! g_queue_is_empty (members)) {
            emit_continue (", ");
        }
    }
    emit_end ("))");
}
예제 #17
0
파일: emit_cpp.c 프로젝트: ahans/lcm
/** 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_);
}
예제 #18
0
파일: emit_c.c 프로젝트: tbeu/lcm
/** 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);
}
예제 #19
0
파일: emit_cpp.c 프로젝트: cd127/lcm-1
static void _decode_recursive(lcmgen_t* lcm, FILE* f, lcm_member_t* lm, int depth)
{
    // primitive array
    if (depth+1 == g_ptr_array_size(lm->dimensions) &&
            lcm_is_primitive_type(lm->type->lctypename) &&
            strcmp(lm->type->lctypename, "string")) {
        lcm_dimension_t *dim = (lcm_dimension_t*) g_ptr_array_index(lm->dimensions, depth);

        int decode_indent = 1 + depth;
        if(!lcm_is_constant_size_array(lm)) {
            emit(1 + depth, "if(%s%s) {", dim_size_prefix(dim->size), dim->size);
            emit_start(2 + depth, "this->%s", lm->membername);
            for(int i=0; i<depth; i++)
                emit_continue("[a%d]", i);
            emit_end(".resize(%s%s);", dim_size_prefix(dim->size), dim->size);
            decode_indent++;
        }

        emit_start(decode_indent, "tlen = __%s_decode_array(buf, offset + pos, maxlen - pos, &this->%s",
                   lm->type->lctypename, lm->membername);
        for(int i=0; i<depth; i++)
            emit_continue("[a%d]", i);
        emit_end("[0], %s%s);", dim_size_prefix(dim->size), dim->size);
        emit(decode_indent, "if(tlen < 0) return tlen; else pos += tlen;");
        if(!lcm_is_constant_size_array(lm)) {
            emit(1 + depth, "}");
        }
    } else if(depth == g_ptr_array_size(lm->dimensions)) {
        if(!strcmp(lm->type->lctypename, "string")) {
            emit(1 + depth, "int32_t __elem_len;");
            emit(1 + depth, "tlen = __int32_t_decode_array(buf, offset + pos, maxlen - pos, &__elem_len, 1);");
            emit(1 + depth, "if(tlen < 0) return tlen; else pos += tlen;");
            emit(1 + depth, "if(__elem_len > maxlen - pos) return -1;");
            emit_start(1 + depth, "this->%s", lm->membername);
            for(int i=0; i<depth; i++)
                emit_continue("[a%d]", i);
            emit_end(".assign(((const char*)buf) + offset + pos, __elem_len -  1);");
            emit(1 + depth, "pos += __elem_len;");
        } else {
            emit_start(1 + depth, "tlen = this->%s", lm->membername);
            for(int i=0; i<depth; i++)
                emit_continue("[a%d]", i);
            emit_end("._decodeNoHash(buf, offset + pos, maxlen - pos);");
            emit(1 + depth, "if(tlen < 0) return tlen; else pos += tlen;");
        }
    } else {
        lcm_dimension_t *dim = (lcm_dimension_t*) g_ptr_array_index(lm->dimensions, depth);

        if(!lcm_is_constant_size_array(lm)) {
            emit_start(1+depth, "this->%s", lm->membername);
            for(int i=0; i<depth; i++) {
                emit_continue("[a%d]", i);
            }
            emit_end(".resize(%s%s);", dim_size_prefix(dim->size), dim->size);
        }
        emit(1+depth, "for (int a%d = 0; a%d < %s%s; a%d++) {",
             depth, depth, dim_size_prefix(dim->size), dim->size, depth);

        _decode_recursive(lcm, f, lm, depth+1);

        emit(1+depth, "}");
    }
}
예제 #20
0
파일: emit_cpp.c 프로젝트: cd127/lcm-1
/** 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_);
}
예제 #21
0
bool multiget_ascii_downstream(downstream *d, conn *uc,
    int (*emit_start)(conn *c, char *cmd, int cmd_len),
    int (*emit_skey)(conn *c, char *skey, int skey_len),
    int (*emit_end)(conn *c),
    mcache *front_cache) {
    assert(d != NULL);
    assert(d->downstream_conns != NULL);
    assert(d->multiget == NULL);
    assert(uc != NULL);
    assert(uc->noreply == false);

    proxy_td *ptd = d->ptd;
    assert(ptd != NULL);

    proxy_stats_cmd *psc_get =
        &ptd->stats.stats_cmd[STATS_CMD_TYPE_REGULAR][STATS_CMD_GET];
    proxy_stats_cmd *psc_get_key =
        &ptd->stats.stats_cmd[STATS_CMD_TYPE_REGULAR][STATS_CMD_GET_KEY];

    int nwrite = 0;
    int nconns = mcs_server_count(&d->mst);

    for (int i = 0; i < nconns; i++) {
        if (d->downstream_conns[i] != NULL &&
            cproxy_prep_conn_for_write(d->downstream_conns[i]) == false) {
            d->ptd->stats.stats.err_downstream_write_prep++;
            cproxy_close_conn(d->downstream_conns[i]);
            return false;
        }
    }

    if (uc->next != NULL) {
        // More than one upstream conn, so we need a hashtable
        // to track keys for de-deplication.
        //
        d->multiget = genhash_init(128, skeyhash_ops);
        if (settings.verbose > 1) {
            fprintf(stderr, "cproxy multiget hash table new\n");
        }
    }

    // Snapshot the volatile only once.
    //
    uint32_t msec_current_time_snapshot = msec_current_time;

    int   uc_num = 0;
    conn *uc_cur = uc;

    while (uc_cur != NULL) {
        assert(uc_cur->cmd == -1);
        assert(uc_cur->item == NULL);
        assert(uc_cur->state == conn_pause);
        assert(IS_ASCII(uc_cur->protocol));
        assert(IS_PROXY(uc_cur->protocol));

        char *command = uc_cur->cmd_start;
        assert(command != NULL);

        char *space = strchr(command, ' ');
        assert(space > command);

        int cmd_len = space - command;
        assert(cmd_len == 3 || cmd_len == 4); // Either get or gets.

        int cas_emit = (command[3] == 's');

        if (settings.verbose > 1) {
            fprintf(stderr, "forward multiget %s (%d %d)\n",
                    command, cmd_len, uc_num);
        }

        while (space != NULL) {
            char *key = space + 1;
            char *next_space = strchr(key, ' ');
            int   key_len;

            if (next_space != NULL) {
                key_len = next_space - key;
            } else {
                key_len = strlen(key);

                // We've reached the last key.
                //
                psc_get->read_bytes += (key - command + key_len);
            }

            // This key_len check helps skip consecutive spaces.
            //
            if (key_len > 0) {
                ptd->stats.stats.tot_multiget_keys++;

                psc_get_key->seen++;
                psc_get_key->read_bytes += key_len;

                // Update key-based statistics.
                //
                bool do_key_stats =
                    matcher_check(&ptd->key_stats_matcher,
                                  key, key_len, true) == true &&
                    matcher_check(&ptd->key_stats_unmatcher,
                                  key, key_len, false) == false;

                if (do_key_stats) {
                    touch_key_stats(ptd, key, key_len,
                                    msec_current_time_snapshot,
                                    STATS_CMD_TYPE_REGULAR,
                                    STATS_CMD_GET_KEY,
                                    1, 0, 0,
                                    key_len, 0);
                }

                // Handle a front cache hit by queuing response.
                //
                // Note, front cache stats are part of mcache.
                //
                if (!cas_emit) {
                    item *it = mcache_get(front_cache, key, key_len,
                                          msec_current_time_snapshot);
                    if (it != NULL) {
                        assert(it->nkey == key_len);
                        assert(strncmp(ITEM_key(it), key, it->nkey) == 0);

                        cproxy_upstream_ascii_item_response(it, uc_cur, 0);

                        psc_get_key->hits++;
                        psc_get_key->write_bytes += it->nbytes;

                        if (do_key_stats) {
                            touch_key_stats(ptd, key, key_len,
                                            msec_current_time_snapshot,
                                            STATS_CMD_TYPE_REGULAR,
                                            STATS_CMD_GET_KEY,
                                            0, 1, 0,
                                            0, it->nbytes);
                        }

                        // The refcount was inc'ed by mcache_get() for us.
                        //
                        item_remove(it);

                        goto loop_next;
                    }
                }

                bool self = false;

                conn *c = cproxy_find_downstream_conn(d, key, key_len,
                                                      &self);
                if (c != NULL) {
                    if (self) {
                        // Optimization for talking with ourselves,
                        // to avoid extra network hop.
                        //
                        ptd->stats.stats.tot_optimize_self++;

                        item *it = item_get(key, key_len);
                        if (it != NULL) {
                            cproxy_upstream_ascii_item_response(it, uc_cur,
                                                                cas_emit);

                            psc_get_key->hits++;
                            psc_get_key->write_bytes += it->nbytes;

                            if (do_key_stats) {
                                touch_key_stats(ptd, key, key_len,
                                                msec_current_time_snapshot,
                                                STATS_CMD_TYPE_REGULAR,
                                                STATS_CMD_GET_KEY,
                                                0, 1, 0,
                                                0, it->nbytes);
                            }

                            // The refcount was inc'ed by item_get() for us.
                            //
                            item_remove(it);

                            if (settings.verbose > 1) {
                                fprintf(stderr,
                                        "optimize self multiget hit: %s\n",
                                        key);
                            }
                        } else {
                            psc_get_key->misses++;

                            if (do_key_stats) {
                                touch_key_stats(ptd, key, key_len,
                                                msec_current_time_snapshot,
                                                STATS_CMD_TYPE_REGULAR,
                                                STATS_CMD_GET_KEY,
                                                0, 0, 1,
                                                0, 0);
                            }

                            if (settings.verbose > 1) {
                                fprintf(stderr,
                                        "optimize self multiget miss: %s\n",
                                        key);
                            }
                        }

                        goto loop_next;
                    }

                    // See if we've already requested this key via
                    // the multiget hash table, in order to
                    // de-deplicate repeated keys.
                    //
                    bool first_request = true;

                    if (d->multiget != NULL) {
                        // TODO: Use Trond's allocator here.
                        //
                        multiget_entry *entry =
                            calloc(1, sizeof(multiget_entry));
                        if (entry != NULL) {
                            entry->upstream_conn = uc_cur;
                            entry->opaque = 0;
                            entry->hits = 0;
                            entry->next = genhash_find(d->multiget, key);

                            genhash_update(d->multiget, key, entry);

                            if (entry->next != NULL) {
                                first_request = false;
                            }
                        } else {
                            // TODO: Handle out of multiget entry memory.
                        }
                    }

                    if (first_request) {
                        assert(c->item == NULL);
                        assert(c->state == conn_pause);
                        assert(IS_PROXY(c->protocol));
                        assert(c->ilist != NULL);
                        assert(c->isize > 0);

                        if (c->msgused <= 1 &&
                            c->msgbytes <= 0) {
                            emit_start(c, command, cmd_len);
                        }

                        // Provide the preceding space as optimization
                        // for ascii-to-ascii configuration.
                        //
                        emit_skey(c, key - 1, key_len + 1);
                    } else {
                        ptd->stats.stats.tot_multiget_keys_dedupe++;

                        if (settings.verbose > 1) {
                            char buf[KEY_MAX_LENGTH + 10];
                            memcpy(buf, key, key_len);
                            buf[key_len] = '\0';

                            fprintf(stderr,
                                    "%d cproxy multiget dedpue: %s\n",
                                    uc_cur->sfd, buf);
                        }
                    }
                } else {
                    // TODO: Handle when downstream conn is down.
                }
            }

        loop_next:
            space = next_space;
        }

        uc_num++;
        uc_cur = uc_cur->next;
    }

    for (int i = 0; i < nconns; i++) {
        conn *c = d->downstream_conns[i];
        if (c != NULL &&
            (c->msgused > 1 ||
             c->msgbytes > 0)) {
            emit_end(c);

            conn_set_state(c, conn_mwrite);
            c->write_and_go = conn_new_cmd;

            if (update_event(c, EV_WRITE | EV_PERSIST)) {
                nwrite++;

                if (uc->noreply) {
                    c->write_and_go = conn_pause;
                }
            } else {
                if (settings.verbose > 1) {
                    fprintf(stderr,
                            "Couldn't update cproxy write event\n");
                }

                d->ptd->stats.stats.err_oom++;
                cproxy_close_conn(c);
            }
        }
    }

    if (settings.verbose > 1) {
        fprintf(stderr, "forward multiget nwrite %d out of %d\n",
                nwrite, nconns);
    }

    d->downstream_used_start = nwrite;
    d->downstream_used       = nwrite;

    if (cproxy_dettach_if_noreply(d, uc) == false) {
        d->upstream_suffix = "END\r\n";

        cproxy_start_downstream_timeout(d, NULL);
    }

    return nwrite > 0;
}
예제 #22
0
파일: emit_cpp.c 프로젝트: cd127/lcm-1
static void emit_compare(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    const char *sn = ls->structname->shortname;
    emit(0, "/// Deep compare. FIXME floats and doubles are compared to 1e-5");
    emit(0, "bool %s::operator==(%s const & other) const", sn, sn);
    emit(0, "{");
    if(0 == g_ptr_array_size(ls->members)) {
        emit(1,     "return true;");
        emit(0,"}");
        emit(0,"");
        return;
    }
    // For each member (non-array)
    uint8_t firstNonArray = 1;
    uint8_t arraysExist = 0;
    emit_start(1, "bool equal = true;");
    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);
        uint8_t isFloat = (0==strcmp(lm->type->lctypename,"float")) || (0==strcmp(lm->type->lctypename,"double"));

        // Deal with arrays afterwards
        if (0 != g_ptr_array_size(lm->dimensions)) {
            arraysExist = 1;
            continue;
        }

        emit_end("");
        if (firstNonArray) {
            if (isFloat) {
                emit_start(1, "equal = ( (std::fabs(%s - other.%s) < 1e-5) )", lm->membername, lm->membername);
            }
            else {
                emit_start(1, "equal = (%s == other.%s)", lm->membername, lm->membername);
            }
            firstNonArray = 0;
        }
        else {
            if (isFloat) {
                emit_start(2, "&& ( (std::fabs(%s - other.%s) < 1e-5) )", lm->membername, lm->membername);
            }
            else {
                emit_start(2, "&& (%s == other.%s)", lm->membername, lm->membername);
            }
        }
    }
    emit_end(";");
    emit(0,"");

    if (arraysExist) {
        emit(1, "if (!equal) {");
        emit(2, "return false;");
        emit(1, "}");
        emit(0,"");
        // For each array member
        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);
            int numDim = g_ptr_array_size(lm->dimensions);

            if (0 == numDim) {
                continue;
            }

            uint8_t isFloat = (0==strcmp(lm->type->lctypename,"float")) || (0==strcmp(lm->type->lctypename,"double"));

            char * dimStr = g_strdup_printf("");
            for (uint8_t dim = 0; dim < numDim; ++dim) {
                lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, dim);
                emit(1+dim, "for ( uint dim%i = 0; dim%i < %i; ++dim%i)", dim, dim, atoi(ld->size) , dim);
                char * tmpStr = g_strdup_printf("%s", dimStr);
                g_free(dimStr);
                dimStr = g_strdup_printf("%s[dim%i]", tmpStr, dim);
                g_free(tmpStr);
            }

            emit (numDim, "{");
            if (isFloat) {
                emit (numDim+1, "if ( (std::fabs(%s - other.%s) > 1e-5) )", lm->membername, lm->membername);
            }
            else {
                emit (numDim+1, "if (!(%s%s == other.%s%s))", lm->membername, dimStr, lm->membername, dimStr);
            }
            emit (numDim+1, "{");
            emit (numDim+2, "return false;");
            emit (numDim+1, "}");

            emit (numDim, "}");

            emit(0,"");
            g_free(dimStr);
        }
    }
    emit(1, "return equal;");
    emit(0,"}");
    emit(0,"");
}
예제 #23
0
파일: emit_cpp.c 프로젝트: cd127/lcm-1
static void emit_print(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    const char *sn = ls->structname->shortname;
    emit(0, "std::string %s::toDebugStr(std::string const & layout) const", sn);
    emit(0, "{");
    if(0 == g_ptr_array_size(ls->members)) {
        emit(1,     "return \"\";");
        emit(0,"}");
        emit(0,"");
        return;
    }
    emit(1, "std::stringstream ss(\"\");");
    // For each member
    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);
        uint8_t isString = (0==strcmp(lm->type->lctypename,"string"));
        int ndim = g_ptr_array_size(lm->dimensions);

        char * valueAssignment;
        char * valueAssignment2;     // Needs to be split for possibly adding array index
        if (isString) {
            valueAssignment = g_strdup_printf("= '\" << %s << \"'\"", lm->membername);
            valueAssignment2 = g_strdup_printf(" << std::endl;");
        }
        else if ( lcm_is_primitive_type(lm->type->lctypename) ) {
            valueAssignment = g_strdup_printf("= \" << std::to_string(%s", lm->membername);
            valueAssignment2 = g_strdup_printf(") << std::endl;");
        }
        else {
            valueAssignment = g_strdup_printf("\" << std::endl << %s", lm->membername);
            if (0==ndim) {
                valueAssignment2 = g_strdup_printf(".toDebugStr(\"  \"+layout);");
            }
            else {
                valueAssignment2 = g_strdup_printf(".toDebugStr(\"    \"+layout);");
            }
        }

        emit_start(1, "ss << layout << \"%s ", lm->membername);
        if (0==ndim) {
            emit_end("%s%s", valueAssignment, valueAssignment2);
        }
        else {
            // Check if it's a dynamic array, in which case we ignore it at the moment.
            uint8_t isDynamic=0;
            for (int dim=0; dim < ndim; ++dim) {
                lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, dim);
                if (!is_dim_size_fixed(ld->size)) {
                    isDynamic=1;
                    break;
                }
            }
            if (!isDynamic) {
                // End previous line so that each element is on a new line
                emit_end("\" << std::endl;");

                // Print first component in array
                emit_start(1, "ss << \"  \" << layout << \"");
                for (int dim=0; dim < ndim; ++dim) {
                    emit_continue("[0]");
                }
                emit_continue("%s", valueAssignment);
                for (int dim=0; dim < ndim; ++dim) { // Copy-paste is not pretty but is the simplest way to avoid mem allocation
                    emit_continue("[0]");
                }
                emit_end("%s", valueAssignment2);

                // Print last component in array
                emit_start(1, "ss << \"  \" << layout << \"");
                for (int dim=0; dim < ndim; ++dim) {
                    lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, dim);
                    emit_continue("[%i]", atoi(ld->size)-1);
                }
                emit_continue("%s", valueAssignment);
                for (int dim=0; dim < ndim; ++dim) { // Copy-paste is not pretty but is the simplest way to avoid mem allocation
                    lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, dim);
                    emit_continue("[%i]", atoi(ld->size)-1);
                }
                emit_end("%s", valueAssignment2);
            }
            else {
                emit_end("is a dynamic array\" << std::endl;");
            }
        }
        g_free (valueAssignment);
    }
    emit(0, "");
    emit(1, "return ss.str();");
    emit(0,"}");
    emit(0,"");
}
예제 #24
0
파일: emit_java.c 프로젝트: gizatt/zcm
int emit_java(zcmgen_t *zcm)
{
    GHashTable *type_table = g_hash_table_new(g_str_hash, g_str_equal);

    g_hash_table_insert(type_table, "byte",   prim("byte",
                                             "# = ins.readByte();",
                                             "outs.writeByte(#);"));
    g_hash_table_insert(type_table, "int8_t",   prim("byte",
                                               "# = ins.readByte();",
                                               "outs.writeByte(#);"));
    g_hash_table_insert(type_table, "int16_t",  prim("short",
                                               "# = ins.readShort();",
                                               "outs.writeShort(#);"));
    g_hash_table_insert(type_table, "int32_t",  prim("int",
                                               "# = ins.readInt();",
                                               "outs.writeInt(#);"));
    g_hash_table_insert(type_table, "int64_t",  prim("long",
                                               "# = ins.readLong();",
                                               "outs.writeLong(#);"));

    g_hash_table_insert(type_table, "string",   prim("String",
                                                     "__strbuf = new char[ins.readInt()-1]; for (int _i = 0; _i < __strbuf.length; _i++) __strbuf[_i] = (char) (ins.readByte()&0xff); ins.readByte(); # = new String(__strbuf);",
                                                     "__strbuf = new char[#.length()]; #.getChars(0, #.length(), __strbuf, 0); outs.writeInt(__strbuf.length+1); for (int _i = 0; _i < __strbuf.length; _i++) outs.write(__strbuf[_i]); outs.writeByte(0);"));

//    g_hash_table_insert(type_table, "string",   prim("String",
//                                               "__strbuf = new byte[ins.readInt()-1]; ins.readFully(__strbuf); ins.readByte(); # = new String(__strbuf, \"UTF-8\");",
//                                               "__strbuf = #.getBytes(\"UTF-8\"); outs.writeInt(__strbuf.length+1); outs.write(__strbuf, 0, __strbuf.length); outs.writeByte(0);"));

    g_hash_table_insert(type_table, "boolean",  prim("boolean",
                                               "# = ins.readByte()!=0;",
                                               "outs.writeByte( # ? 1 : 0);"));
    g_hash_table_insert(type_table, "float",    prim("float",
                                               "# = ins.readFloat();",
                                               "outs.writeFloat(#);"));
    g_hash_table_insert(type_table, "double",   prim("double",
                                               "# = ins.readDouble();",
                                               "outs.writeDouble(#);"));

    //////////////////////////////////////////////////////////////
    // ENUMS
    for (unsigned int en = 0; en < g_ptr_array_size(zcm->enums); en++) {
        zcm_enum_t *le = (zcm_enum_t *) g_ptr_array_index(zcm->enums, en);

        const char *classname = make_fqn(zcm, le->enumname->lctypename);
        char *path = g_strdup_printf("%s%s%s.java",
                                  getopt_get_string(zcm->gopt, "jpath"),
                                  strlen(getopt_get_string(zcm->gopt, "jpath")) > 0 ? G_DIR_SEPARATOR_S : "",
                                  dots_to_slashes(classname));

        if (!zcm_needs_generation(zcm, le->zcmfile, path))
            continue;

        if (getopt_get_bool(zcm->gopt, "jmkdir"))
            make_dirs_for_file(path);

        FILE *f = fopen(path, "w");
        if (f==NULL)
            return -1;

        if (strlen(le->enumname->package) > 0)
            emit(0, "package %s;", le->enumname->package);
        else
            emit(0, "package %s;", getopt_get_string(zcm->gopt, "jdefaultpkg"));

        emit(0, " ");
        emit(0, "import java.io.*;");
        emit(0, "import java.util.*;");
        emit(0, " ");

        emit(0, "public final class %s %s", le->enumname->shortname, getopt_get_string(zcm->gopt, "jdecl"));

        emit(0, "{");
        emit(1, "public int value;");
        emit(0, " ");

        for (unsigned int v = 0; v < g_ptr_array_size(le->values); v++) {
            zcm_enum_value_t *lev = (zcm_enum_value_t *) g_ptr_array_index(le->values, v);
            emit(1, "public static final int %-16s = %i;",
                    lev->valuename, lev->value);
        }
        emit(0," ");

        emit(1,"public %s(int value) { this.value = value; }",
                le->enumname->shortname);
        emit(0," ");

        emit(1,"public int getValue() { return value; }");
        emit(0," ");

        emit(1,"public void _encodeRecursive(DataOutput outs) throws IOException");
        emit(1,"{");
        emit(2,"outs.writeInt(this.value);");
        emit(1,"}");
        emit(0," ");

        emit(1,"public void encode(DataOutput outs) throws IOException");
        emit(1,"{");
        emit(2,"outs.writeLong(ZCM_FINGERPRINT);");
        emit(2,"_encodeRecursive(outs);");
        emit(1,"}");
        emit(0," ");

        emit(1,"public static %s _decodeRecursiveFactory(DataInput ins) throws IOException", make_fqn(zcm, le->enumname->lctypename));
        emit(1,"{");
        emit(2,"%s o = new %s(0);", make_fqn(zcm, le->enumname->lctypename), make_fqn(zcm, le->enumname->lctypename));
        emit(2,"o._decodeRecursive(ins);");
        emit(2,"return o;");
        emit(1,"}");
        emit(0," ");

        emit(1,"public void _decodeRecursive(DataInput ins) throws IOException");
        emit(1,"{");
        emit(2,"this.value = ins.readInt();");
        emit(1,"}");
        emit(0," ");

        emit(1,"public %s(DataInput ins) throws IOException", le->enumname->shortname);
        emit(1,"{");
        emit(2,"long hash = ins.readLong();");
        emit(2,"if (hash != ZCM_FINGERPRINT)");
        emit(3,     "throw new IOException(\"ZCM Decode error: bad fingerprint\");");
        emit(2,"_decodeRecursive(ins);");
        emit(1,"}");
        emit(0," ");

        emit(1,"public %s copy()", classname);
        emit(1,"{");
        emit(2,"return new %s(this.value);", classname);
        emit(1,"}");
        emit(0," ");

        emit(1,"public static final long _hashRecursive(ArrayList<Class<?>> clss)");
        emit(1,"{");
        emit(2,"return ZCM_FINGERPRINT;");
        emit(1,"}");
        emit(0," ");
        emit(1, "public static final long ZCM_FINGERPRINT = 0x%016"PRIx64"L;", le->hash);
        emit(0, "}");
        fclose(f);
    }

    for (unsigned int st = 0; st < g_ptr_array_size(zcm->structs); st++) {
        zcm_struct_t *lr = (zcm_struct_t *) g_ptr_array_index(zcm->structs, st);

        const char *classname = make_fqn(zcm, lr->structname->lctypename);
        char *path = g_strdup_printf("%s%s%s.java",
                                  getopt_get_string(zcm->gopt, "jpath"),
                                  strlen(getopt_get_string(zcm->gopt, "jpath")) > 0 ? G_DIR_SEPARATOR_S : "",
                                  dots_to_slashes(classname));

        if (!zcm_needs_generation(zcm, lr->zcmfile, path))
            continue;

        if (getopt_get_bool(zcm->gopt, "jmkdir"))
            make_dirs_for_file(path);

        FILE *f = fopen(path, "w");
        if (f==NULL)
            return -1;

        emit(0, "/* ZCM type definition class file\n"
                " * This file was automatically generated by zcm-gen\n"
                " * DO NOT MODIFY BY HAND!!!!\n"
                " */\n");

        if (strlen(lr->structname->package) > 0)
            emit(0, "package %s;", lr->structname->package);
        else
            emit(0, "package %s;", getopt_get_string(zcm->gopt, "jdefaultpkg"));

        emit(0, " ");
        emit(0, "import java.io.*;");

        if (0) {
            // Determine if we even need the java.nio.* package.
            int usenio = 0;
            for (unsigned int member = 0; member < g_ptr_array_size(lr->members); member++) {
                zcm_member_t *lm = (zcm_member_t *) g_ptr_array_index(lr->members, member);
                primitive_info_t *pinfo = (primitive_info_t*) g_hash_table_lookup(type_table, lm->type->lctypename);
                if (pinfo!=NULL && !strcmp(pinfo->storage, "float")) {
                    usenio = 1;
                    break;
                }
            }
            if (usenio)
                emit(0, "import java.nio.*;");
        }

        emit(0, "import java.util.*;");
        emit(0, "import zcm.zcm.*;");
        emit(0, " ");
        emit(0, "public final class %s %s", lr->structname->shortname, getopt_get_string(zcm->gopt, "jdecl"));
        emit(0, "{");

        for (unsigned int member = 0; member < g_ptr_array_size(lr->members); member++) {
            zcm_member_t *lm = (zcm_member_t *) g_ptr_array_index(lr->members, member);
            primitive_info_t *pinfo = (primitive_info_t*) g_hash_table_lookup(type_table, lm->type->lctypename);

            emit_start(1, "public ");

            if (pinfo==NULL)  {
                emit_continue("%s", make_fqn(zcm, lm->type->lctypename));
            } else {
                emit_continue("%s", pinfo->storage);
            }

            emit_continue(" %s", lm->membername);
            for (unsigned int i = 0; i < g_ptr_array_size(lm->dimensions); i++)
                emit_continue("[]");
            emit_end(";");
        }
        emit(0," ");

        // public constructor
        emit(1,"public %s()", lr->structname->shortname);
        emit(1,"{");

        // pre-allocate any fixed-size arrays.
        for (unsigned int member = 0; member < g_ptr_array_size(lr->members); member++) {
            zcm_member_t *lm = (zcm_member_t *) g_ptr_array_index(lr->members, member);
            primitive_info_t *pinfo = (primitive_info_t*) g_hash_table_lookup(type_table, lm->type->lctypename);

            if (g_ptr_array_size(lm->dimensions)==0 || !zcm_is_constant_size_array(lm))
                continue;

            emit_start(2, "%s = new ", lm->membername);
            if (pinfo != NULL)
                emit_continue("%s", pinfo->storage);
            else
                emit_continue("%s", make_fqn(zcm, lm->type->lctypename));

            for (unsigned int i = 0; i < g_ptr_array_size(lm->dimensions); i++) {
                zcm_dimension_t *dim = (zcm_dimension_t*) g_ptr_array_index(lm->dimensions, i);
                emit_continue("[%s]", dim->size);
            }
            emit_end(";");
        }
        emit(1,"}");
        emit(0," ");

        emit(1, "public static final long ZCM_FINGERPRINT;");
        emit(1, "public static final long ZCM_FINGERPRINT_BASE = 0x%016"PRIx64"L;", lr->hash);
        emit(0," ");

        //////////////////////////////////////////////////////////////
        // CONSTANTS
        for (unsigned int cn = 0; cn < g_ptr_array_size(lr->constants); cn++) {
            zcm_constant_t *lc = (zcm_constant_t *) g_ptr_array_index(lr->constants, cn);
            assert(zcm_is_legal_const_type(lc->lctypename));

            if (!strcmp(lc->lctypename, "int8_t")) {
                emit(1, "public static final byte %s = (byte) %s;", lc->membername, lc->val_str);
            } else if (!strcmp(lc->lctypename, "int16_t")) {
                emit(1, "public static final short %s = (short) %s;", lc->membername, lc->val_str);
            } else if (!strcmp(lc->lctypename, "int32_t")) {
                emit(1, "public static final int %s = %s;", lc->membername, lc->val_str);
            } else if (!strcmp(lc->lctypename, "int64_t")) {
                emit(1, "public static final long %s = %sL;", lc->membername, lc->val_str);
            } else if (!strcmp(lc->lctypename, "float")) {
                emit(1, "public static final float %s = %sf;", lc->membername, lc->val_str);
            } else if (!strcmp(lc->lctypename, "double")) {
                emit(1, "public static final double %s = %s;", lc->membername, lc->val_str);
            } else {
                assert(0);
            }
        }
        if (g_ptr_array_size(lr->constants) > 0)
            emit(0, "");

        ///////////////// compute fingerprint //////////////////
        emit(1, "static {");
        emit(2, "ZCM_FINGERPRINT = _hashRecursive(new ArrayList<Class<?>>());");
        emit(1, "}");
        emit(0, " ");

        emit(1, "public static long _hashRecursive(ArrayList<Class<?>> classes)");
        emit(1, "{");
        emit(2, "if (classes.contains(%s.class))", make_fqn(zcm, lr->structname->lctypename));
        emit(3,     "return 0L;");
        emit(0, " ");
        emit(2, "classes.add(%s.class);", make_fqn(zcm, lr->structname->lctypename));

        emit(2, "long hash = ZCM_FINGERPRINT_BASE");
        for (unsigned int member = 0; member < g_ptr_array_size(lr->members); member++) {
            zcm_member_t *lm = (zcm_member_t *) g_ptr_array_index(lr->members, member);
            primitive_info_t *pinfo = (primitive_info_t*) g_hash_table_lookup(type_table, lm->type->lctypename);

            if (pinfo)
                continue;

            emit(3, " + %s._hashRecursive(classes)", make_fqn(zcm, lm->type->lctypename));
        }
        emit(3,";");

        emit(2, "classes.remove(classes.size() - 1);");
        emit(2, "return (hash<<1) + ((hash>>63)&1);");

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

        ///////////////// encode //////////////////

        emit(1,"public void encode(DataOutput outs) throws IOException");
        emit(1,"{");
        emit(2,"outs.writeLong(ZCM_FINGERPRINT);");
        emit(2,"_encodeRecursive(outs);");
        emit(1,"}");
        emit(0," ");

        emit(1,"public void _encodeRecursive(DataOutput outs) throws IOException");
        emit(1,"{");
        if(struct_has_string_member(lr))
            emit(2, "char[] __strbuf = null;");
        char accessor[1024];

        for (unsigned int member = 0; member < g_ptr_array_size(lr->members); member++) {
            zcm_member_t *lm = (zcm_member_t *) g_ptr_array_index(lr->members, member);
            primitive_info_t *pinfo = (primitive_info_t*) g_hash_table_lookup(type_table, lm->type->lctypename);
            make_accessor(lm, "this", accessor);

            encode_recursive(zcm, lm, f, pinfo, accessor, 0);
            emit(0," ");
        }
        emit(1,"}");
        emit(0," ");

        ///////////////// decode //////////////////

        // decoding constructors
        emit(1, "public %s(byte[] data) throws IOException", lr->structname->shortname);
        emit(1, "{");
        emit(2, "this(new ZCMDataInputStream(data));");
        emit(1, "}");
        emit(0, " ");

        emit(1,"public %s(DataInput ins) throws IOException", lr->structname->shortname);
        emit(1,"{");
        emit(2,"if (ins.readLong() != ZCM_FINGERPRINT)");
        emit(3,     "throw new IOException(\"ZCM Decode error: bad fingerprint\");");
        emit(0," ");
        emit(2,"_decodeRecursive(ins);");
        emit(1,"}");
        emit(0," ");

        emit(1,"public static %s _decodeRecursiveFactory(DataInput ins) throws IOException", make_fqn(zcm, lr->structname->lctypename));
        emit(1,"{");
        emit(2,"%s o = new %s();", make_fqn(zcm, lr->structname->lctypename), make_fqn(zcm, lr->structname->lctypename));
        emit(2,"o._decodeRecursive(ins);");
        emit(2,"return o;");
        emit(1,"}");
        emit(0," ");

        emit(1,"public void _decodeRecursive(DataInput ins) throws IOException");
        emit(1,"{");
        if(struct_has_string_member(lr))
            emit(2, "char[] __strbuf = null;");
        for (unsigned int member = 0; member < g_ptr_array_size(lr->members); member++) {
            zcm_member_t *lm = (zcm_member_t *) g_ptr_array_index(lr->members, member);
            primitive_info_t *pinfo = (primitive_info_t*) g_hash_table_lookup(type_table, lm->type->lctypename);

            make_accessor(lm, "this", accessor);

            // allocate an array if necessary
            if (g_ptr_array_size(lm->dimensions) > 0) {

                emit_start(2, "this.%s = new ", lm->membername);

                if (pinfo != NULL)
                    emit_continue("%s", pinfo->storage);
                else
                    emit_continue("%s", make_fqn(zcm, lm->type->lctypename));

                for (unsigned int i = 0; i < g_ptr_array_size(lm->dimensions); i++) {
                    zcm_dimension_t *dim = (zcm_dimension_t*) g_ptr_array_index(lm->dimensions, i);
                    emit_continue("[(int) %s]", dim->size);
                }
                emit_end(";");
            }

            decode_recursive(zcm, lm, f, pinfo, accessor, 0);
            emit(0," ");
        }

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


        ///////////////// copy //////////////////

        emit(1,"public %s copy()", classname);
        emit(1,"{");
        emit(2,"%s outobj = new %s();", classname, classname);

        for (unsigned int member = 0; member < g_ptr_array_size(lr->members); member++) {
            zcm_member_t *lm = (zcm_member_t *) g_ptr_array_index(lr->members, member);
            primitive_info_t *pinfo = (primitive_info_t*) g_hash_table_lookup(type_table, lm->type->lctypename);
            make_accessor(lm, "", accessor);

            // allocate an array if necessary
            if (g_ptr_array_size(lm->dimensions) > 0) {

                emit_start(2, "outobj.%s = new ", lm->membername);

                if (pinfo != NULL)
                    emit_continue("%s", pinfo->storage);
                else
                    emit_continue("%s", make_fqn(zcm, lm->type->lctypename));

                for (unsigned int i = 0; i < g_ptr_array_size(lm->dimensions); i++) {
                    zcm_dimension_t *dim = (zcm_dimension_t*) g_ptr_array_index(lm->dimensions, i);
                    emit_continue("[(int) %s]", dim->size);
                }
                emit_end(";");
            }

            copy_recursive(zcm, lm, f, pinfo, accessor, 0);
            emit(0," ");
        }

        emit(2,"return outobj;");
        emit(1,"}");
        emit(0," ");

        ////////
        emit(0, "}\n");
        fclose(f);
    }

/* XXX deallocate our storage. unfinished since memory leaks are non-critical for zcm-gen.

    hashtable_iterator_t *hit = hashtable_iterator_create(type_table);
    hashtable_entry_t *entry;
    while ((entry = hashtable_iterator_next(hit)) != NULL) {
        free((char*) entry->value);
    }
    hashtable_iterator_destroy(hit);

    hashtable_destroy(type_table);
*/
    return 0;
}
예제 #25
0
파일: emit_java.c 프로젝트: gizatt/zcm
void copy_recursive(zcmgen_t *zcm, zcm_member_t *lm, FILE *f, primitive_info_t *pinfo, char *accessor, int depth)
{
    // base case: primitive array
    if (depth+1 == g_ptr_array_size(lm->dimensions) && pinfo != NULL) {

        char accessor_array[1024];
        make_accessor_array(lm, "", accessor_array);

        // one method works for all primitive types, yay!
        zcm_dimension_t *dim = (zcm_dimension_t*) g_ptr_array_index(lm->dimensions, depth);

        if (dim->mode == ZCM_VAR) {
            emit(2+depth, "if (this.%s > 0)", dim->size);
            emit_start(3+depth, "System.arraycopy(this.%s, 0, outobj.%s, 0, %s%s);",
                       accessor_array,
                       accessor_array,
                       dim_size_prefix(dim->size),
                       dim->size);
        } else {
            emit_start(2+depth, "System.arraycopy(this.%s, 0, outobj.%s, 0, %s%s);",
                       accessor_array,
                       accessor_array,
                       dim_size_prefix(dim->size),
                       dim->size);
        }

        return;
    }

    // base case: generic
    if (depth == g_ptr_array_size(lm->dimensions)) {
        if (pinfo != NULL) {

            emit_start(2+g_ptr_array_size(lm->dimensions), "outobj.%s", lm->membername);
            for (unsigned int i = 0; i < g_ptr_array_size(lm->dimensions); i++) {
                emit_continue("[%c]", 'a'+i);
            }
            emit_continue(" = this.%s", lm->membername);

            for (unsigned int i = 0; i < g_ptr_array_size(lm->dimensions); i++) {
                emit_continue("[%c]", 'a'+i);
            }

            emit_end(";");

        } else {
            emit(2+depth, "outobj.%s = this.%s.copy();", accessor, accessor);
        }

        return;
    }

    zcm_dimension_t *dim = (zcm_dimension_t*) g_ptr_array_index(lm->dimensions, depth);

    emit(2+depth, "for (int %c = 0; %c < %s%s; %c++) {",
         'a'+depth, 'a'+depth, dim_size_prefix(dim->size), dim->size, 'a'+depth);

    copy_recursive(zcm, lm, f, pinfo, accessor, depth+1);

    emit(2+depth, "}");
}
예제 #26
0
파일: emit_cpp.c 프로젝트: cd127/lcm-1
static void emit_init_test(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    const char *sn = ls->structname->shortname;
    emit(0, "bool %s::initTestObject()", sn);
    emit(0, "{");
    if(0 == g_ptr_array_size(ls->members)) {
        emit(1,     "return true;");
        emit(0,"}");
        emit(0,"");
        return;
    }
    // For each member
    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);
        char const* mapped_typename = map_type_name(lm->type->lctypename);
        char const* typeInitValue = init_test_value(mapped_typename);
        char * valueAssignment;

        // For non-primitive types, simply call object's init function
        if ( ! lcm_is_primitive_type(lm->type->lctypename) ) {
            valueAssignment = strdup(".initTestObject();");
        }
        else {
            valueAssignment = g_strdup_printf(" = %s;", typeInitValue);
        }

        int ndim = g_ptr_array_size(lm->dimensions);

        if (0==ndim) {
            emit(1, "%s%s", lm->membername, valueAssignment);
            free (valueAssignment);
        }
        else {
            // Check if it's a dynamic array, in which case we ignore it at the moment.
            uint8_t isDynamic=0;
            for (int dim=0; dim < ndim; ++dim) {
                lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, dim);
                if (!is_dim_size_fixed(ld->size)) {
                    isDynamic=1;
                    break;
                }
            }
            if (!isDynamic) {
                // Set first component in array
                emit_start(1, "%s", lm->membername);
                for (int dim=0; dim < ndim; ++dim) {
                    emit_continue("[0]");
                }
                emit_end("%s", valueAssignment);

                // Set last component in array
                emit_start(1, "%s", lm->membername);
                for (int dim=0; dim < ndim; ++dim) {
                    lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, dim);
                    emit_continue("[%i]", atoi(ld->size)-1);
                }
                emit_end("%s", valueAssignment);
            }
            else {
                emit(1, "//%s is a dynamic array", lm->membername);
            }
            g_free (valueAssignment);
            free((char*)mapped_typename);
            free((char*)typeInitValue);
        }
    }
    emit(0, "");
    emit(1, "return true;");
    emit(0,"}");
    emit(0,"");
}
예제 #27
0
파일: emit_cpp.c 프로젝트: cd127/lcm-1
static void emit_inc_test(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    const char *sn = ls->structname->shortname;
    emit(0, "bool %s::incTestObject()", sn);
    emit(0, "{");
    if(0 == g_ptr_array_size(ls->members)) {
        emit(1,     "return true;");
        emit(0,"}");
        emit(0,"");
        return;
    }
    // For each member
    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);
        char * valueAssignment;

        // For non-primitive types, simply call object's increment function
        if ( ! lcm_is_primitive_type(lm->type->lctypename) ) {
            valueAssignment = strdup(".incTestObject()");
        }
        else if (!strcmp(lm->type->lctypename,"string")) {
            valueAssignment = g_strdup_printf(" = std::to_string(std::stol(%s", lm->membername);
        }
        else {
            valueAssignment = strdup("++");
        }

        int ndim = g_ptr_array_size(lm->dimensions);

        if (0==ndim) {
            emit_start(1, "%s%s", lm->membername, valueAssignment);
            if (!strcmp(lm->type->lctypename,"string")) {
                emit_continue(")+1)");
            }
            emit_end(";");
        }
        else {
            // Check if it's a dynamic array, in which case we ignore it at the moment.
            uint8_t isDynamic=0;
            for (int dim=0; dim < ndim; ++dim) {
                lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, dim);
                if (!is_dim_size_fixed(ld->size)) {
                    isDynamic=1;
                    break;
                }
            }
            if (!isDynamic) {
                // Inc first component in array
                emit_start(1, "%s", lm->membername);
                for (int dim=0; dim < ndim; ++dim) {
                    emit_continue("[0]");
                }
                emit_continue("%s", valueAssignment);
                if (!strcmp(lm->type->lctypename,"string")) {
                    // This is not pretty but is the simplest way to avoid mem allocation
                    for (int dim=0; dim < ndim; ++dim) {
                        emit_continue("[0]");
                    }
                    emit_continue(")+1)");
                }
                emit_end(";");

                // Inc last component in array
                emit_start(1, "%s", lm->membername);
                for (int dim=0; dim < ndim; ++dim) {
                    lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, dim);
                    emit_continue("[%i]", atoi(ld->size)-1);
                }
                emit_continue("%s", valueAssignment);
                if (!strcmp(lm->type->lctypename,"string")) {
                    // This is not pretty but is the simplest way to avoid mem allocation
                    for (int dim=0; dim < ndim; ++dim) {
                        lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, dim);
                        emit_continue("[%i]", atoi(ld->size)-1);
                    }
                    emit_continue(")+1)");
                }
                emit_end(";");
            }
            else {
                emit(1, "//%s is a dynamic array", lm->membername);
            }
            g_free (valueAssignment);
        }
    }
    emit(0, "");
    emit(1, "return true;");
    emit(0,"}");
    emit(0,"");
}
예제 #28
0
파일: emit_cpp.c 프로젝트: cd127/lcm-1
static void emit_compare_test(lcmgen_t *lcm, FILE *f, lcm_struct_t *ls)
{
    const char *sn = ls->structname->shortname;
    emit(0, "bool %s::compareTestObject(%s const & other) const", sn, sn);
    emit(0, "{");
    if(0 == g_ptr_array_size(ls->members)) {
        emit(1,     "return true;");
        emit(0,"}");
        emit(0,"");
        return;
    }
    // For each member
    uint8_t firstVar = 1;
    emit_start(1, "bool equal = true;");
    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);
        int numDim = g_ptr_array_size(lm->dimensions);
        uint8_t isFloat = (0==strcmp(lm->type->lctypename,"float")) || (0==strcmp(lm->type->lctypename,"double"));

        emit_end("");
        if (firstVar) {
            emit_start(1, "equal = ");
            firstVar = 0;
        }
        else {
            emit_start(2, "&& ");
        }

        if (0==numDim) {
            if (isFloat) {
                emit_continue("( (std::fabs(%s - other.%s) < 1e-5) )", lm->membername, lm->membername);
            }
            else if ( ! lcm_is_primitive_type(lm->type->lctypename) ) {
                emit_continue("(%s.compareTestObject(other.%s))", lm->membername, lm->membername);
            }
            else {
                emit_continue("(%s == other.%s)", lm->membername, lm->membername);
            }
        }
        else {
            // Check if it's a dynamic array, in which case we ignore it at the moment.
            uint8_t isDynamic=0;
            for (int dim=0; dim < numDim; ++dim) {
                lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, dim);
                if (!is_dim_size_fixed(ld->size)) {
                    isDynamic=1;
                    break;
                }
            }
            if (!isDynamic) {
                // Compare first component in array
                char * dimStr = g_strdup_printf("");
                for (uint8_t dim = 0; dim < numDim; ++dim) {
                    char * tmpStr = g_strdup_printf("%s", dimStr);
                    g_free(dimStr);
                    dimStr = g_strdup_printf("%s[0]", tmpStr);
                    g_free(tmpStr);
                }

                if (isFloat) {
                    emit_continue("( (std::fabs(%s%s - other.%s%s) < 1e-5) )", lm->membername, dimStr, lm->membername, dimStr);
                }
                else if ( ! lcm_is_primitive_type(lm->type->lctypename) ) {
                    emit_continue("(%s%s.compareTestObject(other.%s%s))", lm->membername, dimStr, lm->membername, dimStr);
                }
                else {
                    emit_continue("(%s%s == other.%s%s)", lm->membername, dimStr, lm->membername, dimStr);
                }
                g_free(dimStr);

                dimStr = g_strdup_printf("");
                // Compare last component in array
                for (uint8_t dim = 0; dim < numDim; ++dim) {
                    lcm_dimension_t *ld = (lcm_dimension_t *) g_ptr_array_index(lm->dimensions, dim);
                    char * tmpStr = g_strdup_printf("%s", dimStr);
                    g_free(dimStr);
                    dimStr = g_strdup_printf("%s[%i]", tmpStr, atoi(ld->size)-1);
                    g_free(tmpStr);
                }

                if (isFloat) {
                    emit_continue(" && ( (std::fabs(%s%s - other.%s%s) < 1e-5) )", lm->membername, dimStr, lm->membername, dimStr);
                }
                else if ( ! lcm_is_primitive_type(lm->type->lctypename) ) {
                    emit_continue(" && (%s%s.compareTestObject(other.%s%s))", lm->membername, dimStr, lm->membername, dimStr);
                }
                else {
                    emit_continue(" && (%s%s == other.%s%s)", lm->membername, dimStr, lm->membername, dimStr);
                }
                g_free(dimStr);
            }
            else {
                emit_end("// %s is a dynamic array", lm->membername);
            }
        }

    }
    emit_end(";");
    emit(0,"");
    emit(1, "return equal;");
    emit(0,"}");
    emit(0,"");
}