From 67e5edd8d0f42be68a57603e56eb0ee97b51d2d7 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 21 Apr 2013 09:37:45 -0600 Subject: kconfig2html will now handle line continuations --- nuttx/tools/kconfig2html.c | 307 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 236 insertions(+), 71 deletions(-) (limited to 'nuttx') diff --git a/nuttx/tools/kconfig2html.c b/nuttx/tools/kconfig2html.c index c5b3f3cbd..733361238 100644 --- a/nuttx/tools/kconfig2html.c +++ b/nuttx/tools/kconfig2html.c @@ -219,61 +219,40 @@ static struct reserved_s g_reserved[] = ****************************************************************************/ /**************************************************************************** - * Name: show_usage + * Name: debug * * Description: - * Show usage of this program and exit with the specified error code + * Debug output (conditional) * ****************************************************************************/ -static void show_usage(const char *progname, int exitcode) +static void debug(const char *fmt, ...) { - fprintf(stderr, "USAGE: %s [-d] [-i] [-a ] {-o ] []\n", progname); - fprintf(stderr, " %s [-h]\n\n", progname); - fprintf(stderr, "Where:\n\n"); - fprintf(stderr, "\t-a : Select relative path to the apps/ directory. Theis path is relative\n"); - fprintf(stderr, "\t to the . Default: ../apps\n"); - fprintf(stderr, "\t-o : Send output to . Default: Output goes to stdout\n"); - fprintf(stderr, "\t-i : Show hidden, internal configuration variables\n"); - fprintf(stderr, "\t-d : Enable debug output\n"); - fprintf(stderr, "\t-h : Prints this message and exits\n"); - fprintf(stderr, "\t is the directory containing the root Kconfig file.\n"); - fprintf(stderr, "\t Default : .\n"); - exit(exitcode); -} - -/**************************************************************************** - * Name: skip_space - * - * Description: - * Skip over any spaces - * - ****************************************************************************/ + va_list ap; -static char *skip_space(char *ptr) -{ - while (*ptr && isspace((int)*ptr)) ptr++; - return ptr; + if (g_debug) + { + va_start(ap, fmt); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + } } /**************************************************************************** - * Name: debug + * Name: error * * Description: - * Debug output (conditional) + * Error output (unconditional) * ****************************************************************************/ -static void debug(const char *fmt, ...) +static void error(const char *fmt, ...) { va_list ap; - if (g_debug) - { - va_start(ap, fmt); - (void)vfprintf(stderr, fmt, ap); - va_end(ap); - } + va_start(ap, fmt); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); } /**************************************************************************** @@ -310,6 +289,44 @@ static void body(const char *fmt, ...) va_end(ap); } +/**************************************************************************** + * Name: show_usage + * + * Description: + * Show usage of this program and exit with the specified error code + * + ****************************************************************************/ + +static void show_usage(const char *progname, int exitcode) +{ + error("USAGE: %s [-d] [-i] [-a ] {-o ] []\n", progname); + error(" %s [-h]\n\n", progname); + error("Where:\n\n"); + error("\t-a : Select relative path to the apps/ directory. Theis path is relative\n"); + error("\t to the . Default: ../apps\n"); + error("\t-o : Send output to . Default: Output goes to stdout\n"); + error("\t-i : Show hidden, internal configuration variables\n"); + error("\t-d : Enable debug output\n"); + error("\t-h : Prints this message and exits\n"); + error("\t is the directory containing the root Kconfig file.\n"); + error("\t Default : .\n"); + exit(exitcode); +} + +/**************************************************************************** + * Name: skip_space + * + * Description: + * Skip over any spaces + * + ****************************************************************************/ + +static char *skip_space(char *ptr) +{ + while (*ptr && isspace((int)*ptr)) ptr++; + return ptr; +} + /**************************************************************************** * Name: dequote * @@ -353,31 +370,179 @@ static char *dequote(char *ptr) return ptr; } +/**************************************************************************** + * Name: htmlize + * + * Description: + * HTML-ize a string. Convert characters: + * + * " " quotation mark + * ' ' apostrophe + * & & ampersand + * < < less-than + * > > greater-than + * + ****************************************************************************/ + +static char *htmlize(const char *src) +{ + char *dest = g_scratch; + const char *str; + + /* We may get here with the source pointer equal to NULL. Return the + * disfavor. + */ + + if (!src) + { + return NULL; + } + + /* Transfer each character from the source string into the scratch buffer */ + + dest = g_scratch; + *dest = '\0'; + + for (; *src; src++) + { + /* Expand characters as necessary */ + + str = NULL; + switch (*src) + { + case '"': + str = """; + break; + + case '\'': + str = "'"; + break; + + case '&': + str = "&"; + break; + + case '<': + str = "<"; + break; + + case '>': + str = ">"; + break; + + default: + *dest++ = *src; + *dest = '\0'; + continue; + } + + /* Transfer a string */ + + strcat(dest, str); + dest += strlen(str); + } + + return g_scratch; +} + /**************************************************************************** * Name: read_line * * Description: + * Read a new line from the Kconfig file into the g_line[] buffer, using + * the g_scratch buffer if necessary to concatenate lines that end with a + * line continuation character (backslash). + * + ****************************************************************************/ + +static char *read_line(FILE *stream) +{ + char *ptr; + int len; + + /* Read the next line */ + + g_line[LINE_SIZE] = '\0'; + if (!fgets(g_line, LINE_SIZE, stream)) + { + return NULL; + } + + /* Loop to handle continuation lines */ + + for(;;) + { + /* How long is the line so far? */ + + len = strlen(g_line); + + /* Remove any newline character at the end of the buffer */ + + if (g_line[len-1] == '\n') + { + len--; + g_line[len] = '\0'; + } + + /* Does this continue on the next line? Note taht this check + * could erroneoulsy combine two lines if a comment line ends with + * a line continuation... Don't do that! + */ + + if (g_line[len-1] != '\\') + { + /* No.. return now */ + + return g_line; + } + + /* Yes.. Replace the backslash with a space delimiter */ + + g_line[len-1] = ' '; + + /* Read the next line into the scratch buffer */ + + g_scratch[SCRATCH_SIZE] = '\0'; + if (!fgets(g_scratch, SCRATCH_SIZE, stream)) + { + return NULL; + } + + /* Skip any leading whitespace and copy the rest of the next line + * into the line buffer. Note that the leading white space is + * replaced with a single character to serve as a delimiter. + */ + + ptr = skip_space(g_scratch); + strncpy(&g_line[len], ptr, LINE_SIZE - len); + } +} + +/**************************************************************************** + * Name: kconfig_line + * + * Description: * Read a new line, skipping over leading white space and ignore lines * that contain only comments. * ****************************************************************************/ -/* Read the next line from the Kconfig file */ - -static char *read_line(FILE *stream) +static char *kconfig_line(FILE *stream) { char *ptr; for (;;) { + /* Read the next line from the Kconfig file */ /* Is there already valid data in the line buffer? This can happen while parsing * help text and we read one line too far. */ if (!g_preread) { - g_line[LINE_SIZE] = '\0'; - if (!fgets(g_line, LINE_SIZE, stream)) + /* Read the next line */ + + if (!read_line(stream)) { return NULL; } @@ -581,7 +746,7 @@ static char *getstring(char *ptr) } } - return ptr; + return htmlize(ptr); } /**************************************************************************** @@ -598,7 +763,7 @@ static void push_dependency(const char *dependency) if (ndx >= MAX_DEPENDENCIES) { - fprintf(stderr, "Too many dependencies, aborting\n"); + error("Too many dependencies, aborting\n"); exit(ERROR_TOO_MANY_DEPENDENCIES); } @@ -619,7 +784,7 @@ static void pop_dependency(void) int ndx = g_ndependencies - 1; if (ndx < 0) { - fprintf(stderr, "Dependency underflow, aborting\n"); + error("Dependency underflow, aborting\n"); exit(ERROR_DEPENDENCIES_UNDERFLOW); } @@ -646,7 +811,7 @@ static void incr_level(void) if (ndx >= MAX_LEVELS) { - fprintf(stderr, "Nesting level is too deep, aborting\n"); + error("Nesting level is too deep, aborting\n"); exit(ERROR_NESTING_TOO_DEEP); } @@ -671,7 +836,7 @@ static void decr_level(void) if (ndx < 0) { - fprintf(stderr, "Nesting level underflow, aborting\n"); + error("Nesting level underflow, aborting\n"); exit(ERROR_NESTING_UNDERFLOW); } @@ -692,7 +857,7 @@ static void incr_paranum(void) if (ndx < 0) { - fprintf(stderr, "Nesting level underflow, aborting\n"); + error("Nesting level underflow, aborting\n"); exit(ERROR_NESTING_UNDERFLOW); } @@ -784,8 +949,7 @@ static inline void process_help(FILE *stream) { /* Read the next line of comment text */ - g_line[LINE_SIZE] = '\0'; - if (!fgets(g_line, LINE_SIZE, stream)) + if (!read_line(stream)) { break; } @@ -874,7 +1038,7 @@ static inline void process_help(FILE *stream) newpara = false; } - body(" %s", ptr); + body(" %s", htmlize(ptr)); } if (!newpara) @@ -911,7 +1075,7 @@ static inline char *process_config(FILE *stream, const char *configname, help = false; - while ((ptr = read_line(stream)) != NULL) + while ((ptr = kconfig_line(stream)) != NULL) { /* Process the first token on the Kconfig file line */ @@ -1036,7 +1200,7 @@ static inline char *process_config(FILE *stream, const char *configname, ndx = config.cnselect; if (ndx >= MAX_SELECT) { - fprintf(stderr, "Too many 'select' lines\n"); + error("Too many 'select' lines\n"); exit(ERROR_TOO_MANY_SELECT); } @@ -1052,7 +1216,7 @@ static inline char *process_config(FILE *stream, const char *configname, char *value = strtok_r(NULL, " ", &g_lasts); if (strcmp(value, "on") != 0) { - fprintf(stderr, "Expected \"on\" after \"depends\"\n"); + error("Expected \"on\" after \"depends\"\n"); exit(ERRROR_ON_AFTER_DEPENDS); } @@ -1077,7 +1241,8 @@ static inline char *process_config(FILE *stream, const char *configname, default: { - debug("Terminating token: %s\n", token); + debug("CONFIG_%s: Terminating token: %s\n", + config.cname, token); } break; } @@ -1292,7 +1457,7 @@ static inline char *process_choice(FILE *stream, const char *kconfigdir) /* Process each line in the choice */ - while ((ptr = read_line(stream)) != NULL) + while ((ptr = kconfig_line(stream)) != NULL) { /* Process the first token on the Kconfig file line */ @@ -1332,7 +1497,7 @@ static inline char *process_choice(FILE *stream, const char *kconfigdir) char *value = strtok_r(NULL, " ", &g_lasts); if (strcmp(value, "on") != 0) { - fprintf(stderr, "Expected \"on\" after \"depends\"\n"); + error("Expected \"on\" after \"depends\"\n"); exit(ERRROR_ON_AFTER_DEPENDS); } @@ -1351,7 +1516,7 @@ static inline char *process_choice(FILE *stream, const char *kconfigdir) default: { - debug("Terminating token: %s\n", token); + debug("Choice: Terminating token: %s\n", token); } break; } @@ -1480,7 +1645,7 @@ static inline char *process_menu(FILE *stream, const char *kconfigdir) /* Process each line in the choice */ - while ((ptr = read_line(stream)) != NULL) + while ((ptr = kconfig_line(stream)) != NULL) { /* Process the first token on the Kconfig file line */ @@ -1496,7 +1661,7 @@ static inline char *process_menu(FILE *stream, const char *kconfigdir) char *value = strtok_r(NULL, " ", &g_lasts); if (strcmp(value, "on") != 0) { - fprintf(stderr, "Expected \"on\" after \"depends\"\n"); + error("Expected \"on\" after \"depends\"\n"); exit(ERRROR_ON_AFTER_DEPENDS); } @@ -1508,7 +1673,7 @@ static inline char *process_menu(FILE *stream, const char *kconfigdir) default: { - debug("Terminating token: %s\n", token); + debug("Menu: Terminating token: %s\n", token); } break; } @@ -1607,7 +1772,7 @@ static char *parse_kconfigfile(FILE *stream, const char *kconfigdir) /* Process each line in the Kconfig file */ - while ((ptr = read_line(stream)) != NULL) + while ((ptr = kconfig_line(stream)) != NULL) { /* Process the first token on the Kconfig file line */ @@ -1741,7 +1906,7 @@ static char *parse_kconfigfile(FILE *stream, const char *kconfigdir) { /* Set token to NULL to skip to the next line */ - debug("Unhandled token: %s\n", token); + error("Unhandled token: %s\n", token); token = NULL; } break; @@ -1778,7 +1943,7 @@ static void process_kconfigfile(const char *kconfigdir) stream = fopen(kconfigpath, "r"); if (!stream) { - fprintf(stderr, "open %s failed: %s\n", kconfigpath, strerror(errno)); + error("open %s failed: %s\n", kconfigpath, strerror(errno)); exit(ERROR_KCONFIG_OPEN_FAILURE); } @@ -1845,15 +2010,15 @@ int main(int argc, char **argv, char **envp) break; case '?' : - fprintf(stderr, "Unrecognized option: %c\n", optopt); + error("Unrecognized option: %c\n", optopt); show_usage(argv[0], ERROR_UNRECOGNIZED_OPTION); case ':' : - fprintf(stderr, "Missing option argument, option: %c\n", optopt); + error("Missing option argument, option: %c\n", optopt); show_usage(argv[0], ERROR_MISSING_OPTION_ARGUMENT); break; - fprintf(stderr, "Unexpected option: %c\n", ch); + error("Unexpected option: %c\n", ch); show_usage(argv[0], ERROR_UNEXPECTED_OPTION); } } @@ -1870,7 +2035,7 @@ int main(int argc, char **argv, char **envp) if (optind < argc) { - fprintf(stderr, "Unexpected garbage at the end of the line\n"); + error("Unexpected garbage at the end of the line\n"); show_usage(argv[0], ERROR_TOO_MANY_ARGUMENTS); } @@ -1881,7 +2046,7 @@ int main(int argc, char **argv, char **envp) g_outfile = fopen(outfile, "w"); if (!g_outfile) { - fprintf(stderr, "open %s failed: %s\n", outfile, strerror(errno)); + error("open %s failed: %s\n", outfile, strerror(errno)); exit(ERROR_OUTFILE_OPEN_FAILURE); } } @@ -1891,7 +2056,7 @@ int main(int argc, char **argv, char **envp) g_tmpfile = fopen(TMPFILE_NAME, "w"); if (!g_tmpfile) { - fprintf(stderr, "open %s failed: %s\n", TMPFILE_NAME, strerror(errno)); + error("open %s failed: %s\n", TMPFILE_NAME, strerror(errno)); exit(ERROR_TMPFILE_OPEN_FAILURE); } @@ -1942,7 +2107,7 @@ int main(int argc, char **argv, char **envp) g_tmpfile = fopen(TMPFILE_NAME, "r"); if (!g_tmpfile) { - fprintf(stderr, "open %s failed: %s\n", TMPFILE_NAME, strerror(errno)); + error("open %s failed: %s\n", TMPFILE_NAME, strerror(errno)); exit(ERROR_TMPFILE_OPEN_FAILURE); } -- cgit v1.2.3