Пример #1
0
int emit_cpp(lcmgen_t *lcmgen)
{
    // iterate through all defined message types
    for (unsigned int i = 0; i < g_ptr_array_size(lcmgen->structs); i++) {
        lcm_struct_t *lr = (lcm_struct_t *) g_ptr_array_index(lcmgen->structs, i);

        const char *tn = lr->structname->lctypename;
        char *tn_ = dots_to_slashes(tn);

        // compute the target filename
        char *header_name = g_strdup_printf("%s%s%s.hpp",
                                            getopt_get_string(lcmgen->gopt, "cpp-hpath"),
                                            strlen(getopt_get_string(lcmgen->gopt, "cpp-hpath")) > 0 ? G_DIR_SEPARATOR_S : "",
                                            tn_);

        // generate code if needed
        if (lcm_needs_generation(lcmgen, lr->lcmfile, header_name)) {
            make_dirs_for_file(header_name);

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

            emit_header_start(lcmgen, f, lr);
            emit_encode(lcmgen, f, lr);
            emit_decode(lcmgen, f, lr);
            emit_encoded_size(lcmgen, f, lr);
            emit_get_hash(lcmgen, f, lr);
            emit(0, "const char* %s::getTypeName()", lr->structname->shortname);
            emit(0, "{");
            emit(1,     "return \"%s\";", lr->structname->shortname);
            emit(0, "}");
            emit(0, "");

            emit_encode_nohash(lcmgen, f, lr);
            emit_decode_nohash(lcmgen, f, lr);
            emit_encoded_size_nohash(lcmgen, f, lr);
            emit_compute_hash(lcmgen, f, lr);

            emit_compare(lcmgen, f, lr);
            emit(0, "/// Testing (ignores dynamic arrays & affects only first and last elements of static arrays)");
            emit(0, "/// {");
            emit_print(lcmgen, f, lr);
            emit_init_test(lcmgen, f, lr);
            emit_inc_test(lcmgen, f, lr);
            emit_compare_test(lcmgen, f, lr);
            emit(0, "/// }");

            emit_package_namespace_close(lcmgen, f, lr);
            emit(0, "#endif");

            fclose(f);
        }
        g_free(header_name);
        free(tn_);
    }

    return 0;
}
Пример #2
0
static int
emit_package (lcmgen_t *lcm, _package_contents_t *pc)
{
    // create the package directory, if necessary
    char **dirs = g_strsplit (pc->name, ".", 0);
    char *pdname = build_filenamev (dirs);
    char package_dir[PATH_MAX];
    char package_dir_prefix[PATH_MAX];
    int have_package = dirs[0] != NULL;
    int write_init_py = !getopt_get_bool(lcm->gopt, "python-no-init");

    sprintf (package_dir_prefix, "%s%s", getopt_get_string(lcm->gopt, "ppath"), 
            strlen(getopt_get_string(lcm->gopt, "ppath")) > 0 ? 
            G_DIR_SEPARATOR_S : "");
    sprintf(package_dir, "%s%s%s", package_dir_prefix, pdname,
            have_package ? G_DIR_SEPARATOR_S : "");
    free (pdname);
    if (strlen (package_dir)) {
        if (! g_file_test (package_dir, G_FILE_TEST_EXISTS)) {
//            g_mkdir_with_parents (package_dir, 0755);
            mkdir_with_parents (package_dir, 0755);
        }
        if (!g_file_test (package_dir, G_FILE_TEST_IS_DIR)) {
            err ("Could not create directory %s\n", package_dir);
            return -1;
        }
    }

    // write the package __init__.py files, if necessary
    FILE *init_py_fp = NULL;
    GHashTable * init_py_imports = g_hash_table_new_full(g_str_hash, 
            g_str_equal, free, NULL);
    if (have_package && write_init_py) {
        int ndirs = 0;
        for (ndirs=0; dirs[ndirs]; ndirs++);

        for (int i=0 ; i<ndirs; i++) {
            char *initpy_fname_parts[1024];
            assert(ndirs + 4 < 1024);

            initpy_fname_parts[0] = package_dir_prefix;
            for (int j=0; j<=i; j++) {
                initpy_fname_parts[j+1] = dirs[j];
            }
            initpy_fname_parts[i+2] = "__init__.py";
            initpy_fname_parts[i+3] = NULL;

            char *initpy_fname = build_filenamev (initpy_fname_parts);
            int created_initpy = 0;

            // close init_py_fp if already open
            if(init_py_fp) {
                fclose(init_py_fp);
                init_py_fp = NULL;
            }

            if (! g_file_test (initpy_fname, G_FILE_TEST_EXISTS)) {
                // __init__.py does not exist for this package.  Create it.
                created_initpy = 1;
                init_py_fp = fopen(initpy_fname, "w");
            } else {
                // open the existing __init__.py file, and make note of the
                // modules it imports
                created_initpy = 0;
                init_py_fp = fopen(initpy_fname, "r+");
            }

            if (!init_py_fp) {
                perror ("fopen");
                free (initpy_fname);
                return -1;
            }
#ifndef WIN32
            // lock __init__.py for exclusive write access
            // TODO do the equivalent in windows
            struct flock lockinfo;
            lockinfo.l_type = F_WRLCK;
            lockinfo.l_start = 0;
            lockinfo.l_whence = SEEK_SET;
            lockinfo.l_len = 0 ;
            lockinfo.l_pid = getpid();
            if(0 != fcntl(fileno(init_py_fp), F_SETLKW, &lockinfo)) {
                perror("locking __init__.py");
                free(initpy_fname);
                fclose(init_py_fp);
                return -1;
            }
#endif

            if(created_initpy) {
                fprintf (init_py_fp, "\"\"\"LCM package __init__.py file\n"
                        "This file automatically generated by lcm-gen.\n"
                        "DO NOT MODIFY BY HAND!!!!\n"
                        "\"\"\"\n\n");
            } else {
                while(!feof(init_py_fp)) {
                    char buf[4096];
                    memset(buf, 0, sizeof(buf));
                    char *result = fgets(buf, sizeof(buf)-1, init_py_fp);
                    if(!result)
                        break;

                    g_strstrip(buf);
                    char **words = g_strsplit(buf, " ", -1);
                    if(!words[0] || !words[1] || !words[2] || !words[3])
                        continue;
                    if(!strcmp(words[0], "from") && !strcmp(words[2], "import")) {
                        char *module_name = strdup(words[1]+1); // ignore leading dot
                        g_hash_table_replace(init_py_imports, module_name, 
                                module_name);
                    }

                    g_strfreev(words);
                }
            }
            free (initpy_fname);
        }
    }
    g_strfreev (dirs);

    ////////////////////////////////////////////////////////////
    // ENUMS
    for (int i=0; i<pc->enums->len; i++) {
        lcm_enum_t *le = (lcm_enum_t *) g_ptr_array_index (pc->enums, i);

        char path[PATH_MAX];
        sprintf (path, "%s%s.py", package_dir, le->enumname->shortname);

        if(init_py_fp && 
           !g_hash_table_lookup(init_py_imports, le->enumname->shortname))
            fprintf(init_py_fp, "from .%s import %s\n", 
                    le->enumname->shortname,
                    le->enumname->shortname);

        if (!lcm_needs_generation(lcm, le->lcmfile, path))
            continue;

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

        fprintf(f, "\"\"\"LCM type definitions\n"
                "This file automatically generated by lcm.\n"
                "DO NOT MODIFY BY HAND!!!!\n"
                "\"\"\"\n"
                "\n"
                "try:\n"
                "    import cStringIO.StringIO as BytesIO\n"
                "except ImportError:\n"
                "    from io import BytesIO\n"
                "import struct\n\n");

        // enums always encoded as int32
        emit (0, "class %s(object):", le->enumname->shortname);
        emit (1, "__slots__ = [ \"value\" ]");
        for (unsigned int v = 0; v < le->values->len; v++) {
            lcm_enum_value_t *lev = (lcm_enum_value_t *) g_ptr_array_index(le->values, v);
            emit(1, "%s = %i", lev->valuename, lev->value);
        }

        emit (1, "_packed_fingerprint = struct.pack(\">Q\", 0x%"PRIx64")",
                le->hash);
        fprintf (f, "\n");

        emit (1, "def __init__ (self, value):");
        emit (2,     "self.value = value");
        fprintf (f, "\n");

        emit (1, "def _get_hash_recursive(parents):");
        emit (2,     "return 0x%"PRIx64, le->hash);
        emit (1, "_get_hash_recursive=staticmethod(_get_hash_recursive)");
        emit (1, "def _get_packed_fingerprint():");
        emit (2,     "return %s._packed_fingerprint", le->enumname->shortname);
        emit (1, "_get_packed_fingerprint = staticmethod(_get_packed_fingerprint)");
        fprintf (f, "\n");

        emit (1, "def encode(self):");
        emit (2,     "return struct.pack(\">Qi\", 0x%"PRIx64", self.value)",
                le->hash);

        emit (1, "def _encode_one(self, buf):");
        emit (2,     "buf.write (struct.pack(\">i\", self.value))");
        fprintf (f, "\n");

        emit (1, "def decode(data):");
        emit (2,     "if hasattr (data, 'read'):");
        emit (3,         "buf = data");
        emit (2,     "else:");
        emit (3,         "buf = BytesIO(data)");
        emit (2,     "if buf.read(8) != %s._packed_fingerprint:", 
                le->enumname->shortname);
        emit (3,         "raise ValueError(\"Decode error\")");
        emit (2,     "return %s(struct.unpack(\">i\", buf.read(4))[0])",
                le->enumname->shortname);
        emit (1, "decode = staticmethod(decode)");

        emit (1, "def _decode_one(buf):");
        emit (2,     "return %s(struct.unpack(\">i\", buf.read(4))[0])",
                le->enumname->shortname);
        emit (1, "_decode_one = staticmethod(_decode_one)");

        fprintf (f, "\n");
        fclose (f);
    }

    ////////////////////////////////////////////////////////////
    // STRUCTS
    for (int i = 0; i<pc->structs->len; i++) {
        lcm_struct_t *ls = (lcm_struct_t *) g_ptr_array_index(pc->structs, i);

        char path[PATH_MAX];
        sprintf (path, "%s%s.py", package_dir, ls->structname->shortname);

        if(init_py_fp && 
           !g_hash_table_lookup(init_py_imports, ls->structname->shortname))
            fprintf(init_py_fp, "from .%s import %s\n", 
                    ls->structname->shortname,
                    ls->structname->shortname);

        if (!lcm_needs_generation(lcm, ls->lcmfile, path))
            continue;

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

        fprintf(f, "\"\"\"LCM type definitions\n"
                "This file automatically generated by lcm.\n"
                "DO NOT MODIFY BY HAND!!!!\n"
                "\"\"\"\n"
                "\n"
                "try:\n"
                "    import cStringIO.StringIO as BytesIO\n"
                "except ImportError:\n"
                "    from io import BytesIO\n"
                "import struct\n\n");

        emit_python_dependencies (lcm, f, ls);

        fprintf(f, "class %s(object):\n", ls->structname->shortname);
        fprintf (f,"    __slots__ = [");
        for (unsigned int member = 0; member < ls->members->len; member++) {
            lcm_member_t *lm = (lcm_member_t *) g_ptr_array_index (ls->members, member);
            fprintf (f, "\"%s\"%s", lm->membername, 
                    member < ls->members->len-1 ? ", " : "");
        }
        fprintf (f, "]\n\n");

        // CONSTANTS
        for (unsigned int cn = 0; cn < g_ptr_array_size(ls->constants); cn++) {
            lcm_constant_t *lc = (lcm_constant_t *) g_ptr_array_index(ls->constants, cn);
            assert(lcm_is_legal_const_type(lc->lctypename));
            emit(1, "%s = %s", lc->membername, lc->val_str);
        }
        if (g_ptr_array_size(ls->constants) > 0)
            emit(0, "");

        emit_python_init (lcm, f, ls);
        emit_python_encode (lcm, f, ls);
        emit_python_encode_one (lcm, f, ls);
        emit_python_decode (lcm, f, ls);
        emit_python_decode_one (lcm, f, ls);
        emit_python_fingerprint (lcm, f, ls);
        fclose (f);
    }

    if(init_py_fp)
        fclose(init_py_fp);
    g_hash_table_destroy(init_py_imports);
    return 0;
}
Пример #3
0
// XXX step 2, basically the main function
static int
emit_package (lcmgen_t *lcm, _package_contents_t *pc)
{
    // create the package directory, if necessary
    char **dirs = g_strsplit (pc->name, ".", 0);
    char *pdname = build_filenamev (dirs);
    char package_dir[PATH_MAX];
    char package_dir_prefix[PATH_MAX];
    int have_package = dirs[0] != NULL;

    sprintf (package_dir_prefix, "%s%s", getopt_get_string(lcm->gopt, "lpath"),
            strlen(getopt_get_string(lcm->gopt, "lpath")) > 0 ?
            G_DIR_SEPARATOR_S : "");
    sprintf(package_dir, "%s%s%s", package_dir_prefix, pdname,
            have_package ? G_DIR_SEPARATOR_S : "");
    free (pdname);
    if (strlen (package_dir)) {
        if (! g_file_test (package_dir, G_FILE_TEST_EXISTS)) {
//            g_mkdir_with_parents (package_dir, 0755);
            mkdir_with_parents (package_dir, 0755);
        }
        if (!g_file_test (package_dir, G_FILE_TEST_IS_DIR)) {
            err ("Could not create directory %s\n", package_dir);
            return -1;
        }
    }

    // write the package init.lua files, if necessary
    FILE *init_lua_fp = NULL;
    GHashTable * initlua_requires = NULL;
    GHashTable * initlua_requires_subpack = NULL;

    if (have_package) {
        int ndirs = 0;
        for (ndirs=0; dirs[ndirs]; ndirs++);

        for (int i=0 ; i<ndirs; i++) {

        	// make filename
        	char *initlua_fname;

        	{
        		char *initlua_fname_parts[1024];
        		assert(ndirs + 4 < 1024);

        		initlua_fname_parts[0] = package_dir_prefix;
        		for (int j=0; j<=i; j++) {
        			initlua_fname_parts[j+1] = dirs[j];
        		}
        		initlua_fname_parts[i+2] = "init.lua";
        		initlua_fname_parts[i+3] = NULL;

        		initlua_fname = build_filenamev (initlua_fname_parts);
        	}

            // make current package name
        	char * package_name;

        	{
        		char * name_parts[1024];
        		assert(i < 1024);

        		for (int j = 0; j <= i; j++) {
        			name_parts[j] = dirs[j];
        		}
        		name_parts[i + 1] = NULL;

        		package_name = g_strjoinv(".", name_parts);
        	}

            if (initlua_requires) {
            	g_hash_table_destroy(initlua_requires);
            	initlua_requires = NULL;
            }

            if (initlua_requires_subpack) {
            	g_hash_table_destroy(initlua_requires_subpack);
            	initlua_requires_subpack = NULL;
            }

            initlua_requires = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
            initlua_requires_subpack = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);

            // if the file already exists, read the contents
            if (g_file_test (initlua_fname, G_FILE_TEST_EXISTS)) {

            	init_lua_fp = fopen(initlua_fname, "r");

            	if (!init_lua_fp) {
            		perror ("fopen");
            		free (initlua_fname);
            		g_free(package_name);
            		return -1;
            	}

            	while(!feof(init_lua_fp)) {
            		char buf[4096];
            		memset(buf, 0, sizeof(buf));
            		char *result = fgets(buf, sizeof(buf)-1, init_lua_fp);
            		if(!result)
            			break;

            		// XXX get all of the previous types and packages

            		// this regex works because the first part is greedy
            		GRegex * regex = g_regex_new("require\\('([\\w+\\.]*\\.)(\\w+)'\\)( -- subpackage)?",
						(GRegexCompileFlags) 0, (GRegexMatchFlags) 0, NULL);
            		GMatchInfo * matchinfo;

            		if(g_regex_match(regex, buf, (GRegexMatchFlags) 0, &matchinfo)){
            			if(g_match_info_get_match_count(matchinfo) == 3){
            				// not a subpackage
            				gchar * classname = g_match_info_fetch(matchinfo, 2);
            				g_hash_table_insert(initlua_requires, g_strdup(classname), g_strdup(classname));
            			}else if(g_match_info_get_match_count(matchinfo) == 4){
            				// this is a subpackage
            				// XXX fprintf(stderr, "> buff: %s\n", buf);
            				gchar * superpackage = g_match_info_fetch(matchinfo, 1);
            				gchar * subpackage = g_match_info_fetch(matchinfo, 2);
            				// XXX fprintf(stderr, "> super: %s, sub: %s\n", superpackage, subpackage);
            				gchar * fullsubpackage = g_strjoin("", superpackage, subpackage, NULL);
            				// XXX fprintf(stderr, "> [2] inserting: %s\n", fullsubpackage);
            				g_hash_table_insert(initlua_requires_subpack, g_strdup(fullsubpackage), g_strdup(fullsubpackage));
            				g_free(fullsubpackage);
            			}
            		}

            		g_match_info_free(matchinfo);
            		g_regex_unref(regex);
            	}

            	fclose(init_lua_fp);
            	init_lua_fp = NULL;
            }

            init_lua_fp = fopen(initlua_fname, "w");
            // XXX fprintf(stderr, "> opened: %s\n", initlua_fname);

            if (!init_lua_fp) {
            	perror ("fopen");
            	free (initlua_fname);
            	g_free(package_name);
            	return -1;
            }

#ifndef WIN32
            // lock init.lua for exclusive write access
            // TODO do the equivalent in windows
            struct flock lockinfo;
            lockinfo.l_type = F_WRLCK;
            lockinfo.l_start = 0;
            lockinfo.l_whence = SEEK_SET;
            lockinfo.l_len = 0 ;
            lockinfo.l_pid = getpid();
            if(0 != fcntl(fileno(init_lua_fp), F_SETLKW, &lockinfo)) {
                perror("locking init.lua");
                free(initlua_fname);
                g_free(package_name);
                fclose(init_lua_fp);
                return -1;
            }
#endif

            fprintf (init_lua_fp, "--[[\n"
            		"LCM package init.lua file\n"
            		"This file automatically generated by lcm-gen.\n"
            		"DO NOT MODIFY BY HAND!!!!\n"
            		"--]]\n"
            		"\n"
            		"local M = {}\n"
            		"\n");

            // add in all previous types
            GList * package_types = g_hash_table_get_values(initlua_requires);

            for (int j = 0; j < g_list_length(package_types); j++) {
            	char * tn = (char *) g_list_nth_data(package_types, j);
            	char * fn = g_strjoin(".", package_name, tn, NULL);
            	fprintf(init_lua_fp, "M.%s = require('%s')\n", tn, fn);
            	g_free(fn);
            }

            g_list_free(package_types);

            // add in all previous packages
            GList * subpacks = g_hash_table_get_values(initlua_requires_subpack);

            for (int j = 0; j < g_list_length(subpacks); j++) {
            	char * spn = (char *) g_list_nth_data(subpacks, j);
            	// get the base of the package name
            	char ** tmpsplit = g_strsplit(spn, ".", -1);
            	char * sn = tmpsplit[g_strv_length(tmpsplit) - 1];
            	// XXX fprintf(stderr, "[1] sn: %s, spn: %s\n", sn, spn);
            	fprintf(init_lua_fp, "M.%s = require('%s') -- subpackage\n", sn, spn);
            	g_strfreev(tmpsplit);
            }

            g_list_free(subpacks);

            // if the current package has a subpackage (which eventually contains the target package)
            // add a `require` for that subpackage to the current (if it hasn't already)
            if (i + 1 < ndirs) {
            	char *subpack_name = g_strjoin(".", package_name, dirs[i + 1], NULL);

            	// check for the subpackage name
            	if (!g_hash_table_lookup(initlua_requires_subpack, subpack_name)) {

            		// add it if it didn't exist
            		g_hash_table_insert(initlua_requires_subpack, g_strdup(subpack_name), g_strdup(subpack_name));
            		// XXX fprintf(stderr, "[2] sn: %s, spn: %s\n", dirs[i + 1], subpack_name);
            		fprintf(init_lua_fp, "M.%s = require('%s') -- subpackage\n", dirs[i + 1], subpack_name);
            	}

            	g_free(subpack_name);
            }

            // not yet the target?
            if (i + 1 < ndirs) {

            	// close it out
            	fprintf(init_lua_fp, "\nreturn M\n\n");
            	fclose(init_lua_fp);
            	init_lua_fp = NULL;
            }

            free (initlua_fname);
            g_free(package_name);
        }
    }
    g_strfreev (dirs);

    ////////////////////////////////////////////////////////////
    // STRUCTS
    for (int i = 0; i<pc->structs->len; i++) {
        lcm_struct_t *ls = (lcm_struct_t *) g_ptr_array_index(pc->structs, i);

        char path[PATH_MAX];
        sprintf (path, "%s%s.lua", package_dir, ls->structname->shortname);

        if(init_lua_fp){

        	// XXX add the 'require' to the appropriate init.lua
        	if (!g_hash_table_lookup(initlua_requires, ls->structname->shortname)) {
        		fprintf(init_lua_fp, "M.%s = require('%s')\n", ls->structname->shortname, ls->structname->lctypename);
        	}

        	// XXX look for subpackages
        	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);

        		if(g_str_has_prefix(lm->type->package, pc->name)){

        			// make a regex starting with the current package...
        			gchar ** tmpsplit = g_strsplit(pc->name, ".", 0);
        			gchar * regexpackage = g_strjoinv("\\.", tmpsplit);

        			// only look for immediate submodules, not submodules of the submodules
        			gchar * regexstr = g_strjoin("", "^", regexpackage, "\\.(\\w+)", NULL);

        			GRegex * regex = g_regex_new(regexstr, (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, NULL);
        			GMatchInfo * matchinfo;

        			g_strfreev(tmpsplit);
        			g_free(regexpackage);
        			g_free(regexstr);

        			if (g_regex_match(regex, lm->type->package, (GRegexMatchFlags) 0, &matchinfo)) {
        				if (g_match_info_get_match_count(matchinfo) == 2) {
        					gchar * fullsubpackage = g_match_info_fetch(matchinfo, 0);
        					gchar * subpackage = g_match_info_fetch(matchinfo, 1);

        					// was it already in the file?
        					if (!g_hash_table_lookup(initlua_requires_subpack, fullsubpackage)) {
        						// XXX fprintf(stderr, "> [1] inserting: %s\n", fullsubpackage);
        						g_hash_table_insert(initlua_requires_subpack, g_strdup(fullsubpackage), g_strdup(fullsubpackage));
        						fprintf(init_lua_fp, "M.%s = require('%s') -- subpackage\n", subpackage, fullsubpackage);
        					}
        				}
        			}

        			g_match_info_free(matchinfo);
        			g_regex_unref(regex);
        		}
        	}
        }

        if (!lcm_needs_generation(lcm, ls->lcmfile, path))
            continue;

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

        fprintf(f, "--[[\n"
        		"LCM type definitions\n"
        		"This file automatically generated by lcm.\n"
        		"DO NOT MODIFY BY HAND!!!!\n"
        		"--]]\n"
        		"\n"
        		"local lcm = require('lcm')\n\n");

        emit_lua_dependencies (lcm, f, ls);

        // XXX added this...
        emit_lua_locals(lcm, f, ls);
        emit_lua_buffer_helper(lcm, f, ls);

        // XXX step 3, start making the object
        emit(0, "local %s = {}", ls->structname->shortname);
        emit(0, "%s.__index = %s", ls->structname->shortname, ls->structname->shortname);
        emit(0, "");

        // CONSTANTS
        for (unsigned int cn = 0; cn < g_ptr_array_size(ls->constants); cn++) {
            lcm_constant_t *lc = (lcm_constant_t *) g_ptr_array_index(ls->constants, cn);
            assert(lcm_is_legal_const_type(lc->lctypename));
            emit(1, "%s.%s = %s", ls->structname->shortname,
            		lc->membername, lc->val_str);
        }
        if (g_ptr_array_size(ls->constants) > 0)
            emit(0, "");

        // NAMES
        emit(0, "%s.name = '%s'", ls->structname->shortname, ls->structname->lctypename);
        emit(0, "%s.packagename = '%s'", ls->structname->shortname, ls->structname->package);
        emit(0, "%s.shortname = '%s'", ls->structname->shortname, ls->structname->shortname);
        emit(0, "");

        emit_lua_new (lcm, f, ls);
        emit_lua_fingerprint (lcm, f, ls);
        emit_lua_encode (lcm, f, ls);
        emit_lua_encode_one (lcm, f, ls);
        emit_lua_decode (lcm, f, ls);
        emit_lua_decode_one (lcm, f, ls);

        emit(0, "return %s", ls->structname->shortname);
        emit(0, "");

        fclose (f);
    }

    if(init_lua_fp){
    	fprintf(init_lua_fp, "\nreturn M\n\n");
        fclose(init_lua_fp);
    }

    g_hash_table_destroy(initlua_requires);
    return 0;
}
Пример #4
0
Файл: emit_c.c Проект: tbeu/lcm
int emit_enum(lcmgen_t *lcmgen, lcm_enum_t *le)
{
    char *tn = le->enumname->lctypename;
    char *tn_ = dots_to_underscores(tn);
    char *header_name = g_strdup_printf("%s/%s.h", getopt_get_string(lcmgen->gopt, "c-hpath"), tn_);
    char *c_name      = g_strdup_printf("%s/%s.c", getopt_get_string(lcmgen->gopt, "c-cpath"), tn_);

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

        emit_header_top(lcmgen, f, tn_);

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

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

        free (tn_upper);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        free (tn_upper);
    }

    return 0;
}
Пример #5
0
Файл: emit_c.c Проект: tbeu/lcm
int emit_struct(lcmgen_t *lcmgen, lcm_struct_t *lr)
{
    char *tn = lr->structname->lctypename;
    char *tn_ = dots_to_underscores(tn);
    char *header_name = g_strdup_printf("%s/%s.h", getopt_get_string(lcmgen->gopt, "c-hpath"), tn_);
    char *c_name      = g_strdup_printf("%s/%s.c", getopt_get_string(lcmgen->gopt, "c-cpath"), tn_);

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

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

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

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

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

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

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

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

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

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

        fclose(f);
    }

    return 0;
}