2 * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include <libxml/parser.h>
21 #include <libxml/tree.h>
24 #include "halcc-object.h"
25 #include "halcc-parser.h"
26 #include "halcc-util.h"
28 #define HALCC_DESERIALIZER_VERSION_MAJOR 1
29 #define HALCC_DESERIALIZER_VERSION_MINOR 0
31 #define __xmlchar__ __attribute__((__cleanup__(free_xmlstr)))
33 static void free_xmlstr(unsigned char **str)
38 static int parse_interface(xmlNode *node, halcc_interface *interface)
43 if (!xmlStrEqual(node->name, "interface")) {
44 printf("Invalid interface node, %s\n", node->name);
48 for (xmlNode *child = node->children; child; child = child->next) {
49 if (xmlStrEqual(child->name, "name")) {
50 __xmlchar__ xmlChar *name = xmlNodeGetContent(child);
51 halcc_interface_set_name(interface, name);
52 } else if (xmlStrEqual(child->name, "instance")) {
53 __xmlchar__ xmlChar *instance = xmlNodeGetContent(child);
54 halcc_interface_set_instance_id(interface, (char *) instance);
61 static int parse_hal(xmlNode *node, halcc_hal *hal)
68 if (!xmlStrEqual(node->name, "hal")) {
69 printf("Invalid hal node, %s\n", node->name);
73 for (xmlNode *child = node->children; child; child = child->next) {
74 if (xmlStrEqual(child->name, "name")) {
75 __xmlchar__ xmlChar *name = xmlNodeGetContent(child);
77 ret = halcc_hal_set_name(hal, name);
79 printf("Failed to halcc_hal_set_name(), name=%s, ret=%d\n", name, ret);
80 } else if (xmlStrEqual(child->name, "version")) {
81 int major, min_minor, max_minor;
83 __xmlchar__ xmlChar *version = xmlNodeGetContent(child);
85 scanned = sscanf(version, "%d.%d-%d", &major, &min_minor, &max_minor);
87 case 2: // 3.5 is equal to 3.5-5
88 max_minor = min_minor;
89 ret = halcc_hal_set_version(hal, major, min_minor, max_minor);
92 ret = halcc_hal_set_version(hal, major, min_minor, max_minor);
100 printf("Failed to halcc_hal_set_version(), ret=%d\n", ret);
101 } else if (xmlStrEqual(child->name, "transport")) {
102 __xmlchar__ xmlChar *transport = xmlNodeGetContent(child);
104 if (xmlStrEqual(transport, "passthrough"))
105 ret = halcc_hal_set_transport(hal, HALCC_TRANSPORT_PASSTHROUGH);
106 else if (xmlStrEqual(transport, "IPC"))
107 ret = halcc_hal_set_transport(hal, HALCC_TRANSPORT_IPC);
112 printf("Failed to halcc_hal_set_transport(), %s, ret=%d\n", transport, ret);
113 } else if (xmlStrEqual(child->name, "interface")) {
114 halcc_interface *iface;
116 ret = halcc_interface_new(&iface);
118 printf("Failed to halcc_interface_new(), ret=%d\n", ret);
122 ret = parse_interface(child, iface);
124 printf("Failed to parse_interface(), ret=%d\n", ret);
125 halcc_interface_free(iface);
129 halcc_hal_add_interface(hal, iface);
131 } else if (xmlStrEqual(child->name, "dependency")) {
132 for (xmlNode *grand_child = child->children; grand_child; grand_child = grand_child->next) {
135 if (!xmlStrEqual(grand_child->name, "hal"))
138 ret = halcc_hal_new(&h);
142 ret = parse_hal(grand_child, h);
149 halcc_hal_add_dependency(hal, h);
158 static int parse_manifest(xmlNode *node, halcc_manifest *manifest)
169 if (!xmlStrEqual(node->name, "manifest")) {
170 printf("Invalid manifest node, %s\n", node->name);
175 prop = xmlGetProp(node, "version");
177 printf("Failed to xmlGetProp() \"version\"\n");
181 ret = sscanf(prop, "%d.%d", &major, &minor);
185 printf("Failed to scan version, ret=%d\n", ret);
189 if (major != HALCC_DESERIALIZER_VERSION_MAJOR || minor != HALCC_DESERIALIZER_VERSION_MINOR) {
190 printf("Manifest scheme doesn't match. Requires manifest version %d.%d\n",
191 HALCC_DESERIALIZER_VERSION_MAJOR, HALCC_DESERIALIZER_VERSION_MINOR);
195 ret = halcc_manifest_set_version(manifest, major, minor);
197 printf("Failed to halcc_manifest_set_version(), ret=%d\n", ret);
202 prop = xmlGetProp(node, "type");
204 printf("Failed to xmlGetProp() \"type\"\n");
208 if (xmlStrEqual(prop, "platform")) {
209 ret = halcc_manifest_set_type(manifest, HALCC_MANIFEST_TYPE_HAL_API);
211 printf("Failed to halcc_manifest_set_type() HALCC_MANIFEST_TYPE_HAL_API, ret=%d\n", ret);
212 } else if (xmlStrEqual(prop, "device")) {
213 ret = halcc_manifest_set_type(manifest, HALCC_MANIFEST_TYPE_HAL_BACKEND);
215 printf("Failed to halcc_manifest_set_type() HALCC_MANIFEST_TYPE_HAL_BACKEND, ret=%d\n", ret);
217 printf("Invalid type property=%s\n", prop);
227 prop = xmlGetProp(node, "level");
229 printf("Failed to xmlGetProp() \"level\"\n");
233 ret = sscanf(prop, "%d", &level);
237 printf("Failed to scan manifest level\n");
241 ret = halcc_manifest_set_level(manifest, level);
243 printf("Failed to halcc_manifest_set_level(), ret=%d\n", ret);
247 for (xmlNode *child = node->children; child; child = child->next) {
250 if (!xmlStrEqual(child->name, "hal"))
253 ret = halcc_hal_new(&h);
255 printf("Failed to halcc_hal_new(), ret=%d\n", ret);
259 ret = parse_hal(child, h);
261 printf("Failed to parse_hal(), ret=%d\n", ret);
267 halcc_manifest_add_hal(manifest, h);
275 static int parse_xml_doc(xmlDoc *doc, halcc_manifest *manifest)
277 xmlNode *root = NULL;
280 if (!doc || !manifest)
283 root = xmlDocGetRootElement(doc);
285 printf("Failed to get root element\n");
289 ret = parse_manifest(root, manifest);
291 printf("Failed to parse_manifest(), ret=%d\n", ret);
298 int halcc_parse_fd(int fd, halcc_manifest *manifest)
304 printf("Invalid manifest\n");
308 doc = xmlReadFd(fd, NULL, NULL, 0);
310 printf("Failed to read doc %d\n", fd);
314 ret = parse_xml_doc(doc, manifest);
321 int halcc_parse_path(const char *filepath, halcc_manifest *manifest)
326 if (!filepath || !manifest) {
327 printf("Invalid filepath or manifest\n");
331 doc = xmlReadFile(filepath, NULL, 0);
333 printf("Failed to read doc %s\n", filepath);
337 ret = parse_xml_doc(doc, manifest);
344 int halcc_parse_string(const char *string, int len, halcc_manifest *manifest)
349 if (!string || !manifest) {
350 printf("Invalid string or manifest\n");
354 doc = xmlReadMemory(string, len, NULL, NULL, 0);
356 printf("Failed to read xml string\n");
360 ret = parse_xml_doc(doc, manifest);