static void
transform_finished (YelpTransform    *transform,
                    YelpInfoDocument *info)
{
    YelpInfoDocumentPrivate *priv = GET_PRIV (info);
    gchar *docuri;
    GError *error;

    g_assert (transform == priv->transform);

    if (priv->state == INFO_STATE_STOP) {
        info_document_disconnect (info);
        return;
    }

    info_document_disconnect (info);
    priv->state = INFO_STATE_PARSED;

    /* We want to free priv->xmldoc, but we can't free it before transform
       is finalized.   Otherwise, we could crash when YelpTransform frees
       its libxslt resources.
     */
    g_object_weak_ref ((GObject *) transform,
                       (GWeakNotify) transform_finalized,
                       info);

    docuri = yelp_uri_get_document_uri (priv->uri);
    error = g_error_new (YELP_ERROR, YELP_ERROR_NOT_FOUND,
                         _("The requested page was not found in the document ‘%s’."),
                         docuri);
    g_free (docuri);
    yelp_document_error_pending ((YelpDocument *) info, error);
    g_error_free (error);
}
static gboolean
info_request_page (YelpDocument         *document,
                   const gchar          *page_id,
                   GCancellable         *cancellable,
                   YelpDocumentCallback  callback,
                   gpointer              user_data)
{
    YelpInfoDocumentPrivate *priv = GET_PRIV (document);
    gchar *docuri;
    GError *error;
    gboolean handled;

    if (page_id == NULL)
        page_id = priv->root_id;

    handled =
        YELP_DOCUMENT_CLASS (yelp_info_document_parent_class)->request_page (document,
                                                                             page_id,
                                                                             cancellable,
                                                                             callback,
                                                                             user_data);
    if (handled) {
        return TRUE;
    }

    g_mutex_lock (&priv->mutex);

    switch (priv->state) {
    case INFO_STATE_BLANK:
	priv->state = INFO_STATE_PARSING;
	priv->process_running = TRUE;
        g_object_ref (document);
	priv->thread = g_thread_new ("info-page",
                                     (GThreadFunc) info_document_process,
                                     document);
	break;
    case INFO_STATE_PARSING:
	break;
    case INFO_STATE_PARSED:
    case INFO_STATE_STOP:
        docuri = yelp_uri_get_document_uri (priv->uri);
        error = g_error_new (YELP_ERROR, YELP_ERROR_NOT_FOUND,
                             _("The page ‘%s’ was not found in the document ‘%s’."),
                             page_id, docuri);
        g_free (docuri);
        yelp_document_signal (document, page_id,
                              YELP_DOCUMENT_SIGNAL_ERROR,
                              error);
        g_error_free (error);
        break;
    }

    g_mutex_unlock (&priv->mutex);
    return TRUE;
}
YelpDocument *
yelp_info_document_new (YelpUri *uri)
{
    YelpInfoDocument *info;
    YelpInfoDocumentPrivate *priv;
    gchar *doc_uri;

    g_return_val_if_fail (uri != NULL, NULL);

    doc_uri = yelp_uri_get_document_uri (uri);
    info = (YelpInfoDocument *) g_object_new (YELP_TYPE_INFO_DOCUMENT,
                                              "document-uri", doc_uri,
                                              NULL);
    g_free (doc_uri);
    priv = GET_PRIV (info);

    priv->uri = g_object_ref (uri);

    return (YelpDocument *) info;
}
YelpDocument *
yelp_document_get_for_uri (YelpUri *uri)
{
    static GHashTable *documents = NULL;
    gchar *docuri = NULL;
    gchar *page_id, *tmp;
    YelpDocument *document = NULL;

    if (documents == NULL)
        documents = g_hash_table_new_full (g_str_hash, g_str_equal,
                                           g_free, g_object_unref);

    g_return_val_if_fail (yelp_uri_is_resolved (uri), NULL);

    switch (yelp_uri_get_document_type (uri)) {
    case YELP_URI_DOCUMENT_TYPE_TEXT:
    case YELP_URI_DOCUMENT_TYPE_HTML:
    case YELP_URI_DOCUMENT_TYPE_XHTML:
        /* We use YelpSimpleDocument for these, which is a single-file
         * responder. But the document URI may be set to the directory
         * holding the file, to allow a directory of HTML files to act
         * as a single document. So we cache these by a fuller URI.
         */
        docuri = yelp_uri_get_document_uri (uri);
        page_id = yelp_uri_get_page_id (uri);
        tmp = g_strconcat (docuri, "/", page_id, NULL);
        g_free (docuri);
        g_free (page_id);
        docuri = tmp;
        break;
    case YELP_URI_DOCUMENT_TYPE_MAN:
        /* The document URI for man pages is just man:, so we use the
         * full canonical URI to look these up.
         */
        docuri = yelp_uri_get_canonical_uri (uri);
        break;
    default:
        docuri = yelp_uri_get_document_uri (uri);
        break;
    }

    if (docuri == NULL)
        return NULL;
    document = g_hash_table_lookup (documents, docuri);

    if (document != NULL) {
        g_free (docuri);
        return g_object_ref (document);
    }

    switch (yelp_uri_get_document_type (uri)) {
    case YELP_URI_DOCUMENT_TYPE_TEXT:
    case YELP_URI_DOCUMENT_TYPE_HTML:
    case YELP_URI_DOCUMENT_TYPE_XHTML:
        document = yelp_simple_document_new (uri);
        break;
    case YELP_URI_DOCUMENT_TYPE_DOCBOOK:
        document = yelp_docbook_document_new (uri);
        break;
    case YELP_URI_DOCUMENT_TYPE_MALLARD:
        document = yelp_mallard_document_new (uri);
        break;
    case YELP_URI_DOCUMENT_TYPE_MAN:
        document = yelp_man_document_new (uri);
        break;
    case YELP_URI_DOCUMENT_TYPE_INFO:
        document = yelp_info_document_new (uri);
        break;
    case YELP_URI_DOCUMENT_TYPE_HELP_LIST:
        document = yelp_help_list_new (uri);
        break;
    case YELP_URI_DOCUMENT_TYPE_NOT_FOUND:
    case YELP_URI_DOCUMENT_TYPE_EXTERNAL:
    case YELP_URI_DOCUMENT_TYPE_ERROR:
        break;
    }

    if (document != NULL) {
        g_hash_table_insert (documents, docuri, document);
        return g_object_ref (document);
    }

    g_free (docuri);
    return NULL;
}
Exemple #5
0
static void
print_uri (gchar *orig, YelpUri *uri, GOutputStream *stream)
{
    GFile *file;
    const gchar *type = NULL;
    gchar *tmp, **tmpv, *out;

    g_output_stream_write (stream, orig, strlen (orig), NULL, NULL);
    g_output_stream_write (stream, "\n", 1, NULL, NULL);

    switch (yelp_uri_get_document_type (uri)) {
    case YELP_URI_DOCUMENT_TYPE_DOCBOOK:
        type = "DOCBOOK";
        break;
    case YELP_URI_DOCUMENT_TYPE_MALLARD:
        type = "MALLARD";
        break;
    case YELP_URI_DOCUMENT_TYPE_MAN:
        type = "MAN";
        break;
    case YELP_URI_DOCUMENT_TYPE_INFO:
        type = "INFO";
        break;
    case YELP_URI_DOCUMENT_TYPE_TEXT:
        type = "TEXT";
        break;
    case YELP_URI_DOCUMENT_TYPE_HTML:
        type = "HTML";
        break;
    case YELP_URI_DOCUMENT_TYPE_XHTML:
        type = "XHTML";
        break;
    case YELP_URI_DOCUMENT_TYPE_HELP_LIST:
        type = "TOC";
        break;
    case YELP_URI_DOCUMENT_TYPE_NOT_FOUND:
        type = "NOT FOUND";
        break;
    case YELP_URI_DOCUMENT_TYPE_EXTERNAL:
        type = "EXTERNAL";
        break;
    case YELP_URI_DOCUMENT_TYPE_ERROR:
        type = "ERROR";
        break;
    case YELP_URI_DOCUMENT_TYPE_UNRESOLVED:
        type = "UNRESOLVED";
        break;
    default:
        g_assert_not_reached ();
        break;
    }

    out = g_strdup_printf ("DOCUMENT TYPE: %s\n", type);
    g_output_stream_write (stream, out, strlen (out), NULL, NULL);
    g_free (out);

    tmp = yelp_uri_get_document_uri (uri);
    if (tmp) {
        out = g_strdup_printf ("DOCUMENT URI:  %s\n", tmp);
        g_output_stream_write (stream, out, strlen (out), NULL, NULL);
        g_free (out);
        g_free (tmp);
    }

    tmp = yelp_uri_get_canonical_uri (uri);
    if (tmp) {
        out = g_strdup_printf ("CANONICAL URI: %s\n", tmp);
        g_output_stream_write (stream, out, strlen (out), NULL, NULL);
        g_free (out);
        g_free (tmp);
    }

    file = yelp_uri_get_file (uri);
    if (file) {
        tmp = g_file_get_uri (file);
        out = g_strdup_printf ("FILE URI:      %s\n", tmp);
        g_output_stream_write (stream, out, strlen (out), NULL, NULL);
        g_free (out);
        g_free (tmp);
        g_object_unref (file);
    }

    tmpv = yelp_uri_get_search_path (uri);
    if (tmpv) {
        int i;
        for (i = 0; tmpv[i]; i++) {
            if (i == 0)
                out = g_strdup_printf ("SEARCH PATH:   %s\n", tmpv[i]);
            else
                out = g_strdup_printf ("               %s\n", tmpv[i]);
            g_output_stream_write (stream, out, strlen (out), NULL, NULL);
            g_free (out);
        }
        g_strfreev (tmpv);
    }

    tmp = yelp_uri_get_page_id (uri);
    if (tmp) {
        out = g_strdup_printf ("PAGE ID:       %s\n", tmp);
        g_output_stream_write (stream, out, strlen (out), NULL, NULL);
        g_free (out);
        g_free (tmp);
    }

    tmp = yelp_uri_get_frag_id (uri);
    if (tmp) {
        out = g_strdup_printf ("FRAG ID:       %s\n", tmp);
        g_output_stream_write (stream, out, strlen (out), NULL, NULL);
        g_free (out);
        g_free (tmp);
    }

    g_output_stream_write (stream, "\0", 1, NULL, NULL);
}