[gtk+/wip/otte/shader: 13/98] gskslpreprocessor: Support parsing #version
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/shader: 13/98] gskslpreprocessor: Support parsing #version
- Date: Mon, 23 Oct 2017 03:11:06 +0000 (UTC)
commit 2a3a72816f9ac060f2bcd74c7e4be8a48c0f39b8
Author: Benjamin Otte <otte redhat com>
Date: Mon Oct 2 15:17:40 2017 +0200
gskslpreprocessor: Support parsing #version
This required a lot of reorganization because we have to track if we're
at the start of the document.
On the plus side, we now parse the #version tag and if it's correctly
used, we emit a warning that we don't support it.
Aren't we awesome?
gsk/gskenums.h | 17 ++++
gsk/gskslcompiler.h | 3 +-
gsk/gskslpreprocessor.c | 226 +++++++++++++++++++++++++++++++++--------------
3 files changed, 179 insertions(+), 67 deletions(-)
---
diff --git a/gsk/gskenums.h b/gsk/gskenums.h
index ca9d5a8..ddca9b2 100644
--- a/gsk/gskenums.h
+++ b/gsk/gskenums.h
@@ -175,4 +175,21 @@ typedef enum {
GSK_SERIALIZATION_INVALID_DATA
} GskSerializationError;
+/**
+ * GskSlProfile:
+ * @GSK_SL_PROFILE_NONE: No profile has been selected. Behaves the same
+ * as @GSK_SL_PROFILE_CORE.
+ * @GSK_SL_PROFILE_CORE: The OpenGL core profile
+ * @GSK_SL_PROFILE_COMPATIBILITY: The OpenGL compatibility profile
+ * @GSK_SL_PROFILE_ES: The OpenGL-ES profile
+ *
+ * Profile to use for GLSL compilation.
+ **/
+typedef enum {
+ GSK_SL_PROFILE_NONE,
+ GSK_SL_PROFILE_CORE,
+ GSK_SL_PROFILE_COMPATIBILITY,
+ GSK_SL_PROFILE_ES,
+} GskSlProfile;
+
#endif /* __GSK_TYPES_H__ */
diff --git a/gsk/gskslcompiler.h b/gsk/gskslcompiler.h
index 58c9e3a..16c2f2e 100644
--- a/gsk/gskslcompiler.h
+++ b/gsk/gskslcompiler.h
@@ -43,7 +43,8 @@ typedef enum {
typedef enum {
GSK_SL_COMPILER_WARNING_CONSTANT,
GSK_SL_COMPILER_WARNING_DEAD_CODE,
- GSK_SL_COMPILER_WARNING_SHADOW
+ GSK_SL_COMPILER_WARNING_SHADOW,
+ GSK_SL_COMPILER_WARNING_UNIMPLEMENTED
} GskSlCompilerWarning;
#define GSK_SL_COMPILER_ERROR (gsk_sl_compiler_error_quark ())
diff --git a/gsk/gskslpreprocessor.c b/gsk/gskslpreprocessor.c
index 98276c7..bf22097 100644
--- a/gsk/gskslpreprocessor.c
+++ b/gsk/gskslpreprocessor.c
@@ -76,27 +76,6 @@ gsk_sl_preprocessor_clear_token (gpointer data)
}
GskSlPreprocessor *
-gsk_sl_preprocessor_new (GskSlCompiler *compiler,
- GskCodeSource *source)
-{
- GskSlPreprocessor *preproc;
-
- preproc = g_slice_new0 (GskSlPreprocessor);
-
- preproc->ref_count = 1;
- preproc->compiler = g_object_ref (compiler);
- preproc->tokenizer = gsk_sl_tokenizer_new (source,
- gsk_sl_preprocessor_error_func,
- preproc,
- NULL);
- preproc->tokens = g_array_new (FALSE, FALSE, sizeof (GskSlPpToken));
- g_array_set_clear_func (preproc->tokens, gsk_sl_preprocessor_clear_token);
- preproc->defines = gsk_sl_compiler_copy_defines (compiler);
-
- return preproc;
-}
-
-GskSlPreprocessor *
gsk_sl_preprocessor_ref (GskSlPreprocessor *preproc)
{
g_return_val_if_fail (preproc != NULL, NULL);
@@ -169,6 +148,69 @@ gsk_sl_preprocessor_in_ignored_conditional (GskSlPreprocessor *preproc)
return FALSE;
}
+static void
+gsk_sl_preprocessor_handle_version (GskSlPreprocessor *preproc,
+ GskCodeLocation *location,
+ int version,
+ const char *profile_name,
+ gboolean first_token_ever)
+{
+ G_GNUC_UNUSED GskSlProfile profile;
+
+ if (version <= 0)
+ {
+ gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, location, "version must be a positive number.");
+ return;
+ }
+ if (profile_name == NULL)
+ profile = GSK_SL_PROFILE_NONE;
+ else if (g_str_equal (profile_name, "core"))
+ profile = GSK_SL_PROFILE_CORE;
+ else if (g_str_equal (profile_name, "compatibility"))
+ profile = GSK_SL_PROFILE_COMPATIBILITY;
+ else if (g_str_equal (profile_name, "es"))
+ profile = GSK_SL_PROFILE_ES;
+ else
+ {
+ gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, location, "Unknown #version profile \"%s\".",
profile_name);
+ return;
+ }
+ if (!first_token_ever)
+ {
+ gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, location, "#version directive must be first in
compilation.");
+ return;
+ }
+
+ gsk_sl_preprocessor_warn_full (preproc, UNIMPLEMENTED, location, "#version directive not supported.");
+}
+
+static gboolean
+gsk_sl_preprocessor_next_token (GskSlPreprocessor *preproc,
+ GskSlPpToken *pp,
+ gboolean *last_was_newline)
+{
+ gboolean contained_newline = FALSE;
+
+ pp->token = (GskSlToken) { 0, };
+
+ do
+ {
+ pp->location = *gsk_sl_tokenizer_get_location (preproc->tokenizer);
+ *last_was_newline = gsk_sl_token_is (&pp->token, GSK_SL_TOKEN_NEWLINE);
+ contained_newline |= gsk_sl_token_is (&pp->token, GSK_SL_TOKEN_NEWLINE);
+ gsk_sl_tokenizer_read_token (preproc->tokenizer, &pp->token);
+ }
+ while (gsk_sl_token_is_skipped (&pp->token));
+
+ return contained_newline || gsk_sl_token_is (&pp->token, GSK_SL_TOKEN_EOF);
+}
+
+static void
+gsk_sl_preprocessor_handle_token (GskSlPreprocessor *preproc,
+ GskSlPpToken *pp,
+ gboolean was_newline,
+ gboolean was_start_of_document);
+
static gboolean
gsk_sl_preprocessor_include (GskSlPreprocessor *preproc,
GskSlPpToken *pp,
@@ -176,6 +218,7 @@ gsk_sl_preprocessor_include (GskSlPreprocessor *preproc,
{
GskCodeSource *source;
GError *error = NULL;
+ gboolean was_newline;
source = gsk_sl_compiler_resolve_include (preproc->compiler,
gsk_sl_tokenizer_get_location (preproc->tokenizer)->source,
@@ -214,36 +257,15 @@ gsk_sl_preprocessor_include (GskSlPreprocessor *preproc,
gsk_sl_preprocessor_error_func,
preproc,
NULL);
- return TRUE;
-}
-
-static gboolean
-gsk_sl_preprocessor_next_token (GskSlPreprocessor *preproc,
- GskSlPpToken *pp,
- gboolean *last_was_newline)
-{
- gboolean contained_newline = FALSE;
-
- pp->token = (GskSlToken) { 0, };
- do
- {
- pp->location = *gsk_sl_tokenizer_get_location (preproc->tokenizer);
- *last_was_newline = gsk_sl_token_is (&pp->token, GSK_SL_TOKEN_NEWLINE);
- contained_newline |= gsk_sl_token_is (&pp->token, GSK_SL_TOKEN_NEWLINE);
- gsk_sl_tokenizer_read_token (preproc->tokenizer, &pp->token);
- }
- while (gsk_sl_token_is_skipped (&pp->token));
+ /* process first token, so we can ensure it assumes a newline */
+ gsk_sl_preprocessor_next_token (preproc, pp, &was_newline);
+ gsk_sl_preprocessor_handle_token (preproc, pp, TRUE, FALSE);
- return contained_newline || gsk_sl_token_is (&pp->token, GSK_SL_TOKEN_EOF);
+ return TRUE;
}
static void
-gsk_sl_preprocessor_handle_token (GskSlPreprocessor *preproc,
- GskSlPpToken *pp,
- gboolean was_newline);
-
-static void
gsk_sl_preprocessor_append_token (GskSlPreprocessor *preproc,
GskSlPpToken *pp,
GSList *used_defines)
@@ -257,7 +279,7 @@ gsk_sl_preprocessor_append_token (GskSlPreprocessor *preproc,
preproc->pending_tokenizers = g_slist_remove (preproc->pending_tokenizers, preproc->tokenizer);
gsk_sl_preprocessor_clear_token (pp);
gsk_sl_preprocessor_next_token (preproc, pp, &was_newline);
- gsk_sl_preprocessor_handle_token (preproc, pp, TRUE);
+ gsk_sl_preprocessor_handle_token (preproc, pp, TRUE, FALSE);
return;
}
@@ -304,7 +326,8 @@ gsk_sl_preprocessor_append_token (GskSlPreprocessor *preproc,
}
static void
-gsk_sl_preprocessor_handle_preprocessor_directive (GskSlPreprocessor *preproc)
+gsk_sl_preprocessor_handle_preprocessor_directive (GskSlPreprocessor *preproc,
+ gboolean first_token_ever)
{
GskSlPpToken pp;
gboolean was_newline;
@@ -312,7 +335,7 @@ gsk_sl_preprocessor_handle_preprocessor_directive (GskSlPreprocessor *preproc)
if (gsk_sl_preprocessor_next_token (preproc, &pp, &was_newline))
{
/* empty # line */
- gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline);
+ gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline, FALSE);
return;
}
@@ -351,7 +374,7 @@ gsk_sl_preprocessor_handle_preprocessor_directive (GskSlPreprocessor *preproc)
}
else
{
- gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline);
+ gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline, FALSE);
}
return;
}
@@ -379,7 +402,7 @@ gsk_sl_preprocessor_handle_preprocessor_directive (GskSlPreprocessor *preproc)
}
else
{
- gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline);
+ gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline, FALSE);
}
return;
}
@@ -394,7 +417,7 @@ gsk_sl_preprocessor_handle_preprocessor_directive (GskSlPreprocessor *preproc)
if (gsk_sl_preprocessor_next_token (preproc, &pp, &was_newline))
{
gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, &pp.location, "No variable after
#ifdef.");
- gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline);
+ gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline, FALSE);
return;
}
if (!gsk_sl_token_is (&pp.token, GSK_SL_TOKEN_IDENTIFIER))
@@ -420,7 +443,7 @@ gsk_sl_preprocessor_handle_preprocessor_directive (GskSlPreprocessor *preproc)
}
else
{
- gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline);
+ gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline, FALSE);
}
return;
}
@@ -431,7 +454,7 @@ gsk_sl_preprocessor_handle_preprocessor_directive (GskSlPreprocessor *preproc)
if (gsk_sl_preprocessor_next_token (preproc, &pp, &was_newline))
{
gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, &pp.location, "No variable after
#ifndef.");
- gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline);
+ gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline, FALSE);
return;
}
if (!gsk_sl_token_is (&pp.token, GSK_SL_TOKEN_IDENTIFIER))
@@ -457,7 +480,7 @@ gsk_sl_preprocessor_handle_preprocessor_directive (GskSlPreprocessor *preproc)
}
else
{
- gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline);
+ gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline, FALSE);
}
return;
}
@@ -475,7 +498,7 @@ gsk_sl_preprocessor_handle_preprocessor_directive (GskSlPreprocessor *preproc)
if (gsk_sl_preprocessor_next_token (preproc, &pp, &was_newline))
{
gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, &pp.location, "No variable after
#define.");
- gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline);
+ gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline, FALSE);
return;
}
if (!gsk_sl_token_is (&pp.token, GSK_SL_TOKEN_IDENTIFIER))
@@ -499,7 +522,7 @@ gsk_sl_preprocessor_handle_preprocessor_directive (GskSlPreprocessor *preproc)
gsk_sl_preprocessor_clear_token (&pp);
}
g_hash_table_replace (preproc->defines, (gpointer) gsk_sl_define_get_name (define), define);
- gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline);
+ gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline, FALSE);
return;
}
}
@@ -509,7 +532,7 @@ gsk_sl_preprocessor_handle_preprocessor_directive (GskSlPreprocessor *preproc)
if (gsk_sl_preprocessor_next_token (preproc, &pp, &was_newline))
{
gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, &pp.location, "No filename after
#include.");
- gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline);
+ gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline, FALSE);
return;
}
if (gsk_sl_token_is (&pp.token, GSK_SL_TOKEN_STRING))
@@ -543,7 +566,7 @@ gsk_sl_preprocessor_handle_preprocessor_directive (GskSlPreprocessor *preproc)
if (gsk_sl_preprocessor_next_token (preproc, &pp, &was_newline))
{
gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, &pp.location, "No variable after
#undef.");
- gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline);
+ gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline, FALSE);
return;
}
if (!gsk_sl_token_is (&pp.token, GSK_SL_TOKEN_IDENTIFIER))
@@ -562,16 +585,52 @@ gsk_sl_preprocessor_handle_preprocessor_directive (GskSlPreprocessor *preproc)
}
else
{
- gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline);
+ gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline, FALSE);
}
return;
}
}
-#if 0
else if (g_str_equal (pp.token.str, "version"))
{
+ gsk_sl_preprocessor_clear_token (&pp);
+ if (gsk_sl_preprocessor_next_token (preproc, &pp, &was_newline))
+ {
+ gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, &pp.location, "No version specified
after #version.");
+ gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline, FALSE);
+ return;
+ }
+ if (!gsk_sl_token_is (&pp.token, GSK_SL_TOKEN_INTCONSTANT))
+ {
+ gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, &pp.location, "Expected version
number.");
+ gsk_sl_preprocessor_clear_token (&pp);
+ }
+ else
+ {
+ GskCodeLocation location = pp.location;
+ gint version = pp.token.i32;
+
+ gsk_sl_preprocessor_clear_token (&pp);
+ if (gsk_sl_preprocessor_next_token (preproc, &pp, &was_newline))
+ {
+ gsk_sl_preprocessor_handle_version (preproc, &location, version, NULL, first_token_ever);
+ gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline, FALSE);
+ return;
+ }
+ else if (gsk_sl_token_is (&pp.token, GSK_SL_TOKEN_IDENTIFIER))
+ {
+ gsk_sl_preprocessor_handle_version (preproc, &pp.location, version, pp.token.str,
first_token_ever);
+ gsk_sl_preprocessor_clear_token (&pp);
+ if (gsk_sl_preprocessor_next_token (preproc, &pp, &was_newline))
+ {
+ gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline, FALSE);
+ return;
+ }
+ }
+
+ gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, &pp.location, "Expected newline
#version.");
+ gsk_sl_preprocessor_clear_token (&pp);
+ }
}
-#endif
else
{
gsk_sl_preprocessor_error_full (preproc, PREPROCESSOR, &pp.location, "Unknown preprocessor
directive #%s.", pp.token.str);
@@ -587,13 +646,14 @@ gsk_sl_preprocessor_handle_preprocessor_directive (GskSlPreprocessor *preproc)
while (!gsk_sl_preprocessor_next_token (preproc, &pp, &was_newline))
gsk_sl_preprocessor_clear_token (&pp);
- gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline);
+ gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline, FALSE);
}
static void
gsk_sl_preprocessor_handle_token (GskSlPreprocessor *preproc,
GskSlPpToken *pp,
- gboolean was_newline)
+ gboolean was_newline,
+ gboolean start_of_document)
{
if (gsk_sl_token_is (&pp->token, GSK_SL_TOKEN_HASH))
{
@@ -605,7 +665,7 @@ gsk_sl_preprocessor_handle_token (GskSlPreprocessor *preproc,
else
{
gsk_sl_preprocessor_clear_token (pp);
- gsk_sl_preprocessor_handle_preprocessor_directive (preproc);
+ gsk_sl_preprocessor_handle_preprocessor_directive (preproc, start_of_document);
}
}
else
@@ -614,6 +674,40 @@ gsk_sl_preprocessor_handle_token (GskSlPreprocessor *preproc,
}
}
+GskSlPreprocessor *
+gsk_sl_preprocessor_new (GskSlCompiler *compiler,
+ GskCodeSource *source)
+{
+ GskSlPreprocessor *preproc;
+ GskSlPpToken pp;
+
+ preproc = g_slice_new0 (GskSlPreprocessor);
+
+ preproc->ref_count = 1;
+ preproc->compiler = g_object_ref (compiler);
+ preproc->tokenizer = gsk_sl_tokenizer_new (source,
+ gsk_sl_preprocessor_error_func,
+ preproc,
+ NULL);
+ preproc->tokens = g_array_new (FALSE, FALSE, sizeof (GskSlPpToken));
+ g_array_set_clear_func (preproc->tokens, gsk_sl_preprocessor_clear_token);
+ preproc->defines = gsk_sl_compiler_copy_defines (compiler);
+
+ /* process the first token, so we can parse #version */
+ pp.location = *gsk_sl_tokenizer_get_location (preproc->tokenizer);
+ gsk_sl_tokenizer_read_token (preproc->tokenizer, &pp.token);
+ if (!gsk_sl_token_is_skipped (&pp.token))
+ gsk_sl_preprocessor_handle_token (preproc, &pp, TRUE, TRUE);
+ else
+ {
+ gboolean was_newline;
+ gsk_sl_preprocessor_next_token (preproc, &pp, &was_newline);
+ gsk_sl_preprocessor_handle_token (preproc, &pp, TRUE, FALSE);
+ }
+
+ return preproc;
+}
+
static void
gsk_sl_preprocessor_ensure (GskSlPreprocessor *preproc)
{
@@ -624,7 +718,7 @@ gsk_sl_preprocessor_ensure (GskSlPreprocessor *preproc)
{
gsk_sl_preprocessor_next_token (preproc, &pp, &was_newline);
- gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline || pp.location.bytes == 0);
+ gsk_sl_preprocessor_handle_token (preproc, &pp, was_newline, FALSE);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]