gskslcompiler: Add support for adding defines
gtk-glsl implements this via the usual -D and -U options. Preprocessor directives aren't implemented yet, but defines are replaced in the source code already.
This commit is contained in:
@@ -18,13 +18,17 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gskslcompiler.h"
|
||||
#include "gskslcompilerprivate.h"
|
||||
|
||||
#include "gsksldefineprivate.h"
|
||||
#include "gskslpreprocessorprivate.h"
|
||||
#include "gskslprogramprivate.h"
|
||||
#include "gsksltokenizerprivate.h"
|
||||
|
||||
struct _GskSlCompiler {
|
||||
GObject parent_instance;
|
||||
|
||||
GHashTable *defines;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GskSlCompiler, gsk_sl_compiler, G_TYPE_OBJECT)
|
||||
@@ -32,7 +36,9 @@ G_DEFINE_TYPE (GskSlCompiler, gsk_sl_compiler, G_TYPE_OBJECT)
|
||||
static void
|
||||
gsk_sl_compiler_dispose (GObject *object)
|
||||
{
|
||||
//GskSlCompiler *compiler = GSK_SL_COMPILER (object);
|
||||
GskSlCompiler *compiler = GSK_SL_COMPILER (object);
|
||||
|
||||
g_hash_table_destroy (compiler->defines);
|
||||
|
||||
G_OBJECT_CLASS (gsk_sl_compiler_parent_class)->dispose (object);
|
||||
}
|
||||
@@ -48,6 +54,8 @@ gsk_sl_compiler_class_init (GskSlCompilerClass *klass)
|
||||
static void
|
||||
gsk_sl_compiler_init (GskSlCompiler *compiler)
|
||||
{
|
||||
compiler->defines = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
NULL, (GDestroyNotify) gsk_sl_define_unref);
|
||||
}
|
||||
|
||||
GskSlCompiler *
|
||||
@@ -56,6 +64,124 @@ gsk_sl_compiler_new (void)
|
||||
return g_object_new (GSK_TYPE_SL_COMPILER, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_compiler_add_define_error_func (GskSlTokenizer *parser,
|
||||
gboolean fatal,
|
||||
const GskCodeLocation *location,
|
||||
const GskSlToken *token,
|
||||
const GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
GError **real_error = user_data;
|
||||
|
||||
if (!fatal)
|
||||
return;
|
||||
|
||||
if (*real_error)
|
||||
return;
|
||||
|
||||
*real_error = g_error_copy (error);
|
||||
g_prefix_error (real_error,
|
||||
"%3zu:%2zu: ",
|
||||
location->lines + 1,
|
||||
location->line_bytes);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_compiler_add_define (GskSlCompiler *compiler,
|
||||
const char *name,
|
||||
const char *definition,
|
||||
GError **error)
|
||||
{
|
||||
GskSlTokenizer *tokenizer;
|
||||
GskSlDefine *define;
|
||||
GskCodeLocation location;
|
||||
GskSlToken token = { 0, };
|
||||
GError *real_error = NULL;
|
||||
GBytes *bytes;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_SL_COMPILER (compiler), FALSE);
|
||||
g_return_val_if_fail (name != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
if (!gsk_sl_string_is_valid_identifier (name))
|
||||
{
|
||||
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "Define name \"%s\" is not a valid identifier", name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (definition == NULL)
|
||||
definition = "1";
|
||||
|
||||
define = gsk_sl_define_new (name, NULL);
|
||||
bytes = g_bytes_new_static (definition, strlen (definition));
|
||||
tokenizer = gsk_sl_tokenizer_new (bytes,
|
||||
gsk_sl_compiler_add_define_error_func,
|
||||
&real_error,
|
||||
NULL);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
do
|
||||
{
|
||||
gsk_sl_token_clear (&token);
|
||||
location = *gsk_sl_tokenizer_get_location (tokenizer);
|
||||
gsk_sl_tokenizer_read_token (tokenizer, &token);
|
||||
}
|
||||
while (gsk_sl_token_is_skipped (&token));
|
||||
|
||||
if (gsk_sl_token_is (&token, GSK_SL_TOKEN_EOF))
|
||||
break;
|
||||
|
||||
gsk_sl_define_add_token (define, &location, &token);
|
||||
}
|
||||
|
||||
gsk_sl_token_clear (&token);
|
||||
gsk_sl_tokenizer_unref (tokenizer);
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
if (real_error == NULL)
|
||||
{
|
||||
g_hash_table_replace (compiler->defines, (gpointer) gsk_sl_define_get_name (define), define);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_sl_define_unref (define);
|
||||
g_propagate_error (error, real_error);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_compiler_remove_define (GskSlCompiler *compiler,
|
||||
const char *name)
|
||||
{
|
||||
g_return_if_fail (GSK_IS_SL_COMPILER (compiler));
|
||||
g_return_if_fail (name != NULL);
|
||||
|
||||
g_hash_table_remove (compiler->defines, name);
|
||||
}
|
||||
|
||||
GHashTable *
|
||||
gsk_sl_compiler_copy_defines (GskSlCompiler *compiler)
|
||||
{
|
||||
GHashTable *copy;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
|
||||
copy = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
NULL, (GDestroyNotify) gsk_sl_define_unref);
|
||||
|
||||
g_hash_table_iter_init (&iter, compiler->defines);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
g_hash_table_replace (copy, key, gsk_sl_define_ref (value));
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
GskSlProgram *
|
||||
gsk_sl_compiler_compile (GskSlCompiler *compiler,
|
||||
GBytes *source)
|
||||
|
||||
@@ -34,6 +34,15 @@ G_DECLARE_FINAL_TYPE (GskSlCompiler, gsk_sl_compiler, GSK, SL_COMPILER, GObject)
|
||||
GDK_AVAILABLE_IN_3_92
|
||||
GskSlCompiler * gsk_sl_compiler_new (void);
|
||||
|
||||
GDK_AVAILABLE_IN_3_92
|
||||
gboolean gsk_sl_compiler_add_define (GskSlCompiler *compiler,
|
||||
const char *name,
|
||||
const char *definition,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_3_92
|
||||
void gsk_sl_compiler_remove_define (GskSlCompiler *compiler,
|
||||
const char *name);
|
||||
|
||||
GDK_AVAILABLE_IN_3_92
|
||||
GskSlProgram * gsk_sl_compiler_compile (GskSlCompiler *compiler,
|
||||
GBytes *source);
|
||||
|
||||
30
gsk/gskslcompilerprivate.h
Normal file
30
gsk/gskslcompilerprivate.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/* 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_COMPILER_PRIVATE_H__
|
||||
#define __GSK_SL_COMPILER_PRIVATE_H__
|
||||
|
||||
#include "gsk/gskslcompiler.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GHashTable * gsk_sl_compiler_copy_defines (GskSlCompiler *compiler);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_COMPILER_PRIVATE_H__ */
|
||||
132
gsk/gsksldefine.c
Normal file
132
gsk/gsksldefine.c
Normal file
@@ -0,0 +1,132 @@
|
||||
/* 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 "gsksldefineprivate.h"
|
||||
|
||||
typedef struct _GskSlDefineToken GskSlDefineToken;
|
||||
|
||||
struct _GskSlDefineToken {
|
||||
GskCodeLocation location;
|
||||
GskSlToken token;
|
||||
};
|
||||
|
||||
struct _GskSlDefine {
|
||||
int ref_count;
|
||||
|
||||
char *name;
|
||||
GFile *source_file;
|
||||
|
||||
GArray *tokens;
|
||||
};
|
||||
|
||||
GskSlDefine *
|
||||
gsk_sl_define_new (const char *name,
|
||||
GFile *source_file)
|
||||
{
|
||||
GskSlDefine *result;
|
||||
|
||||
result = g_slice_new0 (GskSlDefine);
|
||||
|
||||
result->ref_count = 1;
|
||||
result->name = g_strdup (name);
|
||||
if (source_file)
|
||||
result->source_file = g_object_ref (source_file);
|
||||
result->tokens = g_array_new (FALSE, FALSE, sizeof (GskSlDefineToken));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GskSlDefine *
|
||||
gsk_sl_define_ref (GskSlDefine *define)
|
||||
{
|
||||
g_return_val_if_fail (define != NULL, NULL);
|
||||
|
||||
define->ref_count += 1;
|
||||
|
||||
return define;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_define_unref (GskSlDefine *define)
|
||||
{
|
||||
if (define == NULL)
|
||||
return;
|
||||
|
||||
define->ref_count -= 1;
|
||||
if (define->ref_count > 0)
|
||||
return;
|
||||
|
||||
g_array_free (define->tokens, TRUE);
|
||||
|
||||
if (define->source_file)
|
||||
g_object_unref (define->source_file);
|
||||
g_free (define->name);
|
||||
|
||||
g_slice_free (GskSlDefine, define);
|
||||
}
|
||||
|
||||
const char *
|
||||
gsk_sl_define_get_name (GskSlDefine *define)
|
||||
{
|
||||
return define->name;
|
||||
}
|
||||
|
||||
GFile *
|
||||
gsk_sl_define_get_source_file (GskSlDefine *define)
|
||||
{
|
||||
return define->source_file;
|
||||
}
|
||||
|
||||
guint
|
||||
gsk_sl_define_get_n_tokens (GskSlDefine *define)
|
||||
{
|
||||
return define->tokens->len;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_define_get_token (GskSlDefine *define,
|
||||
guint i,
|
||||
GskCodeLocation *location,
|
||||
GskSlToken *token)
|
||||
{
|
||||
GskSlDefineToken *dt;
|
||||
|
||||
dt = &g_array_index (define->tokens, GskSlDefineToken, i);
|
||||
|
||||
if (location)
|
||||
*location = dt->location;
|
||||
if (token)
|
||||
gsk_sl_token_copy (token, &dt->token);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_define_add_token (GskSlDefine *define,
|
||||
const GskCodeLocation *location,
|
||||
const GskSlToken *token)
|
||||
{
|
||||
GskSlDefineToken dt;
|
||||
|
||||
dt.location = *location;
|
||||
gsk_sl_token_copy (&dt.token, token);
|
||||
|
||||
g_array_append_val (define->tokens, dt);
|
||||
}
|
||||
|
||||
|
||||
51
gsk/gsksldefineprivate.h
Normal file
51
gsk/gsksldefineprivate.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/* 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_DEFINE_PRIVATE_H__
|
||||
#define __GSK_SL_DEFINE_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "gsksltokenizerprivate.h"
|
||||
#include "gsksltypesprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GskSlDefine GskSlDefine;
|
||||
|
||||
GskSlDefine * gsk_sl_define_new (const char *name,
|
||||
GFile *source_file);
|
||||
|
||||
GskSlDefine * gsk_sl_define_ref (GskSlDefine *define);
|
||||
void gsk_sl_define_unref (GskSlDefine *define);
|
||||
|
||||
const char * gsk_sl_define_get_name (GskSlDefine *define);
|
||||
GFile * gsk_sl_define_get_source_file (GskSlDefine *define);
|
||||
guint gsk_sl_define_get_n_tokens (GskSlDefine *define);
|
||||
void gsk_sl_define_get_token (GskSlDefine *define,
|
||||
guint i,
|
||||
GskCodeLocation *location,
|
||||
GskSlToken *token);
|
||||
|
||||
void gsk_sl_define_add_token (GskSlDefine *define,
|
||||
const GskCodeLocation *location,
|
||||
const GskSlToken *token);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GSK_SL_DEFINE_PRIVATE_H__ */
|
||||
@@ -20,16 +20,25 @@
|
||||
|
||||
#include "gskslpreprocessorprivate.h"
|
||||
|
||||
#include "gskslcompilerprivate.h"
|
||||
#include "gsksldefineprivate.h"
|
||||
#include "gsksltokenizerprivate.h"
|
||||
|
||||
typedef struct _GskSlPpToken GskSlPpToken;
|
||||
|
||||
struct _GskSlPpToken {
|
||||
GskCodeLocation location;
|
||||
GskSlToken token;
|
||||
};
|
||||
|
||||
struct _GskSlPreprocessor
|
||||
{
|
||||
int ref_count;
|
||||
|
||||
GskSlCompiler *compiler;
|
||||
GskSlTokenizer *tokenizer;
|
||||
GskCodeLocation location;
|
||||
GskSlToken token;
|
||||
GArray *tokens;
|
||||
GHashTable *defines;
|
||||
};
|
||||
|
||||
/* API */
|
||||
@@ -48,6 +57,14 @@ gsk_sl_preprocessor_error_func (GskSlTokenizer *parser,
|
||||
error->message);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_preprocessor_clear_token (gpointer data)
|
||||
{
|
||||
GskSlPpToken *pp = data;
|
||||
|
||||
gsk_sl_token_clear (&pp->token);
|
||||
}
|
||||
|
||||
GskSlPreprocessor *
|
||||
gsk_sl_preprocessor_new (GskSlCompiler *compiler,
|
||||
GBytes *source)
|
||||
@@ -62,6 +79,9 @@ gsk_sl_preprocessor_new (GskSlCompiler *compiler,
|
||||
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;
|
||||
}
|
||||
@@ -86,35 +106,29 @@ gsk_sl_preprocessor_unref (GskSlPreprocessor *preproc)
|
||||
if (preproc->ref_count > 0)
|
||||
return;
|
||||
|
||||
g_hash_table_destroy (preproc->defines);
|
||||
gsk_sl_tokenizer_unref (preproc->tokenizer);
|
||||
gsk_sl_token_clear (&preproc->token);
|
||||
g_object_unref (preproc->compiler);
|
||||
g_array_free (preproc->tokens, TRUE);
|
||||
|
||||
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_NEWLINE)
|
||||
|| 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 gboolean
|
||||
gsk_sl_preprocessor_next_token (GskSlPreprocessor *preproc)
|
||||
gsk_sl_preprocessor_next_token (GskSlPreprocessor *preproc,
|
||||
GskSlPpToken *pp)
|
||||
{
|
||||
gboolean was_newline;
|
||||
|
||||
pp->token = (GskSlToken) { 0, };
|
||||
|
||||
do
|
||||
{
|
||||
preproc->location = *gsk_sl_tokenizer_get_location (preproc->tokenizer);
|
||||
was_newline = gsk_sl_token_is (&preproc->token, GSK_SL_TOKEN_NEWLINE);
|
||||
gsk_sl_tokenizer_read_token (preproc->tokenizer, &preproc->token);
|
||||
pp->location = *gsk_sl_tokenizer_get_location (preproc->tokenizer);
|
||||
was_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 (&preproc->token));
|
||||
while (gsk_sl_token_is_skipped (&pp->token));
|
||||
|
||||
return was_newline;
|
||||
}
|
||||
@@ -122,17 +136,23 @@ gsk_sl_preprocessor_next_token (GskSlPreprocessor *preproc)
|
||||
static void
|
||||
gsk_sl_preprocessor_handle_preprocessor_directive (GskSlPreprocessor *preproc)
|
||||
{
|
||||
gboolean was_newline = gsk_sl_preprocessor_next_token (preproc);
|
||||
GskSlPpToken pp;
|
||||
|
||||
gboolean was_newline = gsk_sl_preprocessor_next_token (preproc, &pp);
|
||||
|
||||
/* empty # line */
|
||||
if (was_newline)
|
||||
return;
|
||||
|
||||
if (gsk_sl_token_is (&preproc->token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
{
|
||||
if (g_str_equal (preproc->token.str, "define"))
|
||||
gsk_sl_preprocessor_clear_token (&pp);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gsk_sl_token_is (&pp.token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
{
|
||||
if (g_str_equal (pp.token.str, "define"))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, "Unknown preprocessor directive #define.");
|
||||
gsk_sl_preprocessor_clear_token (&pp);
|
||||
}
|
||||
#if 0
|
||||
else if (g_str_equal (preproc->token.str, "else"))
|
||||
@@ -165,49 +185,89 @@ gsk_sl_preprocessor_handle_preprocessor_directive (GskSlPreprocessor *preproc)
|
||||
else if (g_str_equal (preproc->token.str, "pragma"))
|
||||
{
|
||||
}
|
||||
else if (g_str_equal (preproc->token.str, "undef"))
|
||||
{
|
||||
}
|
||||
else if (g_str_equal (preproc->token.str, "version"))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, "Unknown preprocessor directive #%s.", preproc->token.str);
|
||||
gsk_sl_preprocessor_error (preproc, "Unknown preprocessor directive #%s.", pp.token.str);
|
||||
gsk_sl_preprocessor_clear_token (&pp);
|
||||
}
|
||||
}
|
||||
else if (gsk_sl_token_is (&preproc->token, GSK_SL_TOKEN_ELSE))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, "Unknown preprocessor directive #else.");
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, "Missing identifier for preprocessor directive.");
|
||||
gsk_sl_preprocessor_clear_token (&pp);
|
||||
}
|
||||
|
||||
while (!gsk_sl_preprocessor_next_token (preproc, &pp))
|
||||
gsk_sl_preprocessor_clear_token (&pp);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_preprocessor_append_token (GskSlPreprocessor *preproc,
|
||||
GskSlPpToken *pp,
|
||||
GSList *used_defines)
|
||||
{
|
||||
if (gsk_sl_token_is (&pp->token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
{
|
||||
GskSlDefine *define;
|
||||
char *ident = pp->token.str;
|
||||
|
||||
define = g_hash_table_lookup (preproc->defines, ident);
|
||||
if (define &&
|
||||
!g_slist_find (used_defines, define))
|
||||
{
|
||||
GSList new_defines = { define, used_defines };
|
||||
GskSlPpToken dpp;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < gsk_sl_define_get_n_tokens (define); i++)
|
||||
{
|
||||
gsk_sl_define_get_token (define, i, &dpp.location, &dpp.token);
|
||||
gsk_sl_preprocessor_append_token (preproc, &dpp, &new_defines);
|
||||
}
|
||||
|
||||
gsk_sl_preprocessor_clear_token (pp);
|
||||
return;
|
||||
}
|
||||
|
||||
gsk_sl_token_init_from_identifier (&pp->token, ident);
|
||||
g_free (ident);
|
||||
}
|
||||
|
||||
while (!gsk_sl_preprocessor_next_token (preproc));
|
||||
g_array_append_val (preproc->tokens, *pp);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_preprocessor_ensure (GskSlPreprocessor *preproc)
|
||||
{
|
||||
GskSlPpToken pp;
|
||||
gboolean was_newline = FALSE;
|
||||
|
||||
if (!gsk_sl_token_is (&preproc->token, GSK_SL_TOKEN_EOF))
|
||||
if (preproc->tokens->len > 0)
|
||||
return;
|
||||
|
||||
was_newline = gsk_sl_preprocessor_next_token (preproc);
|
||||
was_newline = gsk_sl_preprocessor_next_token (preproc, &pp);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (gsk_sl_token_is (&preproc->token, GSK_SL_TOKEN_HASH))
|
||||
if (gsk_sl_token_is (&pp.token, GSK_SL_TOKEN_HASH))
|
||||
{
|
||||
if (!was_newline &&
|
||||
preproc->location.bytes != 0)
|
||||
pp.location.bytes != 0)
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, "Unexpected \"#\" - preprocessor directives must be at start of line.");
|
||||
was_newline = gsk_sl_preprocessor_next_token (preproc);
|
||||
gsk_sl_preprocessor_clear_token (&pp);
|
||||
was_newline = gsk_sl_preprocessor_next_token (preproc, &pp);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_sl_preprocessor_clear_token (&pp);
|
||||
gsk_sl_preprocessor_handle_preprocessor_directive (preproc);
|
||||
was_newline = TRUE;
|
||||
}
|
||||
@@ -218,12 +278,7 @@ gsk_sl_preprocessor_ensure (GskSlPreprocessor *preproc)
|
||||
}
|
||||
}
|
||||
|
||||
if (gsk_sl_token_is (&preproc->token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
{
|
||||
char *ident = preproc->token.str;
|
||||
gsk_sl_token_init_from_identifier (&preproc->token, ident);
|
||||
g_free (ident);
|
||||
}
|
||||
gsk_sl_preprocessor_append_token (preproc, &pp, NULL);
|
||||
}
|
||||
|
||||
const GskSlToken *
|
||||
@@ -231,7 +286,7 @@ gsk_sl_preprocessor_get (GskSlPreprocessor *preproc)
|
||||
{
|
||||
gsk_sl_preprocessor_ensure (preproc);
|
||||
|
||||
return &preproc->token;
|
||||
return &g_array_index (preproc->tokens, GskSlPpToken, 0).token;
|
||||
}
|
||||
|
||||
const GskCodeLocation *
|
||||
@@ -239,7 +294,7 @@ gsk_sl_preprocessor_get_location (GskSlPreprocessor *preproc)
|
||||
{
|
||||
gsk_sl_preprocessor_ensure (preproc);
|
||||
|
||||
return &preproc->location;
|
||||
return &g_array_index (preproc->tokens, GskSlPpToken, 0).location;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -248,7 +303,7 @@ gsk_sl_preprocessor_consume (GskSlPreprocessor *preproc,
|
||||
{
|
||||
gsk_sl_preprocessor_ensure (preproc);
|
||||
|
||||
gsk_sl_token_clear (&preproc->token);
|
||||
g_array_remove_index (preproc->tokens, 0);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -269,8 +324,8 @@ gsk_sl_preprocessor_error (GskSlPreprocessor *preproc,
|
||||
gsk_sl_preprocessor_ensure (preproc);
|
||||
gsk_sl_preprocessor_error_func (preproc->tokenizer,
|
||||
TRUE,
|
||||
&preproc->location,
|
||||
&preproc->token,
|
||||
gsk_sl_preprocessor_get_location (preproc),
|
||||
gsk_sl_preprocessor_get (preproc),
|
||||
error,
|
||||
NULL);
|
||||
|
||||
|
||||
@@ -314,6 +314,256 @@ gsk_sl_token_clear (GskSlToken *token)
|
||||
token->type = GSK_SL_TOKEN_EOF;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_token_copy (GskSlToken *dest,
|
||||
const GskSlToken *src)
|
||||
{
|
||||
dest->type = src->type;
|
||||
|
||||
switch (src->type)
|
||||
{
|
||||
case GSK_SL_TOKEN_IDENTIFIER:
|
||||
dest->str = g_strdup (src->str);
|
||||
break;
|
||||
|
||||
case GSK_SL_TOKEN_BOOLCONSTANT:
|
||||
dest->b = src->b;
|
||||
break;
|
||||
|
||||
case GSK_SL_TOKEN_FLOATCONSTANT:
|
||||
dest->f = src->f;
|
||||
break;
|
||||
|
||||
case GSK_SL_TOKEN_DOUBLECONSTANT:
|
||||
dest->d = src->d;
|
||||
break;
|
||||
|
||||
case GSK_SL_TOKEN_INTCONSTANT:
|
||||
dest->i32 = src->i32;
|
||||
break;
|
||||
|
||||
case GSK_SL_TOKEN_UINTCONSTANT:
|
||||
dest->u32 = src->u32;
|
||||
break;
|
||||
|
||||
case GSK_SL_TOKEN_EOF:
|
||||
case GSK_SL_TOKEN_ERROR:
|
||||
case GSK_SL_TOKEN_NEWLINE:
|
||||
case GSK_SL_TOKEN_WHITESPACE:
|
||||
case GSK_SL_TOKEN_COMMENT:
|
||||
case GSK_SL_TOKEN_SINGLE_LINE_COMMENT:
|
||||
case GSK_SL_TOKEN_CONST:
|
||||
case GSK_SL_TOKEN_BREAK:
|
||||
case GSK_SL_TOKEN_CONTINUE:
|
||||
case GSK_SL_TOKEN_DO:
|
||||
case GSK_SL_TOKEN_ELSE:
|
||||
case GSK_SL_TOKEN_FOR:
|
||||
case GSK_SL_TOKEN_IF:
|
||||
case GSK_SL_TOKEN_DISCARD:
|
||||
case GSK_SL_TOKEN_RETURN:
|
||||
case GSK_SL_TOKEN_SWITCH:
|
||||
case GSK_SL_TOKEN_CASE:
|
||||
case GSK_SL_TOKEN_DEFAULT:
|
||||
case GSK_SL_TOKEN_SUBROUTINE:
|
||||
case GSK_SL_TOKEN_BVEC2:
|
||||
case GSK_SL_TOKEN_BVEC3:
|
||||
case GSK_SL_TOKEN_BVEC4:
|
||||
case GSK_SL_TOKEN_IVEC2:
|
||||
case GSK_SL_TOKEN_IVEC3:
|
||||
case GSK_SL_TOKEN_IVEC4:
|
||||
case GSK_SL_TOKEN_UVEC2:
|
||||
case GSK_SL_TOKEN_UVEC3:
|
||||
case GSK_SL_TOKEN_UVEC4:
|
||||
case GSK_SL_TOKEN_VEC2:
|
||||
case GSK_SL_TOKEN_VEC3:
|
||||
case GSK_SL_TOKEN_VEC4:
|
||||
case GSK_SL_TOKEN_MAT2:
|
||||
case GSK_SL_TOKEN_MAT3:
|
||||
case GSK_SL_TOKEN_MAT4:
|
||||
case GSK_SL_TOKEN_CENTROID:
|
||||
case GSK_SL_TOKEN_IN:
|
||||
case GSK_SL_TOKEN_OUT:
|
||||
case GSK_SL_TOKEN_INOUT:
|
||||
case GSK_SL_TOKEN_UNIFORM:
|
||||
case GSK_SL_TOKEN_PATCH:
|
||||
case GSK_SL_TOKEN_SAMPLE:
|
||||
case GSK_SL_TOKEN_BUFFER:
|
||||
case GSK_SL_TOKEN_SHARED:
|
||||
case GSK_SL_TOKEN_COHERENT:
|
||||
case GSK_SL_TOKEN_VOLATILE:
|
||||
case GSK_SL_TOKEN_RESTRICT:
|
||||
case GSK_SL_TOKEN_READONLY:
|
||||
case GSK_SL_TOKEN_WRITEONLY:
|
||||
case GSK_SL_TOKEN_DVEC2:
|
||||
case GSK_SL_TOKEN_DVEC3:
|
||||
case GSK_SL_TOKEN_DVEC4:
|
||||
case GSK_SL_TOKEN_DMAT2:
|
||||
case GSK_SL_TOKEN_DMAT3:
|
||||
case GSK_SL_TOKEN_DMAT4:
|
||||
case GSK_SL_TOKEN_NOPERSPECTIVE:
|
||||
case GSK_SL_TOKEN_FLAT:
|
||||
case GSK_SL_TOKEN_SMOOTH:
|
||||
case GSK_SL_TOKEN_LAYOUT:
|
||||
case GSK_SL_TOKEN_MAT2X2:
|
||||
case GSK_SL_TOKEN_MAT2X3:
|
||||
case GSK_SL_TOKEN_MAT2X4:
|
||||
case GSK_SL_TOKEN_MAT3X2:
|
||||
case GSK_SL_TOKEN_MAT3X3:
|
||||
case GSK_SL_TOKEN_MAT3X4:
|
||||
case GSK_SL_TOKEN_MAT4X2:
|
||||
case GSK_SL_TOKEN_MAT4X3:
|
||||
case GSK_SL_TOKEN_MAT4X4:
|
||||
case GSK_SL_TOKEN_DMAT2X2:
|
||||
case GSK_SL_TOKEN_DMAT2X3:
|
||||
case GSK_SL_TOKEN_DMAT2X4:
|
||||
case GSK_SL_TOKEN_DMAT3X2:
|
||||
case GSK_SL_TOKEN_DMAT3X3:
|
||||
case GSK_SL_TOKEN_DMAT3X4:
|
||||
case GSK_SL_TOKEN_DMAT4X2:
|
||||
case GSK_SL_TOKEN_DMAT4X3:
|
||||
case GSK_SL_TOKEN_DMAT4X4:
|
||||
case GSK_SL_TOKEN_ATOMIC_UINT:
|
||||
case GSK_SL_TOKEN_SAMPLER1D:
|
||||
case GSK_SL_TOKEN_SAMPLER2D:
|
||||
case GSK_SL_TOKEN_SAMPLER3D:
|
||||
case GSK_SL_TOKEN_SAMPLERCUBE:
|
||||
case GSK_SL_TOKEN_SAMPLER1DSHADOW:
|
||||
case GSK_SL_TOKEN_SAMPLER2DSHADOW:
|
||||
case GSK_SL_TOKEN_SAMPLERCUBESHADOW:
|
||||
case GSK_SL_TOKEN_SAMPLER1DARRAY:
|
||||
case GSK_SL_TOKEN_SAMPLER2DARRAY:
|
||||
case GSK_SL_TOKEN_SAMPLER1DARRAYSHADOW:
|
||||
case GSK_SL_TOKEN_SAMPLER2DARRAYSHADOW:
|
||||
case GSK_SL_TOKEN_ISAMPLER1D:
|
||||
case GSK_SL_TOKEN_ISAMPLER2D:
|
||||
case GSK_SL_TOKEN_ISAMPLER3D:
|
||||
case GSK_SL_TOKEN_ISAMPLERCUBE:
|
||||
case GSK_SL_TOKEN_ISAMPLER1DARRAY:
|
||||
case GSK_SL_TOKEN_ISAMPLER2DARRAY:
|
||||
case GSK_SL_TOKEN_USAMPLER1D:
|
||||
case GSK_SL_TOKEN_USAMPLER2D:
|
||||
case GSK_SL_TOKEN_USAMPLER3D:
|
||||
case GSK_SL_TOKEN_USAMPLERCUBE:
|
||||
case GSK_SL_TOKEN_USAMPLER1DARRAY:
|
||||
case GSK_SL_TOKEN_USAMPLER2DARRAY:
|
||||
case GSK_SL_TOKEN_SAMPLER2DRECT:
|
||||
case GSK_SL_TOKEN_SAMPLER2DRECTSHADOW:
|
||||
case GSK_SL_TOKEN_ISAMPLER2DRECT:
|
||||
case GSK_SL_TOKEN_USAMPLER2DRECT:
|
||||
case GSK_SL_TOKEN_SAMPLERBUFFER:
|
||||
case GSK_SL_TOKEN_ISAMPLERBUFFER:
|
||||
case GSK_SL_TOKEN_USAMPLERBUFFER:
|
||||
case GSK_SL_TOKEN_SAMPLERCUBEARRAY:
|
||||
case GSK_SL_TOKEN_SAMPLERCUBEARRAYSHADOW:
|
||||
case GSK_SL_TOKEN_ISAMPLERCUBEARRAY:
|
||||
case GSK_SL_TOKEN_USAMPLERCUBEARRAY:
|
||||
case GSK_SL_TOKEN_SAMPLER2DMS:
|
||||
case GSK_SL_TOKEN_ISAMPLER2DMS:
|
||||
case GSK_SL_TOKEN_USAMPLER2DMS:
|
||||
case GSK_SL_TOKEN_SAMPLER2DMSARRAY:
|
||||
case GSK_SL_TOKEN_ISAMPLER2DMSARRAY:
|
||||
case GSK_SL_TOKEN_USAMPLER2DMSARRAY:
|
||||
case GSK_SL_TOKEN_IMAGE1D:
|
||||
case GSK_SL_TOKEN_IIMAGE1D:
|
||||
case GSK_SL_TOKEN_UIMAGE1D:
|
||||
case GSK_SL_TOKEN_IMAGE2D:
|
||||
case GSK_SL_TOKEN_IIMAGE2D:
|
||||
case GSK_SL_TOKEN_UIMAGE2D:
|
||||
case GSK_SL_TOKEN_IMAGE3D:
|
||||
case GSK_SL_TOKEN_IIMAGE3D:
|
||||
case GSK_SL_TOKEN_UIMAGE3D:
|
||||
case GSK_SL_TOKEN_IMAGE2DRECT:
|
||||
case GSK_SL_TOKEN_IIMAGE2DRECT:
|
||||
case GSK_SL_TOKEN_UIMAGE2DRECT:
|
||||
case GSK_SL_TOKEN_IMAGECUBE:
|
||||
case GSK_SL_TOKEN_IIMAGECUBE:
|
||||
case GSK_SL_TOKEN_UIMAGECUBE:
|
||||
case GSK_SL_TOKEN_IMAGEBUFFER:
|
||||
case GSK_SL_TOKEN_IIMAGEBUFFER:
|
||||
case GSK_SL_TOKEN_UIMAGEBUFFER:
|
||||
case GSK_SL_TOKEN_IMAGE1DARRAY:
|
||||
case GSK_SL_TOKEN_IIMAGE1DARRAY:
|
||||
case GSK_SL_TOKEN_UIMAGE1DARRAY:
|
||||
case GSK_SL_TOKEN_IMAGE2DARRAY:
|
||||
case GSK_SL_TOKEN_IIMAGE2DARRAY:
|
||||
case GSK_SL_TOKEN_UIMAGE2DARRAY:
|
||||
case GSK_SL_TOKEN_IMAGECUBEARRAY:
|
||||
case GSK_SL_TOKEN_IIMAGECUBEARRAY:
|
||||
case GSK_SL_TOKEN_UIMAGECUBEARRAY:
|
||||
case GSK_SL_TOKEN_IMAGE2DMS:
|
||||
case GSK_SL_TOKEN_IIMAGE2DMS:
|
||||
case GSK_SL_TOKEN_UIMAGE2DMS:
|
||||
case GSK_SL_TOKEN_IMAGE2DMSARRAY:
|
||||
case GSK_SL_TOKEN_IIMAGE2DMSARRAY:
|
||||
case GSK_SL_TOKEN_UIMAGE2DMSARRAY:
|
||||
case GSK_SL_TOKEN_STRUCT:
|
||||
case GSK_SL_TOKEN_VOID:
|
||||
case GSK_SL_TOKEN_WHILE:
|
||||
case GSK_SL_TOKEN_FLOAT:
|
||||
case GSK_SL_TOKEN_DOUBLE:
|
||||
case GSK_SL_TOKEN_INT:
|
||||
case GSK_SL_TOKEN_UINT:
|
||||
case GSK_SL_TOKEN_BOOL:
|
||||
case GSK_SL_TOKEN_LEFT_OP:
|
||||
case GSK_SL_TOKEN_RIGHT_OP:
|
||||
case GSK_SL_TOKEN_INC_OP:
|
||||
case GSK_SL_TOKEN_DEC_OP:
|
||||
case GSK_SL_TOKEN_LE_OP:
|
||||
case GSK_SL_TOKEN_GE_OP:
|
||||
case GSK_SL_TOKEN_EQ_OP:
|
||||
case GSK_SL_TOKEN_NE_OP:
|
||||
case GSK_SL_TOKEN_AND_OP:
|
||||
case GSK_SL_TOKEN_OR_OP:
|
||||
case GSK_SL_TOKEN_XOR_OP:
|
||||
case GSK_SL_TOKEN_MUL_ASSIGN:
|
||||
case GSK_SL_TOKEN_DIV_ASSIGN:
|
||||
case GSK_SL_TOKEN_ADD_ASSIGN:
|
||||
case GSK_SL_TOKEN_MOD_ASSIGN:
|
||||
case GSK_SL_TOKEN_LEFT_ASSIGN:
|
||||
case GSK_SL_TOKEN_RIGHT_ASSIGN:
|
||||
case GSK_SL_TOKEN_AND_ASSIGN:
|
||||
case GSK_SL_TOKEN_XOR_ASSIGN:
|
||||
case GSK_SL_TOKEN_OR_ASSIGN:
|
||||
case GSK_SL_TOKEN_SUB_ASSIGN:
|
||||
case GSK_SL_TOKEN_LEFT_PAREN:
|
||||
case GSK_SL_TOKEN_RIGHT_PAREN:
|
||||
case GSK_SL_TOKEN_LEFT_BRACKET:
|
||||
case GSK_SL_TOKEN_RIGHT_BRACKET:
|
||||
case GSK_SL_TOKEN_LEFT_BRACE:
|
||||
case GSK_SL_TOKEN_RIGHT_BRACE:
|
||||
case GSK_SL_TOKEN_DOT:
|
||||
case GSK_SL_TOKEN_COMMA:
|
||||
case GSK_SL_TOKEN_COLON:
|
||||
case GSK_SL_TOKEN_EQUAL:
|
||||
case GSK_SL_TOKEN_SEMICOLON:
|
||||
case GSK_SL_TOKEN_BANG:
|
||||
case GSK_SL_TOKEN_DASH:
|
||||
case GSK_SL_TOKEN_TILDE:
|
||||
case GSK_SL_TOKEN_PLUS:
|
||||
case GSK_SL_TOKEN_STAR:
|
||||
case GSK_SL_TOKEN_SLASH:
|
||||
case GSK_SL_TOKEN_PERCENT:
|
||||
case GSK_SL_TOKEN_LEFT_ANGLE:
|
||||
case GSK_SL_TOKEN_RIGHT_ANGLE:
|
||||
case GSK_SL_TOKEN_VERTICAL_BAR:
|
||||
case GSK_SL_TOKEN_CARET:
|
||||
case GSK_SL_TOKEN_AMPERSAND:
|
||||
case GSK_SL_TOKEN_QUESTION:
|
||||
case GSK_SL_TOKEN_HASH:
|
||||
case GSK_SL_TOKEN_INVARIANT:
|
||||
case GSK_SL_TOKEN_PRECISE:
|
||||
case GSK_SL_TOKEN_HIGH_PRECISION:
|
||||
case GSK_SL_TOKEN_MEDIUM_PRECISION:
|
||||
case GSK_SL_TOKEN_LOW_PRECISION:
|
||||
case GSK_SL_TOKEN_PRECISION:
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *keywords[] = {
|
||||
[GSK_SL_TOKEN_CONST] = "const",
|
||||
[GSK_SL_TOKEN_BOOL] = "bool",
|
||||
@@ -1484,6 +1734,23 @@ gsk_sl_token_reader_read_identifier (GskSlTokenReader *reader,
|
||||
token->str = g_string_free (string, FALSE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_string_is_valid_identifier (const char *ident)
|
||||
{
|
||||
guint i;
|
||||
|
||||
if (!is_identifier_start (ident[0]))
|
||||
return FALSE;
|
||||
|
||||
for (i = 1; ident[i]; i++)
|
||||
{
|
||||
if (!is_identifier (ident[i]))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_token_init_from_identifier (GskSlToken *token,
|
||||
const char *ident)
|
||||
@@ -1518,6 +1785,16 @@ gsk_sl_token_init_from_identifier (GskSlToken *token,
|
||||
token->str = g_strdup (ident);
|
||||
}
|
||||
|
||||
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_NEWLINE)
|
||||
|| 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);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_tokenizer_read_token (GskSlTokenizer *tokenizer,
|
||||
GskSlToken *token)
|
||||
|
||||
@@ -265,11 +265,14 @@ struct _GskSlToken {
|
||||
};
|
||||
|
||||
void gsk_sl_token_clear (GskSlToken *token);
|
||||
void gsk_sl_token_copy (GskSlToken *dest,
|
||||
const GskSlToken *src);
|
||||
|
||||
gboolean gsk_sl_string_is_valid_identifier (const char *ident);
|
||||
void gsk_sl_token_init_from_identifier (GskSlToken *token,
|
||||
const char *ident);
|
||||
|
||||
gboolean gsk_sl_token_is_finite (const GskSlToken *token);
|
||||
gboolean gsk_sl_token_is_skipped (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);
|
||||
|
||||
@@ -34,6 +34,7 @@ gsk_private_sources = files([
|
||||
'gskprivate.c',
|
||||
'gskprofiler.c',
|
||||
'gskshaderbuilder.c',
|
||||
'gsksldefine.c',
|
||||
'gskslfunction.c',
|
||||
'gskslnode.c',
|
||||
'gskslpreprocessor.c',
|
||||
|
||||
44
gtk/glsl.c
44
gtk/glsl.c
@@ -132,6 +132,41 @@ usage (GOptionContext *ctx)
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
define (const gchar *option_name,
|
||||
const gchar *value,
|
||||
gpointer data,
|
||||
GError **error)
|
||||
{
|
||||
GskSlCompiler *compiler = data;
|
||||
char **tokens;
|
||||
gboolean result;
|
||||
|
||||
tokens = g_strsplit (value, "=", 2);
|
||||
|
||||
result = gsk_sl_compiler_add_define (compiler,
|
||||
tokens[0],
|
||||
tokens[1],
|
||||
error);
|
||||
|
||||
g_strfreev (tokens);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
undefine (const gchar *option_name,
|
||||
const gchar *value,
|
||||
gpointer data,
|
||||
GError **error)
|
||||
{
|
||||
GskSlCompiler *compiler = data;
|
||||
|
||||
gsk_sl_compiler_remove_define (compiler, value);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@@ -139,13 +174,16 @@ main (int argc, char *argv[])
|
||||
char **filenames = NULL;
|
||||
char *output_file = NULL;
|
||||
gboolean print = FALSE;
|
||||
GskSlCompiler *compiler;
|
||||
const GOptionEntry entries[] = {
|
||||
{ "define", 'D', 0, G_OPTION_ARG_CALLBACK, define, "Add a preprocssor definition", "NAME[=VALUE]" },
|
||||
{ "undef", 'U', 0, G_OPTION_ARG_CALLBACK, undefine, "Cancel previous preprocessor definition", "NAME" },
|
||||
{ "print", 'p', 0, G_OPTION_ARG_NONE, &print, "Print instead of compiling", NULL },
|
||||
{ "output", 'o', 0, G_OPTION_ARG_FILENAME, &output_file, "Output filename", "FILE" },
|
||||
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, "List of input files", "FILE [FILE...]" },
|
||||
{ NULL, }
|
||||
};
|
||||
GskSlCompiler *compiler;
|
||||
GOptionGroup *group;
|
||||
GError *error = NULL;
|
||||
GOutputStream *output;
|
||||
gboolean success = TRUE;
|
||||
@@ -157,7 +195,9 @@ main (int argc, char *argv[])
|
||||
|
||||
compiler = gsk_sl_compiler_new ();
|
||||
ctx = g_option_context_new (NULL);
|
||||
g_option_context_add_main_entries (ctx, entries, NULL);
|
||||
group = g_option_group_new (NULL, NULL, NULL, g_object_ref (compiler), g_object_unref);
|
||||
g_option_group_add_entries (group, entries);
|
||||
g_option_context_set_main_group (ctx, group);
|
||||
|
||||
if (!g_option_context_parse (ctx, &argc, &argv, &error))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user