Vendor dependencies
Let's see how I like this workflow.
This commit is contained in:
parent
34d1830413
commit
9c435dc440
7500 changed files with 1665121 additions and 99 deletions
210
vendor/cxx-build/src/gen/out.rs
vendored
Normal file
210
vendor/cxx-build/src/gen/out.rs
vendored
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
use crate::gen::block::Block;
|
||||
use crate::gen::builtin::Builtins;
|
||||
use crate::gen::include::Includes;
|
||||
use crate::gen::Opt;
|
||||
use crate::syntax::namespace::Namespace;
|
||||
use crate::syntax::Types;
|
||||
use std::cell::RefCell;
|
||||
use std::fmt::{self, Arguments, Write};
|
||||
|
||||
pub(crate) struct OutFile<'a> {
|
||||
pub header: bool,
|
||||
pub opt: &'a Opt,
|
||||
pub types: &'a Types<'a>,
|
||||
pub include: Includes<'a>,
|
||||
pub builtin: Builtins<'a>,
|
||||
content: RefCell<Content<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Content<'a> {
|
||||
bytes: String,
|
||||
namespace: &'a Namespace,
|
||||
blocks: Vec<BlockBoundary<'a>>,
|
||||
section_pending: bool,
|
||||
blocks_pending: usize,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
enum BlockBoundary<'a> {
|
||||
Begin(Block<'a>),
|
||||
End(Block<'a>),
|
||||
}
|
||||
|
||||
impl<'a> OutFile<'a> {
|
||||
pub fn new(header: bool, opt: &'a Opt, types: &'a Types) -> Self {
|
||||
OutFile {
|
||||
header,
|
||||
opt,
|
||||
types,
|
||||
include: Includes::new(),
|
||||
builtin: Builtins::new(),
|
||||
content: RefCell::new(Content::new()),
|
||||
}
|
||||
}
|
||||
|
||||
// Write a blank line if the preceding section had any contents.
|
||||
pub fn next_section(&mut self) {
|
||||
self.content.get_mut().next_section();
|
||||
}
|
||||
|
||||
pub fn begin_block(&mut self, block: Block<'a>) {
|
||||
self.content.get_mut().begin_block(block);
|
||||
}
|
||||
|
||||
pub fn end_block(&mut self, block: Block<'a>) {
|
||||
self.content.get_mut().end_block(block);
|
||||
}
|
||||
|
||||
pub fn set_namespace(&mut self, namespace: &'a Namespace) {
|
||||
self.content.get_mut().set_namespace(namespace);
|
||||
}
|
||||
|
||||
pub fn write_fmt(&self, args: Arguments) {
|
||||
let content = &mut *self.content.borrow_mut();
|
||||
Write::write_fmt(content, args).unwrap();
|
||||
}
|
||||
|
||||
pub fn content(&mut self) -> Vec<u8> {
|
||||
self.flush();
|
||||
let include = &self.include.content.bytes;
|
||||
let builtin = &self.builtin.content.bytes;
|
||||
let content = &self.content.get_mut().bytes;
|
||||
let len = include.len() + builtin.len() + content.len() + 2;
|
||||
let mut out = String::with_capacity(len);
|
||||
out.push_str(include);
|
||||
if !out.is_empty() && !builtin.is_empty() {
|
||||
out.push('\n');
|
||||
}
|
||||
out.push_str(builtin);
|
||||
if !out.is_empty() && !content.is_empty() {
|
||||
out.push('\n');
|
||||
}
|
||||
out.push_str(content);
|
||||
if out.is_empty() {
|
||||
out.push_str("// empty\n");
|
||||
}
|
||||
out.into_bytes()
|
||||
}
|
||||
|
||||
fn flush(&mut self) {
|
||||
self.include.content.flush();
|
||||
self.builtin.content.flush();
|
||||
self.content.get_mut().flush();
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Write for Content<'a> {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
self.write(s);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> PartialEq for Content<'a> {
|
||||
fn eq(&self, _other: &Self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Content<'a> {
|
||||
fn new() -> Self {
|
||||
Content::default()
|
||||
}
|
||||
|
||||
pub fn next_section(&mut self) {
|
||||
self.section_pending = true;
|
||||
}
|
||||
|
||||
pub fn begin_block(&mut self, block: Block<'a>) {
|
||||
self.push_block_boundary(BlockBoundary::Begin(block));
|
||||
}
|
||||
|
||||
pub fn end_block(&mut self, block: Block<'a>) {
|
||||
self.push_block_boundary(BlockBoundary::End(block));
|
||||
}
|
||||
|
||||
pub fn set_namespace(&mut self, namespace: &'a Namespace) {
|
||||
for name in self.namespace.iter().rev() {
|
||||
self.end_block(Block::UserDefinedNamespace(name));
|
||||
}
|
||||
for name in namespace {
|
||||
self.begin_block(Block::UserDefinedNamespace(name));
|
||||
}
|
||||
self.namespace = namespace;
|
||||
}
|
||||
|
||||
pub fn write_fmt(&mut self, args: Arguments) {
|
||||
Write::write_fmt(self, args).unwrap();
|
||||
}
|
||||
|
||||
fn write(&mut self, b: &str) {
|
||||
if !b.is_empty() {
|
||||
if self.blocks_pending > 0 {
|
||||
self.flush_blocks();
|
||||
}
|
||||
if self.section_pending && !self.bytes.is_empty() {
|
||||
self.bytes.push('\n');
|
||||
}
|
||||
self.bytes.push_str(b);
|
||||
self.section_pending = false;
|
||||
self.blocks_pending = 0;
|
||||
}
|
||||
}
|
||||
|
||||
fn push_block_boundary(&mut self, boundary: BlockBoundary<'a>) {
|
||||
if self.blocks_pending > 0 && boundary == self.blocks.last().unwrap().rev() {
|
||||
self.blocks.pop();
|
||||
self.blocks_pending -= 1;
|
||||
} else {
|
||||
self.blocks.push(boundary);
|
||||
self.blocks_pending += 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&mut self) {
|
||||
self.set_namespace(Default::default());
|
||||
if self.blocks_pending > 0 {
|
||||
self.flush_blocks();
|
||||
}
|
||||
}
|
||||
|
||||
fn flush_blocks(&mut self) {
|
||||
self.section_pending = !self.bytes.is_empty();
|
||||
let mut read = self.blocks.len() - self.blocks_pending;
|
||||
let mut write = read;
|
||||
|
||||
while read < self.blocks.len() {
|
||||
match self.blocks[read] {
|
||||
BlockBoundary::Begin(begin_block) => {
|
||||
if self.section_pending {
|
||||
self.bytes.push('\n');
|
||||
self.section_pending = false;
|
||||
}
|
||||
Block::write_begin(begin_block, &mut self.bytes);
|
||||
self.blocks[write] = BlockBoundary::Begin(begin_block);
|
||||
write += 1;
|
||||
}
|
||||
BlockBoundary::End(end_block) => {
|
||||
write = write.checked_sub(1).unwrap();
|
||||
let begin_block = self.blocks[write];
|
||||
assert_eq!(begin_block, BlockBoundary::Begin(end_block));
|
||||
Block::write_end(end_block, &mut self.bytes);
|
||||
self.section_pending = true;
|
||||
}
|
||||
}
|
||||
read += 1;
|
||||
}
|
||||
|
||||
self.blocks.truncate(write);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> BlockBoundary<'a> {
|
||||
fn rev(self) -> BlockBoundary<'a> {
|
||||
match self {
|
||||
BlockBoundary::Begin(block) => BlockBoundary::End(block),
|
||||
BlockBoundary::End(block) => BlockBoundary::Begin(block),
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue