dbus-gparser.c

00001 /* -*- mode: C; c-file-style: "gnu" -*- */
00002 /* dbus-gparser.c parse DBus description files
00003  *
00004  * Copyright (C) 2003, 2005  Red Hat, Inc.
00005  *
00006  * Licensed under the Academic Free License version 2.1
00007  * 
00008  * This program is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  * 
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  */
00023 #include "dbus-gparser.h"
00024 #include "dbus/dbus-glib-lowlevel.h"
00025 #include "dbus-gidl.h"
00026 #include "dbus-gobject.h"
00027 #include "dbus/dbus-signature.h"
00028 #include <string.h>
00029 
00030 #include <libintl.h>
00031 #define _(x) gettext ((x))
00032 #define N_(x) x
00033 
00034 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00035 
00036 #define ELEMENT_IS(name) (strcmp (element_name, (name)) == 0)
00037 
00038 typedef struct
00039 {
00040   const char  *name;
00041   const char **retloc;
00042 } LocateAttr;
00043 
00044 static gboolean
00045 locate_attributes (const char  *element_name,
00046                    const char **attribute_names,
00047                    const char **attribute_values,
00048                    GError     **error,
00049                    const char  *first_attribute_name,
00050                    const char **first_attribute_retloc,
00051                    ...)
00052 {
00053   va_list args;
00054   const char *name;
00055   const char **retloc;
00056   int n_attrs;
00057 #define MAX_ATTRS 24
00058   LocateAttr attrs[MAX_ATTRS];
00059   gboolean retval;
00060   int i;
00061 
00062   g_return_val_if_fail (first_attribute_name != NULL, FALSE);
00063   g_return_val_if_fail (first_attribute_retloc != NULL, FALSE);
00064 
00065   retval = TRUE;
00066 
00067   n_attrs = 1;
00068   attrs[0].name = first_attribute_name;
00069   attrs[0].retloc = first_attribute_retloc;
00070   *first_attribute_retloc = NULL;
00071   
00072   va_start (args, first_attribute_retloc);
00073 
00074   name = va_arg (args, const char*);
00075   retloc = va_arg (args, const char**);
00076 
00077   while (name != NULL)
00078     {
00079       if (retloc == NULL)
00080         {
00081           va_end (args);
00082           return FALSE;
00083         }
00084 
00085       g_assert (n_attrs < MAX_ATTRS);
00086       
00087       attrs[n_attrs].name = name;
00088       attrs[n_attrs].retloc = retloc;
00089       n_attrs += 1;
00090       *retloc = NULL;      
00091 
00092       name = va_arg (args, const char*);
00093       retloc = va_arg (args, const char**);
00094     }
00095 
00096   va_end (args);
00097 
00098   if (!retval)
00099     return retval;
00100 
00101   i = 0;
00102   while (attribute_names[i])
00103     {
00104       int j;
00105       gboolean found;
00106 
00107       found = FALSE;
00108       j = 0;
00109       while (j < n_attrs)
00110         {
00111           if (strcmp (attrs[j].name, attribute_names[i]) == 0)
00112             {
00113               retloc = attrs[j].retloc;
00114 
00115               if (*retloc != NULL)
00116                 {
00117                   g_set_error (error,
00118                                G_MARKUP_ERROR,
00119                                G_MARKUP_ERROR_PARSE,
00120                                _("Attribute \"%s\" repeated twice on the same <%s> element"),
00121                                attrs[j].name, element_name);
00122                   retval = FALSE;
00123                   goto out;
00124                 }
00125 
00126               *retloc = attribute_values[i];
00127               found = TRUE;
00128             }
00129 
00130           ++j;
00131         }
00132 
00133       if (!found)
00134         {
00135           /* We want to passthrough namespaced XML nodes that we don't know anything about. */
00136           if (strchr (attribute_names[i], ':') == NULL)
00137             {
00138               g_set_error (error,
00139                            G_MARKUP_ERROR,
00140                            G_MARKUP_ERROR_PARSE,
00141                            _("Attribute \"%s\" is invalid on <%s> element in this context"),
00142                            attribute_names[i], element_name);
00143               retval = FALSE;
00144               goto out;
00145             }
00146         }
00147 
00148       ++i;
00149     }
00150 
00151  out:
00152   return retval;
00153 }
00154 
00155 #if 0
00156 static gboolean
00157 check_no_attributes (const char  *element_name,
00158                      const char **attribute_names,
00159                      const char **attribute_values,
00160                      GError     **error)
00161 {
00162   if (attribute_names[0] != NULL)
00163     {
00164       g_set_error (error,
00165                    G_MARKUP_ERROR,
00166                    G_MARKUP_ERROR_PARSE,
00167                    _("Attribute \"%s\" is invalid on <%s> element in this context"),
00168                    attribute_names[0], element_name);
00169       return FALSE;
00170     }
00171 
00172   return TRUE;
00173 }
00174 #endif
00175 
00176 struct Parser
00177 {
00178   int refcount;
00179 
00180   NodeInfo *result; /* Filled in when we pop the last node */
00181   GSList *node_stack;
00182   InterfaceInfo *interface;
00183   MethodInfo *method;
00184   SignalInfo *signal;
00185   PropertyInfo *property;
00186   ArgInfo *arg;
00187   gboolean in_annotation;
00188   guint unknown_namespaced_depth;
00189 };
00190 
00191 Parser*
00192 parser_new (void)
00193 {
00194   Parser *parser;
00195 
00196   parser = g_new0 (Parser, 1);
00197 
00198   parser->refcount = 1;
00199 
00200   return parser;
00201 }
00202 
00203 Parser *
00204 parser_ref (Parser *parser)
00205 {
00206   parser->refcount += 1;
00207 
00208   return parser;
00209 }
00210 
00211 void
00212 parser_unref (Parser *parser)
00213 {
00214   parser->refcount -= 1;
00215   if (parser->refcount == 0)
00216     {
00217       if (parser->result)
00218         node_info_unref (parser->result);
00219 
00220       g_free (parser);
00221     }
00222 }
00223 
00224 gboolean
00225 parser_check_doctype (Parser      *parser,
00226                       const char  *doctype,
00227                       GError     **error)
00228 {
00229   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
00230   
00231   if (strcmp (doctype, "node") != 0)
00232     {
00233       g_set_error (error,
00234                    G_MARKUP_ERROR,
00235                    G_MARKUP_ERROR_PARSE,
00236                    "D-BUS description file has the wrong document type %s, use node or interface",
00237                    doctype);
00238       return FALSE;
00239     }
00240   else
00241     return TRUE;
00242 }
00243 
00244 static gboolean
00245 parse_node (Parser      *parser,
00246             const char  *element_name,
00247             const char **attribute_names,
00248             const char **attribute_values,
00249             GError     **error)
00250 {
00251   const char *name;
00252   NodeInfo *node;
00253   
00254   if (parser->interface ||
00255       parser->method ||
00256       parser->signal ||
00257       parser->property ||
00258       parser->arg ||
00259       parser->in_annotation)
00260     {
00261       g_set_error (error, G_MARKUP_ERROR,
00262                    G_MARKUP_ERROR_PARSE,
00263                    _("Can't put <%s> element here"),
00264                    element_name);
00265       return FALSE;      
00266     }
00267 
00268   name = NULL;
00269   if (!locate_attributes (element_name, attribute_names,
00270                           attribute_values, error,
00271                           "name", &name,
00272                           NULL))
00273     return FALSE;
00274 
00275   /* Only the root node can have no name */
00276   if (parser->node_stack != NULL && name == NULL)
00277     {
00278       g_set_error (error, G_MARKUP_ERROR,
00279                    G_MARKUP_ERROR_PARSE,
00280                    _("\"%s\" attribute required on <%s> element "),
00281                    "name", element_name);
00282       return FALSE;
00283     }
00284 
00285   /* Root element name must be absolute */
00286   if (parser->node_stack == NULL && name && *name != '/')
00287     {
00288       g_set_error (error, G_MARKUP_ERROR,
00289                    G_MARKUP_ERROR_PARSE,
00290                    _("\"%s\" attribute on <%s> element must be an absolute object path, \"%s\" not OK"),
00291                    "name", element_name, name);
00292       return FALSE;
00293     }
00294 
00295   /* Other element names must not be absolute */
00296   if (parser->node_stack != NULL && name && *name == '/')
00297     {
00298       g_set_error (error, G_MARKUP_ERROR,
00299                    G_MARKUP_ERROR_PARSE,
00300                    _("\"%s\" attribute on <%s> element must not be an absolute object path, \"%s\" starts with /"),
00301                    "name", element_name, name);
00302       return FALSE;
00303     }
00304   
00305   node = node_info_new (name);
00306 
00307   if (parser->node_stack != NULL)
00308     {
00309       node_info_add_node (parser->node_stack->data,
00310                           node);
00311     }
00312   
00313   parser->node_stack = g_slist_prepend (parser->node_stack,
00314                                         node);
00315   
00316   return TRUE;
00317 }
00318 
00319 static gboolean
00320 parse_interface (Parser      *parser,
00321                  const char  *element_name,
00322                  const char **attribute_names,
00323                  const char **attribute_values,
00324                  GError     **error)
00325 {
00326   const char *name;
00327   InterfaceInfo *iface;
00328   NodeInfo *top;
00329   
00330   if (parser->interface ||
00331       parser->method ||
00332       parser->signal ||
00333       parser->property ||
00334       parser->arg ||
00335       parser->in_annotation ||
00336       (parser->node_stack == NULL))
00337     {
00338       g_set_error (error, G_MARKUP_ERROR,
00339                    G_MARKUP_ERROR_PARSE,
00340                    _("Can't put <%s> element here"),
00341                    element_name);
00342       return FALSE;      
00343     }
00344 
00345   name = NULL;
00346   if (!locate_attributes (element_name, attribute_names,
00347                           attribute_values, error,
00348                           "name", &name,
00349                           NULL))
00350     return FALSE;
00351 
00352   if (name == NULL)
00353     {
00354       g_set_error (error, G_MARKUP_ERROR,
00355                    G_MARKUP_ERROR_PARSE,
00356                    _("\"%s\" attribute required on <%s> element "),
00357                    "name", element_name);
00358       return FALSE;
00359     }
00360 
00361   top = parser->node_stack->data;
00362   
00363   iface = interface_info_new (name);
00364   node_info_add_interface (top, iface);
00365   interface_info_unref (iface);
00366 
00367   parser->interface = iface;
00368   
00369   return TRUE;
00370 }
00371 
00372 static gboolean
00373 parse_method (Parser      *parser,
00374               const char  *element_name,
00375               const char **attribute_names,
00376               const char **attribute_values,
00377               GError     **error)
00378 {
00379   const char *name;
00380   MethodInfo *method;
00381   
00382   if (parser->interface == NULL ||
00383       parser->node_stack == NULL ||
00384       parser->method ||
00385       parser->signal ||
00386       parser->property ||
00387       parser->in_annotation ||
00388       parser->arg)
00389     {
00390       g_set_error (error, G_MARKUP_ERROR,
00391                    G_MARKUP_ERROR_PARSE,
00392                    _("Can't put <%s> element here"),
00393                    element_name);
00394       return FALSE;      
00395     }
00396 
00397   name = NULL;
00398   if (!locate_attributes (element_name, attribute_names,
00399                           attribute_values, error,
00400                           "name", &name,
00401                           NULL))
00402     return FALSE;
00403 
00404   if (name == NULL)
00405     {
00406       g_set_error (error, G_MARKUP_ERROR,
00407                    G_MARKUP_ERROR_PARSE,
00408                    _("\"%s\" attribute required on <%s> element "),
00409                    "name", element_name);
00410       return FALSE;
00411     }
00412 
00413   method = method_info_new (name);
00414   interface_info_add_method (parser->interface, method);
00415   method_info_unref (method);
00416 
00417   parser->method = method;
00418   
00419   return TRUE;
00420 }
00421 
00422 static gboolean
00423 parse_signal (Parser      *parser,
00424               const char  *element_name,
00425               const char **attribute_names,
00426               const char **attribute_values,
00427               GError     **error)
00428 {
00429   const char *name;
00430   SignalInfo *signal;
00431   
00432   if (parser->interface == NULL ||
00433       parser->node_stack == NULL ||
00434       parser->signal ||
00435       parser->method ||
00436       parser->property ||
00437       parser->in_annotation ||
00438       parser->arg)
00439     {
00440       g_set_error (error, G_MARKUP_ERROR,
00441                    G_MARKUP_ERROR_PARSE,
00442                    _("Can't put <%s> element here"),
00443                    element_name);
00444       return FALSE;      
00445     }
00446 
00447   name = NULL;
00448   if (!locate_attributes (element_name, attribute_names,
00449                           attribute_values, error,
00450                           "name", &name,
00451                           NULL))
00452     return FALSE;
00453 
00454   if (name == NULL)
00455     {
00456       g_set_error (error, G_MARKUP_ERROR,
00457                    G_MARKUP_ERROR_PARSE,
00458                    _("\"%s\" attribute required on <%s> element "),
00459                    "name", element_name);
00460       return FALSE;
00461     }
00462 
00463   signal = signal_info_new (name);
00464   interface_info_add_signal (parser->interface, signal);
00465   signal_info_unref (signal);
00466 
00467   parser->signal = signal;
00468   
00469   return TRUE;
00470 }
00471 
00472 static gboolean
00473 validate_signature (const char *str,
00474                     const char *element_name,
00475                     GError    **error)
00476 {
00477   DBusError derror;
00478 
00479   dbus_error_init (&derror);
00480   
00481   if (!dbus_signature_validate (str, &derror))
00482     {
00483       dbus_set_g_error (error, &derror);
00484       return FALSE;
00485     }
00486   return TRUE;
00487 }
00488 
00489 static gboolean
00490 parse_property (Parser      *parser,
00491                 const char  *element_name,
00492                 const char **attribute_names,
00493                 const char **attribute_values,
00494                 GError     **error)
00495 {
00496   const char *name;
00497   const char *access;
00498   const char *type;
00499   PropertyInfo *property;
00500   PropertyAccessFlags access_flags;
00501   
00502   if (parser->interface == NULL ||
00503       parser->node_stack == NULL ||
00504       parser->signal ||
00505       parser->method ||
00506       parser->property ||
00507       parser->in_annotation ||
00508       parser->arg)
00509     {
00510       g_set_error (error, G_MARKUP_ERROR,
00511                    G_MARKUP_ERROR_PARSE,
00512                    _("Can't put <%s> element here"),
00513                    element_name);
00514       return FALSE;      
00515     }
00516 
00517   name = NULL;
00518   if (!locate_attributes (element_name, attribute_names,
00519                           attribute_values, error,
00520                           "name", &name,
00521                           "access", &access,
00522                           "type", &type,
00523                           NULL))
00524     return FALSE;
00525 
00526   if (name == NULL)
00527     {
00528       g_set_error (error, G_MARKUP_ERROR,
00529                    G_MARKUP_ERROR_PARSE,
00530                    _("\"%s\" attribute required on <%s> element "),
00531                    "name", element_name);
00532       return FALSE;
00533     }
00534 
00535   if (access == NULL)
00536     {
00537       g_set_error (error, G_MARKUP_ERROR,
00538                    G_MARKUP_ERROR_PARSE,
00539                    _("\"%s\" attribute required on <%s> element "),
00540                    "access", element_name);
00541       return FALSE;
00542     }
00543 
00544   if (type == NULL)
00545     {
00546       g_set_error (error, G_MARKUP_ERROR,
00547                    G_MARKUP_ERROR_PARSE,
00548                    _("\"%s\" attribute required on <%s> element "),
00549                    "type", element_name);
00550       return FALSE;
00551     }
00552 
00553   if (!validate_signature (type, element_name, error))
00554     return FALSE;
00555 
00556   access_flags = 0;
00557   if (strcmp (access, "readwrite") == 0)
00558     access_flags = PROPERTY_READ | PROPERTY_WRITE;
00559   else if (strcmp (access, "read") == 0)
00560     access_flags = PROPERTY_READ;
00561   else if (strcmp (access, "write") == 0)
00562     access_flags = PROPERTY_WRITE;
00563   else
00564     {
00565       g_set_error (error, G_MARKUP_ERROR,
00566                    G_MARKUP_ERROR_PARSE,
00567                    _("access=\"%s\" must have value readwrite, read, or write on %s\n"),
00568                    access, element_name);
00569       return FALSE;
00570     }
00571   
00572   property = property_info_new (name, type, access_flags);
00573   interface_info_add_property (parser->interface, property);
00574   property_info_unref (property);
00575 
00576   parser->property = property;
00577   
00578   return TRUE;
00579 }
00580 
00581 static gboolean
00582 parse_arg (Parser      *parser,
00583            const char  *element_name,
00584            const char **attribute_names,
00585            const char **attribute_values,
00586            GError     **error)
00587 {
00588   const char *name;
00589   const char *type;
00590   const char *direction;
00591   ArgDirection dir;
00592   ArgInfo *arg;
00593   char *generated_name;
00594   
00595   if (!(parser->method || parser->signal) ||
00596       parser->node_stack == NULL ||
00597       parser->property ||
00598       parser->in_annotation ||
00599       parser->arg)
00600     {
00601       g_set_error (error, G_MARKUP_ERROR,
00602                    G_MARKUP_ERROR_PARSE,
00603                    _("Can't put <%s> element here"),
00604                    element_name);
00605       return FALSE;      
00606     }
00607 
00608   name = NULL;
00609   if (!locate_attributes (element_name, attribute_names,
00610                           attribute_values, error,
00611                           "name", &name,
00612                           "type", &type,
00613                           "direction", &direction,
00614                           NULL))
00615     return FALSE;
00616 
00617   /* name can be null for args */
00618   
00619   if (type == NULL)
00620     {
00621       g_set_error (error, G_MARKUP_ERROR,
00622                    G_MARKUP_ERROR_PARSE,
00623                    _("\"%s\" attribute required on <%s> element "),
00624                    "type", element_name);
00625       return FALSE;
00626     }
00627 
00628   if (direction == NULL)
00629     {
00630       /* methods default to in, signal to out */
00631       if (parser->method)
00632         direction = "in";
00633       else if (parser->signal)
00634         direction = "out";
00635       else
00636         g_assert_not_reached ();
00637     }
00638 
00639   dir = ARG_INVALID;
00640   
00641   if (strcmp (direction, "in") == 0)
00642     dir = ARG_IN;
00643   else if (strcmp (direction, "out") == 0)
00644     dir = ARG_OUT;
00645   
00646   if (dir == ARG_INVALID ||
00647       (parser->signal && dir == ARG_IN))
00648     {
00649       if (parser->signal)
00650         g_set_error (error, G_MARKUP_ERROR,
00651                      G_MARKUP_ERROR_PARSE,
00652                      _("Signals must have direction=\"out\" (just omit the direction attribute)"));
00653       else
00654         g_set_error (error, G_MARKUP_ERROR,
00655                      G_MARKUP_ERROR_PARSE,
00656                      _("\"%s\" attribute on <%s> has value \"in\" or \"out\""),
00657                      "direction", element_name);
00658       return FALSE;
00659     }
00660 
00661   if (!validate_signature (type, element_name, error))
00662     return FALSE;
00663 
00664   generated_name = NULL;
00665   if (name == NULL)
00666     generated_name = g_strdup_printf ("arg%d",
00667                                       parser->method ?
00668                                       method_info_get_n_args (parser->method) :
00669                                       signal_info_get_n_args (parser->signal));
00670                                       
00671   arg = arg_info_new (name ? name : generated_name, dir, type);
00672   if (parser->method)
00673     method_info_add_arg (parser->method, arg);
00674   else if (parser->signal)
00675     signal_info_add_arg (parser->signal, arg);
00676   else
00677     g_assert_not_reached ();
00678 
00679   g_free (generated_name);
00680   
00681   arg_info_unref (arg);
00682 
00683   parser->arg = arg;
00684   
00685   return TRUE;
00686 }
00687 
00688 static gboolean
00689 parse_annotation (Parser      *parser,
00690                   const char  *element_name,
00691                   const char **attribute_names,
00692                   const char **attribute_values,
00693                   GError     **error)
00694 {
00695   const char *name;
00696   const char *value;
00697   
00698   if (!(parser->method || parser->interface || parser->arg) || 
00699       parser->node_stack == NULL ||
00700       parser->signal ||
00701       parser->property ||
00702       parser->in_annotation)
00703     {
00704       g_set_error (error, G_MARKUP_ERROR,
00705                    G_MARKUP_ERROR_PARSE,
00706                    _("Can't put <%s> element here"),
00707                    element_name);
00708       return FALSE;      
00709     }
00710 
00711   name = NULL;
00712   if (!locate_attributes (element_name, attribute_names,
00713                           attribute_values, error,
00714                           "name", &name,
00715                           "value", &value,
00716                           NULL))
00717     return FALSE;
00718 
00719   if (name == NULL)
00720     {
00721       g_set_error (error, G_MARKUP_ERROR,
00722                    G_MARKUP_ERROR_PARSE,
00723                    _("\"%s\" attribute required on <%s> element "),
00724                    "name", element_name);
00725       return FALSE;
00726     }
00727   if (value == NULL)
00728     {
00729       g_set_error (error, G_MARKUP_ERROR,
00730                    G_MARKUP_ERROR_PARSE,
00731                    _("\"%s\" attribute required on <%s> element "),
00732                    "value", element_name);
00733       return FALSE;
00734     }
00735 
00736   if (parser->arg)
00737     arg_info_add_annotation (parser->arg, name, value);
00738   else if (parser->method)
00739     method_info_add_annotation (parser->method, name, value);
00740   else if (parser->interface)
00741     interface_info_add_annotation (parser->interface, name, value);
00742   else
00743     g_assert_not_reached ();
00744 
00745   parser->in_annotation = TRUE;
00746 
00747   return TRUE;
00748 }
00749 
00750 gboolean
00751 parser_start_element (Parser      *parser,
00752                       const char  *element_name,
00753                       const char **attribute_names,
00754                       const char **attribute_values,
00755                       GError     **error)
00756 {
00757   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
00758 
00759   if (ELEMENT_IS ("node"))
00760     {
00761       if (!parse_node (parser, element_name, attribute_names,
00762                        attribute_values, error))
00763         return FALSE;
00764     }
00765   else if (ELEMENT_IS ("interface"))
00766     {
00767       if (!parse_interface (parser, element_name, attribute_names,
00768                             attribute_values, error))
00769         return FALSE;
00770     }
00771   else if (ELEMENT_IS ("method"))
00772     {
00773       if (!parse_method (parser, element_name, attribute_names,
00774                          attribute_values, error))
00775         return FALSE;
00776     }
00777   else if (ELEMENT_IS ("signal"))
00778     {
00779       if (!parse_signal (parser, element_name, attribute_names,
00780                          attribute_values, error))
00781         return FALSE;
00782     }
00783   else if (ELEMENT_IS ("property"))
00784     {
00785       if (!parse_property (parser, element_name, attribute_names,
00786                            attribute_values, error))
00787         return FALSE;
00788     }
00789   else if (ELEMENT_IS ("arg"))
00790     {
00791       if (!parse_arg (parser, element_name, attribute_names,
00792                       attribute_values, error))
00793         return FALSE;
00794     }
00795   else if (ELEMENT_IS ("annotation"))
00796     {
00797       if (!parse_annotation (parser, element_name, attribute_names,
00798                              attribute_values, error))
00799         return FALSE;
00800     }
00801   else
00802     {
00803       if (strchr (element_name, ':') != NULL)
00804         /* Passthrough XML-namespaced nodes */
00805         parser->unknown_namespaced_depth += 1;
00806       else if (parser->unknown_namespaced_depth == 0)
00807         {
00808           g_set_error (error, G_MARKUP_ERROR,
00809                        G_MARKUP_ERROR_PARSE,
00810                        _("Element <%s> not recognized"),
00811                        element_name);
00812           return FALSE;
00813         }
00814     }
00815   
00816   return TRUE;
00817 }
00818 
00819 gboolean
00820 parser_end_element (Parser      *parser,
00821                     const char  *element_name,
00822                     GError     **error)
00823 {
00824   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
00825 
00826   if (ELEMENT_IS ("interface"))
00827     {
00828       parser->interface = NULL;
00829     }
00830   else if (ELEMENT_IS ("method"))
00831     {
00832       parser->method = NULL;
00833     }
00834   else if (ELEMENT_IS ("signal"))
00835     {
00836       parser->signal = NULL;
00837     }
00838   else if (ELEMENT_IS ("property"))
00839     {
00840       parser->property = NULL;
00841     }
00842   else if (ELEMENT_IS ("arg"))
00843     {
00844       parser->arg = NULL;
00845     }
00846   else if (ELEMENT_IS ("annotation"))
00847     {
00848       parser->in_annotation = FALSE;
00849     }
00850   else if (ELEMENT_IS ("node"))
00851     {
00852       NodeInfo *top;
00853 
00854       g_assert (parser->node_stack != NULL);
00855       top = parser->node_stack->data;
00856 
00857       parser->node_stack = g_slist_remove (parser->node_stack,
00858                                            top);
00859 
00860       if (parser->node_stack == NULL)
00861         parser->result = top; /* We are done, store the result */      
00862     }
00863   else if (strchr (element_name, ':') != NULL)
00864     {
00865       /* Passthrough XML-namespaced nodes */
00866       parser->unknown_namespaced_depth -= 1;
00867     }
00868   else if (parser->unknown_namespaced_depth > 0)
00869     {
00870                 /* pass through unknown elements underneath a namespace */
00871     }
00872   else
00873     g_assert_not_reached (); /* should have had an error on start_element */
00874   
00875   return TRUE;
00876 }
00877 
00878 gboolean
00879 parser_content (Parser      *parser,
00880                 const char  *content,
00881                 int          len,
00882                 GError     **error)
00883 {
00884   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
00885 
00886   /* FIXME check that it's all whitespace */
00887   
00888   return TRUE;
00889 }
00890 
00891 gboolean
00892 parser_finished (Parser      *parser,
00893                  GError     **error)
00894 {
00895   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
00896 
00897   return TRUE;
00898 }
00899 
00900 NodeInfo*
00901 parser_get_nodes (Parser *parser)
00902 {
00903   return parser->result;
00904 }
00905 
00906 #endif /* DOXYGEN_SHOULD_SKIP_THIS */

Generated on Tue Feb 24 16:47:59 2009 for D-BUSGLibBindings by  doxygen 1.5.1