Adds new build system to repo (#1)

This commit is contained in:
Thad House
2017-07-28 07:29:49 -07:00
committed by Peter Johnson
parent 4f5b5b1377
commit 1243cf04ea
87 changed files with 1278 additions and 39 deletions

View File

@@ -0,0 +1,152 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2015. All Rights Reserved. */
/* 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. */
/*----------------------------------------------------------------------------*/
/* ====================================================================
* Copyright (c) 1995-1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group and was originally based
* on public domain software written at the National Center for
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
#include "support/Base64.h"
namespace wpi {
// aaaack but it's fast and const should make it shared text page.
static const unsigned char pr2six[256] =
{
// ASCII table
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
};
std::size_t Base64Decode(llvm::StringRef encoded, std::string* plain) {
const unsigned char *end = encoded.bytes_begin();
while (pr2six[*end] <= 63 && end != encoded.bytes_end()) ++end;
std::size_t nprbytes = end - encoded.bytes_begin();
plain->clear();
if (nprbytes == 0)
return 0;
plain->reserve(((nprbytes + 3) / 4) * 3);
const unsigned char *cur = encoded.bytes_begin();
while (nprbytes > 4) {
(*plain) += (pr2six[cur[0]] << 2 | pr2six[cur[1]] >> 4);
(*plain) += (pr2six[cur[1]] << 4 | pr2six[cur[2]] >> 2);
(*plain) += (pr2six[cur[2]] << 6 | pr2six[cur[3]]);
cur += 4;
nprbytes -= 4;
}
// Note: (nprbytes == 1) would be an error, so just ignore that case
if (nprbytes > 1) (*plain) += (pr2six[cur[0]] << 2 | pr2six[cur[1]] >> 4);
if (nprbytes > 2) (*plain) += (pr2six[cur[1]] << 4 | pr2six[cur[2]] >> 2);
if (nprbytes > 3) (*plain) += (pr2six[cur[2]] << 6 | pr2six[cur[3]]);
return (end - encoded.bytes_begin()) + ((4 - nprbytes) & 3);
}
static const char basis_64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
void Base64Encode(llvm::StringRef plain, std::string* encoded) {
encoded->clear();
if (plain.empty())
return;
std::size_t len = plain.size();
encoded->reserve(((len + 2) / 3 * 4) + 1);
std::size_t i;
for (i = 0; (i + 2) < len; i += 3) {
(*encoded) += basis_64[(plain[i] >> 2) & 0x3F];
(*encoded) +=
basis_64[((plain[i] & 0x3) << 4) | ((int)(plain[i + 1] & 0xF0) >> 4)];
(*encoded) += basis_64[((plain[i + 1] & 0xF) << 2) |
((int)(plain[i + 2] & 0xC0) >> 6)];
(*encoded) += basis_64[plain[i + 2] & 0x3F];
}
if (i < len) {
(*encoded) += basis_64[(plain[i] >> 2) & 0x3F];
if (i == (len - 1)) {
(*encoded) += basis_64[((plain[i] & 0x3) << 4)];
(*encoded) += '=';
} else {
(*encoded) +=
basis_64[((plain[i] & 0x3) << 4) | ((int)(plain[i + 1] & 0xF0) >> 4)];
(*encoded) += basis_64[((plain[i + 1] & 0xF) << 2)];
}
(*encoded) += '=';
}
}
} // namespace wpi

View File

@@ -0,0 +1,120 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2015. All Rights Reserved. */
/* 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. */
/*----------------------------------------------------------------------------*/
#include "support/leb128.h"
#include "support/raw_istream.h"
namespace wpi {
/**
* Get size of unsigned LEB128 data
* @val: value
*
* Determine the number of bytes required to encode an unsigned LEB128 datum.
* The algorithm is taken from Appendix C of the DWARF 3 spec. For information
* on the encodings refer to section "7.6 - Variable Length Data". Return
* the number of bytes required.
*/
std::size_t SizeUleb128(unsigned long val) {
std::size_t count = 0;
do {
val >>= 7;
++count;
} while (val != 0);
return count;
}
/**
* Write unsigned LEB128 data
* @addr: the address where the ULEB128 data is to be stored
* @val: value to be stored
*
* Encode an unsigned LEB128 encoded datum. The algorithm is taken
* from Appendix C of the DWARF 3 spec. For information on the
* encodings refer to section "7.6 - Variable Length Data". Return
* the number of bytes written.
*/
std::size_t WriteUleb128(llvm::SmallVectorImpl<char>& dest, unsigned long val) {
std::size_t count = 0;
do {
unsigned char byte = val & 0x7f;
val >>= 7;
if (val != 0)
byte |= 0x80; // mark this byte to show that more bytes will follow
dest.push_back(byte);
count++;
} while (val != 0);
return count;
}
/**
* Read unsigned LEB128 data
* @addr: the address where the ULEB128 data is stored
* @ret: address to store the result
*
* Decode an unsigned LEB128 encoded datum. The algorithm is taken
* from Appendix C of the DWARF 3 spec. For information on the
* encodings refer to section "7.6 - Variable Length Data". Return
* the number of bytes read.
*/
std::size_t ReadUleb128(const char* addr, unsigned long* ret) {
unsigned long result = 0;
int shift = 0;
std::size_t count = 0;
while (1) {
unsigned char byte = *reinterpret_cast<const unsigned char*>(addr);
addr++;
count++;
result |= (byte & 0x7f) << shift;
shift += 7;
if (!(byte & 0x80)) break;
}
*ret = result;
return count;
}
/**
* Read unsigned LEB128 data from a stream
* @is: the input stream where the ULEB128 data is to be read from
* @ret: address to store the result
*
* Decode an unsigned LEB128 encoded datum. The algorithm is taken
* from Appendix C of the DWARF 3 spec. For information on the
* encodings refer to section "7.6 - Variable Length Data". Return
* false on stream error, true on success.
*/
bool ReadUleb128(raw_istream& is, unsigned long* ret) {
unsigned long result = 0;
int shift = 0;
while (1) {
unsigned char byte;
is.read((char*)&byte, 1);
if (is.has_error()) return false;
result |= (byte & 0x7f) << shift;
shift += 7;
if (!(byte & 0x80)) break;
}
*ret = result;
return true;
}
} // namespace wpi

View File

@@ -0,0 +1,79 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2015. All Rights Reserved. */
/* 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. */
/*----------------------------------------------------------------------------*/
#include "support/raw_istream.h"
#include <cstdlib>
#include <cstring>
#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h>
#endif
using namespace wpi;
void raw_mem_istream::close() {}
std::size_t raw_mem_istream::in_avail() const { return m_left; }
void raw_mem_istream::read_impl(void* data, std::size_t len) {
if (len > m_left) {
error_detected();
return;
}
std::memcpy(data, m_cur, len);
m_cur += len;
m_left -= len;
}
raw_fd_istream::raw_fd_istream(int fd, bool shouldClose, std::size_t bufSize)
: m_bufSize(bufSize), m_fd(fd), m_shouldClose(shouldClose) {
m_cur = m_end = m_buf = static_cast<char*>(std::malloc(bufSize));
}
raw_fd_istream::~raw_fd_istream() {
if (m_shouldClose) close();
std::free(m_buf);
}
void raw_fd_istream::close() {
if (m_fd >= 0) {
::close(m_fd);
m_fd = -1;
}
}
std::size_t raw_fd_istream::in_avail() const { return m_end - m_cur; }
void raw_fd_istream::read_impl(void* data, std::size_t len) {
std::size_t left = m_end - m_cur;
if (left < len) {
// not enough data
if (m_cur == m_end) {
#ifdef _WIN32
int count = ::_read(m_fd, m_buf, m_bufSize);
#else
ssize_t count = ::read(m_fd, m_buf, m_bufSize);
#endif
if (count < 0) {
error_detected();
return;
}
m_cur = m_buf;
m_end = m_buf + count;
return read_impl(data, len);
}
std::memcpy(data, m_cur, left);
return read_impl(static_cast<char*>(data) + left, len - left);
}
std::memcpy(data, m_cur, len);
m_cur += len;
}

View File

@@ -0,0 +1,31 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2015. All Rights Reserved. */
/* 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. */
/*----------------------------------------------------------------------------*/
#include "support/raw_socket_istream.h"
#include "tcpsockets/NetworkStream.h"
using namespace wpi;
void raw_socket_istream::read_impl(void* data, std::size_t len) {
char* cdata = static_cast<char*>(data);
std::size_t pos = 0;
while (pos < len) {
NetworkStream::Error err;
std::size_t count =
m_stream.receive(&cdata[pos], len - pos, &err, m_timeout);
if (count == 0) {
error_detected();
return;
}
pos += count;
}
}
void raw_socket_istream::close() { m_stream.close(); }
std::size_t raw_socket_istream::in_avail() const { return 0; }

View File

@@ -0,0 +1,39 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2015. All Rights Reserved. */
/* 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. */
/*----------------------------------------------------------------------------*/
#include "support/raw_socket_ostream.h"
#include "tcpsockets/NetworkStream.h"
using namespace wpi;
raw_socket_ostream::~raw_socket_ostream() {
flush();
if (m_shouldClose) close();
}
void raw_socket_ostream::write_impl(const char* data, std::size_t len) {
std::size_t pos = 0;
while (pos < len) {
NetworkStream::Error err;
std::size_t count =
m_stream.send(&data[pos], len - pos, &err);
if (count == 0) {
error_detected();
return;
}
pos += count;
}
}
uint64_t raw_socket_ostream::current_pos() const { return 0; }
void raw_socket_ostream::close() {
if (!m_shouldClose) return;
flush();
m_stream.close();
}

View File

@@ -0,0 +1,89 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2015. All Rights Reserved. */
/* 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. */
/*----------------------------------------------------------------------------*/
#include "support/timestamp.h"
#ifdef _WIN32
#include <cassert>
#include <exception>
#include <windows.h>
#else
#include <chrono>
#endif
// offset in microseconds
static unsigned long long zerotime() {
#ifdef _WIN32
FILETIME ft;
unsigned long long tmpres = 0;
// 100-nanosecond intervals since January 1, 1601 (UTC)
// which means 0.1 us
GetSystemTimeAsFileTime(&ft);
tmpres |= ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
// January 1st, 1970 - January 1st, 1601 UTC ~ 369 years
// or 116444736000000000 us
static const unsigned long long deltaepoch = 116444736000000000ull;
tmpres -= deltaepoch;
return tmpres;
#else
// 100-ns intervals
using namespace std::chrono;
return duration_cast<nanoseconds>(
high_resolution_clock::now().time_since_epoch()).count() / 100u;
#endif
}
static unsigned long long timestamp() {
#ifdef _WIN32
LARGE_INTEGER li;
QueryPerformanceCounter(&li);
// there is an imprecision with the initial value,
// but what matters is that timestamps are monotonic and consistent
return static_cast<unsigned long long>(li.QuadPart);
#else
// 100-ns intervals
using namespace std::chrono;
return duration_cast<nanoseconds>(
steady_clock::now().time_since_epoch()).count() / 100u;
#endif
}
#ifdef _WIN32
static unsigned long long update_frequency() {
LARGE_INTEGER li;
if (!QueryPerformanceFrequency(&li) || !li.QuadPart) {
// log something
std::terminate();
}
return static_cast<unsigned long long>(li.QuadPart);
}
#endif
static const unsigned long long zerotime_val = zerotime();
static const unsigned long long offset_val = timestamp();
#ifdef _WIN32
static const unsigned long long frequency_val = update_frequency();
#endif
unsigned long long wpi::Now() {
#ifdef _WIN32
assert(offset_val > 0u);
assert(frequency_val > 0u);
unsigned long long delta = timestamp() - offset_val;
// because the frequency is in update per seconds, we have to multiply the
// delta by 10,000,000
unsigned long long delta_in_us = delta * 10000000ull / frequency_val;
return delta_in_us + zerotime_val;
#else
return zerotime_val + timestamp() - offset_val;
#endif
}
unsigned long long WPI_Now() {
return wpi::Now();
}