Skip to content

Commit

Permalink
XRC: new parser
Browse files Browse the repository at this point in the history
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
  • Loading branch information
masatake committed Dec 28, 2023
1 parent de99fa0 commit 472f4ed
Show file tree
Hide file tree
Showing 8 changed files with 256 additions and 0 deletions.
1 change: 1 addition & 0 deletions Units/simple-xrc.d/args.ctags
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--sort=no
22 changes: 22 additions & 0 deletions Units/simple-xrc.d/expected.tags
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
frame_view input.xrc /^ <object class="wxFrame" name="frame_view" subclass="hachoir.wx.frame_view.frame_view_t">$/;" o
main_menu_bar input.xrc /^ <object class="wxMenuBar" name="main_menu_bar">$/;" o
file_menu input.xrc /^ <object class="wxMenu" name="file_menu">$/;" o
file_menu_open_file input.xrc /^ <object class="wxMenuItem" name="file_menu_open_file">$/;" o
file_menu_close_window input.xrc /^ <object class="wxMenuItem" name="file_menu_close_window">$/;" o
tree_view input.xrc /^ <object class="wxTreeCtrl" name="tree_view" subclass="hachoir.wx.tree_view.tree_view_t">$/;" o
hex_view input.xrc /^ <object class="wxScrolledWindow" name="hex_view" subclass="hachoir.wx.hex_view.hex_view_/;" o
field_view input.xrc /^ <object class="wxListCtrl" name="field_view" subclass="hachoir.wx.field_view.field_view_/;" o
field_menu input.xrc /^ <object class="wxMenu" name="field_menu">$/;" o
field_menu_split input.xrc /^ <object class="wxMenu" name="field_menu_split">$/;" o
field_menu_split_bytes input.xrc /^ <object class="wxMenuItem" name="field_menu_split_bytes">$/;" o
field_menu_split_bits input.xrc /^ <object class="wxMenuItem" name="field_menu_split_bits">$/;" o
field_menu_convert_to_core_type input.xrc /^ <object class="wxMenu" name="field_menu_convert_to_core_type">$/;" o
field_menu_dump_to_disk input.xrc /^ <object class="wxMenuItem" name="field_menu_dump_to_disk">$/;" o
field_menu_parse_substream input.xrc /^ <object class="wxMenuItem" name="field_menu_parse_substream">$/;" o
field_menu_open_window_here input.xrc /^ <object class="wxMenuItem" name="field_menu_open_window_here">$/;" o
field_menu_address input.xrc /^ <object class="wxMenu" name="field_menu_address">$/;" o
field_menu_address_absolute input.xrc /^ <object class="wxMenuItem" name="field_menu_address_absolute">$/;" o
field_menu_address_relative input.xrc /^ <object class="wxMenuItem" name="field_menu_address_relative">$/;" o
field_menu_address_base input.xrc /^ <object class="wxMenu" name="field_menu_address_base">$/;" o
field_menu_address_base_hex input.xrc /^ <object class="wxMenuItem" name="field_menu_address_base_hex">$/;" o
field_menu_address_base_dec input.xrc /^ <object class="wxMenuItem" name="field_menu_address_base_dec">$/;" o
1 change: 1 addition & 0 deletions Units/simple-xrc.d/features
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
xpath
107 changes: 107 additions & 0 deletions Units/simple-xrc.d/input.xrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Taken from hachoir/wx/resource/hachoir_wx.xrc -->
<resource>
<object class="wxFrame" name="frame_view" subclass="hachoir.wx.frame_view.frame_view_t">
<title></title>
<object class="wxMenuBar" name="main_menu_bar">
<object class="wxMenu" name="file_menu">
<label>File</label>
<object class="wxMenuItem" name="file_menu_open_file">
<label>Open File...</label>
<accel>Ctrl-O</accel>
</object>
<object class="wxMenuItem" name="file_menu_close_window">
<label>Close Window</label>
<accel>Ctrl-W</accel>
</object>
</object>
</object>
<size>800, 600</size>
<style>wxDEFAULT_FRAME_STYLE</style>
<object class="wxSplitterWindow" name="">
<orientation>vertical</orientation>
<sashpos>150</sashpos>
<style>wxSP_LIVE_UPDATE</style>
<object class="wxTreeCtrl" name="tree_view" subclass="hachoir.wx.tree_view.tree_view_t">
<style>wxTR_TWIST_BUTTONS|wxTR_SINGLE|wxTR_DEFAULT_STYLE</style>
</object>
<object class="wxSplitterWindow" name="">
<orientation>horizontal</orientation>
<object class="wxScrolledWindow" name="hex_view" subclass="hachoir.wx.hex_view.hex_view_t">
<style>wxVSCROLL</style>
<font>
<size>11</size>
<family>modern</family>
<style>normal</style>
<weight>normal</weight>
<underlined>0</underlined>
<face>Monaco</face>
</font>
</object>
<object class="wxListCtrl" name="field_view" subclass="hachoir.wx.field_view.field_view_t">
<style>wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_VIRTUAL|wxLC_HRULES|wxLC_VRULES</style>
<font>
<size>11</size>
<family>modern</family>
<style>normal</style>
<weight>normal</weight>
<underlined>0</underlined>
<face>Monaco</face>
</font>
<tooltip>Right-click for extra fun!</tooltip>
</object>
<sashpos>200</sashpos>
<style>wxSP_LIVE_UPDATE</style>
</object>
</object>
</object>
<object class="wxMenu" name="field_menu">
<label>Field</label>
<object class="wxMenu" name="field_menu_split">
<label>Split</label>
<object class="wxMenuItem" name="field_menu_split_bytes">
<label>Bytes...</label>
</object>
<object class="wxMenuItem" name="field_menu_split_bits">
<label>Bits...</label>
</object>
</object>
<object class="wxMenu" name="field_menu_convert_to_core_type">
<label>Convert to Core Type</label>
</object>
<object class="wxMenuItem" name="field_menu_dump_to_disk">
<label>Dump To Disk...</label>
</object>
<object class="wxMenuItem" name="field_menu_parse_substream">
<label>Parse Sub-Stream</label>
</object>
<object class="wxMenuItem" name="field_menu_open_window_here">
<label>Open New Window Here</label>
</object>
<object class="separator"/>
<object class="wxMenu" name="field_menu_address">
<label>Address Offset</label>
<object class="wxMenuItem" name="field_menu_address_absolute">
<label>Absolute</label>
<radio>1</radio>
<checked>1</checked>
</object>
<object class="wxMenuItem" name="field_menu_address_relative">
<label>Relative</label>
<radio>1</radio>
</object>
</object>
<object class="wxMenu" name="field_menu_address_base">
<label>Address Base</label>
<object class="wxMenuItem" name="field_menu_address_base_hex">
<label>Hexadecimal</label>
<radio>1</radio>
<checked>1</checked>
</object>
<object class="wxMenuItem" name="field_menu_address_base_dec">
<label>Decimal</label>
<radio>1</radio>
</object>
</object>
</object>
</resource>
2 changes: 2 additions & 0 deletions docs/news/HEAD.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ The following parsers have been added:
* PkgConfig *optlib*: new parser
* I18nRubyGem *YAML based subparser* · Close #3533

* XRC *libxml*: new parser

Changes about parser specific kinds, roles, fields, and extras
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
1 change: 1 addition & 0 deletions main/parsers_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
PlistXMLParser, \
RelaxNGParser, \
SvgParser, \
XrcParser, \
XmlParser, \
XsltParser
#else
Expand Down
121 changes: 121 additions & 0 deletions parsers/xrc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
*
* Copyright (c) 2023, Masatake YAMATO
* Copyright (c) 2023, Red Hat, K.K.
*
* This source code is released for free distribution under the terms of the
* GNU General Public License version 2 or (at your option) any later version.
*
* This module contains functions for generating tags for XML Based Resource System (XRC) files
*
* Reference:
* - https://docs.wxwidgets.org/3.0/overview_xrc.html
*/

/*
* INCLUDE FILES
*/
#include "general.h" /* must always come first */

#include "xml.h"

#include "entry.h"
#include "parse.h"

/*
* DATA DECLARATIONS
*/

typedef enum {
K_OBJECT,
} xrcKind;

/*
* FUNCTION DECLARATIONS
*/

static void makeXRCTag (xmlNode *node,
const char *xpath,
const struct sTagXpathMakeTagSpec *spec,
struct sTagEntryInfo *tag,
void *userData);

/*
* DATA DEFINITIONS
*/

static kindDefinition XrcKinds [] = {
{ true, 'o', "object", "objects", }
};

static tagXpathTable xrcXpathMainTable[] = {
{ /* "//object/@name", */
"/resource//object/@name",
LXPATH_TABLE_DO_MAKE,
{ .makeTagSpec = { K_OBJECT, ROLE_DEFINITION_INDEX, makeXRCTag, } }
},
};

enum xrcXpathTable {
TABLE_MAIN
};

static tagXpathTableTable xrcXpathTableTable[] = {
[TABLE_MAIN] = { ARRAY_AND_SIZE(xrcXpathMainTable) },
};

/*
* FUNCTION DEFINITIONS
*/

static void makeXRCTag (xmlNode *node,
const char *xpath,
const struct sTagXpathMakeTagSpec *spec,
struct sTagEntryInfo *tag,
void *userData)
{
if (*tag->name == '\0')
return;

makeTagEntry (tag);
}

static void
findXrcTags (void)
{
scheduleRunningBaseparser (0);
}

static void
runXPathEngine(xmlSubparser *s,
xmlXPathContext *ctx, xmlNode *root)
{
findXMLTags (ctx, root, TABLE_MAIN, NULL);
}

static xmlSubparser xrcSubparser = {
.subparser = {
.direction = SUBPARSER_SUB_RUNS_BASE,
},
.runXPathEngine = runXPathEngine,
};

extern parserDefinition*
XrcParser (void)
{
static const char *const extensions [] = { "xrc", NULL };
parserDefinition* const def = parserNew ("XRC");
static parserDependency dependencies [] = {
[0] = { DEPTYPE_SUBPARSER, "XML", &xrcSubparser },
};

def->kindTable = XrcKinds;
def->kindCount = ARRAY_SIZE (XrcKinds);
def->extensions = extensions;
def->parser = findXrcTags;
def->tagXpathTableTable = xrcXpathTableTable;
def->tagXpathTableCount = ARRAY_SIZE (xrcXpathTableTable);
def->dependencies = dependencies;
def->dependencyCount = ARRAY_SIZE (dependencies);
return def;
}
1 change: 1 addition & 0 deletions source.mak
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ XML_SRCS = \
parsers/plist.c \
parsers/relaxng.c \
parsers/xml.c \
parsers/xrc.c \
parsers/xslt.c \
\
$(NULL)
Expand Down

0 comments on commit 472f4ed

Please sign in to comment.