add an initial version of WPILib

This is our commit 24ccb7836abaa36b0e913474c818da4b6ae7bc9a which
corresponds with FPGA image v23.

Change-Id: I25b999bbcef39aaea6132562c80360d87780b8c3
diff --git a/aos/externals/allwpilib/hal/include/Log.hpp b/aos/externals/allwpilib/hal/include/Log.hpp
new file mode 100644
index 0000000..eb221e7
--- /dev/null
+++ b/aos/externals/allwpilib/hal/include/Log.hpp
@@ -0,0 +1,103 @@
+#pragma once
+
+#include <sstream>
+#include <iomanip>
+#include <string>
+#include <stdio.h>
+#include <sys/time.h>
+
+inline std::string NowTime();
+
+enum TLogLevel {logNONE, logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4};
+
+class Log
+{
+public:
+    Log();
+    virtual ~Log();
+    std::ostringstream& Get(TLogLevel level = logINFO);
+public:
+    static TLogLevel& ReportingLevel();
+    static std::string ToString(TLogLevel level);
+    static TLogLevel FromString(const std::string& level);
+protected:
+    std::ostringstream os;
+private:
+    Log(const Log&);
+    Log& operator =(const Log&);
+};
+
+inline Log::Log()
+{
+}
+
+inline std::ostringstream& Log::Get(TLogLevel level)
+{
+    os << "- " << NowTime();
+    os << " " << ToString(level) << ": ";
+    os << std::string(level > logDEBUG ? level - logDEBUG : 0, '\t');
+    return os;
+}
+
+inline Log::~Log()
+{
+    os << std::endl;
+    fprintf(stderr, "%s", os.str().c_str());
+    fflush(stderr);
+}
+
+inline TLogLevel& Log::ReportingLevel()
+{
+    static TLogLevel reportingLevel = logDEBUG4;
+    return reportingLevel;
+}
+
+inline std::string Log::ToString(TLogLevel level)
+{
+	static const char* const buffer[] = {"NONE", "ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4"};
+    return buffer[level];
+}
+
+inline TLogLevel Log::FromString(const std::string& level)
+{
+    if (level == "DEBUG4")
+        return logDEBUG4;
+    if (level == "DEBUG3")
+        return logDEBUG3;
+    if (level == "DEBUG2")
+        return logDEBUG2;
+    if (level == "DEBUG1")
+        return logDEBUG1;
+    if (level == "DEBUG")
+        return logDEBUG;
+    if (level == "INFO")
+        return logINFO;
+    if (level == "WARNING")
+        return logWARNING;
+    if (level == "ERROR")
+        return logERROR;
+    if (level == "NONE")
+    	return logNONE;
+    Log().Get(logWARNING) << "Unknown logging level '" << level << "'. Using INFO level as default.";
+    return logINFO;
+}
+
+typedef Log FILELog;
+
+#define FILE_LOG(level) \
+    if (level > FILELog::ReportingLevel()) ; \
+    else Log().Get(level)
+
+inline std::string NowTime()
+{
+    char buffer[11];
+    time_t t;
+    time(&t);
+    tm * r = gmtime(&t);
+    strftime(buffer, sizeof(buffer), "%H:%M:%S", r);
+    struct timeval tv;
+    gettimeofday(&tv, 0);
+    char result[100] = {0};
+    sprintf(result, "%s.%03ld", buffer, (long)tv.tv_usec / 1000);
+    return result;
+}