Example #1
0
static xmlNodePtr
find_schema_subnode_by_locale(xmlNodePtr node, const gchar* locale)
{
  xmlNodePtr iter;
  xmlNodePtr found = NULL;
    
  iter = node->xmlChildrenNode;
      
  while (iter != NULL)
    {
      if (iter->type == XML_ELEMENT_NODE &&
          strcmp((char *)iter->name, "local_schema") == 0)
        {
          char* this_locale = my_xmlGetProp(iter, "locale");
          
          if (locale && this_locale &&
              strcmp(locale, this_locale) == 0)
            {
              found = iter;
              xmlFree(this_locale);
              break;
            }
          else if (this_locale == NULL &&
                   locale == NULL)
            {
              found = iter;
              break;
            }
          else if (this_locale != NULL)
            xmlFree(this_locale);
        }
      iter = iter->next;
    }

  return found;
}
Example #2
0
static void
dir_fill_cache_from_doc(Dir* d)
{
  xmlNodePtr node;
  
  if (d->doc == NULL ||
      d->doc->xmlRootNode == NULL ||
      d->doc->xmlRootNode->xmlChildrenNode == NULL)
    {
      /* Empty document - just return. */
      return;
    }

  node = d->doc->xmlRootNode->xmlChildrenNode;

  while (node != NULL)
    {
      if (node->type == XML_ELEMENT_NODE && 
          (strcmp((xmlChar *)node->name, "entry") == 0))
        {
          gchar* attr = my_xmlGetProp(node, "name");

          if (attr != NULL)
            {
              if (g_hash_table_lookup(d->entry_cache, attr) != NULL)
                {
                  gconf_log(GCL_WARNING,
                             _("Duplicate entry `%s' in `%s', ignoring"),
                             attr, d->xml_filename);
                }
              else
                {
                  Entry* e;
                  
                  e = entry_new(attr);

                  entry_set_node(e, node);
                  
                  entry_fill_from_node(e);
                  
                  safe_g_hash_table_insert(d->entry_cache,
                                           (gchar*)entry_get_name(e), e);
                }

              free(attr);
            }
          else
            {
              gconf_log(GCL_WARNING,
                         _("Entry with no name in XML file `%s', ignoring"),
                         d->xml_filename);
            }
        }
      else
        {
          if (node->type == XML_ELEMENT_NODE)
            gconf_log(GCL_WARNING,
                      _("A toplevel node in XML file `%s' is <%s> rather than <entry>, ignoring"),
                      d->xml_filename,
                      node->name ? (char*) node->name : "unknown");
        }
      
      node = node->next;
    }
}
Example #3
0
/* this actually works on any node,
   not just <entry>, such as the <car>
   and <cdr> nodes and the <li> nodes and the
   <default> node
*/
static GConfValue*
node_extract_value(xmlNodePtr node, const gchar** locales, GError** err)
{
  GConfValue* value = NULL;
  gchar* type_str;
  GConfValueType type = GCONF_VALUE_INVALID;
  const gchar* default_locales[] = { "C", NULL };
  
  if (locales == NULL)
    locales = default_locales;
  
  type_str = my_xmlGetProp(node, "type");

  if (type_str == NULL)
    {
      gconf_set_error(err, GCONF_ERROR_PARSE_ERROR,
                      _("No \"type\" attribute for <%s> node"),
                      (node->name ? (char*)node->name : "(nil)"));
      return NULL;
    }
      
  type = gconf_value_type_from_string(type_str);

  xmlFree(type_str);
  
  switch (type)
    {
    case GCONF_VALUE_INVALID:
      {
        gconf_set_error(err, GCONF_ERROR_PARSE_ERROR,
                        _("A node has unknown \"type\" attribute `%s', ignoring"), type_str);
        return NULL;
      }
      break;
    case GCONF_VALUE_INT:
    case GCONF_VALUE_BOOL:
    case GCONF_VALUE_FLOAT:
      {
        gchar* value_str;
        
        value_str = my_xmlGetProp(node, "value");
        
        if (value_str == NULL)
          {
            gconf_set_error(err, GCONF_ERROR_PARSE_ERROR,
                            _("No \"value\" attribute for node"));
            return NULL;
          }
            
        value = gconf_value_new_from_string(type, value_str, err);

        xmlFree(value_str);

        g_return_val_if_fail( (value != NULL) ||
                              (err == NULL) ||
                              (*err != NULL),
                              NULL );
        
        return value;
      }
      break;
    case GCONF_VALUE_STRING:
      {
        xmlNodePtr iter;
        
        iter = node->xmlChildrenNode;

        while (iter != NULL)
          {
            if (iter->type == XML_ELEMENT_NODE)
              {
                GConfValue* v = NULL;

                if (strcmp((char *)iter->name, "stringvalue") == 0)
                  {
                    gchar* s;

                    s = (gchar *)xmlNodeGetContent(iter);

                    v = gconf_value_new(GCONF_VALUE_STRING);

                    /* strdup() caused purely by g_free()/free()
                       difference */
                    gconf_value_set_string(v, s ? s : "");
                    if (s)
                      xmlFree(s);
                        
                    return v;
                  }
                else
                  {
                    /* What the hell is this? */
                    gconf_log(GCL_WARNING,
                              _("Didn't understand XML node <%s> inside an XML list node"),
                              iter->name ? iter->name : (guchar*)"???");
                  }
              }
            iter = iter->next;
          }
        return NULL;
      }
      break;      
    case GCONF_VALUE_SCHEMA:
      return schema_node_extract_value(node, locales);
      break;
    case GCONF_VALUE_LIST:
      {
        xmlNodePtr iter;
        GSList* values = NULL;
        GConfValueType list_type = GCONF_VALUE_INVALID;

        {
          gchar* s;
          s = my_xmlGetProp(node, "ltype");
          if (s != NULL)
            {
              list_type = gconf_value_type_from_string(s);
              xmlFree(s);
            }
        }

        switch (list_type)
          {
          case GCONF_VALUE_INVALID:
          case GCONF_VALUE_LIST:
          case GCONF_VALUE_PAIR:
            gconf_set_error(err, GCONF_ERROR_PARSE_ERROR,
                            _("Invalid type (list, pair, or unknown) in a list node"));
              
            return NULL;
          default:
            break;
          }
        
        iter = node->xmlChildrenNode;

        while (iter != NULL)
          {
            if (iter->type == XML_ELEMENT_NODE)
              {
                GConfValue* v = NULL;
                if (strcmp((char*)iter->name, "li") == 0)
                  {
                    
                    v = node_extract_value(iter, locales, err);
                    if (v == NULL)
                      {
                        if (err && *err)
                          {
                            gconf_log(GCL_WARNING,
                                      _("Bad XML node: %s"),
                                      (*err)->message);
                            /* avoid pile-ups */
                            g_clear_error(err);
                          }
                      }
                    else if (v->type != list_type)
                      {
                        gconf_log(GCL_WARNING, _("List contains a badly-typed node (%s, should be %s)"),
                                  gconf_value_type_to_string(v->type),
                                  gconf_value_type_to_string(list_type));
                        gconf_value_free(v);
                        v = NULL;
                      }
                  }
                else
                  {
                    /* What the hell is this? */
                    gconf_log(GCL_WARNING,
                              _("Didn't understand XML node <%s> inside an XML list node"),
                              iter->name ? iter->name : (guchar*)"???");
                  }

                if (v != NULL)
                  values = g_slist_prepend(values, v);
              }
            iter = iter->next;
          }
        
        /* put them in order, set the value */
        values = g_slist_reverse(values);

        value = gconf_value_new(GCONF_VALUE_LIST);

        gconf_value_set_list_type(value, list_type);
        gconf_value_set_list_nocopy(value, values);

        return value;
      }
      break;
    case GCONF_VALUE_PAIR:
      {
        GConfValue* car = NULL;
        GConfValue* cdr = NULL;
        xmlNodePtr iter;
        
        iter = node->xmlChildrenNode;

        while (iter != NULL)
          {
            if (iter->type == XML_ELEMENT_NODE)
              {
                if (car == NULL && strcmp((char *)iter->name, "car") == 0)
                  {
                    car = node_extract_value(iter, locales, err);
                    if (car == NULL)
                      {
                        if (err && *err)
                          {
                            gconf_log(GCL_WARNING,
                                      _("Ignoring bad car from XML pair: %s"),
                                      (*err)->message);
                            /* prevent pile-ups */
                            g_clear_error(err);
                          }
                      }
                    else if (car->type == GCONF_VALUE_LIST ||
                             car->type == GCONF_VALUE_PAIR)
                      {
                        gconf_log(GCL_WARNING, _("parsing XML file: lists and pairs may not be placed inside a pair"));
                        gconf_value_free(car);
                        car = NULL;
                      }
                  }
                else if (cdr == NULL && strcmp((char *)iter->name, "cdr") == 0)
                  {
                    cdr = node_extract_value(iter, locales, err);
                    if (cdr == NULL)
                      {
                        if (err && *err)
                          {
                            gconf_log(GCL_WARNING,
                                      _("Ignoring bad cdr from XML pair: %s"),
                                      (*err)->message);
                            /* avoid pile-ups */
                            g_clear_error(err);
                          }
                      }
                    else if (cdr->type == GCONF_VALUE_LIST ||
                             cdr->type == GCONF_VALUE_PAIR)
                      {
                        gconf_log(GCL_WARNING,
                                  _("parsing XML file: lists and pairs may not be placed inside a pair"));
                        gconf_value_free(cdr);
                        cdr = NULL;
                      }
                  }
                else
                  {
                    /* What the hell is this? */
                    gconf_log(GCL_WARNING,
                              _("Didn't understand XML node <%s> inside an XML pair node"),
                              iter->name ? (gchar*)iter->name : "???");                    
                  }
              }
            iter = iter->next;
          }

        /* Return the pair if we got both halves */
        if (car && cdr)
          {
            value = gconf_value_new(GCONF_VALUE_PAIR);
            gconf_value_set_car_nocopy(value, car);
            gconf_value_set_cdr_nocopy(value, cdr);

            return value;
          }
        else
          {
            gconf_log(GCL_WARNING, _("Didn't find car and cdr for XML pair node"));
            if (car)
              {
                g_assert(cdr == NULL);
                gconf_value_free(car);
                gconf_set_error(err, GCONF_ERROR_PARSE_ERROR,
                                _("Missing cdr from pair of values in XML file"));
              }
            else if (cdr)
              {
                g_assert(car == NULL);
                gconf_value_free(cdr);
                gconf_set_error(err, GCONF_ERROR_PARSE_ERROR,
                                _("Missing car from pair of values in XML file"));
              }
            else
              {
                gconf_set_error(err, GCONF_ERROR_PARSE_ERROR,
                                _("Missing both car and cdr values from pair in XML file"));
              }

            return NULL;
          }
      }
      break;
    default:
      g_assert_not_reached();
      return NULL;
      break;
    }
}
Example #4
0
static GConfValue*
schema_node_extract_value(xmlNodePtr node, const gchar** locales)
{
  GConfValue* value = NULL;
  gchar* owner_str;
  gchar* stype_str;
  gchar* list_type_str;
  gchar* car_type_str;
  gchar* cdr_type_str;
  GConfSchema* sc;
  xmlNodePtr iter;
  guint i;
  xmlNodePtr* localized_nodes;
  xmlNodePtr best = NULL;
  
  /* owner, type are for all locales;
     default value, descriptions are per-locale
  */

  owner_str = my_xmlGetProp(node, "owner");
  stype_str = my_xmlGetProp(node, "stype");
  list_type_str = my_xmlGetProp(node, "list_type");
  car_type_str = my_xmlGetProp(node, "car_type");
  cdr_type_str = my_xmlGetProp(node, "cdr_type");

  sc = gconf_schema_new();

  if (owner_str)
    {
      gconf_schema_set_owner(sc, owner_str);
      xmlFree(owner_str);
    }
  if (stype_str)
    {
      GConfValueType stype;
      stype = gconf_value_type_from_string(stype_str);
      gconf_schema_set_type(sc, stype);
      xmlFree(stype_str);
    }
  if (list_type_str)
    {
      GConfValueType type;
      type = gconf_value_type_from_string(list_type_str);
      gconf_schema_set_list_type(sc, type);
      xmlFree(list_type_str);
    }
  if (car_type_str)
    {
      GConfValueType type;
      type = gconf_value_type_from_string(car_type_str);
      gconf_schema_set_car_type(sc, type);
      xmlFree(car_type_str);
    }
  if (cdr_type_str)
    {
      GConfValueType type;
      type = gconf_value_type_from_string(cdr_type_str);
      gconf_schema_set_cdr_type(sc, type);
      xmlFree(cdr_type_str);
    }  
  
  if (locales != NULL && locales[0])
    {
      /* count the number of possible locales */
      int n_locales;
      
      n_locales = 0;
      while (locales[n_locales])
        ++n_locales;
      
      localized_nodes = g_new0(xmlNodePtr, n_locales);
      
      /* Find the node for each possible locale */
      iter = node->xmlChildrenNode;
      
      while (iter != NULL)
        {
          if (iter->type == XML_ELEMENT_NODE &&
              strcmp((char *)iter->name, "local_schema") == 0)
            {
              char* locale_name;
              
              locale_name = my_xmlGetProp(iter, "locale");
              
              if (locale_name != NULL)
                {
                  i = 0;
                  while (locales[i])
                    {
                      if (strcmp(locales[i], locale_name) == 0)
                        {
                          localized_nodes[i] = iter;
                          break;
                        }
                      ++i;
                    }

                  xmlFree(locale_name);
                  
                  /* Quit as soon as we have the best possible locale */
                  if (localized_nodes[0] != NULL)
                    break;
                }
            }
          
          iter = iter->next;
        }

      /* See which is the best locale we managed to load, they are in
         order of preference. */
      
      i = 0;
      best = localized_nodes[i];
      while (best == NULL && i < n_locales)
        {
          best = localized_nodes[i];
          ++i;
        }
      
      g_free(localized_nodes);
    }

  /* If no locale matched, try picking the the null localization,
   * and then try picking the first node
   */
  if (best == NULL)
    best = find_schema_subnode_by_locale (node, NULL);

  if (best == NULL)
    {
      best = node->xmlChildrenNode;
      while (best && best->type != XML_ELEMENT_NODE)
        best = best->next;
    }
  
  /* Extract info from the best locale node */
  if (best != NULL)
    schema_subnode_extract_data(best, sc); 
  
  /* Create a GConfValue with this schema and return it */
  value = gconf_value_new(GCONF_VALUE_SCHEMA);
      
  gconf_value_set_schema_nocopy(value, sc);

  return value;
}
Example #5
0
static void
schema_subnode_extract_data(xmlNodePtr node, GConfSchema* sc)
{
  gchar* sd_str;
  gchar* locale_str;
  GError* error = NULL;
  
  sd_str = my_xmlGetProp(node, "short_desc");
  locale_str = my_xmlGetProp(node, "locale");
  
  if (sd_str)
    {
      gconf_schema_set_short_desc(sc, sd_str);
      xmlFree(sd_str);
    }

  if (locale_str)
    {
      gconf_log(GCL_DEBUG, "found locale `%s'", locale_str);
      gconf_schema_set_locale(sc, locale_str);
      xmlFree(locale_str);
    }
  else
    {
      gconf_log(GCL_DEBUG, "found <%s> with no locale setting",
                node->name ? node->name : (unsigned char*) "null");
    }
  
  if (node->xmlChildrenNode != NULL)
    {
      GConfValue* default_value = NULL;
      xmlChar* ld_str = NULL;
      GSList* bad_nodes = NULL;
      xmlNodePtr iter = node->xmlChildrenNode;

      while (iter != NULL)
        {
          if (iter->type == XML_ELEMENT_NODE)
            {
              if (default_value == NULL &&
                  strcmp((char *)iter->name, "default") == 0)
                {
                  default_value = node_extract_value(iter, NULL, &error);

                  if (error != NULL)
                    {
                      g_assert(default_value == NULL);
                      
                      gconf_log(GCL_WARNING, _("Failed reading default value for schema: %s"), 
                                error->message);
                      g_error_free(error);
                      error = NULL;
                      
                      bad_nodes = g_slist_prepend(bad_nodes, iter);
                    }
                }
              else if (ld_str == NULL &&
                       strcmp((char *)iter->name, "longdesc") == 0)
                {
                  ld_str = xmlNodeGetContent(iter);
                }
              else
                {
                  bad_nodes = g_slist_prepend(bad_nodes, iter);
                }
            }
          else
            bad_nodes = g_slist_prepend(bad_nodes, iter); /* what is this node? */

          iter = iter->next;
        }
      

      /* Remove the bad nodes from the parse tree */
      if (bad_nodes != NULL)
        {
          GSList* tmp = bad_nodes;
          
          while (tmp != NULL)
            {
              xmlUnlinkNode(tmp->data);
              xmlFreeNode(tmp->data);
              
              tmp = g_slist_next(tmp);
            }
          
          g_slist_free(bad_nodes);
        }

      if (default_value != NULL)
        gconf_schema_set_default_value_nocopy(sc, default_value);

      if (ld_str)
        {
          gconf_schema_set_long_desc(sc, (char *)ld_str);
          xmlFree(ld_str);
        }
    }
}
Example #6
0
void
entry_fill_from_node(Entry* e)
{
  gchar* tmp;
  GError* error = NULL;

  g_return_if_fail(e->node != NULL);
  
  tmp = my_xmlGetProp(e->node, "schema");
  
  if (tmp != NULL)
    {
      /* Filter any crap schemas that appear, some speed cost */
      gchar* why_bad = NULL;
      if (gconf_valid_key(tmp, &why_bad))
        {
          g_assert(why_bad == NULL);
          e->schema_name = g_strdup(tmp);
        }
      else
        {
          e->schema_name = NULL;
          gconf_log(GCL_WARNING, _("Ignoring schema name `%s', invalid: %s"),
                    tmp, why_bad);
          g_free(why_bad);
        }
          
      xmlFree(tmp);
    }
      
  tmp = my_xmlGetProp(e->node, "mtime");

  if (tmp != NULL)
    {
      e->mod_time = gconf_string_to_gulong(tmp);
      xmlFree(tmp);
    }
  else
    e->mod_time = 0;

  tmp = my_xmlGetProp(e->node, "muser");

  if (tmp != NULL)
    {
      e->mod_user = g_strdup(tmp);
      xmlFree(tmp);
    }
  else
    e->mod_user = NULL;

  entry_sync_if_needed(e);
  
  if (e->cached_value != NULL)
    gconf_value_free(e->cached_value);
  
  e->cached_value = node_extract_value(e->node, NULL, /* FIXME current locale as a guess */
                                       &error);

  if (e->cached_value)
    {
      g_return_if_fail(error == NULL);
      return;
    }
  else if (error != NULL)
    {
      /* Ignore errors from node_extract_value() if we got a schema name,
       * since the node's only purpose may be to store the schema name.
       */
      if (e->schema_name == NULL)
        gconf_log (GCL_WARNING,
                   _("Ignoring XML node `%s': %s"),
                   e->name, error->message);
      g_error_free(error);
    }
}