예제 #1
0
파일: utils.c 프로젝트: Abramovuch/ClipIt
/* Ellipsize a string according to the settings */
GString *ellipsize_string(GString *string)
{
    gchar *start = NULL,
          *end   = NULL;

    gint str_len = g_utf8_strlen(string->str, -1);
    if (str_len > prefs.item_length)
    {
        switch (prefs.ellipsize)
        {
            case PANGO_ELLIPSIZE_START:
                end = g_utf8_substring(string->str, str_len - prefs.item_length, str_len);
                g_string_printf(string, "...%s", end);
            break;
            case PANGO_ELLIPSIZE_MIDDLE:
                start = g_utf8_substring(string->str, 0, prefs.item_length/2);
                end = g_utf8_substring(string->str, str_len - prefs.item_length/2, str_len);
                g_string_printf(string, "%s...%s", start, end);
            break;
            case PANGO_ELLIPSIZE_END:
                start = g_utf8_substring(string->str, 0, prefs.item_length);
                g_string_assign(string, start);
                string = g_string_append(string, "...");
            break;
        }
    }

    g_free(start);
    g_free(end);

    return string;
}
예제 #2
0
static gchar *
gtk_label_accessible_get_selection (AtkText *atk_text,
                                    gint     selection_num,
                                    gint    *start_pos,
                                    gint    *end_pos)
{
  GtkWidget *widget;
  GtkLabel  *label;

  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
  if (widget == NULL)
    return NULL;

  if (selection_num != 0)
    return NULL;

  label = GTK_LABEL (widget);

  if (gtk_label_get_selection_bounds (label, start_pos, end_pos))
    {
      const gchar *text;

      text = gtk_label_get_text (label);

      if (text)
        return g_utf8_substring (text, *start_pos, *end_pos);
    }

  return NULL;
}
static void traverse_directory(const gchar *path) 
{
    GDir *dir = NULL;
    GError *error = NULL;
    const gchar *file = NULL;
    gchar *newpath = NULL;
    gchar *syspath = NULL;

    dir = g_dir_open(path, 0, &error);
    if (!dir) {
        printf("ERROR: %s, line %d, %s\n", __func__, __LINE__, error->message);
        g_error_free(error);
        error = NULL;
        return;
    }

    while (file = g_dir_read_name(dir)) {
        newpath = g_strdup_printf("%s/%s", path, file);
        if (g_file_test(newpath, G_FILE_TEST_IS_DIR)) {
            traverse_directory(newpath);
        } else if (g_file_test(newpath, G_FILE_TEST_IS_REGULAR)) {
            syspath = g_utf8_substring(newpath, strlen(m_buildroot), strlen(newpath));
            app_pkg_add_filelist(m_apkg, syspath);

            g_free(syspath);
            syspath = NULL;
        }

        g_free(newpath);
        newpath = NULL;
    }

    g_dir_close(dir);
    dir = NULL;
}
void assert_substring(const gchar * haystack, const gchar * needle,
		      gint begin, gint length)
{
    gchar *subStr = g_utf8_substring(haystack, begin, begin + length);
    g_assert_cmpstr(subStr, ==, needle);
    g_free(subStr);
}
예제 #5
0
static void overwrite (GString *gstr, char *text_to_insert, guint32 p1, guint32 p2) {

    glong len, ins_len;
    gsize pos;
    gchar *ins_str = NULL;

    if (p1 == p2)
        return;

    if (p1 > p2) {
        pos = p2;
        len = p1 - p2;
    }
    else{
        pos = p1;
        len = p2 - p1;
    }

    ins_len = g_utf8_strlen(text_to_insert, -1);
    if (len > ins_len) {
        len = ins_len;
    } else if (len < ins_len) {
        ins_str = g_utf8_substring(text_to_insert, 0, len);
    }

    if (!ins_str) ins_str = g_strdup(text_to_insert);

    if (pos > gstr->len)
        pos = gstr->len;

    g_string_erase(gstr, pos, len);

    g_string_insert(gstr, pos, ins_str);
    g_free(ins_str);
}
static void
gbp_gcc_toolchain_provider_load_worker (IdeTask      *task,
                                        gpointer      source_object,
                                        gpointer      task_data,
                                        GCancellable *cancellable)
{
  GbpGccToolchainProvider *self = source_object;
  g_autoptr(GPtrArray) toolchains = NULL;
  FileSearching *fs = task_data;

  g_assert (IDE_IS_TASK (task));
  g_assert (GBP_IS_GCC_TOOLCHAIN_PROVIDER (self));
  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
  g_assert (fs != NULL);
  g_assert (fs->found_files != NULL);

  toolchains = g_ptr_array_new_with_free_func (g_object_unref);

  for (guint i = 0; i < fs->found_files->len; i++)
    {
      GFile *file = g_ptr_array_index (fs->found_files, i);
      g_autofree gchar *basename = NULL;
      glong basename_length = 0;

      g_assert (G_IS_FILE (file));

      basename = g_file_get_basename (file);
      basename_length = g_utf8_strlen (basename, -1);

      if (basename_length > strlen ("-gcc"))
        {
          g_autofree gchar *arch = NULL;

          arch = g_utf8_substring (basename, 0, g_utf8_strlen (basename, -1) - strlen ("-gcc"));

          /* MinGW is out of the scope of this provider */
          if (g_strrstr (arch, "-") != NULL && g_strrstr (arch, "mingw32") == NULL)
            {
              g_autoptr(IdeTriplet) system_triplet = ide_triplet_new_from_system ();

              /* The default toolchain already covers the system triplet */
              if (g_strcmp0 (ide_triplet_get_full_name (system_triplet), arch) != 0)
                {
                  g_autoptr(IdeToolchain) toolchain = NULL;

                  toolchain = gbp_gcc_toolchain_provider_get_toolchain_from_file (self, file, arch);
                  g_ptr_array_add (toolchains, g_steal_pointer (&toolchain));
                }
            }
        }
    }

  ide_task_return_pointer (task,
                           g_steal_pointer (&toolchains),
                           g_ptr_array_unref);
}
예제 #7
0
static gchar *
gtk_text_cell_accessible_get_text (AtkText *atk_text,
                                   gint     start_pos,
                                   gint     end_pos)
{
  gchar *text;

  text = GTK_TEXT_CELL_ACCESSIBLE (atk_text)->cell_text;
  if (text)
    return g_utf8_substring (text, start_pos, end_pos > -1 ? end_pos : g_utf8_strlen (text, -1));
  else
    return g_strdup ("");
}
예제 #8
0
static char *
ellipsize_tab_label (const char *label)
{
  static const int MAX_LENGTH = 50;
  char *substring;
  char *result;

  if (g_utf8_strlen (label, -1) < MAX_LENGTH)
    return g_strdup (label);

  substring = g_utf8_substring (label, 0, MAX_LENGTH);
  result = g_strconcat (substring, "…", NULL);
  g_free (substring);

  return result;
}
예제 #9
0
static gchar *
gtk_icon_view_item_accessible_get_text (AtkText *text,
                                        gint     start_pos,
                                        gint     end_pos)
{
  GtkIconViewItemAccessible *item;

  item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);
  if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
    return NULL;

  if (item->text)
    return g_utf8_substring (item->text, start_pos, end_pos > -1 ? end_pos : g_utf8_strlen (item->text, -1));
  else
    return g_strdup ("");
}
예제 #10
0
static int tgp_msg_send_split (struct tgl_state *TLS, const char *message, tgl_peer_id_t to) {
  int size = (int)g_utf8_strlen (message, -1), start = 0;

  if (size > TGP_MAX_MSG_SIZE * TGP_DEFAULT_MAX_MSG_SPLIT_COUNT) {
    return -E2BIG;
  }
  while (size > start) {
    int end = start + (int)TGP_MAX_MSG_SIZE;
    if (end > size) {
      end = size;
    }
    gchar *chunk = g_utf8_substring (message, start, end);
    tgp_msg_send_schedule (TLS, chunk, to);
    start = end;
  }
  return 1;
}
예제 #11
0
static int tgp_msg_send_split (struct tgl_state *TLS, const char *message, tgl_peer_id_t to) {
  int max = TGP_DEFAULT_MAX_MSG_SPLIT_COUNT;
  if (max < 1) {
    max = 1;
  }
  int size = (int)g_utf8_strlen(message, -1);
  if (size > TGP_MAX_MSG_SIZE * max) {
    return -E2BIG;
  }
  int start = 0;
  while (size > start) {
    int e = start + (int)TGP_MAX_MSG_SIZE;
    gchar *chunk = g_utf8_substring (message, start, e);
    tgp_msg_send_schedule (TLS, chunk, to);
    start = e;
  }
  return 1;
}
예제 #12
0
static gchar*
gtk_label_accessible_get_text (AtkText *atk_text,
                               gint     start_pos,
                               gint     end_pos)
{
  GtkWidget *widget;
  const gchar *text;

  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
  if (widget == NULL)
    return NULL;

  text = gtk_label_get_text (GTK_LABEL (widget));

  if (text)
    return g_utf8_substring (text, start_pos, end_pos > -1 ? end_pos : g_utf8_strlen (text, -1));

  return NULL;
}
예제 #13
0
static gchar *
ev_page_accessible_get_substring (AtkText *text,
				  gint     start_offset,
				  gint     end_offset)
{
	EvPageAccessible *self = EV_PAGE_ACCESSIBLE (text);
	EvView *view = ev_page_accessible_get_view (self);
	gchar *substring, *normalized;
	const gchar* page_text;

	if (!view->page_cache)
		return NULL;

	page_text = ev_page_cache_get_text (view->page_cache, self->priv->page);
	start_offset = MAX (0, start_offset);
	if (end_offset < 0 || end_offset > g_utf8_strlen (page_text, -1))
		end_offset = strlen (page_text);

	substring = g_utf8_substring (page_text, start_offset, end_offset);
	normalized = g_utf8_normalize (substring, -1, G_NORMALIZE_NFKC);
	g_free (substring);

	return normalized;
}
예제 #14
0
/**
 * as_validator_validate_component_node:
 **/
static AsComponent*
as_validator_validate_component_node (AsValidator *validator, AsXMLData *xdt, xmlNode *root)
{
	xmlNode *iter;
	AsComponent *cpt;
	guint i;
	g_autofree gchar *metadata_license = NULL;
	g_autofree gchar *cpttype = NULL;
	g_autoptr(GHashTable) found_tags = NULL;
	g_auto(GStrv) cid_parts = NULL;
	const gchar *summary;
	const gchar *cid;
	AsParserMode mode;

	found_tags = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
	mode = as_xmldata_get_parser_mode (xdt);

	/* validate the resulting AsComponent for sanity */
	cpt = as_component_new ();
	as_xmldata_parse_component_node (xdt, root, cpt, NULL);
	as_validator_set_current_cpt (validator, cpt);

	/* check if component type is valid */
	cpttype = (gchar*) xmlGetProp (root, (xmlChar*) "type");
	if (cpttype != NULL) {
		if (as_component_kind_from_string (cpttype) == AS_COMPONENT_KIND_UNKNOWN) {
			as_validator_add_issue (validator,
						AS_ISSUE_IMPORTANCE_ERROR,
						AS_ISSUE_KIND_VALUE_WRONG,
						"Invalid component type found: %s",
						cpttype);
		}
	}

	/* validate the AppStream ID */
	cid = as_component_get_id (cpt);
	cid_parts = g_strsplit (cid, ".", 3);
	if (g_strv_length (cid_parts) != 3) {
		if (as_component_get_kind (cpt) == AS_COMPONENT_KIND_DESKTOP_APP) {
			/* since the ID and .desktop-file-id are tied together, we can't make this an error for desktop apps */
			as_validator_add_issue (validator,
					AS_ISSUE_IMPORTANCE_WARNING,
					AS_ISSUE_KIND_VALUE_WRONG,
					"The component ID is not a reverse domain-name. Please update the ID and that of the accompanying .desktop file to follow the latest version of the specifications and avoid future issues.");
		} else {
			/* anything which isn't a .desktop app should follow the schema though */
			as_validator_add_issue (validator,
					AS_ISSUE_IMPORTANCE_ERROR,
					AS_ISSUE_KIND_VALUE_WRONG,
					"The component ID is no reverse domain-name.");
		}
	} else {
		/* some people just add random dots to their ID - check if we have an actual known TLD as first part, to be more certain that this is a reverse domain name
		 * (this issue happens quite often with old .desktop files) */
		if (!as_utils_is_tld (cid_parts[0])) {
			as_validator_add_issue (validator,
						AS_ISSUE_IMPORTANCE_INFO,
						AS_ISSUE_KIND_VALUE_WRONG,
						"The component ID might not follow the reverse domain-name schema (we do not know about the TLD '%s').", cid_parts[0]);
		}
	}

	/* validate characters in AppStream ID */
	for (i = 0; cid[i] != '\0'; i++) {
		/* check if we have a printable, alphanumeric ASCII character or a dot, hyphen or underscore */
		if ((!g_ascii_isalnum (cid[i])) &&
		    (cid[i] != '.') &&
		    (cid[i] != '-') &&
		    (cid[i] != '_')) {
			g_autofree gchar *c = NULL;
			c = g_utf8_substring (cid, i, i + 1);
			as_validator_add_issue (validator,
					AS_ISSUE_IMPORTANCE_ERROR,
					AS_ISSUE_KIND_VALUE_WRONG,
					"The component ID contains an invalid character: '%s'", c);
		}
	}



	for (iter = root->children; iter != NULL; iter = iter->next) {
		const gchar *node_name;
		g_autofree gchar *node_content = NULL;
		gboolean tag_valid = TRUE;
		/* discard spaces */
		if (iter->type != XML_ELEMENT_NODE)
			continue;
		node_name = (const gchar*) iter->name;
		node_content = (gchar*) xmlNodeGetContent (iter);

		if (g_strcmp0 (node_name, "id") == 0) {
			gchar *prop;
			prop = (gchar*) xmlGetProp (iter, (xmlChar*) "type");
			if (prop != NULL) {
				as_validator_add_issue (validator,
							AS_ISSUE_IMPORTANCE_INFO,
							AS_ISSUE_KIND_PROPERTY_INVALID,
							"The id tag for \"%s\" still contains a 'type' property, probably from an old conversion.",
							node_content);
			}
			g_free (prop);
			if (as_component_get_kind (cpt) == AS_COMPONENT_KIND_DESKTOP_APP) {
				if (!g_str_has_suffix (node_content, ".desktop"))
					as_validator_add_issue (validator,
								AS_ISSUE_IMPORTANCE_WARNING,
								AS_ISSUE_KIND_VALUE_WRONG,
								"Component id belongs to a desktop-application, but does not resemble the .desktop file name: \"%s\"",
								node_content);
			}
		} else if (g_strcmp0 (node_name, "metadata_license") == 0) {
			metadata_license = g_strdup (node_content);
			as_validator_check_appear_once (validator, iter, found_tags, cpt);
		} else if (g_strcmp0 (node_name, "pkgname") == 0) {
			if (g_hash_table_contains (found_tags, node_name)) {
				as_validator_add_issue (validator,
							AS_ISSUE_IMPORTANCE_PEDANTIC,
							AS_ISSUE_KIND_TAG_DUPLICATED,
							"The tag 'pkgname' appears multiple times. You should evaluate creating a metapackage containing the data in order to avoid defining multiple package names per component.");
			}
		} else if (g_strcmp0 (node_name, "source_pkgname") == 0) {
			if (g_hash_table_contains (found_tags, node_name)) {
				as_validator_add_issue (validator,
							AS_ISSUE_IMPORTANCE_ERROR,
							AS_ISSUE_KIND_TAG_DUPLICATED,
							"The tag 'source_pkgname' appears multiple times.");
			}
		} else if (g_strcmp0 (node_name, "name") == 0) {
			as_validator_check_appear_once (validator, iter, found_tags, cpt);
		} else if (g_strcmp0 (node_name, "summary") == 0) {
			as_validator_check_appear_once (validator, iter, found_tags, cpt);
		} else if (g_strcmp0 (node_name, "description") == 0) {
			as_validator_check_appear_once (validator, iter, found_tags, cpt);
			as_validator_check_description_tag (validator, iter, cpt, mode);
		} else if (g_strcmp0 (node_name, "icon") == 0) {
			gchar *prop;
			prop = as_validator_check_type_property (validator, cpt, iter);
			if ((g_strcmp0 (prop, "cached") == 0) || (g_strcmp0 (prop, "stock") == 0)) {
				if (g_strrstr (node_content, "/") != NULL)
					as_validator_add_issue (validator,
								AS_ISSUE_IMPORTANCE_ERROR,
								AS_ISSUE_KIND_VALUE_WRONG,
								"Icons of type 'stock' or 'cached' must not contain a full or relative path to the icon.");
			}
			g_free (prop);
		} else if (g_strcmp0 (node_name, "url") == 0) {
			gchar *prop;
			prop = as_validator_check_type_property (validator, cpt, iter);
			if (as_url_kind_from_string (prop) == AS_URL_KIND_UNKNOWN) {
				as_validator_add_issue (validator,
							AS_ISSUE_IMPORTANCE_ERROR,
							AS_ISSUE_KIND_PROPERTY_INVALID,
							"Invalid property for 'url' tag: \"%s\"",
							prop);
			}
			g_free (prop);
		} else if (g_strcmp0 (node_name, "categories") == 0) {
			as_validator_check_appear_once (validator, iter, found_tags, cpt);
			as_validator_check_children_quick (validator, iter, "category", cpt);
		} else if (g_strcmp0 (node_name, "keywords") == 0) {
			as_validator_check_appear_once (validator, iter, found_tags, cpt);
			as_validator_check_children_quick (validator, iter, "keyword", cpt);
		} else if (g_strcmp0 (node_name, "mimetypes") == 0) {
			as_validator_check_appear_once (validator, iter, found_tags, cpt);
			as_validator_check_children_quick (validator, iter, "mimetype", cpt);
		} else if (g_strcmp0 (node_name, "provides") == 0) {
			as_validator_check_appear_once (validator, iter, found_tags, cpt);
		} else if (g_strcmp0 (node_name, "screenshots") == 0) {
			as_validator_check_children_quick (validator, iter, "screenshot", cpt);
		} else if (g_strcmp0 (node_name, "project_license") == 0) {
			as_validator_check_appear_once (validator, iter, found_tags, cpt);
		} else if (g_strcmp0 (node_name, "project_group") == 0) {
			as_validator_check_appear_once (validator, iter, found_tags, cpt);
		} else if (g_strcmp0 (node_name, "developer_name") == 0) {
			as_validator_check_appear_once (validator, iter, found_tags, cpt);
		} else if (g_strcmp0 (node_name, "compulsory_for_desktop") == 0) {
			as_validator_check_appear_once (validator, iter, found_tags, cpt);
		} else if (g_strcmp0 (node_name, "releases") == 0) {
			as_validator_check_children_quick (validator, iter, "release", cpt);
		} else if ((g_strcmp0 (node_name, "languages") == 0) && (mode == AS_PARSER_MODE_DISTRO)) {
			as_validator_check_appear_once (validator, iter, found_tags, cpt);
			as_validator_check_children_quick (validator, iter, "lang", cpt);
		} else if ((g_strcmp0 (node_name, "translation") == 0) && (mode == AS_PARSER_MODE_UPSTREAM)) {
			g_autofree gchar *prop = NULL;
			AsTranslationKind trkind;
			prop = as_validator_check_type_property (validator, cpt, iter);
			trkind = as_translation_kind_from_string (prop);
			if (trkind == AS_TRANSLATION_KIND_UNKNOWN) {
				as_validator_add_issue (validator,
							AS_ISSUE_IMPORTANCE_ERROR,
							AS_ISSUE_KIND_VALUE_WRONG,
							"Unknown type '%s' for <translation/> tag.", prop);
			}
		} else if (g_strcmp0 (node_name, "extends") == 0) {
		} else if (g_strcmp0 (node_name, "bundle") == 0) {
			g_autofree gchar *prop = NULL;
			prop = as_validator_check_type_property (validator, cpt, iter);
			if ((g_strcmp0 (prop, "limba") != 0) && (g_strcmp0 (prop, "flatpak") != 0)) {
				as_validator_add_issue (validator,
							AS_ISSUE_IMPORTANCE_ERROR,
							AS_ISSUE_KIND_VALUE_WRONG,
							"Unknown type '%s' for <bundle/> tag.", prop);
			}
		} else if (g_strcmp0 (node_name, "update_contact") == 0) {
			if (mode == AS_PARSER_MODE_DISTRO) {
				as_validator_add_issue (validator,
							AS_ISSUE_IMPORTANCE_WARNING,
							AS_ISSUE_KIND_TAG_NOT_ALLOWED,
							"The 'update_contact' tag should not be included in distro AppStream XML.");
			} else {
				as_validator_check_appear_once (validator, iter, found_tags, cpt);
			}
		} else if (g_strcmp0 (node_name, "metadata") == 0) {
			as_validator_add_issue (validator,
						AS_ISSUE_IMPORTANCE_PEDANTIC,
						AS_ISSUE_KIND_TAG_UNKNOWN,
						"Found custom metadata in <metadata/> tag. Use of this tag is common, but should be avoided if possible.");
			tag_valid = FALSE;
		} else if (!g_str_has_prefix (node_name, "x-")) {
			as_validator_add_issue (validator,
						AS_ISSUE_IMPORTANCE_WARNING,
						AS_ISSUE_KIND_TAG_UNKNOWN,
						"Found invalid tag: '%s'. Non-standard tags must be prefixed with \"x-\".",
				node_name);
			tag_valid = FALSE;
		}

		if (tag_valid) {
			as_validator_check_content_empty (validator,
							node_content,
							node_name,
							AS_ISSUE_IMPORTANCE_WARNING,
							cpt);
		}
	}

	if (metadata_license == NULL) {
		if (mode == AS_PARSER_MODE_UPSTREAM)
			as_validator_add_issue (validator,
						AS_ISSUE_IMPORTANCE_ERROR,
						AS_ISSUE_KIND_TAG_MISSING,
						"The essential tag 'metadata_license' is missing.");
	}

	/* check if the summary is sane */
	summary = as_component_get_summary (cpt);
	if ((summary != NULL) && ((strstr (summary, "\n") != NULL) || (strstr (summary, "\t") != NULL))) {
		as_validator_add_issue (validator,
					AS_ISSUE_IMPORTANCE_ERROR,
					AS_ISSUE_KIND_VALUE_WRONG,
					"The summary tag must not contain tabs or linebreaks.");
	}

	/* check if we have a description */
	if (as_str_empty (as_component_get_description (cpt))) {
		AsComponentKind cpt_kind;
		cpt_kind = as_component_get_kind (cpt);

		if ((cpt_kind == AS_COMPONENT_KIND_DESKTOP_APP) ||
			(cpt_kind == AS_COMPONENT_KIND_FONT)) {
			as_validator_add_issue (validator,
					AS_ISSUE_IMPORTANCE_ERROR,
					AS_ISSUE_KIND_TAG_MISSING,
					"The component is missing a long description. Components of this type must have a long description.");
		} else if (cpt_kind != AS_COMPONENT_KIND_GENERIC) {
			as_validator_add_issue (validator,
					AS_ISSUE_IMPORTANCE_INFO,
					AS_ISSUE_KIND_TAG_MISSING,
					"The component is missing a long description. It is recommended to add one.");
		}
	}

	/* validate font specific stuff */
	if (as_component_get_kind (cpt) == AS_COMPONENT_KIND_FONT) {
		if (!g_str_has_suffix (as_component_get_id (cpt), ".font"))
			as_validator_add_issue (validator,
					AS_ISSUE_IMPORTANCE_ERROR,
					AS_ISSUE_KIND_VALUE_WRONG,
					"Components of type 'font' must have an AppStream ID with a '.font' suffix.");
		if (as_component_get_provided_for_kind (cpt, AS_PROVIDED_KIND_FONT) == NULL)
			as_validator_add_issue (validator,
					AS_ISSUE_IMPORTANCE_WARNING,
					AS_ISSUE_KIND_TAG_MISSING,
					"Type 'font' component, but no font information was provided via a provides/font tag.");
	}

	/* validate addon specific stuff */
	if (as_component_get_extends (cpt)->len > 0) {
		if (as_component_get_kind (cpt) != AS_COMPONENT_KIND_ADDON)
			as_validator_add_issue (validator,
						AS_ISSUE_IMPORTANCE_ERROR,
						AS_ISSUE_KIND_TAG_NOT_ALLOWED,
						"An 'extends' tag is specified, but the component is not an addon.");
	} else {
		if (as_component_get_kind (cpt) == AS_COMPONENT_KIND_ADDON)
			as_validator_add_issue (validator,
						AS_ISSUE_IMPORTANCE_ERROR,
						AS_ISSUE_KIND_TAG_MISSING,
						"The component is an addon, but no 'extends' tag was specified.");
	}

	as_validator_clear_current_cpt (validator);
	return cpt;
}
예제 #15
0
파일: jid.c 프로젝트: anossov/profanity
Jid*
jid_create(const gchar *const str)
{
    Jid *result = NULL;

    /* if str is NULL g_strdup returns NULL */
    gchar *trimmed = g_strdup(str);
    if (trimmed == NULL) {
        return NULL;
    }

    if (strlen(trimmed) == 0) {
        g_free(trimmed);
        return NULL;
    }

    if (g_str_has_prefix(trimmed, "/") || g_str_has_prefix(trimmed, "@")) {
        g_free(trimmed);
        return NULL;
    }

    if (!g_utf8_validate(trimmed, -1, NULL)) {
        g_free(trimmed);
        return NULL;
    }

    result = malloc(sizeof(struct jid_t));
    result->str = NULL;
    result->localpart = NULL;
    result->domainpart = NULL;
    result->resourcepart = NULL;
    result->barejid = NULL;
    result->fulljid = NULL;

    gchar *atp = g_utf8_strchr(trimmed, -1, '@');
    gchar *slashp = g_utf8_strchr(trimmed, -1, '/');
    gchar *domain_start = trimmed;

    if (atp) {
        result->localpart = g_utf8_substring(trimmed, 0, g_utf8_pointer_to_offset(trimmed, atp));
        domain_start = atp + 1;
    }

    if (slashp) {
        result->resourcepart = g_strdup(slashp + 1);
        result->domainpart = g_utf8_substring(domain_start, 0, g_utf8_pointer_to_offset(domain_start, slashp));
        char *barejidraw = g_utf8_substring(trimmed, 0, g_utf8_pointer_to_offset(trimmed, slashp));
        result->barejid = g_utf8_strdown(barejidraw, -1);
        result->fulljid = g_strdup(trimmed);
        g_free(barejidraw);
    } else {
        result->domainpart = g_strdup(domain_start);
        result->barejid = g_utf8_strdown(trimmed, -1);
    }

    if (result->domainpart == NULL) {
        jid_destroy(result);
        return NULL;
    }

    result->str = trimmed;

    return result;
}
예제 #16
0
static void
parse_and_decrypt_signons (const char *signons,
                           gboolean handle_forms)
{
  int version;
  gchar **lines;
  int i;
  guint length;

  lines = g_strsplit (signons, "\r\n", -1);
  if (!g_ascii_strncasecmp (lines[0], "#2c", 3))
    version = 1;
  else if (!g_ascii_strncasecmp (lines[0], "#2d", 3))
    version = 2;
  else if (!g_ascii_strncasecmp (lines[0], "#2e", 3))
    version = 3;
  else
    goto out;

  /* Skip the never-saved list */
  for (i = 1; lines[i] && !g_str_equal (lines[i], "."); i++) {
    ;
  }

  i++;

  /*
   * Read saved passwords. The information is stored in blocks
   * separated by lines that only contain a dot. We find a block by
   * the separator and parse them one by one.
   */
  length = g_strv_length (lines);

  while (i < length) {
    size_t begin = i;
    size_t end = i + 1;
    const char *realmBracketBegin = " (";
    const char *realmBracketEnd = ")";
    SoupURI *uri = NULL;
    char *realm = NULL;

    while (lines[end] && !g_str_equal (lines[end], "."))
      end++;

    i = end + 1;

    /* A block has at least five lines */
    if (end - begin < 5)
      continue;

    /* The first line is the site URL.
     * For HTTP authentication logins, the URL may contain http realm,
     * which will be in bracket:
     *   sitename:8080 (realm)
     */
    if (g_strstr_len (lines[begin], -1, realmBracketBegin)) {
      char *start_ptr, *end_ptr;
      char *full_url, *url;
      glong start, end;

      /* In this case the scheme may not exist. We assume that the
       * scheme is HTTP.
       */
      if (!g_strstr_len (lines[begin], -1, "://"))
        full_url = g_strconcat ("http://", lines[begin], NULL);
      else
        full_url = g_strdup (lines[begin]);

      start_ptr = g_strstr_len (full_url, -1, realmBracketBegin);
      start = g_utf8_pointer_to_offset (full_url, start_ptr);
      url = g_utf8_substring (full_url, 0, start);
      url = g_strstrip (url);
      uri = soup_uri_new (url);
      g_free (url);

      start += strlen (realmBracketBegin);
      end_ptr = g_strstr_len (full_url, -1, realmBracketEnd) -1;
      end = g_utf8_pointer_to_offset (full_url, end_ptr);
      realm = g_utf8_substring (full_url, start, end);

      g_free (full_url);
    } else {
      /* Don't have HTTP realm. It is the URL that the following
       * password belongs to.
       */
      uri = soup_uri_new (lines[begin]);
    }

    if (!SOUP_URI_VALID_FOR_HTTP (uri)) {
      soup_uri_free (uri);
      g_free (realm);
      continue;
    }

    ++begin;

    /* There may be multiple username/password pairs for this site.
     * In this case, they are saved in one block without a separated
     * line (contains a dot).
     */
    while (begin + 4 < end) {
      char *username = NULL;
      char *password = NULL;
      char *form_username = NULL;
      char *form_password = NULL;
      guint32 item_id;

      /* The username */
      if (handle_forms) {
        form_username = g_strdup (lines[begin++]);
      } else {
        begin++; /* Skip username element */
      }
      username = decrypt (lines[begin++]);

      /* The password */
      /* The element name has a leading '*' */
      if (lines[begin][0] == '*') {
        if (handle_forms) {
          form_password = g_strdup (lines[begin++]);
        } else {
          begin++; /* Skip password element */
        }
        password = decrypt (lines[begin++]);
      } else {
        /* Maybe the file is broken, skip to the next block */
        g_free (username);
        break;
      }

      /* The action attribute for from the form element. This line
       * exists in version 2 or above
       */
      if (version >= 2) {
        if (begin < end)
          /* Skip it */ ;
        begin++;

        /* Version 3 has an extra line for further use */
        if (version == 3)
          begin++;
      }

      if (handle_forms && !realm &&
          username && password &&
          !g_str_equal (username, "") &&
          !g_str_equal (form_username, "") &&
          !g_str_equal (form_password, "*")) {
        char *u = soup_uri_to_string (uri, FALSE);
        /* We skip the '*' at the beginning of form_password. */
        _ephy_profile_utils_store_form_auth_data (u,
                                                 form_username,
                                                 form_password+1,
                                                 username,
                                                 password);
        g_free (u);
      } else if (!handle_forms && realm &&
                 username && password &&
                 !g_str_equal (username, "") &&
                 form_username == NULL && form_password == NULL) {
        gnome_keyring_set_network_password_sync (NULL,
                                                 username,
                                                 realm,
                                                 uri->host,
                                                 NULL,
                                                 uri->scheme,
                                                 NULL,
                                                 uri->port,
                                                 password,
                                                 &item_id);
      }

      g_free (username);
      g_free (password);
      g_free (form_username);
      g_free (form_password);
    }

    soup_uri_free (uri);
    g_free (realm);
  }

 out:
  g_strfreev (lines);
}
예제 #17
0
/**
 * as_validator_validate_component_id:
 *
 * Validate the component-ID.
 */
static void
as_validator_validate_component_id (AsValidator *validator, xmlNode *idnode, AsComponent *cpt)
{
	guint i;
	g_auto(GStrv) cid_parts = NULL;
	g_autofree gchar *cid = (gchar*) xmlNodeGetContent (idnode);

	cid_parts = g_strsplit (cid, ".", 3);
	if (g_strv_length (cid_parts) != 3) {
		if (as_component_get_kind (cpt) == AS_COMPONENT_KIND_DESKTOP_APP) {
			/* since the ID and .desktop-file-id are tied together, we can't make this an error for desktop apps */
			as_validator_add_issue (validator, idnode,
					AS_ISSUE_IMPORTANCE_WARNING,
					AS_ISSUE_KIND_VALUE_WRONG,
					"The component ID is not a reverse domain-name. Please update the ID and that of the accompanying .desktop file to follow the latest version of the Desktop-Entry and AppStream specifications and avoid future issues.");
		} else {
			/* anything which isn't a .desktop app must follow the schema though */
			as_validator_add_issue (validator, idnode,
					AS_ISSUE_IMPORTANCE_ERROR,
					AS_ISSUE_KIND_VALUE_WRONG,
					"The component ID is no reverse domain-name.");
		}
	} else {
		/* some people just add random dots to their ID - check if we have an actual known TLD as first part, to be more certain that this is a reverse domain name
		 * (this issue happens quite often with old .desktop files) */
		if (!as_utils_is_tld (cid_parts[0])) {
			as_validator_add_issue (validator, idnode,
						AS_ISSUE_IMPORTANCE_INFO,
						AS_ISSUE_KIND_VALUE_WRONG,
						"The component ID might not follow the reverse domain-name schema (we do not know about the TLD '%s').", cid_parts[0]);
		}
	}

	/* validate characters in AppStream ID */
	for (i = 0; cid[i] != '\0'; i++) {
		/* check if we have a printable, alphanumeric ASCII character or a dot, hyphen or underscore */
		if ((!g_ascii_isalnum (cid[i])) &&
		    (cid[i] != '.') &&
		    (cid[i] != '-') &&
		    (cid[i] != '_')) {
			g_autofree gchar *c = NULL;
			c = g_utf8_substring (cid, i, i + 1);
			as_validator_add_issue (validator, idnode,
					AS_ISSUE_IMPORTANCE_ERROR,
					AS_ISSUE_KIND_VALUE_WRONG,
					"The component ID [%s] contains an invalid character: '%s'", cid, c);
		}
	}

	/* project-group specific constraints on the ID */
	if ((g_strcmp0 (as_component_get_project_group (cpt), "Freedesktop") == 0) ||
	    (g_strcmp0 (as_component_get_project_group (cpt), "FreeDesktop") == 0)) {
		if (!g_str_has_prefix (cid, "org.freedesktop."))
			as_validator_add_issue (validator, idnode,
						AS_ISSUE_IMPORTANCE_ERROR,
						AS_ISSUE_KIND_VALUE_WRONG,
						"The component is part of the Freedesktop project, but its id does not start with fd.o's reverse-DNS name (\"org.freedesktop\").");
	} else if (g_strcmp0 (as_component_get_project_group (cpt), "KDE") == 0) {
		if (!g_str_has_prefix (cid, "org.kde."))
			as_validator_add_issue (validator, idnode,
						AS_ISSUE_IMPORTANCE_ERROR,
						AS_ISSUE_KIND_VALUE_WRONG,
						"The component is part of the KDE project, but its id does not start with KDEs reverse-DNS name (\"org.kde\").");
	} else if (g_strcmp0 (as_component_get_project_group (cpt), "GNOME") == 0) {
		if (!g_str_has_prefix (cid, "org.gnome."))
			as_validator_add_issue (validator, idnode,
						AS_ISSUE_IMPORTANCE_PEDANTIC,
						AS_ISSUE_KIND_VALUE_WRONG,
						"The component is part of the GNOME project, but its id does not start with GNOMEs reverse-DNS name (\"org.gnome\").");
	}
}
예제 #18
0
파일: awesome.c 프로젝트: harbop/spop
static void notification_callback(const GString* status, gpointer data) {
    queue_status qs;
    gboolean repeat, shuffle;
    sp_track* cur_track;
    int cur_track_nb;
    int tot_tracks;

    GString* text;
    GString* rep_shuf;

    /* Read full status */
    qs = queue_get_status(&cur_track, &cur_track_nb, &tot_tracks);
    repeat = queue_get_repeat();
    shuffle = queue_get_shuffle();

    /* Prepare the data to display */
    text = g_string_sized_new(1024);
    rep_shuf = g_string_sized_new(40);

    if (repeat || shuffle)
        g_string_printf(rep_shuf, " [<b>" col("#daf", "%s") "</b>]",
                        repeat ? (shuffle ? "rs" : "r") : "s");

    if (qs == STOPPED)
        g_string_printf(text, "[stopped]%s", rep_shuf->str);
    else {
        /* Read more data */
        guint track_min, track_sec, pos_min, pos_sec;
        gchar* track_name;
        gchar* track_artist;
        GString* short_title = NULL;

        track_get_data(cur_track, &track_name, &track_artist, NULL, NULL, &track_sec, NULL);
        pos_sec = session_play_time() / 1000;
        track_min = track_sec / 60;
        track_sec %= 60;
        pos_min = pos_sec / 60;
        pos_sec %= 60;

        /* Prepare data to display */
        if (qs == PAUSED)
            g_string_append(text, "<b>[p]</b> ");

        /* Assume the strings are valid UTF-8 */
        if (g_utf8_strlen(track_name, -1) >= 30) {
            gchar* tmp_string = g_utf8_substring(track_name, 0, 29);
            short_title = g_string_new(tmp_string);
            g_string_append(short_title, "…");
            g_free(tmp_string);
        }
        else {
            short_title = g_string_new(track_name);
        }

        g_string_append_printf(text,
                               "[<b>" col("#afd", "%d") ":</b> " col("#adf", "%s") " / " col("#fad", "%s") "]"
                               " [<b>" col("#dfa", "%u:%02u") "</b>/" col("#dfa", "%u:%02u") "]%s",
                               cur_track_nb+1, track_artist, short_title->str,
                               pos_min, pos_sec, track_min, track_sec, rep_shuf->str);

        /* Free some memory */
        g_string_free(short_title, TRUE);
        g_free(track_name);
        g_free(track_artist);
    }
    g_string_free(rep_shuf, TRUE);

    /* Replace " with \" and & with &amp; */
    g_string_replace(text, "\"", "\\\"");
    g_string_replace(text, "&", "&amp;");

    /* Send to Awesome */
    set_text(text->str);

    g_string_free(text, TRUE);
}
void                                                                               
install_deb(const char *deb,
            void (*converted)(double *percent, void *arg, const char *filename),
            void (*problem)(char *prob, void *arg),
            void *arg)
{
    double percent = .0;
    char *meta = NULL;
	char *v1 = NULL, *v2 = NULL, *v3 = NULL;
	gchar *package = NULL;
    gchar *version = NULL;
    gchar *arch = NULL;
    char out[PATH_MAX] = { '\0' };

    m_arg = arg;
    m_problem = problem;

	m_buildroot = tmpnam(NULL);
	meta = tmpnam(NULL);
    if (!m_buildroot || !meta) {
        printf("ERROR: failed to create temporary directory\n");
        m_problem(_("ERROR: failed to create temporary directory"), arg);
        goto exit;
    }
#ifdef DEBUG
    printf("buildroot: %s\nmeta: %s\n", m_buildroot, meta);
#endif

	deb_extract(deb, m_buildroot);
	percent = 0.2;
    converted(&percent, m_arg, out);
    deb_control(deb, meta);
    percent = 0.4;
    converted(&percent, m_arg, out);

	v1 = malloc(256);
	v2 = malloc(256);
	v3 = malloc(256);
    if (!v1 || !v2 || !v3) {
        printf("ERROR: failed to allocate memory\n");
        m_problem(_("ERROR: failed to allocate memory"), arg);
        goto exit;
    }

	if (deb_info(deb, meta, "Package", v1) == -1)
        goto exit;
    package = g_utf8_substring(v1, 9, strlen(v1) - 1);
    if (deb_info(deb, meta, "Version", v2) == -1)
        goto exit;
    version = g_utf8_substring(v2, 9, strlen(v2) - 1);
	if (deb_info(deb, meta, "Architecture", v3) == -1)
        goto exit;
    arch = g_utf8_substring(v3, 14, strlen(v3) - 1);

    m_apkg = app_pkg_new();
    if (!m_apkg) {
        printf("ERROR: failed to instance AppPkg object\n");
        goto exit;
    }
    app_pkg_set_name(m_apkg, package);
    app_pkg_set_version(m_apkg, version);
    app_pkg_set_release(m_apkg, "1");
    if (strstr(v3, "amd64"))
        app_pkg_set_arch(m_apkg, "x86_64");
    else
        app_pkg_set_arch(m_apkg, arch);

	deb_info(deb, meta, "Homepage", v1);
	app_pkg_set_url(m_apkg, v1);

	deb_info(deb, meta, "Section", v1);
	app_pkg_set_group(m_apkg, v1);

	deb_info(deb, meta, "Description", v1);
	char *p = strchr(v1, '\n');
	*p = '\0';
	app_pkg_set_summary(m_apkg, v1);
	app_pkg_set_description(m_apkg, p+1);

	app_pkg_set_packager(m_apkg, "isoft-packager");
    percent = 0.6;
    converted(&percent, m_arg, out);

    for (int i = 0; m_dirtyfiles[i]; i++) {
        memset(out, 0, sizeof(out));
        snprintf(out, sizeof(out) - 1, "%s/%s", m_buildroot, m_dirtyfiles[i]);
        unlink(out);
    }
	traverse_directory(m_buildroot);
    memset(out, 0, sizeof(out));
    snprintf(out, sizeof(out) - 1, "%s.rpm", deb);
    app_pkg_write(m_apkg, m_buildroot, out);
    percent = 0.8;
    converted(&percent, m_arg, out);

    percent = 1.0;
    converted(&percent, m_arg, out);

exit:
    if (package) {
        g_free(package);
        package = NULL;
    }

    if (version) {
        g_free(version);
        version = NULL;
    }

    if (arch) {
        g_free(arch);
        arch = NULL;
    }

    if (m_apkg) {
        app_pkg_free(m_apkg);
        m_apkg = NULL;
    }
}
예제 #20
0
char *
cb_text_transform_text (const char         *text,
                        const CbTextEntity *entities,
                        gsize               n_entities,
                        guint               flags,
                        gsize               n_medias,
                        gint64              quote_id,
                        guint               display_range_start)
{
  GString *str;
  const  guint text_len   = g_utf8_strlen (text, -1);
  int i;
  char *end_str;
  gboolean last_entity_was_trailing = FALSE;
  guint last_end   = 0;
  guint cur_end    = text_len;
  gint32 *info;

  if (text_len == 0)
    return g_strdup (text);

  str = g_string_new (NULL);

  info = g_newa (gint32, n_entities);
  memset (info, 0, n_entities * sizeof (gint32));

  for (i = (int)n_entities - 1; i >= 0; i --)
    {
      char *btw;
      guint entity_to;
      gsize btw_length = cur_end - entities[i].to;

      if (entities[i].to <= display_range_start)
        continue;

      entity_to = entities[i].to - display_range_start;

      btw = g_utf8_substring (text,
                              entity_to,
                              cur_end);

      if (!is_whitespace (btw) && btw_length > 0)
        {
          g_free (btw);
          break;
        }
      else
        cur_end = entity_to;

      if (entities[i].to == cur_end &&
          (is_hashtag (entities[i].display_text) || is_link (entities[i].target)))
          {
            info[i] |= TRAILING;
            cur_end = entities[i].from - display_range_start;
          }
      else
        {
          g_free (btw);
          break;
        }

      g_free (btw);
    }


  for (i = 0; i < (int)n_entities; i ++)
    {
      const CbTextEntity *entity = &entities[i];
      char *before;
      guint entity_to;

      if (entity->to <= display_range_start)
        continue;

      entity_to = entity->to - display_range_start;
      before = g_utf8_substring (text,
                                 last_end,
                                 entity->from - display_range_start);

      if (!(last_entity_was_trailing && is_whitespace (before)))
        g_string_append (str, before);

      if ((flags & CB_TEXT_TRANSFORM_REMOVE_TRAILING_HASHTAGS) > 0 &&
          (info[i] & TRAILING) > 0 &&
          is_hashtag (entity->display_text))
        {
          last_end = entity_to;
          last_entity_was_trailing = TRUE;
          g_free (before);
          continue;
        }

      last_entity_was_trailing = FALSE;

      if (((flags & CB_TEXT_TRANSFORM_REMOVE_MEDIA_LINKS) > 0 &&
           is_media_url (entity->target, entity->display_text, n_medias)) ||
          (quote_id != 0 && is_quote_link (entity, quote_id)))
        {
          last_end = entity_to;
          g_free (before);
          continue;
        }

      if ((flags & CB_TEXT_TRANSFORM_EXPAND_LINKS) > 0)
        {
          if (entity->display_text[0] == '@')
            g_string_append (str, entity->display_text);
          else
            g_string_append (str, entity->target ? entity->target : entity->display_text);
        }
      else
        {
          g_string_append (str, "<span underline=\"none\"><a href=\"");
          g_string_append (str, entity->target ? entity->target : entity->display_text);
          g_string_append (str, "\"");

          if (entity->tooltip_text != NULL)
            {
              char *c = cb_utils_escape_ampersands (entity->tooltip_text);
              char *cc = cb_utils_escape_quotes (c);

              g_string_append (str, " title=\"");
              g_string_append (str, cc);
              g_string_append (str, "\"");

              g_free (cc);
              g_free (c);
            }

          g_string_append (str, ">");
          g_string_append (str, entity->display_text);
          g_string_append (str,"</a></span>");
        }

      last_end = entity_to;
      g_free (before);
    }

  end_str = g_utf8_substring (text, last_end, text_len);
  g_string_append (str, end_str);

  g_free (end_str);

  /* As a last step, make sure that removing trailing hashtags did not leave some
   * trailing whitespace (esp. newlines) behind.
   * Technically, that condition is too lax but it's good enough in practice and
   * we actually *never* care about trailing whitespace and can alway safely
   * remove it. */
  if ((flags & CB_TEXT_TRANSFORM_REMOVE_TRAILING_HASHTAGS) > 0 &&
      strlen (str->str) > 0)
    {
      char *p = str->str + str->len;
      gunichar c = g_utf8_get_char (p);

      while (c == '\0' || g_unichar_isspace (c))
        {
          p = g_utf8_prev_char (p);

          if (p == str->str)
            break;

          c = g_utf8_get_char (p);
        }

      /* Go one forward again, since the current character is the first non-space one. */
      p = g_utf8_next_char (p);

      g_string_truncate (str, p - str->str);
    }

  return g_string_free (str, FALSE);
}