GtkSharp/generator/Parser.cs
Dan Winship 622c360576 * parser/gapi2xml.pl (addFuncElems): if a struct or boxed type has
a constructor or a ref, unref, or destroy method, then it must be
	a reference type, so mark it "opaque" but then also mark all of
	its fields public and writable.

	* */*-api*.raw: Regen

	* generator/Parser.cs (ParseNamespace): make the opaque attribute
	check actually look at the value of the attribute rather than just
	checking if it's there, so that you can change a struct's opaque
	attribute from "true" to "false" via metadata and have that work.

	* generator/BoxedGen.cs (Generate): do not generate the boxed's
	"Free" method (since it's guaranteed to crash when we pass it a
	stack pointer). If "Copy" is marked deprecated, create a
	deprecated no-op for it, otherwise just skip it (since otherwise
	it will just leak memory when we copy its result onto the stack).

	* pango/Pango.metadata: deprecate Pango.Color.Copy and
	Pango.Matrix.Copy. Hide some array fields in Pango.GlyphString
	that we've never generated correctly. Tweak Pango.LayoutLine
	fields to be the same as they used to be.

	* pango/GlyphItem.custom (glyphs, item):
	* pango/GlyphString.custom (Zero, New):
	* pango/Item.custom (Zero, New):
	* pango/LayoutRun.custom (glyphs, item): add deprecated API compat

	* gdk/Gdk.metadata: undo the parser's new opaquification of
	Gdk.Font; it's been deprecated since pre-gtk# times, and no one
	should be using it, so there's no point in fixing it now. Fix up a
	few other things to match how they used to be. Fix RgbCmap's
	constructor args.

	* gdk/RgbCmap.custom (Zero, New): deprecated API compat

	* gdk/PangoAttrEmbossed.custom:
	* gdk/PangoAttrStipple.custom (Zero, New, Attr): deprecated API
	compat
	(explicit operator ...): allow casting back and forth between
	Pango.Attribute. (We can't usefully make them real subclasses of
	Pango.Attribute, because there's no way for
	Pango.Attribute.GetAttribute() to be able to dtrt with them.)

	* gtk/Gtk.metadata: deprecate Gtk.Requisition.Copy,
	Gtk.TextIter.Copy, and Gtk.TreeIter.Copy. Mark the return value of
	TextView.DefaultAttributes as "owned". Mark TargetList's fields
	private so it stays how it used to be.

	* gtk/TextAttributes.custom (Zero, New): deprecated API compat

	* gnomevfs/Gnomevfs.metadata: remove a bunch of opaque
	declarations that the parser figures out on its own now.

	* art/Art.metadata:
	* glade/Glade.metadata:
	* rsvg/Rsvg.metadata: un-mark everything the parser marked opaque
	in these libraries, because all of the structs in question would
	still be unusably broken, so the API churn would be pointless.

svn path=/trunk/gtk-sharp/; revision=48387
2005-08-15 15:15:57 +00:00

165 lines
4.5 KiB
C#

// GtkSharp.Generation.Parser.cs - The XML Parsing engine.
//
// Author: Mike Kestner <mkestner@speakeasy.net>
//
// Copyright (c) 2001-2003 Mike Kestner
// Copyright (c) 2003 Ximian Inc.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of version 2 of the GNU General Public
// License as published by the Free Software Foundation.
//
// This program 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
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this program; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
namespace GtkSharp.Generation {
using System;
using System.Collections;
using System.IO;
using System.Xml;
public class Parser {
private XmlDocument Load (string filename)
{
XmlDocument doc = new XmlDocument ();
try {
Stream stream = File.OpenRead (filename);
doc.Load (stream);
stream.Close ();
} catch (XmlException e) {
Console.WriteLine ("Invalid XML file.");
Console.WriteLine (e);
doc = null;
}
return doc;
}
public IGeneratable[] Parse (string filename)
{
XmlDocument doc = Load (filename);
if (doc == null)
return null;
XmlElement root = doc.DocumentElement;
if ((root == null) || !root.HasChildNodes) {
Console.WriteLine ("No Namespaces found.");
return null;
}
ArrayList gens = new ArrayList ();
foreach (XmlNode child in root.ChildNodes) {
XmlElement elem = child as XmlElement;
if (elem == null)
continue;
switch (child.Name) {
case "namespace":
gens.AddRange (ParseNamespace (elem));
break;
case "symbol":
gens.Add (ParseSymbol (elem));
break;
default:
Console.WriteLine ("Parser::Parse - Unexpected child node: " + child.Name);
break;
}
}
return (IGeneratable[]) gens.ToArray (typeof (IGeneratable));
}
private ArrayList ParseNamespace (XmlElement ns)
{
ArrayList result = new ArrayList ();
foreach (XmlNode def in ns.ChildNodes) {
XmlElement elem = def as XmlElement;
if (elem == null)
continue;
if (elem.HasAttribute("hidden"))
continue;
bool is_opaque = false;
if (elem.GetAttribute ("opaque") == "true" ||
elem.GetAttribute ("opaque") == "1")
is_opaque = true;
switch (def.Name) {
case "alias":
string aname = elem.GetAttribute("cname");
string atype = elem.GetAttribute("type");
if ((aname == "") || (atype == ""))
continue;
result.Add (new AliasGen (aname, atype));
break;
case "boxed":
result.Add (is_opaque ? new OpaqueGen (ns, elem) as object : new BoxedGen (ns, elem) as object);
break;
case "callback":
result.Add (new CallbackGen (ns, elem));
break;
case "enum":
result.Add (new EnumGen (ns, elem));
break;
case "interface":
result.Add (new InterfaceGen (ns, elem));
break;
case "object":
result.Add (new ObjectGen (ns, elem));
break;
case "class":
result.Add (new ClassGen (ns, elem));
break;
case "struct":
result.Add (is_opaque ? new OpaqueGen (ns, elem) as object : new StructGen (ns, elem) as object);
break;
default:
Console.WriteLine ("Parser::ParseNamespace - Unexpected node: " + def.Name);
break;
}
}
return result;
}
private IGeneratable ParseSymbol (XmlElement symbol)
{
string type = symbol.GetAttribute ("type");
string cname = symbol.GetAttribute ("cname");
string name = symbol.GetAttribute ("name");
IGeneratable result = null;
if (type == "simple")
result = new SimpleGen (cname, name);
else if (type == "manual")
result = new ManualGen (cname, name);
else if (type == "alias")
result = new AliasGen (cname, name);
else if (type == "marshal") {
string mtype = symbol.GetAttribute ("marshal_type");
string call = symbol.GetAttribute ("call_fmt");
string from = symbol.GetAttribute ("from_fmt");
result = new MarshalGen (cname, name, mtype, call, from);
} else
Console.WriteLine ("Parser::ParseSymbol - Unexpected symbol type " + type);
return result;
}
}
}