mirror of
https://github.com/open62541/open62541.git
synced 2025-06-03 04:00:21 +00:00
refactor(tools): Simplify code generation in nodeset injector
This commit is contained in:
parent
eedd7e8998
commit
2f80c19b85
@ -1273,8 +1273,6 @@ add_custom_target(open62541-code-generation DEPENDS open62541-generator-types
|
||||
open62541-generator-namespace)
|
||||
|
||||
# Generate Nodeset injector source files
|
||||
# TODO: Forward UA_INFORMATION_MODEL_AUTOLOAD to generate_nodesetinjector.py, so
|
||||
# it knows which nodesets to load
|
||||
if(UA_ENABLE_NODESET_INJECTOR)
|
||||
message(STATUS "Nodesetinjector feature enabled")
|
||||
set(UA_NODESETINJECTOR_SOURCE_FILES "") # List is appended from within ua_generate_nodeset
|
||||
|
@ -10,8 +10,12 @@ import argparse
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('outfile', help='outfile w/o extension')
|
||||
parser.add_argument('nodesets', nargs='+', help='List of Nodesets')
|
||||
args = parser.parse_args()
|
||||
|
||||
# Normalize to lower case letters
|
||||
nodesets = [ns.lower().replace('-', '_') for ns in args.nodesets]
|
||||
|
||||
fh = open(args.outfile + ".h", "w", encoding='utf8')
|
||||
fc = open(args.outfile + ".c", "w", encoding='utf8')
|
||||
|
||||
@ -52,14 +56,48 @@ printc('''
|
||||
* Any manual changes will be overwritten. */
|
||||
|
||||
#include "nodesetinjector.h"
|
||||
//<
|
||||
''')
|
||||
|
||||
# Includes for each nodeset
|
||||
for ns in nodesets:
|
||||
printc(f'#include <open62541/namespace_{ns}_generated.h>')
|
||||
|
||||
# Special case: PADIM requires IRDI beforehand
|
||||
if 'padim' in nodesets:
|
||||
printc('#include <open62541/namespace_irdi_generated.h>')
|
||||
|
||||
printc('''
|
||||
UA_StatusCode UA_Server_injectNodesets(UA_Server *server) {
|
||||
UA_StatusCode retval = UA_STATUSCODE_GOOD;
|
||||
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Attaching the AUTOLOAD Nodesets to the server!");
|
||||
//>
|
||||
UA_StatusCode retval = UA_STATUSCODE_GOOD;
|
||||
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Attaching the AUTOLOAD Nodesets to the server!");
|
||||
''')
|
||||
|
||||
return retval;
|
||||
# Function calls for each nodeset
|
||||
for ns in nodesets:
|
||||
# Special handling: Insert IRDI before PADIM
|
||||
if ns == 'padim':
|
||||
printc('''
|
||||
/* namespace_irdi_generated */
|
||||
retval |= namespace_irdi_generated(server);
|
||||
if(retval != UA_STATUSCODE_GOOD) {
|
||||
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Adding the namespace_irdi_generated failed. Please check previous error output.");
|
||||
return retval;
|
||||
}
|
||||
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "The namespace_irdi_generated successfully added.");
|
||||
''')
|
||||
|
||||
printc(f'''
|
||||
/* namespace_{ns}_generated */
|
||||
retval |= namespace_{ns}_generated(server);
|
||||
if(retval != UA_STATUSCODE_GOOD) {{
|
||||
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Adding the namespace_{ns}_generated failed. Please check previous error output.");
|
||||
return retval;
|
||||
}}
|
||||
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "The namespace_{ns}_generated successfully added.");
|
||||
''')
|
||||
|
||||
printc('''
|
||||
return retval;
|
||||
}
|
||||
''')
|
||||
|
||||
|
@ -1,147 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
### This Source Code Form is subject to the terms of the Mozilla Public
|
||||
### License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
### file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
### Copyright 2023 (c) Fraunhofer IOSB (Author: Noel Graf)
|
||||
|
||||
import argparse
|
||||
import re
|
||||
import os
|
||||
import platform
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('outfile', help='outfile w/o extension')
|
||||
parser.add_argument('namespace', help='namespace')
|
||||
args = parser.parse_args()
|
||||
|
||||
include_line_counter = 0
|
||||
code_line_counter = 0
|
||||
existing_namespaces = []
|
||||
data = []
|
||||
|
||||
|
||||
def is_unix():
|
||||
try:
|
||||
# Check if the os.uname() function is available
|
||||
os.uname()
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
|
||||
def windows_exec():
|
||||
import msvcrt
|
||||
|
||||
global include_line_counter
|
||||
global code_line_counter
|
||||
global existing_namespaces
|
||||
global data
|
||||
|
||||
# Open the file in read-write mode
|
||||
with open(args.outfile + ".c", "r+", encoding='utf8') as file:
|
||||
# Lock the file
|
||||
msvcrt.locking(file.fileno(), msvcrt.LK_LOCK, 1)
|
||||
|
||||
# Write to the file
|
||||
write_code_generation(file)
|
||||
|
||||
# Unlock the file
|
||||
msvcrt.locking(file.fileno(), msvcrt.LK_UNLCK, 1)
|
||||
|
||||
|
||||
def unix_exec():
|
||||
import fcntl
|
||||
|
||||
global include_line_counter
|
||||
global code_line_counter
|
||||
global existing_namespaces
|
||||
global data
|
||||
|
||||
with open(args.outfile + ".c", "r+", encoding='utf8') as file:
|
||||
# Acquire a lock on the file
|
||||
fcntl.flock(file, fcntl.LOCK_EX)
|
||||
|
||||
# Write to the file
|
||||
write_code_generation(file)
|
||||
|
||||
# Release the lock on the file
|
||||
fcntl.flock(file, fcntl.LOCK_UN)
|
||||
|
||||
|
||||
def print_include(string):
|
||||
data[include_line_counter] = string
|
||||
|
||||
|
||||
def print_function_call(string):
|
||||
data[code_line_counter] = string
|
||||
|
||||
|
||||
def generate_code():
|
||||
#########################
|
||||
# Print the header file #
|
||||
#########################
|
||||
|
||||
print_include('''
|
||||
#include <open62541/{namespace}.h>
|
||||
//<
|
||||
'''.format(namespace=args.namespace))
|
||||
|
||||
#########################
|
||||
# Print the source file #
|
||||
#########################
|
||||
|
||||
print_function_call('''
|
||||
/* {namespace} */
|
||||
retval |= {namespace}(server);
|
||||
if(retval != UA_STATUSCODE_GOOD) {{
|
||||
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Adding the {namespace} failed. Please check previous error output.");
|
||||
return retval;
|
||||
}}
|
||||
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "The {namespace} successfully added.");
|
||||
//>
|
||||
'''.format(namespace=args.namespace))
|
||||
|
||||
|
||||
def write_code_generation(file):
|
||||
global include_line_counter
|
||||
global code_line_counter
|
||||
global existing_namespaces
|
||||
global data
|
||||
|
||||
# Write to the file
|
||||
lines = file.readlines()
|
||||
line_counter = 0
|
||||
# List which contains the existing namespaces
|
||||
existing_namespaces = []
|
||||
for line in lines:
|
||||
namespaces = re.findall(r"namespace_.*_generated\(.*\)", line)
|
||||
if namespaces:
|
||||
namespaces = namespaces[0].split("(")[0]
|
||||
existing_namespaces.append(namespaces)
|
||||
if re.search("//<", line):
|
||||
include_line_counter = line_counter
|
||||
if re.search("//>", line):
|
||||
code_line_counter = line_counter
|
||||
line_counter += 1
|
||||
|
||||
if args.namespace not in existing_namespaces:
|
||||
# Set the file descriptor to the beginning of the file
|
||||
file.seek(0)
|
||||
# read a list of lines into data
|
||||
data = file.readlines()
|
||||
generate_code()
|
||||
# Set the file descriptor to the beginning of the file and delete content
|
||||
file.seek(0)
|
||||
file.truncate(0)
|
||||
file.writelines(data)
|
||||
|
||||
|
||||
if platform.system == "Linux":
|
||||
unix_exec()
|
||||
else:
|
||||
if is_unix():
|
||||
unix_exec()
|
||||
else:
|
||||
windows_exec()
|
Loading…
Reference in New Issue
Block a user