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

Generated on Wed Oct 3 10:04:23 2007 for D-BUSGLibBindings by  doxygen 1.5.1