dfsm: Add all the missing API reference comments
[bendy-bus:bendy-bus.git] / dfsm / dfsm-ast-statement-throw.c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /*
3  * D-Bus Simulator
4  * Copyright (C) Philip Withnall 2011 <philip@tecnocode.co.uk>
5  * 
6  * D-Bus Simulator is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * D-Bus Simulator is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with D-Bus Simulator.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 /**
21  * SECTION:dfsm-ast-statement-throw
22  * @short_description: AST throw statement
23  * @stability: Unstable
24  * @include: dfsm/dfsm-ast-statement-throw.h
25  *
26  * AST throw statement implementation for supporting method replies with errors.
27  */
28
29 #include "config.h"
30
31 #include <glib.h>
32 #include <glib/gi18n-lib.h>
33
34 #include "dfsm-ast-statement-throw.h"
35 #include "dfsm-parser.h"
36 #include "dfsm-parser-internal.h"
37
38 static void dfsm_ast_statement_throw_finalize (GObject *object);
39 static void dfsm_ast_statement_throw_sanity_check (DfsmAstNode *node);
40 static void dfsm_ast_statement_throw_pre_check_and_register (DfsmAstNode *node, DfsmEnvironment *environment, GError **error);
41 static void dfsm_ast_statement_throw_execute (DfsmAstStatement *statement, DfsmEnvironment *environment, DfsmOutputSequence *output_sequence);
42
43 struct _DfsmAstStatementThrowPrivate {
44         gchar *error_name;
45 };
46
47 G_DEFINE_TYPE (DfsmAstStatementThrow, dfsm_ast_statement_throw, DFSM_TYPE_AST_STATEMENT)
48
49 static void
50 dfsm_ast_statement_throw_class_init (DfsmAstStatementThrowClass *klass)
51 {
52         GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
53         DfsmAstNodeClass *node_class = DFSM_AST_NODE_CLASS (klass);
54         DfsmAstStatementClass *statement_class = DFSM_AST_STATEMENT_CLASS (klass);
55
56         g_type_class_add_private (klass, sizeof (DfsmAstStatementThrowPrivate));
57
58         gobject_class->finalize = dfsm_ast_statement_throw_finalize;
59
60         node_class->sanity_check = dfsm_ast_statement_throw_sanity_check;
61         node_class->pre_check_and_register = dfsm_ast_statement_throw_pre_check_and_register;
62
63         statement_class->execute = dfsm_ast_statement_throw_execute;
64 }
65
66 static void
67 dfsm_ast_statement_throw_init (DfsmAstStatementThrow *self)
68 {
69         self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, DFSM_TYPE_AST_STATEMENT_THROW, DfsmAstStatementThrowPrivate);
70 }
71
72 static void
73 dfsm_ast_statement_throw_finalize (GObject *object)
74 {
75         DfsmAstStatementThrowPrivate *priv = DFSM_AST_STATEMENT_THROW (object)->priv;
76
77         g_free (priv->error_name);
78
79         /* Chain up to the parent class */
80         G_OBJECT_CLASS (dfsm_ast_statement_throw_parent_class)->finalize (object);
81 }
82
83 static void
84 dfsm_ast_statement_throw_sanity_check (DfsmAstNode *node)
85 {
86         DfsmAstStatementThrowPrivate *priv = DFSM_AST_STATEMENT_THROW (node)->priv;
87
88         g_assert (priv->error_name != NULL);
89 }
90
91 static void
92 dfsm_ast_statement_throw_pre_check_and_register (DfsmAstNode *node, DfsmEnvironment *environment, GError **error)
93 {
94         DfsmAstStatementThrowPrivate *priv = DFSM_AST_STATEMENT_THROW (node)->priv;
95
96         if (g_dbus_is_member_name (priv->error_name) == FALSE) {
97                 g_set_error (error, DFSM_PARSE_ERROR, DFSM_PARSE_ERROR_AST_INVALID, _("Invalid D-Bus error name: %s"), priv->error_name);
98                 return;
99         }
100
101         /* Whether the transition we're in is allowed to throw errors is checked by the transition itself, not us. */
102 }
103
104 static void
105 dfsm_ast_statement_throw_execute (DfsmAstStatement *statement, DfsmEnvironment *environment, DfsmOutputSequence *output_sequence)
106 {
107         DfsmAstStatementThrowPrivate *priv = DFSM_AST_STATEMENT_THROW (statement)->priv;
108         gchar *message;
109         GError *child_error = NULL;
110
111         message = g_strdup_printf (_("Error message generated by %s()."), G_STRFUNC);
112         g_dbus_error_set_dbus_error (&child_error, priv->error_name, message, NULL);
113         g_free (message);
114
115         dfsm_output_sequence_add_throw (output_sequence, child_error);
116
117         g_error_free (child_error);
118 }
119
120 /**
121  * dfsm_ast_statement_throw_new:
122  * @error_name: name of the D-Bus error to throw
123  *
124  * Create a new #DfsmAstStatement for throwing a D-Bus error of type @error_name.
125  *
126  * Return value: (transfer full): a new AST node
127  */
128 DfsmAstStatement *
129 dfsm_ast_statement_throw_new (const gchar *error_name)
130 {
131         DfsmAstStatementThrow *statement;
132         DfsmAstStatementThrowPrivate *priv;
133
134         g_return_val_if_fail (error_name != NULL && *error_name != '\0', NULL);
135
136         statement = g_object_new (DFSM_TYPE_AST_STATEMENT_THROW, NULL);
137         priv = statement->priv;
138
139         priv->error_name = g_strdup (error_name);
140
141         return DFSM_AST_STATEMENT (statement);
142 }