123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188(*
* oBus_introspect.ml
* ------------------
* Copyright : (c) 2008, Jeremie Dimino <jeremie@dimino.org>
* Licence : BSD3
*
* This file is a part of obus, an ocaml implementation of D-Bus.
*)openOBus_xml_parsertypename=stringtypeannotation=name*stringtypeargument=nameoption*OBus_value.T.singletypeaccess=Read|Write|Read_writetypemember=|Methodofname*argumentlist*argumentlist*annotationlist|Signalofname*argumentlist*annotationlist|Propertyofname*OBus_value.T.single*access*annotationlisttypeinterface=name*memberlist*annotationlisttypenode=OBus_path.elementtypedocument=interfacelist*nodelistexceptionParse_failure=OBus_xml_parser.Parse_failurelet()=Printexc.register_printer(function|Parse_failure((line,column),msg)->Some(Printf.sprintf"failed to parse D-Bus introspection document, at line %d, column %d: %s"linecolumnmsg)|_->None)letannotationsp=anyp(elt"annotation"(funp->letname=arp"name"inletvalue=arp"value"in(name,value)))typedirection=In|Outletatypep=letsignature=arp"type"inmatchOBus_value.signature_of_stringsignaturewith|[]->failwithp"empty signature"|[t]->t|_->Printf.ksprintf(failwithp)"this signature contains more than one single type: %S"signatureletargumentsp=anyp(elt"arg"(funp->letname=aop"name"inletdir=afdp"direction"In[("in",In);("out",Out)]inlettyp=atypepin(dir,(name,typ))))letmk_anametestp=letname=arp"name"inmatchtestnamewith|Someerror->failwithp(OBus_string.error_messageerror)|None->nameletamember=mk_anameOBus_name.validate_memberletanode=mk_anameOBus_path.validate_elementletainterface=mk_anameOBus_name.validate_interfaceletmethod_decl=elt"method"(funp->letname=amemberpinletargs=argumentspinletins,outs=OBus_util.split(function|(In,x)->OBus_util.InLx|(Out,x)->OBus_util.InRx)argsinletannots=annotationspin(Method(name,ins,outs,annots)))letsignal_decl=elt"signal"(funp->letname=amemberpinletargs=argumentspinletannots=annotationspin(Signal(name,List.mapsndargs,annots)))letproperty_decl=elt"property"(funp->letname=amemberpinletaccess=afrp"access"[("read",Read);("write",Write);("readwrite",Read_write)]inlettyp=atypepinletannots=annotationspin(Property(name,typ,access,annots)))letnode=elt"node"(funp->letname=anodepinmatchOBus_path.validate_elementnamewith|None->name|Someerror->failwithp(OBus_string.error_message{errorwithOBus_string.typ="node name"}))letinterface=elt"interface"(funp->letname=ainterfacepinletdecls=anyp(union[method_decl;signal_decl;property_decl])inletannots=annotationspin(name,decls,annots))letdocument=elt"node"(funp->letinterfs=anypinterfaceinletsubs=anypnodein(interfs,subs))letinputxi=OBus_xml_parser.inputxidocumenttypexml=Elementofstring*(string*string)list*xmllistletto_xml(ifaces,nodes)=letpannots=List.map(fun(n,v)->Element("annotation",[("name",n);("value",v)],[]))inletpargsdir=List.map(fun(n,t)->letattrs=[("type",OBus_value.string_of_signature[t])]inletattrs=matchdirwith|SomeIn->("direction","in")::attrs|SomeOut->("direction","out")::attrs|None->attrsinletattrs=matchnwith|Somen->("name",n)::attrs|None->attrsinElement("arg",attrs,[]))inElement("node",[],List.map(fun(name,content,annots)->Element("interface",[("name",name)],pannotsannots@List.map(function|Method(name,ins,outs,annots)->Element("method",[("name",name)],pargs(SomeIn)ins@pargs(SomeOut)outs@pannotsannots)|Signal(name,args,annots)->Element("signal",[("name",name)],pargsNoneargs@pannotsannots)|Property(name,typ,access,annots)->Element("property",[("name",name);("type",OBus_value.string_of_signature[typ]);("access",matchaccesswith|Read->"read"|Write->"write"|Read_write->"readwrite")],pannotsannots))content))ifaces@List.map(funn->Element("node",[("name",n)],[]))nodes)letoutputxodoc=letrecaux(Element(name,attrs,children))=Xmlm.outputxo(`El_start(("",name),List.map(fun(name,value)->(("",name),value))attrs));List.iterauxchildren;Xmlm.outputxo`El_endinXmlm.outputxo(`Dtd(Some"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n\
\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">"));aux(to_xmldoc)(* +-----------------------------------------------------------------+
| Annotations |
+-----------------------------------------------------------------+ *)letdeprecated="org.freedesktop.DBus.Deprecated"letcsymbol="org.freedesktop.DBus.GLib.CSymbol"letno_reply="org.freedesktop.DBus.Method.NoReply"letemits_changed_signal="org.freedesktop.DBus.Property.EmitsChangedSignal"