From 1975e66bc85629d9407a439497caf7f2f42d318e Mon Sep 17 00:00:00 2001 From: PhoenixBound Date: Thu, 2 Jul 2026 20:41:08 -0500 Subject: [PATCH 1/3] Use std::filesystem instead of pre-C++17 alternatives It's been 9 years. All the compilers support C++17 well now, 100%. Visual Studio 2022 still supports Windows 7, so that part's fine. gcc 8 and the associated libstdc++ version were released in May 2018; Debian oldoldstable (bullseye as of writing) has gcc 10, and my understanding is that Debian is normally considered to be pretty late to get new versions of things. I'm not expecting this to get merged right away, but it'd nice to delete code, once that does become realistic. --- setup.py | 2 +- src/Makefile | 10 +- src/filesystem/LICENSE | 36 ------ src/filesystem/filesystem_mini.h | 211 ------------------------------- src/fs.h | 13 +- 5 files changed, 9 insertions(+), 263 deletions(-) delete mode 100644 src/filesystem/LICENSE delete mode 100644 src/filesystem/filesystem_mini.h diff --git a/setup.py b/setup.py index 949c74f..c7eed11 100755 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ extra_link_args = [] if platform.system() == "Linux" or platform.system() == "Darwin": - extra_compile_args = ["-std=c++11"] + extra_compile_args = ["-std=c++17"] setup(name="ccscript", version="1.500", diff --git a/src/Makefile b/src/Makefile index ee35881..e56237f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,7 +1,7 @@ # # Crappy makefile for ccscript compiler (ccc) # -CXXFLAGS = -c -Wall -O3 -std=c++11 +CXXFLAGS = -c -Wall -O3 -std=c++17 OBJDIR = obj BINDIR = bin OUTFILE = ccc @@ -92,17 +92,17 @@ $(OBJDIR)/%.o: %.cpp # Object dependencies # $(OBJDIR)/anchor.o: anchor.h -$(OBJDIR)/ast.o: ast.h err.h value.h anchor.h symboltable.h string.h bytechunk.h module.h stringparser.h exception.h compiler.h util.h fs.h filesystem/filesystem_mini.h +$(OBJDIR)/ast.o: ast.h err.h value.h anchor.h symboltable.h string.h bytechunk.h module.h stringparser.h exception.h compiler.h util.h fs.h $(OBJDIR)/bytechunk.o: bytechunk.h anchor.h ast.h err.h value.h exception.h -$(OBJDIR)/ccc.o: ccc.h compiler.h module.h err.h util.h fs.h filesystem/filesystem_mini.h -$(OBJDIR)/compiler.o: compiler.h module.h err.h anchor.h ast.h value.h bytechunk.h symboltable.h exception.h util.h fs.h filesystem/filesystem_mini.h +$(OBJDIR)/ccc.o: ccc.h compiler.h module.h err.h util.h fs.h +$(OBJDIR)/compiler.o: compiler.h module.h err.h anchor.h ast.h value.h bytechunk.h symboltable.h exception.h util.h fs.h $(OBJDIR)/lexer.o: lexer.h err.h $(OBJDIR)/module.o: module.h err.h compiler.h ast.h value.h lexer.h parser.h symboltable.h bytechunk.h exception.h util.h $(OBJDIR)/parser.o: parser.h lexer.h err.h ast.h value.h $(OBJDIR)/stringparser.o: stringparser.h err.h value.h ast.h parser.h lexer.h module.h bytechunk.h $(OBJDIR)/symboltable.o: symboltable.h anchor.h ast.h err.h value.h $(OBJDIR)/table.o: table.h -$(OBJDIR)/util.o: util.h fs.h filesystem/filesystem_mini.h +$(OBJDIR)/util.o: util.h fs.h $(OBJDIR)/value.o: value.h table.h function.h string.h bytechunk.h diff --git a/src/filesystem/LICENSE b/src/filesystem/LICENSE deleted file mode 100644 index ccf4e97..0000000 --- a/src/filesystem/LICENSE +++ /dev/null @@ -1,36 +0,0 @@ -Copyright (c) 2016 Wenzel Jakob , 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. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS 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 COPYRIGHT HOLDER OR 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. - -You are under no obligation whatsoever to provide any bug fixes, patches, or -upgrades to the features, functionality or performance of the source code -("Enhancements") to anyone; however, if you choose to make your Enhancements -available either publicly, or directly to the author of this software, without -imposing a separate written license agreement for such Enhancements, then you -hereby grant the following license: a non-exclusive, royalty-free perpetual -license to install, use, modify, prepare derivative works, incorporate into -other computer software, distribute, and sublicense such enhancements or -derivative works thereof, in binary and source code form. diff --git a/src/filesystem/filesystem_mini.h b/src/filesystem/filesystem_mini.h deleted file mode 100644 index 5b3e23d..0000000 --- a/src/filesystem/filesystem_mini.h +++ /dev/null @@ -1,211 +0,0 @@ -#ifndef FILESYSTEM_PATH_H_ -#define FILESYSTEM_PATH_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(__linux) - #include -#endif - -namespace filesystem { - /** - * \brief Simple class for manipulating paths on POSIX systems - */ - class path { - public: - path() : m_absolute(false) {} - path(const path &path) : m_path(path.m_path), m_absolute(path.m_absolute) {} - path(const char *string) { set(string); } - path(const std::string &string) { set(string); } - size_t length() const { return m_path.size(); } - bool empty() const { return m_path.empty(); } - bool is_absolute() const { return m_absolute; } - - path make_absolute() const { - char temp[PATH_MAX]; - - if (realpath(string().c_str(), temp) == NULL) - throw std::runtime_error("Internal error in realpath(): " + std::string(strerror(errno))); - - return path(temp); - } - - bool exists() const { - struct stat sb; - return stat(string().c_str(), &sb) == 0; - } - - size_t file_size() const { - struct stat sb; - - if (stat(string().c_str(), &sb) != 0) - throw std::runtime_error("path::file_size(): cannot stat file \"" + string() + "\"!"); - - return (size_t) sb.st_size; - } - - bool is_directory() const { - struct stat sb; - - if (stat(string().c_str(), &sb)) - return false; - - return S_ISDIR(sb.st_mode); - } - - bool is_file() const { - struct stat sb; - - if (stat(string().c_str(), &sb)) - return false; - - return S_ISREG(sb.st_mode); - } - - std::string extension() const { - const std::string &name = filename(); - size_t pos = name.find_last_of("."); - - if (pos == std::string::npos) - return ""; - - return name.substr(pos+1); - } - - std::string filename() const { - if (empty()) - return ""; - - const std::string &last = m_path[m_path.size()-1]; - return last; - } - - path parent_path() const { - path result; - result.m_absolute = m_absolute; - - if (m_path.empty()) { - if (!m_absolute) - result.m_path.push_back(".."); - } else { - size_t until = m_path.size() - 1; - - for (size_t i = 0; i < until; ++i) - result.m_path.push_back(m_path[i]); - } - - return result; - } - - path& operator/=(const path &other) { - if (other.m_absolute) - throw std::runtime_error("path::operator/(): expected a relative path!"); - - for (size_t i=0; i tokenize(const std::string &string, const std::string &delim) { - std::string::size_type lastPos = 0, pos = string.find_first_of(delim, lastPos); - std::vector tokens; - - while (lastPos != std::string::npos) { - if (pos != lastPos) - tokens.push_back(string.substr(lastPos, pos - lastPos)); - - lastPos = pos; - - if (lastPos == std::string::npos || lastPos + 1 == string.length()) - break; - - pos = string.find_first_of(delim, ++lastPos); - } - - return tokens; - } - - protected: - std::vector m_path; - bool m_absolute; - }; - - inline bool exists(const path& p) { - return p.exists(); - } - - inline bool equivalent(const path& p1, const path& p2) { - return p1.make_absolute() == p2.make_absolute(); - } -} -#endif \ No newline at end of file diff --git a/src/fs.h b/src/fs.h index 52f84a4..cc3a00a 100644 --- a/src/fs.h +++ b/src/fs.h @@ -1,11 +1,4 @@ #pragma once -#ifdef _WIN32 - #ifndef _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING - #define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING - #endif // !_SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING - #include - namespace fs = std::experimental::filesystem::v1; -#else - #include "filesystem/filesystem_mini.h" - namespace fs = filesystem; -#endif +#include +namespace fs = std::filesystem; + From 84cb22f7427192ea2eb0106ebeaeb891f1069515 Mon Sep 17 00:00:00 2001 From: PhoenixBound Date: Fri, 3 Jul 2026 02:04:46 -0500 Subject: [PATCH 2/3] Fix MSVC support MSVC has a loud deprecation "warning" (error) for things that are deprecated in C++17, namely the Windows codecvt junk. Ideally this would be fixed as part of u8string-ifying and fs::path-ing everything in the compiler, but that's a big change and would probably screw up existing UTF-8 and Japanese support others are working on... so take the easy way out for now. Also removes the weird restriction that only Mac and Linux can have compiler flags (what about the BSDs and other Unix-like OSes?). This platform logic is probably a bit broken in some edge cases. setuptools' logic for choosing a C compiler is possible to introspect, apparently (https://stackoverflow.com/a/32192172), but I don't think there's a direct way to check it. All I could find is the logic for choosing a "default" compiler, and that's to use MSVC on Windows in all cases except when MinGW/MSys or Cygwin is detected. I thought I remembered Python docs saying "use a compiler with the same ABI as what Python was compiled with," which is why I reached for platform.python_compiler() here... --- setup.py | 7 +++++-- vs2019/ccscript.vcxproj | 6 ++++-- vs2019/tests.vcxproj | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index c7eed11..2639f0c 100755 --- a/setup.py +++ b/setup.py @@ -10,8 +10,11 @@ extra_compile_args = [] extra_link_args = [] -if platform.system() == "Linux" or platform.system() == "Darwin": - extra_compile_args = ["-std=c++17"] +if platform.python_compiler().startswith('MSC '): + extra_compile_args.append("/std:c++17") + extra_compile_args.append("/D_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING") +else: + extra_compile_args.append("-std=c++17") setup(name="ccscript", version="1.500", diff --git a/vs2019/ccscript.vcxproj b/vs2019/ccscript.vcxproj index 047d9d0..e3f375a 100644 --- a/vs2019/ccscript.vcxproj +++ b/vs2019/ccscript.vcxproj @@ -60,9 +60,10 @@ Level3 true - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + WIN32;_DEBUG;_CONSOLE;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;%(PreprocessorDefinitions) true MultiThreadedDebug + stdcpp17 Console @@ -82,9 +83,10 @@ true true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + WIN32;NDEBUG;_CONSOLE;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;%(PreprocessorDefinitions) true MultiThreaded + stdcpp17 Console diff --git a/vs2019/tests.vcxproj b/vs2019/tests.vcxproj index 44f7b16..9543420 100644 --- a/vs2019/tests.vcxproj +++ b/vs2019/tests.vcxproj @@ -77,6 +77,7 @@ Level3 ProgramDatabase + stdcpp17 true From e443066ab4e367e2f2c894dd4243032b0f55e2ce Mon Sep 17 00:00:00 2001 From: PhoenixBound Date: Sun, 5 Jul 2026 18:20:44 -0500 Subject: [PATCH 3/3] Directly check the compiler that setuptools uses instead of guessing As far as I can tell, all of these interfaces are documented parts of either setuptools or distutils. The linked GitHub issues currently offer no advice for avoiding "ccompiler" APIs, and the linked documentation recommends inheritance from the build_ext command class to extend things. The setuptools pip package is supposed to provide the 'distutils' import package, so this should work even on Python versions where distutils has been removed, in theory. --- setup.py | 49 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/setup.py b/setup.py index 2639f0c..f95c55f 100755 --- a/setup.py +++ b/setup.py @@ -1,20 +1,45 @@ #!/usr/bin/python3 import os -import platform +from distutils.ccompiler import get_default_compiler from setuptools import setup +from setuptools.command.build_ext import build_ext from setuptools.extension import Extension source_files = [os.path.join("src", x) for x in os.listdir("src") if x.lower().endswith(".cpp")] -extra_compile_args = [] -extra_link_args = [] +# As of July 2026, setuptools doesn't seem to include its own method to add compiler flags dependent +# on the specific compiler (I legitimately don't understand how extra_compile_args is supposed to +# work normally). But it does provide distutils' interface for checking what the compiler is, which +# should work in a stable way until they add their own way. +# See https://setuptools.pypa.io/en/latest/userguide/interfaces.html for info on stability tiers. +# See https://setuptools.pypa.io/en/latest/userguide/extension.html for the recommendation to +# inherit from existing commands to augment build functionality. +# See https://github.com/pypa/setuptools/issues/2806 for people asking for an upgrade path for many +# things related to creating and detecting compilers. +# Especially this comment: https://github.com/pypa/setuptools/issues/2806#issuecomment-1367674526 +class build_ext_with_compiler_flags(build_ext): + def finalize_options(self): + super().finalize_options() -if platform.python_compiler().startswith('MSC '): - extra_compile_args.append("/std:c++17") - extra_compile_args.append("/D_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING") -else: - extra_compile_args.append("-std=c++17") + extra_compile_args = [] + extra_link_args = [] + + compiler_type = None + if self.compiler is None: + compiler_type = get_default_compiler() + else: + compiler_type = self.compiler + + if compiler_type == 'msvc': + extra_compile_args.append('/std:c++17') + extra_compile_args.append('/D_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING') + else: + extra_compile_args.append('-std=c++17') + + for ext in self.extensions: + ext.extra_compile_args.extend(extra_compile_args) + ext.extra_link_args.extend(extra_link_args) setup(name="ccscript", version="1.500", @@ -23,8 +48,8 @@ ext_modules=[ Extension("ccscript", source_files, - language="c++", - extra_compile_args=extra_compile_args, - extra_link_args=extra_link_args + language="c++" ) - ]) + ], + cmdclass={'build_ext': build_ext_with_compiler_flags} + )