mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 05:18:08 +02:00
glcpp: Support line continuations within preprocessor directives.
Fixes CorrectPreprocess5.frag.
This commit is contained in:
parent
186e2634bf
commit
bc1097d151
1 changed files with 79 additions and 0 deletions
79
glcpp/pp.c
79
glcpp/pp.c
|
|
@ -21,6 +21,8 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include "glcpp.h"
|
||||
|
||||
void
|
||||
|
|
@ -56,11 +58,88 @@ glcpp_warning (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...)
|
|||
parser->info_log = talloc_strdup_append(parser->info_log, "\n");
|
||||
}
|
||||
|
||||
/* Searches backwards for '^ *#' from a given starting point. */
|
||||
static int
|
||||
in_directive(const char *shader, const char *ptr)
|
||||
{
|
||||
assert(ptr >= shader);
|
||||
|
||||
/* Search backwards for '#'. If we find a \n first, it doesn't count */
|
||||
for (; ptr >= shader && *ptr != '#'; ptr--) {
|
||||
if (*ptr == '\n')
|
||||
return 0;
|
||||
}
|
||||
if (ptr >= shader) {
|
||||
/* Found '#'...look for spaces preceded by a newline */
|
||||
for (ptr--; ptr >= shader && isblank(*ptr); ptr--);
|
||||
// FIXME: I don't think the '\n' case can happen
|
||||
if (ptr < shader || *ptr == '\n')
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Remove any line continuation characters in preprocessing directives.
|
||||
* However, ignore any in GLSL code, as "There is no line continuation
|
||||
* character" (1.30 page 9) in GLSL.
|
||||
*/
|
||||
static char *
|
||||
remove_line_continuations(glcpp_parser_t *ctx, const char *shader)
|
||||
{
|
||||
int in_continued_line = 0;
|
||||
int extra_newlines = 0;
|
||||
char *clean = talloc_strdup(ctx, "");
|
||||
const char *search_start = shader;
|
||||
const char *newline;
|
||||
while ((newline = strchr(search_start, '\n')) != NULL) {
|
||||
const char *backslash = NULL;
|
||||
/* Find the preceding '\', if it exists */
|
||||
if (newline[-1] == '\\') {
|
||||
backslash = newline - 1;
|
||||
} else if (newline[-1] == '\r' && newline[-2] == '\\') {
|
||||
backslash = newline - 2;
|
||||
}
|
||||
/* Double backslashes don't count (the backslash is escaped) */
|
||||
if (backslash != NULL && backslash[-1] == '\\') {
|
||||
backslash = NULL;
|
||||
}
|
||||
|
||||
if (backslash != NULL) {
|
||||
/* We found a line continuation, but do we care? */
|
||||
if (!in_continued_line) {
|
||||
if (in_directive(shader, backslash)) {
|
||||
in_continued_line = 1;
|
||||
extra_newlines = 0;
|
||||
}
|
||||
}
|
||||
if (in_continued_line) {
|
||||
/* Copy everything before the \ */
|
||||
clean = talloc_strndup_append(clean, shader, backslash - shader);
|
||||
shader = newline + 1;
|
||||
extra_newlines++;
|
||||
}
|
||||
} else if (in_continued_line) {
|
||||
/* Copy everything up to and including the \n */
|
||||
clean = talloc_strndup_append(clean, shader, newline - shader + 1);
|
||||
shader = newline + 1;
|
||||
/* Output extra newlines to make line numbers match */
|
||||
for (; extra_newlines > 0; extra_newlines--)
|
||||
clean = talloc_strdup_append(clean, "\n");
|
||||
in_continued_line = 0;
|
||||
}
|
||||
search_start = newline + 1;
|
||||
}
|
||||
clean = talloc_strdup_append(clean, shader);
|
||||
return clean;
|
||||
}
|
||||
|
||||
extern int
|
||||
preprocess(void *talloc_ctx, const char **shader, char **info_log)
|
||||
{
|
||||
int errors;
|
||||
glcpp_parser_t *parser = glcpp_parser_create ();
|
||||
*shader = remove_line_continuations(parser, *shader);
|
||||
|
||||
glcpp_lex_set_source_string (parser, *shader);
|
||||
|
||||
glcpp_parser_parse (parser);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue