Files
allwpilib/gen/wpilibj_frcnetcomm.py
Tyler Veness d89b7dd412 Move CameraServer and WPILib headers into their own folder
The old headers were moved into folders because doing so avoids polluting
the system include directories.

Folder names were also normalized to lowercase.
2018-07-22 19:40:57 -07:00

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()