📄 xml-parser.c
字号:
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 + -