static void end_element (GMarkupParseContext *context, const gchar *element_name, gpointer user_data, GError **error) { ParseState *state = user_data; if (strcmp (element_name, "default") == 0) { state->value = g_variant_parse (state->type, state->string->str, NULL, NULL, error); if (state->value == NULL) return; if (state->l10n) { if (state->context) { gint len; /* Contextified messages are supported by prepending the * context, followed by '\004' to the start of the message * string. We do that here to save GSettings the work * later on. * * Note: we are about to g_free() the context anyway... */ len = strlen (state->context); state->context[len] = '\004'; g_string_prepend_len (state->string, state->context, len + 1); } g_variant_builder_add (&state->key_options, "{sv}", "l10n", g_variant_new ("(ys)", state->l10n, state->string->str)); } g_string_free (state->string, TRUE); state->string = NULL; g_free (state->context); state->context = NULL; } else if (strcmp (element_name, "key") == 0) { if (state->value == NULL) { g_set_error_literal (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "element <default> is required in <key>\n"); return; } if (state->min != NULL) { if (g_variant_compare (state->value, state->min) < 0 || g_variant_compare (state->value, state->max) > 0) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "<default> is not contained in the specified range"); return; } state->min = state->max = NULL; } else if (state->choices != NULL) { if (!is_valid_choices (state->value, state->choices->str)) { g_set_error_literal (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "<default> contains string not in <choices>"); return; } state->choices = NULL; } gvdb_item_set_value (state->key, state->value); gvdb_item_set_options (state->key, g_variant_builder_end (&state->key_options)); state->value = NULL; } else if (strcmp (element_name, "summary") == 0 || strcmp (element_name, "description") == 0) { g_string_free (state->string, TRUE); state->string = NULL; } else if (strcmp (element_name, "choices") == 0) { gchar *choices; choices = g_string_free (state->choices, FALSE); g_variant_builder_add (&state->key_options, "{sv}", "choices", g_variant_new_byte_array (choices, -1)); g_free (choices); } }
static gboolean _eventd_events_event_matches(EventdEventsEvent *self, EventdEvent *event, GQuark *current_flags) { if ( self->if_data != NULL ) { gchar **data; for ( data = self->if_data ; *data != NULL ; ++data ) { if ( ! eventd_event_has_data(event, *data) ) return FALSE; } } if ( self->if_data_matches != NULL ) { EventdEventsEventDataMatch *match; GVariant *data; for ( match = self->if_data_matches ; match->data != NULL ; ++match ) { if ( ! eventd_event_has_data(event, match->data) ) continue; if ( ( data = eventd_event_get_data(event, match->data) ) == NULL ) return FALSE; if ( match->key != NULL ) { if ( ! g_variant_is_of_type(data, G_VARIANT_TYPE_VARDICT) ) return FALSE; data = g_variant_lookup_value(data, match->key, g_variant_get_type(match->value)); if ( data == NULL ) return FALSE; } else if ( ! g_variant_type_equal(g_variant_get_type(data), g_variant_get_type(match->value)) ) return FALSE; gint ret; ret = g_variant_compare(data, match->value); ret = CLAMP(ret, -1, 1); if ( ( ret != match->accepted[0] ) && ( ret != match->accepted[1] ) ) return FALSE; } } if ( self->if_data_regexes != NULL ) { EventdEventsEventDataRegex *match; const gchar *data; for ( match = self->if_data_regexes ; match->data != NULL ; ++match ) { if ( ! eventd_event_has_data(event, match->data) ) continue; if ( ( data = eventd_event_get_data_string(event, match->data) ) == NULL ) return FALSE; if ( ! g_regex_match(match->regex, data, 0, NULL) ) return FALSE; } } if ( current_flags != NULL ) { GQuark *flag; if ( self->flags_whitelist != NULL ) { GQuark *wflag; for ( wflag = self->flags_whitelist ; *wflag != 0 ; ++wflag ) { gboolean has = FALSE; for ( flag = current_flags ; ( *flag != 0 ) && ( ! has ) ; ++flag ) { if ( *flag == *wflag ) has = TRUE; } if ( ! has ) return FALSE; } } if ( self->flags_blacklist != NULL ) { GQuark *bflag; for ( bflag = self->flags_blacklist ; *bflag != 0 ; ++bflag ) { for ( flag = current_flags ; *flag != 0 ; ++flag ) { if ( *flag == *bflag ) return FALSE; } } } } return TRUE; }
static void start_element (GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer user_data, GError **error) { ParseState *state = user_data; const GSList *element_stack; const gchar *container; element_stack = g_markup_parse_context_get_element_stack (context); container = element_stack->next ? element_stack->next->data : NULL; #define COLLECT(first, ...) \ g_markup_collect_attributes (element_name, \ attribute_names, attribute_values, error, \ first, __VA_ARGS__, G_MARKUP_COLLECT_INVALID) #define OPTIONAL G_MARKUP_COLLECT_OPTIONAL #define STRDUP G_MARKUP_COLLECT_STRDUP #define STRING G_MARKUP_COLLECT_STRING #define NO_ATTRS() COLLECT (G_MARKUP_COLLECT_INVALID, NULL) if (container == NULL) { if (strcmp (element_name, "schemalist") == 0) { COLLECT (OPTIONAL | STRDUP, "gettext-domain", &state->schemalist_domain); return; } } else if (strcmp (container, "schemalist") == 0) { if (strcmp (element_name, "schema") == 0) { const gchar *id, *path; if (COLLECT (STRING, "id", &id, OPTIONAL | STRING, "path", &path, OPTIONAL | STRDUP, "gettext-domain", &state->schema_domain)) { if (!g_hash_table_lookup (state->schemas, id)) { state->schema = gvdb_hash_table_new (state->schemas, id); state->schema_root = gvdb_hash_table_insert (state->schema, ""); if (path != NULL) gvdb_hash_table_insert_string (state->schema, ".path", path); } else g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "<schema id='%s'> already specified", id); } return; } } else if (strcmp (container, "schema") == 0) { if (strcmp (element_name, "key") == 0) { const gchar *name, *type; if (COLLECT (STRING, "name", &name, STRING, "type", &type)) { if (!is_valid_keyname (name, error)) return; if (!g_hash_table_lookup (state->schema, name)) { state->key = gvdb_hash_table_insert (state->schema, name); gvdb_item_set_parent (state->key, state->schema_root); } else { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "<key name='%s'> already specified", name); return; } if (g_variant_type_string_is_valid (type)) state->type = g_variant_type_new (type); else { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "invalid GVariant type string '%s'", type); return; } g_variant_builder_init (&state->key_options, G_VARIANT_TYPE ("a{sv}")); } return; } else if (strcmp (element_name, "child") == 0) { const gchar *name, *schema; if (COLLECT (STRING, "name", &name, STRING, "schema", &schema)) { gchar *childname; if (!is_valid_keyname (name, error)) return; childname = g_strconcat (name, "/", NULL); if (!g_hash_table_lookup (state->schema, childname)) gvdb_hash_table_insert_string (state->schema, childname, schema); else g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "<child name='%s'> already specified", name); g_free (childname); return; } } } else if (strcmp (container, "key") == 0) { if (strcmp (element_name, "default") == 0) { const gchar *l10n; if (COLLECT (STRING | OPTIONAL, "l10n", &l10n, STRDUP | OPTIONAL, "context", &state->context)) { if (l10n != NULL) { if (!g_hash_table_lookup (state->schema, ".gettext-domain")) { const gchar *domain = state->schema_domain ? state->schema_domain : state->schemalist_domain; if (domain == NULL) { g_set_error_literal (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "l10n requested, but no " "gettext domain given"); return; } gvdb_hash_table_insert_string (state->schema, ".gettext-domain", domain); if (strcmp (l10n, "messages") == 0) state->l10n = 'm'; else if (strcmp (l10n, "time") == 0) state->l10n = 't'; else { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "unsupported l10n category: %s", l10n); return; } } } else { state->l10n = '\0'; if (state->context != NULL) { g_set_error_literal (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "translation context given for " " value without l10n enabled"); return; } } state->string = g_string_new (NULL); } return; } else if (strcmp (element_name, "summary") == 0 || strcmp (element_name, "description") == 0) { state->string = g_string_new (NULL); NO_ATTRS (); return; } else if (strcmp (element_name, "range") == 0) { const gchar *min_str, *max_str; if (!type_allows_range (state->type)) { gchar *type = g_variant_type_dup_string (state->type); g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "Element <%s> not allowed for keys of type \"%s\"\n", element_name, type); g_free (type); return; } if (!COLLECT (STRING, "min", &min_str, STRING, "max", &max_str)) return; state->min = g_variant_parse (state->type, min_str, NULL, NULL, error); if (state->min == NULL) return; state->max = g_variant_parse (state->type, max_str, NULL, NULL, error); if (state->max == NULL) return; if (g_variant_compare (state->min, state->max) > 0) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "Element <%s> specified minimum is greater than maxmimum", element_name); return; } g_variant_builder_add (&state->key_options, "{sv}", "range", g_variant_new ("(@?@?)", state->min, state->max)); return; } else if (strcmp (element_name, "choices") == 0) { if (!type_allows_choices (state->type)) { gchar *type = g_variant_type_dup_string (state->type); g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "Element <%s> not allowed for keys of type \"%s\"\n", element_name, type); g_free (type); return; } state->choices = g_string_new ("\xff"); NO_ATTRS (); return; } } else if (strcmp (container, "choices") == 0) { if (strcmp (element_name, "choice") == 0) { const gchar *value; if (COLLECT (STRING, "value", &value)) g_string_append_printf (state->choices, "%s\xff", value); return; } } if (container) g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, "Element <%s> not allowed inside <%s>\n", element_name, container); else g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, "Element <%s> not allowed at toplevel\n", element_name); }
static gboolean check_gsettings_condition (NemoAction *action, const gchar *condition) { gchar **split = g_strsplit (condition, " ", 6); gint len = g_strv_length (split); if (len != 6 && len != 3) { g_strfreev (split); return FALSE; } if (g_strcmp0 (split[0], "gsettings") != 0) { g_strfreev (split); return FALSE; } if (len == 6 && (!g_variant_type_string_is_valid (split[GSETTINGS_TYPE_INDEX]) || !operator_is_valid (split[GSETTINGS_OP_INDEX]))) { g_printerr ("Nemo Action: Either gsettings variant type (%s) or operator (%s) is invalid.\n", split[GSETTINGS_TYPE_INDEX], split[GSETTINGS_OP_INDEX]); g_strfreev (split); return FALSE; } GSettingsSchemaSource *schema_source; gboolean ret = FALSE; const GVariantType *target_type; if (len == 3) { target_type = G_VARIANT_TYPE_BOOLEAN; } else { target_type = G_VARIANT_TYPE (split[GSETTINGS_TYPE_INDEX]); } schema_source = g_settings_schema_source_get_default(); if (g_settings_schema_source_lookup (schema_source, split[GSETTINGS_SCHEMA_INDEX], TRUE)) { GSettings *s = g_settings_new (split[GSETTINGS_SCHEMA_INDEX]); gchar **keys = g_settings_list_keys (s); gint i; for (i = 0; i < g_strv_length (keys); i++) { if (len == 3) { if (g_strcmp0 (keys[i], split[GSETTINGS_KEY_INDEX]) == 0) { GVariant *setting_var = g_settings_get_value (s, split[GSETTINGS_KEY_INDEX]); const GVariantType *setting_type = g_variant_get_type (setting_var); if (g_variant_type_equal (setting_type, target_type)) ret = g_variant_get_boolean (setting_var); g_variant_unref (setting_var); } } else { if (g_strcmp0 (keys[i], split[GSETTINGS_KEY_INDEX]) == 0) { GVariant *setting_var = g_settings_get_value (s, split[GSETTINGS_KEY_INDEX]); const GVariantType *setting_type = g_variant_get_type (setting_var); if (g_variant_type_equal (setting_type, target_type)) { GVariant *target_var = g_variant_parse (target_type, split[GSETTINGS_VAL_INDEX], NULL, NULL, NULL); if (target_var != NULL) { gint vector = g_variant_compare (setting_var, target_var); ret = try_vector (split[GSETTINGS_OP_INDEX], vector); g_variant_unref (target_var); } else { g_printerr ("Nemo Action: gsettings value could not be parsed into a valid GVariant\n"); } } g_variant_unref (setting_var); } } } g_strfreev (keys); g_object_unref (s); g_strfreev (split); return ret; } else { g_strfreev (split); return FALSE; } }