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.
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
|
||||
#define __GSK_H_INSIDE__
|
||||
|
||||
#include <gsk/gskcodesource.h>
|
||||
#include <gsk/gskenums.h>
|
||||
#include <gsk/gskpixelshader.h>
|
||||
#include <gsk/gskrenderer.h>
|
||||
|
||||
151
gsk/gskcodesource.c
Normal file
151
gsk/gskcodesource.c
Normal file
@@ -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);
|
||||
}
|
||||
|
||||
41
gsk/gskcodesource.h
Normal file
41
gsk/gskcodesource.h
Normal file
@@ -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__ */
|
||||
35
gsk/gskcodesourceprivate.h
Normal file
35
gsk/gskcodesourceprivate.h
Normal file
@@ -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__ */
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -1393,18 +1425,6 @@ set_parse_error (GError **error,
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -14,6 +14,7 @@ gsk_private_source_shaders = [
|
||||
]
|
||||
|
||||
gsk_public_sources = files([
|
||||
'gskcodesource.c',
|
||||
'gskpixelshader.c',
|
||||
'gskrenderer.c',
|
||||
'gskrendernode.c',
|
||||
|
||||
Reference in New Issue
Block a user