Main Page | Modules | Data Structures | Directories | File List | Data Fields | Related Pages

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

Generated on Fri Sep 30 19:45:35 2005 for D-BUS by  doxygen 1.4.4