📄 nutcomponent.c
字号:
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 + -