diff options
Diffstat (limited to '')
-rw-r--r-- | common.h | 12 | ||||
-rw-r--r-- | makefile.c | 18 | ||||
-rw-r--r-- | mklint.c | 42 |
3 files changed, 64 insertions, 8 deletions
@@ -38,7 +38,8 @@ X(WC_CONTINUATION_TO_BLANK, "continuation-to-blank", WARN)\ X(WC_EOF_LINE_CONTINUATION, "eof-line-continuation", WARN)\ X(WC_UNINDENTED_CONTINUATION, "unindented-continuation", WARN)\ - X(WC_SPACELESS_CONTINUATION, "spaceless-continuation", WARN) + X(WC_SPACELESS_CONTINUATION, "spaceless-continuation", WARN)\ + X(WC_COMMENT_CONTINUATION, "comment-continuation", WARN) enum action { @@ -75,12 +76,19 @@ struct line { size_t lineno; int eof; int nest_level; - char continuation_joiner; + char continuation_joiner; /* If '\\', it shall be '\\\n' */ +}; + +enum macro_bracket_style { + INCONSISTENT, + ROUND, + CURLY }; struct style { size_t max_line_length; int only_empty_blank_lines; + enum macro_bracket_style macro_bracket_style; }; @@ -36,10 +36,24 @@ open_default_makefile(const char **pathp) "alternatives are ./makefile and ./Makefile"); find_existing_fallbacks: + /* This serves two purposes: to inform the user that + * we are only checking one of the files, and which + * would (which is printed earlier), and to information + * the user that it can be confusing. It is not common + * practice run make(1) to generate ./makefile from + * ./Makefile and (either immediately or by running + * make(1) again) built the project from ./Makefile, + * although that certainly can be useful if there are + * parts of the makefile you want to generate, such + * as .h file dependencies for .c files in very large + * projects that have many .h files and many .c files + * that each only depend on a few .h files. + */ for (i++; i < ELEMSOF(default_makefiles); i++) if (!access(default_makefiles[i], F_OK)) - warnf_warning(WC_EXTRA_MAKEFILE, "found additional standard makefile: %s", - default_makefiles[i]); + warnf_confusing(WC_EXTRA_MAKEFILE, + "found additional standard makefile, this be confusing: %s", + default_makefiles[i]); return fd; } @@ -8,7 +8,8 @@ int exit_status = 0; struct style style = { .max_line_length = 120, - .only_empty_blank_lines = 1 + .only_empty_blank_lines = 1, + .macro_bracket_style = ROUND }; @@ -18,7 +19,7 @@ set_line_continuation_joiner(struct line *line) if (line->len && line->data[line->len - 1] == '\\') { line->data[--line->len] = '\0'; /* Doesn't matter here if the first non-white space is # */ - line->continuation_joiner = line->data[0] == '\t' ? '\t' : ' '; + line->continuation_joiner = line->data[0] == '\t' ? '\\' : ' '; } else { line->continuation_joiner = '\0'; } @@ -82,7 +83,6 @@ check_line_continuations(struct line *lines, size_t nlines) } - static enum line_class classify_line(struct line *line) { @@ -92,6 +92,7 @@ classify_line(struct line *line) if (!line->len) return EMPTY; +start_over: s = line->data; while (isspace(*s)) { @@ -99,7 +100,7 @@ classify_line(struct line *line) warned_bad_space = 1; warnf_undefined(WC_LEADING_BAD_SPACE, "%s:%zu: line contains leading white space other than" - "<space> and <tab>, which causes undefined behaviour", + "<space> and <tab>, which causes undefined behaviour", line->path, line->lineno); /* TODO what do we do here? */ } @@ -117,12 +118,24 @@ classify_line(struct line *line) return COMMENT; } else if (!*s) { + if (line->continuation_joiner) { + line++; + goto start_over; + } return BLANK; } else if (line->data[0] == '\t') { return COMMAND_LINE; } else { + if (*s == '-') { /* We will warn about this later */ + s++; + while (isspace(*s)) + s++; + } + + /* TODO unspecified behaviour if include line with <backslash> */ + /* TODO unspecified behaviour if continuation that looks like an include line */ return OTHER; } } @@ -178,12 +191,33 @@ main(int argc, char *argv[]) break; case COMMAND_LINE: + /* TODO list may, for historical reasons, end at a comment line; + * note, the specifications specify “comment line” which is + * define to include empty and blank lines; note however + * that a line that begins with a <hash> that is prefixed + * by whitespace is not a comment line, so, if it begins + * with <tab> followed by zero or more whitespace, and then + * a <hash>, it a command line, not a comment line. */ + /* TODO on line continuation, remove first '\t', if any, and join with '\\\n' */ case OTHER: + /* TODO first non-comment line shall be special target .POSIX without + * prerequisites or commands, behaviour is unspecified otherwise */ + /* TODO on line continuation, remove leading white space and join with ' ' */ break; default: abort(); } + + while (lines[i].continuation_joiner) { + if (memchr(lines[i].data, '#', lines[i].len)) { + warnf_confusing(WC_COMMENT_CONTINUATION, + "%s:%zu: using continuation of line to continue " + "a comment on the next line can cause confusion", + lines[i].path, lines[i].lineno); + } + i += 1; + } } free(lines); |