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           g_set_error (error,
00136                        G_MARKUP_ERROR,
00137                        G_MARKUP_ERROR_PARSE,
00138                        _("Attribute \"%s\" is invalid on <%s> element in this context"),
00139                        attribute_names[i], element_name);
00140           retval = FALSE;
00141           goto out;
00142         }
00143 
00144       ++i;
00145     }
00146 
00147  out:
00148   return retval;
00149 }
00150 
00151 #if 0
00152 static gboolean
00153 check_no_attributes (const char  *element_name,
00154                      const char **attribute_names,
00155                      const char **attribute_values,
00156                      GError     **error)
00157 {
00158   if (attribute_names[0] != NULL)
00159     {
00160       g_set_error (error,
00161                    G_MARKUP_ERROR,
00162                    G_MARKUP_ERROR_PARSE,
00163                    _("Attribute \"%s\" is invalid on <%s> element in this context"),
00164                    attribute_names[0], element_name);
00165       return FALSE;
00166     }
00167 
00168   return TRUE;
00169 }
00170 #endif
00171 
00172 struct Parser
00173 {
00174   int refcount;
00175 
00176   NodeInfo *result; /* Filled in when we pop the last node */
00177   GSList *node_stack;
00178   InterfaceInfo *interface;
00179   MethodInfo *method;
00180   SignalInfo *signal;
00181   PropertyInfo *property;
00182   ArgInfo *arg;
00183   gboolean in_annotation;
00184 };
00185 
00186 Parser*
00187 parser_new (void)
00188 {
00189   Parser *parser;
00190 
00191   parser = g_new0 (Parser, 1);
00192 
00193   parser->refcount = 1;
00194 
00195   return parser;
00196 }
00197 
00198 Parser *
00199 parser_ref (Parser *parser)
00200 {
00201   parser->refcount += 1;
00202 
00203   return parser;
00204 }
00205 
00206 void
00207 parser_unref (Parser *parser)
00208 {
00209   parser->refcount -= 1;
00210   if (parser->refcount == 0)
00211     {
00212       if (parser->result)
00213         node_info_unref (parser->result);
00214 
00215       g_free (parser);
00216     }
00217 }
00218 
00219 gboolean
00220 parser_check_doctype (Parser      *parser,
00221                       const char  *doctype,
00222                       GError     **error)
00223 {
00224   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
00225   
00226   if (strcmp (doctype, "node") != 0)
00227     {
00228       g_set_error (error,
00229                    G_MARKUP_ERROR,
00230                    G_MARKUP_ERROR_PARSE,
00231                    "D-BUS description file has the wrong document type %s, use node or interface",
00232                    doctype);
00233       return FALSE;
00234     }
00235   else
00236     return TRUE;
00237 }
00238 
00239 static gboolean
00240 parse_node (Parser      *parser,
00241             const char  *element_name,
00242             const char **attribute_names,
00243             const char **attribute_values,
00244             GError     **error)
00245 {
00246   const char *name;
00247   NodeInfo *node;
00248   
00249   if (parser->interface ||
00250       parser->method ||
00251       parser->signal ||
00252       parser->property ||
00253       parser->arg ||
00254       parser->in_annotation)
00255     {
00256       g_set_error (error, G_MARKUP_ERROR,
00257                    G_MARKUP_ERROR_PARSE,
00258                    _("Can't put <%s> element here"),
00259                    element_name);
00260       return FALSE;      
00261     }
00262 
00263   name = NULL;
00264   if (!locate_attributes (element_name, attribute_names,
00265                           attribute_values, error,
00266                           "name", &name,
00267                           NULL))
00268     return FALSE;
00269 
00270   /* Only the root node can have no name */
00271   if (parser->node_stack != NULL && name == NULL)
00272     {
00273       g_set_error (error, G_MARKUP_ERROR,
00274                    G_MARKUP_ERROR_PARSE,
00275                    _("\"%s\" attribute required on <%s> element "),
00276                    "name", element_name);
00277       return FALSE;
00278     }
00279 
00280   /* Root element name must be absolute */
00281   if (parser->node_stack == NULL && name && *name != '/')
00282     {
00283       g_set_error (error, G_MARKUP_ERROR,
00284                    G_MARKUP_ERROR_PARSE,
00285                    _("\"%s\" attribute on <%s> element must be an absolute object path, \"%s\" not OK"),
00286                    "name", element_name, name);
00287       return FALSE;
00288     }
00289 
00290   /* Other element names must not be absolute */
00291   if (parser->node_stack != NULL && name && *name == '/')
00292     {
00293       g_set_error (error, G_MARKUP_ERROR,
00294                    G_MARKUP_ERROR_PARSE,
00295                    _("\"%s\" attribute on <%s> element must not be an absolute object path, \"%s\" starts with /"),
00296                    "name", element_name, name);
00297       return FALSE;
00298     }
00299   
00300   node = node_info_new (name);
00301 
00302   if (parser->node_stack != NULL)
00303     {
00304       node_info_add_node (parser->node_stack->data,
00305                           node);
00306     }
00307   
00308   parser->node_stack = g_slist_prepend (parser->node_stack,
00309                                         node);
00310   
00311   return TRUE;
00312 }
00313 
00314 static gboolean
00315 parse_interface (Parser      *parser,
00316                  const char  *element_name,
00317                  const char **attribute_names,
00318                  const char **attribute_values,
00319                  GError     **error)
00320 {
00321   const char *name;
00322   InterfaceInfo *iface;
00323   NodeInfo *top;
00324   
00325   if (parser->interface ||
00326       parser->method ||
00327       parser->signal ||
00328       parser->property ||
00329       parser->arg ||
00330       parser->in_annotation ||
00331       (parser->node_stack == NULL))
00332     {
00333       g_set_error (error, G_MARKUP_ERROR,
00334                    G_MARKUP_ERROR_PARSE,
00335                    _("Can't put <%s> element here"),
00336                    element_name);
00337       return FALSE;      
00338     }
00339 
00340   name = NULL;
00341   if (!locate_attributes (element_name, attribute_names,
00342                           attribute_values, error,
00343                           "name", &name,
00344                           NULL))
00345     return FALSE;
00346 
00347   if (name == NULL)
00348     {
00349       g_set_error (error, G_MARKUP_ERROR,
00350                    G_MARKUP_ERROR_PARSE,
00351                    _("\"%s\" attribute required on <%s> element "),
00352                    "name", element_name);
00353       return FALSE;
00354     }
00355 
00356   top = parser->node_stack->data;
00357   
00358   iface = interface_info_new (name);
00359   node_info_add_interface (top, iface);
00360   interface_info_unref (iface);
00361 
00362   parser->interface = iface;
00363   
00364   return TRUE;
00365 }
00366 
00367 static gboolean
00368 parse_method (Parser      *parser,
00369               const char  *element_name,
00370               const char **attribute_names,
00371               const char **attribute_values,
00372               GError     **error)
00373 {
00374   const char *name;
00375   MethodInfo *method;
00376   
00377   if (parser->interface == NULL ||
00378       parser->node_stack == NULL ||
00379       parser->method ||
00380       parser->signal ||
00381       parser->property ||
00382       parser->in_annotation ||
00383       parser->arg)
00384     {
00385       g_set_error (error, G_MARKUP_ERROR,
00386                    G_MARKUP_ERROR_PARSE,
00387                    _("Can't put <%s> element here"),
00388                    element_name);
00389       return FALSE;      
00390     }
00391 
00392   name = NULL;
00393   if (!locate_attributes (element_name, attribute_names,
00394                           attribute_values, error,
00395                           "name", &name,
00396                           NULL))
00397     return FALSE;
00398 
00399   if (name == NULL)
00400     {
00401       g_set_error (error, G_MARKUP_ERROR,
00402                    G_MARKUP_ERROR_PARSE,
00403                    _("\"%s\" attribute required on <%s> element "),
00404                    "name", element_name);
00405       return FALSE;
00406     }
00407 
00408   method = method_info_new (name);
00409   interface_info_add_method (parser->interface, method);
00410   method_info_unref (method);
00411 
00412   parser->method = method;
00413   
00414   return TRUE;
00415 }
00416 
00417 static gboolean
00418 parse_signal (Parser      *parser,
00419               const char  *element_name,
00420               const char **attribute_names,
00421               const char **attribute_values,
00422               GError     **error)
00423 {
00424   const char *name;
00425   SignalInfo *signal;
00426   
00427   if (parser->interface == NULL ||
00428       parser->node_stack == NULL ||
00429       parser->signal ||
00430       parser->method ||
00431       parser->property ||
00432       parser->in_annotation ||
00433       parser->arg)
00434     {
00435       g_set_error (error, G_MARKUP_ERROR,
00436                    G_MARKUP_ERROR_PARSE,
00437                    _("Can't put <%s> element here"),
00438                    element_name);
00439       return FALSE;      
00440     }
00441 
00442   name = NULL;
00443   if (!locate_attributes (element_name, attribute_names,
00444                           attribute_values, error,
00445                           "name", &name,
00446                           NULL))
00447     return FALSE;
00448 
00449   if (name == NULL)
00450     {
00451       g_set_error (error, G_MARKUP_ERROR,
00452                    G_MARKUP_ERROR_PARSE,
00453                    _("\"%s\" attribute required on <%s> element "),
00454                    "name", element_name);
00455       return FALSE;
00456     }
00457 
00458   signal = signal_info_new (name);
00459   interface_info_add_signal (parser->interface, signal);
00460   signal_info_unref (signal);
00461 
00462   parser->signal = signal;
00463   
00464   return TRUE;
00465 }
00466 
00467 static gboolean
00468 validate_signature (const char *str,
00469                     const char *element_name,
00470                     GError    **error)
00471 {
00472   DBusError derror;
00473 
00474   dbus_error_init (&derror);
00475   
00476   if (!dbus_signature_validate (str, &derror))
00477     {
00478       dbus_set_g_error (error, &derror);
00479       return FALSE;
00480     }
00481   return TRUE;
00482 }
00483 
00484 static gboolean
00485 parse_property (Parser      *parser,
00486                 const char  *element_name,
00487                 const char **attribute_names,
00488                 const char **attribute_values,
00489                 GError     **error)
00490 {
00491   const char *name;
00492   const char *access;
00493   const char *type;
00494   PropertyInfo *property;
00495   PropertyAccessFlags access_flags;
00496   
00497   if (parser->interface == NULL ||
00498       parser->node_stack == NULL ||
00499       parser->signal ||
00500       parser->method ||
00501       parser->property ||
00502       parser->in_annotation ||
00503       parser->arg)
00504     {
00505       g_set_error (error, G_MARKUP_ERROR,
00506                    G_MARKUP_ERROR_PARSE,
00507                    _("Can't put <%s> element here"),
00508                    element_name);
00509       return FALSE;      
00510     }
00511 
00512   name = NULL;
00513   if (!locate_attributes (element_name, attribute_names,
00514                           attribute_values, error,
00515                           "name", &name,
00516                           "access", &access,
00517                           "type", &type,
00518                           NULL))
00519     return FALSE;
00520 
00521   if (name == NULL)
00522     {
00523       g_set_error (error, G_MARKUP_ERROR,
00524                    G_MARKUP_ERROR_PARSE,
00525                    _("\"%s\" attribute required on <%s> element "),
00526                    "name", element_name);
00527       return FALSE;
00528     }
00529 
00530   if (access == NULL)
00531     {
00532       g_set_error (error, G_MARKUP_ERROR,
00533                    G_MARKUP_ERROR_PARSE,
00534                    _("\"%s\" attribute required on <%s> element "),
00535                    "access", element_name);
00536       return FALSE;
00537     }
00538 
00539   if (type == NULL)
00540     {
00541       g_set_error (error, G_MARKUP_ERROR,
00542                    G_MARKUP_ERROR_PARSE,
00543                    _("\"%s\" attribute required on <%s> element "),
00544                    "type", element_name);
00545       return FALSE;
00546     }
00547 
00548   if (!validate_signature (type, element_name, error))
00549     return FALSE;
00550 
00551   access_flags = 0;
00552   if (strcmp (access, "readwrite") == 0)
00553     access_flags = PROPERTY_READ | PROPERTY_WRITE;
00554   else if (strcmp (access, "read") == 0)
00555     access_flags = PROPERTY_READ;
00556   else if (strcmp (access, "write") == 0)
00557     access_flags = PROPERTY_WRITE;
00558   else
00559     {
00560       g_set_error (error, G_MARKUP_ERROR,
00561                    G_MARKUP_ERROR_PARSE,
00562                    _("access=\"%s\" must have value readwrite, read, or write on %s\n"),
00563                    access, element_name);
00564       return FALSE;
00565     }
00566   
00567   property = property_info_new (name, type, access_flags);
00568   interface_info_add_property (parser->interface, property);
00569   property_info_unref (property);
00570 
00571   parser->property = property;
00572   
00573   return TRUE;
00574 }
00575 
00576 static gboolean
00577 parse_arg (Parser      *parser,
00578            const char  *element_name,
00579            const char **attribute_names,
00580            const char **attribute_values,
00581            GError     **error)
00582 {
00583   const char *name;
00584   const char *type;
00585   const char *direction;
00586   ArgDirection dir;
00587   ArgInfo *arg;
00588   char *generated_name;
00589   
00590   if (!(parser->method || parser->signal) ||
00591       parser->node_stack == NULL ||
00592       parser->property ||
00593       parser->in_annotation ||
00594       parser->arg)
00595     {
00596       g_set_error (error, G_MARKUP_ERROR,
00597                    G_MARKUP_ERROR_PARSE,
00598                    _("Can't put <%s> element here"),
00599                    element_name);
00600       return FALSE;      
00601     }
00602 
00603   name = NULL;
00604   if (!locate_attributes (element_name, attribute_names,
00605                           attribute_values, error,
00606                           "name", &name,
00607                           "type", &type,
00608                           "direction", &direction,
00609                           NULL))
00610     return FALSE;
00611 
00612   /* name can be null for args */
00613   
00614   if (type == NULL)
00615     {
00616       g_set_error (error, G_MARKUP_ERROR,
00617                    G_MARKUP_ERROR_PARSE,
00618                    _("\"%s\" attribute required on <%s> element "),
00619                    "type", element_name);
00620       return FALSE;
00621     }
00622 
00623   if (direction == NULL)
00624     {
00625       /* methods default to in, signal to out */
00626       if (parser->method)
00627         direction = "in";
00628       else if (parser->signal)
00629         direction = "out";
00630       else
00631         g_assert_not_reached ();
00632     }
00633 
00634   dir = ARG_INVALID;
00635   
00636   if (strcmp (direction, "in") == 0)
00637     dir = ARG_IN;
00638   else if (strcmp (direction, "out") == 0)
00639     dir = ARG_OUT;
00640   
00641   if (dir == ARG_INVALID ||
00642       (parser->signal && dir == ARG_IN))
00643     {
00644       if (parser->signal)
00645         g_set_error (error, G_MARKUP_ERROR,
00646                      G_MARKUP_ERROR_PARSE,
00647                      _("Signals must have direction=\"out\" (just omit the direction attribute)"));
00648       else
00649         g_set_error (error, G_MARKUP_ERROR,
00650                      G_MARKUP_ERROR_PARSE,
00651                      _("\"%s\" attribute on <%s> has value \"in\" or \"out\""),
00652                      "direction", element_name);
00653       return FALSE;
00654     }
00655 
00656   if (!validate_signature (type, element_name, error))
00657     return FALSE;
00658 
00659   generated_name = NULL;
00660   if (name == NULL)
00661     generated_name = g_strdup_printf ("arg%d",
00662                                       parser->method ?
00663                                       method_info_get_n_args (parser->method) :
00664                                       signal_info_get_n_args (parser->signal));
00665                                       
00666   arg = arg_info_new (name ? name : generated_name, dir, type);
00667   if (parser->method)
00668     method_info_add_arg (parser->method, arg);
00669   else if (parser->signal)
00670     signal_info_add_arg (parser->signal, arg);
00671   else
00672     g_assert_not_reached ();
00673 
00674   g_free (generated_name);
00675   
00676   arg_info_unref (arg);
00677 
00678   parser->arg = arg;
00679   
00680   return TRUE;
00681 }
00682 
00683 static gboolean
00684 parse_annotation (Parser      *parser,
00685                   const char  *element_name,
00686                   const char **attribute_names,
00687                   const char **attribute_values,
00688                   GError     **error)
00689 {
00690   const char *name;
00691   const char *value;
00692   
00693   if (!(parser->method || parser->interface || parser->arg) || 
00694       parser->node_stack == NULL ||
00695       parser->signal ||
00696       parser->property ||
00697       parser->in_annotation)
00698     {
00699       g_set_error (error, G_MARKUP_ERROR,
00700                    G_MARKUP_ERROR_PARSE,
00701                    _("Can't put <%s> element here"),
00702                    element_name);
00703       return FALSE;      
00704     }
00705 
00706   name = NULL;
00707   if (!locate_attributes (element_name, attribute_names,
00708                           attribute_values, error,
00709                           "name", &name,
00710                           "value", &value,
00711                           NULL))
00712     return FALSE;
00713 
00714   if (name == NULL)
00715     {
00716       g_set_error (error, G_MARKUP_ERROR,
00717                    G_MARKUP_ERROR_PARSE,
00718                    _("\"%s\" attribute required on <%s> element "),
00719                    "name", element_name);
00720       return FALSE;
00721     }
00722   if (value == NULL)
00723     {
00724       g_set_error (error, G_MARKUP_ERROR,
00725                    G_MARKUP_ERROR_PARSE,
00726                    _("\"%s\" attribute required on <%s> element "),
00727                    "value", element_name);
00728       return FALSE;
00729     }
00730 
00731   if (parser->arg)
00732     arg_info_add_annotation (parser->arg, name, value);
00733   else if (parser->method)
00734     method_info_add_annotation (parser->method, name, value);
00735   else if (parser->interface)
00736     interface_info_add_annotation (parser->interface, name, value);
00737   else
00738     g_assert_not_reached ();
00739 
00740   parser->in_annotation = TRUE;
00741 
00742   return TRUE;
00743 }
00744 
00745 gboolean
00746 parser_start_element (Parser      *parser,
00747                       const char  *element_name,
00748                       const char **attribute_names,
00749                       const char **attribute_values,
00750                       GError     **error)
00751 {
00752   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
00753 
00754   if (ELEMENT_IS ("node"))
00755     {
00756       if (!parse_node (parser, element_name, attribute_names,
00757                        attribute_values, error))
00758         return FALSE;
00759     }
00760   else if (ELEMENT_IS ("interface"))
00761     {
00762       if (!parse_interface (parser, element_name, attribute_names,
00763                             attribute_values, error))
00764         return FALSE;
00765     }
00766   else if (ELEMENT_IS ("method"))
00767     {
00768       if (!parse_method (parser, element_name, attribute_names,
00769                          attribute_values, error))
00770         return FALSE;
00771     }
00772   else if (ELEMENT_IS ("signal"))
00773     {
00774       if (!parse_signal (parser, element_name, attribute_names,
00775                          attribute_values, error))
00776         return FALSE;
00777     }
00778   else if (ELEMENT_IS ("property"))
00779     {
00780       if (!parse_property (parser, element_name, attribute_names,
00781                            attribute_values, error))
00782         return FALSE;
00783     }
00784   else if (ELEMENT_IS ("arg"))
00785     {
00786       if (!parse_arg (parser, element_name, attribute_names,
00787                       attribute_values, error))
00788         return FALSE;
00789     }
00790   else if (ELEMENT_IS ("annotation"))
00791     {
00792       if (!parse_annotation (parser, element_name, attribute_names,
00793                              attribute_values, error))
00794         return FALSE;
00795     }
00796   else
00797     {
00798       g_set_error (error, G_MARKUP_ERROR,
00799                    G_MARKUP_ERROR_PARSE,
00800                    _("Element <%s> not recognized"),
00801                    element_name);
00802     }
00803   
00804   return TRUE;
00805 }
00806 
00807 gboolean
00808 parser_end_element (Parser      *parser,
00809                     const char  *element_name,
00810                     GError     **error)
00811 {
00812   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
00813 
00814   if (ELEMENT_IS ("interface"))
00815     {
00816       parser->interface = NULL;
00817     }
00818   else if (ELEMENT_IS ("method"))
00819     {
00820       parser->method = NULL;
00821     }
00822   else if (ELEMENT_IS ("signal"))
00823     {
00824       parser->signal = NULL;
00825     }
00826   else if (ELEMENT_IS ("property"))
00827     {
00828       parser->property = NULL;
00829     }
00830   else if (ELEMENT_IS ("arg"))
00831     {
00832       parser->arg = NULL;
00833     }
00834   else if (ELEMENT_IS ("annotation"))
00835     {
00836       parser->in_annotation = FALSE;
00837     }
00838   else if (ELEMENT_IS ("node"))
00839     {
00840       NodeInfo *top;
00841 
00842       g_assert (parser->node_stack != NULL);
00843       top = parser->node_stack->data;
00844 
00845       parser->node_stack = g_slist_remove (parser->node_stack,
00846                                            top);
00847 
00848       if (parser->node_stack == NULL)
00849         parser->result = top; /* We are done, store the result */      
00850     }
00851   else
00852     g_assert_not_reached (); /* should have had an error on start_element */
00853   
00854   return TRUE;
00855 }
00856 
00857 gboolean
00858 parser_content (Parser      *parser,
00859                 const char  *content,
00860                 int          len,
00861                 GError     **error)
00862 {
00863   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
00864 
00865   /* FIXME check that it's all whitespace */
00866   
00867   return TRUE;
00868 }
00869 
00870 gboolean
00871 parser_finished (Parser      *parser,
00872                  GError     **error)
00873 {
00874   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
00875 
00876   return TRUE;
00877 }
00878 
00879 NodeInfo*
00880 parser_get_nodes (Parser *parser)
00881 {
00882   return parser->result;
00883 }
00884 
00885 #endif /* DOXYGEN_SHOULD_SKIP_THIS */

Generated on Mon Mar 17 16:28:48 2008 for D-BUSGLibBindings by  doxygen 1.5.1