From: Trent Huber Date: Wed, 11 Dec 2024 07:47:03 +0000 (-0500) Subject: Update line_is_comment() function X-Git-Url: https://trenthuber.com/code?a=commitdiff_plain;h=2e1a852fe342819747d3c0eedf7e7ad796b2caae;p=xpmview.git Update line_is_comment() function - Thanks to [dasbrotchen](https://github.com/trenthuber/simplexpm/pull/1) for bringing up the issues of comments and strings on the same line - Improved the method of removing comments from lines; takes into account strings - Subtle formatting and TODOs --- diff --git a/src/parser.c b/src/parser.c index 0e9b2e5..f1f4b09 100644 --- a/src/parser.c +++ b/src/parser.c @@ -169,14 +169,11 @@ bool parse_xpm_file(Image *image, const char *file_path) { SIMPLE_XPM_ERROR("Line %d in pixels sections contains too few characters to " "be properly parsed", line_number); for (size_t j = 0; j < width; ++j) { - for (size_t k = 0; k < chars_per_pixel; ++k) { + for (size_t k = 0; k < chars_per_pixel; ++k) key_buffer[k] = *line_buffer_p++; - } - for (size_t l = 0; l < num_colors; ++l) { - if (strncmp(&keys[l * chars_per_pixel], key_buffer, chars_per_pixel) == 0) { + for (size_t l = 0; l < num_colors; ++l) + if (strncmp(&keys[l * chars_per_pixel], key_buffer, chars_per_pixel) == 0) pixels[width * i + j] = color_table[current_mode * num_colors + l]; - } - } } if (*line_buffer_p++ != '"') // Needs to be done manually for whitespace SIMPLE_XPM_ERROR("Expected a `\"' at the end of line %d", line_number); @@ -191,6 +188,9 @@ bool parse_xpm_file(Image *image, const char *file_path) { fprintf(stdout, "simplexpm: INFO: Parsing XPM extensions\n"); } + /* TODO: Generally improve tokenizer and specifically allow for "};" to appear + * on the same line as the ",". + */ get_next_line_check_eof(&line_buffer, file); line_buffer_p = line_buffer; check_next_token(&line_buffer_p, "}"); diff --git a/src/tokenizer.c b/src/tokenizer.c index 065e8d9..ac93d04 100644 --- a/src/tokenizer.c +++ b/src/tokenizer.c @@ -10,31 +10,44 @@ static bool is_multiline; static unsigned int multiline_num; static bool line_is_comment(char *line) { - - // Remove comments from line - char *multiline_start = NULL; - do { - if (is_multiline) { - char *multiline_end; - if (multiline_start) multiline_end = strstr(multiline_start + 2, "*/"); - else multiline_end = strstr(line, "*/"); - if (!multiline_end) { - if (!multiline_start) return true; - *multiline_start = '\0'; + for (int i = 0; i < (int)strlen(line); ++i) { + switch (line[i]) { + case '/': + switch (line[i + 1]) { + case '/': + line[i] = '\0'; + goto loop_end; + case '*':; + char *multiline_end = strstr(&line[i + 2], "*/"); + if (!multiline_end) { + line[i] = '\0'; + multiline_num = line_number; + is_multiline = true; + goto loop_end; + } + line[i] = ' '; + multiline_end += strlen("*/"); + memmove(&line[i + 1], multiline_end, strlen(multiline_end) + 1); break; } + break; + case '*': + if (!is_multiline) break; + if (line[i + 1] != '/') break; is_multiline = false; - if (multiline_start) *(multiline_start++) = ' '; - else multiline_start = line; - multiline_end += strlen("*/"); - memmove(multiline_start, multiline_end, strlen(multiline_end) + 1); + memmove(line, &line[i + 2], strlen(&line[i + 2]) + 1); + i = -1; + break; + case '"':; + char *string_end = strstr(&line[i + 1], "\""); + if (!string_end) + SIMPLE_XPM_ERROR("String on line %d not terminated; " + "no support for multiline strings", line_number); + i += string_end - &line[i]; + break; } - char *singleline_start = strstr(line, "//"); - if (singleline_start) - *singleline_start = '\0'; - - multiline_start = strstr(line, "/*"); - } while (multiline_start && (multiline_num = line_number, is_multiline = true)); + } +loop_end: // Return true if the line is only whitespace at this point return *strstrip(&line) == '\0'; @@ -99,6 +112,7 @@ char *get_next_token(char **string) { return result; } +// Used for the "values" and "colors" sections, but not the "pixels" section bool get_terminal_token(char **string, char **token) { bool result = true; while (**string == '\t' || **string == ' ') ++*string;