3 * Copyright (C) 2007 Mathias Hasselmann
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 * Mathias Hasselmann <mathias.hasselmann@gmx.de>
25 class Vala
.VAPICheck
: Object
{
26 public VAPICheck (string gidlname
, CodeContext context
= new
CodeContext ()) {
27 gidl
= new
SourceFile (context
, gidlname
);
28 metadata
= new
SourceFile (context
, gidlname
.substring (0, gidlname
.len () - 5) + ".metadata");
29 this
.context
= context
;
32 public CodeContext context
{ get; construct; }
33 public SourceFile gidl
{ get; construct; }
34 public SourceFile metadata
{ get; construct; }
36 private List
<string> _scope
;
37 private Set
<string> _symbols
;
39 private void parse_gidl () {
40 _scope
= new ArrayList
<string> ();
41 _symbols
= new HashSet
<string> (str_hash
, str_equal
);
44 foreach (weak IdlModule module
in Idl
.parse_file (gidl
.filename
)) {
45 parse_members (module
.name
, module
.entries
);
47 } catch (MarkupError e
) {
48 stderr
.printf ("%s: %s\n", gidl
.filename
, e
.message
);
52 private void add_symbol (string name
, string? separator
= null) {
54 if (null != separator
) {
55 string fullname
= get_scope () + separator
+ name
;
56 _symbols
.add (fullname
);
62 private string get_scope () {
63 return _scope
[_scope
.size
- 1];
66 private void enter_scope (string name
) {
71 private void leave_scope () {
72 _scope
.remove_at (_scope
.size
- 1);
75 private void parse_members (string name
, GLib
.List
<IdlNode
> members
) {
78 foreach (weak IdlNode node
in members
) {
80 case IdlNodeTypeId
.ENUM
:
81 parse_members (((IdlNodeEnum
) node
).gtype_name
,
82 ((IdlNodeEnum
) node
).values
);
85 case IdlNodeTypeId
.FUNCTION
:
86 parse_members (((IdlNodeFunction
) node
).symbol
,
87 (GLib
.List
<IdlNode
>) ((IdlNodeFunction
) node
).parameters
);
90 case IdlNodeTypeId
.BOXED
:
91 parse_members (((IdlNodeBoxed
) node
).gtype_name
,
92 ((IdlNodeBoxed
) node
).members
);
95 case IdlNodeTypeId
.INTERFACE
:
96 case IdlNodeTypeId
.OBJECT
:
97 parse_members (((IdlNodeInterface
) node
).gtype_name
,
98 ((IdlNodeInterface
) node
).members
);
101 case IdlNodeTypeId
.FIELD
:
102 case IdlNodeTypeId
.PARAM
:
103 add_symbol (node
.name
, ".");
106 case IdlNodeTypeId
.PROPERTY
:
107 case IdlNodeTypeId
.SIGNAL
:
108 add_symbol (node
.name
, "::");
111 case IdlNodeTypeId
.STRUCT
:
112 parse_members (node
.name
, ((IdlNodeStruct
) node
).members
);
115 case IdlNodeTypeId
.VALUE
:
116 case IdlNodeTypeId
.VFUNC
:
121 warning ("TODO: %s: Implement support for type %d nodes", node
.name
, node
.type
);
129 private int check_metadata () {
131 var metafile
= new IOChannel
.file (metadata
.filename
, "r");
135 while (IOStatus
.NORMAL
== metafile
.read_line (out line
, null, null)) {
136 var tokens
= line
.split (" ", 2);
137 var symbol
= tokens
[0];
139 if (symbol
.size () > 0 && !_symbols
.contains (symbol
)) {
140 var src
= new
SourceReference (metadata
, lineno
, 1, lineno
, (int)symbol
.len ());
141 Report
.error (src
, "Symbol `%s' not found".printf (symbol
));
148 } catch (Error error
) {
149 Report
.error (null, "%s: %s".printf (metadata
.filename
, error
.message
));
155 if (!FileUtils
.test (gidl
.filename
, FileTest
.IS_REGULAR
)) {
156 Report
.error (null, "%s not found".printf (gidl
.filename
));
160 if (!FileUtils
.test (metadata
.filename
, FileTest
.IS_REGULAR
)) {
161 Report
.error (null, "%s not found".printf (metadata
.filename
));
167 return check_metadata ();
170 static int main (string[] args
) {
171 if (2 != args
.length
|| !args
[1].has_suffix (".gidl")) {
172 stdout
.printf ("Usage: %s library.gidl\n",
173 Path
.get_basename (args
[0]));
177 var vapicheck
= new
VAPICheck (args
[1]);
178 return vapicheck
.run ();