From 9bfd637a1969677a1683a964c271e33815d329fd Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sat, 17 Oct 2015 00:36:29 -0700 Subject: [PATCH 01/12] Core SConscript --- lib/core/SConscript | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 lib/core/SConscript diff --git a/lib/core/SConscript b/lib/core/SConscript new file mode 100644 index 0000000..e69de29 From af30c9e5972fc3b1ba01e7fcfd2e030390520a24 Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sat, 17 Oct 2015 00:37:17 -0700 Subject: [PATCH 02/12] Add String.hh --- lib/core/include/core/String.hh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 lib/core/include/core/String.hh diff --git a/lib/core/include/core/String.hh b/lib/core/include/core/String.hh new file mode 100644 index 0000000..0206db5 --- /dev/null +++ b/lib/core/include/core/String.hh @@ -0,0 +1,18 @@ +/* String.hh + * vim: set tw=80: + * Eryn Wells + */ +/** + * Strings are fun. + */ + +#include + + +namespace erw { +namespace core { + +typedef std::string String; + +} /* namespace core */ +} /* namespace erw */ From 134f2aa3fb1b46ccc38f4b9694953c4d38a305ab Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sat, 17 Oct 2015 09:16:26 -0700 Subject: [PATCH 03/12] InFile class --- lib/core/SConscript | 4 + lib/core/include/core/File.hh | 105 +++++++++++++++++++++++++ lib/core/src/File.cc | 140 ++++++++++++++++++++++++++++++++++ 3 files changed, 249 insertions(+) create mode 100644 lib/core/include/core/File.hh create mode 100644 lib/core/src/File.cc diff --git a/lib/core/SConscript b/lib/core/SConscript index e69de29..024769d 100644 --- a/lib/core/SConscript +++ b/lib/core/SConscript @@ -0,0 +1,4 @@ +# SConscript +# Eryn Wells + +Library('erw', ['src/File.cc']) diff --git a/lib/core/include/core/File.hh b/lib/core/include/core/File.hh new file mode 100644 index 0000000..5f84641 --- /dev/null +++ b/lib/core/include/core/File.hh @@ -0,0 +1,105 @@ +/* File.hh + * vim: set tw=80: + * Eryn Wells + */ +/** + * File interface. + */ + +#include +#include +#include + +#include "String.hh" + + +namespace erw { +namespace core { + +struct File +{ + enum class SeekFrom { + /** Seek from the beginning of the file. */ + Begin, + /** Seek from the current file offset. */ + Here, + /** Seek from the end of the file. */ + End, + }; + + typedef std::bitset<3> Mode; + + static constexpr Mode In = Mode(1); + static constexpr Mode Out = Mode(2); + static constexpr Mode Binary = Mode(4); + + /** Destructor. */ + virtual ~File(); + + /** Seek to an absolute position in the file. */ + virtual File& seek(size_t pos) = 0; + + /** + * Seek to an `offset` from the given anchor point in the file. + * @see SeekFrom + */ + virtual File& seek(ssize_t offset, SeekFrom from) = 0; + +protected: + /** Convert a File::Mode to an iostream openmode bitset. */ + virtual std::ios_base::openmode modeToIOSMode(Mode mode); +}; + + +/** File handle for reading. */ +struct InFile + : public File +{ + /** Open a file at `path` for reading. */ + InFile(const String& path, File::Mode mode); + + /** Deleted copy constructor. File handles cannot be copied. */ + InFile(const InFile& other) = delete; + + /** Move `other` to this InFile. */ + InFile(InFile&& other); + + virtual ~InFile(); + + /** Move `other` to this InFile. File handles cannot be copied. */ + InFile& operator=(InFile& other); + + /** Read up to `count` characters into the provided `buffer`. */ + InFile& read(char* buffer, ssize_t count); + + /** @see File::seek */ + InFile& seek(size_t pos) override; + + /** @See File::seek */ + InFile& seek(ssize_t pos, File::SeekFrom from) override; + +private: + std::ifstream mStream; + + std::ios_base::openmode modeToIOSMode(File::Mode mode) override; +}; + + +struct OutFile + : public File +{ + /** Write `count` characters from the provided `buffer` into this file. */ + InFile& write(char* buffer, ssize_t count); + + /** @see File::seek */ + InFile& seek(size_t pos) override; + + /** @See File::seek */ + InFile& seek(ssize_t pos, File::SeekFrom from) override; + +private: + std::ofstream stream; +}; + +} /* namespace core */ +} /* namespace erw */ diff --git a/lib/core/src/File.cc b/lib/core/src/File.cc new file mode 100644 index 0000000..68ec789 --- /dev/null +++ b/lib/core/src/File.cc @@ -0,0 +1,140 @@ +/* File.cc + * vim: set tw=80: + * Eryn Wells + */ +/** + * Implementation of file handling. + */ + +#include "core/File.hh" + + +namespace erw { +namespace core { + +#pragma mark - File + +File::~File() +{ } + + +/* + * InFile::modeToIOSMode -- + */ +std::ios_base::openmode +File::modeToIOSMode(Mode mode) +{ + std::ios_base::openmode openmode = 0; + if ((mode & In).any()) { + openmode |= std::ios_base::in; + } + if ((mode & Out).any()) { + openmode |= std::ios_base::out; + } + if ((mode & Binary).any()) { + openmode |= std::ios_base::binary; + } + return openmode; +} + +#pragma mark - InFile + +/* + * InFile::InFile -- + */ +InFile::InFile(const String& path, + InFile::Mode mode) + : mStream(path, modeToIOSMode(mode)) +{ } + + +/* + * InFile::InFile -- + */ +InFile::InFile(InFile&& other) + : mStream(std::move(other.mStream)) +{ } + + +/* + * InFile::~InFile -- + */ +InFile::~InFile() +{ } + + +/* + * InFile::operator= -- + */ +InFile& +InFile::operator=(InFile& other) +{ + mStream = std::move(other.mStream); + return *this; +} + + +/* + * InFile::read -- + */ +InFile& +InFile::read(char* buffer, + ssize_t count) +{ + mStream.read(buffer, count); + return *this; +} + + +/* + * InFile::seek -- + */ +InFile& +InFile::seek(size_t pos) +{ + mStream.seekg(pos); + return *this; +} + + +/* + * InFile::seek -- + */ +InFile& +InFile::seek(ssize_t off, + File::SeekFrom from) +{ + std::ios_base::seekdir dir; + switch (from) { + case File::SeekFrom::Begin: + dir = std::ios_base::beg; + break; + case File::SeekFrom::Here: + dir = std::ios_base::cur; + break; + case File::SeekFrom::End: + dir = std::ios_base::end; + break; + } + mStream.seekg(off, dir); + return *this; +} + + +/* + * InFile::modeToIOSMode -- + */ +std::ios_base::openmode +InFile::modeToIOSMode(File::Mode mode) +{ + // Ensure In flag is always set. + if (!(mode & File::In).any()) { + mode |= File::In; + } + return File::modeToIOSMode(mode); +} + +#pragma mark - OutFile + +} /* namespace core */ +} /* namespace erw */ From 864174827458e09c48293d32107c65eeba91b4aa Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sun, 18 Oct 2015 08:23:59 -0700 Subject: [PATCH 04/12] Add File::path(), which returns the path the File was initialized with; remove core namespace --- lib/core/include/core/File.hh | 13 ++++++++++--- lib/core/include/core/String.hh | 2 -- lib/core/src/File.cc | 32 +++++++++++++++++++++++++++----- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/lib/core/include/core/File.hh b/lib/core/include/core/File.hh index 5f84641..d47ae88 100644 --- a/lib/core/include/core/File.hh +++ b/lib/core/include/core/File.hh @@ -14,7 +14,6 @@ namespace erw { -namespace core { struct File { @@ -36,6 +35,8 @@ struct File /** Destructor. */ virtual ~File(); + String path() const noexcept; + /** Seek to an absolute position in the file. */ virtual File& seek(size_t pos) = 0; @@ -46,8 +47,12 @@ struct File virtual File& seek(ssize_t offset, SeekFrom from) = 0; protected: + const String mPath; + /** Convert a File::Mode to an iostream openmode bitset. */ virtual std::ios_base::openmode modeToIOSMode(Mode mode); + + File(const String& path); }; @@ -57,7 +62,7 @@ struct InFile { /** Open a file at `path` for reading. */ InFile(const String& path, File::Mode mode); - + /** Deleted copy constructor. File handles cannot be copied. */ InFile(const InFile& other) = delete; @@ -69,6 +74,8 @@ struct InFile /** Move `other` to this InFile. File handles cannot be copied. */ InFile& operator=(InFile& other); + String path() const; + /** Read up to `count` characters into the provided `buffer`. */ InFile& read(char* buffer, ssize_t count); @@ -79,6 +86,7 @@ struct InFile InFile& seek(ssize_t pos, File::SeekFrom from) override; private: + String mPath; std::ifstream mStream; std::ios_base::openmode modeToIOSMode(File::Mode mode) override; @@ -101,5 +109,4 @@ private: std::ofstream stream; }; -} /* namespace core */ } /* namespace erw */ diff --git a/lib/core/include/core/String.hh b/lib/core/include/core/String.hh index 0206db5..2e65fe4 100644 --- a/lib/core/include/core/String.hh +++ b/lib/core/include/core/String.hh @@ -10,9 +10,7 @@ namespace erw { -namespace core { typedef std::string String; -} /* namespace core */ } /* namespace erw */ diff --git a/lib/core/src/File.cc b/lib/core/src/File.cc index 68ec789..3fa3430 100644 --- a/lib/core/src/File.cc +++ b/lib/core/src/File.cc @@ -10,16 +10,37 @@ namespace erw { -namespace core { #pragma mark - File +/* + * File::File -- + */ +File::File(const String& path) + : mPath(path) +{ } + + +/* + * File::~File -- + */ File::~File() { } /* - * InFile::modeToIOSMode -- + * File::path -- + */ +String +File::path() + const noexcept +{ + return mPath; +} + + +/* + * File::modeToIOSMode -- */ std::ios_base::openmode File::modeToIOSMode(Mode mode) @@ -44,7 +65,8 @@ File::modeToIOSMode(Mode mode) */ InFile::InFile(const String& path, InFile::Mode mode) - : mStream(path, modeToIOSMode(mode)) + : File(path), + mStream(path, modeToIOSMode(mode)) { } @@ -52,7 +74,8 @@ InFile::InFile(const String& path, * InFile::InFile -- */ InFile::InFile(InFile&& other) - : mStream(std::move(other.mStream)) + : File(other.mPath), + mStream(std::move(other.mStream)) { } @@ -136,5 +159,4 @@ InFile::modeToIOSMode(File::Mode mode) #pragma mark - OutFile -} /* namespace core */ } /* namespace erw */ From 283a5648a84e77ac848ceeb79708926af2b24fd3 Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Mon, 19 Oct 2015 07:55:06 -0700 Subject: [PATCH 05/12] Breaking up xml parsing into xml namespace and classes --- lib/core/include/core/xml/Document.hh | 47 +++++ lib/core/include/core/xml/Node.hh | 41 ++++ lib/core/src/xml/Document.cc | 275 ++++++++++++++++++++++++++ lib/core/src/xml/Node.cc | 76 +++++++ 4 files changed, 439 insertions(+) create mode 100644 lib/core/include/core/xml/Document.hh create mode 100644 lib/core/include/core/xml/Node.hh create mode 100644 lib/core/src/xml/Document.cc create mode 100644 lib/core/src/xml/Node.cc diff --git a/lib/core/include/core/xml/Document.hh b/lib/core/include/core/xml/Document.hh new file mode 100644 index 0000000..bbccfa8 --- /dev/null +++ b/lib/core/include/core/xml/Document.hh @@ -0,0 +1,47 @@ +/* XMLDocument.hh + * vim: set tw=80: + * Eryn Wells + */ +/** + * An XML document and related structures. + */ + +#pragma once + +#include +#include +#include + +#include "core/File.hh" +#include "core/String.hh" + + +namespace erw { +namespace xml { + +struct Document; + + +/** An XML document. */ +struct Document +{ + /** + * Constructor. Parse an XML document out of the given file. Doing so takes + * ownership of the file. + */ + Document(InFile&& file); + + /** Constructor. Parse an XML document from the given string. */ + Document(const String& string); + + ~Document(); + + const Node& root() const noexcept; + +protected: + /** The root of the XML tree. The document owns its root. */ + Node mRoot; +}; + +} /* namespace xml */ +} /* namespace erw */ diff --git a/lib/core/include/core/xml/Node.hh b/lib/core/include/core/xml/Node.hh new file mode 100644 index 0000000..3ea27f7 --- /dev/null +++ b/lib/core/include/core/xml/Node.hh @@ -0,0 +1,41 @@ +/* Node.hh + * vim: set tw=80: + * Eryn Wells + */ +/** + * An XML node. + */ + +#pragma once + +#include +#include + +#include "String.hh" + +namespace erw { +namespace xml { + +/** A node in an XML tree. */ +struct Node +{ + typedef std::vector List; + typedef std::map AttributeMap; + + Node(); + Node(const String& name, const List& children); + Node(const Node& other); + ~Node(); + + String name() const noexcept; + List children() const noexcept; + +protected: + /** The name of the node. */ + String mName; + /** Children of this node. The node owns its children. */ + List mChildren; +}; + +} /* namespace xml */ +} /* namespace erw */ diff --git a/lib/core/src/xml/Document.cc b/lib/core/src/xml/Document.cc new file mode 100644 index 0000000..53829e9 --- /dev/null +++ b/lib/core/src/xml/Document.cc @@ -0,0 +1,275 @@ +/* XMLParser.cc + * vim: set tw=80: + * Eryn Wells + */ +/** + * Implementation of an XML parser. + */ + +#include +#include + +#include +#include + +#include "XMLParser.hh" + + + +namespace { + +/* + * initLibrary -- + */ +void +initLibrary() +{ + static std::once_flag once; + std::call_once(once, []() { + xmlInitParser(); + }); +} + + +/* + * parseFile -- + */ +XMLNode +parseFile(File&& file) +{ + const size_t kInitialBufferSize = 16; + const size_t kBufferSize = 1024; + + static_assert(kInitialBufferSize < kBufferSize, + "XML parser initial buffer size must be smaller than the " + "total buffer size"); + + initLibrary(); + + char buffer[kBufferSize]; + ssize_t bytesRead = 0; + + bytesRead = file.read(buffer, kInitialBufferSize); + xmlParserCtxtPtr context = xmlCreatePushParserCtxt(nullptr, nullptr, + buffer, bytesRead, + file.path().c_str()); + if (!context) { + // TODO: Throw an appropriate error... + throw 42; + } + + /* + * Read chunks until we're done. Once all data has been read, indicate that + * the parser should terminate by calling xmlParseChunk() with a last + * argument of 1 rather than 0. + */ + while ((bytesRead = file.read(buffer, kBufferSize)) > 0) { + xmlParseChunk(context, buffer, bytesRead, 0); + } + xmlParseChunk(context, buffer, 0, 1); + + bool succeeded = bool(context->wellFormed); + xmlDocPtr document = context->myDoc; + + xmlFreeParserCtxt(context); + + return succeeded ? XMLDocument::UCPtr(new XML2Document(document)) : nullptr; +} + +} + + +namespace erw { + +struct XML2Node + : public XMLNode +{ + XML2Node(xmlNodePtr node); + + virtual ~XML2Node(); + + virtual String name() const noexcept override; + virtual String content() const noexcept override; + virtual XMLNode::AttributeMap attributes() const noexcept override; + +private: + xmlNodePtr mNode; + + /** Make a list of children of the node, excluding text nodes. */ + XMLNode::List childrenOfXML2Node(xmlNodePtr node) const noexcept; +}; + + +/** An XML parser that uses libxml2. */ +struct XML2Document + : public XMLDocument +{ + /** + * Initialize the xml2 library, if needed. This function may be called more + * than once with no adverse affects. + */ + static void initLibrary(); + + /** + * Parse a file into a libxml2 document object. Note: because of move + * semantics related to the file UPtr, the file will be closed after this + * method completes. + * + * @param [in] file The file to parse. + * @return A libxml2 document, or nullptr if the parse fails. + */ + static XMLDocument::UCPtr parseFile(File::UPtr file); + + static XMLDocument::UCPtr parseString(const String& string); + + XML2Document(xmlDocPtr document); + + virtual ~XML2Document(); + + virtual XMLNode::WCPtr root() const noexcept override; + +private: + xmlDocPtr mDocument; +}; + +#pragma mark - erw::XMLDocument + +/* static */ XMLDocument::UCPtr +XMLDocument::parseFile(File::UPtr file) +{ + return XML2Document::parseFile(std::move(file)); +} + + +/* static */ XMLDocument::UCPtr +XMLDocument::parseString(const String& string) +{ + return XML2Document::parseString(string); +} + + +XMLDocument(InFile&& file) + : mRoot() +{ } + + +XMLDocument::~XMLDocument() +{ } + +#pragma mark - erw::XML2Document + + + +/* static */ XMLDocument::UCPtr +XML2Document::parseString(const String& string) +{ + initLibrary(); + xmlDocPtr document = xmlReadMemory(string.c_str(), string.size(), "memory.xml", NULL, 0); + return document ? XMLDocument::UCPtr(new XML2Document(document)) : nullptr; +} + + +XML2Document::XML2Document(xmlDocPtr document) + : XMLDocument(XMLNode::Ptr(new XML2Node(xmlDocGetRootElement(document)))), + mDocument(document) +{ } + + +XML2Document::~XML2Document() +{ + if (mDocument) { + xmlFreeDoc(mDocument); + mDocument = nullptr; + } +} + + +XMLNode::WCPtr +XML2Document::root() + const noexcept +{ + return mRoot; +} + +#pragma mark - XMLNode + +XMLNode::~XMLNode() +{ } + + +XMLNode::XMLNode(XMLNode::List&& children) + : mChildren(children) +{ } + + +XMLNode::WCList +XMLNode::children() + const noexcept +{ + WCList weakChildren; + for (Ptr child : mChildren) { + weakChildren.push_back(WCPtr(child)); + } + return weakChildren; +} + +#pragma mark - XML2Node + +XML2Node::XML2Node(xmlNodePtr node) + : XMLNode(childrenOfXML2Node(node)), + mNode(node) +{ } + + +XML2Node::~XML2Node() +{ } + + +String +XML2Node::name() + const noexcept +{ + return (const char *)mNode->name; +} + + +String +XML2Node::content() + const noexcept +{ + xmlChar *content = xmlNodeGetContent(mNode); + String contentString((const char *)content); + xmlFree(content); + return contentString; +} + + +XMLNode::AttributeMap +XML2Node::attributes() + const noexcept +{ + AttributeMap attrs; + for (xmlAttrPtr attr = mNode->properties; attr && attr->name && attr->children; attr = attr->next) { + xmlChar *value = xmlNodeListGetString(mNode->doc, attr->children, 1); + attrs[(const char *)attr->name] = (const char *)value; + xmlFree(value); + } + return attrs; +} + + +XMLNode::List +XML2Node::childrenOfXML2Node(xmlNodePtr node) + const noexcept +{ + XMLNode::List children; + for (xmlNodePtr c = node->children; c != nullptr; c = c->next) { + if (c->type != XML_ELEMENT_NODE) { + continue; + } + children.push_back(XMLNode::Ptr(new XML2Node(c))); + } + return children; +} + +} /* namespace erw */ diff --git a/lib/core/src/xml/Node.cc b/lib/core/src/xml/Node.cc new file mode 100644 index 0000000..7517de0 --- /dev/null +++ b/lib/core/src/xml/Node.cc @@ -0,0 +1,76 @@ +/* XMLNode.cc + * vim: set tw=80: + * Eryn Wells + */ +/** + * Implementation of a node in an XML tree. + */ + +#include "core/XMLDocument.hh" + +#include +#include + + +namespace erw { +namespace xml { + +/* + * Node::Node -- + */ +Node::Node() + : mName(), + mChildren() +{ } + + +/* + * Node::Node -- + */ +Node::Node(const String& name, + const List& children) + : mName(name), + mChildren(children) +{ } + + +/* + * Node::Node -- + */ +Node::Node(const Node& other) + : mName(other.name), + mChildren(other.children) +{ } + + +/* + * Node::~Node -- + */ +Node::~Node() +{ } + +#pragma mark Properties + +/* + * Node::name -- + */ +String +Node::name() + const +{ + return mName; +} + + +/* + * Node::children -- + */ +List +Node::children() + const +{ + return mChildren; +} + +} /* namespace xml */ +} /* namespace erw */ From c669ad98f1e83bec1d4affd44bdef075d97b1280 Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sat, 5 Dec 2015 09:52:52 -0800 Subject: [PATCH 06/12] Doc comment for SConstruct --- SConstruct | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/SConstruct b/SConstruct index 4f4d44c..48b0d84 100644 --- a/SConstruct +++ b/SConstruct @@ -1,11 +1,12 @@ # SConstruct # vim: set ft=python: -# -# Toplevel Scons build script. This should be mostly complete and generic enough -# for most builds. -# # Eryn Wells +''' +Toplevel Scons build script. This should be mostly complete and generic enough +for most builds. +''' + import logging setup_logging() From fd2e6ae69916b901f6304536f34242eb119a1d64 Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sat, 5 Dec 2015 09:53:32 -0800 Subject: [PATCH 07/12] Add swiftc tool --- site_scons/site_init.py | 2 +- site_scons/site_tools/swiftc.py | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 site_scons/site_tools/swiftc.py diff --git a/site_scons/site_init.py b/site_scons/site_init.py index cb25ecf..12b7b3c 100644 --- a/site_scons/site_init.py +++ b/site_scons/site_init.py @@ -184,7 +184,7 @@ class Environment(SCons.Environment.Environment): def _append_custom_tools(self, kwargs): '''Add custom tools to the `kwargs`.''' tools = kwargs.setdefault('tools', ['default']) - for tool in ['lib', 'test', 'program', 'sconscript']: + for tool in ['lib', 'test', 'program', 'sconscript', 'swiftc']: if tool in tools: continue tools.append(tool) diff --git a/site_scons/site_tools/swiftc.py b/site_scons/site_tools/swiftc.py new file mode 100644 index 0000000..5d2766d --- /dev/null +++ b/site_scons/site_tools/swiftc.py @@ -0,0 +1,33 @@ +# swiftc.py +# vim: set ft=python: +# Eryn Wells + +''' +SCons plugin for building Swift files with swiftc. +''' + +import SCons.Action +import SCons.Tool +import SCons.Util + +SwiftSuffix = '.swift' +SwiftAction = SCons.Action.Action("$SWIFTCCOM", "$SWIFTCCOMSTR") + +compilers = ['swiftc'] + +def generate(env): + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + static_obj.add_action(SwiftSuffix, SwiftAction) + static_obj.add_emitter(SwiftSuffix, SCons.Defaults.SharedObjectEmitter) + shared_obj.add_action(SwiftSuffix, SwiftAction) + shared_obj.add_emitter(SwiftSuffix, SCons.Defaults.SharedObjectEmitter) + + if 'SWIFTC' not in env: + compiler = env.Detect(compilers) + env['SWIFTC'] = compiler if compiler else compilers[0] + env['SWIFTFLAGS'] = SCons.Util.CLVar('') + env['SWIFTCCOM'] = '$SWIFTC -o $TARGET -c $SWIFTFLAGS $SOURCES' + env['SWIFTFILESUFFIX'] = SwiftSuffix + +def exists(env): + return env.Detect(compilers) From 517a083694ed6444a1dff235a72879b16d6f78a9 Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sat, 27 Feb 2016 08:55:09 -0800 Subject: [PATCH 08/12] Add Append and Replace to the env --- site_scons/site_tools/sconscript.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/site_scons/site_tools/sconscript.py b/site_scons/site_tools/sconscript.py index b898481..12c0015 100644 --- a/site_scons/site_tools/sconscript.py +++ b/site_scons/site_tools/sconscript.py @@ -9,12 +9,15 @@ import SCons.Script def _do_sconscript(env): original_sconscript = env.SConscript - + def sconscript(env, sconscript, clone=False, *args, **kwargs): exports = {'Library': env.Library, 'StaticLibrary': env.StaticLibrary, 'SharedLibrary': env.SharedLibrary, - 'Program': env.Program} + 'Program': env.Program, + + 'Append': env.Append, + 'Replace': env.Replace} SCons.Script._SConscript.GlobalDict.update(exports) env.log('Reading {}'.format(sconscript)) return original_sconscript(sconscript, From 2ab67a8138010dc6b2ef9ae8ed57b6520149e524 Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sat, 27 Feb 2016 09:11:38 -0800 Subject: [PATCH 09/12] Add color diagnostics switch for gcc --- site_scons/site_init.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/site_scons/site_init.py b/site_scons/site_init.py index 12b7b3c..e4398ca 100644 --- a/site_scons/site_init.py +++ b/site_scons/site_init.py @@ -105,6 +105,9 @@ class Environment(SCons.Environment.Environment): if colorful and sys.stdout.isatty(): if 'clang' in self['CC'] or 'clang' in self['CXX']: self.AppendUnique(CCFLAGS=['-fcolor-diagnostics']) + elif 'gcc' in self['CC'] or 'g++' in self['CXX']: + # TODO: Also set a GCC_COLORS variable in the system environment? + self.AppendUnique(CCFLAGS=['-fdiagnostics-color=always']) # Pretty printing self.SetDefault(ARCOMSTR=Environment._comstr('Archiving', succinct)) From 84b5595490fa52da13c42be008692242d76d1fdd Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sun, 28 Feb 2016 09:22:34 -0800 Subject: [PATCH 10/12] Remove TODO --- site_scons/site_init.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/site_scons/site_init.py b/site_scons/site_init.py index e4398ca..2d3788b 100644 --- a/site_scons/site_init.py +++ b/site_scons/site_init.py @@ -138,8 +138,6 @@ class Environment(SCons.Environment.Environment): def process_src(self): out_dir = self.build_root.Dir('src') - # TODO: Do the thing. - # do_sconscript(env, env.source_root, src_out_dir) self.SConscript(self.src_root.File('SConscript'), variant_dir=out_dir) self.Append(CPPPATH=[self.src_root]) From 146b177ca99f133b6391afc1acbbdd602360a2d0 Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sun, 28 Feb 2016 09:22:46 -0800 Subject: [PATCH 11/12] Property export env --- site_scons/site_tools/sconscript.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/site_scons/site_tools/sconscript.py b/site_scons/site_tools/sconscript.py index 12c0015..3e9b597 100644 --- a/site_scons/site_tools/sconscript.py +++ b/site_scons/site_tools/sconscript.py @@ -11,19 +11,18 @@ def _do_sconscript(env): original_sconscript = env.SConscript def sconscript(env, sconscript, clone=False, *args, **kwargs): - exports = {'Library': env.Library, - 'StaticLibrary': env.StaticLibrary, - 'SharedLibrary': env.SharedLibrary, - 'Program': env.Program, - - 'Append': env.Append, - 'Replace': env.Replace} + exports = { + 'Library': env.Library, + 'Object': env.Object, + 'SharedObject': env.SharedObject, + 'StaticLibrary': env.StaticLibrary, + 'SharedLibrary': env.SharedLibrary, + 'Program': env.Program, + 'env': env.Clone() if clone else env, + } SCons.Script._SConscript.GlobalDict.update(exports) env.log('Reading {}'.format(sconscript)) - return original_sconscript(sconscript, - {'env': env.Clone() if clone else env}, - *args, - **kwargs) + return original_sconscript(sconscript, {}, *args, **kwargs) return sconscript From 50177d96b8b243f739d9a2adfe71734dc39f89b0 Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sun, 28 Feb 2016 09:24:20 -0800 Subject: [PATCH 12/12] Remove paths module --- site_scons/paths.py | 30 ------------------------------ site_scons/site_init.py | 3 --- 2 files changed, 33 deletions(-) delete mode 100644 site_scons/paths.py diff --git a/site_scons/paths.py b/site_scons/paths.py deleted file mode 100644 index c2b37b9..0000000 --- a/site_scons/paths.py +++ /dev/null @@ -1,30 +0,0 @@ -# paths.py -# Eryn Wells - -import os -import os.path - - -def is_executable(path): - return os.path.exists(path) and os.access(path, os.X_OK) - - -def which(program): - ''' - Look for `program` in system path and return the full path to that binary if - it is found. Otherwise, return `None`. - ''' - path, name = os.path.split(program) - if path: - if is_executable(program): - return program - else: - pathext = [''] + os.environ.get('PATHEXT', '').split(os.pathsep) - for path in os.environ.get('PATH', '').split(os.pathsep): - exe = os.path.join(path, program) - for ext in pathext: - candidate = exe + ext - if is_executable(candidate): - return candidate - return None - diff --git a/site_scons/site_init.py b/site_scons/site_init.py index 2d3788b..0c2f2ba 100644 --- a/site_scons/site_init.py +++ b/site_scons/site_init.py @@ -3,12 +3,9 @@ import logging import sys - import SCons.Environment import SCons.Errors -import paths - def setup_logging(level=logging.DEBUG): '''Configure global logging for the SCons system.'''