summaryrefslogtreecommitdiff
path: root/nuttx/tools
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-04-22 07:22:55 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-04-22 07:22:55 -0600
commit58d19e46e06d8b0f06c997f001b159682d76672f (patch)
tree7dfcac261a2bd2fc419a41ec398b90edcdaad049 /nuttx/tools
parent6411b04961653795766bed50dec6df1e7250d6cb (diff)
downloadpx4-nuttx-58d19e46e06d8b0f06c997f001b159682d76672f.tar.gz
px4-nuttx-58d19e46e06d8b0f06c997f001b159682d76672f.tar.bz2
px4-nuttx-58d19e46e06d8b0f06c997f001b159682d76672f.zip
kconfig2html: Add support for dependencies on default values
Diffstat (limited to 'nuttx/tools')
-rw-r--r--nuttx/tools/kconfig2html.c489
1 files changed, 328 insertions, 161 deletions
diff --git a/nuttx/tools/kconfig2html.c b/nuttx/tools/kconfig2html.c
index 6a0745674..05e09663d 100644
--- a/nuttx/tools/kconfig2html.c
+++ b/nuttx/tools/kconfig2html.c
@@ -57,6 +57,7 @@
#define MAX_DEPENDENCIES 100
#define MAX_LEVELS 100
#define MAX_SELECT 16
+#define MAX_DEFAULTS 80
#define TAB_SIZE 4
#define VAR_SIZE 80
#define HTML_VAR_SIZE (2*VAR_SIZE + 64)
@@ -114,9 +115,14 @@ enum error_e
ERROR_OUTFILE_OPEN_FAILURE,
ERROR_TMPFILE_OPEN_FAILURE,
ERROR_KCONFIG_OPEN_FAILURE,
+ ERROR_TOO_MANY_DEFAULTS,
+ ERROR_MISSING_DEFAULT_VALUE,
+ ERROR_GARBAGE_AFTER_DEFAULT,
+ ERROR_DEFAULT_UNDERFLOW,
ERROR_TOO_MANY_SELECT,
ERROR_TOO_MANY_DEPENDENCIES,
ERROR_DEPENDENCIES_UNDERFLOW,
+ ERRROR_MISSING_ON_AFTER_DEPENDS,
ERRROR_ON_AFTER_DEPENDS,
ERROR_NESTING_TOO_DEEP,
ERROR_NESTING_UNDERFLOW
@@ -125,40 +131,50 @@ enum error_e
struct reserved_s
{
enum token_type_e ttype;
- const char *tname;
+ const char *tname;
};
-union value_u
+struct default_item_s
{
- char *s;
- int i;
- bool b;
+ char *ddefault;
+ char *ddependency;
+};
+
+struct default_s
+{
+ int dnitems;
+ struct default_item_s ditem[MAX_DEFAULTS];
+};
+
+struct select_s
+{
+ int snvar;
+ char *svarname[MAX_SELECT];
};
struct config_s
{
enum config_type_e ctype;
- char *cname;
- char *cdesc;
- char *cdefault;
- char *clower;
- char *cupper;
- char *cselect[MAX_SELECT];
- int cnselect;
- int cndependencies;
+ char *cname;
+ char *cdesc;
+ char *clower;
+ char *cupper;
+ struct default_s cdefault;
+ struct select_s cselect;
+ int cndependencies;
};
struct choice_s
{
- char *cprompt;
- char *cdefault;
- int cndependencies;
+ char *cprompt;
+ struct default_s cdefault;
+ int cndependencies;
};
struct menu_s
{
- char *mname;
- int mndependencies;
+ char *mname;
+ int mndependencies;
};
/****************************************************************************
@@ -169,7 +185,7 @@ static char g_line[LINE_SIZE+1];
static char g_scratch[SCRATCH_SIZE+1];
static FILE *g_outfile;
static FILE *g_tmpfile;
-static char *g_lasts;
+static char *g_lnptr;
static bool g_debug;
static bool g_internal;
static bool g_preread;
@@ -183,6 +199,8 @@ static int g_inchoice;
static int g_menu_number;
static int g_choice_number;
+static const char g_delimiters[] = " ,";
+
static struct reserved_s g_reserved[] =
{
{TOKEN_COMMENT, "comment"},
@@ -596,6 +614,8 @@ static char *read_line(FILE *stream)
char *ptr;
int len;
+ g_lnptr = NULL;
+
/* Read the next line */
g_line[LINE_SIZE] = '\0';
@@ -629,6 +649,7 @@ static char *read_line(FILE *stream)
{
/* No.. return now */
+ g_lnptr = g_line;
return g_line;
}
@@ -703,6 +724,7 @@ static char *kconfig_line(FILE *stream)
ptr = skip_space(g_line);
if (*ptr && *ptr != '#' && *ptr != '\n')
{
+ g_lnptr = ptr;
return ptr;
}
}
@@ -732,30 +754,64 @@ static enum token_type_e tokenize(const char *token)
}
/****************************************************************************
- * Name: MY_strtok_r
+ * Name: findchar
*
* Description:
- * A replacement that can be used if your platform does not support strtok_r.
+ * Find a character in a string. This differs from strchr() because it
+ * skips over quoted characters. For example, if you are searching for
+ * '"', encountering '"' will terminate the search, but "\"" will not.
*
****************************************************************************/
-#ifndef HAVE_STRTOK_R
-static char *MY_strtok_r(char *str, const char *delim, char **saveptr)
+static char *findchar(char *ptr, char ch)
{
- char *pbegin;
- char *pend = NULL;
+ bool escaped = false;
- /* Decide if we are starting a new string or continuing from
- * the point we left off.
- */
+ /* Search for the leading quotation marked */
- if (str)
+ for (; *ptr; ptr++)
{
- pbegin = str;
+ if (escaped)
+ {
+ /* Skip over this character and reset the escaped flag */
+
+ escaped = false;
+ }
+ else if (*ptr == '\\')
+ {
+ /* Set the escaped flag to skip over the next character */
+
+ escaped = true;
+ }
+ else if (*ptr == ch)
+ {
+ /* We have found the (unescaped) character we are looking for */
+
+ return ptr;
+ }
}
- else if (saveptr && *saveptr)
+
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: get_token
+ *
+ * Description:
+ * Get the next delimited token from the line buffer.
+ *
+ ****************************************************************************/
+
+static char *get_token(void)
+{
+ char *pbegin;
+ char *pend = NULL;
+
+ /* The position to begin/resume parsing is in g_lnptr. */
+
+ if (g_lnptr && *g_lnptr)
{
- pbegin = *saveptr;
+ pbegin = g_lnptr;
}
else
{
@@ -765,7 +821,7 @@ static char *MY_strtok_r(char *str, const char *delim, char **saveptr)
/* Find the beginning of the next token */
for (;
- *pbegin && strchr(delim, *pbegin) != NULL;
+ *pbegin && strchr(g_delimiters, *pbegin) != NULL;
pbegin++);
/* If we are at the end of the string with nothing
@@ -774,14 +830,26 @@ static char *MY_strtok_r(char *str, const char *delim, char **saveptr)
if (!*pbegin)
{
+ g_lnptr = pbegin;
return NULL;
}
- /* Find the end of the token */
+ /* Get if the token is a quoted string */
- for (pend = pbegin + 1;
- *pend && strchr(delim, *pend) == NULL;
- pend++);
+ if (*pbegin == '"')
+ {
+ /* Search for the trailing quotation mark */
+
+ pend = findchar(pbegin + 1, '"');
+ }
+ else
+ {
+ /* Find the end of the token */
+
+ for (pend = pbegin + 1;
+ *pend && strchr(g_delimiters, *pend) == NULL;
+ pend++);
+ }
/* pend either points to the end of the string or to
* the first delimiter after the string.
@@ -798,91 +866,46 @@ static char *MY_strtok_r(char *str, const char *delim, char **saveptr)
* beginning of the token.
*/
- if (saveptr)
- {
- *saveptr = pend;
- }
-
+ g_lnptr = pend;
return pbegin;
}
-#define strtok_r MY_strtok_r
-#endif
-
-/****************************************************************************
- * Name: findchar
- *
- * Description:
- * Find a character in a string. This differs from strchr() because it
- * skips over quoted characters. For example, if you are searching for
- * '"', encountering '"' will terminate the search, but "\"" will not.
- *
- ****************************************************************************/
-
-static char *findchar(char *ptr, char ch)
-{
- bool escaped = false;
-
- /* Search for the leading quotation marked */
-
- for (; *ptr; ptr++)
- {
- if (escaped)
- {
- /* Skip over this character and reset the escaped flag */
-
- escaped = false;
- }
- else if (*ptr == '\\')
- {
- /* Set the escaped flag to skip over the next character */
-
- escaped = true;
- }
- else if (*ptr == ch)
- {
- /* We have found the (unescaped) character we are looking for */
-
- return ptr;
- }
- }
-
- return NULL;
-}
-
/****************************************************************************
- * Name: getstring
+ * Name: get_html_string
*
* Description:
- * Extract a quoted string
+ * Extract a quoted string from the line buffer, dequote it, and make it
+ * HTML ready.
*
****************************************************************************/
-static char *getstring(char *ptr)
+static char *get_html_string(void)
{
- char *endptr;
+ char *pbegin;
+ char *pend;
- /* Search for the leading quotation mark */
+ /* Search for the leading quotation mark in the line buffer */
- ptr = findchar(ptr, '"');
- if (ptr)
+ pbegin = strchr(g_lnptr, '"');
+ if (pbegin)
{
/* Skip over the quote */
- ptr++;
+ pbegin++;
/* Search for the trailing quotation mark */
- endptr = findchar(ptr, '"');
- if (endptr)
+ pend = findchar(pbegin, '"');
+ if (pend)
{
/* Replace the final quote with a NUL */
- *endptr = '\0';
+ *pend = '\0';
}
}
- return htmlize_text(ptr);
+ g_lnptr = pend + 1;
+ return htmlize_text(pbegin);
}
/****************************************************************************
@@ -1184,6 +1207,168 @@ static inline void process_help(FILE *stream)
}
/****************************************************************************
+ * Name: process_default
+ *
+ * Description:
+ * Read and parse the Kconfig default statement.
+ *
+ ****************************************************************************/
+
+static void process_default(FILE *stream, struct default_s *defp)
+{
+ enum token_type_e tokid;
+ char *token;
+ int ndx;
+
+ /* Check if we have space for another default value */
+
+ ndx = defp->dnitems;
+ if (ndx >= MAX_DEFAULTS)
+ {
+ error("Too many default values\n");
+ exit(ERROR_TOO_MANY_DEFAULTS);
+ }
+
+ /* Get the next token which will be the value of the default */
+
+ token = get_token();
+ if (!token)
+ {
+ error("Missing default value\n");
+ exit(ERROR_MISSING_DEFAULT_VALUE);
+ }
+
+ defp->ditem[ndx].ddefault = strdup(token);
+ defp->ditem[ndx].ddependency = NULL;
+
+ /* Check if the default value is followed by "depends on" */
+
+ token = get_token();
+ if (token)
+ {
+ /* Yes.. something follows the default value. */
+
+ tokid = tokenize(token);
+ if (tokid != TOKEN_IF)
+ {
+ error("Unrecognized garbage after default value\n");
+ exit(ERROR_GARBAGE_AFTER_DEFAULT);
+ }
+
+ /* The rest of the line is the dependency */
+
+ defp->ditem[ndx].ddependency = strdup(g_lnptr);
+ }
+
+ /* Update the number of defaults we have encountered in this block */
+
+ defp->dnitems++;
+}
+
+/****************************************************************************
+ * Name: print_default
+ *
+ * Description:
+ * Output and the list of defaults to the the HTML body file.
+ *
+ ****************************************************************************/
+
+static void print_default(struct default_s *defp)
+{
+ struct default_item_s *item;
+ int i;
+
+ /* Check if there are any default value */
+
+ if (defp->dnitems > 0)
+ {
+ /* Yes, output the defaults differently if there is only one */
+
+ if (defp->dnitems == 1)
+ {
+ /* Output the Default */
+
+ item = &defp->ditem[0];
+ body(" <li>\n");
+ body(" <i>Default</i>: %s\n", item->ddefault);
+
+ /* Output the dependency */
+
+ if (item->ddependency)
+ {
+ body(" <p>\n");
+ body(" <i>Dependency:</i>\n");
+ body(" %s\n", htmlize_expression(item->ddependency));
+ body(" </p>\n");
+ }
+
+ body(" </li>\n");
+ }
+ else
+ {
+ /* Output a sub-list of defaults. */
+
+ body(" <li>\n");
+ body(" <i>Default Values</i>:\n");
+ body(" <ul>\n");
+
+ for (i = 0; i < defp->dnitems; i++)
+ {
+ /* Output the Default */
+
+ item = &defp->ditem[i];
+ body(" <li>\n");
+ body(" <i>Default</i>: %s\n", item->ddefault);
+
+ /* Output the dependency */
+
+ if (item->ddependency)
+ {
+ body(" <p>\n");
+ body(" <i>Dependency:</i>\n");
+ body(" %s\n", htmlize_expression(item->ddependency));
+ body(" </p>\n");
+ }
+ }
+
+ body(" </ul>\n");
+ body(" </li>\n");
+ }
+ }
+}
+
+/****************************************************************************
+ * Name: free_default
+ *
+ * Description:
+ * Output and the list of defaults to the the HTML body file.
+ *
+ ****************************************************************************/
+
+static void free_default(struct default_s *defp)
+{
+ struct default_item_s *item;
+ int i;
+
+ /* Free strings for each default */
+
+ for (i = 0; i < defp->dnitems; i++)
+ {
+ /* Free the default value string */
+
+ item = &defp->ditem[i];
+ free(item->ddefault);
+
+ /* Free any dependency on the default */
+
+ if (item->ddependency)
+ {
+ free(item->ddependency);
+ }
+ }
+}
+
+/****************************************************************************
* Name: process_config
*
* Description:
@@ -1215,8 +1400,7 @@ static inline char *process_config(FILE *stream, const char *configname,
{
/* Process the first token on the Kconfig file line */
- g_lasts = NULL;
- token = strtok_r(ptr, " ", &g_lasts);
+ token = get_token();
if (token != NULL)
{
tokid = tokenize(token);
@@ -1230,7 +1414,7 @@ static inline char *process_config(FILE *stream, const char *configname,
/* Get the description following the type */
- ptr = getstring(g_lasts);
+ ptr = get_html_string();
if (ptr)
{
config.cdesc = strdup(ptr);
@@ -1250,7 +1434,7 @@ static inline char *process_config(FILE *stream, const char *configname,
/* Get the description following the type */
- ptr = getstring(g_lasts);
+ ptr = get_html_string();
if (ptr)
{
config.cdesc = strdup(ptr);
@@ -1270,7 +1454,7 @@ static inline char *process_config(FILE *stream, const char *configname,
/* Get the description following the type */
- ptr = getstring(g_lasts);
+ ptr = get_html_string();
if (ptr)
{
config.cdesc = strdup(ptr);
@@ -1290,7 +1474,7 @@ static inline char *process_config(FILE *stream, const char *configname,
/* Get the description following the type */
- ptr = getstring(g_lasts);
+ ptr = get_html_string();
if (ptr)
{
config.cdesc = strdup(ptr);
@@ -1304,20 +1488,19 @@ static inline char *process_config(FILE *stream, const char *configname,
case TOKEN_DEFAULT:
{
- char *value = strtok_r(NULL, " ", &g_lasts);
- config.cdefault = strdup(value);
+ process_default(stream, &config.cdefault);
token = NULL;
}
break;
case TOKEN_RANGE:
{
- char *value = strtok_r(NULL, " ,", &g_lasts);
+ char *value = get_token();
if (value)
{
config.clower = strdup(value);
- value = strtok_r(NULL, " ", &g_lasts);
+ value = get_token();
if (value)
{
config.cupper = strdup(value);
@@ -1333,30 +1516,30 @@ static inline char *process_config(FILE *stream, const char *configname,
char *value;
int ndx;
- ndx = config.cnselect;
+ ndx = config.cselect.snvar;
if (ndx >= MAX_SELECT)
{
error("Too many 'select' lines\n");
exit(ERROR_TOO_MANY_SELECT);
}
- value = strtok_r(NULL, " ", &g_lasts);
- config.cselect[ndx] = strdup(value);
- config.cnselect = ndx + 1;
- token = NULL;
+ value = get_token();
+ config.cselect.svarname[ndx] = strdup(value);
+ config.cselect.snvar = ndx + 1;
+ token = NULL;
}
break;
case TOKEN_DEPENDS:
{
- char *value = strtok_r(NULL, " ", &g_lasts);
+ char *value = get_token();
if (strcmp(value, "on") != 0)
{
error("Expected \"on\" after \"depends\"\n");
exit(ERRROR_ON_AFTER_DEPENDS);
}
- push_dependency(htmlize_expression(g_lasts));
+ push_dependency(htmlize_expression(g_lnptr));
config.cndependencies++;
token = NULL;
}
@@ -1445,12 +1628,9 @@ static inline char *process_config(FILE *stream, const char *configname,
body(" <li><i>Type</i>: %s</li>\n", type2str(config.ctype));
}
- /* Print the default value of the configuration variable */
+ /* Print the default values of the configuration variable */
- if (config.cdefault)
- {
- body(" <li><i>Default</i>: %s</li>\n", config.cdefault);
- }
+ print_default(&config.cdefault);
/* Print the range of values of the configuration variable */
@@ -1474,15 +1654,15 @@ static inline char *process_config(FILE *stream, const char *configname,
/* Print the default value of the configuration variable auto-selected by this setting */
- if (config.cnselect > 0)
+ if (config.cselect.snvar > 0)
{
body(" <li><i>Selects</i>: <a href=\"#CONFIG_%s\">CONFIG_%s</a>",
- config.cselect[0], config.cselect[0]);
+ config.cselect.svarname[0], config.cselect.svarname[0]);
- for (i = 1; i < config.cnselect; i++)
+ for (i = 1; i < config.cselect.snvar; i++)
{
body(", <a href=\"#CONFIG_%s\">CONFIG_%s</a>",
- config.cselect[i], config.cselect[i]);
+ config.cselect.svarname[i], config.cselect.svarname[i]);
}
body("</li>\n");
@@ -1532,6 +1712,8 @@ static inline char *process_config(FILE *stream, const char *configname,
/* Free allocated memory */
+ free_default(&config.cdefault);
+
if (config.cname)
{
free(config.cname);
@@ -1542,11 +1724,6 @@ static inline char *process_config(FILE *stream, const char *configname,
free(config.cdesc);
}
- if (config.cdefault)
- {
- free(config.cdefault);
- }
-
if (config.clower)
{
free(config.clower);
@@ -1557,11 +1734,11 @@ static inline char *process_config(FILE *stream, const char *configname,
free(config.cupper);
}
- if (config.cnselect > 0)
+ if (config.cselect.snvar > 0)
{
- for (i = 0; i < config.cnselect; i++)
+ for (i = 0; i < config.cselect.snvar; i++)
{
- free(config.cselect[i]);
+ free(config.cselect.svarname[i]);
}
}
@@ -1597,8 +1774,7 @@ static inline char *process_choice(FILE *stream, const char *kconfigdir)
{
/* Process the first token on the Kconfig file line */
- g_lasts = NULL;
- token = strtok_r(ptr, " ", &g_lasts);
+ token = get_token();
if (token != NULL)
{
tokid = tokenize(token);
@@ -1608,7 +1784,7 @@ static inline char *process_choice(FILE *stream, const char *kconfigdir)
{
/* Get the prompt string */
- ptr = getstring(g_lasts);
+ ptr = get_html_string();
if (ptr)
{
choice.cprompt = strdup(ptr);
@@ -1622,22 +1798,21 @@ static inline char *process_choice(FILE *stream, const char *kconfigdir)
case TOKEN_DEFAULT:
{
- char *value = strtok_r(NULL, " ", &g_lasts);
- choice.cdefault = strdup(value);
+ process_default(stream, &choice.cdefault);
token = NULL;
}
break;
case TOKEN_DEPENDS:
{
- char *value = strtok_r(NULL, " ", &g_lasts);
+ char *value = get_token();
if (strcmp(value, "on") != 0)
{
error("Expected \"on\" after \"depends\"\n");
exit(ERRROR_ON_AFTER_DEPENDS);
}
- push_dependency(htmlize_expression(g_lasts));
+ push_dependency(htmlize_expression(g_lnptr));
choice.cndependencies++;
token = NULL;
}
@@ -1680,13 +1855,10 @@ static inline char *process_choice(FILE *stream, const char *kconfigdir)
body("</a></h3>\n");
g_choice_number++;
- /* Show the default */
+ /* Print the default values of the configuration variable */
body("<ul>\n");
- if (choice.cdefault)
- {
- body(" <li><i>Default</i>: <code>CONFIG_%s</code>\n</li>", choice.cdefault);
- }
+ print_default(&choice.cdefault);
/* Print the list of dependencies (if any) */
@@ -1728,16 +1900,13 @@ static inline char *process_choice(FILE *stream, const char *kconfigdir)
/* Free allocated memory */
+ free_default(&choice.cdefault);
+
if (choice.cprompt)
{
free(choice.cprompt);
}
- if (choice.cdefault)
- {
- free(choice.cdefault);
- }
-
/* Increment the nesting level */
incr_level();
@@ -1776,7 +1945,7 @@ static inline char *process_menu(FILE *stream, const char *kconfigdir)
/* Get the menu name */
- menuname = getstring(g_lasts);
+ menuname = get_html_string();
menu.mname = strdup(menuname);
/* Process each line in the choice */
@@ -1785,8 +1954,7 @@ static inline char *process_menu(FILE *stream, const char *kconfigdir)
{
/* Process the first token on the Kconfig file line */
- g_lasts = NULL;
- token = strtok_r(ptr, " ", &g_lasts);
+ token = get_token();
if (token != NULL)
{
tokid = tokenize(token);
@@ -1794,14 +1962,14 @@ static inline char *process_menu(FILE *stream, const char *kconfigdir)
{
case TOKEN_DEPENDS:
{
- char *value = strtok_r(NULL, " ", &g_lasts);
+ char *value = get_token();
if (strcmp(value, "on") != 0)
{
error("Expected \"on\" after \"depends\"\n");
exit(ERRROR_ON_AFTER_DEPENDS);
}
- push_dependency(htmlize_expression(g_lasts));
+ push_dependency(htmlize_expression(g_lnptr));
menu.mndependencies++;
token = NULL;
}
@@ -1912,8 +2080,7 @@ static char *parse_kconfigfile(FILE *stream, const char *kconfigdir)
{
/* Process the first token on the Kconfig file line */
- g_lasts = NULL;
- token = strtok_r(ptr, " ", &g_lasts);
+ token = get_token();
while (token != NULL)
{
tokid = tokenize(token);
@@ -1924,7 +2091,7 @@ static char *parse_kconfigfile(FILE *stream, const char *kconfigdir)
{
/* Get the relative path from the Kconfig file line */
- char *relpath = strtok_r(NULL, " ", &g_lasts);
+ char *relpath = get_token();
/* Remove optional quoting */
@@ -1970,7 +2137,7 @@ static char *parse_kconfigfile(FILE *stream, const char *kconfigdir)
case TOKEN_CONFIG:
case TOKEN_MENUCONFIG:
{
- char *configname = strtok_r(NULL, " ", &g_lasts);
+ char *configname = get_token();
token = process_config(stream, configname, kconfigdir);
}
break;
@@ -2025,7 +2192,7 @@ static char *parse_kconfigfile(FILE *stream, const char *kconfigdir)
case TOKEN_IF:
{
- char *dependency = strtok_r(NULL, " ", &g_lasts);
+ char *dependency = get_token();
push_dependency(htmlize_expression(dependency));
token = NULL;
}
@@ -2232,7 +2399,7 @@ int main(int argc, char **argv, char **envp)
/* Tell the reader that this is an auto-generated file */
body("<p>\n");
- body(" <b>Maintaining this Document</b>.\n");
+ body(" <b>Overview</b>.\n");
body(" The NuttX RTOS is highly configurable.\n");
body(" The NuttX configuration files are maintained using the <a href=\"http://ymorin.is-a-geek.org/projects/kconfig-frontends\">kconfig-frontends</a> tool.\n");
body(" That configuration tool uses <code>Kconfig</code> files that can be found through the NuttX source tree.\n");
@@ -2241,7 +2408,7 @@ int main(int argc, char **argv, char **envp)
body(" This configurable options are descrived in this document.\n");
body("</p>\n");
body("<p>\n");
- body(" <b>NOTE</b>:\n");
+ body(" <b>Mainenance Note</b>.\n");
body(" This documenation was auto-generated using the <a href=\"http://sourceforge.net/p/nuttx/git/ci/master/tree/nuttx/tools/kconfig2html.c\">kconfig2html</a> tool\n");
body(" That tools analyzes the NuttX <code>Kconfig</code> and generates this HTML document.\n");
body(" This HTML document file should not be editted manually.\n");