1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-14 06:42:58 +08:00

feat(xml): add the basics of declarative XML support

This commit is contained in:
Gabor Kiss-Vamosi 2024-11-22 10:46:13 +01:00
parent db11e7bae5
commit fc5939dcff
114 changed files with 21316 additions and 5 deletions

View File

@ -1390,7 +1390,7 @@ menu "LVGL configuration"
default n
help
You won't be able to open URLs after enabling this feature.
Note that FFmpeg image decoder will always use lvgl file system.
Note that FFmpeg image decoder will always use lvgl file system.
endmenu
menu "Others"
@ -1591,7 +1591,8 @@ menu "LVGL configuration"
int "Font manager name max length"
depends on LV_USE_FONT_MANAGER
default 32
config LV_USE_XML
bool "Enable loading XML UIs runtime"
config LVGL_VERSION_MAJOR
int
default 9 # LVGL_VERSION_MAJOR

View File

@ -18,3 +18,4 @@ Other Components
obj_property
observer
snapshot
xml

View File

@ -0,0 +1,301 @@
.. _xml:
====================
XML - Declarative UI
====================
Introduction
------------
LVGL is capable of loading UI elements written in XML.
Although still under development, the basics are already functional, serving as a preview.
This declarative language serves as the backend for LVGL's UI editor (currently under development),
which enables faster and more maintainable UI implementation.
Note that, the UI editor is not required to utilize LVGL's XML loading capabilities.
Describing the UI in XML in a declarative manner offers several advantages:
- XML files can be loaded at runtime (e.g., from an SD card) to change the application build.
- XML is simpler to write than C, enabling people with different skill sets to create LVGL UIs.
- XML is textual data, making it easy to parse and manipulate with scripts.
- XML can be used to generate LVGL code in any language.
- XML helps to separate the view from the logic.
Currently supported features:
- Load XML components at runtime from file or data
- Nest components and widgets any deep
- Dynamically create instances of XML components in C
- Register images and font that can be accessed by name later in the XMLs
- Constants are working for widget and style properties
- Parameters can be defined and passed and used for components
- Basic built in widgets (label, slider, bar, button, etc)
- Style sheets and local styles that can be assigned to parts and states support the basic style properties
Limitations:
- Only basic widgets are supported with limited functionality.
- Only a few style properties are supported.
- Events are not supported yet.
- Animations are not supported yet.
- Subjects are not supported yet.
- The documentation is not complete yet.
Main Concept
~~~~~~~~~~~~
It's important to distinguish between widgets and components:
Widgets are the core building blocks of the UI and are not meant to be loaded at runtime
but rather compiled into the application. The main characteristics of widgets are:
- Similar to LVGL's built-in widgets.
- Built from classes.
- Have a large API with set/get/add/etc. functions.
- Support "internal widgets" (e.g., tabview's tabs, dropdown's list).
- Have custom and complex logic inside.
- Cannot be loaded from XML at runtime because custom code cannot be loaded.
Components are built from other components and widgets and can be loaded at runtime.
The main characteristics of components are:
- Built from widgets or other components.
- Can be used for styling widgets.
- Can contain widgets or other components.
- Cannot have custom C code.
- Can be loaded from XML at runtime as they describe only the visuals.
Components
----------
Overview
~~~~~~~~
In light of the above, only components can be loaded from XML.
An example of a ``my_button`` component looks like this:
.. code-block:: xml
<component>
<consts>
<px name="size" value="100"/>
<color name="orange" value="0xffa020"/>
</consts>
<api>
<prop name="btn_text" default="Apply" type="string"/>
</api>
<styles>
<style name="blue" bg_color="0x0000ff" radius="2"/>
<style name="red" bg_color="0xff0000"/>
</styles>
<view extends="lv_button" width="#size" styles="blue red:pressed">
<my_h3 text="$btn_text" align="center" color="#orange" style_text_color:checked="0x00ff00"/>
</view>
</component>
- ``<component>``: The root element.
- ``<consts>``: Constants with ``int``, ``px``, ``string``, ``color``, or ``style`` types.
Constants can later be referenced as ``#name``.
- ``<params>``: Parameters with ``int``, ``px``, ``string``, ``color``, or ``style`` types.
Parameters can later be referenced as ``$name``.
- ``<styles>``: ``<style>`` properties can be defined with names and properties.
- ``<view>``: Describes how the component looks. Can reference constants, parameters, and styles.
Naming conventions:
- A standard XML syntax is used.
- Lowercase letters with ``_`` separation are used for attribute names.
- The usual variable name rules apply for attribute and tag names: only letters, numbers, `'_'` and can't start with a number.
- LVGL API is followed as much as possible, e.g., ``align="center"``, ``bg_color="0xff0000"``.
- ``params`` can be referenced with ``$``
- ``consts`` can be referenced with ``#``
- ``styles`` can be attached to states and/or parts like ``styles="red blue:pressed green:focused:scrollbar"``
- Local styles can be used like ``<lv_label style_text_color="0xff0000" style_text_color:checked="0x00ff00" ``
Usage
~~~~~
Once a component is created (e.g., ``my_button``), it can be registered by calling either:
- ``lv_xml_component_register_from_file("A:lvgl/examples/others/xml/my_button.xml");``
- ``lv_xml_component_register_from_data("my_button", xml_data_of_my_button);``
These registration functions process the XML data and save some relevant data internally.
This is required to make LVGL recognize the components by name.
When loaded from a file, the file name is used as the component name.
After this, a new instance of any of the registered components can be created with:
``lv_obj_t * obj = lv_xml_create(lv_screen_active(), "my_button", NULL);``
The created widget is a normal LVGL widget that can be used like any other manually created widget.
The last parameter can be ``NULL`` or an attribute list, like this:
.. code-block:: c
/* Can be local */
char * my_button_attrs[] = {
"x", "10",
"y", "-10",
"align", "bottom_left",
"btn_text", "New button",
NULL, NULL,
};
lv_obj_t * btn1 = lv_xml_create(lv_screen_active(), "my_button", my_button_attrs);
Parameters
~~~~~~~~~~
It is possible to pass parameters to child components and widgets.
These parameters can be set on a parent widget or provided by the user.
Additionally, it's possible to use the extended widget's attributes
(see ``<view extends="...">``) when a widget or component is created.
This means that components and widgets inherit the API of the extended widget
as well.
The following example demonstrates parameter chaining and the use of the
``text`` label property on a component:
.. code-block:: xml
<!-- h3.xml -->
<component>
<view extends="lv_label"/>
</component>
.. code-block:: xml
<!-- red_button.xml -->
<component>
<api>
<prop type="string" name="btn_text" default="None"/>
</api>
<view extends="lv_button" style_radius="0" style_bg_color="0xff0000">
<h3 text="$btn_text"/>
</view>
</component>
.. code-block:: c
lv_xml_component_register_from_file("A:path/to/h3.xml");
lv_xml_component_register_from_file("A:path/to/red_button.xml");
/* Creates a button with "None" text */
lv_xml_create(lv_screen_active(), "red_button", NULL);
/* Use attributes to set the button text */
const char * attrs[] = {
"btn_text", "Click here",
NULL, NULL,
};
lv_xml_create(lv_screen_active(), "red_button", attrs);
Widgets
-------
Overview
~~~~~~~~
Widgets are written in C and compiled into the application.
They can be referenced from components, and their API can be used via the exposed attributes
(e.g., label text or slider value).
Usage
~~~~~
To make the widgets accessible from XML, an XML parser needs to be registered for each widget.
The XML parser for the slider looks like this:
.. code-block:: c
void * lv_xml_label_create(lv_xml_parser_state_t * state, const char ** attrs)
{
/* Create the label */
void * item = lv_label_create(lv_xml_state_get_parent(state));
return item;
}
void lv_xml_label_apply(lv_xml_parser_state_t * state, const char ** attrs)
{
void * item = lv_xml_state_get_item(state);
/*Apply the common properties, e.g. width, height, styles flags etc*/
lv_xml_obj_apply(state, attrs);
/* Apply the common properties, e.g., width, height, styles, flags, etc. */
lv_obj_xml_apply_attrs(state, item, attrs);
/* Process the label-specific attributes */
for(int i = 0; attrs[i]; i += 2) {
const char * name = attrs[i];
const char * value = attrs[i + 1];
if(lv_streq("text", name)) lv_label_set_text(item, value);
if(lv_streq("long_mode", name)) lv_label_set_long_mode(item, long_mode_text_to_enum_value(value));
}
}
/* Helper to convert the string to enum values */
static lv_label_long_mode_t long_mode_text_to_enum_value(const char * txt)
{
if(lv_streq("wrap", txt)) return LV_LABEL_LONG_WRAP;
if(lv_streq("scroll", txt)) return LV_LABEL_LONG_SCROLL;
LV_LOG_WARN("%s is an unknown value for label's long_mode", txt);
return 0; /* Return 0 in the absence of a better option. */
}
A widget XML process can be registered like
:cpp:expr:`lv_xml_widget_register("lv_label", lv_xml_label_create, lv_xml_label_apply);`
After this, a widget can be created like this:
.. code-block:: c
const char * attrs[] = {
"text", "Click here",
"align", "center",
NULL, NULL,
};
lv_xml_create(lv_screen_active(), "lv_label", attrs);
LVGL automatically registers its built-in widgets,
so only custom widgets need to be registered manually.
Images and Fonts
----------------
In an XML file, images and fonts can be referenced via a name like this:
``<lv_image src="image1" style_text_font="font1"/>``
The font and image names must be mapped to the actual resources in the following way:
.. code-block:: c
lv_xml_register_image("image1", "path/to/logo.png");
lv_xml_register_image("image2", &some_image_dsc);
lv_xml_register_font("font1", &arial_14);
The built-in fonts are automatically registered with names like
``"lv_montserrat_16"``.
The registration functions should be called after
:cpp:expr:`lv_init()` but before :cpp:expr:`lv_xml_create(...)`.
Example
-------
.. include:: ../../examples/others/xml/index.rst
.. _xml_api:
API
---

View File

@ -23,6 +23,7 @@ extern "C" {
#include "observer/lv_example_observer.h"
#include "snapshot/lv_example_snapshot.h"
#include "gestures/lv_example_gestures.h"
#include "xml/lv_example_xml.h"
/*********************
* DEFINES

View File

@ -0,0 +1,5 @@
Load components at runtime
--------------------------
.. lv_example:: others/xml/lv_example_xml_1
:language: c

View File

@ -0,0 +1,38 @@
/**
* @file lv_example_xml.h
*
*/
#ifndef LV_EXAMPLE_XML_H
#define LV_EXAMPLE_XML_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_example_xml_1(void);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_EXAMPLE_XML_H*/

View File

@ -0,0 +1,37 @@
#include "../../lv_examples.h"
#if LV_BUILD_EXAMPLES && LV_USE_XML
void lv_example_xml_1(void)
{
lv_xml_component_register_from_file("A:lvgl/examples/others/xml/my_h3.xml");
lv_xml_component_register_from_file("A:lvgl/examples/others/xml/my_card.xml");
lv_xml_component_register_from_file("A:lvgl/examples/others/xml/my_button.xml");
lv_xml_component_register_from_file("A:lvgl/examples/others/xml/view.xml");
lv_obj_t * obj = lv_xml_create(lv_screen_active(), "view", NULL);
lv_obj_set_pos(obj, 10, 10);
const char * my_button_attrs[] = {
"x", "10",
"y", "-10",
"align", "bottom_left",
"btn_text", "New button",
NULL, NULL,
};
lv_xml_component_unregister("my_button");
lv_xml_create(lv_screen_active(), "my_button", my_button_attrs);
const char * slider_attrs[] = {
"x", "200",
"y", "-15",
"align", "bottom_left",
"value", "30",
NULL, NULL,
};
lv_obj_t * slider = lv_xml_create(lv_screen_active(), "lv_slider", slider_attrs);
lv_obj_set_width(slider, 100);
}
#endif

View File

@ -0,0 +1,15 @@
<component>
<consts>
<px name="size" value="100"/>
<color name="orange" value="0xffa020"/>
</consts>
<api>
<prop name="btn_text" type="string"/>
</api>
<view extends="lv_button" width="#size">
<my_h3 text="$btn_text" align="center" color="#orange"/>
</view>
</component>

View File

@ -0,0 +1,23 @@
<component>
<consts>
<px name="size" value="100%"/>
</consts>
<api>
<prop name="title" type="string" default="No title"/>
<prop name="action" type="string" default="No action"/>
<prop name="bg_color" type="color" default="0xcccccc"/>
<prop name="btn_rel_style" type="style" />
<prop name="btn_pr_style" type="style" />
</api>
<styles>
<style name="gray" bg_color="0x888888"/>
<style name="blue" bg_color="0x0000ff"/>
</styles>
<view extends="lv_obj" style_radius="3" width="#size" height="content" style_bg_color="$bg_color" >
<lv_label text="$title" align="left_mid"/>
<my_button styles="$btn_rel_style $btn_pr_style:pressed" btn_text="$action" align="right_mid"/>
</view>
</component>

View File

@ -0,0 +1,12 @@
<component>
<api>
<prop name="color" type="color" default="0x000000"/>
<prop name="style" type="style"/>
</api>
<view extends="lv_label"
style_text_color="$color"
styles="$style"
style_text_font="lv_montserrat_18">
</view>
</component>

View File

@ -0,0 +1,25 @@
<component>
<consts>
<color name="light_blue" value="0xbbbbff"/>
<color name="dark_blue" value="0x000080"/>
</consts>
<styles>
<style name="btn_style" bg_color="#dark_blue" bg_opa="150"/>
<style name="btn_pr_style" bg_opa="255"/>
</styles>
<view extends="lv_obj" width="280" height="content" style_bg_color="#light_blue">
<lv_label text="Hello"/>
<my_card title="Card 1"
y="0"
btn_rel_style="btn_style"
btn_pr_style="btn_pr_style"/>
<my_card y="85"
bg_color="0xffaaaa"
action="Apply"
btn_rel_style="btn_style"
btn_pr_style="btn_pr_style"/>
</view>
</component>

View File

@ -1076,11 +1076,14 @@
#define LV_USE_FONT_MANAGER 0
#if LV_USE_FONT_MANAGER
/*Font manager name max length*/
/**Font manager name max length*/
#define LV_FONT_MANAGER_NAME_MAX_LEN 32
#endif
/** Enable loading XML UIs runtime */
#define LV_USE_XML 0
/*==================
* DEVICES
*==================*/

2
lvgl.h
View File

@ -94,6 +94,8 @@ extern "C" {
#include "src/others/ime/lv_ime_pinyin.h"
#include "src/others/file_explorer/lv_file_explorer.h"
#include "src/others/font_manager/lv_font_manager.h"
#include "src/others/xml/lv_xml.h"
#include "src/others/xml/lv_xml_component.h"
#include "src/libs/barcode/lv_barcode.h"
#include "src/libs/bin_decoder/lv_bin_decoder.h"

View File

@ -28,6 +28,7 @@ extern "C" {
#include "src/others/ime/lv_ime_pinyin_private.h"
#include "src/others/fragment/lv_fragment_private.h"
#include "src/others/observer/lv_observer_private.h"
#include "src/others/xml/lv_xml_private.h"
#include "src/libs/qrcode/lv_qrcode_private.h"
#include "src/libs/barcode/lv_barcode_private.h"
#include "src/libs/gif/lv_gif_private.h"

View File

@ -47,6 +47,7 @@
--exclude=../src/libs/tjpgd/tjpgd.h
--exclude=../src/libs/tjpgd/tjpgdcnf.h
--exclude=../src/libs/thorvg
--exclude=../src/libs/expat
--exclude=../src/libs/lz4
--exclude=../src/others/vg_lite_tvg/vg_lite.h
--exclude=../tests/unity/unity.c

13
src/libs/expat/add_lvgl_if.sh Executable file
View File

@ -0,0 +1,13 @@
#!/bin/bash
#Add LVGL #if LV_USE_THORVG_INTERNAL guard
#Usage
# find -name "*.cpp" | xargs ./add_lvgl_if.sh
# find -name "t*.h" | xargs ./add_lvgl_if.sh
sed '0,/\*\/$/ {/\*\/$/ {n; s|^|\n#include "../../lv_conf_internal.h"\n#if LV_USE_XML\n|}}' $@ -i
sed -i -e '$a\
\
#endif /* LV_USE_XML */\
' $@ -i

129
src/libs/expat/ascii.h Normal file
View File

@ -0,0 +1,129 @@
/*
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 1999-2000 Thai Open Source Software Center Ltd
Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2007 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "../../lv_conf_internal.h"
#if LV_USE_XML
#define ASCII_A 0x41
#define ASCII_B 0x42
#define ASCII_C 0x43
#define ASCII_D 0x44
#define ASCII_E 0x45
#define ASCII_F 0x46
#define ASCII_G 0x47
#define ASCII_H 0x48
#define ASCII_I 0x49
#define ASCII_J 0x4A
#define ASCII_K 0x4B
#define ASCII_L 0x4C
#define ASCII_M 0x4D
#define ASCII_N 0x4E
#define ASCII_O 0x4F
#define ASCII_P 0x50
#define ASCII_Q 0x51
#define ASCII_R 0x52
#define ASCII_S 0x53
#define ASCII_T 0x54
#define ASCII_U 0x55
#define ASCII_V 0x56
#define ASCII_W 0x57
#define ASCII_X 0x58
#define ASCII_Y 0x59
#define ASCII_Z 0x5A
#define ASCII_a 0x61
#define ASCII_b 0x62
#define ASCII_c 0x63
#define ASCII_d 0x64
#define ASCII_e 0x65
#define ASCII_f 0x66
#define ASCII_g 0x67
#define ASCII_h 0x68
#define ASCII_i 0x69
#define ASCII_j 0x6A
#define ASCII_k 0x6B
#define ASCII_l 0x6C
#define ASCII_m 0x6D
#define ASCII_n 0x6E
#define ASCII_o 0x6F
#define ASCII_p 0x70
#define ASCII_q 0x71
#define ASCII_r 0x72
#define ASCII_s 0x73
#define ASCII_t 0x74
#define ASCII_u 0x75
#define ASCII_v 0x76
#define ASCII_w 0x77
#define ASCII_x 0x78
#define ASCII_y 0x79
#define ASCII_z 0x7A
#define ASCII_0 0x30
#define ASCII_1 0x31
#define ASCII_2 0x32
#define ASCII_3 0x33
#define ASCII_4 0x34
#define ASCII_5 0x35
#define ASCII_6 0x36
#define ASCII_7 0x37
#define ASCII_8 0x38
#define ASCII_9 0x39
#define ASCII_TAB 0x09
#define ASCII_SPACE 0x20
#define ASCII_EXCL 0x21
#define ASCII_QUOT 0x22
#define ASCII_AMP 0x26
#define ASCII_APOS 0x27
#define ASCII_MINUS 0x2D
#define ASCII_PERIOD 0x2E
#define ASCII_COLON 0x3A
#define ASCII_SEMI 0x3B
#define ASCII_LT 0x3C
#define ASCII_EQUALS 0x3D
#define ASCII_GT 0x3E
#define ASCII_LSQB 0x5B
#define ASCII_RSQB 0x5D
#define ASCII_UNDERSCORE 0x5F
#define ASCII_LPAREN 0x28
#define ASCII_RPAREN 0x29
#define ASCII_FF 0x0C
#define ASCII_SLASH 0x2F
#define ASCII_HASH 0x23
#define ASCII_PIPE 0x7C
#define ASCII_COMMA 0x2C
#endif /* LV_USE_XML */

72
src/libs/expat/asciitab.h Normal file
View File

@ -0,0 +1,72 @@
/*
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "../../lv_conf_internal.h"
#if LV_USE_XML
/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,
/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
#endif /* LV_USE_XML */

1081
src/libs/expat/expat.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,151 @@
/* expat_config.h. Generated from expat_config.h.in by configure. */
#include "../../lv_conf_internal.h"
#if LV_USE_XML
/* expat_config.h.in. Generated from configure.ac by autoheader. */
#ifndef EXPAT_CONFIG_H
#define EXPAT_CONFIG_H 1
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
/* 1234 = LILENDIAN, 4321 = BIGENDIAN */
#define BYTEORDER 1234
#define XML_POOR_ENTROPY 1
/* Define to 1 if you have the `arc4random' function. */
/* #undef HAVE_ARC4RANDOM */
/* Define to 1 if you have the `arc4random_buf' function. */
/* #undef HAVE_ARC4RANDOM_BUF */
/* define if the compiler supports basic C++11 syntax */
/*#define HAVE_CXX11 1*/
/* Define to 1 if you have the <dlfcn.h> header file. */
/*#define HAVE_DLFCN_H 1*/
/* Define to 1 if you have the <fcntl.h> header file. */
/*#define HAVE_FCNTL_H 1*/
/* Define to 1 if you have the `getpagesize' function. */
/*#define HAVE_GETPAGESIZE 1*/
/* Define to 1 if you have the `getrandom' function. */
/*#define HAVE_GETRANDOM 1*/
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `bsd' library (-lbsd). */
/* #undef HAVE_LIBBSD */
/* Define to 1 if you have a working `mmap' system call. */
/*#define HAVE_MMAP 1*/
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
/*#define HAVE_STRINGS_H 1*/
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have `syscall' and `SYS_getrandom'. */
//#define HAVE_SYSCALL_GETRANDOM 0
/* Define to 1 if you have the <sys/param.h> header file. */
/*#define HAVE_SYS_PARAM_H 1*/
/* Define to 1 if you have the <sys/stat.h> header file. */
/*#define HAVE_SYS_STAT_H 1*/
/* Define to 1 if you have the <sys/types.h> header file. */
/*#define HAVE_SYS_TYPES_H 1*/
/* Define to 1 if you have the <unistd.h> header file. */
/*#define HAVE_UNISTD_H 1*/
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "expat"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "https://github.com/libexpat/libexpat/issues"
/* Define to the full name of this package. */
#define PACKAGE_NAME "expat"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "expat 2.6.3"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "expat"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "2.6.3"
/* Define to 1 if all of the C90 standard headers exist (not just the ones
required in a freestanding environment). This macro is provided for
backward compatibility; new code need not use it. */
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "2.6.3"
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
/* Define to allow retrieving the byte offsets for attribute names and values.
*/
/* #undef XML_ATTR_INFO */
/* Define to specify how much context to retain around the current parse
point, 0 to disable. */
#define XML_CONTEXT_BYTES 1024
/* Define to include code reading entropy from `/dev/urandom'. */
/*#define XML_DEV_URANDOM 1*/
/* Define to make parameter entity parsing functionality available. */
/*#define XML_DTD 1*/
/* Define as 1/0 to enable/disable support for general entities. */
#define XML_GE 0
/* Define to make XML Namespaces functionality available. */
/*#define XML_NS 1*/
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Define to `long int' if <sys/types.h> does not define. */
/* #undef off_t */
#endif // ndef EXPAT_CONFIG_H
#endif /* LV_USE_XML */

View File

@ -0,0 +1,171 @@
/*
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
Copyright (c) 2000-2004 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2001-2002 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016 Cristian Rodríguez <crrodriguez@opensuse.org>
Copyright (c) 2016-2019 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2018 Yury Gribov <tetra2005@gmail.com>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "../../lv_conf_internal.h"
#if LV_USE_XML
#ifndef Expat_External_INCLUDED
#define Expat_External_INCLUDED 1
/* External API definitions */
/* Expat tries very hard to make the API boundary very specifically
defined. There are two macros defined to control this boundary;
each of these can be defined before including this header to
achieve some different behavior, but doing so it not recommended or
tested frequently.
XMLCALL - The calling convention to use for all calls across the
"library boundary." This will default to cdecl, and
try really hard to tell the compiler that's what we
want.
XMLIMPORT - Whatever magic is needed to note that a function is
to be imported from a dynamically loaded library
(.dll, .so, or .sl, depending on your platform).
The XMLCALL macro was added in Expat 1.95.7. The only one which is
expected to be directly useful in client code is XMLCALL.
Note that on at least some Unix versions, the Expat library must be
compiled with the cdecl calling convention as the default since
system headers may assume the cdecl convention.
*/
#ifndef XMLCALL
# if defined(_MSC_VER)
# define XMLCALL __cdecl
# elif defined(__GNUC__) && defined(__i386) && ! defined(__INTEL_COMPILER)
# define XMLCALL __attribute__((cdecl))
# else
/* For any platform which uses this definition and supports more than
one calling convention, we need to extend this definition to
declare the convention used on that platform, if it's possible to
do so.
If this is the case for your platform, please file a bug report
with information on how to identify your platform via the C
pre-processor and how to specify the same calling convention as the
platform's malloc() implementation.
*/
# define XMLCALL
# endif
#endif /* not defined XMLCALL */
#if ! defined(XML_STATIC) && ! defined(XMLIMPORT)
# ifndef XML_BUILDING_EXPAT
/* using Expat from an application */
# if defined(_MSC_EXTENSIONS) && ! defined(__BEOS__) && ! defined(__CYGWIN__)
# define XMLIMPORT __declspec(dllimport)
# endif
# endif
#endif /* not defined XML_STATIC */
#ifndef XML_ENABLE_VISIBILITY
# define XML_ENABLE_VISIBILITY 0
#endif
#if ! defined(XMLIMPORT) && XML_ENABLE_VISIBILITY
# define XMLIMPORT __attribute__((visibility("default")))
#endif
/* If we didn't define it above, define it away: */
#ifndef XMLIMPORT
# define XMLIMPORT
#endif
#if defined(__GNUC__) \
&& (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))
# define XML_ATTR_MALLOC __attribute__((__malloc__))
#else
# define XML_ATTR_MALLOC
#endif
#if defined(__GNUC__) \
&& ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
# define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
#else
# define XML_ATTR_ALLOC_SIZE(x)
#endif
#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
#ifdef __cplusplus
extern "C" {
#endif
#ifdef XML_UNICODE_WCHAR_T
# ifndef XML_UNICODE
# define XML_UNICODE
# endif
# if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2)
# error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc"
# endif
#endif
#ifdef XML_UNICODE /* Information is UTF-16 encoded. */
# ifdef XML_UNICODE_WCHAR_T
typedef wchar_t XML_Char;
typedef wchar_t XML_LChar;
# else
typedef unsigned short XML_Char;
typedef char XML_LChar;
# endif /* XML_UNICODE_WCHAR_T */
#else /* Information is UTF-8 encoded. */
typedef char XML_Char;
typedef char XML_LChar;
#endif /* XML_UNICODE */
#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */
typedef long long XML_Index;
typedef unsigned long long XML_Size;
#else
typedef long XML_Index;
typedef unsigned long XML_Size;
#endif /* XML_LARGE_SIZE */
#ifdef __cplusplus
}
#endif
#endif /* not Expat_External_INCLUDED */
#endif /* LV_USE_XML */

View File

@ -0,0 +1,73 @@
/*
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "../../lv_conf_internal.h"
#if LV_USE_XML
/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */
/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML,
/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
#endif /* LV_USE_XML */

182
src/libs/expat/internal.h Normal file
View File

@ -0,0 +1,182 @@
/* internal.h
Internal definitions used by Expat. This is not needed to compile
client code.
The following calling convention macros are defined for frequently
called functions:
FASTCALL - Used for those internal functions that have a simple
body and a low number of arguments and local variables.
PTRCALL - Used for functions called though function pointers.
PTRFASTCALL - Like PTRCALL, but for low number of arguments.
inline - Used for selected internal functions for which inlining
may improve performance on some platforms.
Note: Use of these macros is based on judgement, not hard rules,
and therefore subject to change.
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2002-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2003 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2018 Yury Gribov <tetra2005@gmail.com>
Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <snild@sony.com>
Copyright (c) 2024 Taichi Haradaguchi <20001722@ymail.ne.jp>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "../../lv_conf_internal.h"
#if LV_USE_XML
#if defined(__GNUC__) && defined(__i386__) && ! defined(__MINGW32__)
/* We'll use this version by default only where we know it helps.
regparm() generates warnings on Solaris boxes. See SF bug #692878.
Instability reported with egcs on a RedHat Linux 7.3.
Let's comment out:
#define FASTCALL __attribute__((stdcall, regparm(3)))
and let's try this:
*/
# define FASTCALL __attribute__((regparm(3)))
# define PTRFASTCALL __attribute__((regparm(3)))
#endif
/* Using __fastcall seems to have an unexpected negative effect under
MS VC++, especially for function pointers, so we won't use it for
now on that platform. It may be reconsidered for a future release
if it can be made more effective.
Likely reason: __fastcall on Windows is like stdcall, therefore
the compiler cannot perform stack optimizations for call clusters.
*/
/* Make sure all of these are defined if they aren't already. */
#ifndef FASTCALL
# define FASTCALL
#endif
#ifndef PTRCALL
# define PTRCALL
#endif
#ifndef PTRFASTCALL
# define PTRFASTCALL
#endif
#ifndef XML_MIN_SIZE
# if ! defined(__cplusplus) && ! defined(inline)
# ifdef __GNUC__
# define inline __inline
# endif /* __GNUC__ */
# endif
#endif /* XML_MIN_SIZE */
#ifdef __cplusplus
# define inline inline
#else
# ifndef inline
# define inline
# endif
#endif
#include <limits.h> // ULONG_MAX
#if defined(_WIN32) \
&& (! defined(__USE_MINGW_ANSI_STDIO) \
|| (1 - __USE_MINGW_ANSI_STDIO - 1 == 0))
# define EXPAT_FMT_ULL(midpart) "%" midpart "I64u"
# if defined(_WIN64) // Note: modifiers "td" and "zu" do not work for MinGW
# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "I64d"
# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "I64u"
# else
# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "d"
# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "u"
# endif
#else
# define EXPAT_FMT_ULL(midpart) "%" midpart "llu"
# if ! defined(ULONG_MAX)
# error Compiler did not define ULONG_MAX for us
# elif ULONG_MAX == 18446744073709551615u // 2^64-1
# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "ld"
# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "lu"
# else
# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "d"
# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "u"
# endif
#endif
#ifndef UNUSED_P
# define UNUSED_P(p) (void)p
#endif
/* NOTE BEGIN If you ever patch these defaults to greater values
for non-attack XML payload in your environment,
please file a bug report with libexpat. Thank you!
*/
#define EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT \
100.0f
#define EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT \
8388608 // 8 MiB, 2^23
/* NOTE END */
#include "expat.h" // so we can use type XML_Parser below
#ifdef __cplusplus
extern "C" {
#endif
void _INTERNAL_trim_to_complete_utf8_characters(const char *from,
const char **fromLimRef);
#if defined(XML_GE) && XML_GE == 1
unsigned long long testingAccountingGetCountBytesDirect(XML_Parser parser);
unsigned long long testingAccountingGetCountBytesIndirect(XML_Parser parser);
const char *unsignedCharToPrintable(unsigned char c);
#endif
extern
#if ! defined(XML_TESTING)
const
#endif
XML_Bool g_reparseDeferralEnabledDefault; // written ONLY in runtests.c
#if defined(XML_TESTING)
extern unsigned int g_bytesScanned; // used for testing only
#endif
#ifdef __cplusplus
}
#endif
#endif /* LV_USE_XML */

View File

@ -0,0 +1,72 @@
/*
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "../../lv_conf_internal.h"
#if LV_USE_XML
/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME,
/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
#endif /* LV_USE_XML */

142
src/libs/expat/nametab.h Normal file
View File

@ -0,0 +1,142 @@
/*
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "../../lv_conf_internal.h"
#if LV_USE_XML
static const unsigned namingBitmap[] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x04000000,
0x87FFFFFE, 0x07FFFFFE, 0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,
0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFE00F, 0xFC31FFFF, 0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, 0xFFFF0003, 0xFFFFFFFF,
0xFFFF199F, 0x033FCFFF, 0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF, 0x00000000, 0x07FFFFFE,
0x000007FE, 0xFFFE0000, 0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060,
0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003, 0xFFF99FE0, 0x03C5FDFF,
0xB0000000, 0x00030003, 0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000,
0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001, 0xFFF99FE0, 0x23CDFDFF,
0xB0000000, 0x00000003, 0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000,
0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003, 0xFFFDDFE0, 0x03EFFDFF,
0x40000000, 0x00000003, 0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFE, 0x000D7FFF,
0x0000003F, 0x00000000, 0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000,
0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF, 0x0007DAED, 0x50000000,
0x82315001, 0x002C62AB, 0x40000000, 0xF580C900, 0x00000007, 0x02010800,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0FFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0x03FFFFFF, 0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF,
0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF, 0x00000000, 0x00004C40,
0x00000000, 0x00000000, 0x00000007, 0x00000000, 0x00000000, 0x00000000,
0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF, 0x001FFFFF, 0xFFFFFFFE,
0xFFFFFFFF, 0x07FFFFFF, 0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000000F,
0x00000000, 0x00000000, 0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE,
0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF, 0x00FFFFFF, 0x00000000,
0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000,
0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003, 0xFFFFD7C0, 0xFFFFFFFB,
0x547F7FFF, 0x000FFFFD, 0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF, 0x00000000, 0xFFFE0000,
0x027FFFFF, 0xFFFFFFFE, 0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF,
0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF, 0xFFFFFFFF, 0x7CFFFFFF,
0xFFEF7FFF, 0x03FF3DFF, 0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF,
0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF, 0xFFF987E4, 0xD36DFDFF,
0x5E003987, 0x001FFFC0, 0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1,
0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3, 0xD63DC7EC, 0xC3BFC718,
0x00803DC7, 0x0000FF80, 0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3,
0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3, 0xFFFDDFEC, 0xC3FFFDFF,
0x00803DCF, 0x0000FFC3, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000, 0xFEF02596, 0x3BFF6CAE,
0x03FF3F5F, 0x00000000, 0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF,
0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x1FFF0000, 0x00000002,
0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF, 0x661FFFFF, 0xFFFFFFFE,
0xFFFFFFFF, 0x77FFFFFF,
};
static const unsigned char nmstrtPages[] = {
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x09, 0x0A, 0x0B,
0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, 0x00, 0x14, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
};
static const unsigned char namePages[] = {
0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00, 0x00, 0x1F, 0x20, 0x21,
0x22, 0x23, 0x24, 0x25, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, 0x26, 0x14, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
};
#endif /* LV_USE_XML */

398
src/libs/expat/siphash.h Normal file
View File

@ -0,0 +1,398 @@
/* ==========================================================================
* siphash.h - SipHash-2-4 in a single header file
* --------------------------------------------------------------------------
* Derived by William Ahern from the reference implementation[1] published[2]
* by Jean-Philippe Aumasson and Daniel J. Berstein.
* Minimal changes by Sebastian Pipping and Victor Stinner on top, see below.
* Licensed under the CC0 Public Domain Dedication license.
*
* 1. https://www.131002.net/siphash/siphash24.c
* 2. https://www.131002.net/siphash/
* --------------------------------------------------------------------------
* HISTORY:
*
* 2020-10-03 (Sebastian Pipping)
* - Drop support for Visual Studio 9.0/2008 and earlier
*
* 2019-08-03 (Sebastian Pipping)
* - Mark part of sip24_valid as to be excluded from clang-format
* - Re-format code using clang-format 9
*
* 2018-07-08 (Anton Maklakov)
* - Add "fall through" markers for GCC's -Wimplicit-fallthrough
*
* 2017-11-03 (Sebastian Pipping)
* - Hide sip_tobin and sip_binof unless SIPHASH_TOBIN macro is defined
*
* 2017-07-25 (Vadim Zeitlin)
* - Fix use of SIPHASH_MAIN macro
*
* 2017-07-05 (Sebastian Pipping)
* - Use _SIP_ULL macro to not require a C++11 compiler if compiled as C++
* - Add const qualifiers at two places
* - Ensure <=80 characters line length (assuming tab width 4)
*
* 2017-06-23 (Victor Stinner)
* - Address Win64 compile warnings
*
* 2017-06-18 (Sebastian Pipping)
* - Clarify license note in the header
* - Address C89 issues:
* - Stop using inline keyword (and let compiler decide)
* - Replace _Bool by int
* - Turn macro siphash24 into a function
* - Address invalid conversion (void pointer) by explicit cast
* - Address lack of stdint.h for Visual Studio 2003 to 2008
* - Always expose sip24_valid (for self-tests)
*
* 2012-11-04 - Born. (William Ahern)
* --------------------------------------------------------------------------
* USAGE:
*
* SipHash-2-4 takes as input two 64-bit words as the key, some number of
* message bytes, and outputs a 64-bit word as the message digest. This
* implementation employs two data structures: a struct sipkey for
* representing the key, and a struct siphash for representing the hash
* state.
*
* For converting a 16-byte unsigned char array to a key, use either the
* macro sip_keyof or the routine sip_tokey. The former instantiates a
* compound literal key, while the latter requires a key object as a
* parameter.
*
* unsigned char secret[16];
* arc4random_buf(secret, sizeof secret);
* struct sipkey *key = sip_keyof(secret);
*
* For hashing a message, use either the convenience macro siphash24 or the
* routines sip24_init, sip24_update, and sip24_final.
*
* struct siphash state;
* void *msg;
* size_t len;
* uint64_t hash;
*
* sip24_init(&state, key);
* sip24_update(&state, msg, len);
* hash = sip24_final(&state);
*
* or
*
* hash = siphash24(msg, len, key);
*
* To convert the 64-bit hash value to a canonical 8-byte little-endian
* binary representation, use either the macro sip_binof or the routine
* sip_tobin. The former instantiates and returns a compound literal array,
* while the latter requires an array object as a parameter.
* --------------------------------------------------------------------------
* NOTES:
*
* o Neither sip_keyof, sip_binof, nor siphash24 will work with compilers
* lacking compound literal support. Instead, you must use the lower-level
* interfaces which take as parameters the temporary state objects.
*
* o Uppercase macros may evaluate parameters more than once. Lowercase
* macros should not exhibit any such side effects.
* ==========================================================================
*/
#include "../../lv_conf_internal.h"
#if LV_USE_XML
#ifndef SIPHASH_H
#define SIPHASH_H
#include <stddef.h> /* size_t */
#include <stdint.h> /* uint64_t uint32_t uint8_t */
/*
* Workaround to not require a C++11 compiler for using ULL suffix
* if this code is included and compiled as C++; related GCC warning is:
* warning: use of C++11 long long integer constant [-Wlong-long]
*/
#define SIP_ULL(high, low) ((((uint64_t)high) << 32) | (low))
#define SIP_ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
#define SIP_U32TO8_LE(p, v) \
(p)[0] = (uint8_t)((v) >> 0); \
(p)[1] = (uint8_t)((v) >> 8); \
(p)[2] = (uint8_t)((v) >> 16); \
(p)[3] = (uint8_t)((v) >> 24);
#define SIP_U64TO8_LE(p, v) \
SIP_U32TO8_LE((p) + 0, (uint32_t)((v) >> 0)); \
SIP_U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));
#define SIP_U8TO64_LE(p) \
(((uint64_t)((p)[0]) << 0) | ((uint64_t)((p)[1]) << 8) \
| ((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) \
| ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) \
| ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56))
#define SIPHASH_INITIALIZER {0, 0, 0, 0, {0}, 0, 0}
struct siphash {
uint64_t v0, v1, v2, v3;
unsigned char buf[8], *p;
uint64_t c;
}; /* struct siphash */
#define SIP_KEYLEN 16
struct sipkey {
uint64_t k[2];
}; /* struct sipkey */
#define sip_keyof(k) sip_tokey(&(struct sipkey){{0}}, (k))
static struct sipkey *
sip_tokey(struct sipkey *key, const void *src) {
key->k[0] = SIP_U8TO64_LE((const unsigned char *)src);
key->k[1] = SIP_U8TO64_LE((const unsigned char *)src + 8);
return key;
} /* sip_tokey() */
#ifdef SIPHASH_TOBIN
# define sip_binof(v) sip_tobin((unsigned char[8]){0}, (v))
static void *
sip_tobin(void *dst, uint64_t u64) {
SIP_U64TO8_LE((unsigned char *)dst, u64);
return dst;
} /* sip_tobin() */
#endif /* SIPHASH_TOBIN */
static void
sip_round(struct siphash *H, const int rounds) {
int i;
for (i = 0; i < rounds; i++) {
H->v0 += H->v1;
H->v1 = SIP_ROTL(H->v1, 13);
H->v1 ^= H->v0;
H->v0 = SIP_ROTL(H->v0, 32);
H->v2 += H->v3;
H->v3 = SIP_ROTL(H->v3, 16);
H->v3 ^= H->v2;
H->v0 += H->v3;
H->v3 = SIP_ROTL(H->v3, 21);
H->v3 ^= H->v0;
H->v2 += H->v1;
H->v1 = SIP_ROTL(H->v1, 17);
H->v1 ^= H->v2;
H->v2 = SIP_ROTL(H->v2, 32);
}
} /* sip_round() */
static struct siphash *
sip24_init(struct siphash *H, const struct sipkey *key) {
H->v0 = SIP_ULL(0x736f6d65U, 0x70736575U) ^ key->k[0];
H->v1 = SIP_ULL(0x646f7261U, 0x6e646f6dU) ^ key->k[1];
H->v2 = SIP_ULL(0x6c796765U, 0x6e657261U) ^ key->k[0];
H->v3 = SIP_ULL(0x74656462U, 0x79746573U) ^ key->k[1];
H->p = H->buf;
H->c = 0;
return H;
} /* sip24_init() */
#define sip_endof(a) (&(a)[sizeof(a) / sizeof *(a)])
static struct siphash *
sip24_update(struct siphash *H, const void *src, size_t len) {
const unsigned char *p = (const unsigned char *)src, *pe = p + len;
uint64_t m;
do {
while (p < pe && H->p < sip_endof(H->buf))
*H->p++ = *p++;
if (H->p < sip_endof(H->buf))
break;
m = SIP_U8TO64_LE(H->buf);
H->v3 ^= m;
sip_round(H, 2);
H->v0 ^= m;
H->p = H->buf;
H->c += 8;
} while (p < pe);
return H;
} /* sip24_update() */
static uint64_t
sip24_final(struct siphash *H) {
const char left = (char)(H->p - H->buf);
uint64_t b = (H->c + left) << 56;
switch (left) {
case 7:
b |= (uint64_t)H->buf[6] << 48;
/* fall through */
case 6:
b |= (uint64_t)H->buf[5] << 40;
/* fall through */
case 5:
b |= (uint64_t)H->buf[4] << 32;
/* fall through */
case 4:
b |= (uint64_t)H->buf[3] << 24;
/* fall through */
case 3:
b |= (uint64_t)H->buf[2] << 16;
/* fall through */
case 2:
b |= (uint64_t)H->buf[1] << 8;
/* fall through */
case 1:
b |= (uint64_t)H->buf[0] << 0;
/* fall through */
case 0:
break;
}
H->v3 ^= b;
sip_round(H, 2);
H->v0 ^= b;
H->v2 ^= 0xff;
sip_round(H, 4);
return H->v0 ^ H->v1 ^ H->v2 ^ H->v3;
} /* sip24_final() */
static uint64_t
siphash24(const void *src, size_t len, const struct sipkey *key) {
struct siphash state = SIPHASH_INITIALIZER;
return sip24_final(sip24_update(sip24_init(&state, key), src, len));
} /* siphash24() */
/*
* SipHash-2-4 output with
* k = 00 01 02 ...
* and
* in = (empty string)
* in = 00 (1 byte)
* in = 00 01 (2 bytes)
* in = 00 01 02 (3 bytes)
* ...
* in = 00 01 02 ... 3e (63 bytes)
*/
static int
sip24_valid(void) {
/* clang-format off */
static const unsigned char vectors[64][8] = {
{ 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, },
{ 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, },
{ 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, },
{ 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, },
{ 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, },
{ 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, },
{ 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, },
{ 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, },
{ 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, },
{ 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, },
{ 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, },
{ 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, },
{ 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, },
{ 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, },
{ 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, },
{ 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, },
{ 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, },
{ 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, },
{ 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, },
{ 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, },
{ 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, },
{ 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, },
{ 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, },
{ 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, },
{ 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, },
{ 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, },
{ 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, },
{ 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, },
{ 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, },
{ 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, },
{ 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, },
{ 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, },
{ 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, },
{ 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, },
{ 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, },
{ 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, },
{ 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, },
{ 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, },
{ 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, },
{ 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, },
{ 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, },
{ 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, },
{ 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, },
{ 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, },
{ 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, },
{ 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, },
{ 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, },
{ 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, },
{ 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, },
{ 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, },
{ 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, },
{ 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, },
{ 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, },
{ 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, },
{ 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, },
{ 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, },
{ 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, },
{ 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, },
{ 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, },
{ 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, },
{ 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, },
{ 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, },
{ 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, },
{ 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, }
};
/* clang-format on */
unsigned char in[64];
struct sipkey k;
size_t i;
sip_tokey(&k, "\000\001\002\003\004\005\006\007\010\011"
"\012\013\014\015\016\017");
for (i = 0; i < sizeof in; ++i) {
in[i] = (unsigned char)i;
if (siphash24(in, i, &k) != SIP_U8TO64_LE(vectors[i]))
return 0;
}
return 1;
} /* sip24_valid() */
#ifdef SIPHASH_MAIN
# include <stdio.h>
int
main(void) {
const int ok = sip24_valid();
if (ok)
puts("OK");
else
puts("FAIL");
return ! ok;
} /* main() */
#endif /* SIPHASH_MAIN */
#endif /* SIPHASH_H */
#endif /* LV_USE_XML */

72
src/libs/expat/utf8tab.h Normal file
View File

@ -0,0 +1,72 @@
/*
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "../../lv_conf_internal.h"
#if LV_USE_XML
/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4,
/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM,
#endif /* LV_USE_XML */

View File

@ -0,0 +1,54 @@
/*
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
Copyright (c) 2002 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2005 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2017-2023 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2023 Orgad Shaneh <orgad.shaneh@audiocodes.com>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "../../lv_conf_internal.h"
#if LV_USE_XML
#ifndef WINCONFIG_H
#define WINCONFIG_H
#ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#include <memory.h>
#include <string.h>
#endif /* ndef WINCONFIG_H */
#endif /* LV_USE_XML */

8567
src/libs/expat/xmlparse.c Normal file

File diff suppressed because it is too large Load Diff

1261
src/libs/expat/xmlrole.c Normal file

File diff suppressed because it is too large Load Diff

148
src/libs/expat/xmlrole.h Normal file
View File

@ -0,0 +1,148 @@
/*
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
Copyright (c) 2002 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2017-2024 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "../../lv_conf_internal.h"
#if LV_USE_XML
#ifndef XmlRole_INCLUDED
#define XmlRole_INCLUDED 1
#ifdef __VMS
/* 0 1 2 3 0 1 2 3
1234567890123456789012345678901 1234567890123456789012345678901 */
# define XmlPrologStateInitExternalEntity XmlPrologStateInitExternalEnt
#endif
#include "xmltok.h"
#ifdef __cplusplus
extern "C" {
#endif
enum {
XML_ROLE_ERROR = -1,
XML_ROLE_NONE = 0,
XML_ROLE_XML_DECL,
XML_ROLE_INSTANCE_START,
XML_ROLE_DOCTYPE_NONE,
XML_ROLE_DOCTYPE_NAME,
XML_ROLE_DOCTYPE_SYSTEM_ID,
XML_ROLE_DOCTYPE_PUBLIC_ID,
XML_ROLE_DOCTYPE_INTERNAL_SUBSET,
XML_ROLE_DOCTYPE_CLOSE,
XML_ROLE_GENERAL_ENTITY_NAME,
XML_ROLE_PARAM_ENTITY_NAME,
XML_ROLE_ENTITY_NONE,
XML_ROLE_ENTITY_VALUE,
XML_ROLE_ENTITY_SYSTEM_ID,
XML_ROLE_ENTITY_PUBLIC_ID,
XML_ROLE_ENTITY_COMPLETE,
XML_ROLE_ENTITY_NOTATION_NAME,
XML_ROLE_NOTATION_NONE,
XML_ROLE_NOTATION_NAME,
XML_ROLE_NOTATION_SYSTEM_ID,
XML_ROLE_NOTATION_NO_SYSTEM_ID,
XML_ROLE_NOTATION_PUBLIC_ID,
XML_ROLE_ATTRIBUTE_NAME,
XML_ROLE_ATTRIBUTE_TYPE_CDATA,
XML_ROLE_ATTRIBUTE_TYPE_ID,
XML_ROLE_ATTRIBUTE_TYPE_IDREF,
XML_ROLE_ATTRIBUTE_TYPE_IDREFS,
XML_ROLE_ATTRIBUTE_TYPE_ENTITY,
XML_ROLE_ATTRIBUTE_TYPE_ENTITIES,
XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN,
XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS,
XML_ROLE_ATTRIBUTE_ENUM_VALUE,
XML_ROLE_ATTRIBUTE_NOTATION_VALUE,
XML_ROLE_ATTLIST_NONE,
XML_ROLE_ATTLIST_ELEMENT_NAME,
XML_ROLE_IMPLIED_ATTRIBUTE_VALUE,
XML_ROLE_REQUIRED_ATTRIBUTE_VALUE,
XML_ROLE_DEFAULT_ATTRIBUTE_VALUE,
XML_ROLE_FIXED_ATTRIBUTE_VALUE,
XML_ROLE_ELEMENT_NONE,
XML_ROLE_ELEMENT_NAME,
XML_ROLE_CONTENT_ANY,
XML_ROLE_CONTENT_EMPTY,
XML_ROLE_CONTENT_PCDATA,
XML_ROLE_GROUP_OPEN,
XML_ROLE_GROUP_CLOSE,
XML_ROLE_GROUP_CLOSE_REP,
XML_ROLE_GROUP_CLOSE_OPT,
XML_ROLE_GROUP_CLOSE_PLUS,
XML_ROLE_GROUP_CHOICE,
XML_ROLE_GROUP_SEQUENCE,
XML_ROLE_CONTENT_ELEMENT,
XML_ROLE_CONTENT_ELEMENT_REP,
XML_ROLE_CONTENT_ELEMENT_OPT,
XML_ROLE_CONTENT_ELEMENT_PLUS,
XML_ROLE_PI,
XML_ROLE_COMMENT,
#ifdef XML_DTD
XML_ROLE_TEXT_DECL,
XML_ROLE_IGNORE_SECT,
XML_ROLE_INNER_PARAM_ENTITY_REF,
#endif /* XML_DTD */
XML_ROLE_PARAM_ENTITY_REF
};
typedef struct prolog_state {
int(PTRCALL *handler)(struct prolog_state *state, int tok, const char *ptr,
const char *end, const ENCODING *enc);
unsigned level;
int role_none;
#ifdef XML_DTD
unsigned includeLevel;
int documentEntity;
int inEntityValue;
#endif /* XML_DTD */
} PROLOG_STATE;
void XmlPrologStateInit(PROLOG_STATE *state);
#ifdef XML_DTD
void XmlPrologStateInitExternalEntity(PROLOG_STATE *state);
#endif /* XML_DTD */
#define XmlTokenRole(state, tok, ptr, end, enc) \
(((state)->handler)(state, tok, ptr, end, enc))
#ifdef __cplusplus
}
#endif
#endif /* not XmlRole_INCLUDED */
#endif /* LV_USE_XML */

1678
src/libs/expat/xmltok.c Normal file

File diff suppressed because it is too large Load Diff

327
src/libs/expat/xmltok.h Normal file
View File

@ -0,0 +1,327 @@
/*
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2002-2005 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "../../lv_conf_internal.h"
#if LV_USE_XML
#ifndef XmlTok_INCLUDED
#define XmlTok_INCLUDED 1
#ifdef __cplusplus
extern "C" {
#endif
/* The following token may be returned by XmlContentTok */
#define XML_TOK_TRAILING_RSQB \
-5 /* ] or ]] at the end of the scan; might be \
start of illegal ]]> sequence */
/* The following tokens may be returned by both XmlPrologTok and
XmlContentTok.
*/
#define XML_TOK_NONE -4 /* The string to be scanned is empty */
#define XML_TOK_TRAILING_CR \
-3 /* A CR at the end of the scan; \
might be part of CRLF sequence */
#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
#define XML_TOK_PARTIAL -1 /* only part of a token */
#define XML_TOK_INVALID 0
/* The following tokens are returned by XmlContentTok; some are also
returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok.
*/
#define XML_TOK_START_TAG_WITH_ATTS 1
#define XML_TOK_START_TAG_NO_ATTS 2
#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag <e/> */
#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4
#define XML_TOK_END_TAG 5
#define XML_TOK_DATA_CHARS 6
#define XML_TOK_DATA_NEWLINE 7
#define XML_TOK_CDATA_SECT_OPEN 8
#define XML_TOK_ENTITY_REF 9
#define XML_TOK_CHAR_REF 10 /* numeric character reference */
/* The following tokens may be returned by both XmlPrologTok and
XmlContentTok.
*/
#define XML_TOK_PI 11 /* processing instruction */
#define XML_TOK_XML_DECL 12 /* XML decl or text decl */
#define XML_TOK_COMMENT 13
#define XML_TOK_BOM 14 /* Byte order mark */
/* The following tokens are returned only by XmlPrologTok */
#define XML_TOK_PROLOG_S 15
#define XML_TOK_DECL_OPEN 16 /* <!foo */
#define XML_TOK_DECL_CLOSE 17 /* > */
#define XML_TOK_NAME 18
#define XML_TOK_NMTOKEN 19
#define XML_TOK_POUND_NAME 20 /* #name */
#define XML_TOK_OR 21 /* | */
#define XML_TOK_PERCENT 22
#define XML_TOK_OPEN_PAREN 23
#define XML_TOK_CLOSE_PAREN 24
#define XML_TOK_OPEN_BRACKET 25
#define XML_TOK_CLOSE_BRACKET 26
#define XML_TOK_LITERAL 27
#define XML_TOK_PARAM_ENTITY_REF 28
#define XML_TOK_INSTANCE_START 29
/* The following occur only in element type declarations */
#define XML_TOK_NAME_QUESTION 30 /* name? */
#define XML_TOK_NAME_ASTERISK 31 /* name* */
#define XML_TOK_NAME_PLUS 32 /* name+ */
#define XML_TOK_COND_SECT_OPEN 33 /* <![ */
#define XML_TOK_COND_SECT_CLOSE 34 /* ]]> */
#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */
#define XML_TOK_COMMA 38
/* The following token is returned only by XmlAttributeValueTok */
#define XML_TOK_ATTRIBUTE_VALUE_S 39
/* The following token is returned only by XmlCdataSectionTok */
#define XML_TOK_CDATA_SECT_CLOSE 40
/* With namespace processing this is returned by XmlPrologTok for a
name with a colon.
*/
#define XML_TOK_PREFIXED_NAME 41
#ifdef XML_DTD
# define XML_TOK_IGNORE_SECT 42
#endif /* XML_DTD */
#ifdef XML_DTD
# define XML_N_STATES 4
#else /* not XML_DTD */
# define XML_N_STATES 3
#endif /* not XML_DTD */
#define XML_PROLOG_STATE 0
#define XML_CONTENT_STATE 1
#define XML_CDATA_SECTION_STATE 2
#ifdef XML_DTD
# define XML_IGNORE_SECTION_STATE 3
#endif /* XML_DTD */
#define XML_N_LITERAL_TYPES 2
#define XML_ATTRIBUTE_VALUE_LITERAL 0
#define XML_ENTITY_VALUE_LITERAL 1
/* The size of the buffer passed to XmlUtf8Encode must be at least this. */
#define XML_UTF8_ENCODE_MAX 4
/* The size of the buffer passed to XmlUtf16Encode must be at least this. */
#define XML_UTF16_ENCODE_MAX 2
typedef struct position {
/* first line and first column are 0 not 1 */
XML_Size lineNumber;
XML_Size columnNumber;
} POSITION;
typedef struct {
const char *name;
const char *valuePtr;
const char *valueEnd;
char normalized;
} ATTRIBUTE;
struct encoding;
typedef struct encoding ENCODING;
typedef int(PTRCALL *SCANNER)(const ENCODING *, const char *, const char *,
const char **);
enum XML_Convert_Result {
XML_CONVERT_COMPLETED = 0,
XML_CONVERT_INPUT_INCOMPLETE = 1,
XML_CONVERT_OUTPUT_EXHAUSTED
= 2 /* and therefore potentially input remaining as well */
};
struct encoding {
SCANNER scanners[XML_N_STATES];
SCANNER literalScanners[XML_N_LITERAL_TYPES];
int(PTRCALL *nameMatchesAscii)(const ENCODING *, const char *, const char *,
const char *);
int(PTRFASTCALL *nameLength)(const ENCODING *, const char *);
const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *);
int(PTRCALL *getAtts)(const ENCODING *enc, const char *ptr, int attsMax,
ATTRIBUTE *atts);
int(PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr);
int(PTRCALL *predefinedEntityName)(const ENCODING *, const char *,
const char *);
void(PTRCALL *updatePosition)(const ENCODING *, const char *ptr,
const char *end, POSITION *);
int(PTRCALL *isPublicId)(const ENCODING *enc, const char *ptr,
const char *end, const char **badPtr);
enum XML_Convert_Result(PTRCALL *utf8Convert)(const ENCODING *enc,
const char **fromP,
const char *fromLim, char **toP,
const char *toLim);
enum XML_Convert_Result(PTRCALL *utf16Convert)(const ENCODING *enc,
const char **fromP,
const char *fromLim,
unsigned short **toP,
const unsigned short *toLim);
int minBytesPerChar;
char isUtf8;
char isUtf16;
};
/* Scan the string starting at ptr until the end of the next complete
token, but do not scan past eptr. Return an integer giving the
type of token.
Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set.
Return XML_TOK_PARTIAL when the string does not contain a complete
token; nextTokPtr will not be set.
Return XML_TOK_INVALID when the string does not start a valid
token; nextTokPtr will be set to point to the character which made
the token invalid.
Otherwise the string starts with a valid token; nextTokPtr will be
set to point to the character following the end of that token.
Each data character counts as a single token, but adjacent data
characters may be returned together. Similarly for characters in
the prolog outside literals, comments and processing instructions.
*/
#define XmlTok(enc, state, ptr, end, nextTokPtr) \
(((enc)->scanners[state])(enc, ptr, end, nextTokPtr))
#define XmlPrologTok(enc, ptr, end, nextTokPtr) \
XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
#define XmlContentTok(enc, ptr, end, nextTokPtr) \
XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \
XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
#ifdef XML_DTD
# define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \
XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr)
#endif /* XML_DTD */
/* This is used for performing a 2nd-level tokenization on the content
of a literal that has already been returned by XmlTok.
*/
#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \
(((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr))
#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \
XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \
XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \
(((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2))
#define XmlNameLength(enc, ptr) (((enc)->nameLength)(enc, ptr))
#define XmlSkipS(enc, ptr) (((enc)->skipS)(enc, ptr))
#define XmlGetAttributes(enc, ptr, attsMax, atts) \
(((enc)->getAtts)(enc, ptr, attsMax, atts))
#define XmlCharRefNumber(enc, ptr) (((enc)->charRefNumber)(enc, ptr))
#define XmlPredefinedEntityName(enc, ptr, end) \
(((enc)->predefinedEntityName)(enc, ptr, end))
#define XmlUpdatePosition(enc, ptr, end, pos) \
(((enc)->updatePosition)(enc, ptr, end, pos))
#define XmlIsPublicId(enc, ptr, end, badPtr) \
(((enc)->isPublicId)(enc, ptr, end, badPtr))
#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \
(((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim))
#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \
(((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim))
typedef struct {
ENCODING initEnc;
const ENCODING **encPtr;
} INIT_ENCODING;
int XmlParseXmlDecl(int isGeneralTextEntity, const ENCODING *enc,
const char *ptr, const char *end, const char **badPtr,
const char **versionPtr, const char **versionEndPtr,
const char **encodingNamePtr,
const ENCODING **namedEncodingPtr, int *standalonePtr);
int XmlInitEncoding(INIT_ENCODING *p, const ENCODING **encPtr,
const char *name);
const ENCODING *XmlGetUtf8InternalEncoding(void);
const ENCODING *XmlGetUtf16InternalEncoding(void);
int FASTCALL XmlUtf8Encode(int charNumber, char *buf);
int FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf);
int XmlSizeOfUnknownEncoding(void);
typedef int(XMLCALL *CONVERTER)(void *userData, const char *p);
ENCODING *XmlInitUnknownEncoding(void *mem, int *table, CONVERTER convert,
void *userData);
int XmlParseXmlDeclNS(int isGeneralTextEntity, const ENCODING *enc,
const char *ptr, const char *end, const char **badPtr,
const char **versionPtr, const char **versionEndPtr,
const char **encodingNamePtr,
const ENCODING **namedEncodingPtr, int *standalonePtr);
int XmlInitEncodingNS(INIT_ENCODING *p, const ENCODING **encPtr,
const char *name);
const ENCODING *XmlGetUtf8InternalEncodingNS(void);
const ENCODING *XmlGetUtf16InternalEncodingNS(void);
ENCODING *XmlInitUnknownEncodingNS(void *mem, int *table, CONVERTER convert,
void *userData);
#ifdef __cplusplus
}
#endif
#endif /* not XmlTok_INCLUDED */
#endif /* LV_USE_XML */

1825
src/libs/expat/xmltok_impl.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,80 @@
/*
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
Copyright (c) 2017-2019 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "../../lv_conf_internal.h"
#if LV_USE_XML
enum {
BT_NONXML, /* e.g. noncharacter-FFFF */
BT_MALFORM, /* illegal, with regard to encoding */
BT_LT, /* less than = "<" */
BT_AMP, /* ampersand = "&" */
BT_RSQB, /* right square bracket = "[" */
BT_LEAD2, /* lead byte of a 2-byte UTF-8 character */
BT_LEAD3, /* lead byte of a 3-byte UTF-8 character */
BT_LEAD4, /* lead byte of a 4-byte UTF-8 character */
BT_TRAIL, /* trailing unit, e.g. second 16-bit unit of a 4-byte char. */
BT_CR, /* carriage return = "\r" */
BT_LF, /* line feed = "\n" */
BT_GT, /* greater than = ">" */
BT_QUOT, /* quotation character = "\"" */
BT_APOS, /* apostrophe = "'" */
BT_EQUALS, /* equal sign = "=" */
BT_QUEST, /* question mark = "?" */
BT_EXCL, /* exclamation mark = "!" */
BT_SOL, /* solidus, slash = "/" */
BT_SEMI, /* semicolon = ";" */
BT_NUM, /* number sign = "#" */
BT_LSQB, /* left square bracket = "[" */
BT_S, /* white space, e.g. "\t", " "[, "\r"] */
BT_NMSTRT, /* non-hex name start letter = "G".."Z" + "g".."z" + "_" */
BT_COLON, /* colon = ":" */
BT_HEX, /* hex letter = "A".."F" + "a".."f" */
BT_DIGIT, /* digit = "0".."9" */
BT_NAME, /* dot and middle dot = "." + chr(0xb7) */
BT_MINUS, /* minus = "-" */
BT_OTHER, /* known not to be a name or name start character */
BT_NONASCII, /* might be a name or name start character */
BT_PERCNT, /* percent sign = "%" */
BT_LPAR, /* left parenthesis = "(" */
BT_RPAR, /* right parenthesis = "(" */
BT_AST, /* asterisk = "*" */
BT_PLUS, /* plus sign = "+" */
BT_COMMA, /* comma = "," */
BT_VERBAR /* vertical bar = "|" */
};
#include <stddef.h>
#endif /* LV_USE_XML */

128
src/libs/expat/xmltok_ns.c Normal file
View File

@ -0,0 +1,128 @@
/* This file is included!
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
Copyright (c) 2002 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2002 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2017-2021 Sebastian Pipping <sebastian@pipping.org>
Licensed under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "../../lv_conf_internal.h"
#if LV_USE_XML
#ifdef XML_TOK_NS_C
const ENCODING *
NS(XmlGetUtf8InternalEncoding)(void) {
return &ns(internal_utf8_encoding).enc;
}
const ENCODING *
NS(XmlGetUtf16InternalEncoding)(void) {
# if BYTEORDER == 1234
return &ns(internal_little2_encoding).enc;
# elif BYTEORDER == 4321
return &ns(internal_big2_encoding).enc;
# else
const short n = 1;
return (*(const char *)&n ? &ns(internal_little2_encoding).enc
: &ns(internal_big2_encoding).enc);
# endif
}
static const ENCODING *const NS(encodings)[] = {
&ns(latin1_encoding).enc, &ns(ascii_encoding).enc,
&ns(utf8_encoding).enc, &ns(big2_encoding).enc,
&ns(big2_encoding).enc, &ns(little2_encoding).enc,
&ns(utf8_encoding).enc /* NO_ENC */
};
static int PTRCALL
NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr) {
return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_PROLOG_STATE,
ptr, end, nextTokPtr);
}
static int PTRCALL
NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr) {
return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_CONTENT_STATE,
ptr, end, nextTokPtr);
}
int
NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr,
const char *name) {
int i = getEncodingIndex(name);
if (i == UNKNOWN_ENC)
return 0;
SET_INIT_ENC_INDEX(p, i);
p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog);
p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent);
p->initEnc.updatePosition = initUpdatePosition;
p->encPtr = encPtr;
*encPtr = &(p->initEnc);
return 1;
}
static const ENCODING *
NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) {
# define ENCODING_MAX 128
char buf[ENCODING_MAX] = "";
char *p = buf;
int i;
XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1);
if (ptr != end)
return 0;
*p = 0;
if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2)
return enc;
i = getEncodingIndex(buf);
if (i == UNKNOWN_ENC)
return 0;
return NS(encodings)[i];
}
int
NS(XmlParseXmlDecl)(int isGeneralTextEntity, const ENCODING *enc,
const char *ptr, const char *end, const char **badPtr,
const char **versionPtr, const char **versionEndPtr,
const char **encodingName, const ENCODING **encoding,
int *standalone) {
return doParseXmlDecl(NS(findEncoding), isGeneralTextEntity, enc, ptr, end,
badPtr, versionPtr, versionEndPtr, encodingName,
encoding, standalone);
}
#endif /* XML_TOK_NS_C */
#endif /* LV_USE_XML */

View File

@ -3436,7 +3436,7 @@
#endif
#if LV_USE_FONT_MANAGER
/*Font manager name max length*/
/**Font manager name max length*/
#ifndef LV_FONT_MANAGER_NAME_MAX_LEN
#ifdef CONFIG_LV_FONT_MANAGER_NAME_MAX_LEN
#define LV_FONT_MANAGER_NAME_MAX_LEN CONFIG_LV_FONT_MANAGER_NAME_MAX_LEN
@ -3447,6 +3447,15 @@
#endif
/** Enable loading XML UIs runtime */
#ifndef LV_USE_XML
#ifdef CONFIG_LV_USE_XML
#define LV_USE_XML CONFIG_LV_USE_XML
#else
#define LV_USE_XML 0
#endif
#endif
/*==================
* DEVICES
*==================*/

View File

@ -6,7 +6,6 @@
/*********************
* INCLUDES
*********************/
#include "others/sysmon/lv_sysmon_private.h"
#include "misc/lv_timer_private.h"
#include "misc/lv_profiler_builtin_private.h"
#include "misc/lv_anim_private.h"
@ -39,6 +38,8 @@
#include "themes/simple/lv_theme_simple.h"
#include "misc/lv_fs.h"
#include "osal/lv_os_private.h"
#include "others/sysmon/lv_sysmon_private.h"
#include "others/xml/lv_xml.h"
#if LV_USE_NEMA_GFX
#include "draw/nema_gfx/lv_draw_nema_gfx.h"
@ -357,6 +358,10 @@ void lv_init(void)
lv_ffmpeg_init();
#endif
#if LV_USE_XML
lv_xml_init();
#endif
lv_initialized = true;
LV_LOG_TRACE("finished");

View File

@ -348,6 +348,11 @@ typedef struct _lv_sysmon_perf_info_t lv_sysmon_perf_info_t;
#endif /*LV_USE_SYSMON*/
typedef struct _lv_xml_component_ctx_t lv_xml_component_ctx_t;
typedef struct _lv_xml_parser_state_t lv_xml_parser_state_t;
#endif /*__ASSEMBLY__*/
/**********************

389
src/others/xml/lv_xml.c Normal file
View File

@ -0,0 +1,389 @@
/**
* @file lv_xml.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_xml.h"
#if LV_USE_XML
#include "lv_xml_base_types.h"
#include "lv_xml_parser.h"
#include "lv_xml_component.h"
#include "lv_xml_component_private.h"
#include "lv_xml_widget.h"
#include "lv_xml_style.h"
#include "lv_xml.h"
#include "lv_xml_utils.h"
#include "lv_xml_private.h"
#include "parsers/lv_xml_obj_parser.h"
#include "parsers/lv_xml_button_parser.h"
#include "parsers/lv_xml_label_parser.h"
#include "parsers/lv_xml_image_parser.h"
#include "parsers/lv_xml_slider_parser.h"
#include "parsers/lv_xml_tabview_parser.h"
#include "parsers/lv_xml_chart_parser.h"
#include "../../libs/expat/expat.h"
#include "../../draw/lv_draw_image.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void view_start_element_handler(void * user_data, const char * name, const char ** attrs);
static void view_end_element_handler(void * user_data, const char * name);
/**********************
* STATIC VARIABLES
**********************/
static lv_ll_t font_ll;
static lv_ll_t image_ll;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void lv_xml_init(void)
{
lv_ll_init(&font_ll, sizeof(lv_xml_font_t));
lv_ll_init(&image_ll, sizeof(lv_xml_image_t));
#if LV_FONT_MONTSERRAT_14
lv_xml_register_font("lv_montserrat_14", &lv_font_montserrat_14);
#endif
#if LV_FONT_MONTSERRAT_16
lv_xml_register_font("lv_montserrat_16", &lv_font_montserrat_16);
#endif
#if LV_FONT_MONTSERRAT_18
lv_xml_register_font("lv_montserrat_18", &lv_font_montserrat_18);
#endif
#if LV_FONT_MONTSERRAT_20
lv_xml_register_font("lv_montserrat_20", &lv_font_montserrat_20);
#endif
lv_xml_component_init();
lv_xml_widget_register("lv_obj", lv_xml_obj_create, lv_xml_obj_apply);
lv_xml_widget_register("lv_button", lv_xml_button_create, lv_xml_button_apply);
lv_xml_widget_register("lv_label", lv_xml_label_create, lv_xml_label_apply);
lv_xml_widget_register("lv_image", lv_xml_image_create, lv_xml_image_apply);
lv_xml_widget_register("lv_slider", lv_xml_slider_create, lv_xml_slider_apply);
lv_xml_widget_register("lv_tabview", lv_xml_tabview_create, lv_xml_tabview_apply);
lv_xml_widget_register("lv_tabview-tab_bar", lv_xml_tabview_tab_bar_create, lv_xml_tabview_tab_bar_apply);
lv_xml_widget_register("lv_tabview-tab", lv_xml_tabview_tab_create, lv_xml_tabview_tab_apply);
lv_xml_widget_register("lv_chart", lv_xml_chart_create, lv_xml_chart_apply);
lv_xml_widget_register("lv_chart-cursor", lv_xml_chart_cursor_create, lv_xml_chart_cursor_apply);
lv_xml_widget_register("lv_chart-series", lv_xml_chart_series_create, lv_xml_chart_series_apply);
}
lv_obj_t * lv_xml_create_from_ctx(lv_obj_t * parent, lv_xml_component_ctx_t * parent_ctx, lv_xml_component_ctx_t * ctx,
const char ** attrs)
{
/* Initialize the parser state */
lv_xml_parser_state_t state;
lv_xml_parser_state_init(&state);
state.ctx = *ctx;
state.parent = parent;
state.parent_attrs = attrs;
state.parent_ctx = parent_ctx;
lv_obj_t ** parent_node = lv_ll_ins_head(&state.parent_ll);
*parent_node = parent;
/* Create an XML parser and set handlers */
XML_Parser parser = XML_ParserCreate(NULL);
XML_SetUserData(parser, &state);
XML_SetElementHandler(parser, view_start_element_handler, view_end_element_handler);
/* Parse the XML */
if(XML_Parse(parser, ctx->view_def, lv_strlen(ctx->view_def), XML_TRUE) == XML_STATUS_ERROR) {
LV_LOG_WARN("XML parsing error: %s on line %lu", XML_ErrorString(XML_GetErrorCode(parser)),
XML_GetCurrentLineNumber(parser));
XML_ParserFree(parser);
return NULL;
}
state.item = state.view;
if(attrs) {
ctx->root_widget->apply_cb(&state, attrs);
}
lv_ll_clear(&state.parent_ll);
XML_ParserFree(parser);
return state.view;
}
lv_obj_t * lv_xml_create(lv_obj_t * parent, const char * name, const char ** attrs)
{
lv_obj_t * item = NULL;
/* Select the widget specific parser type based on the name */
lv_widget_processor_t * p = lv_xml_widget_get_processor(name);
if(p) {
lv_xml_parser_state_t state;
lv_xml_parser_state_init(&state);
state.parent = parent;
state.item = p->create_cb(&state, attrs);
if(attrs) {
p->apply_cb(&state, attrs);
}
return state.item;
}
lv_xml_component_ctx_t * ctx = lv_xml_component_get_ctx(name);
if(ctx) {
item = lv_xml_create_from_ctx(parent, NULL, ctx, attrs);
return item;
}
/* If it isn't a component either then it is unknown */
LV_LOG_WARN("'%s' in not a known widget, element, or component", name);
return NULL;
}
lv_result_t lv_xml_register_font(const char * name, const lv_font_t * font)
{
lv_xml_font_t * f = lv_ll_ins_head(&font_ll);
f->name = lv_strdup(name);
f->font = font;
return LV_RESULT_OK;
}
const lv_font_t * lv_xml_get_font(const char * name)
{
lv_xml_font_t * f;
LV_LL_READ(&font_ll, f) {
if(lv_streq(f->name, name)) return f->font;
}
return NULL;
}
lv_result_t lv_xml_register_image(const char * name, const void * src)
{
lv_xml_image_t * img = lv_ll_ins_head(&image_ll);
img->name = lv_strdup(name);
if(lv_image_src_get_type(src) == LV_IMAGE_SRC_FILE) {
img->src = lv_strdup(src);
}
else {
img->src = src;
}
return LV_RESULT_OK;
}
const void * lv_xml_get_image(const char * name)
{
lv_xml_image_t * img;
LV_LL_READ(&image_ll, img) {
if(lv_streq(img->name, name)) return img->src;
}
return NULL;
}
/**********************
* STATIC FUNCTIONS
**********************/
static const char * get_param_type(lv_xml_component_ctx_t * ctx, const char * name)
{
lv_xml_param_t * p;
LV_LL_READ(&ctx->param_ll, p) {
if(lv_streq(p->name, name)) return p->type;
}
return NULL;
}
static const char * get_param_default(lv_xml_component_ctx_t * ctx, const char * name)
{
lv_xml_param_t * p;
LV_LL_READ(&ctx->param_ll, p) {
if(lv_streq(p->name, name)) return p->def;
}
return NULL;
}
static void resolve_params(lv_xml_component_ctx_t * item_ctx, lv_xml_component_ctx_t * parent_ctx,
const char ** item_attrs, const char ** parent_attrs)
{
uint32_t i;
for(i = 0; item_attrs[i]; i += 2) {
const char * name = item_attrs[i];
const char * value = item_attrs[i + 1];
if(lv_streq(name, "styles")) continue; /*Styles will handle it themselves*/
if(value[0] == '$') {
/*E.g. the ${my_color} value is the my_color attribute name on the parent*/
const char * name_clean = &value[1]; /*skips `$`*/
const char * type = get_param_type(item_ctx, name_clean);
if(type == NULL) {
LV_LOG_WARN("'%s' parameter is not defined on '%s'", name_clean, item_ctx->name);
}
const char * ext_value = lv_xml_get_value_of(parent_attrs, name_clean);
if(ext_value) {
/*If the value is not resolved earlier (e.g. it's a top level element created manually)
* use the default value*/
if(ext_value[0] == '#' || ext_value[0] == '$') {
ext_value = get_param_default(item_ctx, name_clean);
}
else if(lv_streq(type, "style")) {
lv_xml_style_t * s = lv_xml_get_style_by_name(parent_ctx, ext_value);
ext_value = s->long_name;
}
}
else {
/*If the API attribute is not provide don't set it*/
ext_value = get_param_default(item_ctx, name_clean);
}
if(ext_value) {
item_attrs[i + 1] = ext_value;
}
else {
/*Not set and no default value either
*Don't set this property*/
item_attrs[i] = "";
item_attrs[i + 1] = "";
}
}
}
}
static void resolve_consts(const char ** item_attrs, lv_xml_component_ctx_t * ctx)
{
uint32_t i;
for(i = 0; item_attrs[i]; i += 2) {
const char * name = item_attrs[i];
const char * value = item_attrs[i + 1];
if(lv_streq(name, "styles")) continue; /*Styles will handle it themselves*/
if(value[0] == '#') {
const char * value_clean = &value[1];
lv_xml_const_t * c;
LV_LL_READ(&ctx->const_ll, c) {
if(lv_streq(c->name, value_clean)) {
item_attrs[i + 1] = c->value;
break;
}
}
/*If the const attribute is not provide don't set it*/
if(c == NULL) {
item_attrs[i] = "";
item_attrs[i + 1] = "";
}
}
}
}
static void view_start_element_handler(void * user_data, const char * name, const char ** attrs)
{
lv_xml_parser_state_t * state = (lv_xml_parser_state_t *)user_data;
bool is_view = false;
if(lv_streq(name, "view")) {
const char * extends = lv_xml_get_value_of(attrs, "extends");
name = extends ? extends : "lv_obj";
is_view = true;
}
lv_obj_t ** current_parent_p = lv_ll_get_tail(&state->parent_ll);
if(current_parent_p == NULL) {
if(state->parent == NULL) {
LV_LOG_ERROR("There is no parent object available for %s. This also should never happen.", name);
return;
}
else {
current_parent_p = &state->parent;
}
}
else {
state->parent = *current_parent_p;
}
/*In `state->attrs` we have parameters of the component creation
*E.g. <my_button x="10" title="Hello"/>
*In `attrs` we have the attributes of child of the view.
*E.g. in `my_button` `<lv_label x="5" text="${title}".
*This function changes the pointers in the child attributes if the start with '$'
*with the corresponding parameter. E.g. "text", "${title}" -> "text", "Hello" */
resolve_params(&state->ctx, state->parent_ctx, attrs, state->parent_attrs);
resolve_consts(attrs, &state->ctx);
void * item = NULL;
/* Select the widget specific parser type based on the name */
lv_widget_processor_t * p = lv_xml_widget_get_processor(name);
if(p) {
item = p->create_cb(state, attrs);
state->item = item;
/*If it's a widget remove all styles. E.g. if it extends an `lv_button`
*now it has the button theme styles. However if it were a real widget
*it had e.g. `my_widget_class` so the button's theme wouldn't apply on it.
*Removing the style will ensure a better preview*/
if(state->ctx.is_widget) lv_obj_remove_style_all(item);
/*Apply the attributes from e.g. `<lv_slider value="30" x="20">`*/
if(item) {
p->apply_cb(state, attrs);
}
}
/* If not a widget, check if it is a component */
if(item == NULL) {
item = lv_xml_component_process(state, name, attrs);
state->item = item;
}
/* If it isn't a component either then it is unknown */
if(item == NULL) {
LV_LOG_WARN("'%s' in not a known widget, element, or component", name);
return;
}
void ** new_parent = lv_ll_ins_tail(&state->parent_ll);
*new_parent = item;
if(is_view) {
state->view = item;
}
}
static void view_end_element_handler(void * user_data, const char * name)
{
LV_UNUSED(name);
lv_xml_parser_state_t * state = (lv_xml_parser_state_t *)user_data;
lv_obj_t ** current_parent = lv_ll_get_tail(&state->parent_ll);
if(current_parent) {
lv_ll_remove(&state->parent_ll, current_parent);
lv_free(current_parent);
}
}
#endif /* LV_USE_XML */

57
src/others/xml/lv_xml.h Normal file
View File

@ -0,0 +1,57 @@
/**
* @file lv_xml.h
*
*/
#ifndef LV_XML_H
#define LV_XML_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../misc/lv_types.h"
#if LV_USE_XML
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_xml_init(void);
lv_obj_t * lv_xml_create(lv_obj_t * parent, const char * name, const char ** attrs);
lv_obj_t * lv_xml_create_from_ctx(lv_obj_t * parent, lv_xml_component_ctx_t * parent_ctx, lv_xml_component_ctx_t * ctx,
const char ** attrs);
lv_result_t lv_xml_register_font(const char * name, const lv_font_t * font);
const lv_font_t * lv_xml_get_font(const char * name);
lv_result_t lv_xml_register_image(const char * name, const void * src);
const void * lv_xml_get_image(const char * name);
/**********************
* MACROS
**********************/
#endif /* LV_USE_XML */
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_XML_H*/

View File

@ -0,0 +1,111 @@
/**
* @file lv_xml_base_parser.c
*
*/
/*********************
* INCLUDES
*********************/
#include "../../lvgl.h"
#if LV_USE_XML
#include "lv_xml_base_types.h"
#include "lv_xml_private.h"
#include "lv_xml_parser.h"
#include "lv_xml_style.h"
#include "lv_xml_component_private.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
int32_t lv_xml_to_size(const char * txt)
{
if(lv_streq(txt, "content")) return LV_SIZE_CONTENT;
int32_t v = lv_xml_atoi(txt);
if(txt[lv_strlen(txt) - 1] == '%') return lv_pct(v);
else return v;
}
lv_align_t lv_xml_align_string_to_enum_value(const char * txt)
{
if(lv_streq("top_left", txt)) return LV_ALIGN_TOP_LEFT;
if(lv_streq("top_mid", txt)) return LV_ALIGN_TOP_MID;
if(lv_streq("top_right", txt)) return LV_ALIGN_TOP_LEFT;
if(lv_streq("bottom_left", txt)) return LV_ALIGN_BOTTOM_LEFT;
if(lv_streq("bottom_mid", txt)) return LV_ALIGN_BOTTOM_MID;
if(lv_streq("bottom_right", txt)) return LV_ALIGN_BOTTOM_RIGHT;
if(lv_streq("right_mid", txt)) return LV_ALIGN_RIGHT_MID;
if(lv_streq("left_mid", txt)) return LV_ALIGN_LEFT_MID;
if(lv_streq("center", txt)) return LV_ALIGN_CENTER;
LV_LOG_WARN("%s is an unknown value for align", txt);
return 0; /*Return 0 in lack of a better option. */
}
lv_dir_t lv_xml_dir_string_to_enum_value(const char * txt)
{
if(lv_streq("top", txt)) return LV_DIR_TOP;
if(lv_streq("bottom", txt)) return LV_DIR_BOTTOM;
if(lv_streq("left", txt)) return LV_DIR_LEFT;
if(lv_streq("right", txt)) return LV_DIR_RIGHT;
if(lv_streq("all", txt)) return LV_DIR_ALL;
LV_LOG_WARN("%s is an unknown value for dir", txt);
return 0; /*Return 0 in lack of a better option. */
}
lv_flex_flow_t lv_xml_flex_flow_string_to_enum_value(const char * txt)
{
if(lv_streq("column", txt)) return LV_FLEX_FLOW_COLUMN;
if(lv_streq("column_reverse", txt)) return LV_FLEX_FLOW_COLUMN_REVERSE;
if(lv_streq("column_wrap", txt)) return LV_FLEX_FLOW_COLUMN_WRAP;
if(lv_streq("column_wrap_reverse", txt)) return LV_FLEX_FLOW_COLUMN_WRAP_REVERSE;
if(lv_streq("row", txt)) return LV_FLEX_FLOW_ROW;
if(lv_streq("row_reverse", txt)) return LV_FLEX_FLOW_ROW_REVERSE;
if(lv_streq("row_wrap", txt)) return LV_FLEX_FLOW_ROW_WRAP;
if(lv_streq("row_wrap_reverse", txt)) return LV_FLEX_FLOW_ROW_WRAP_REVERSE;
LV_LOG_WARN("%s is an unknown value for flex flow", txt);
return 0; /*Return 0 in lack of a better option. */
}
lv_flex_align_t lv_xml_flex_align_string_to_enum_value(const char * txt)
{
if(lv_streq("center", txt)) return LV_FLEX_ALIGN_CENTER;
if(lv_streq("end", txt)) return LV_FLEX_ALIGN_END;
if(lv_streq("start", txt)) return LV_FLEX_ALIGN_START;
if(lv_streq("space_around", txt)) return LV_FLEX_ALIGN_SPACE_AROUND;
if(lv_streq("space_between", txt)) return LV_FLEX_ALIGN_SPACE_BETWEEN;
if(lv_streq("space_evenly", txt)) return LV_FLEX_ALIGN_SPACE_EVENLY;
LV_LOG_WARN("%s is an unknown value for flex align", txt);
return 0; /*Return 0 in lack of a better option. */
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif /* LV_USE_XML */

View File

@ -0,0 +1,76 @@
/**
* @file lv_xml_base_types.h
*
*/
#ifndef LV_XML_BASE_TYPES_H
#define LV_XML_BASE_TYPES_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../misc/lv_types.h"
#include "../../misc/lv_style.h"
#if LV_USE_XML
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Process inputs "content", "32", "32px", or "25%"
* and convert them to integer
* @param txt the input string
* @return the integer size
*/
int32_t lv_xml_to_size(const char * txt);
/**
* Convert an align string to enum
* @param txt e.g. "center"
* @return the related enum, e.g. `LV_ALIGN_CENTER`
*/
lv_align_t lv_xml_align_string_to_enum_value(const char * txt);
/**
* Convert a direction string to enum
* @param txt e.g. "top"
* @return the related enum, e.g. `LV_DIR_TOP`
*/
lv_dir_t lv_xml_dir_string_to_enum_value(const char * txt);
/**
* Convert a flex flow string to enum
* @param txt e.g. "row_wrap"
* @return the related enum, e.g. `LV_FLEX_FLOW_ROW_WRAP`
*/
lv_flex_flow_t lv_xml_flex_flow_string_to_enum_value(const char * txt);
/**
* Convert a flex align string to enum
* @param txt e.g. "space_between"
* @return the related enum, e.g. `LV_FLEX_ALIGN_SPACE_BETWEEN`
*/
lv_flex_align_t lv_xml_flex_align_string_to_enum_value(const char * txt);
/**********************
* MACROS
**********************/
#endif /* LV_USE_XML */
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_XML_BASE_TYPES_H*/

View File

@ -0,0 +1,306 @@
/**
* @file lv_xml_component.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_xml_component.h"
#if LV_USE_XML
#include "lv_xml_component_private.h"
#include "lv_xml_private.h"
#include "lv_xml_parser.h"
#include "lv_xml_style.h"
#include "lv_xml_base_types.h"
#include "lv_xml_widget.h"
#include "parsers/lv_xml_obj_parser.h"
#include "../../libs/expat/expat.h"
#include "../../misc/lv_fs.h"
#include <string.h>
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void start_metadata_handler(void * user_data, const char * name, const char ** attrs);
static void end_metadata_handler(void * user_data, const char * name);
static void process_const_element(lv_xml_parser_state_t * state, const char ** attrs);
static void process_prop_element(lv_xml_parser_state_t * state, const char ** attrs);
static char * extract_view_content(const char * xml_definition);
/**********************
* STATIC VARIABLES
**********************/
static lv_ll_t component_ctx_ll;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void lv_xml_component_init(void)
{
lv_ll_init(&component_ctx_ll, sizeof(lv_xml_component_ctx_t));
}
lv_obj_t * lv_xml_component_process(lv_xml_parser_state_t * state, const char * name, const char ** attrs)
{
lv_xml_component_ctx_t * ctx = lv_xml_component_get_ctx(name);
if(ctx == NULL) return NULL;
lv_obj_t * item = lv_xml_create_from_ctx(state->parent, &state->ctx, ctx, attrs);
if(item == NULL) {
LV_LOG_WARN("Couldn't create component '%s'", name);
return NULL;
}
/* Apply the properties of the component, e.g. <my_button x="20" styles="red"/> */
state->item = item;
ctx->root_widget->apply_cb(state, attrs);
return item;
}
lv_xml_component_ctx_t * lv_xml_component_get_ctx(const char * component_name)
{
lv_xml_component_ctx_t * ctx;
LV_LL_READ(&component_ctx_ll, ctx) {
if(lv_streq(ctx->name, component_name)) return ctx;
}
return NULL;
}
lv_result_t lv_xml_component_register_from_data(const char * name, const char * xml_def)
{
/* Create a temporary parser state to extract styles/params/consts */
lv_xml_parser_state_t state;
lv_xml_parser_state_init(&state);
state.ctx.name = name;
/* Parse the XML to extract metadata */
XML_Parser parser = XML_ParserCreate(NULL);
XML_SetUserData(parser, &state);
XML_SetElementHandler(parser, start_metadata_handler, end_metadata_handler);
if(XML_Parse(parser, xml_def, lv_strlen(xml_def), XML_TRUE) == XML_STATUS_ERROR) {
LV_LOG_WARN("XML parsing error: %s on line %lu",
XML_ErrorString(XML_GetErrorCode(parser)),
(unsigned long)XML_GetCurrentLineNumber(parser));
XML_ParserFree(parser);
return LV_RESULT_INVALID;
}
XML_ParserFree(parser);
/* Copy extracted metadata to component processor */
lv_xml_component_ctx_t * ctx = lv_ll_ins_head(&component_ctx_ll);
lv_memzero(ctx, sizeof(lv_xml_component_ctx_t));
lv_memcpy(ctx, &state.ctx, sizeof(lv_xml_component_ctx_t));
/* Extract view content directly instead of using XML parser */
ctx->view_def = extract_view_content(xml_def);
ctx->name = lv_strdup(name);
if(!ctx->view_def) {
LV_LOG_WARN("Failed to extract view content");
/* Clean up and return error */
lv_free(ctx);
return LV_RESULT_INVALID;
}
return LV_RESULT_OK;
}
lv_result_t lv_xml_component_register_from_file(const char * path)
{
/* Extract component name from path */
/* Create a copy of the filename to modify */
char * filename = lv_strdup(lv_fs_get_last(path));
const char * ext = lv_fs_get_ext(filename);
filename[lv_strlen(filename) - lv_strlen(ext) - 1] = '\0'; /*Trim the extension*/
lv_fs_res_t fs_res;
lv_fs_file_t f;
fs_res = lv_fs_open(&f, path, LV_FS_MODE_RD);
if(fs_res != LV_FS_RES_OK) {
LV_LOG_WARN("Couldn't open %s", path);
lv_free(filename);
return LV_RESULT_INVALID;
}
/* Determine file size */
lv_fs_seek(&f, 0, LV_FS_SEEK_END);
uint32_t file_size = 0;
lv_fs_tell(&f, &file_size);
lv_fs_seek(&f, 0, LV_FS_SEEK_SET);
/* Create the buffer */
char * xml_buf = lv_malloc(file_size + 1);
if(xml_buf == NULL) {
LV_LOG_WARN("Memory allocation failed for file %s (%d bytes)", path, file_size + 1);
lv_free(filename);
lv_fs_close(&f);
return LV_RESULT_INVALID;
}
/* Read the file content */
uint32_t rn;
lv_fs_read(&f, xml_buf, file_size, &rn);
if(rn != file_size) {
LV_LOG_WARN("Couldn't read %s fully", path);
lv_free(filename);
lv_free(xml_buf);
lv_fs_close(&f);
return LV_RESULT_INVALID;
}
/* Null-terminate the buffer */
xml_buf[rn] = '\0';
/* Register the component */
lv_result_t res = lv_xml_component_register_from_data(filename, xml_buf);
/* Housekeeping */
lv_free(filename);
lv_free(xml_buf);
lv_fs_close(&f);
return res;
}
lv_result_t lv_xml_component_unregister(const char * name)
{
lv_xml_component_ctx_t * ctx = lv_xml_component_get_ctx(name);
if(ctx == NULL) return LV_RESULT_INVALID;
lv_ll_remove(&component_ctx_ll, ctx);
lv_free((char *)ctx->name);
lv_free((char *)ctx->view_def);
lv_ll_clear(&ctx->param_ll);
lv_ll_clear(&ctx->style_ll);
lv_free(ctx);
return LV_RESULT_OK;
}
/**********************
* STATIC FUNCTIONS
**********************/
static void process_const_element(lv_xml_parser_state_t * state, const char ** attrs)
{
const char * name = lv_xml_get_value_of(attrs, "name");
const char * value = lv_xml_get_value_of(attrs, "value");
if(name == NULL) {
LV_LOG_WARN("'name' is missing from a constant");
return;
}
if(value == NULL) {
LV_LOG_WARN("'value' is missing from a constant");
return;
}
lv_xml_const_t * cnst = lv_ll_ins_tail(&state->ctx.const_ll);
cnst->name = lv_strdup(name);
cnst->value = lv_strdup(value);
}
static void process_prop_element(lv_xml_parser_state_t * state, const char ** attrs)
{
lv_xml_param_t * cnst = lv_ll_ins_tail(&state->ctx.param_ll);
cnst->name = lv_strdup(lv_xml_get_value_of(attrs, "name"));
const char * def = lv_xml_get_value_of(attrs, "default");
if(def) cnst->def = lv_strdup(def);
else cnst->def = NULL;
const char * type = lv_xml_get_value_of(attrs, "type");
if(type == NULL) type = "compound"; /*If there in no type it means there are <param>s*/
cnst->type = lv_strdup(lv_xml_get_value_of(attrs, "type"));
}
static void start_metadata_handler(void * user_data, const char * name, const char ** attrs)
{
lv_xml_parser_state_t * state = (lv_xml_parser_state_t *)user_data;
lv_xml_parser_section_t old_section = state->section;
lv_xml_parser_start_section(state, name);
if(lv_streq(name, "view")) {
const char * extends = lv_xml_get_value_of(attrs, "extends");
if(extends == NULL) extends = "lv_obj";
state->ctx.root_widget = lv_xml_widget_get_processor(extends);
}
if(lv_streq(name, "widget")) state->ctx.is_widget = 1;
if(old_section != state->section) return; /*Ignore the section opening, e.g. <styles>*/
/* Process elements based on current context */
switch(state->section) {
case LV_XML_PARSER_SECTION_API:
process_prop_element(state, attrs);
break;
case LV_XML_PARSER_SECTION_CONSTS:
process_const_element(state, attrs);
break;
case LV_XML_PARSER_SECTION_STYLES:
if(lv_streq(name, "style")) {
lv_xml_style_register(&state->ctx, attrs);
}
break;
default:
break;
}
}
static void end_metadata_handler(void * user_data, const char * name)
{
lv_xml_parser_state_t * state = (lv_xml_parser_state_t *)user_data;
lv_xml_parser_end_section(state, name);
}
static char * extract_view_content(const char * xml_definition)
{
if(!xml_definition) return NULL;
/* Find start of view tag */
const char * start = strstr(xml_definition, "<view");
if(!start) return NULL;
/* Find end of view tag */
const char * end = strstr(xml_definition, "</view>");
if(!end) return NULL;
end += 7; /* Include "</view>" in result */
/* Calculate and allocate length */
size_t len = end - start;
char * view_content = lv_malloc(len + 1);
if(!view_content) return NULL;
/* Copy content and null terminate */
lv_memcpy(view_content, start, len);
view_content[len] = '\0';
return view_content;
}
#endif /* LV_USE_XML */

View File

@ -0,0 +1,78 @@
/**
* @file lv_xml_component.h
*
*/
#ifndef LV_LABEL_XML_COMPONENT_H
#define LV_LABEL_XML_COMPONENT_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../misc/lv_types.h"
#if LV_USE_XML
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Process a component during parsing an XML. It create a widget and apply all the attributes
* @param state the current parsing state
* @param name name of the component
* @param attrs attributes of the widget
* @return
*/
lv_obj_t * lv_xml_component_process(lv_xml_parser_state_t * state, const char * name, const char ** attrs);
/**
* Load the styles, constants, another data of the component. It needs to be called only once for each component.
* @param name the name as the component will be referenced later in other components
* @param xml_def the XML definition of the component as a NULL terminated string
* @return LV_RES_OK: loaded successfully, LV_RES_INVALID: otherwise
*/
lv_result_t lv_xml_component_register_from_data(const char * name, const char * xml_def);
/**
* Load the styles, constants, another data of the component. It needs to be called only once for each component.
* @param path path to an XML file
* @return LV_RES_OK: loaded successfully, LV_RES_INVALID: otherwise
*/
lv_result_t lv_xml_component_register_from_file(const char * path);
/**
* Get the ctx of a component which was registered by
* `lv_xml_component_register_from_data` or `lv_xml_component_register_from_file`
* @param component_name name of the component
* @return pointer the ctx or NULL if not found
*/
lv_xml_component_ctx_t * lv_xml_component_get_ctx(const char * component_name);
/**
* Remove a component from from the list.
* @param name the name of the component (used during registration)
* @return LV_RESULT_OK on successful unregistration, LV_RESULT_INVALID otherwise.
*/
lv_result_t lv_xml_component_unregister(const char * name);
/**********************
* MACROS
**********************/
#endif /* LV_USE_XML */
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_XML_COMPONENT_H*/

View File

@ -0,0 +1,58 @@
/**
* @file lv_xml_component_private.h
*
*/
#ifndef LV_XML_COMPONENT_PRIVATE_H
#define LV_XML_COMPONENT_PRIVATE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "lv_xml.h"
#if LV_USE_XML
#include "lv_xml_utils.h"
#include "../../misc/lv_ll.h"
/**********************
* TYPEDEFS
**********************/
typedef void * (*lv_xml_component_process_cb_t)(lv_obj_t * parent, const char * data, const char ** attrs);
struct _lv_xml_component_ctx_t {
const char * name;
lv_ll_t style_ll;
lv_ll_t const_ll;
lv_ll_t param_ll;
const char * view_def;
struct _lv_widget_processor_t * root_widget;
uint32_t is_widget : 1; /*1: not component but widget registered as a component for preview*/
struct _lv_xml_component_ctx_t * next;
};
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Initialize the components system.
*/
void lv_xml_component_init(void);
/**********************
* MACROS
**********************/
#endif /* LV_USE_XML */
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_XML_COMPONENT_PRIVATE_H*/

View File

@ -0,0 +1,98 @@
/**
* @file lv_xml.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_xml.h"
#if LV_USE_XML
#include "lv_xml_private.h"
#include "lv_xml_parser.h"
#include "lv_xml_style.h"
#include "lv_xml_component_private.h"
#include "lv_xml_base_types.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void lv_xml_parser_state_init(lv_xml_parser_state_t * state)
{
lv_memzero(state, sizeof(lv_xml_parser_state_t));
lv_ll_init(&state->ctx.style_ll, sizeof(lv_xml_style_t));
lv_ll_init(&state->ctx.const_ll, sizeof(lv_xml_const_t));
lv_ll_init(&state->ctx.param_ll, sizeof(lv_xml_param_t));
lv_ll_init(&state->parent_ll, sizeof(lv_obj_t *));
}
void lv_xml_parser_start_section(lv_xml_parser_state_t * state, const char * name)
{
/* Check for context changes */
if(lv_streq(name, "api")) {
state->section = LV_XML_PARSER_SECTION_API;
return;
}
else if(lv_streq(name, "consts")) {
state->section = LV_XML_PARSER_SECTION_CONSTS;
return;
}
else if(lv_streq(name, "styles")) {
state->section = LV_XML_PARSER_SECTION_STYLES;
return;
}
else if(lv_streq(name, "view")) {
state->section = LV_XML_PARSER_SECTION_VIEW;
return;
}
}
void lv_xml_parser_end_section(lv_xml_parser_state_t * state, const char * name)
{
/* Reset context when leaving a block */
if(lv_streq(name, "params") ||
lv_streq(name, "consts") ||
lv_streq(name, "styles") ||
lv_streq(name, "view")) {
state->section = LV_XML_PARSER_SECTION_NONE;
}
}
void * lv_xml_state_get_parent(lv_xml_parser_state_t * state)
{
return state->parent;
}
void * lv_xml_state_get_item(lv_xml_parser_state_t * state)
{
return state->item;
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif /* LV_USE_XML */

View File

@ -0,0 +1,84 @@
/**
* @file lv_xml_parser.h
*
*/
#ifndef LV_XML_PARSER_H
#define LV_XML_PARSER_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../misc/lv_types.h"
#if LV_USE_XML
#include "lv_xml_component.h"
#include "lv_xml_component_private.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
typedef enum {
LV_XML_PARSER_SECTION_NONE,
LV_XML_PARSER_SECTION_API,
LV_XML_PARSER_SECTION_CONSTS,
LV_XML_PARSER_SECTION_STYLES,
LV_XML_PARSER_SECTION_VIEW
} lv_xml_parser_section_t;
struct _lv_xml_parser_state_t {
lv_xml_component_ctx_t ctx;
lv_ll_t parent_ll;
lv_obj_t * parent;
lv_obj_t * item;
lv_obj_t * view; /*Pointer to the created view during component creation*/
const char ** parent_attrs;
lv_xml_component_ctx_t * parent_ctx;
lv_xml_parser_section_t section;
};
typedef struct {
const char * name;
const char * value;
} lv_xml_const_t;
typedef struct {
const char * name;
const char * def;
const char * type;
} lv_xml_param_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_xml_parser_state_init(lv_xml_parser_state_t * state);
void lv_xml_parser_start_section(lv_xml_parser_state_t * state, const char * name);
void lv_xml_parser_end_section(lv_xml_parser_state_t * state, const char * name);
void * lv_xml_state_get_parent(lv_xml_parser_state_t * state);
void * lv_xml_state_get_item(lv_xml_parser_state_t * state);
/**********************
* MACROS
**********************/
#endif /* LV_USE_XML */
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_XML_PARSER_H*/

View File

@ -0,0 +1,58 @@
/**
* @file lv_xml_ptivate.h
*
*/
#ifndef LV_XML_PRIVATE_H
#define LV_XML_PRIVATE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "lv_xml.h"
#if LV_USE_XML
#include "parsers/lv_xml_obj_parser.h"
#include "lv_xml_parser.h"
#include "lv_xml_base_types.h"
#include "lv_xml_utils.h"
#include "lv_xml_style.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
typedef struct {
const char * name;
const lv_font_t * font;
} lv_xml_font_t;
typedef struct {
const char * name;
const void * src;
} lv_xml_image_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**********************
* MACROS
**********************/
#endif /* LV_USE_XML */
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_XML_PRIVATE_H*/

View File

@ -0,0 +1,202 @@
/**
* @file lv_xml_style.c
*
*/
/*********************
* INCLUDES
*********************/
#include "../../lvgl.h"
#if LV_USE_XML
#include "lv_xml_base_types.h"
#include "lv_xml_parser.h"
#include "lv_xml_style.h"
#include "lv_xml_utils.h"
#include "lv_xml_component_private.h"
#include <string.h>
/*********************
* DEFINES
*********************/
#ifdef _MSC_VER
#define strtok_r strtok_s // Use strtok_s as an equivalent to strtok_r in Visual Studio
#endif
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
lv_state_t lv_xml_style_state_string_to_enum_value(const char * txt)
{
if(lv_streq("default", txt)) return LV_STATE_DEFAULT;
if(lv_streq("pressed", txt)) return LV_STATE_PRESSED;
if(lv_streq("checked", txt)) return LV_STATE_CHECKED;
if(lv_streq("scrolled", txt)) return LV_STATE_SCROLLED;
return 0; /*Return 0 in lack of a better option. */
}
lv_part_t lv_xml_style_part_string_to_enum_value(const char * txt)
{
if(lv_streq("main", txt)) return LV_PART_MAIN;
if(lv_streq("scrollbar", txt)) return LV_PART_SCROLLBAR;
if(lv_streq("indicator", txt)) return LV_PART_INDICATOR;
if(lv_streq("knob", txt)) return LV_PART_KNOB;
return 0; /*Return 0 in lack of a better option. */
}
void lv_xml_style_register(lv_xml_component_ctx_t * ctx, const char ** attrs)
{
const char * style_name = lv_xml_get_value_of(attrs, "name");
if(style_name == NULL) {
LV_LOG_WARN("'name' is missing from a style");
return;
}
lv_xml_style_t * xml_style = lv_ll_ins_tail(&ctx->style_ll);
lv_style_t * style = &xml_style->style;
lv_style_init(style);
xml_style->name = lv_strdup(style_name);
size_t long_name_len = lv_strlen(ctx->name) + 1 + lv_strlen(style_name) + 1;
xml_style->long_name = lv_malloc(long_name_len);
lv_snprintf((char *)xml_style->long_name, long_name_len, "%s.%s", ctx->name, style_name); /*E.g. my_button.style1*/
for(int i = 0; attrs[i]; i += 2) {
const char * name = attrs[i];
const char * value = attrs[i + 1];
if(lv_streq(name, "name")) continue;
if(lv_streq(name, "help")) continue;
if(value[0] == '#') {
const char * value_clean = &value[1];
lv_xml_const_t * c;
LV_LL_READ(&ctx->const_ll, c) {
if(lv_streq(c->name, value_clean)) {
value = c->value;
break;
}
}
}
if(lv_streq(name, "width")) lv_style_set_width(style, lv_xml_to_size(value));
else if(lv_streq(name, "height")) lv_style_set_height(style, lv_xml_to_size(value));
else if(lv_streq(name, "radius")) lv_style_set_radius(style, lv_xml_atoi(value));
else if(lv_streq(name, "bg_opa")) lv_style_set_bg_opa(style, lv_xml_atoi(value));
else if(lv_streq(name, "bg_color")) lv_style_set_bg_color(style, lv_xml_to_color(value));
else if(lv_streq(name, "border_color")) lv_style_set_border_color(style, lv_xml_to_color(value));
else if(lv_streq(name, "border_width")) lv_style_set_border_width(style, lv_xml_atoi(value));
else if(lv_streq(name, "border_opa")) lv_style_set_border_opa(style, lv_xml_atoi(value));
else if(lv_streq(name, "text_color")) lv_style_set_text_color(style, lv_xml_to_color(value));
else if(lv_streq(name, "text_font")) lv_style_set_text_font(style, lv_xml_get_font(value));
else if(lv_streq(name, "bg_image_src")) lv_style_set_bg_image_src(style, lv_xml_get_image(value));
else if(lv_streq(name, "bg_image_tiled")) lv_style_set_bg_image_tiled(style, lv_xml_to_bool(value));
else {
LV_LOG_WARN("%s style property is not supported", name);
}
}
}
const char * lv_xml_style_string_process(char * txt, lv_style_selector_t * selector)
{
*selector = 0;
char * style_name = lv_xml_split_str(&txt, ':');
char * selector_str = lv_xml_split_str(&txt, ':');
while(selector_str != NULL) {
/* Handle different states and parts */
*selector |= lv_xml_style_state_string_to_enum_value(selector_str);
*selector |= lv_xml_style_part_string_to_enum_value(selector_str);
/* Move to the next token */
selector_str = lv_xml_split_str(&txt, ':');
}
return style_name;
}
void lv_xml_style_add_to_obj(lv_xml_parser_state_t * state, lv_obj_t * obj, const char * text)
{
char * str = lv_strdup(text);
char * str_ori = str;
/* Split the string based on space and colons */
char * onestyle_str = lv_xml_split_str(&str, ' ');
while(onestyle_str != NULL) {
/* Parse the parts and states after the space */
lv_style_selector_t selector = 0;
const char * style_name = lv_xml_style_string_process(onestyle_str, &selector);
if(style_name != NULL) {
lv_xml_style_t * xml_style = NULL;
/*Resolve parameters or just find the style*/
if(style_name[0] == '$') {
/*E.g. `$pr_style` style name means use the value
*coming from the parent's `pr_style` named attribute*/
const char * name_clean = &style_name[1];
const char * parent_style_name = lv_xml_get_value_of(state->parent_attrs, name_clean);
if(parent_style_name) {
xml_style = lv_xml_get_style_by_name(state->parent_ctx, parent_style_name);
}
}
else {
xml_style = lv_xml_get_style_by_name(&state->ctx, style_name);
}
if(xml_style) {
/* Apply with the selector */
lv_obj_add_style(obj, &xml_style->style, selector);
}
}
onestyle_str = lv_xml_split_str(&str, ' ');
}
lv_free(str_ori);
}
lv_xml_style_t * lv_xml_get_style_by_name(lv_xml_component_ctx_t * ctx, const char * style_name_raw)
{
const char * style_name = strrchr(style_name_raw, '.');
if(style_name) {
char component_name[256];
size_t len = (size_t)(style_name - style_name_raw);
lv_memcpy(component_name, style_name_raw, len);
component_name[len] = '\0';
ctx = lv_xml_component_get_ctx(component_name);
style_name++; /*Skip the dot*/
}
else {
style_name = style_name_raw;
}
lv_xml_style_t * xml_style;
LV_LL_READ(&ctx->style_ll, xml_style) {
if(lv_streq(xml_style->name, style_name)) return xml_style;
}
LV_LOG_WARN("No style found with %s name", style_name_raw);
return NULL;
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif /* LV_USE_XML */

View File

@ -0,0 +1,91 @@
/**
* @file lv_xml_style.h
*
*/
#ifndef LV_XML_STYLE_H
#define LV_XML_STYLE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../misc/lv_types.h"
#include "../../misc/lv_style.h"
#include "../../core/lv_obj_style.h"
#if LV_USE_XML
/**********************
* TYPEDEFS
**********************/
typedef struct _lv_xml_style_t {
const char * name;
const char * long_name;
lv_style_t style;
} lv_xml_style_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Add a style to `ctx` and set the style properties from `attrs`
* @param ctx add styles here. (Constants should be already added as style properties might use them)
* @param attrs list of attribute names and values
*/
void lv_xml_style_register(lv_xml_component_ctx_t * ctx, const char ** attrs);
/**
* Add the styles to an object. Handles multiple styles and selectors too.
* @param state the parser state
* @param obj the target widget
* @param text the styles' string, e.g. "blue red:pressed:knob"
*/
void lv_xml_style_add_to_obj(lv_xml_parser_state_t * state, lv_obj_t * obj, const char * text);
/**
* Convert a style state to enum
* @param txt e.g. "pressed"
* @return the enum `LV_STATE_PRESSED`
*/
lv_state_t lv_xml_style_state_string_to_enum_value(const char * txt);
/**
* Convert a style part to enum
* @param txt e.g. "knob"
* @return the enum `LV_PART_KNOB`
*/
lv_part_t lv_xml_style_part_string_to_enum_value(const char * txt);
/**
* Decompose a string like `"style1:pressed:checked:knob"` to style name and selector
* @param txt the input string
* @param selector store the selectors here
* @return the style name or `NULL` on any error
*/
const char * lv_xml_style_string_process(char * txt, lv_style_selector_t * selector);
/**
* Find a style by name which was added by `lv_xml_style_register`
* @param ctx the default context to search in
* @param name the name of the style. Can start with a component name prefix (e.g. `my_button.blue`) to overwrite the ctx
* @return the style structure
*/
lv_xml_style_t * lv_xml_get_style_by_name(lv_xml_component_ctx_t * ctx, const char * name);
/**********************
* MACROS
**********************/
#endif /* LV_USE_XML */
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_XML_STYLE_H*/

View File

@ -0,0 +1,237 @@
/**
* @file lv_xml_utils.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_xml_utils.h"
#include "../../stdlib/lv_string.h"
#if LV_USE_XML
#if LV_USE_STDLIB_STRING == LV_STDLIB_CLIB
#include <stdlib.h>
#endif
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
#if LV_USE_STDLIB_STRING != LV_STDLIB_CLIB
static bool lv_xml_is_digit(char c, int base);
#endif
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
const char * lv_xml_get_value_of(const char ** attrs, const char * name)
{
if(attrs == NULL) return NULL;
if(name == NULL) return NULL;
for(int i = 0; attrs[i]; i += 2) {
if(lv_streq(attrs[i], name)) return attrs[i + 1];
}
return NULL;
}
lv_color_t lv_xml_to_color(const char * str)
{
return lv_color_hex(lv_xml_strtol(str, NULL, 16));
}
bool lv_xml_to_bool(const char * str)
{
return lv_streq(str, "false") ? false : true;
}
#if LV_USE_STDLIB_STRING == LV_STDLIB_CLIB
int32_t lv_xml_atoi(const char * str)
{
return atoi(str);
}
int32_t lv_xml_strtol(const char * str, char ** endptr, int32_t base)
{
return strtol(str, endptr, base);
}
#else /*LV_USE_STDLIB_STRING == LV_STDLIB_CLIB*/
int32_t lv_xml_atoi(const char * str)
{
const char * s = str;
int32_t result = 0;
int sign = 1;
/* Skip leading whitespace */
while(*s == ' ' || *s == '\t') s++;
/* Handle optional sign */
if(*s == '-') {
sign = -1;
s++;
}
else if(*s == '+') {
s++;
}
/* Convert the string*/
while(*s) {
if(*s >= '0' && *s <= '9') {
int32_t digit = *s - '0';
/* Check for overflow before it happens */
if(result > (INT_MAX - digit) / 10) {
return (sign == 1) ? INT_MAX : INT_MIN; // Return limits on overflow
}
result = result * 10 + digit;
s++;
}
else {
break; // Non-digit character
}
}
return result * sign;
}
int32_t lv_xml_strtol(const char * str, char ** endptr, int32_t base)
{
const char * s = str;
int32_t result = 0;
int32_t sign = 1;
/* Skip leading whitespace */
while(*s == ' ' || *s == '\t') s++;
/* Handle optional sign*/
if(*s == '-') {
sign = -1;
s++;
}
else if(*s == '+') {
s++;
}
/* Determine base if 0 is passed as base*/
if(base == 0) {
if(*s == '0') {
if(*(s + 1) == 'x' || *(s + 1) == 'X') {
base = 16;
s += 2;
}
else {
base = 8;
s++;
}
}
else {
base = 10;
}
}
/* Convert the string*/
while(*s) {
int32_t digit;
if(lv_xml_is_digit(*s, base)) {
if(*s >= '0' && *s <= '9') {
digit = *s - '0';
}
else if(*s >= 'a' && *s <= 'f') {
digit = *s - 'a' + 10;
}
else if(*s >= 'A' && *s <= 'F') {
digit = *s - 'A' + 10;
}
else {
/* This should not happen due to lv_xml_is_digit check*/
break;
}
/* Check for overflow */
if(result > (INT32_MAX - digit) / base) {
result = (sign == 1) ? INT32_MAX : INT32_MIN;
if(endptr) *endptr = (char *)s;
return result;
}
result = result * base + digit;
}
s++;
}
/* Set end pointer to the last character processed*/
if(endptr) {
*endptr = (char *)s;
}
return result * sign;
}
#endif /*LV_USE_STDLIB_STRING == LV_STDLIB_CLIB*/
char * lv_xml_split_str(char ** src, char delimiter)
{
if(*src[0] == '\0') return NULL;
char * src_first = *src;
char * src_next = *src;
/*Find the delimiter*/
while(*src_next != '\0') {
if(*src_next == delimiter) {
*src_next = '\0'; /*Close the string on the delimiter*/
*src = src_next + 1; /*Change the source continue after the found delimiter*/
return src_first;
}
src_next++;
}
/*No delimiter found, return the string as it is*/
*src = src_next; /*Move the source point to the end*/
return src_first;
}
/**********************
* STATIC FUNCTIONS
**********************/
#if LV_USE_STDLIB_STRING != LV_STDLIB_CLIB
static bool lv_xml_is_digit(char c, int base)
{
if(base <= 10) {
return (c >= '0' && c < '0' + base);
}
else {
return (c >= '0' && c <= '9') || (c >= 'a' && c < 'a' + (base - 10)) || (c >= 'A' && c < 'A' + (base - 10));
}
}
#endif /*LV_USE_STDLIB_STRING == LV_STDLIB_CLIB*/
#endif /* LV_USE_XML */

View File

@ -0,0 +1,50 @@
/**
* @file lv_xml_utils.h
*
*/
#ifndef LV_XML_UTILS_H
#define LV_XML_UTILS_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../lv_conf_internal.h"
#if LV_USE_XML
#include LV_STDINT_INCLUDE
#include "../../misc/lv_color.h"
/**********************
* GLOBAL PROTOTYPES
**********************/
const char * lv_xml_get_value_of(const char ** attrs, const char * name);
int32_t lv_xml_atoi(const char * str);
lv_color_t lv_xml_to_color(const char * str);
bool lv_xml_to_bool(const char * str);
int32_t lv_xml_strtol(const char * str, char ** endptr, int32_t base);
/**
* Find a delimiter in a string, terminate the string on the delimiter and
* update the source string to the next part
* @param src point to a variable containing the input string
* @param delimiter a delimiter character, e.g. ':'
* @return the beginning of next section in the string closed at the delimiter
*/
char * lv_xml_split_str(char ** src, char delimiter);
#endif /* LV_USE_XML */
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_XML_UTILS_H*/

View File

@ -0,0 +1,78 @@
/**
* @file lv_xml_widget.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_xml_widget.h"
#include "lv_xml_parser.h"
#include "../../stdlib/lv_string.h"
#include "../../stdlib/lv_mem.h"
#if LV_USE_XML
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
static lv_widget_processor_t * widget_processor_head;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
lv_result_t lv_xml_widget_register(const char * name, lv_xml_widget_create_cb_t create_cb,
lv_xml_widget_apply_cb_t apply_cb)
{
lv_widget_processor_t * p = lv_malloc(sizeof(lv_widget_processor_t));
lv_memzero(p, sizeof(lv_widget_processor_t));
p->name = lv_strdup(name);
p->create_cb = create_cb;
p->apply_cb = apply_cb;
if(widget_processor_head == NULL) widget_processor_head = p;
else {
p->next = widget_processor_head;
widget_processor_head = p;
}
return LV_RESULT_OK;
}
lv_widget_processor_t * lv_xml_widget_get_processor(const char * name)
{
/* Select the widget specific parser type based on the name */
lv_widget_processor_t * p = widget_processor_head;
while(p) {
if(lv_streq(p->name, name)) {
return p;
}
p = p->next;
}
return NULL;
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif /* LV_USE_XML */

View File

@ -0,0 +1,57 @@
/**
* @file lv_xml_widget.h
*
*/
#ifndef LV_XML_WIDGET_H
#define LV_XML_WIDGET_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../misc/lv_types.h"
#if LV_USE_XML
#include "lv_xml.h"
#include "lv_xml_utils.h"
/**********************
* TYPEDEFS
**********************/
typedef void * (*lv_xml_widget_create_cb_t)(lv_xml_parser_state_t * state, const char ** parent_attrs);
typedef void (*lv_xml_widget_apply_cb_t)(lv_xml_parser_state_t * state, const char ** parent_attrs);
typedef struct _lv_widget_processor_t {
const char * name;
lv_xml_widget_create_cb_t create_cb;
lv_xml_widget_apply_cb_t apply_cb;
struct _lv_widget_processor_t * next;
} lv_widget_processor_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
lv_result_t lv_xml_widget_register(const char * name, lv_xml_widget_create_cb_t create_cb,
lv_xml_widget_apply_cb_t apply_cb);
lv_widget_processor_t * lv_xml_widget_get_processor(const char * name);
/**********************
* MACROS
**********************/
#endif /* LV_USE_XML */
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_XML_WIDGET_H*/

View File

@ -0,0 +1,59 @@
/**
* @file lv_xml_button_parser.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_xml_button_parser.h"
#if LV_USE_XML
#include "../../../lvgl.h"
#include "../../../lvgl_private.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void * lv_xml_button_create(lv_xml_parser_state_t * state, const char ** attrs)
{
LV_UNUSED(attrs);
void * item = lv_button_create(lv_xml_state_get_parent(state));
return item;
}
void lv_xml_button_apply(lv_xml_parser_state_t * state, const char ** attrs)
{
/*Apply the common properties, e.g. width, height, styles flags etc*/
lv_xml_obj_apply(state, attrs);
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif /* LV_USE_XML */

View File

@ -0,0 +1,41 @@
/**
* @file lv_xml_button_parser.h
*
*/
#ifndef LV_BUTTON_XML_PARSER_H
#define LV_BUTTON_XML_PARSER_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../lv_xml.h"
#if LV_USE_XML
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void * lv_xml_button_create(lv_xml_parser_state_t * state, const char ** attrs);
void lv_xml_button_apply(lv_xml_parser_state_t * state, const char ** attrs);
/**********************
* MACROS
**********************/
#endif /* LV_USE_XML */
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_BUTTON_XML_PARSE_H*/

View File

@ -0,0 +1,145 @@
/**
* @file lv_xml_chart_parser.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_xml_chart_parser.h"
#if LV_USE_XML
#include "../../../lvgl.h"
#include "../../../lvgl_private.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static lv_chart_type_t chart_type_string_to_enum_value(const char * txt);
static lv_chart_update_mode_t chart_update_mode_string_to_enum_value(const char * txt);
static lv_chart_axis_t chart_axis_string_to_enum_value(const char * txt);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void * lv_xml_chart_create(lv_xml_parser_state_t * state, const char ** attrs)
{
LV_UNUSED(attrs);
void * item = lv_chart_create(lv_xml_state_get_parent(state));
return item;
}
void lv_xml_chart_apply(lv_xml_parser_state_t * state, const char ** attrs)
{
void * item = lv_xml_state_get_item(state);
lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/
for(int i = 0; attrs[i]; i += 2) {
const char * name = attrs[i];
const char * value = attrs[i + 1];
if(lv_streq("point_count", name)) lv_chart_set_point_count(item, lv_xml_atoi(value));
if(lv_streq("type", name)) lv_chart_set_type(item, chart_type_string_to_enum_value(value));
if(lv_streq("mode", name)) lv_chart_set_update_mode(item, chart_update_mode_string_to_enum_value(value));
}
}
void * lv_xml_chart_series_create(lv_xml_parser_state_t * state, const char ** attrs)
{
const char * color = lv_xml_get_value_of(attrs, "color");
const char * axis = lv_xml_get_value_of(attrs, "axis");
void * item = lv_chart_add_series(lv_xml_state_get_parent(state), lv_color_hex(lv_xml_strtol(color, NULL, 16)),
chart_axis_string_to_enum_value(axis));
lv_obj_t * parent = lv_xml_state_get_parent(state);
lv_chart_set_all_value(parent, item, lv_rand(10, 90));
return item;
}
void lv_xml_chart_series_apply(lv_xml_parser_state_t * state, const char ** attrs)
{
LV_UNUSED(state);
LV_UNUSED(attrs);
/*Nothing to apply*/
}
void * lv_xml_chart_cursor_create(lv_xml_parser_state_t * state, const char ** attrs)
{
const char * color = lv_xml_get_value_of(attrs, "color");
const char * dir = lv_xml_get_value_of(attrs, "dir");
void * item = lv_chart_add_cursor(lv_xml_state_get_parent(state), lv_color_hex(lv_xml_strtol(color, NULL, 16)),
lv_xml_dir_string_to_enum_value(dir));
lv_obj_t * parent = lv_xml_state_get_parent(state);
lv_point_t p = {30, 40};
lv_chart_set_cursor_pos(parent, item, &p);
/* There are no properties to process */
return item;
}
void lv_xml_chart_cursor_apply(lv_xml_parser_state_t * state, const char ** attrs)
{
LV_UNUSED(state);
LV_UNUSED(attrs);
/*Nothing to apply*/
}
/**********************
* STATIC FUNCTIONS
**********************/
static lv_chart_type_t chart_type_string_to_enum_value(const char * txt)
{
if(lv_streq("none", txt)) return LV_CHART_TYPE_NONE;
if(lv_streq("line", txt)) return LV_CHART_TYPE_LINE;
if(lv_streq("bar", txt)) return LV_CHART_TYPE_BAR;
if(lv_streq("scatter", txt)) return LV_CHART_TYPE_SCATTER;
LV_LOG_WARN("%s is an unknown value for chart's chart_type", txt);
return 0; /*Return 0 in lack of a better option. */
}
static lv_chart_update_mode_t chart_update_mode_string_to_enum_value(const char * txt)
{
if(lv_streq("shift", txt)) return LV_CHART_UPDATE_MODE_SHIFT;
if(lv_streq("circular", txt)) return LV_CHART_UPDATE_MODE_CIRCULAR;
LV_LOG_WARN("%s is an unknown value for chart's chart_update_mode", txt);
return 0; /*Return 0 in lack of a better option. */
}
static lv_chart_axis_t chart_axis_string_to_enum_value(const char * txt)
{
if(lv_streq("primary_x", txt)) return LV_CHART_AXIS_PRIMARY_X;
if(lv_streq("primary_y", txt)) return LV_CHART_AXIS_PRIMARY_Y;
if(lv_streq("secondary_x", txt)) return LV_CHART_AXIS_SECONDARY_X;
if(lv_streq("secondary_y", txt)) return LV_CHART_AXIS_SECONDARY_Y;
LV_LOG_WARN("%s is an unknown value for chart's chart_axis", txt);
return 0; /*Return 0 in lack of a better option. */
}
#endif /* LV_USE_XML */

View File

@ -0,0 +1,43 @@
/**
* @file lv_xml_chart_parser.h
*
*/
#ifndef LV_CHART_XML_PARSER_H
#define LV_CHART_XML_PARSER_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../lv_xml.h"
#if LV_USE_XML
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void * lv_xml_chart_create(lv_xml_parser_state_t * state, const char ** attrs);
void lv_xml_chart_apply(lv_xml_parser_state_t * state, const char ** attrs);
void * lv_xml_chart_series_create(lv_xml_parser_state_t * state, const char ** attrs);
void lv_xml_chart_series_apply(lv_xml_parser_state_t * state, const char ** attrs);
void * lv_xml_chart_cursor_create(lv_xml_parser_state_t * state, const char ** attrs);
void lv_xml_chart_cursor_apply(lv_xml_parser_state_t * state, const char ** attrs);
/**********************
* MACROS
**********************/
#endif /* LV_USE_XML */
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_CHART_XML_PARSE_H*/

View File

@ -0,0 +1,112 @@
/**
* @file lv_xml_image_parser.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_xml_image_parser.h"
#if LV_USE_XML
#include "../../../lvgl.h"
#include "../../../lvgl_private.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void * lv_xml_image_create(lv_xml_parser_state_t * state, const char ** attrs)
{
LV_UNUSED(attrs);
void * item = lv_image_create(lv_xml_state_get_parent(state));
if(item == NULL) {
LV_LOG_ERROR("Failed to create image");
return NULL;
}
return item;
}
void lv_xml_check_file(const char * filepath)
{
lv_fs_file_t f;
lv_fs_res_t res = lv_fs_open(&f, filepath, LV_FS_MODE_RD);
if(res == LV_FS_RES_OK) {
uint32_t size;
uint8_t buffer[10];
lv_fs_read(&f, buffer, 0, &size);
lv_fs_seek(&f, 0, LV_FS_SEEK_END);
lv_fs_tell(&f, &size);
LV_LOG_USER("File %s exists (%u bytes)", filepath, size);
lv_fs_close(&f);
lv_image_header_t info;
lv_image_decoder_get_info(filepath, &info);
LV_LOG_USER("Image info: %d x %d, %d color", info.w, info.h, info.cf);
}
else {
LV_LOG_ERROR("Failed to open file: %s", filepath);
}
}
void lv_xml_image_apply(lv_xml_parser_state_t * state, const char ** attrs)
{
void * item = lv_xml_state_get_item(state);
if(item == NULL) {
LV_LOG_ERROR("Failed to get image");
return;
}
lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/
for(int i = 0; attrs[i]; i += 2) {
const char * name = attrs[i];
const char * value = attrs[i + 1];
if(lv_streq("src", name)) {
const void * img_src = lv_xml_get_image(value);
if(img_src == NULL) {
LV_LOG_WARN("Failed to get image source for '%s'", value);
return;
}
lv_image_set_src(item, (const char *)img_src);
}
}
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif /* LV_USE_XML */

View File

@ -0,0 +1,43 @@
/**
* @file lv_xml_image_parser.h
*
*/
#ifndef LV_XML_IMAGE_PARSER_H
#define LV_XML_IMAGE_PARSER_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../lv_xml.h"
#if LV_USE_XML
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void * lv_xml_image_create(lv_xml_parser_state_t * state, const char ** attrs);
void lv_xml_image_apply(lv_xml_parser_state_t * state, const char ** attrs);
void lv_xml_check_file(const char * filepath);
/**********************
* MACROS
**********************/
#endif /* LV_USE_XML */
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_XML_IMAGE_PARSER_H*/

View File

@ -0,0 +1,76 @@
/**
* @file lv_xml_label_parser.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_xml_label_parser.h"
#if LV_USE_XML
#include "../../../lvgl.h"
#include "../../../lvgl_private.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static lv_label_long_mode_t long_mode_text_to_enum_value(const char * txt);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void * lv_xml_label_create(lv_xml_parser_state_t * state, const char ** attrs)
{
LV_UNUSED(attrs);
void * item = lv_label_create(lv_xml_state_get_parent(state));
return item;
}
void lv_xml_label_apply(lv_xml_parser_state_t * state, const char ** attrs)
{
void * item = lv_xml_state_get_item(state);
lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/
for(int i = 0; attrs[i]; i += 2) {
const char * name = attrs[i];
const char * value = attrs[i + 1];
if(lv_streq("text", name)) lv_label_set_text(item, value);
if(lv_streq("long_mode", name)) lv_label_set_long_mode(item, long_mode_text_to_enum_value(value));
}
}
/**********************
* STATIC FUNCTIONS
**********************/
static lv_label_long_mode_t long_mode_text_to_enum_value(const char * txt)
{
if(lv_streq("wrap", txt)) return LV_LABEL_LONG_MODE_WRAP;
if(lv_streq("scroll", txt)) return LV_LABEL_LONG_MODE_SCROLL;
LV_LOG_WARN("%s is an unknown value for label's long_mode", txt);
return 0; /*Return 0 in lack of a better option. */
}
#endif /* LV_USE_XML */

View File

@ -0,0 +1,41 @@
/**
* @file lv_xml_label_parser.h
*
*/
#ifndef LV_LABEL_XML_PARSER_H
#define LV_LABEL_XML_PARSER_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../lv_xml.h"
#if LV_USE_XML
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void * lv_xml_label_create(lv_xml_parser_state_t * state, const char ** attrs);
void lv_xml_label_apply(lv_xml_parser_state_t * state, const char ** attrs);
/**********************
* MACROS
**********************/
#endif /* LV_USE_XML */
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_LABEL_XML_PARSE_H*/

View File

@ -0,0 +1,89 @@
/**
* @file lv_xml_obj_parser.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_xml_obj_parser.h"
#if LV_USE_XML
#include "../../../lvgl.h"
#include "../../../lvgl_private.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void * lv_xml_obj_create(lv_xml_parser_state_t * state, const char ** attrs)
{
LV_UNUSED(attrs);
void * item = lv_obj_create(lv_xml_state_get_parent(state));
return item;
}
void lv_xml_obj_apply(lv_xml_parser_state_t * state, const char ** attrs)
{
void * item = lv_xml_state_get_item(state);
for(int i = 0; attrs[i]; i += 2) {
const char * name = attrs[i];
const char * value = attrs[i + 1];
if(lv_streq("x", name)) lv_obj_set_x(item, lv_xml_to_size(value));
if(lv_streq("y", name)) lv_obj_set_y(item, lv_xml_to_size(value));
if(lv_streq("width", name)) lv_obj_set_width(item, lv_xml_to_size(value));
if(lv_streq("height", name)) lv_obj_set_height(item, lv_xml_to_size(value));
if(lv_streq("align", name)) lv_obj_set_align(item, lv_xml_align_string_to_enum_value(value));
if(lv_streq("styles", name)) lv_xml_style_add_to_obj(state, item, value);
if(lv_strlen(name) > 6 && lv_memcmp("style_", name, 6) == 0) {
char name_local[512];
lv_strlcpy(name_local, name, sizeof(name_local));
lv_style_selector_t selector;
const char * prop_name = lv_xml_style_string_process(name_local, &selector);
if(lv_streq("style_radius", prop_name)) lv_obj_set_style_radius(item, lv_xml_atoi(value), selector);
if(lv_streq("style_bg_color", prop_name)) lv_obj_set_style_bg_color(item, lv_xml_to_color(value), selector);
if(lv_streq("style_bg_opa", prop_name)) lv_obj_set_style_bg_opa(item, lv_xml_atoi(value), selector);
if(lv_streq("style_border_color", prop_name)) lv_obj_set_style_border_color(item, lv_xml_to_color(value), selector);
if(lv_streq("style_border_opa", prop_name)) lv_obj_set_style_border_opa(item, lv_xml_atoi(value), selector);
if(lv_streq("style_border_width", prop_name)) lv_obj_set_style_border_width(item, lv_xml_atoi(value), selector);
if(lv_streq("style_bg_image_src", prop_name)) lv_obj_set_style_bg_image_src(item, lv_xml_get_image(value), selector);
if(lv_streq("style_bg_image_tiled", prop_name)) lv_obj_set_style_bg_image_tiled(item, lv_xml_to_bool(value), selector);
if(lv_streq("style_text_color", prop_name)) lv_obj_set_style_text_color(item, lv_xml_to_color(value), selector);
if(lv_streq("style_text_font", prop_name)) lv_obj_set_style_text_font(item, lv_xml_get_font(value), selector);
}
}
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif /* LV_USE_XML */

View File

@ -0,0 +1,41 @@
/**
* @file lv_xml_obj_parser.h
*
*/
#ifndef LV_OBJ_XML_PARSER_H
#define LV_OBJ_XML_PARSER_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../lv_xml.h"
#if LV_USE_XML
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void * lv_xml_obj_create(lv_xml_parser_state_t * state, const char ** attrs);
void lv_xml_obj_apply(lv_xml_parser_state_t * state, const char ** attrs);
/**********************
* MACROS
**********************/
#endif /* LV_USE_XML */
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_OBJ_XML_PARSE_H*/

View File

@ -0,0 +1,99 @@
/**
* @file lv_xml_slider_parser.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_xml_slider_parser.h"
#if LV_USE_XML
#include "../../../lvgl.h"
#include "../../../lvgl_private.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static lv_slider_orientation_t orentation_text_to_enum_value(const char * txt);
static lv_slider_mode_t mode_text_to_enum_value(const char * txt);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void * lv_xml_slider_create(lv_xml_parser_state_t * state, const char ** attrs)
{
LV_UNUSED(attrs);
void * item = lv_slider_create(lv_xml_state_get_parent(state));
return item;
}
void lv_xml_slider_apply(lv_xml_parser_state_t * state, const char ** attrs)
{
void * item = lv_xml_state_get_item(state);
lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/
for(int i = 0; attrs[i]; i += 2) {
const char * name = attrs[i];
const char * value = attrs[i + 1];
if(lv_streq("value", name)) lv_slider_set_value(item, lv_xml_atoi(value), LV_ANIM_OFF);
if(lv_streq("left_value", name)) lv_slider_set_left_value(item, lv_xml_atoi(value), LV_ANIM_OFF);
if(lv_streq("orientation", name)) lv_slider_set_orientation(item, orentation_text_to_enum_value(value));
if(lv_streq("mode", name)) lv_slider_set_mode(item, mode_text_to_enum_value(value));
if(lv_streq("range_min", name)) lv_slider_set_range(item, lv_xml_atoi(value), lv_slider_get_max_value(item));
if(lv_streq("range_max", name)) lv_slider_set_range(item, lv_slider_get_min_value(item), lv_xml_atoi(value));
if(lv_streq("range", name)) {
char buf[64];
lv_strlcpy(buf, value, sizeof(buf));
char * buf_p = buf;
int32_t v1 = lv_xml_atoi(lv_xml_split_str(&buf_p, ' '));
int32_t v2 = lv_xml_atoi(buf_p);
lv_slider_set_range(item, v1, v2);
}
}
}
/**********************
* STATIC FUNCTIONS
**********************/
static lv_slider_orientation_t orentation_text_to_enum_value(const char * txt)
{
if(lv_streq("auto", txt)) return LV_SLIDER_ORIENTATION_AUTO;
if(lv_streq("horizontal", txt)) return LV_SLIDER_ORIENTATION_HORIZONTAL;
if(lv_streq("vertical", txt)) return LV_SLIDER_ORIENTATION_VERTICAL;
LV_LOG_WARN("%s is an unknown value for slider's orientation", txt);
return 0; /*Return 0 in lack of a better option. */
}
static lv_slider_mode_t mode_text_to_enum_value(const char * txt)
{
if(lv_streq("normal", txt)) return LV_SLIDER_MODE_NORMAL;
if(lv_streq("range", txt)) return LV_SLIDER_MODE_RANGE;
if(lv_streq("symmetrical", txt)) return LV_SLIDER_MODE_SYMMETRICAL;
LV_LOG_WARN("%s is an unknown value for slider's mode", txt);
return 0; /*Return 0 in lack of a better option. */
}
#endif /* LV_USE_XML */

View File

@ -0,0 +1,40 @@
/**
* @file lv_xml_slider_parser.h
*
*/
#ifndef LV_SLIDER_XML_PARSER_H
#define LV_SLIDER_XML_PARSER_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../lv_xml.h"
#if LV_USE_XML
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void * lv_xml_slider_create(lv_xml_parser_state_t * state, const char ** attrs);
void lv_xml_slider_apply(lv_xml_parser_state_t * state, const char ** attrs);
/**********************
* MACROS
**********************/
#endif /* LV_USE_XML */
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_SLIDER_XML_PARSE_H*/

View File

@ -0,0 +1,109 @@
/**
* @file lv_xml_tabview_parser.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_xml_tabview_parser.h"
#if LV_USE_XML
#include "../../../lvgl.h"
#include "../../../lvgl_private.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void * lv_xml_tabview_create(lv_xml_parser_state_t * state, const char ** attrs)
{
void * item = lv_tabview_create(lv_xml_state_get_parent(state));
lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/
for(int i = 0; attrs[i]; i += 2) {
const char * name = attrs[i];
const char * value = attrs[i + 1];
if(lv_streq("active", name)) lv_tabview_set_active(item, lv_xml_atoi(value), 0);
if(lv_streq("tab_bar_position", name)) lv_tabview_set_tab_bar_position(item, lv_xml_dir_string_to_enum_value(value));
}
return item;
}
void lv_xml_tabview_apply(lv_xml_parser_state_t * state, const char ** attrs)
{
void * item = lv_xml_state_get_item(state);
lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/
for(int i = 0; attrs[i]; i += 2) {
const char * name = attrs[i];
const char * value = attrs[i + 1];
if(lv_streq("active", name)) lv_tabview_set_active(item, lv_xml_atoi(value), 0);
if(lv_streq("tab_bar_position", name)) lv_tabview_set_tab_bar_position(item, lv_xml_dir_string_to_enum_value(value));
}
}
void * lv_xml_tabview_tab_bar_create(lv_xml_parser_state_t * state, const char ** attrs)
{
void * item = lv_tabview_get_tab_bar(lv_xml_state_get_parent(state));
/*Apply the common properties, e.g. width, height, styles flags etc*/
lv_xml_obj_apply(state, attrs);
return item;
}
void lv_xml_tabview_tab_bar_apply(lv_xml_parser_state_t * state, const char ** attrs)
{
/*Apply the common properties, e.g. width, height, styles flags etc*/
lv_xml_obj_apply(state, attrs);
}
void * lv_xml_tabview_tab_create(lv_xml_parser_state_t * state, const char ** attrs)
{
const char * text = lv_xml_get_value_of(attrs, "text");
void * item = lv_tabview_add_tab(lv_xml_state_get_parent(state), text);
/*Apply the common properties, e.g. width, height, styles flags etc*/
lv_xml_obj_apply(state, attrs);
return item;
}
void lv_xml_tabview_tab_apply(lv_xml_parser_state_t * state, const char ** attrs)
{
/*Apply the common properties, e.g. width, height, styles flags etc*/
lv_xml_obj_apply(state, attrs);
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif /* LV_USE_XML */

View File

@ -0,0 +1,44 @@
/**
* @file lv_xml_tabview_parser.h
*
*/
#ifndef LV_TABVIEW_XML_PARSER_H
#define LV_TABVIEW_XML_PARSER_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../lv_xml.h"
#if LV_USE_XML
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void * lv_xml_tabview_create(lv_xml_parser_state_t * state, const char ** attrs);
void lv_xml_tabview_apply(lv_xml_parser_state_t * state, const char ** attrs);
void * lv_xml_tabview_tab_bar_create(lv_xml_parser_state_t * state, const char ** attrs);
void lv_xml_tabview_tab_bar_apply(lv_xml_parser_state_t * state, const char ** attrs);
void * lv_xml_tabview_tab_create(lv_xml_parser_state_t * state, const char ** attrs);
void lv_xml_tabview_tab_apply(lv_xml_parser_state_t * state, const char ** attrs);
/**********************
* MACROS
**********************/
#endif /* LV_USE_XML */
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_TABVIEW_XML_PARSE_H*/

View File

@ -128,6 +128,17 @@ int lv_strcmp(const char * s1, const char * s2);
*/
int lv_strncmp(const char * s1, const char * s2, size_t len);
/** Returns true if the two strings are equal.
* Just a wrapper around strcmp for convenience.
* @param s1 pointer to the first string
* @param s2 pointer to the second string
* @return true: the strings are equal; false: otherwise
*/
static inline bool lv_streq(const char * s1, const char * s2)
{
return lv_strcmp(s1, s2) == 0;
}
/**
* @brief Duplicate a string by allocating a new one and copying the content.
* @param src Pointer to the source of data to be copied.

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -101,6 +101,7 @@
#define LV_USE_PROFILER 1
#define LV_PROFILER_INCLUDE "lv_profiler_builtin.h"
#define LV_USE_GRIDNAV 1
#define LV_USE_XML 1
#define LV_BUILD_EXAMPLES 1
#define LV_USE_DEMO_WIDGETS 1

View File

@ -0,0 +1,38 @@
/**
* @file lv_example_xml.h
*
*/
#ifndef LV_EXAMPLE_XML_H
#define LV_EXAMPLE_XML_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_example_xml_1(void);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_EXAMPLE_XML_H*/

View File

@ -0,0 +1,15 @@
<component>
<consts>
<px name="size" value="100"/>
<color name="orange" value="0xffa020"/>
</consts>
<api>
<prop type="string" name="btn_text"/>
</api>
<view extends="lv_button" width="#size">
<my_h3 text="$btn_text" align="center" color="#orange"/>
</view>
</component>

View File

@ -0,0 +1,23 @@
<component>
<consts>
<px name="size" value="100%"/>
</consts>
<api>
<prop type="string" name="title" default="No title"/>
<prop type="string" name="action" default="No action"/>
<prop type="color" name="bg_color" default="0xcccccc"/>
<prop type="style" name="btn_rel_style"/>
<prop type="style" name="btn_pr_style"/>
</api>
<styles>
<style name="gray" bg_color="0x888888"/>
<style name="blue" bg_color="0x0000ff"/>
</styles>
<view extends="lv_obj" style_radius="3" width="#size" height="content" style_bg_color="$bg_color" >
<lv_label text="$title" align="left_mid"/>
<my_button styles="$btn_rel_style $btn_pr_style:pressed" btn_text="$action" align="right_mid"/>
</view>
</component>

View File

@ -0,0 +1,10 @@
<component>
<api>
<prop type="color" name="color" default="0"/>
<prop type="style" name="style"/>
</api>
<view extends="lv_label"
style_text_color="$color"
styles="$style"
style_text_font="lv_montserrat_18"></view>
</component>

View File

@ -0,0 +1,25 @@
<component>
<consts>
<color name="light_blue" value="0xbbbbff"/>
<color name="dark_blue" value="0x000080"/>
</consts>
<styles>
<style name="btn_style" bg_color="#dark_blue" bg_opa="150"/>
<style name="btn_pr_style" bg_opa="255"/>
</styles>
<view extends="lv_obj" width="280" height="content" style_bg_color="#light_blue">
<lv_label text="Hello"/>
<my_card title="Card 1"
y="0"
btn_rel_style="btn_style"
btn_pr_style="btn_pr_style"/>
<my_card y="85"
bg_color="0xffaaaa"
action="Apply"
btn_rel_style="btn_style"
btn_pr_style="btn_pr_style"/>
</view>
</component>

View File

@ -0,0 +1,348 @@
#if LV_BUILD_TEST
#include "../lvgl.h"
#include "unity/unity.h"
void setUp(void)
{
/* Function run before every test */
}
void tearDown(void)
{
/* Function run after every test */
lv_obj_clean(lv_screen_active());
}
void test_xml_widget_direct_create(void)
{
lv_obj_set_style_pad_all(lv_screen_active(), 16, 0);
lv_obj_t * slider;
/*Simple create*/
slider = lv_xml_create(lv_screen_active(), "lv_slider", NULL);
/*Adjust the returned widget*/
slider = lv_xml_create(lv_screen_active(), "lv_slider", NULL);
lv_obj_set_pos(slider, 10, 100);
lv_slider_set_value(slider, 40, LV_ANIM_OFF);
/*Use attributes*/
const char * attrs[] = {
"range_min", "-100",
"range_max", "100",
"mode", "symmetrical",
"value", "50",
NULL, NULL,
};
slider = lv_xml_create(lv_screen_active(), "lv_slider", attrs);
lv_obj_set_pos(slider, 10, 200);
TEST_ASSERT_EQUAL_SCREENSHOT("xml/widget_create_1.png");
}
void test_xml_widget_create_from_component(void)
{
lv_obj_set_style_pad_all(lv_screen_active(), 16, 0);
const char * red_slider_xml =
"<component>"
"<view extends=\"lv_slider\" value=\"20\" width=\"100%\" style_bg_color=\"0xff0000\">"
"</view>"
"</component>";
lv_xml_component_register_from_data("red_slider", red_slider_xml);
lv_obj_t * slider;
/*Simple create*/
slider = lv_xml_create(lv_screen_active(), "red_slider", NULL);
/*Adjust the returned widget*/
slider = lv_xml_create(lv_screen_active(), "red_slider", NULL);
lv_obj_set_pos(slider, 10, 100);
lv_slider_set_value(slider, 40, LV_ANIM_OFF);
/*Use attributes*/
const char * attrs[] = {
"range_min", "-100",
"range_max", "100",
"mode", "symmetrical",
"value", "50",
NULL, NULL,
};
slider = lv_xml_create(lv_screen_active(), "red_slider", attrs);
lv_obj_set_pos(slider, 10, 200);
TEST_ASSERT_EQUAL_SCREENSHOT("xml/component_create_1.png");
}
void test_xml_nesting(void)
{
const char * red_button_xml =
"<component>"
"<view extends=\"lv_button\" radius=\"0\" style_bg_color=\"0xff0000\">"
"</view>"
"</component>";
const char * card_xml =
"<component>"
"<view width=\"200\" height=\"content\">"
"<lv_label text=\"Some text here\" align=\"top_mid\"/>"
"<red_button y=\"20\">"
"<lv_label text=\"Button 1\" align=\"center\"/>"
"</red_button>"
"</view>"
"</component>";
lv_xml_component_register_from_data("red_button", red_button_xml);
lv_xml_component_register_from_data("card", card_xml);
lv_obj_t * card;
card = lv_xml_create(lv_screen_active(), "card", NULL);
card = lv_xml_create(lv_screen_active(), "card", NULL);
lv_obj_set_y(card, 80);
/*Use attributes*/
const char * attrs[] = {
"y", "160",
NULL, NULL,
};
card = lv_xml_create(lv_screen_active(), "card", attrs);
TEST_ASSERT_EQUAL_SCREENSHOT("xml/nested_1.png");
}
/*Pass style and simple properties 3 level deep*/
void test_xml_component_params(void)
{
const char * h3_xml =
"<component>"
"<api>"
"<prop name=\"style\" type=\"style\"/>"
"</api>"
"<view extends=\"lv_label\" styles=\"$style\">"
"</view>"
"</component>";
const char * red_button_xml =
"<component>"
"<api>"
"<prop type=\"string\" name=\"btn_text\"/>"
"<prop type=\"style\" name=\"label_style\"/>"
"</api>"
"<view extends=\"lv_button\" style_radius=\"0\" style_bg_color=\"0xff0000\">"
"<h3 text=\"$btn_text\" style=\"$label_style\"/>"
"</view>"
"</component>";
const char * card_xml =
"<component>"
"<api>"
"<prop type=\"string\" name=\"action\" default=\"Default\"/>"
"</api>"
"<styles>"
"<style name=\"style1\" text_color=\"0xffff00\"/>"
"</styles>"
"<view width=\"200\" height=\"content\">"
"<h3 text=\"Title\" align=\"top_mid\" style_text_color=\"0xff0000\"/>"
"<red_button btn_text=\"$action\" label_style=\"style1\" y=\"20\"/>"
"</view>"
"</component>";
lv_xml_component_register_from_data("h3", h3_xml);
lv_xml_component_register_from_data("red_button", red_button_xml);
lv_xml_component_register_from_data("card", card_xml);
lv_xml_create(lv_screen_active(), "card", NULL);
/*Use attributes*/
const char * attrs[] = {
"y", "100",
"action", "Ext. text",
NULL, NULL,
};
lv_xml_create(lv_screen_active(), "card", attrs);
TEST_ASSERT_EQUAL_SCREENSHOT("xml/params_1.png");
}
void test_xml_component_consts(void)
{
const char * h3_xml =
"<component>"
"<consts>"
"<string name=\"action\" value=\"Log in\"/>"
"<color name=\"dark_color\" value=\"0x804000\"/>"
"<color name=\"accent_color\" value=\"0xff8000\"/>"
"<int name=\"size\" value=\"200\"/>"
"</consts>"
"<styles>"
"<style name=\"style1\" bg_color=\"#dark_color\" bg_opa=\"255\"/>"
"</styles>"
"<view extends=\"lv_label\" width=\"#size\" style_text_color=\"#accent_color\" text=\"#action\" styles=\"style1\">"
"</view>"
"</component>";
lv_xml_component_register_from_data("h3", h3_xml);
lv_xml_create(lv_screen_active(), "h3", NULL);
TEST_ASSERT_EQUAL_SCREENSHOT("xml/consts_1.png");
}
void test_xml_component_styles(void)
{
const char * my_btn_xml =
"<component>"
"<styles>"
"<style name=\"rel_style\" bg_color=\"0xff0000\"/>"
"<style name=\"pr_style\" bg_color=\"0x800000\"/>"
"</styles>"
"<view extends=\"lv_button\" style_text_color=\"0x0000ff\" style_text_color:checked=\"0xa0a0ff\" styles=\"rel_style pr_style:checked\">"
"<lv_label/>"
"</view>"
"</component>";
lv_xml_component_register_from_data("my_btn", my_btn_xml);
lv_xml_create(lv_screen_active(), "my_btn", NULL);
lv_obj_t * btn = lv_xml_create(lv_screen_active(), "my_btn", NULL);
lv_obj_set_pos(btn, 0, 100);
lv_obj_add_state(btn, LV_STATE_CHECKED);
lv_test_wait(300); /*Wait for the state transition animation*/
TEST_ASSERT_EQUAL_SCREENSHOT("xml/styles_1.png");
}
void test_xml_error_resilience_syntax_ok(void)
{
const char * my_btn_xml =
"<component>"
"<consts>"
"<int name=\"abc\" value=\"0xff0000\"/>"
"<not_a_type name=\"xyz\" value=\"0xff0000\"/>"
"<int not_a_prop=\"abc\" value=\"0xff0000\"/>"
"<int name=\"abc\" not_a_value=\"0xff0000\"/>"
"</consts>"
"<styles>"
"<style name=\"rel_style\" bg_color=\"0xff0000\" not_a_prop=\"0xff0000\"/>"
"<inv_style name=\"rel_style\" bg_color=\"0x800000\"/>"
"<style bg_color=\"0x800000\"/>"
"</styles>"
"<view extends=\"not_a_widget\" style_text_color=\"0x0000ff\" style_text_color:checked=\"0x8080ff\" styles=\"rel_style pr_style:checked\">"
"<unknown/>"
"<lv_label not_an_attr=\"40\"/>"
"</view>"
"</component>";
lv_xml_component_register_from_data("my_btn", my_btn_xml);
lv_obj_t * btn = lv_xml_create(lv_screen_active(), "my_btn", NULL);
if(btn) lv_obj_set_pos(btn, 0, 100);
}
void test_xml_image_and_font(void)
{
const char * btn_xml =
"<component>"
"<consts>"
"<font name=\"font1\" value=\"lv_montserrat_18\"/>"
"<image name=\"image1\" value=\"test_img1\"/>"
"</consts>"
"<styles>"
"<style name=\"style_rel\" text_font=\"#font1\" text_color=\"0xffffff\" bg_image_src=\"#image1\" bg_image_tiled=\"true\" radius=\"0\"/>"
"<style name=\"style_chk\" text_font=\"lv_montserrat_16\" text_color=\"0xffff00\" bg_image_src=\"test_img2\"/>"
"</styles>"
"<view extends=\"lv_obj\" width=\"100\" height=\"70\" styles=\"style_rel style_chk:checked\" >"
"<lv_label text=\"hello\" align=\"center\" style_bg_color=\"0x888888\" style_bg_opa=\"200\"/>"
"</view>"
"</component>";
/*Monstserrat fonts are registered by LVGL */
LV_IMAGE_DECLARE(img_render_lvgl_logo_l8);
LV_IMAGE_DECLARE(img_render_lvgl_logo_rgb565);
lv_xml_register_image("test_img1", &img_render_lvgl_logo_l8);
lv_xml_register_image("test_img2", &img_render_lvgl_logo_rgb565);
lv_xml_component_register_from_data("btn", btn_xml);
lv_obj_t * btn;
btn = lv_xml_create(lv_screen_active(), "btn", NULL);
btn = lv_xml_create(lv_screen_active(), "btn", NULL);
lv_obj_set_pos(btn, 0, 100);
lv_obj_add_state(btn, LV_STATE_CHECKED);
TEST_ASSERT_EQUAL_SCREENSHOT("xml/image_and_font_1.png");
}
void test_xml_error_resilience_not_closed_tag(void)
{
const char * my_btn_xml =
"<component>"
"<view extends=\"lv_button\">"
"<lv_label/>"
"</component>";
lv_xml_component_register_from_data("my_btn", my_btn_xml);
lv_obj_t * btn = lv_xml_create(lv_screen_active(), "my_btn", NULL);
if(btn) lv_obj_set_pos(btn, 0, 100);
}
void test_xml_error_resilience_string(void)
{
const char * my_btn_xml =
"<component>"
"<view extends=\"lv_button>"
"<lv_label/>"
"</component>";
lv_xml_component_register_from_data("my_btn", my_btn_xml);
lv_obj_t * btn = lv_xml_create(lv_screen_active(), "my_btn", NULL);
if(btn) lv_obj_set_pos(btn, 0, 100);
}
void test_xml_complex(void)
{
lv_xml_component_register_from_file("A:src/test_assets/xml/my_h3.xml");
lv_xml_component_register_from_file("A:src/test_assets/xml/my_card.xml");
lv_xml_component_register_from_file("A:src/test_assets/xml/my_button.xml");
lv_xml_component_register_from_file("A:src/test_assets/xml/view.xml");
lv_obj_t * obj = lv_xml_create(lv_screen_active(), "view", NULL);
lv_obj_set_pos(obj, 10, 10);
const char * my_button_attrs[] = {
"x", "10",
"y", "-10",
"align", "bottom_left",
"btn_text", "New button",
NULL, NULL,
};
lv_xml_create(lv_screen_active(), "my_button", my_button_attrs);
const char * slider_attrs[] = {
"x", "200",
"y", "-15",
"align", "bottom_left",
"value", "30",
NULL, NULL,
};
lv_obj_t * slider = lv_xml_create(lv_screen_active(), "lv_slider", slider_attrs);
lv_obj_set_width(slider, 100);
TEST_ASSERT_EQUAL_SCREENSHOT("xml/complex_1.png");
}
#endif

View File

@ -0,0 +1,75 @@
#if LV_BUILD_TEST
#include "../lvgl.h"
#include "unity/unity.h"
void setUp(void)
{
/* Function run before every test */
}
void tearDown(void)
{
/* Function run after every test */
lv_obj_clean(lv_screen_active());
}
static void test_with_attrs(const char * name)
{
lv_obj_t * scr = lv_screen_active();
lv_obj_set_flex_flow(scr, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(scr, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_xml_create(scr, name, NULL);
const char * attrs_1[] = {
"value", "30",
"width", "100",
NULL, NULL,
};
lv_xml_create(scr, name, attrs_1);
const char * attrs_2[] = {
"range_min", "-100",
"range_max", "100",
"mode", "symmetrical",
"value", "50",
NULL, NULL,
};
lv_xml_create(scr, name, attrs_2);
const char * attrs_3[] = {
"orientation", "vertical",
"height", "80",
"width", "30",
"value", "40",
NULL, NULL,
};
lv_xml_create(scr, name, attrs_3);
TEST_ASSERT_EQUAL_SCREENSHOT("xml/lv_slider.png");
}
void test_xml_slider_widget(void)
{
test_with_attrs("lv_slider");
}
void test_xml_slider_component(void)
{
const char * xml = "<component>"
"<view extends=\"lv_slider\">"
"</view>"
"</component>";
lv_xml_component_register_from_data("slider_test", xml);
test_with_attrs("slider_test");
}
#endif

45
xmls/globals.xml Normal file
View File

@ -0,0 +1,45 @@
<const name="size_content" help="Involve all children"/>
<api>
<enumdef name="lv_style_state">
<enum name="default" help="Some help"/>
<enum name="pressed" help="Some help"/>
<enum name="checked" help="Some help"/>
</enumdef>
<enumdef name="lv_style_part">
<enum name="main" help="Some help"/>
<enum name="scrollbar" help="Some help"/>
<enum name="indicator" help="Some help"/>
<enum name="knob" help="Some help"/>
</enumdef>
<enumdef name="lv_align">
<enum name="top_left" help="Some help"/>
<enum name="bottom_right" help="Some help"/>
<enum name="center" help="Some help"/>
</enumdef>
<enumdef name="lv_dir">
<enum name="top" help="Some help"/>
<enum name="bottom" help="Some help"/>
<enum name="left" help="Some help"/>
<enum name="right" help="Some help"/>
</enumdef>
<enumdef name="lv_flex_flow">
<enum name="row" help="In a row"/>
<enum name="row_wrap" help="In rows and wrap"/>
<enum name="row_reverse" help="In a row with reverse"/>
<enum name="row_wrap_reverse" help="In rows with wrap and reverse"/>
<enum name="column" help="In a column"/>
<enum name="column_wrap" help="In columns and wrap"/>
<enum name="column_reverse" help="In a column with reverse"/>
<enum name="column_wrap_reverse" help="In columns with wrap and reverse"/>
</enumdef>
<enumdef name="lv_flex_align">
<enum name="center" help=""/>
<enum name="start" help=""/>
<enum name="end" help=""/>
<enum name="space_around" help=""/>
<enum name="space_between" help=""/>
<enum name="space_evenly" help=""/>
</enumdef>
</api>

18
xmls/lv_animimg.xml Normal file
View File

@ -0,0 +1,18 @@
<!--
Example
<lv_animinmg src="img1 img2" duration="300" repeat_count="3"/>
-->
<widget>
<api>
<const name="infinite" help="Repeat the animation infinite times"/>
<prop name="src" help="Image sources">
<param name="src_array" type="image_src[count]"/>
</prop>
<prop name="duration" help="Length of the animation in milliseconds">
<param name="time_ms" type="int"/>
</prop>
<prop name="repeat_count">
<param name="cnt" type="int"/>
</prop>
</api>
</widget>

32
xmls/lv_arc.xml Normal file
View File

@ -0,0 +1,32 @@
<!--
Example
<lv_arc mode="reverse" angles="100° 200°" bg_angles="30° 150° range="40 100" value="60"/>
-->
<widget>
<api>
<enumdef name="lv_arc_mode" help="the mode">
<enum name="normal" help="normal"/>
<enum name="symmetrical" help="sym"/>
<enum name="reverse" help="reverse"/>
</enumdef>
<prop name="angles" help="Start and end angles of the indicator">
<param name ="start_angle" type="deg" help="The start angle"/>
<param name ="end_angle" type="deg" help="The end angle"/>
</prop>
<prop name="bg_angles" help="Start and end angles of the background">
<param name ="start_angle" type="deg" help="The start angle"/>
<param name ="end_angle" type="deg" help="The end angle"/>
</prop>
<prop name="range" help="The range">
<param name ="min" type="int" help="The min range"/>
<param name ="max" type="int" help="The max range"/>
</prop>
<prop name="value" help="The current value">
<param name="value" type="int"/>
</prop>
<prop name="mode" help="The mode">
<param name="mode" type="enum:lv_arc_mode"/>
</prop>
</api>
</widget>

38
xmls/lv_bar.xml Normal file
View File

@ -0,0 +1,38 @@
<!--
Example
<lv_bar mode="symmetrical" angles="100° 200°" bg_angles="30° 150° range="40 100" value="60"/>
-->
<widget>
<api>
<enumdef name="lv_bar_mode" help="the mode">
<enum name="normal" help="normal"/>
<enum name="symmetrical" help="sym"/>
<enum name="range" help="range"/>
</enumdef>
<enumdef name="bar_orientation" help="">
<enum name="auto" help=""/>
<enum name="horizontal" help=""/>
<enum name="vertical" help=""/>
</enumdef>
<prop name="range" help="The range">
<param name ="min" type="int" help="The min range"/>
<param name ="max" type="int" help="The max range"/>
</prop>
<prop name="value" help="The current value">
<param name ="value" type="int" help="The current value"/>
<param name ="animated" type="bool" help="Set the value with animation" optional="true" default="false"/>
</prop>
<prop name="mode" help="The mode">
<param name="mode" type="enum:lv_bar_mode"/>
</prop>
<prop name="orientation" help="Orientation">
<param name="mode" type="enum:lv_bar_orientation"/>
</prop>
</api>
</widget>

Some files were not shown because too many files have changed in this diff Show More