⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nutcomponent.c

📁 含有完整TCP/IP PPP协议的嵌入式操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
            lua_pushnil(ls);            while (lua_next(ls, -2)) {                if (lua_isstring(ls, -1)) {                    result[cnt++] = strdup(lua_tostring(ls, -1));                }                lua_pop(ls, 1);            }        }        result[cnt] = NULL;        /* Keep the stack unmodified. */        lua_pop(ls, 1);    }    return result;}NUTCOMPONENT *FindComponentByName(NUTCOMPONENT * root, char *name){    NUTCOMPONENT *walk;    NUTCOMPONENT *compo = NULL;    walk = root->nc_child;    while (walk && compo == NULL) {        if (strcmp(walk->nc_name, name) == 0) {            compo = walk;            break;        } else if (walk->nc_child) {            compo = FindComponentByName(walk, name);        }        walk = walk->nc_nxt;    }    return compo;}/* * The component's table is expected on top of the LUA stack. */void LoadComponentOptions(lua_State * ls, NUTCOMPONENT * compo){    char *name;    NUTCOMPONENTOPTION *opts;    /* Push the option table on the stack. */    lua_pushstring(ls, TKN_OPTIONS);    lua_gettable(ls, -2);    /*     * Now the option table should be on top of the stack.     */    if (lua_istable(ls, -1)) {        opts = compo->nc_opts;        while (opts && opts->nco_nxt) {            opts = opts->nco_nxt;        }        lua_pushnil(ls);        while (lua_next(ls, -2)) {            name = GetStringByNameFromTable(ls, -1, TKN_MACRO, NULL, 0);            if (name) {                if (opts) {                    opts->nco_nxt = calloc(1, sizeof(NUTCOMPONENTOPTION));                    opts = opts->nco_nxt;                } else {                    opts = calloc(1, sizeof(NUTCOMPONENTOPTION));                    compo->nc_opts = opts;                }                opts->nco_name = name;                /* Retrieve the option's brief description. */                opts->nco_brief = GetStringByNameFromTable(ls, -1, TKN_BRIEF, NULL, 0);                /* Retrieve the option's long description. */                opts->nco_description = GetStringByNameFromTable(ls, -1, TKN_DESC, NULL, 0);                /* Retrieve the option's default seeting. */                opts->nco_default = GetStringByNameFromTable(ls, -1, TKN_DEFAULT, NULL, 0);                if (opts->nco_default && opts->nco_value == NULL) {                    opts->nco_value = strdup(opts->nco_default);                }                /* Retrieve the option's requirement keywords. */                opts->nco_requires = GetStringArrayByNameFromTable(ls, -1, TKN_REQUIRES);                /* Retrieve the option's provision keywords. */                opts->nco_provides = GetStringArrayByNameFromTable(ls, -1, TKN_PROVIDES);                /* Retrieve the option's activation requirements. */                opts->nco_active_if = GetStringByNameFromTable(ls, -1, TKN_ACTIF, NULL, 0);                /* Retrieve the option's data flavor. */                opts->nco_flavor = GetStringByNameFromTable(ls, -1, TKN_FLAVOR, NULL, 0);                /* Retrieve the option's data type. */                opts->nco_type = GetStringByNameFromTable(ls, -1, TKN_TYPE, NULL, 0);                /* Retrieve the option's data type. */                opts->nco_ctype = GetStringByNameFromTable(ls, -1, TKN_CTYPE, NULL, 0);                /* Retrieve the name of the file to store the option,                   typically a C header file. */                opts->nco_file = GetStringByNameFromTable(ls, -1, TKN_FILE, NULL, 0);                /* Retrieve possible choices of the option's value. */                opts->nco_choices = GetStringArrayByNameFromTable(ls, -1, TKN_CHOICES);                /* Retrieve the Makefile macros for this option. */                opts->nco_makedefs = GetStringArrayByNameFromTable(ls, -1, TKN_MAKEDEFS);            }            lua_pop(ls, 1);        }    }    lua_pop(ls, 1);}/*! * \brief Recursively load Nut/OS component options. */void LoadOptions(lua_State * ls, NUTCOMPONENT * root, NUTCOMPONENT * compo){    NUTCOMPONENT *subc;    char *name;    while (compo) {        /*         * Push the component array with the given name on top of the         * Lua stack and make sure we got a valid result.         */        lua_getglobal(ls, compo->nc_name);        if (lua_istable(ls, -1)) {            LoadComponentOptions(ls, compo);            /*             * Enumerate the array. Start with nil for the first key.             */            lua_pushnil(ls);            /*             * Each loop will take the key from the top of the stack and             * push the next key followed by the corresponding value back             * to the stack.             */            while (lua_next(ls, -2)) {                /*                 * Now the next value is on top and its key (array index) is below. Components                 * are specified without a named index. Thus, they have a numeric index.                 */                if (lua_isnumber(ls, -2)) {                    name = GetStringByNameFromTable(ls, -1, TKN_NAME, NULL, 0);                    if (name) {                        subc = FindComponentByName(root, name);                        if (subc) {                            LoadComponentOptions(ls, subc);                        }				    	free(name);                    }                }                lua_pop(ls, 1);            }        }        lua_pop(ls, 1);        /*         * Process subcomponents.         */        if (compo->nc_child) {            LoadOptions(ls, root, compo->nc_child);        }        compo = compo->nc_nxt;    }}/*! * \brief Recursively load Nut/OS components. * * Components may have siblings and children. Right now, Nut/OS has two levels * only. The root component is the repository itself and all Nut/OS components * like os, crt, net etc. are children of this root. Anyway, we recursively * call this routine to be prepared for future subcomponents. * * \param ls     Lua state. * \param parent Parent component. * \param path   Top directory of the repository. * \param file   Relative pathname of the script file. * * \return 0 on success, -1 otherwise. * * Option name is a global LUA variable. */int LoadComponentTree(lua_State * ls, NUTCOMPONENT * parent, const char *path, const char *file){    int rc = 0;    char script[255];    char *name;    NUTCOMPONENT *compo = NULL;    /* Build the pathname and check if the script file exists. */    strcpy(script, path);    strcat(script, "/");    strcat(script, file);    if (access(script, 0)) {        sprintf(errtxt, "%s: Script not found", file);        return -1;    }    /*     * Let the interpreter load and parse the script file. In case of     * an error, the error text is available on top of the Lua stack.     */    if ((rc = luaL_loadfile(ls, script)) != 0) {        strcpy(errtxt, lua_tostring(ls, -1));        return -1;    }    /*     * Run the script. Actually the script doesn't do much except     * initializing a bunch of global Lua variables.     */    if(lua_pcall(ls, 0, 0, 0)) {        strcpy(errtxt, lua_tostring(ls, -1));        return -1;    }    /*     * The component is defined by a Lua array, which name is the     * name of the parent component. Push this array on top of the     * Lua stack and make sure we got an array.     */    lua_getglobal(ls, parent->nc_name);    if (!lua_istable(ls, -1)) {        sprintf(errtxt, "%s: '%s' missing or not an array", file, parent->nc_name);        lua_pop(ls, 1);        return -1;    }    /*     * Enumerate the array. Start with nil for the first key.     */    lua_pushnil(ls);    /*     * Each loop will take the key from the top of the stack and     * push the next key followed by the corresponding value back     * to the stack.     */    while (lua_next(ls, -2)) {        /*         * Now the next value is on top and its key (array index) is below. Components         * are specified without a named index. Thus, they have a numeric index.         */        if (lua_isnumber(ls, -2)) {            /*             * This is a numeric index. Now let's check the value, which is             * expected to be an array containing a named index 'name'.             */            name = GetStringByNameFromTable(ls, -1, TKN_NAME, NULL, 0);            if (name) {                /*                 * The value on top of the stack is an array, which contains                 * a named item 'name'. We probably found a new component.                 */                if (compo == NULL) {                    /* This is the first child component of our parent. */                    compo = calloc(1, sizeof(NUTCOMPONENT));                    parent->nc_child = compo;                } else {                    /* Siblings exist already. */                    compo->nc_nxt = calloc(1, sizeof(NUTCOMPONENT));                    compo->nc_nxt->nc_prv = compo;                    compo = compo->nc_nxt;                }                /*                 * Transfer the component's items from Lua to a C structure.                 */                compo->nc_parent = parent;                compo->nc_name = name;                /* Retrieve the component's brief description. */                compo->nc_brief = GetStringByNameFromTable(ls, -1, TKN_BRIEF, NULL, 0);                /* Retrieve the component's long description. */                compo->nc_description = GetStringByNameFromTable(ls, -1, TKN_DESC, NULL, 0);                /* Retrieve the component's requirement keywords. */                compo->nc_requires = GetStringArrayByNameFromTable(ls, -1, TKN_REQUIRES);                /* Retrieve the component's provision keywords. */                compo->nc_provides = GetStringArrayByNameFromTable(ls, -1, TKN_PROVIDES);                /* Retrieve the component's activation requirements. */                compo->nc_active_if = GetStringByNameFromTable(ls, -1, TKN_ACTIF, NULL, 0);                /* Retrieve the component's directory within the source tree. */                compo->nc_subdir = GetStringByNameFromTable(ls, -1, TKN_SUBDIR, NULL, 0);                /* Retrieve the component's source file. */                compo->nc_sources = GetStringArrayByNameFromTable(ls, -1, TKN_SOURCES);                /* Retrieve the optional targets of this component. */                compo->nc_targets = GetStringArrayByNameFromTable(ls, -1, TKN_TARGETS);                /* Retrieve the Makefile macros for this component. */                compo->nc_makedefs = GetStringArrayByNameFromTable(ls, -1, TKN_MAKEDEFS);                /* If this component got any subcomponent, then load it now. */                if (GetStringByNameFromTable(ls, -1, TKN_SCRIPT, script, sizeof(script))) {                    if(LoadComponentTree(ls, compo, path, script)) {                        return -1;                    }                }            }        }        /*         * Remove the value from stack, so the next lua_next will find the         * key (arry index) on top.         */        lua_pop(ls, 1);    }    /*     * Remove the key in order to leave the stack like we found it.     */    lua_pop(ls, 1);    return rc;}void LoadConfigValues(lua_State * ls, NUTCOMPONENT * compo){    NUTCOMPONENTOPTION *opts;    while (compo) {        opts = compo->nc_opts;        while (opts) {            lua_getglobal(ls, opts->nco_name);            if (lua_isstring(ls, -1)) {                if (opts->nco_value) {                    free(opts->nco_value);                }                opts->nco_value = strdup(lua_tostring(ls, -1));                if (opts->nco_value[0] == '\0' || opts->nco_value[0] == ' ') {                    free(opts->nco_value);                    opts->nco_value = NULL;                }                opts->nco_active = 1;            }            lua_pop(ls, 1);            opts = opts->nco_nxt;        }        if (compo->nc_child) {            LoadConfigValues(ls, compo->nc_child);        }        compo = compo->nc_nxt;    }}#if 0int LuaPanic(lua_State *ls){    int i = 1;    return 0;}int LuaError(lua_State *ls){    return -1;    exit(0);}#endif/*! * \brief Open a Nut/OS component repository. * * \param pathname Pathname of the repository file. Use slashes, not backslashes. * * \return Pointer to a NUTREPOSITORY structure on success or NULL otherwise. */NUTREPOSITORY *OpenRepository(const char *pathname){    char *cp;    NUTREPOSITORY *repo; //OS = malloc(sizeof(NUTREPOSITORY));    if(pathname == NULL || access(pathname, 0)) {        return NULL;    }    if((repo = calloc(1, sizeof(NUTREPOSITORY))) != NULL) {        /*         * Cut off the directory path of the repository script. This         * directory is our root directory. All component scripts will         * be below this point.         */        if((repo->nr_dir = strdup(pathname)) == NULL) {            free(repo);            return NULL;        }        if ((cp = strrchr(repo->nr_dir, '/')) != NULL) {            *cp++ = 0;            repo->nr_name = cp;        } else {            repo->nr_dir[0] = 0;        }        /*         * Create a LUA state.         */        repo->nr_ls = lua_open();        //lua_atpanic(repo->nr_ls, LuaPanic);        //lua_cpcall(repo->nr_ls, LuaError, NULL);    }    return repo;}/*! * \brief Close a Nut/OS component repository. * * \param repo Pointer to a NUTREPOSITORY structure. */void CloseRepository(NUTREPOSITORY *repo){    if(repo) {        if(repo->nr_dir) {            free(repo->nr_dir);        }        if(repo->nr_ls) {            lua_close((lua_State *)(repo->nr_ls));        }		free(repo);    }}void ReleaseStringArray(char **stringarray){	int cnt = 0;	while (stringarray[cnt])		free(stringarray[cnt++]);	free(stringarray);}void ReleaseComponentOptions(NUTCOMPONENTOPTION *opts){	NUTCOMPONENTOPTION *c;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -