[gtk+/wip/otte/shader: 17/71] gsk: Add GskCodeSource
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/shader: 17/71] gsk: Add GskCodeSource
- Date: Thu, 12 Oct 2017 23:40:12 +0000 (UTC)
commit d8be69186e540b5ef62e90b1cf9e188a843d0b9c
Author: Benjamin Otte <otte redhat com>
Date: Mon Oct 2 02:14:31 2017 +0200
gsk: Add GskCodeSource
This is basically the source format we use to represent source code.
It can be created either from a file or from a GBytes, so we can use it
to hold all data that can be provided by user input (#defines) or by
actual files.
gsk/gsk.h | 1 +
gsk/gskcodesource.c | 151 ++++++++++++++++++++++++++++++++++++++++
gsk/gskcodesource.h | 41 +++++++++++
gsk/gskcodesourceprivate.h | 35 +++++++++
gsk/gskslcompiler.c | 11 +++-
gsk/gskslpreprocessor.c | 6 +-
gsk/gskslpreprocessorprivate.h | 2 +-
gsk/gsksltokenizer.c | 56 ++++++++++-----
gsk/gsksltokenizerprivate.h | 6 +-
gsk/gsktypes.h | 2 +
gsk/meson.build | 1 +
11 files changed, 286 insertions(+), 26 deletions(-)
---
diff --git a/gsk/gsk.h b/gsk/gsk.h
index 0b9cbd3..d4490fd 100644
--- a/gsk/gsk.h
+++ b/gsk/gsk.h
@@ -20,6 +20,7 @@
#define __GSK_H_INSIDE__
+#include <gsk/gskcodesource.h>
#include <gsk/gskenums.h>
#include <gsk/gskpixelshader.h>
#include <gsk/gskrenderer.h>
diff --git a/gsk/gskcodesource.c b/gsk/gskcodesource.c
new file mode 100644
index 0000000..155994f
--- /dev/null
+++ b/gsk/gskcodesource.c
@@ -0,0 +1,151 @@
+/* GTK - The GIMP Toolkit
+ *
+ * Copyright © 2017 Benjamin Otte <otte gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "gskcodesourceprivate.h"
+
+struct _GskCodeSource {
+ GObject parent_instance;
+
+ char *name;
+ GFile *file;
+
+ GBytes *bytes;
+};
+
+G_DEFINE_TYPE (GskCodeSource, gsk_code_source, G_TYPE_OBJECT)
+
+static void
+gsk_code_source_dispose (GObject *object)
+{
+ GskCodeSource *source = GSK_CODE_SOURCE (object);
+
+ g_free (source->name);
+ if (source->file)
+ g_object_unref (source->file);
+ if (source->bytes)
+ g_bytes_unref (source->bytes);
+
+ G_OBJECT_CLASS (gsk_code_source_parent_class)->dispose (object);
+}
+
+static void
+gsk_code_source_class_init (GskCodeSourceClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = gsk_code_source_dispose;
+}
+
+static void
+gsk_code_source_init (GskCodeSource *source)
+{
+}
+
+const char *
+gsk_code_source_get_name (GskCodeSource *source)
+{
+ g_return_val_if_fail (GSK_IS_CODE_SOURCE (source), NULL);
+
+ return source->name;
+}
+
+GFile *
+gsk_code_source_get_file (GskCodeSource *source)
+{
+ g_return_val_if_fail (GSK_IS_CODE_SOURCE (source), NULL);
+
+ return source->file;
+}
+
+GskCodeSource *
+gsk_code_source_new_for_bytes (const char *name,
+ GBytes *data)
+{
+ GskCodeSource *result;
+
+ g_return_val_if_fail (name != NULL, NULL);
+ g_return_val_if_fail (data != NULL, NULL);
+
+ result = g_object_new (GSK_TYPE_CODE_SOURCE, NULL);
+
+ result->name = g_strdup (name);
+ result->bytes = g_bytes_ref (data);
+
+ return result;
+}
+
+static char *
+get_name_for_file (GFile *file)
+{
+ GFileInfo *info;
+ char *result;
+
+ info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, 0, NULL, NULL);
+
+ if (info)
+ {
+ result = g_strdup (g_file_info_get_display_name (info));
+ g_object_unref (info);
+ }
+ else
+ {
+ result = g_strdup ("<broken file>");
+ }
+
+ return result;
+}
+
+GskCodeSource *
+gsk_code_source_new_for_file (GFile *file)
+{
+ GskCodeSource *result;
+
+ g_return_val_if_fail (G_IS_FILE (file), NULL);
+
+ result = g_object_new (GSK_TYPE_CODE_SOURCE, NULL);
+
+ result->file = g_object_ref (file);
+ result->name = get_name_for_file (file);
+
+ return result;
+}
+
+GBytes *
+gsk_code_source_load (GskCodeSource *source,
+ GError **error)
+{
+ gchar *data;
+ gsize length;
+
+ if (source->bytes)
+ return g_bytes_ref (source->bytes);
+
+ g_return_val_if_fail (source->file, NULL);
+
+ if (!g_file_load_contents (source->file,
+ NULL,
+ &data, &length,
+ NULL,
+ error))
+ return NULL;
+
+ return g_bytes_new_take (data, length);
+}
+
diff --git a/gsk/gskcodesource.h b/gsk/gskcodesource.h
new file mode 100644
index 0000000..415ed95
--- /dev/null
+++ b/gsk/gskcodesource.h
@@ -0,0 +1,41 @@
+/* GTK - The GIMP Toolkit
+ *
+ * Copyright © 2017 Benjamin Otte <otte gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GSK_CODE_SOURCE_H__
+#define __GSK_CODE_SOURCE_H__
+
+#if !defined (__GSK_H_INSIDE__) && !defined (GSK_COMPILATION)
+#error "Only <gsk/gsk.h> can be included directly."
+#endif
+
+#include <gsk/gsktypes.h>
+
+G_BEGIN_DECLS
+
+#define GSK_TYPE_CODE_SOURCE (gsk_code_source_get_type ())
+
+G_DECLARE_FINAL_TYPE (GskCodeSource, gsk_code_source, GSK, CODE_SOURCE, GObject)
+
+GDK_AVAILABLE_IN_3_92
+const char * gsk_code_source_get_name (GskCodeSource *source);
+GDK_AVAILABLE_IN_3_92
+GFile * gsk_code_source_get_file (GskCodeSource *source);
+
+G_END_DECLS
+
+#endif /* __GSK_CODE_SOURCE_H__ */
diff --git a/gsk/gskcodesourceprivate.h b/gsk/gskcodesourceprivate.h
new file mode 100644
index 0000000..83baa21
--- /dev/null
+++ b/gsk/gskcodesourceprivate.h
@@ -0,0 +1,35 @@
+/* GTK - The GIMP Toolkit
+ *
+ * Copyright © 2017 Benjamin Otte <otte gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GSK_CODE_SOURCE_PRIVATE_H__
+#define __GSK_CODE_SOURCE_PRIVATE_H__
+
+#include "gsk/gskcodesource.h"
+
+G_BEGIN_DECLS
+
+GskCodeSource * gsk_code_source_new_for_bytes (const char *name,
+ GBytes *data);
+GskCodeSource * gsk_code_source_new_for_file (GFile *file);
+
+GBytes * gsk_code_source_load (GskCodeSource *source,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* __GSK_CODE_SOURCE_PRIVATE_H__ */
diff --git a/gsk/gskslcompiler.c b/gsk/gskslcompiler.c
index b473cec..1c0b9c6 100644
--- a/gsk/gskslcompiler.c
+++ b/gsk/gskslcompiler.c
@@ -20,6 +20,7 @@
#include "gskslcompilerprivate.h"
+#include "gskcodesourceprivate.h"
#include "gsksldefineprivate.h"
#include "gskslpreprocessorprivate.h"
#include "gskslprogramprivate.h"
@@ -101,6 +102,7 @@ gsk_sl_compiler_add_define (GskSlCompiler *compiler,
GskCodeLocation location;
GskSlToken token = { 0, };
GError *real_error = NULL;
+ GskCodeSource *source;
GBytes *bytes;
g_return_val_if_fail (GSK_IS_SL_COMPILER (compiler), FALSE);
@@ -118,7 +120,8 @@ gsk_sl_compiler_add_define (GskSlCompiler *compiler,
define = gsk_sl_define_new (name, NULL);
bytes = g_bytes_new_static (definition, strlen (definition));
- tokenizer = gsk_sl_tokenizer_new (bytes,
+ source = gsk_code_source_new_for_bytes ("<define>", bytes);
+ tokenizer = gsk_sl_tokenizer_new (source,
gsk_sl_compiler_add_define_error_func,
&real_error,
NULL);
@@ -142,6 +145,7 @@ gsk_sl_compiler_add_define (GskSlCompiler *compiler,
gsk_sl_token_clear (&token);
gsk_sl_tokenizer_unref (tokenizer);
g_bytes_unref (bytes);
+ g_object_unref (source);
if (real_error == NULL)
{
@@ -187,12 +191,14 @@ gsk_sl_compiler_copy_defines (GskSlCompiler *compiler)
GskSlProgram *
gsk_sl_compiler_compile (GskSlCompiler *compiler,
- GBytes *source)
+ GBytes *bytes)
{
GskSlPreprocessor *preproc;
+ GskCodeSource *source;
GskSlProgram *program;
program = g_object_new (GSK_TYPE_SL_PROGRAM, NULL);
+ source = gsk_code_source_new_for_bytes ("<program>", bytes);
preproc = gsk_sl_preprocessor_new (compiler, source);
@@ -205,6 +211,7 @@ gsk_sl_compiler_compile (GskSlCompiler *compiler,
}
gsk_sl_preprocessor_unref (preproc);
+ g_object_unref (source);
return program;
}
diff --git a/gsk/gskslpreprocessor.c b/gsk/gskslpreprocessor.c
index eb22aaa..de92b69 100644
--- a/gsk/gskslpreprocessor.c
+++ b/gsk/gskslpreprocessor.c
@@ -20,6 +20,7 @@
#include "gskslpreprocessorprivate.h"
+#include "gskcodesource.h"
#include "gskslcompilerprivate.h"
#include "gsksldefineprivate.h"
#include "gsksltokenizerprivate.h"
@@ -75,7 +76,7 @@ gsk_sl_preprocessor_clear_token (gpointer data)
GskSlPreprocessor *
gsk_sl_preprocessor_new (GskSlCompiler *compiler,
- GBytes *source)
+ GskCodeSource *source)
{
GskSlPreprocessor *preproc;
@@ -609,7 +610,8 @@ gsk_sl_preprocessor_emit_error (GskSlPreprocessor *preproc,
{
preproc->fatal_error |= fatal;
- g_printerr ("%3zu:%2zu: %s: %s\n",
+ g_printerr ("%s:%zu:%zu: %s: %s\n",
+ gsk_code_source_get_name (location->source),
location->lines + 1, location->line_bytes,
fatal ? "error" : "warn",
error->message);
diff --git a/gsk/gskslpreprocessorprivate.h b/gsk/gskslpreprocessorprivate.h
index 13755d1..3ea5939 100644
--- a/gsk/gskslpreprocessorprivate.h
+++ b/gsk/gskslpreprocessorprivate.h
@@ -26,7 +26,7 @@
G_BEGIN_DECLS
GskSlPreprocessor * gsk_sl_preprocessor_new (GskSlCompiler *compiler,
- GBytes *source);
+ GskCodeSource *source);
GskSlPreprocessor * gsk_sl_preprocessor_ref (GskSlPreprocessor *preproc);
void gsk_sl_preprocessor_unref (GskSlPreprocessor *preproc);
diff --git a/gsk/gsksltokenizer.c b/gsk/gsksltokenizer.c
index e3c5219..6bbeb17 100644
--- a/gsk/gsksltokenizer.c
+++ b/gsk/gsksltokenizer.c
@@ -20,6 +20,7 @@
#include "gsksltokenizerprivate.h"
#include "gskslcompiler.h"
+#include "gskcodesourceprivate.h"
#include <math.h>
#include <string.h>
@@ -36,6 +37,7 @@ struct _GskSlTokenReader {
struct _GskSlTokenizer
{
gint ref_count;
+ GskCodeSource *source;
GBytes *bytes;
GskSlTokenizerErrorFunc error_func;
gpointer user_data;
@@ -45,9 +47,10 @@ struct _GskSlTokenizer
};
static void
-gsk_code_location_init (GskCodeLocation *location)
+gsk_code_location_init (GskCodeLocation *location,
+ GskCodeSource *source)
{
- memset (location, 0, sizeof (GskCodeLocation));
+ *location = (GskCodeLocation) { source, };
}
static void
@@ -1196,12 +1199,13 @@ gsk_sl_token_init_number (GskSlToken *token,
static void
gsk_sl_token_reader_init (GskSlTokenReader *reader,
+ GskCodeSource *source,
GBytes *bytes)
{
reader->data = g_bytes_get_data (bytes, NULL);
reader->end = reader->data + g_bytes_get_size (bytes);
- gsk_code_location_init (&reader->position);
+ gsk_code_location_init (&reader->position, source);
}
static void
@@ -1321,22 +1325,48 @@ gsk_sl_token_reader_consume (GskSlTokenReader *reader,
reader->data += offset;
}
+static void
+gsk_sl_tokenizer_emit_error (GskSlTokenizer *tokenizer,
+ const GskCodeLocation *location,
+ const GskSlToken *token,
+ const GError *error)
+{
+ if (tokenizer->error_func)
+ tokenizer->error_func (tokenizer, TRUE, location, token, error, tokenizer->user_data);
+ else
+ g_warning ("Unhandled GLSL error: %zu:%zu: %s", location->lines + 1, location->line_chars + 1,
error->message);
+}
+
GskSlTokenizer *
-gsk_sl_tokenizer_new (GBytes *bytes,
+gsk_sl_tokenizer_new (GskCodeSource *source,
GskSlTokenizerErrorFunc func,
gpointer user_data,
GDestroyNotify user_destroy)
{
GskSlTokenizer *tokenizer;
+ GError *error = NULL;
tokenizer = g_slice_new0 (GskSlTokenizer);
tokenizer->ref_count = 1;
- tokenizer->bytes = g_bytes_ref (bytes);
+ tokenizer->source = g_object_ref (source);
tokenizer->error_func = func;
tokenizer->user_data = user_data;
tokenizer->user_destroy = user_destroy;
- gsk_sl_token_reader_init (&tokenizer->reader, bytes);
+ tokenizer->bytes = gsk_code_source_load (source, &error);
+ if (tokenizer->bytes == NULL)
+ {
+ GskCodeLocation location;
+ GskSlToken token;
+
+ gsk_code_location_init (&location, tokenizer->source);
+ gsk_sl_token_init (&token, GSK_SL_TOKEN_EOF);
+ gsk_sl_tokenizer_emit_error (tokenizer, &location, &token, error);
+ g_error_free (error);
+ tokenizer->bytes = g_bytes_new (NULL, 0);
+ }
+
+ gsk_sl_token_reader_init (&tokenizer->reader, source, tokenizer->bytes);
return tokenizer;
}
@@ -1360,6 +1390,8 @@ gsk_sl_tokenizer_unref (GskSlTokenizer *tokenizer)
tokenizer->user_destroy (tokenizer->user_data);
g_bytes_unref (tokenizer->bytes);
+ g_object_unref (tokenizer->source);
+
g_slice_free (GskSlTokenizer, tokenizer);
}
@@ -1394,18 +1426,6 @@ set_parse_error (GError **error,
}
static void
-gsk_sl_tokenizer_emit_error (GskSlTokenizer *tokenizer,
- const GskCodeLocation *location,
- const GskSlToken *token,
- const GError *error)
-{
- if (tokenizer->error_func)
- tokenizer->error_func (tokenizer, TRUE, location, token, error, tokenizer->user_data);
- else
- g_warning ("Unhandled GLSL error: %zu:%zu: %s", location->lines + 1, location->line_chars + 1,
error->message);
-}
-
-static void
gsk_sl_token_reader_read_multi_line_comment (GskSlTokenReader *reader,
GskSlToken *token,
GError **error)
diff --git a/gsk/gsksltokenizerprivate.h b/gsk/gsksltokenizerprivate.h
index 381a851..897e5aa 100644
--- a/gsk/gsksltokenizerprivate.h
+++ b/gsk/gsksltokenizerprivate.h
@@ -284,10 +284,10 @@ void gsk_sl_token_print (const GskSlToke
GString *string);
char * gsk_sl_token_to_string (const GskSlToken *token);
-GskSlTokenizer * gsk_sl_tokenizer_new (GBytes *bytes,
+GskSlTokenizer * gsk_sl_tokenizer_new (GskCodeSource *source,
GskSlTokenizerErrorFunc func,
- gpointer user_data,
- GDestroyNotify user_destroy);
+ gpointer user_data,
+ GDestroyNotify user_destroy);
GskSlTokenizer * gsk_sl_tokenizer_ref (GskSlTokenizer *tokenizer);
void gsk_sl_tokenizer_unref (GskSlTokenizer *tokenizer);
diff --git a/gsk/gsktypes.h b/gsk/gsktypes.h
index 7323b93..613781a 100644
--- a/gsk/gsktypes.h
+++ b/gsk/gsktypes.h
@@ -27,6 +27,7 @@
#include <gsk/gskenums.h>
typedef struct _GskCodeLocation GskCodeLocation;
+typedef struct _GskCodeSource GskCodeSource;
typedef struct _GskPixelShader GskPixelShader;
typedef struct _GskRenderer GskRenderer;
typedef struct _GskSlCompiler GskSlCompiler;
@@ -35,6 +36,7 @@ typedef struct _GskTexture GskTexture;
struct _GskCodeLocation
{
+ GskCodeSource *source;
gsize bytes;
gsize chars;
gsize lines;
diff --git a/gsk/meson.build b/gsk/meson.build
index fd3ffbe..0bb7a1f 100644
--- a/gsk/meson.build
+++ b/gsk/meson.build
@@ -14,6 +14,7 @@ gsk_private_source_shaders = [
]
gsk_public_sources = files([
+ 'gskcodesource.c',
'gskpixelshader.c',
'gskrenderer.c',
'gskrendernode.c',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]