gsk: Add a skeleton for a GLSL parser
This commit is contained in:
@@ -5,6 +5,7 @@ private_headers = [
|
||||
'gskgldriverprivate.h',
|
||||
'gskglprofilerprivate.h',
|
||||
'gskglrendererprivate.h',
|
||||
'gskpixelshaderprivate.h',
|
||||
'gskprivate.h',
|
||||
'gskprofilerprivate.h',
|
||||
'gskrendererprivate.h',
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define __GSK_H_INSIDE__
|
||||
|
||||
#include <gsk/gskenums.h>
|
||||
#include <gsk/gskpixelshader.h>
|
||||
#include <gsk/gskrenderer.h>
|
||||
#include <gsk/gskrendernode.h>
|
||||
#include <gsk/gskroundedrect.h>
|
||||
|
||||
184
gsk/gskpixelshader.c
Normal file
184
gsk/gskpixelshader.c
Normal file
@@ -0,0 +1,184 @@
|
||||
/* GSK - The GTK Scene Kit
|
||||
*
|
||||
* Copyright 2017 © Benjamin Otte
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:GskPixelShader
|
||||
* @Title: GskPixelShader
|
||||
* @Short_description: A pixel shader
|
||||
*
|
||||
* #GskPixelShader is the object used to create pixel shaders. The language
|
||||
* used is GLSL with a few extensions.
|
||||
*
|
||||
* #GskPixelShader is an immutable object: That means you cannot change
|
||||
* anything about it other than increasing the reference count via
|
||||
* g_object_ref().
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gskpixelshaderprivate.h"
|
||||
|
||||
#include "gskdebugprivate.h"
|
||||
|
||||
#include "gdk/gdkinternals.h"
|
||||
|
||||
/**
|
||||
* GskPixelShader:
|
||||
*
|
||||
* The `GskPixelShader` structure contains only private data.
|
||||
*
|
||||
* Since: 3.90
|
||||
*/
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_N_TEXTURES,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *properties[N_PROPS];
|
||||
|
||||
G_DEFINE_TYPE (GskPixelShader, gsk_pixel_shader, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gsk_pixel_shader_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
/* GskPixelShader *self = GSK_PIXEL_SHADER (gobject); */
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_pixel_shader_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GskPixelShader *self = GSK_PIXEL_SHADER (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_N_TEXTURES:
|
||||
g_value_set_uint (value, self->n_textures);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_pixel_shader_dispose (GObject *object)
|
||||
{
|
||||
GskPixelShader *self = GSK_PIXEL_SHADER (object);
|
||||
|
||||
gsk_sl_node_unref (self->program);
|
||||
|
||||
G_OBJECT_CLASS (gsk_pixel_shader_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_pixel_shader_class_init (GskPixelShaderClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->set_property = gsk_pixel_shader_set_property;
|
||||
gobject_class->get_property = gsk_pixel_shader_get_property;
|
||||
gobject_class->dispose = gsk_pixel_shader_dispose;
|
||||
|
||||
/**
|
||||
* GskPixelShader:n-textures:
|
||||
*
|
||||
* The number of input textures to the shader.
|
||||
*
|
||||
* Since: 3.92
|
||||
*/
|
||||
properties[PROP_N_TEXTURES] =
|
||||
g_param_spec_uint ("n-textures",
|
||||
"n textures",
|
||||
"The number of input textures",
|
||||
0,
|
||||
G_MAXUINT,
|
||||
0,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
g_object_class_install_properties (gobject_class, N_PROPS, properties);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_pixel_shader_init (GskPixelShader *self)
|
||||
{
|
||||
}
|
||||
|
||||
GskPixelShader *
|
||||
gsk_pixel_shader_new_for_data (GBytes *source,
|
||||
GskShaderErrorFunc error_func,
|
||||
gpointer error_data)
|
||||
{
|
||||
GskPixelShader *shader;
|
||||
GskSlNode *program;
|
||||
|
||||
g_return_val_if_fail (source != NULL, NULL);
|
||||
|
||||
program = gsk_sl_node_new_program (source, NULL);
|
||||
if (program == NULL)
|
||||
return NULL;
|
||||
|
||||
shader = g_object_new (GSK_TYPE_PIXEL_SHADER, NULL);
|
||||
|
||||
shader->program = program;
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_pixel_shader_print (GskPixelShader *shader,
|
||||
GString *string)
|
||||
{
|
||||
g_return_if_fail (GSK_IS_PIXEL_SHADER (shader));
|
||||
g_return_if_fail (string != NULL);
|
||||
|
||||
gsk_sl_node_print (shader->program, string);
|
||||
}
|
||||
|
||||
char *
|
||||
gsk_pixel_shader_to_string (GskPixelShader *shader)
|
||||
{
|
||||
GString *string;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_PIXEL_SHADER (shader), NULL);
|
||||
|
||||
string = g_string_new (NULL);
|
||||
|
||||
gsk_pixel_shader_print (shader, string);
|
||||
|
||||
return g_string_free (string, FALSE);
|
||||
}
|
||||
|
||||
62
gsk/gskpixelshader.h
Normal file
62
gsk/gskpixelshader.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/* GSK - The GTK Scene Kit
|
||||
*
|
||||
* Copyright 2017 © Benjamin Otte
|
||||
*
|
||||
* 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_PIXEL_SHADER_H__
|
||||
#define __GSK_PIXEL_SHADER_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_PIXEL_SHADER (gsk_pixel_shader_get_type ())
|
||||
|
||||
#define GSK_PIXEL_SHADER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_PIXEL_SHADER, GskPixelShader))
|
||||
#define GSK_IS_PIXEL_SHADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_PIXEL_SHADER))
|
||||
|
||||
typedef struct _GskPixelShaderClass GskPixelShaderClass;
|
||||
|
||||
typedef void (* GskShaderErrorFunc) (GskPixelShader *shader,
|
||||
gboolean fatal,
|
||||
const GskCodeLocation *location,
|
||||
const GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GskPixelShader, g_object_unref)
|
||||
|
||||
|
||||
GDK_AVAILABLE_IN_3_92
|
||||
GType gsk_pixel_shader_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_3_92
|
||||
GskPixelShader * gsk_pixel_shader_new_for_data (GBytes *source,
|
||||
GskShaderErrorFunc error_func,
|
||||
gpointer error_data);
|
||||
|
||||
GDK_AVAILABLE_IN_3_92
|
||||
void gsk_pixel_shader_print (GskPixelShader *shader,
|
||||
GString *string);
|
||||
GDK_AVAILABLE_IN_3_92
|
||||
char * gsk_pixel_shader_to_string (GskPixelShader *shader);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_PIXEL_SHADER_H__ */
|
||||
29
gsk/gskpixelshaderprivate.h
Normal file
29
gsk/gskpixelshaderprivate.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef __GSK_PIXEL_SHADER_PRIVATE_H__
|
||||
#define __GSK_PIXEL_SHADER_PRIVATE_H__
|
||||
|
||||
#include "gskpixelshader.h"
|
||||
|
||||
#include "gskslnodeprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GSK_PIXEL_SHADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_TEXTURE, GskPixelShaderClass))
|
||||
#define GSK_IS_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_TEXTURE))
|
||||
#define GSK_PIXEL_SHADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_TEXTURE, GskPixelShaderClass))
|
||||
|
||||
struct _GskPixelShader
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GskSlNode *program;
|
||||
|
||||
guint n_textures;
|
||||
};
|
||||
|
||||
struct _GskPixelShaderClass {
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_PIXEL_SHADER_PRIVATE_H__ */
|
||||
285
gsk/gskslnode.c
Normal file
285
gsk/gskslnode.c
Normal file
@@ -0,0 +1,285 @@
|
||||
/* 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 "gskslnodeprivate.h"
|
||||
|
||||
#include "gskslpreprocessorprivate.h"
|
||||
#include "gsksltypeprivate.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static GskSlNode *
|
||||
gsk_sl_node_alloc (const GskSlNodeClass *klass,
|
||||
gsize size)
|
||||
{
|
||||
GskSlNode *node;
|
||||
|
||||
node = g_slice_alloc0 (size);
|
||||
|
||||
node->class = klass;
|
||||
node->ref_count = 1;
|
||||
|
||||
return node;
|
||||
}
|
||||
#define gsk_sl_node_new(_name, _klass) ((_name *) gsk_sl_node_alloc ((_klass), sizeof (_name)))
|
||||
|
||||
/* PROGRAM */
|
||||
|
||||
typedef struct _GskSlNodeProgram GskSlNodeProgram;
|
||||
|
||||
struct _GskSlNodeProgram {
|
||||
GskSlNode parent;
|
||||
|
||||
GSList *declarations;
|
||||
GSList *functions;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_sl_node_program_free (GskSlNode *node)
|
||||
{
|
||||
GskSlNodeProgram *program = (GskSlNodeProgram *) node;
|
||||
|
||||
g_slist_free (program->declarations);
|
||||
g_slist_free (program->functions);
|
||||
|
||||
g_slice_free (GskSlNodeProgram, program);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_node_program_print (GskSlNode *node,
|
||||
GString *string)
|
||||
{
|
||||
GskSlNodeProgram *program = (GskSlNodeProgram *) node;
|
||||
GSList *l;
|
||||
|
||||
for (l = program->declarations; l; l = l->next)
|
||||
gsk_sl_node_print (l->data, string);
|
||||
|
||||
for (l = program->functions; l; l = l->next)
|
||||
gsk_sl_node_print (l->data, string);
|
||||
}
|
||||
|
||||
static const GskSlNodeClass GSK_SL_NODE_PROGRAM = {
|
||||
gsk_sl_node_program_free,
|
||||
gsk_sl_node_program_print
|
||||
};
|
||||
|
||||
/* FUNCTION */
|
||||
|
||||
typedef struct _GskSlNodeFunction GskSlNodeFunction;
|
||||
|
||||
struct _GskSlNodeFunction {
|
||||
GskSlNode parent;
|
||||
|
||||
GskSlType *return_type;
|
||||
char *name;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_sl_node_function_free (GskSlNode *node)
|
||||
{
|
||||
GskSlNodeFunction *function = (GskSlNodeFunction *) node;
|
||||
|
||||
if (function->return_type)
|
||||
gsk_sl_type_unref (function->return_type);
|
||||
g_free (function->name);
|
||||
|
||||
g_slice_free (GskSlNodeFunction, function);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_node_function_print (GskSlNode *node,
|
||||
GString *string)
|
||||
{
|
||||
GskSlNodeFunction *function = (GskSlNodeFunction *) node;
|
||||
|
||||
gsk_sl_type_print (function->return_type, string);
|
||||
g_string_append (string, "\n");
|
||||
|
||||
g_string_append (string, function->name);
|
||||
g_string_append (string, " (");
|
||||
g_string_append (string, ")\n");
|
||||
|
||||
g_string_append (string, "{\n");
|
||||
g_string_append (string, "}\n");
|
||||
}
|
||||
|
||||
static const GskSlNodeClass GSK_SL_NODE_FUNCTION = {
|
||||
gsk_sl_node_function_free,
|
||||
gsk_sl_node_function_print
|
||||
};
|
||||
|
||||
/* API */
|
||||
|
||||
static GskSlNodeFunction *
|
||||
gsk_sl_node_parse_function_prototype (GskSlNodeProgram *program,
|
||||
GskSlPreprocessor *stream)
|
||||
{
|
||||
GskSlType *type;
|
||||
GskSlNodeFunction *function;
|
||||
const GskSlToken *token;
|
||||
|
||||
type = gsk_sl_type_new_parse (stream);
|
||||
if (type == NULL)
|
||||
return NULL;
|
||||
|
||||
token = gsk_sl_preprocessor_get (stream);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
{
|
||||
gsk_sl_preprocessor_error (stream, "Expected a function name");
|
||||
gsk_sl_type_unref (type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
function = gsk_sl_node_new (GskSlNodeFunction, &GSK_SL_NODE_FUNCTION);
|
||||
function->return_type = type;
|
||||
function->name = g_strdup (token->str);
|
||||
gsk_sl_preprocessor_consume (stream, (GskSlNode *) function);
|
||||
|
||||
token = gsk_sl_preprocessor_get (stream);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_PAREN))
|
||||
{
|
||||
gsk_sl_preprocessor_error (stream, "Expected an openening \"(\"");
|
||||
gsk_sl_node_unref ((GskSlNode *) function);
|
||||
return NULL;
|
||||
}
|
||||
gsk_sl_preprocessor_consume (stream, (GskSlNode *) function);
|
||||
|
||||
token = gsk_sl_preprocessor_get (stream);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_PAREN))
|
||||
{
|
||||
gsk_sl_preprocessor_error (stream, "Expected a closing \")\"");
|
||||
gsk_sl_node_unref ((GskSlNode *) function);
|
||||
return NULL;
|
||||
}
|
||||
gsk_sl_preprocessor_consume (stream, (GskSlNode *) function);
|
||||
|
||||
return function;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_sl_node_parse_function_definition (GskSlNodeProgram *program,
|
||||
GskSlPreprocessor *stream)
|
||||
{
|
||||
GskSlNodeFunction *function;
|
||||
const GskSlToken *token;
|
||||
|
||||
function = gsk_sl_node_parse_function_prototype (program, stream);
|
||||
if (function == NULL)
|
||||
return FALSE;
|
||||
|
||||
token = gsk_sl_preprocessor_get (stream);
|
||||
if (gsk_sl_token_is (token, GSK_SL_TOKEN_SEMICOLON))
|
||||
{
|
||||
gsk_sl_preprocessor_consume (stream, (GskSlNode *) function);
|
||||
program->functions = g_slist_prepend (program->functions, function);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_BRACE))
|
||||
{
|
||||
gsk_sl_preprocessor_error (stream, "Expected an opening \"{\"");
|
||||
gsk_sl_node_unref ((GskSlNode *) function);
|
||||
return FALSE;
|
||||
}
|
||||
gsk_sl_preprocessor_consume (stream, (GskSlNode *) function);
|
||||
|
||||
token = gsk_sl_preprocessor_get (stream);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_BRACE))
|
||||
{
|
||||
gsk_sl_preprocessor_error (stream, "Expected a closing \"}\"");
|
||||
gsk_sl_node_unref ((GskSlNode *) function);
|
||||
return FALSE;
|
||||
}
|
||||
gsk_sl_preprocessor_consume (stream, (GskSlNode *) function);
|
||||
|
||||
program->functions = g_slist_prepend (program->functions, function);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_sl_node_parse_program (GskSlNodeProgram *program,
|
||||
GskSlPreprocessor *stream)
|
||||
{
|
||||
const GskSlToken *token;
|
||||
gboolean result = TRUE;
|
||||
|
||||
for (token = gsk_sl_preprocessor_get (stream);
|
||||
!gsk_sl_token_is (token, GSK_SL_TOKEN_EOF);
|
||||
token = gsk_sl_preprocessor_get (stream))
|
||||
{
|
||||
if (!gsk_sl_node_parse_function_definition (program, stream))
|
||||
{
|
||||
gsk_sl_preprocessor_consume (stream, (GskSlNode *) program);
|
||||
result = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
GskSlNode *
|
||||
gsk_sl_node_new_program (GBytes *source,
|
||||
GError **error)
|
||||
{
|
||||
GskSlPreprocessor *stream;
|
||||
GskSlNodeProgram *program;
|
||||
|
||||
program = gsk_sl_node_new (GskSlNodeProgram, &GSK_SL_NODE_PROGRAM);
|
||||
stream = gsk_sl_preprocessor_new (source);
|
||||
|
||||
gsk_sl_node_parse_program (program, stream);
|
||||
|
||||
gsk_sl_preprocessor_unref (stream);
|
||||
|
||||
return (GskSlNode *) program;
|
||||
}
|
||||
|
||||
GskSlNode *
|
||||
gsk_sl_node_ref (GskSlNode *node)
|
||||
{
|
||||
g_return_val_if_fail (node != NULL, NULL);
|
||||
|
||||
node->ref_count += 1;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_node_unref (GskSlNode *node)
|
||||
{
|
||||
if (node == NULL)
|
||||
return;
|
||||
|
||||
node->ref_count -= 1;
|
||||
if (node->ref_count > 0)
|
||||
return;
|
||||
|
||||
node->class->free (node);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_node_print (GskSlNode *node,
|
||||
GString *string)
|
||||
{
|
||||
node->class->print (node, string);
|
||||
}
|
||||
52
gsk/gskslnodeprivate.h
Normal file
52
gsk/gskslnodeprivate.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* 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_SL_NODE_PRIVATE_H__
|
||||
#define __GSK_SL_NODE_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GskSlNode GskSlNode;
|
||||
typedef struct _GskSlNodeClass GskSlNodeClass;
|
||||
|
||||
struct _GskSlNode {
|
||||
const GskSlNodeClass *class;
|
||||
guint ref_count;
|
||||
};
|
||||
|
||||
struct _GskSlNodeClass {
|
||||
void (* free) (GskSlNode *node);
|
||||
|
||||
void (* print) (GskSlNode *node,
|
||||
GString *string);
|
||||
};
|
||||
|
||||
GskSlNode * gsk_sl_node_new_program (GBytes *source,
|
||||
GError **error);
|
||||
|
||||
GskSlNode * gsk_sl_node_ref (GskSlNode *node);
|
||||
void gsk_sl_node_unref (GskSlNode *node);
|
||||
|
||||
void gsk_sl_node_print (GskSlNode *node,
|
||||
GString *string);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_NODE_PRIVATE_H__ */
|
||||
162
gsk/gskslpreprocessor.c
Normal file
162
gsk/gskslpreprocessor.c
Normal file
@@ -0,0 +1,162 @@
|
||||
/* 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 "gskslpreprocessorprivate.h"
|
||||
|
||||
struct _GskSlPreprocessor
|
||||
{
|
||||
int ref_count;
|
||||
|
||||
GskSlTokenizer *tokenizer;
|
||||
GskCodeLocation location;
|
||||
GskSlToken token;
|
||||
};
|
||||
|
||||
/* API */
|
||||
|
||||
static void
|
||||
gsk_sl_preprocessor_error_func (GskSlTokenizer *parser,
|
||||
gboolean fatal,
|
||||
const GskCodeLocation *location,
|
||||
const GskSlToken *token,
|
||||
const GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_printerr ("%3zu:%2zu: error: %3u: %s: %s\n",
|
||||
location->lines + 1, location->line_bytes,
|
||||
token->type, gsk_sl_token_to_string (token),
|
||||
error->message);
|
||||
}
|
||||
|
||||
GskSlPreprocessor *
|
||||
gsk_sl_preprocessor_new (GBytes *source)
|
||||
{
|
||||
GskSlPreprocessor *preproc;
|
||||
|
||||
preproc = g_slice_new0 (GskSlPreprocessor);
|
||||
|
||||
preproc->ref_count = 1;
|
||||
preproc->tokenizer = gsk_sl_tokenizer_new (source,
|
||||
gsk_sl_preprocessor_error_func,
|
||||
preproc,
|
||||
NULL);
|
||||
|
||||
return preproc;
|
||||
}
|
||||
|
||||
GskSlPreprocessor *
|
||||
gsk_sl_preprocessor_ref (GskSlPreprocessor *preproc)
|
||||
{
|
||||
g_return_val_if_fail (preproc != NULL, NULL);
|
||||
|
||||
preproc->ref_count += 1;
|
||||
|
||||
return preproc;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_preprocessor_unref (GskSlPreprocessor *preproc)
|
||||
{
|
||||
if (preproc == NULL)
|
||||
return;
|
||||
|
||||
preproc->ref_count -= 1;
|
||||
if (preproc->ref_count > 0)
|
||||
return;
|
||||
|
||||
gsk_sl_tokenizer_unref (preproc->tokenizer);
|
||||
gsk_sl_token_clear (&preproc->token);
|
||||
|
||||
g_slice_free (GskSlPreprocessor, preproc);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_sl_token_is_skipped (const GskSlToken *token)
|
||||
{
|
||||
return gsk_sl_token_is (token, GSK_SL_TOKEN_ERROR)
|
||||
|| gsk_sl_token_is (token, GSK_SL_TOKEN_WHITESPACE)
|
||||
|| gsk_sl_token_is (token, GSK_SL_TOKEN_COMMENT)
|
||||
|| gsk_sl_token_is (token, GSK_SL_TOKEN_SINGLE_LINE_COMMENT);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_token_ensure (GskSlPreprocessor *preproc)
|
||||
{
|
||||
if (!gsk_sl_token_is (&preproc->token, GSK_SL_TOKEN_EOF))
|
||||
return;
|
||||
|
||||
do
|
||||
{
|
||||
preproc->location = *gsk_sl_tokenizer_get_location (preproc->tokenizer);
|
||||
gsk_sl_tokenizer_read_token (preproc->tokenizer, &preproc->token);
|
||||
}
|
||||
while (gsk_sl_token_is_skipped (&preproc->token));
|
||||
}
|
||||
|
||||
const GskSlToken *
|
||||
gsk_sl_preprocessor_get (GskSlPreprocessor *preproc)
|
||||
{
|
||||
gsk_sl_token_ensure (preproc);
|
||||
|
||||
return &preproc->token;
|
||||
}
|
||||
|
||||
const GskCodeLocation *
|
||||
gsk_sl_preprocessor_get_location (GskSlPreprocessor *preproc)
|
||||
{
|
||||
gsk_sl_token_ensure (preproc);
|
||||
|
||||
return &preproc->location;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_preprocessor_consume (GskSlPreprocessor *preproc,
|
||||
GskSlNode *consumer)
|
||||
{
|
||||
gsk_sl_token_ensure (preproc);
|
||||
|
||||
gsk_sl_token_clear (&preproc->token);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_preprocessor_error (GskSlPreprocessor *preproc,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
GError *error;
|
||||
va_list args;
|
||||
|
||||
va_start (args, format);
|
||||
error = g_error_new_valist (G_FILE_ERROR,
|
||||
G_FILE_ERROR_FAILED,
|
||||
format,
|
||||
args);
|
||||
va_end (args);
|
||||
|
||||
gsk_sl_token_ensure (preproc);
|
||||
gsk_sl_preprocessor_error_func (preproc->tokenizer,
|
||||
TRUE,
|
||||
&preproc->location,
|
||||
&preproc->token,
|
||||
error,
|
||||
NULL);
|
||||
|
||||
g_error_free (error);
|
||||
}
|
||||
47
gsk/gskslpreprocessorprivate.h
Normal file
47
gsk/gskslpreprocessorprivate.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* 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_SL_PREPROCESSOR_PRIVATE_H__
|
||||
#define __GSK_SL_PREPROCESSOR_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "gskslnodeprivate.h"
|
||||
#include "gsksltokenizerprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GskSlPreprocessor GskSlPreprocessor;
|
||||
|
||||
GskSlPreprocessor * gsk_sl_preprocessor_new (GBytes *source);
|
||||
|
||||
GskSlPreprocessor * gsk_sl_preprocessor_ref (GskSlPreprocessor *preproc);
|
||||
void gsk_sl_preprocessor_unref (GskSlPreprocessor *preproc);
|
||||
|
||||
const GskSlToken * gsk_sl_preprocessor_get (GskSlPreprocessor *preproc);
|
||||
const GskCodeLocation * gsk_sl_preprocessor_get_location (GskSlPreprocessor *preproc);
|
||||
void gsk_sl_preprocessor_consume (GskSlPreprocessor *preproc,
|
||||
GskSlNode *consumer);
|
||||
|
||||
void gsk_sl_preprocessor_error (GskSlPreprocessor *preproc,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF(2, 3);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_PREPROCESSOR_PRIVATE_H__ */
|
||||
1838
gsk/gsksltokenizer.c
Normal file
1838
gsk/gsksltokenizer.c
Normal file
File diff suppressed because it is too large
Load Diff
293
gsk/gsksltokenizerprivate.h
Normal file
293
gsk/gsksltokenizerprivate.h
Normal file
@@ -0,0 +1,293 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2011 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_SL_TOKENIZER_PRIVATE_H__
|
||||
#define __GSK_SL_TOKENIZER_PRIVATE_H__
|
||||
|
||||
#include <gsktypes.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum {
|
||||
GSK_SL_TOKEN_EOF = 0,
|
||||
GSK_SL_TOKEN_ERROR,
|
||||
GSK_SL_TOKEN_WHITESPACE,
|
||||
GSK_SL_TOKEN_COMMENT,
|
||||
GSK_SL_TOKEN_SINGLE_LINE_COMMENT,
|
||||
/* real tokens */
|
||||
GSK_SL_TOKEN_CONST,
|
||||
GSK_SL_TOKEN_BOOL,
|
||||
GSK_SL_TOKEN_FLOAT,
|
||||
GSK_SL_TOKEN_DOUBLE,
|
||||
GSK_SL_TOKEN_INT,
|
||||
GSK_SL_TOKEN_UINT,
|
||||
GSK_SL_TOKEN_BREAK,
|
||||
GSK_SL_TOKEN_CONTINUE,
|
||||
GSK_SL_TOKEN_DO,
|
||||
GSK_SL_TOKEN_ELSE,
|
||||
GSK_SL_TOKEN_FOR,
|
||||
GSK_SL_TOKEN_IF,
|
||||
GSK_SL_TOKEN_DISCARD,
|
||||
GSK_SL_TOKEN_RETURN,
|
||||
GSK_SL_TOKEN_SWITCH,
|
||||
GSK_SL_TOKEN_CASE,
|
||||
GSK_SL_TOKEN_DEFAULT,
|
||||
GSK_SL_TOKEN_SUBROUTINE,
|
||||
GSK_SL_TOKEN_BVEC2,
|
||||
GSK_SL_TOKEN_BVEC3,
|
||||
GSK_SL_TOKEN_BVEC4,
|
||||
GSK_SL_TOKEN_IVEC2,
|
||||
GSK_SL_TOKEN_IVEC3,
|
||||
GSK_SL_TOKEN_IVEC4,
|
||||
GSK_SL_TOKEN_UVEC2,
|
||||
GSK_SL_TOKEN_UVEC3,
|
||||
GSK_SL_TOKEN_UVEC4,
|
||||
GSK_SL_TOKEN_VEC2,
|
||||
GSK_SL_TOKEN_VEC3,
|
||||
GSK_SL_TOKEN_VEC4,
|
||||
GSK_SL_TOKEN_MAT2,
|
||||
GSK_SL_TOKEN_MAT3,
|
||||
GSK_SL_TOKEN_MAT4,
|
||||
GSK_SL_TOKEN_CENTROID,
|
||||
GSK_SL_TOKEN_IN,
|
||||
GSK_SL_TOKEN_OUT,
|
||||
GSK_SL_TOKEN_INOUT,
|
||||
GSK_SL_TOKEN_UNIFORM,
|
||||
GSK_SL_TOKEN_PATCH,
|
||||
GSK_SL_TOKEN_SAMPLE,
|
||||
GSK_SL_TOKEN_BUFFER,
|
||||
GSK_SL_TOKEN_SHARED,
|
||||
GSK_SL_TOKEN_COHERENT,
|
||||
GSK_SL_TOKEN_VOLATILE,
|
||||
GSK_SL_TOKEN_RESTRICT,
|
||||
GSK_SL_TOKEN_READONLY,
|
||||
GSK_SL_TOKEN_WRITEONLY,
|
||||
GSK_SL_TOKEN_DVEC2,
|
||||
GSK_SL_TOKEN_DVEC3,
|
||||
GSK_SL_TOKEN_DVEC4,
|
||||
GSK_SL_TOKEN_DMAT2,
|
||||
GSK_SL_TOKEN_DMAT3,
|
||||
GSK_SL_TOKEN_DMAT4,
|
||||
GSK_SL_TOKEN_NOPERSPECTIVE,
|
||||
GSK_SL_TOKEN_FLAT,
|
||||
GSK_SL_TOKEN_SMOOTH,
|
||||
GSK_SL_TOKEN_LAYOUT,
|
||||
GSK_SL_TOKEN_MAT2X2,
|
||||
GSK_SL_TOKEN_MAT2X3,
|
||||
GSK_SL_TOKEN_MAT2X4,
|
||||
GSK_SL_TOKEN_MAT3X2,
|
||||
GSK_SL_TOKEN_MAT3X3,
|
||||
GSK_SL_TOKEN_MAT3X4,
|
||||
GSK_SL_TOKEN_MAT4X2,
|
||||
GSK_SL_TOKEN_MAT4X3,
|
||||
GSK_SL_TOKEN_MAT4X4,
|
||||
GSK_SL_TOKEN_DMAT2X2,
|
||||
GSK_SL_TOKEN_DMAT2X3,
|
||||
GSK_SL_TOKEN_DMAT2X4,
|
||||
GSK_SL_TOKEN_DMAT3X2,
|
||||
GSK_SL_TOKEN_DMAT3X3,
|
||||
GSK_SL_TOKEN_DMAT3X4,
|
||||
GSK_SL_TOKEN_DMAT4X2,
|
||||
GSK_SL_TOKEN_DMAT4X3,
|
||||
GSK_SL_TOKEN_DMAT4X4,
|
||||
GSK_SL_TOKEN_ATOMIC_UINT,
|
||||
GSK_SL_TOKEN_SAMPLER1D,
|
||||
GSK_SL_TOKEN_SAMPLER2D,
|
||||
GSK_SL_TOKEN_SAMPLER3D,
|
||||
GSK_SL_TOKEN_SAMPLERCUBE,
|
||||
GSK_SL_TOKEN_SAMPLER1DSHADOW,
|
||||
GSK_SL_TOKEN_SAMPLER2DSHADOW,
|
||||
GSK_SL_TOKEN_SAMPLERCUBESHADOW,
|
||||
GSK_SL_TOKEN_SAMPLER1DARRAY,
|
||||
GSK_SL_TOKEN_SAMPLER2DARRAY,
|
||||
GSK_SL_TOKEN_SAMPLER1DARRAYSHADOW,
|
||||
GSK_SL_TOKEN_SAMPLER2DARRAYSHADOW,
|
||||
GSK_SL_TOKEN_ISAMPLER1D,
|
||||
GSK_SL_TOKEN_ISAMPLER2D,
|
||||
GSK_SL_TOKEN_ISAMPLER3D,
|
||||
GSK_SL_TOKEN_ISAMPLERCUBE,
|
||||
GSK_SL_TOKEN_ISAMPLER1DARRAY,
|
||||
GSK_SL_TOKEN_ISAMPLER2DARRAY,
|
||||
GSK_SL_TOKEN_USAMPLER1D,
|
||||
GSK_SL_TOKEN_USAMPLER2D,
|
||||
GSK_SL_TOKEN_USAMPLER3D,
|
||||
GSK_SL_TOKEN_USAMPLERCUBE,
|
||||
GSK_SL_TOKEN_USAMPLER1DARRAY,
|
||||
GSK_SL_TOKEN_USAMPLER2DARRAY,
|
||||
GSK_SL_TOKEN_SAMPLER2DRECT,
|
||||
GSK_SL_TOKEN_SAMPLER2DRECTSHADOW,
|
||||
GSK_SL_TOKEN_ISAMPLER2DRECT,
|
||||
GSK_SL_TOKEN_USAMPLER2DRECT,
|
||||
GSK_SL_TOKEN_SAMPLERBUFFER,
|
||||
GSK_SL_TOKEN_ISAMPLERBUFFER,
|
||||
GSK_SL_TOKEN_USAMPLERBUFFER,
|
||||
GSK_SL_TOKEN_SAMPLERCUBEARRAY,
|
||||
GSK_SL_TOKEN_SAMPLERCUBEARRAYSHADOW,
|
||||
GSK_SL_TOKEN_ISAMPLERCUBEARRAY,
|
||||
GSK_SL_TOKEN_USAMPLERCUBEARRAY,
|
||||
GSK_SL_TOKEN_SAMPLER2DMS,
|
||||
GSK_SL_TOKEN_ISAMPLER2DMS,
|
||||
GSK_SL_TOKEN_USAMPLER2DMS,
|
||||
GSK_SL_TOKEN_SAMPLER2DMSARRAY,
|
||||
GSK_SL_TOKEN_ISAMPLER2DMSARRAY,
|
||||
GSK_SL_TOKEN_USAMPLER2DMSARRAY,
|
||||
GSK_SL_TOKEN_IMAGE1D,
|
||||
GSK_SL_TOKEN_IIMAGE1D,
|
||||
GSK_SL_TOKEN_UIMAGE1D,
|
||||
GSK_SL_TOKEN_IMAGE2D,
|
||||
GSK_SL_TOKEN_IIMAGE2D,
|
||||
GSK_SL_TOKEN_UIMAGE2D,
|
||||
GSK_SL_TOKEN_IMAGE3D,
|
||||
GSK_SL_TOKEN_IIMAGE3D,
|
||||
GSK_SL_TOKEN_UIMAGE3D,
|
||||
GSK_SL_TOKEN_IMAGE2DRECT,
|
||||
GSK_SL_TOKEN_IIMAGE2DRECT,
|
||||
GSK_SL_TOKEN_UIMAGE2DRECT,
|
||||
GSK_SL_TOKEN_IMAGECUBE,
|
||||
GSK_SL_TOKEN_IIMAGECUBE,
|
||||
GSK_SL_TOKEN_UIMAGECUBE,
|
||||
GSK_SL_TOKEN_IMAGEBUFFER,
|
||||
GSK_SL_TOKEN_IIMAGEBUFFER,
|
||||
GSK_SL_TOKEN_UIMAGEBUFFER,
|
||||
GSK_SL_TOKEN_IMAGE1DARRAY,
|
||||
GSK_SL_TOKEN_IIMAGE1DARRAY,
|
||||
GSK_SL_TOKEN_UIMAGE1DARRAY,
|
||||
GSK_SL_TOKEN_IMAGE2DARRAY,
|
||||
GSK_SL_TOKEN_IIMAGE2DARRAY,
|
||||
GSK_SL_TOKEN_UIMAGE2DARRAY,
|
||||
GSK_SL_TOKEN_IMAGECUBEARRAY,
|
||||
GSK_SL_TOKEN_IIMAGECUBEARRAY,
|
||||
GSK_SL_TOKEN_UIMAGECUBEARRAY,
|
||||
GSK_SL_TOKEN_IMAGE2DMS,
|
||||
GSK_SL_TOKEN_IIMAGE2DMS,
|
||||
GSK_SL_TOKEN_UIMAGE2DMS,
|
||||
GSK_SL_TOKEN_IMAGE2DMSARRAY,
|
||||
GSK_SL_TOKEN_IIMAGE2DMSARRAY,
|
||||
GSK_SL_TOKEN_UIMAGE2DMSARRAY,
|
||||
GSK_SL_TOKEN_STRUCT,
|
||||
GSK_SL_TOKEN_VOID,
|
||||
GSK_SL_TOKEN_WHILE,
|
||||
GSK_SL_TOKEN_IDENTIFIER,
|
||||
GSK_SL_TOKEN_FLOATCONSTANT,
|
||||
GSK_SL_TOKEN_DOUBLECONSTANT,
|
||||
GSK_SL_TOKEN_INTCONSTANT,
|
||||
GSK_SL_TOKEN_UINTCONSTANT,
|
||||
GSK_SL_TOKEN_BOOLCONSTANT,
|
||||
GSK_SL_TOKEN_LEFT_OP,
|
||||
GSK_SL_TOKEN_RIGHT_OP,
|
||||
GSK_SL_TOKEN_INC_OP,
|
||||
GSK_SL_TOKEN_DEC_OP,
|
||||
GSK_SL_TOKEN_LE_OP,
|
||||
GSK_SL_TOKEN_GE_OP,
|
||||
GSK_SL_TOKEN_EQ_OP,
|
||||
GSK_SL_TOKEN_NE_OP,
|
||||
GSK_SL_TOKEN_AND_OP,
|
||||
GSK_SL_TOKEN_OR_OP,
|
||||
GSK_SL_TOKEN_XOR_OP,
|
||||
GSK_SL_TOKEN_MUL_ASSIGN,
|
||||
GSK_SL_TOKEN_DIV_ASSIGN,
|
||||
GSK_SL_TOKEN_ADD_ASSIGN,
|
||||
GSK_SL_TOKEN_MOD_ASSIGN,
|
||||
GSK_SL_TOKEN_LEFT_ASSIGN,
|
||||
GSK_SL_TOKEN_RIGHT_ASSIGN,
|
||||
GSK_SL_TOKEN_AND_ASSIGN,
|
||||
GSK_SL_TOKEN_XOR_ASSIGN,
|
||||
GSK_SL_TOKEN_OR_ASSIGN,
|
||||
GSK_SL_TOKEN_SUB_ASSIGN,
|
||||
GSK_SL_TOKEN_LEFT_PAREN,
|
||||
GSK_SL_TOKEN_RIGHT_PAREN,
|
||||
GSK_SL_TOKEN_LEFT_BRACKET,
|
||||
GSK_SL_TOKEN_RIGHT_BRACKET,
|
||||
GSK_SL_TOKEN_LEFT_BRACE,
|
||||
GSK_SL_TOKEN_RIGHT_BRACE,
|
||||
GSK_SL_TOKEN_DOT,
|
||||
GSK_SL_TOKEN_COMMA,
|
||||
GSK_SL_TOKEN_COLON,
|
||||
GSK_SL_TOKEN_EQUAL,
|
||||
GSK_SL_TOKEN_SEMICOLON,
|
||||
GSK_SL_TOKEN_BANG,
|
||||
GSK_SL_TOKEN_DASH,
|
||||
GSK_SL_TOKEN_TILDE,
|
||||
GSK_SL_TOKEN_PLUS,
|
||||
GSK_SL_TOKEN_STAR,
|
||||
GSK_SL_TOKEN_SLASH,
|
||||
GSK_SL_TOKEN_PERCENT,
|
||||
GSK_SL_TOKEN_LEFT_ANGLE,
|
||||
GSK_SL_TOKEN_RIGHT_ANGLE,
|
||||
GSK_SL_TOKEN_VERTICAL_BAR,
|
||||
GSK_SL_TOKEN_CARET,
|
||||
GSK_SL_TOKEN_AMPERSAND,
|
||||
GSK_SL_TOKEN_QUESTION,
|
||||
GSK_SL_TOKEN_INVARIANT,
|
||||
GSK_SL_TOKEN_PRECISE,
|
||||
GSK_SL_TOKEN_HIGH_PRECISION,
|
||||
GSK_SL_TOKEN_MEDIUM_PRECISION,
|
||||
GSK_SL_TOKEN_LOW_PRECISION,
|
||||
GSK_SL_TOKEN_PRECISION
|
||||
} GskSlTokenType;
|
||||
|
||||
typedef struct _GskSlToken GskSlToken;
|
||||
typedef struct _GskSlTokenizer GskSlTokenizer;
|
||||
|
||||
typedef void (* GskSlTokenizerErrorFunc) (GskSlTokenizer *parser,
|
||||
gboolean fatal,
|
||||
const GskCodeLocation *location,
|
||||
const GskSlToken *token,
|
||||
const GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
struct _GskSlToken {
|
||||
GskSlTokenType type;
|
||||
union {
|
||||
gint32 i32;
|
||||
guint32 u32;
|
||||
float f;
|
||||
double d;
|
||||
gboolean b;
|
||||
char *str;
|
||||
};
|
||||
};
|
||||
|
||||
void gsk_sl_token_clear (GskSlToken *token);
|
||||
|
||||
gboolean gsk_sl_token_is_finite (const GskSlToken *token);
|
||||
#define gsk_sl_token_is(token, _type) ((token)->type == (_type))
|
||||
gboolean gsk_sl_token_is_ident (const GskSlToken *token,
|
||||
const char *ident);
|
||||
gboolean gsk_sl_token_is_function (const GskSlToken *token,
|
||||
const char *ident);
|
||||
|
||||
void gsk_sl_token_print (const GskSlToken *token,
|
||||
GString *string);
|
||||
char * gsk_sl_token_to_string (const GskSlToken *token);
|
||||
|
||||
GskSlTokenizer * gsk_sl_tokenizer_new (GBytes *bytes,
|
||||
GskSlTokenizerErrorFunc func,
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_destroy);
|
||||
|
||||
GskSlTokenizer * gsk_sl_tokenizer_ref (GskSlTokenizer *tokenizer);
|
||||
void gsk_sl_tokenizer_unref (GskSlTokenizer *tokenizer);
|
||||
|
||||
const GskCodeLocation * gsk_sl_tokenizer_get_location (GskSlTokenizer *tokenizer);
|
||||
|
||||
void gsk_sl_tokenizer_read_token (GskSlTokenizer *tokenizer,
|
||||
GskSlToken *token);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_TOKENIZER_PRIVATE_H__ */
|
||||
161
gsk/gsksltype.c
Normal file
161
gsk/gsksltype.c
Normal file
@@ -0,0 +1,161 @@
|
||||
/* 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 "gsksltypeprivate.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
struct _GskSlType
|
||||
{
|
||||
int ref_count;
|
||||
|
||||
GskSlBuiltinType builtin;
|
||||
};
|
||||
|
||||
static GskSlType
|
||||
builtin_types[GSK_SL_N_BUILTIN_TYPES] = {
|
||||
[GSK_SL_VOID] = { 1, GSK_SL_VOID },
|
||||
[GSK_SL_FLOAT] = { 1, GSK_SL_FLOAT },
|
||||
[GSK_SL_DOUBLE] = { 1, GSK_SL_DOUBLE },
|
||||
[GSK_SL_INT] = { 1, GSK_SL_INT },
|
||||
[GSK_SL_UINT] = { 1, GSK_SL_UINT },
|
||||
[GSK_SL_BOOL] = { 1, GSK_SL_BOOL },
|
||||
[GSK_SL_VEC2] = { 1, GSK_SL_VEC2 },
|
||||
[GSK_SL_VEC3] = { 1, GSK_SL_VEC3 },
|
||||
[GSK_SL_VEC4] = { 1, GSK_SL_VEC4 }
|
||||
};
|
||||
|
||||
GskSlType *
|
||||
gsk_sl_type_new_parse (GskSlPreprocessor *stream)
|
||||
{
|
||||
GskSlBuiltinType builtin;
|
||||
const GskSlToken *token;
|
||||
|
||||
token = gsk_sl_preprocessor_get (stream);
|
||||
|
||||
switch ((guint) token->type)
|
||||
{
|
||||
case GSK_SL_TOKEN_VOID:
|
||||
builtin = GSK_SL_VOID;
|
||||
break;
|
||||
case GSK_SL_TOKEN_FLOAT:
|
||||
builtin = GSK_SL_FLOAT;
|
||||
break;
|
||||
case GSK_SL_TOKEN_DOUBLE:
|
||||
builtin = GSK_SL_DOUBLE;
|
||||
break;
|
||||
case GSK_SL_TOKEN_INT:
|
||||
builtin = GSK_SL_INT;
|
||||
break;
|
||||
case GSK_SL_TOKEN_UINT:
|
||||
builtin = GSK_SL_UINT;
|
||||
break;
|
||||
case GSK_SL_TOKEN_BOOL:
|
||||
builtin = GSK_SL_BOOL;
|
||||
break;
|
||||
case GSK_SL_TOKEN_VEC2:
|
||||
builtin = GSK_SL_VEC2;
|
||||
break;
|
||||
case GSK_SL_TOKEN_VEC3:
|
||||
builtin = GSK_SL_VEC3;
|
||||
break;
|
||||
case GSK_SL_TOKEN_VEC4:
|
||||
builtin = GSK_SL_VEC4;
|
||||
break;
|
||||
default:
|
||||
gsk_sl_preprocessor_error (stream, "Expected type specifier");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gsk_sl_preprocessor_consume (stream, NULL);
|
||||
return gsk_sl_type_ref (gsk_sl_type_get_builtin (builtin));
|
||||
}
|
||||
|
||||
GskSlType *
|
||||
gsk_sl_type_get_builtin (GskSlBuiltinType builtin)
|
||||
{
|
||||
g_assert (builtin < GSK_SL_N_BUILTIN_TYPES);
|
||||
|
||||
return &builtin_types[builtin];
|
||||
}
|
||||
|
||||
GskSlType *
|
||||
gsk_sl_type_ref (GskSlType *type)
|
||||
{
|
||||
g_return_val_if_fail (type != NULL, NULL);
|
||||
|
||||
type->ref_count += 1;
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_type_unref (GskSlType *type)
|
||||
{
|
||||
if (type == NULL)
|
||||
return;
|
||||
|
||||
type->ref_count -= 1;
|
||||
if (type->ref_count > 0)
|
||||
return;
|
||||
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_type_print (const GskSlType *type,
|
||||
GString *string)
|
||||
{
|
||||
switch (type->builtin)
|
||||
{
|
||||
case GSK_SL_VOID:
|
||||
g_string_append (string, "void");
|
||||
break;
|
||||
case GSK_SL_FLOAT:
|
||||
g_string_append (string, "float");
|
||||
break;
|
||||
case GSK_SL_DOUBLE:
|
||||
g_string_append (string, "double");
|
||||
break;
|
||||
case GSK_SL_INT:
|
||||
g_string_append (string, "int");
|
||||
break;
|
||||
case GSK_SL_UINT:
|
||||
g_string_append (string, "uint");
|
||||
break;
|
||||
case GSK_SL_BOOL:
|
||||
g_string_append (string, "bool");
|
||||
break;
|
||||
case GSK_SL_VEC2:
|
||||
g_string_append (string, "vec2");
|
||||
break;
|
||||
case GSK_SL_VEC3:
|
||||
g_string_append (string, "vec3");
|
||||
break;
|
||||
case GSK_SL_VEC4:
|
||||
g_string_append (string, "vec4");
|
||||
break;
|
||||
/* add more above */
|
||||
case GSK_SL_N_BUILTIN_TYPES:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
55
gsk/gsksltypeprivate.h
Normal file
55
gsk/gsksltypeprivate.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/* 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_SL_TYPE_PRIVATE_H__
|
||||
#define __GSK_SL_TYPE_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "gskslpreprocessorprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum {
|
||||
GSK_SL_VOID,
|
||||
GSK_SL_FLOAT,
|
||||
GSK_SL_DOUBLE,
|
||||
GSK_SL_INT,
|
||||
GSK_SL_UINT,
|
||||
GSK_SL_BOOL,
|
||||
GSK_SL_VEC2,
|
||||
GSK_SL_VEC3,
|
||||
GSK_SL_VEC4,
|
||||
/* add more above */
|
||||
GSK_SL_N_BUILTIN_TYPES
|
||||
} GskSlBuiltinType;
|
||||
|
||||
typedef struct _GskSlType GskSlType;
|
||||
|
||||
GskSlType * gsk_sl_type_new_parse (GskSlPreprocessor *stream);
|
||||
GskSlType * gsk_sl_type_get_builtin (GskSlBuiltinType builtin);
|
||||
|
||||
GskSlType * gsk_sl_type_ref (GskSlType *type);
|
||||
void gsk_sl_type_unref (GskSlType *type);
|
||||
|
||||
void gsk_sl_type_print (const GskSlType *type,
|
||||
GString *string);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_TYPE_PRIVATE_H__ */
|
||||
@@ -26,7 +26,18 @@
|
||||
#include <gdk/gdk.h>
|
||||
#include <gsk/gskenums.h>
|
||||
|
||||
typedef struct _GskCodeLocation GskCodeLocation;
|
||||
typedef struct _GskPixelShader GskPixelShader;
|
||||
typedef struct _GskRenderer GskRenderer;
|
||||
typedef struct _GskTexture GskTexture;
|
||||
|
||||
struct _GskCodeLocation
|
||||
{
|
||||
gsize bytes;
|
||||
gsize chars;
|
||||
gsize lines;
|
||||
gsize line_bytes;
|
||||
gsize line_chars;
|
||||
};
|
||||
|
||||
#endif /* __GSK_TYPES_H__ */
|
||||
|
||||
@@ -14,6 +14,7 @@ gsk_private_source_shaders = [
|
||||
]
|
||||
|
||||
gsk_public_sources = files([
|
||||
'gskpixelshader.c',
|
||||
'gskrenderer.c',
|
||||
'gskrendernode.c',
|
||||
'gskrendernodeimpl.c',
|
||||
@@ -31,10 +32,15 @@ gsk_private_sources = files([
|
||||
'gskprivate.c',
|
||||
'gskprofiler.c',
|
||||
'gskshaderbuilder.c',
|
||||
'gskslnode.c',
|
||||
'gskslpreprocessor.c',
|
||||
'gsksltokenizer.c',
|
||||
'gsksltype.c'
|
||||
])
|
||||
|
||||
gsk_public_headers = files([
|
||||
'gskenums.h',
|
||||
'gskpixelshader.h',
|
||||
'gskrenderer.h',
|
||||
'gskrendernode.h',
|
||||
'gskroundedrect.h',
|
||||
|
||||
@@ -60,6 +60,8 @@ gtk_inspector_init (void)
|
||||
|
||||
g_type_ensure (G_TYPE_LIST_STORE);
|
||||
|
||||
g_type_ensure (GSK_TYPE_PIXEL_SHADER);
|
||||
|
||||
g_type_ensure (GTK_TYPE_CELL_RENDERER_GRAPH);
|
||||
g_type_ensure (GTK_TYPE_GRAPH_DATA);
|
||||
g_type_ensure (GTK_TYPE_INSPECTOR_ACTIONS);
|
||||
|
||||
3
testsuite/gsksl/meson.build
Normal file
3
testsuite/gsksl/meson.build
Normal file
@@ -0,0 +1,3 @@
|
||||
|
||||
test_parser = executable('test-parser', 'test-parser.c', dependencies: libgtk_dep)
|
||||
test('gsksl/parser', test_parser)
|
||||
360
testsuite/gsksl/test-parser.c
Normal file
360
testsuite/gsksl/test-parser.c
Normal file
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat Inc.
|
||||
*
|
||||
* Author:
|
||||
* Benjamin Otte <otte@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <gsk/gsk.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
# include <io.h>
|
||||
#endif
|
||||
|
||||
static char *
|
||||
test_get_reference_file (const char *glsl_file)
|
||||
{
|
||||
GString *file = g_string_new (NULL);
|
||||
|
||||
if (g_str_has_suffix (glsl_file, ".glsl"))
|
||||
g_string_append_len (file, glsl_file, strlen (glsl_file) - 4);
|
||||
else
|
||||
g_string_append (file, glsl_file);
|
||||
|
||||
g_string_append (file, ".ref.glsl");
|
||||
|
||||
if (!g_file_test (file->str, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
g_string_free (file, TRUE);
|
||||
return g_strdup (glsl_file);
|
||||
}
|
||||
|
||||
return g_string_free (file, FALSE);
|
||||
}
|
||||
|
||||
static char *
|
||||
test_get_errors_file (const char *glsl_file)
|
||||
{
|
||||
GString *file = g_string_new (NULL);
|
||||
|
||||
if (g_str_has_suffix (glsl_file, ".glsl"))
|
||||
g_string_append_len (file, glsl_file, strlen (glsl_file) - 4);
|
||||
else
|
||||
g_string_append (file, glsl_file);
|
||||
|
||||
g_string_append (file, ".errors");
|
||||
|
||||
if (!g_file_test (file->str, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
g_string_free (file, TRUE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return g_string_free (file, FALSE);
|
||||
}
|
||||
|
||||
static char *
|
||||
diff_with_file (const char *file1,
|
||||
char *text,
|
||||
gssize len,
|
||||
GError **error)
|
||||
{
|
||||
const char *command[] = { "diff", "-u", file1, NULL, NULL };
|
||||
char *diff, *tmpfile;
|
||||
int fd;
|
||||
|
||||
diff = NULL;
|
||||
|
||||
if (len < 0)
|
||||
len = strlen (text);
|
||||
|
||||
/* write the text buffer to a temporary file */
|
||||
fd = g_file_open_tmp (NULL, &tmpfile, error);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
if (write (fd, text, len) != (int) len)
|
||||
{
|
||||
close (fd);
|
||||
g_set_error (error,
|
||||
G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
||||
"Could not write data to temporary file '%s'", tmpfile);
|
||||
goto done;
|
||||
}
|
||||
close (fd);
|
||||
command[3] = tmpfile;
|
||||
|
||||
/* run diff command */
|
||||
g_spawn_sync (NULL,
|
||||
(char **) command,
|
||||
NULL,
|
||||
G_SPAWN_SEARCH_PATH,
|
||||
NULL, NULL,
|
||||
&diff,
|
||||
NULL, NULL,
|
||||
error);
|
||||
|
||||
done:
|
||||
g_unlink (tmpfile);
|
||||
g_free (tmpfile);
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
append_error_value (GString *string,
|
||||
GType enum_type,
|
||||
guint value)
|
||||
{
|
||||
GEnumClass *enum_class;
|
||||
GEnumValue *enum_value;
|
||||
|
||||
enum_class = g_type_class_ref (enum_type);
|
||||
enum_value = g_enum_get_value (enum_class, value);
|
||||
|
||||
g_string_append (string, enum_value->value_name);
|
||||
|
||||
g_type_class_unref (enum_class);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
parsing_error_cb (GskPixelShader *shader,
|
||||
gboolean fatal,
|
||||
const GskCodeLocation *location,
|
||||
const GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
GString *errors = user_data;
|
||||
|
||||
if (fatal)
|
||||
g_test_fail ();
|
||||
|
||||
g_string_append_printf (errors,
|
||||
"%zu:%zu: %s: ",
|
||||
location->lines, location->line_chars,
|
||||
fatal ? "ERROR" : "warning");
|
||||
|
||||
g_string_append_printf (errors,
|
||||
"%s\n",
|
||||
error->message);
|
||||
}
|
||||
|
||||
static void
|
||||
parse_glsl_file (GFile *file, gboolean generate)
|
||||
{
|
||||
GskPixelShader *shader;
|
||||
GBytes *bytes;
|
||||
char *glsl, *diff;
|
||||
char *glsl_file, *reference_file, *errors_file;
|
||||
gsize length;
|
||||
GString *errors;
|
||||
GError *error = NULL;
|
||||
|
||||
glsl_file = g_file_get_path (file);
|
||||
errors = g_string_new ("");
|
||||
|
||||
g_file_load_contents (file, NULL,
|
||||
&glsl, &length,
|
||||
NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
bytes = g_bytes_new_take (glsl, length);
|
||||
|
||||
shader = gsk_pixel_shader_new_for_data (bytes,
|
||||
parsing_error_cb,
|
||||
errors);
|
||||
|
||||
glsl = gsk_pixel_shader_to_string (shader);
|
||||
|
||||
if (generate)
|
||||
{
|
||||
g_print ("%s", glsl);
|
||||
goto out;
|
||||
}
|
||||
|
||||
reference_file = test_get_reference_file (glsl_file);
|
||||
|
||||
diff = diff_with_file (reference_file, glsl, -1, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
if (diff && diff[0])
|
||||
{
|
||||
g_test_message ("Resulting CSS doesn't match reference:\n%s", diff);
|
||||
g_test_fail ();
|
||||
}
|
||||
g_free (reference_file);
|
||||
|
||||
errors_file = test_get_errors_file (glsl_file);
|
||||
|
||||
if (errors_file)
|
||||
{
|
||||
diff = diff_with_file (errors_file, errors->str, errors->len, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
if (diff && diff[0])
|
||||
{
|
||||
g_test_message ("Errors don't match expected errors:\n%s", diff);
|
||||
g_test_fail ();
|
||||
}
|
||||
}
|
||||
else if (errors->str[0])
|
||||
{
|
||||
g_test_message ("Unexpected errors:\n%s", errors->str);
|
||||
g_test_fail ();
|
||||
}
|
||||
|
||||
g_object_unref (shader);
|
||||
g_free (errors_file);
|
||||
g_string_free (errors, TRUE);
|
||||
|
||||
g_free (diff);
|
||||
|
||||
out:
|
||||
g_free (glsl_file);
|
||||
g_free (glsl);
|
||||
}
|
||||
|
||||
static void
|
||||
test_glsl_file (GFile *file)
|
||||
{
|
||||
parse_glsl_file (file, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
add_test_for_file (GFile *file)
|
||||
{
|
||||
char *path;
|
||||
|
||||
path = g_file_get_path (file);
|
||||
|
||||
g_test_add_vtable (path,
|
||||
0,
|
||||
g_object_ref (file),
|
||||
NULL,
|
||||
(GTestFixtureFunc) test_glsl_file,
|
||||
(GTestFixtureFunc) g_object_unref);
|
||||
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
static int
|
||||
compare_files (gconstpointer a, gconstpointer b)
|
||||
{
|
||||
GFile *file1 = G_FILE (a);
|
||||
GFile *file2 = G_FILE (b);
|
||||
char *path1, *path2;
|
||||
int result;
|
||||
|
||||
path1 = g_file_get_path (file1);
|
||||
path2 = g_file_get_path (file2);
|
||||
|
||||
result = strcmp (path1, path2);
|
||||
|
||||
g_free (path1);
|
||||
g_free (path2);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
add_tests_for_files_in_directory (GFile *dir)
|
||||
{
|
||||
GFileEnumerator *enumerator;
|
||||
GFileInfo *info;
|
||||
GList *files;
|
||||
GError *error = NULL;
|
||||
|
||||
enumerator = g_file_enumerate_children (dir, G_FILE_ATTRIBUTE_STANDARD_NAME, 0, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
files = NULL;
|
||||
|
||||
while ((info = g_file_enumerator_next_file (enumerator, NULL, &error)))
|
||||
{
|
||||
const char *filename;
|
||||
|
||||
filename = g_file_info_get_name (info);
|
||||
|
||||
if (!g_str_has_suffix (filename, ".glsl") ||
|
||||
g_str_has_suffix (filename, ".out.glsl") ||
|
||||
g_str_has_suffix (filename, ".ref.glsl"))
|
||||
{
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
|
||||
files = g_list_prepend (files, g_file_get_child (dir, filename));
|
||||
|
||||
g_object_unref (info);
|
||||
}
|
||||
|
||||
g_assert_no_error (error);
|
||||
g_object_unref (enumerator);
|
||||
|
||||
files = g_list_sort (files, compare_files);
|
||||
g_list_foreach (files, (GFunc) add_test_for_file, NULL);
|
||||
g_list_free_full (files, g_object_unref);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
gtk_test_init (&argc, &argv);
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
const char *basedir;
|
||||
GFile *dir;
|
||||
|
||||
basedir = g_test_get_dir (G_TEST_DIST);
|
||||
dir = g_file_new_for_path (basedir);
|
||||
add_tests_for_files_in_directory (dir);
|
||||
|
||||
g_object_unref (dir);
|
||||
}
|
||||
else if (strcmp (argv[1], "--generate") == 0)
|
||||
{
|
||||
if (argc >= 3)
|
||||
{
|
||||
GFile *file = g_file_new_for_commandline_arg (argv[2]);
|
||||
|
||||
parse_glsl_file (file, TRUE);
|
||||
|
||||
g_object_unref (file);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
GFile *file = g_file_new_for_commandline_arg (argv[i]);
|
||||
|
||||
add_test_for_file (file);
|
||||
|
||||
g_object_unref (file);
|
||||
}
|
||||
}
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ installed_test_datadir = join_paths(gtk_datadir, 'installed-tests', 'gtk-4.0')
|
||||
|
||||
subdir('gdk')
|
||||
subdir('gsk')
|
||||
subdir('gsksl')
|
||||
subdir('gtk')
|
||||
subdir('css')
|
||||
subdir('a11y')
|
||||
|
||||
Reference in New Issue
Block a user