⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xml-parser.c

📁 yum-metadata-parser 一个用C写的yum仓库解析库
💻 C
📖 第 1 页 / 共 2 页
字号:
    NULL,      /* resolveEntity */    NULL,      /* getEntity */    NULL,      /* entityDecl */    NULL,      /* notationDecl */    NULL,      /* attributeDecl */    NULL,      /* elementDecl */    NULL,      /* unparsedEntityDecl */    NULL,      /* setDocumentLocator */    NULL,      /* startDocument */    NULL,      /* endDocument */    (startElementSAXFunc) primary_sax_start_element, /* startElement */    (endElementSAXFunc) primary_sax_end_element,     /* endElement */    NULL,      /* reference */    (charactersSAXFunc) sax_characters,      /* characters */    NULL,      /* ignorableWhitespace */    NULL,      /* processingInstruction */    NULL,      /* comment */    sax_warning,      /* warning */    sax_error,      /* error */    sax_error,      /* fatalError */};voidsax_context_init (SAXContext *sctx,                  const char *md_type,                  CountFn count_callback,                  PackageFn package_callback,                  gpointer user_data,                  GError **err){    sctx->md_type = md_type;    sctx->error = err;    sctx->count_fn = count_callback;    sctx->package_fn = package_callback;    sctx->user_data = user_data;    sctx->current_package = NULL;    sctx->want_text = FALSE;    sctx->text_buffer = g_string_sized_new (PACKAGE_FIELD_SIZE);}voidyum_xml_parse_primary (const char *filename,                       CountFn count_callback,                       PackageFn package_callback,                       gpointer user_data,                       GError **err){    PrimarySAXContext ctx;    SAXContext *sctx = &ctx.sctx;    int rc;    ctx.state = PRIMARY_PARSER_TOPLEVEL;    ctx.current_dep_list = NULL;    ctx.current_file = NULL;    sax_context_init(sctx, "primary.xml", count_callback, package_callback,                     user_data, err);    xmlSubstituteEntitiesDefault (1);    rc = xmlSAXUserParseFile (&primary_sax_handler, &ctx, filename);    if (sctx->current_package) {        g_warning ("Incomplete package lost");        package_free (sctx->current_package);    }    g_string_free (sctx->text_buffer, TRUE);}/*****************************************************************************/static voidparse_package (const char **attrs, Package *p){    int i;    const char *attr;    const char *value;    for (i = 0; attrs && attrs[i]; i++) {        attr = attrs[i];        value = attrs[++i];        if (!strcmp (attr, "pkgid"))            p->pkgId = g_string_chunk_insert (p->chunk, value);        if (!strcmp (attr, "name"))            p->name = g_string_chunk_insert (p->chunk, value);        else if (!strcmp (attr, "arch"))            p->arch = g_string_chunk_insert (p->chunk, value);    }}typedef enum {    FILELIST_PARSER_TOPLEVEL = 0,    FILELIST_PARSER_PACKAGE,} FilelistSAXContextState;typedef struct {    SAXContext sctx;    FilelistSAXContextState state;    PackageFile *current_file;} FilelistSAXContext;static voidfilelist_parser_toplevel_start (FilelistSAXContext *ctx,                                const char *name,                                const char **attrs){    SAXContext *sctx = &ctx->sctx;    if (!strcmp (name, "package")) {        g_assert (sctx->current_package == NULL);        ctx->state = FILELIST_PARSER_PACKAGE;        sctx->current_package = package_new ();        parse_package (attrs, sctx->current_package);    }    else if (sctx->count_fn && !strcmp (name, "filelists")) {        int i;        const char *attr;        const char *value;        for (i = 0; attrs && attrs[i]; i++) {            attr = attrs[i];            value = attrs[++i];            if (!strcmp (attr, "packages")) {                sctx->count_fn (string_to_guint32_with_default (value, 0),                                sctx->user_data);                break;            }        }    }}static voidfilelist_parser_package_start (FilelistSAXContext *ctx,                               const char *name,                               const char **attrs){    SAXContext *sctx = &ctx->sctx;    Package *p = sctx->current_package;    int i;    const char *attr;    const char *value;    g_assert (p != NULL);    sctx->want_text = TRUE;    if (!strcmp (name, "version")) {        parse_version_info(attrs, p);    }    else if (!strcmp (name, "file")) {        ctx->current_file = package_file_new ();        for (i = 0; attrs && attrs[i]; i++) {            attr = attrs[i];            value = attrs[++i];            if (!strcmp (attr, "type"))                ctx->current_file->type =                    g_string_chunk_insert_const (p->chunk, value);        }    }}static voidfilelist_sax_start_element (void *data, const char *name, const char **attrs){    FilelistSAXContext *ctx = (FilelistSAXContext *) data;    SAXContext *sctx = &ctx->sctx;    if (sctx->text_buffer->len)        g_string_truncate (sctx->text_buffer, 0);    switch (ctx->state) {    case FILELIST_PARSER_TOPLEVEL:        filelist_parser_toplevel_start (ctx, name, attrs);        break;    case FILELIST_PARSER_PACKAGE:        filelist_parser_package_start (ctx, name, attrs);        break;    default:        break;    }}static voidfilelist_parser_package_end (FilelistSAXContext *ctx, const char *name){    SAXContext *sctx = &ctx->sctx;    Package *p = sctx->current_package;    g_assert (p != NULL);    sctx->want_text = FALSE;    if (!strcmp (name, "package")) {        if (sctx->package_fn && !*sctx->error)            sctx->package_fn (p, sctx->user_data);        package_free (p);        sctx->current_package = NULL;        if (ctx->current_file) {            g_free (ctx->current_file);            ctx->current_file = NULL;        }        ctx->state = FILELIST_PARSER_TOPLEVEL;    }    else if (!strcmp (name, "file")) {        PackageFile *file = ctx->current_file;        file->name = g_string_chunk_insert_len (p->chunk,                                                sctx->text_buffer->str,                                                sctx->text_buffer->len);        if (!file->type)            file->type = g_string_chunk_insert_const (p->chunk, "file");        p->files = g_slist_prepend (p->files, file);        ctx->current_file = NULL;    }}static voidfilelist_sax_end_element (void *data, const char *name){    FilelistSAXContext *ctx = (FilelistSAXContext *) data;    SAXContext *sctx = &ctx->sctx;    switch (ctx->state) {    case FILELIST_PARSER_PACKAGE:        filelist_parser_package_end (ctx, name);        break;    default:        break;    }    g_string_truncate (sctx->text_buffer, 0);}static xmlSAXHandler filelist_sax_handler = {    NULL,      /* internalSubset */    NULL,      /* isStandalone */    NULL,      /* hasInternalSubset */    NULL,      /* hasExternalSubset */    NULL,      /* resolveEntity */    NULL,      /* getEntity */    NULL,      /* entityDecl */    NULL,      /* notationDecl */    NULL,      /* attributeDecl */    NULL,      /* elementDecl */    NULL,      /* unparsedEntityDecl */    NULL,      /* setDocumentLocator */    NULL,      /* startDocument */    NULL,      /* endDocument */    (startElementSAXFunc) filelist_sax_start_element, /* startElement */    (endElementSAXFunc) filelist_sax_end_element,     /* endElement */    NULL,      /* reference */    (charactersSAXFunc) sax_characters,      /* characters */    NULL,      /* ignorableWhitespace */    NULL,      /* processingInstruction */    NULL,      /* comment */    sax_warning,      /* warning */    sax_error,      /* error */    sax_error,      /* fatalError */};voidyum_xml_parse_filelists (const char *filename,                         CountFn count_callback,                         PackageFn package_callback,                         gpointer user_data,                         GError **err){    FilelistSAXContext ctx;    SAXContext *sctx = &ctx.sctx;    int rc;    ctx.state = FILELIST_PARSER_TOPLEVEL;    ctx.current_file = NULL;        sax_context_init(sctx, "filelists.xml", count_callback, package_callback,                     user_data, err);    xmlSubstituteEntitiesDefault (1);    rc = xmlSAXUserParseFile (&filelist_sax_handler, &ctx, filename);    if (sctx->current_package) {        g_warning ("Incomplete package lost");        package_free (sctx->current_package);    }    if (ctx.current_file)        g_free (ctx.current_file);    g_string_free (sctx->text_buffer, TRUE);}/*****************************************************************************/typedef enum {    OTHER_PARSER_TOPLEVEL = 0,    OTHER_PARSER_PACKAGE,} OtherSAXContextState;typedef struct {    SAXContext sctx;    OtherSAXContextState state;    ChangelogEntry *current_entry;} OtherSAXContext;static voidother_parser_toplevel_start (OtherSAXContext *ctx,                             const char *name,                             const char **attrs){    SAXContext *sctx = &ctx->sctx;    if (!strcmp (name, "package")) {        g_assert (sctx->current_package == NULL);        ctx->state = OTHER_PARSER_PACKAGE;        sctx->current_package = package_new ();        parse_package (attrs, sctx->current_package);    }    else if (sctx->count_fn && !strcmp (name, "otherdata")) {        int i;        const char *attr;        const char *value;        for (i = 0; attrs && attrs[i]; i++) {            attr = attrs[i];            value = attrs[++i];            if (!strcmp (attr, "packages")) {                sctx->count_fn (string_to_guint32_with_default (value, 0),                                sctx->user_data);                break;            }        }    }}static voidother_parser_package_start (OtherSAXContext *ctx,                            const char *name,                            const char **attrs){    SAXContext *sctx = &ctx->sctx;    Package *p = sctx->current_package;    int i;    const char *attr;    const char *value;    g_assert (p != NULL);    sctx->want_text = TRUE;    if (!strcmp (name, "version")) {        parse_version_info(attrs, p);    }    else if (!strcmp (name, "changelog")) {        ctx->current_entry = changelog_entry_new ();        for (i = 0; attrs && attrs[i]; i++) {            attr = attrs[i];            value = attrs[++i];            if (!strcmp (attr, "author"))                ctx->current_entry->author =                    g_string_chunk_insert_const (p->chunk, value);            else if (!strcmp (attr, "date"))                ctx->current_entry->date = strtol(value, NULL, 10);        }    }}static voidother_sax_start_element (void *data, const char *name, const char **attrs){    OtherSAXContext *ctx = (OtherSAXContext *) data;    SAXContext *sctx = &ctx->sctx;    if (sctx->text_buffer->len)        g_string_truncate (sctx->text_buffer, 0);    switch (ctx->state) {    case OTHER_PARSER_TOPLEVEL:        other_parser_toplevel_start (ctx, name, attrs);        break;    case OTHER_PARSER_PACKAGE:        other_parser_package_start (ctx, name, attrs);        break;    default:        break;    }}static voidother_parser_package_end (OtherSAXContext *ctx, const char *name){    SAXContext *sctx = &ctx->sctx;    Package *p = sctx->current_package;    g_assert (p != NULL);    sctx->want_text = FALSE;    if (!strcmp (name, "package")) {        if (p->changelogs)            p->changelogs = g_slist_reverse (p->changelogs);        if (sctx->package_fn && !*sctx->error)            sctx->package_fn (p, sctx->user_data);        package_free (p);        sctx->current_package = NULL;        if (ctx->current_entry) {            g_free (ctx->current_entry);            ctx->current_entry = NULL;        }        ctx->state = OTHER_PARSER_TOPLEVEL;    }    else if (!strcmp (name, "changelog")) {        ctx->current_entry->changelog =            g_string_chunk_insert_len (p->chunk,                                       sctx->text_buffer->str,                                       sctx->text_buffer->len);        p->changelogs = g_slist_prepend (p->changelogs, ctx->current_entry);        ctx->current_entry = NULL;    }}static voidother_sax_end_element (void *data, const char *name){    OtherSAXContext *ctx = (OtherSAXContext *) data;    SAXContext *sctx = &ctx->sctx;    switch (ctx->state) {    case OTHER_PARSER_PACKAGE:        other_parser_package_end (ctx, name);        break;    default:        break;    }    g_string_truncate (sctx->text_buffer, 0);}static xmlSAXHandler other_sax_handler = {    NULL,      /* internalSubset */    NULL,      /* isStandalone */    NULL,      /* hasInternalSubset */    NULL,      /* hasExternalSubset */    NULL,      /* resolveEntity */    NULL,      /* getEntity */    NULL,      /* entityDecl */    NULL,      /* notationDecl */    NULL,      /* attributeDecl */    NULL,      /* elementDecl */    NULL,      /* unparsedEntityDecl */    NULL,      /* setDocumentLocator */    NULL,      /* startDocument */    NULL,      /* endDocument */    (startElementSAXFunc) other_sax_start_element, /* startElement */    (endElementSAXFunc) other_sax_end_element,     /* endElement */    NULL,      /* reference */    (charactersSAXFunc) sax_characters,      /* characters */    NULL,      /* ignorableWhitespace */    NULL,      /* processingInstruction */    NULL,      /* comment */    sax_warning,      /* warning */    sax_error,      /* error */    sax_error,      /* fatalError */};voidyum_xml_parse_other (const char *filename,                     CountFn count_callback,                     PackageFn package_callback,                     gpointer user_data,                     GError **err){    OtherSAXContext ctx;    SAXContext *sctx = &ctx.sctx;    int rc;    ctx.state = OTHER_PARSER_TOPLEVEL;    ctx.current_entry = NULL;        sax_context_init(sctx, "other.xml", count_callback, package_callback,                     user_data, err);    xmlSubstituteEntitiesDefault (1);    rc = xmlSAXUserParseFile (&other_sax_handler, &ctx, filename);    if (sctx->current_package) {        g_warning ("Incomplete package lost");        package_free (sctx->current_package);    }    if (ctx.current_entry)        g_free (ctx.current_entry);    g_string_free (sctx->text_buffer, TRUE);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -