Files
allwpilib/gen/wpilibj_frcnetcomm.py
Tyler Veness 8958c4eabd Fixed wpilibj_frcnetcomm.py and added invocation to Travis (#1106)
Making Travis run wpilibj_frcnetcomm.py will help avoid bitrot in
FRCNetComm.java in the future. Formatting was also enabled on Python
source files and FRCNetComm.java was added back to the generated files
list.
2018-05-28 00:53:39 -04:00

180 lines
6.1 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
configPath = "."
if os.getcwd().rpartition(os.sep)[2] == "gen":
configPath = ".."
outputName = configPath + \
"/hal/src/main/java/edu/wpi/first/wpilibj/hal/FRCNetComm.java"
# Set initial copyright year and get current year
year = "2016"
currentYear = str(date.today().year)
# Start writing output file
with open(outputName + ".tmp", "w") as temp:
# Write first line of comment
temp.write("/*")
for i in range(0, 76):
temp.write("-")
temp.write("*/\n")
# Write second line of comment
temp.write("/* Copyright (c) ")
if year != currentYear:
temp.write(year)
temp.write("-")
temp.write(currentYear)
temp.write(" FIRST. All Rights Reserved.")
for i in range(0, 24):
temp.write(" ")
if year == currentYear:
for i in range(0, 5):
temp.write(" ")
temp.write("*/\n")
# 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("-")
temp.write("*/\n")
# Write preamble
temp.write("""
package edu.wpi.first.wpilibj.hal;
/**
* JNI wrapper for library <b>FRC_NetworkCommunication</b><br>.
*/
@SuppressWarnings(\"MethodName\")
public class FRCNetComm extends JNIWrapper {
""")
# Read enums from C++ source files
firstEnum = True
files = [
"/ni-libraries/include/FRC_NetworkCommunication/LoadOut.h",
"/hal/src/main/native/include/HAL/UsageReporting.h"
]
for fileName in files:
with open(configPath + fileName, "r") as cppSource:
while True:
# Read until an enum is encountered
line = ""
pos = -1
while "enum" not in line:
line = cppSource.readline()
if line == "":
break
if line == "":
break
# If "{" is on next line, read next line
if "{" not in line:
line = cppSource.readline()
# Write enum to output file as interface
values = []
line = cppSource.readline()
while "}" not in line:
if line == "\n":
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 = cppSource.readline()
# Extract enum name
nameStart = 0
for i, c in enumerate(line):
if c != " " and c != "}":
nameStart = i
break
enumName = line[nameStart:len(line) - 2]
# Write comment for interface name
# Only add newline if not the first enum
if firstEnum == True:
firstEnum = False
else:
temp.write("\n")
temp.write(" /**\n * ")
# Splits camelcase string into words
enumCamel = re.findall(r'[A-Z](?:[a-z]+|[A-Z]*(?=[A-Z]|$))',
enumName)
temp.write(enumCamel[0] + " ")
for i in range(1, len(enumCamel)):
temp.write(enumCamel[i][0].lower() + \
enumCamel[i][1:len(enumCamel[i])] + " ")
temp.write("from " + os.path.basename(fileName) + "\n"
" */\n"
" @SuppressWarnings(\"TypeName\")\n"
" public interface " + enumName + " {\n")
# Write enum values
count = 0
for value in values:
# Pass through empty lines
if value == "":
temp.write("\n")
continue
if "=" not in value:
value = value + " = " + str(count)
count += 1
# Add scoping for values from a different enum
if enumName != "tModuleType" and "kModuleType" in value:
value = value.replace("kModuleType",
"tModuleType.kModuleType")
temp.write(" int " + value[0:len(value)] + ";\n")
# Write end of enum
temp.write(" }\n")
# Write closing brace for file
temp.write("}\n")
# Replace old output file
try:
os.remove(outputName)
except OSError:
pass
os.rename(outputName + ".tmp", outputName)
if __name__ == "__main__":
main()