📄 nutcomponent.c
字号:
/* * Copyright (C) 2004-2005 by egnite Software GmbH. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * For additional information see http://www.ethernut.de/ * *//* * $Log: nutcomponent.c,v $ * Revision 1.23 2005/11/22 09:20:22 haraldkipp * Removed modification of a relative top_blddir path. * * Revision 1.22 2005/10/07 22:36:00 hwmaier * Removed generation of -DETHERNUT2 entry for UserConf.mk as this can now accomplished by the PLATFORM macro. * * Revision 1.21 2005/10/07 22:11:59 hwmaier * Changed LoadComponents to parse options in root level. * Added bld_dir parameter to CreateSampleDirectory. * * Revision 1.20 2005/09/07 16:24:23 christianwelzel * Changed handling of default parameters. Nutconf now creates all default * parameter defines within header files. * * Revision 1.19 2005/07/26 15:55:36 haraldkipp * Version 1.2.3. * Added new keyword "default" to specify default values. They will no * longer appear in the conf files and we can remove the booldata flavor * from most options. * Bugfix: Options will now be recognized in all sublevels. * * Revision 1.18 2005/07/20 09:21:10 haraldkipp * Allow subdivided modules * * Revision 1.17 2005/05/25 09:59:53 haraldkipp * Bugfix: Absolute application path for top_appdir pointed to source directory. * * Revision 1.16 2005/04/28 16:18:22 haraldkipp * Autoconfiscated * * Revision 1.15 2005/04/22 15:16:01 haraldkipp * Can now run without GUI. * * Revision 1.14 2005/02/26 12:13:40 drsung * Added support for relative paths for sample application directory. * * Revision 1.13 2005/02/06 16:39:52 haraldkipp * GBA linker script entry in NutConf.mk fixed * * Revision 1.12 2004/11/24 15:36:53 haraldkipp * Release 1.1.1. * Do not store empty options. * Remove include files from the build tree, if they are no longer used. * Command line parameter 's' allows different settings. * Minor compiler warning fixed. * * Revision 1.11 2004/09/26 13:25:00 drsung * Fixed call to strdup. * * Revision 1.10 2004/09/26 12:04:07 drsung * Fixed several hundred memory leaks :-). * Relative pathes can now be used for source, build and install directory. * * Revision 1.9 2004/09/19 15:13:09 haraldkipp * Only one target per OBJx entry * * Revision 1.8 2004/09/17 13:02:18 haraldkipp * First and last directory added to sample dir * * Revision 1.7 2004/09/07 19:18:11 haraldkipp * Trying to get additional .S and .c targets assembled/compiled. * ETHERNUT2 default for newly created UserConf.mk. * * Revision 1.6 2004/08/18 16:06:03 haraldkipp * Use consistent directory structure * * Revision 1.5 2004/08/18 15:36:25 haraldkipp * Phony target clean divided * * Revision 1.4 2004/08/18 14:05:22 haraldkipp * Fill error text if script not found * * Revision 1.3 2004/08/18 13:34:20 haraldkipp * Now working on Linux * * Revision 1.2 2004/08/03 15:03:25 haraldkipp * Another change of everything * * Revision 1.1 2004/06/07 16:11:22 haraldkipp * Complete redesign based on eCos' configtool * *//* * This module had been intentionally written in C, not C++, * to make its use in simple non-GUI applications as easy as * possible. */#if HAVE_CONFIG_H#include <config.h>#endif#define NUT_CONFIGURE_VERSION "1.2.3"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/stat.h>#include <time.h>#ifdef _WIN32#include <io.h>#include <direct.h>#include "dirent.h"#define mkdir(P, M) _mkdir(P)#define access _access#define strcasecmp stricmp#else#include <unistd.h>#include <dirent.h>#include <errno.h>#define stricmp strcasecmp#define strnicmp strncasecmp#endif#include <fcntl.h>#ifndef O_BINARY#define O_BINARY 0#endif#include <lua.h>#include <lauxlib.h>#ifdef NUT_CONFIGURE_EXEC#include "getopt.h"#endif#include "nutcomponent.h"/*! \brief Internal component name. * Must be unique. */#define TKN_NAME "name"/*! \brief Name of a macro. * Identifier used in configuration include files. */#define TKN_MACRO "macro"/*! \brief */#define TKN_SCRIPT "script"/*! \brief */#define TKN_SUBDIR "subdir"/*! \brief Short component description. */#define TKN_BRIEF "brief"/*! \brief Detailed component description. */#define TKN_DESC "description"/*! \brief Option's default value. */#define TKN_DEFAULT "default"#define TKN_REQUIRES "requires"#define TKN_PROVIDES "provides"/*! \brief Component option list. */#define TKN_OPTIONS "options"/*! \brief */#define TKN_ACTIF "active_if"/*! \brief Component's option flavor. * Possible values are * - boolean: Option may be disabled or enabled * - booldata: Option may be disabled or enabled and contains a value if enabled. */#define TKN_FLAVOR "flavor"/*! \brief Option's value type. * - integer * - bool * - enumerated */#define TKN_TYPE "type"/*! \brief */#define TKN_CTYPE "ctype"/*! \brief Relative path of the configuration include file. */#define TKN_FILE "file"/*! \brief List of source files. */#define TKN_SOURCES "sources"/*! \brief List of explicit target files. */#define TKN_TARGETS "targets"/*! \brief */#define TKN_CHOICES "choices"/*! \brief */#define TKN_MAKEDEFS "makedefs"static char errtxt[1024];#if 0/* Quite helpful during debugging. */void ShowStack(lua_State * ls){ int top; int i; int type; printf("Stack:\n"); top = lua_gettop(ls); for (i = top; i > 0; i--) { type = lua_type(ls, i); printf("%d %s=", i, lua_typename(ls, type)); switch (type) { case LUA_TNONE: break; case LUA_TNIL: break; case LUA_TBOOLEAN: break; case LUA_TLIGHTUSERDATA: break; case LUA_TNUMBER: break; case LUA_TSTRING: printf("%s\n", lua_tostring(ls, -1)); break; case LUA_TTABLE: printf("\n"); lua_pushnil(ls); while (lua_next(ls, i)) { if (lua_type(ls, -2) == LUA_TSTRING) { printf(" %s - %s\n", lua_tostring(ls, -2), lua_typename(ls, lua_type(ls, -1))); } else if (lua_type(ls, -2) == LUA_TNUMBER) { printf(" [%.0lf] %s\n", lua_tonumber(ls, -2), lua_typename(ls, lua_type(ls, -1))); } else { printf(" %s - %s\n", lua_typename(ls, lua_type(ls, -2)), lua_typename(ls, lua_type(ls, -1))); } lua_pop(ls, 1); } break; case LUA_TFUNCTION: break; case LUA_TUSERDATA: break; case LUA_TTHREAD: break; } printf("\n"); }}void ShowCompoTree(NUTCOMPONENT * compo, int level){ NUTCOMPONENTOPTION *opts; int i; while (compo) { for (i = 0; i < level; i++) { printf(" "); } printf("%s\n", compo->nc_name); opts = compo->nc_opts; while (opts) { if (opts->nco_value) { for (i = 0; i <= level; i++) { printf(" "); } printf("%s = %s\n", opts->nco_name, opts->nco_value); } opts = opts->nco_nxt; } if (compo->nc_child) { ShowCompoTree(compo->nc_child, level + 1); } compo = compo->nc_nxt; }}#endifconst char *GetScriptErrorString(void){ return errtxt;}/*! * \brief Get a string value from a named item of a table. * * The table is expected at a specified position of the Lua stack. * * \param ls Lua state. * \param idx Stack position of the table. * \param name Name of the table item. * \param dst Pointer to buffer that receives the string. If NULL, the * buffer will be allocated from heap. * \param siz Size of the buffer. Ignored if dst is NULL. * * \return Pointer to the buffer containing the retrieved value or NULL, * if there is no table item with the specified name. */char *GetStringByNameFromTable(lua_State * ls, int idx, char *name, char *dst, size_t siz){ /* Lua expects the named key into the table on top of the stack. */ lua_pushstring(ls, name); /* This puts the value of the named table entry on top of the stack. Note, that we have to adjust the index because we pushed the key on top. */ lua_gettable(ls, idx < 0 ? idx - 1 : idx + 1); /* Make sure that this is a string. */ if (lua_isstring(ls, -1)) { if (dst == NULL) { dst = strdup(lua_tostring(ls, -1)); } else if (lua_strlen(ls, -1) < siz) { strcpy(dst, lua_tostring(ls, -1)); } else { dst = NULL; } } else { dst = NULL; } /* Remove the value to keep the stack unmodified. */ lua_pop(ls, 1); return dst;}/*! * \brief Get an array of string values from a named item of a table. * * The table is expected at a specified position of the Lua stack. * * \param ls Lua state. * \param idx Stack position of the table. * \param name Name of the table item. * * \return Pointer to an array of string pointers to the retrieved values * or NULL, if there is no table item with the specified name. * The string buffers as well as the array itself are allocated * from heap. */char **GetStringArrayByNameFromTable(lua_State * ls, int idx, char *name){ int cnt = 0; char **result = NULL; /* Lua expects the named key into the table on top of the stack. */ lua_pushstring(ls, name); /* Replaces the key by its value. */ lua_gettable(ls, idx < 0 ? idx - 1 : idx + 1); /* Make sure we have a table on top of the stack and traverse the table, counting the number of strings in this table. */ if (lua_istable(ls, -1)) { lua_pushnil(ls); while (lua_next(ls, -2)) { if (lua_isstring(ls, -1)) { cnt++; } lua_pop(ls, 1); } } /* Keep the stack unmodified. */ lua_pop(ls, 1); /* If we found a table with one or more strings, then allocate a pointer array to store these strings. */ if (cnt) { result = calloc(cnt + 1, sizeof(char *)); cnt = 0; lua_pushstring(ls, name); lua_gettable(ls, idx < 0 ? idx - 1 : idx + 1); if (lua_istable(ls, -1)) { /* Traverse the table. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -