mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
The old headers were moved into folders because doing so avoids polluting the system include directories. Folder names were also normalized to lowercase.
185 lines
6.6 KiB
Python
Executable File
185 lines
6.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# This script generates the network communication interface for wpilibj.
|
|
#
|
|
# This script takes no arguments and should be invoked from either the gen
|
|
# directory or the root directory of the project.
|
|
|
|
from datetime import date
|
|
import os
|
|
import re
|
|
import subprocess
|
|
|
|
|
|
# Check that the current directory is part of a Git repository
|
|
def in_git_repo(directory):
|
|
return subprocess.run(["git", "rev-parse"]).returncode == 0
|
|
|
|
|
|
def main():
|
|
if not in_git_repo("."):
|
|
print("Error: not invoked within a Git repository", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
# Handle running in either the root or gen directories
|
|
config_path = "."
|
|
if os.getcwd().rpartition(os.sep)[2] == "gen":
|
|
config_path = ".."
|
|
|
|
output_name = config_path + \
|
|
"/hal/src/generated/java/edu/wpi/first/wpilibj/hal/FRCNetComm.java"
|
|
|
|
# Set initial copyright year and get current year
|
|
year = "2016"
|
|
current_year = str(date.today().year)
|
|
|
|
# Start writing output file
|
|
with open(output_name + ".tmp", "w") as temp:
|
|
# Write first line of comment
|
|
temp.write("/*")
|
|
for i in range(0, 76):
|
|
temp.write("-")
|
|
print("*/", file=temp)
|
|
|
|
# Write second line of comment
|
|
temp.write("/* Copyright (c) ")
|
|
if year != current_year:
|
|
temp.write(year)
|
|
temp.write("-")
|
|
temp.write(current_year)
|
|
temp.write(" FIRST. All Rights Reserved.")
|
|
for i in range(0, 24):
|
|
temp.write(" ")
|
|
if year == current_year:
|
|
for i in range(0, 5):
|
|
temp.write(" ")
|
|
print("*/", file=temp)
|
|
|
|
# Write rest of lines of comment
|
|
temp.write("""\
|
|
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
|
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
|
/* the project. */
|
|
/*""")
|
|
for i in range(0, 76):
|
|
temp.write("-")
|
|
print("*/", file=temp)
|
|
|
|
# Write preamble
|
|
temp.write("""
|
|
// Autogenerated by wpilibj_frcnetcomm.py. Do not manually edit this file.
|
|
|
|
package edu.wpi.first.wpilibj.hal;
|
|
|
|
/**
|
|
* JNI wrapper for library <b>FRC_NetworkCommunication</b><br>.
|
|
*/
|
|
@SuppressWarnings({\"MethodName\", \"LineLength\"})
|
|
public class FRCNetComm extends JNIWrapper {
|
|
""")
|
|
|
|
# Read enums from C++ source files
|
|
first_enum = True
|
|
files = [
|
|
"/ni-libraries/include/FRC_NetworkCommunication/LoadOut.h",
|
|
"/hal/src/main/native/include/hal/UsageReporting.h"
|
|
]
|
|
for file_name in files:
|
|
with open(config_path + file_name, "r") as cpp_source:
|
|
while True:
|
|
# Read until an enum is encountered
|
|
line = ""
|
|
pos = -1
|
|
while "enum" not in line:
|
|
line = cpp_source.readline()
|
|
if line == "":
|
|
break
|
|
|
|
if line == "":
|
|
break
|
|
|
|
# If "{" is on next line, read next line
|
|
if "{" not in line:
|
|
line = cpp_source.readline()
|
|
|
|
# Write enum to output file as interface
|
|
values = []
|
|
line = cpp_source.readline()
|
|
while "}" not in line:
|
|
if line == os.linesep:
|
|
values.append("")
|
|
elif line[0] != "#":
|
|
try:
|
|
values.append(
|
|
re.search("[^,]+", line.strip()).group())
|
|
except AttributeError:
|
|
# Ignore lines that don't match value regex
|
|
pass
|
|
line = cpp_source.readline()
|
|
|
|
# Extract enum name
|
|
name_start = 0
|
|
for i, c in enumerate(line):
|
|
if c != " " and c != "}":
|
|
name_start = i
|
|
break
|
|
enum_name = line[name_start:len(line) - 2]
|
|
|
|
# Write comment for interface name
|
|
# Only add newline if not the first enum
|
|
if first_enum == True:
|
|
first_enum = False
|
|
else:
|
|
temp.write(os.linesep)
|
|
temp.write(" /**" + os.linesep + " * ")
|
|
|
|
# Splits camelcase string into words
|
|
enum_camel = re.findall(
|
|
r'[A-Z](?:[a-z]+|[A-Z]*(?=[A-Z]|$))', enum_name)
|
|
temp.write(enum_camel[0] + " ")
|
|
for i in range(1, len(enum_camel)):
|
|
temp.write(enum_camel[i][0].lower() + \
|
|
enum_camel[i][1:len(enum_camel[i])] + " ")
|
|
temp.write(
|
|
"from " + os.path.basename(file_name) + os.linesep +
|
|
" */" + os.linesep +
|
|
" @SuppressWarnings({\"TypeName\", \"PMD.ConstantsInInterface\"})" + os.linesep + \
|
|
" public static final class " + enum_name + " {" + os.linesep + \
|
|
" private " + enum_name + "() {" + os.linesep + " }" + os.linesep + os.linesep)
|
|
|
|
# Write enum values
|
|
count = 0
|
|
for value in values:
|
|
# Pass through empty lines
|
|
if value == "":
|
|
temp.write(os.linesep)
|
|
continue
|
|
|
|
if "=" not in value:
|
|
value = value + " = " + str(count)
|
|
count += 1
|
|
|
|
# Add scoping for values from a different enum
|
|
if enum_name != "tModuleType" and "kModuleType" in value:
|
|
value = value.replace("kModuleType",
|
|
"tModuleType.kModuleType")
|
|
temp.write(" public static final int " +
|
|
value[0:len(value)] + ";" + os.linesep)
|
|
|
|
# Write end of enum
|
|
print(" }", file=temp)
|
|
|
|
# Write closing brace for file
|
|
print("}", file=temp)
|
|
|
|
# Replace old output file
|
|
try:
|
|
os.remove(output_name)
|
|
except OSError:
|
|
pass
|
|
os.rename(output_name + ".tmp", output_name)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|