├── debian ├── compat ├── source │ ├── format │ └── lintian-overrides ├── ungoogled-chromium.lintian-overrides ├── changelog.in ├── ungoogled-chromium.links ├── ungoogled-chromium.prerm ├── ungoogled-chromium.postinst ├── patches │ ├── series │ ├── perfetto-system-zlib.patch │ ├── string-include.patch │ ├── clang-version.patch │ ├── atspi.patch │ ├── blink-frags.patch │ ├── icu-shim.patch │ ├── nullptr_t.patch │ ├── generate-ninja.patch │ ├── disable-clang-version-check.patch │ ├── fix-node-architecture.patch │ ├── driver-chrome-path.patch │ ├── clang16.patch │ ├── constcountrycode.patch │ ├── freetype-COLRV1.patch │ ├── material-utils.patch │ ├── template-correction.patch │ ├── sql-virtual-cursor.patch │ └── absl-optional.patch ├── chromium-flags.conf ├── shims │ └── jsoncpp.gn ├── control.in ├── copyright ├── ungoogled-chromium.install ├── initial_preferences └── rules ├── .cirrus_Dockerfile ├── .gitmodules ├── .github ├── workflows │ ├── obs-upload.yml │ └── obs-upload.sh └── README.md ├── .cirrus.yml └── convert ├── replace-name.pl ├── editcontrol.pl ├── compare.sh ├── README.md └── Makefile /debian/compat: -------------------------------------------------------------------------------- 1 | 12 2 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /debian/source/lintian-overrides: -------------------------------------------------------------------------------- 1 | new-package-should-close-itp-bug 2 | -------------------------------------------------------------------------------- /debian/ungoogled-chromium.lintian-overrides: -------------------------------------------------------------------------------- 1 | embedded-library usr/lib/chromium/chrome: srtp 2 | new-package-should-close-itp-bug 3 | -------------------------------------------------------------------------------- /debian/changelog.in: -------------------------------------------------------------------------------- 1 | ungoogled-chromium (@@VERSION@@) @@RELEASE@@; urgency=low 2 | 3 | * New upstream release 4 | 5 | -- @@AUTHOR@@ @@DATETIME@@ 6 | -------------------------------------------------------------------------------- /debian/ungoogled-chromium.links: -------------------------------------------------------------------------------- 1 | usr/share/icons/hicolor/48x48/apps/chromium.png usr/share/pixmaps/chromium.png 2 | usr/lib/chromium/chromedriver usr/bin/chromedriver 3 | -------------------------------------------------------------------------------- /.cirrus_Dockerfile: -------------------------------------------------------------------------------- 1 | # Dockerfile for Python 3 with xz-utils (for tar.xz unpacking) 2 | 3 | FROM python:3.7-slim 4 | 5 | RUN apt update && apt install -y xz-utils wget git 6 | -------------------------------------------------------------------------------- /debian/ungoogled-chromium.prerm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ "$1" = "remove" ] || [ "$1" = "deconfigure" ] ; then 6 | update-alternatives --remove x-www-browser /usr/bin/chromium 7 | update-alternatives --remove gnome-www-browser /usr/bin/chromium 8 | fi 9 | 10 | #DEBHELPER# 11 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "debian/submodules/ungoogled-chromium"] 2 | path = debian/submodules/ungoogled-chromium 3 | url = https://github.com/ungoogled-software/ungoogled-chromium.git 4 | [submodule "debian/submodules/chromium-launcher"] 5 | path = debian/submodules/chromium-launcher 6 | url = https://github.com/foutrelis/chromium-launcher.git 7 | -------------------------------------------------------------------------------- /debian/ungoogled-chromium.postinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] ; then 6 | update-alternatives --install /usr/bin/x-www-browser \ 7 | x-www-browser /usr/bin/chromium 40 8 | update-alternatives --install /usr/bin/gnome-www-browser \ 9 | gnome-www-browser /usr/bin/chromium 40 10 | fi 11 | 12 | #DEBHELPER# 13 | -------------------------------------------------------------------------------- /debian/patches/series: -------------------------------------------------------------------------------- 1 | freetype-COLRV1.patch 2 | icu-shim.patch 3 | clang-version.patch 4 | clang16.patch 5 | nullptr_t.patch 6 | generate-ninja.patch 7 | perfetto-system-zlib.patch 8 | template-correction.patch 9 | fix-node-architecture.patch 10 | disable-clang-version-check.patch 11 | sql-virtual-cursor.patch 12 | atspi.patch 13 | absl-optional.patch 14 | material-utils.patch 15 | driver-chrome-path.patch 16 | string-include.patch 17 | constcountrycode.patch 18 | blink-frags.patch 19 | -------------------------------------------------------------------------------- /debian/patches/perfetto-system-zlib.patch: -------------------------------------------------------------------------------- 1 | --- a/third_party/perfetto/gn/BUILD.gn 2 | +++ b/third_party/perfetto/gn/BUILD.gn 3 | @@ -404,7 +404,7 @@ 4 | if (enable_perfetto_zlib) { 5 | group("zlib") { 6 | if (perfetto_use_system_zlib) { 7 | - public_configs = [ "//gn:system_zlib_config" ] 8 | + public_configs = [ ":system_zlib_config" ] 9 | } else if (perfetto_root_path == "//") { 10 | public_configs = [ "//buildtools:zlib_config" ] 11 | public_deps = [ "//buildtools:zlib" ] 12 | -------------------------------------------------------------------------------- /debian/patches/string-include.patch: -------------------------------------------------------------------------------- 1 | author: Andres Salomon 2 | 3 | Build fix for std::string usage in the header without including . 4 | 5 | --- a/chrome/test/chromedriver/chrome/chrome_finder.h 6 | +++ b/chrome/test/chromedriver/chrome/chrome_finder.h 7 | @@ -5,6 +5,7 @@ 8 | #ifndef CHROME_TEST_CHROMEDRIVER_CHROME_CHROME_FINDER_H_ 9 | #define CHROME_TEST_CHROMEDRIVER_CHROME_CHROME_FINDER_H_ 10 | 11 | +#include 12 | #include 13 | 14 | #include "base/functional/callback_forward.h" 15 | -------------------------------------------------------------------------------- /debian/chromium-flags.conf: -------------------------------------------------------------------------------- 1 | # Do not hide any extensions in the about:extensions dialog 2 | --show-component-extension-options 3 | 4 | # Allow extensions to be loaded remotely 5 | --enable-remote-extensions 6 | 7 | # Enable GPU rasterization 8 | --enable-gpu-rasterization 9 | 10 | # Don't display any warnings about not being the default browser 11 | --no-default-browser-check 12 | 13 | # Disable pinging 14 | --disable-pings 15 | 16 | # Disable hyperlink auditing pings 17 | --no-pings 18 | 19 | # Disable the builtin media router 20 | --media-router=0 21 | -------------------------------------------------------------------------------- /debian/patches/clang-version.patch: -------------------------------------------------------------------------------- 1 | author: Andres Salomon 2 | description: hardcode lld for whatever version of clang we're using 3 | 4 | Upstream doesn't allow overridding the linker name (other than toggling 5 | lld vs gold). 6 | 7 | --- a/build/config/compiler/BUILD.gn 8 | +++ b/build/config/compiler/BUILD.gn 9 | @@ -391,7 +391,7 @@ config("compiler") { 10 | } 11 | 12 | if (use_lld) { 13 | - ldflags += [ "-fuse-ld=lld" ] 14 | + ldflags += [ "-fuse-ld=lld-16" ] 15 | if (lld_path != "") { 16 | ldflags += [ "-B$lld_path" ] 17 | } 18 | -------------------------------------------------------------------------------- /debian/patches/atspi.patch: -------------------------------------------------------------------------------- 1 | author: Andres Salomon 2 | 3 | https://chromium-review.googlesource.com/c/chromium/src/+/4883576 broke 4 | builds with atspi >= 2.50. This fixes it. 5 | 6 | --- a/build/config/linux/atspi2/BUILD.gn 7 | +++ b/build/config/linux/atspi2/BUILD.gn 8 | @@ -20,6 +20,7 @@ if (use_atk) { 9 | major = atspi_version[0] 10 | minor = atspi_version[1] 11 | micro = atspi_version[2] 12 | + not_needed(["major", "micro"]) 13 | 14 | # ATSPI 2.49.90 now defines these for us and it's an error for us to 15 | # redefine them on the compiler command line. 16 | -------------------------------------------------------------------------------- /debian/patches/blink-frags.patch: -------------------------------------------------------------------------------- 1 | authur: Andres Salomon 2 | 3 | More libstdc++13 build fixes. This should go upstream. 4 | 5 | --- a/third_party/blink/renderer/core/paint/fragment_data_iterator.h 6 | +++ b/third_party/blink/renderer/core/paint/fragment_data_iterator.h 7 | @@ -21,7 +21,7 @@ class FragmentDataIteratorBase { 8 | 9 | public: 10 | explicit FragmentDataIteratorBase(Head& head) : fragment_head_(head) {} 11 | - explicit FragmentDataIteratorBase(nullptr_t) {} 12 | + explicit FragmentDataIteratorBase(std::nullptr_t) {} 13 | 14 | Data* GetFragmentData() const { 15 | return !IsDone() ? &fragment_head_.at(idx_) : nullptr; 16 | -------------------------------------------------------------------------------- /debian/patches/icu-shim.patch: -------------------------------------------------------------------------------- 1 | description: allow building against system icu even when is_offical_build=true 2 | author: Andres Salomon 3 | 4 | I noticed this when switching to an official build and trying to build against 5 | the system's libicu, but it may be necessary for other system libs as well. 6 | If we switch to using the bundled icu, we can see if it's possible to get rid 7 | of it. 8 | 9 | --- a/tools/generate_shim_headers/generate_shim_headers.py 10 | +++ b/tools/generate_shim_headers/generate_shim_headers.py 11 | @@ -18,7 +18,7 @@ import sys 12 | 13 | 14 | SHIM_TEMPLATE = """ 15 | -#if defined(OFFICIAL_BUILD) 16 | +#if defined(DONT_TELL_ME_WHAT_TO_DO_GOOGLE) 17 | #error shim headers must not be used in official builds! 18 | #endif 19 | """ 20 | -------------------------------------------------------------------------------- /debian/patches/nullptr_t.patch: -------------------------------------------------------------------------------- 1 | author: Andres Salomon 2 | 3 | libstdc++13 build fixes; nullptr_t needs its namespace specified. 4 | 5 | --- a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/strings/safe_sprintf.h 6 | +++ b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/strings/safe_sprintf.h 7 | @@ -184,7 +184,7 @@ struct Arg { 8 | // 9 | // Warning: don't just do Arg(NULL) here because in some libcs, NULL is an 10 | // alias for nullptr! 11 | - Arg(nullptr_t p) : type(INT) { 12 | + Arg(std::nullptr_t p) : type(INT) { 13 | integer.i = 0; 14 | // Internally, SafeSprintf expects to represent nulls as integers whose 15 | // width is equal to sizeof(NULL), which is not necessarily equal to 16 | -------------------------------------------------------------------------------- /debian/patches/generate-ninja.patch: -------------------------------------------------------------------------------- 1 | author: Andres Salomon 2 | 3 | Bookworm's older gn (generate-ninja) doesn't understand the "mnemonic" 4 | variable. Since that string is used by tests that we delete, it doesn't 5 | matter anyways. 6 | 7 | Index: chromium-117.0.5938.62/third_party/blink/renderer/core/BUILD.gn 8 | =================================================================== 9 | --- a/third_party/blink/renderer/core/BUILD.gn 10 | +++ b/third_party/blink/renderer/core/BUILD.gn 11 | @@ -1677,7 +1677,6 @@ action_foreach("element_locator_test_pro 12 | python_path_root = "${root_out_dir}/pyproto" 13 | python_path_proto = "${python_path_root}/third_party/blink/renderer/core/lcp_critical_path_predictor" 14 | 15 | - mnemonic = "ELOC_PROTO" 16 | 17 | source_dir = "lcp_critical_path_predictor/test_proto" 18 | sources = rebase_path([ "lcp_image_id.asciipb" ], "", source_dir) 19 | -------------------------------------------------------------------------------- /debian/shims/jsoncpp.gn: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The Chromium Authors. All rights reserved. 2 | # Use of this source code is governed by a BSD-style license that can be 3 | # found in the LICENSE file. 4 | 5 | import("//build/config/linux/pkg_config.gni") 6 | import("//build/shim_headers.gni") 7 | 8 | pkg_config("jsoncpp_config") { 9 | packages = [ "jsoncpp" ] 10 | } 11 | 12 | shim_headers("jsoncpp_shim") { 13 | root_path = "source/include" 14 | headers = [ 15 | "json/allocator.h", 16 | "json/assertions.h", 17 | "json/config.h", 18 | "json/forwards.h", 19 | "json/json_features.h", 20 | "json/json.h", 21 | "json/reader.h", 22 | "json/value.h", 23 | "json/version.h", 24 | "json/writer.h" 25 | ] 26 | } 27 | 28 | group("jsoncpp") { 29 | deps = [ ":jsoncpp_shim" ] 30 | public_configs = [ ":jsoncpp_config" ] 31 | } 32 | -------------------------------------------------------------------------------- /.github/workflows/obs-upload.yml: -------------------------------------------------------------------------------- 1 | name: OBS Upload 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | tags: 7 | - '*' 8 | 9 | jobs: 10 | obs-upload: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: styfle/cancel-workflow-action@0.10.0 14 | with: 15 | access_token: ${{ github.token }} 16 | - uses: actions/checkout@v3 17 | - name: Convert from shallow repository to full repository 18 | run: git fetch --unshallow 19 | - name: Initialize submodules 20 | run: git submodule update --init --recursive 21 | - name: Install extra packages 22 | run: sudo apt install -y xmlstarlet 23 | - name: Run OBS Upload Script 24 | env: 25 | OBS_API_USERNAME: ${{ secrets.OBS_API_USERNAME }} 26 | OBS_API_PASSWORD: ${{ secrets.OBS_API_PASSWORD }} 27 | OBS_API_PROJECT: ${{ secrets.OBS_API_PROJECT }} 28 | run: .github/workflows/obs-upload.sh 29 | -------------------------------------------------------------------------------- /debian/patches/disable-clang-version-check.patch: -------------------------------------------------------------------------------- 1 | description: remove strict clang version check during config 2 | author: Andres Salomon 3 | 4 | Chromium 107 has a strict clang version check, added in commit 5 | 8f23a2c2d14fd799813134e995c160354d75d3a0. This needs a proper fix 6 | upstream; some way to check (or specify) whether it's a distribution 7 | build, and therefore shouldn't require a particular git version of 8 | clang. 9 | 10 | For now, let's just get this building in debian. 11 | 12 | --- a/tools/clang/scripts/update.py 13 | +++ b/tools/clang/scripts/update.py 14 | @@ -366,7 +366,7 @@ 15 | return 0 16 | 17 | stamp_version = ReadStampFile(STAMP_FILE).partition(',')[0] 18 | - if PACKAGE_VERSION != stamp_version: 19 | + if False: 20 | print('The expected clang version is %s but the actual version is %s' % 21 | (PACKAGE_VERSION, stamp_version)) 22 | print('Did you run "gclient sync"?') 23 | -------------------------------------------------------------------------------- /debian/patches/fix-node-architecture.patch: -------------------------------------------------------------------------------- 1 | --- a/third_party/node/node.py 2 | +++ b/third_party/node/node.py 3 | @@ -11,14 +11,13 @@ 4 | 5 | 6 | def GetBinaryPath(): 7 | - darwin_name = ('node-darwin-arm64' if platform.machine() == 'arm64' else 8 | - 'node-darwin-x64') 9 | - return os_path.join(os_path.dirname(__file__), *{ 10 | - 'Darwin': ('mac', darwin_name, 'bin', 'node'), 11 | - 'Linux': ('linux', 'node-linux-x64', 'bin', 'node'), 12 | - 'Windows': ('win', 'node.exe'), 13 | - }[platform.system()]) 14 | - 15 | + if platform.machine() == 'x86_64': 16 | + return os_path.join(os_path.dirname(__file__), 'linux', 'node-linux-x64', 'bin', 'node') 17 | + if platform.machine() == 'armv7l': 18 | + return os_path.join(os_path.dirname(__file__), 'linux', 'node-linux-armv7l', 'bin', 'node') 19 | + if platform.machine() == 'aarch64': 20 | + return os_path.join(os_path.dirname(__file__), 'linux', 'node-linux-arm64', 'bin', 'node') 21 | + return '' 22 | 23 | def RunNode(cmd_parts, stdout=None): 24 | cmd = [GetBinaryPath()] + cmd_parts 25 | -------------------------------------------------------------------------------- /.cirrus.yml: -------------------------------------------------------------------------------- 1 | container: 2 | dockerfile: .cirrus_Dockerfile 3 | 4 | # TODO: Syntax checking for debian/ folder contents? 5 | 6 | validate_with_source_task: 7 | submodule_checkout_script: 8 | - git submodule update --init --recursive 9 | check_patch_files_script: 10 | - debian/submodules/ungoogled-chromium/devutils/check_patch_files.py -p debian/patches 11 | merge_patches_script: 12 | - debian/submodules/ungoogled-chromium/utils/patches.py merge -p debian/patches debian/submodules/ungoogled-chromium/patches 13 | download_cache: 14 | folder: download_cache 15 | fingerprint_script: cat debian/submodules/ungoogled-chromium/chromium_version.txt 16 | populate_script: 17 | - mkdir download_cache || true 18 | - debian/submodules/ungoogled-chromium/utils/downloads.py retrieve -i debian/submodules/ungoogled-chromium/downloads.ini -c download_cache 19 | unpack_source_script: 20 | - debian/submodules/ungoogled-chromium/utils/downloads.py unpack -i debian/submodules/ungoogled-chromium/downloads.ini -c download_cache src 21 | validate_patches_script: 22 | - debian/submodules/ungoogled-chromium/devutils/validate_patches.py -l src -p debian/patches -s debian/patches/series 23 | 24 | # vim: set expandtab shiftwidth=4 softtabstop=4: 25 | -------------------------------------------------------------------------------- /debian/patches/driver-chrome-path.patch: -------------------------------------------------------------------------------- 1 | description: Disable usage of google-chrome in driver 2 | author: Michel Le Bihan 3 | 4 | --- a/chrome/test/chromedriver/chrome/chrome_finder.cc 5 | +++ b/chrome/test/chromedriver/chrome/chrome_finder.cc 6 | @@ -68,9 +68,6 @@ void GetApplicationDirs(std::vectoremplace_back("/usr/bin"); 8 | locations->emplace_back("/sbin"); 9 | locations->emplace_back("/bin"); 10 | - // Lastly, try the default installation location. 11 | - locations->emplace_back("/opt/google/chrome"); 12 | - locations->emplace_back("/opt/chromium.org/chromium"); 13 | } 14 | #elif BUILDFLAG(IS_ANDROID) 15 | void GetApplicationDirs(std::vector* locations) { 16 | @@ -126,9 +123,7 @@ std::vector GetChromePro 17 | base::FilePath(chrome::kGoogleChromeBrowserProcessExecutablePath), 18 | base::FilePath(chrome::kChromiumBrowserProcessExecutablePath), 19 | #elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) 20 | - base::FilePath(chrome::kBrowserProcessExecutablePath), 21 | - base::FilePath("chrome"), // Chrome for Testing or Google Chrome 22 | - base::FilePath("google-chrome"), base::FilePath("chromium"), 23 | + base::FilePath("chromium"), 24 | base::FilePath("chromium-browser"), 25 | #else 26 | // it will compile but won't work on other OSes 27 | -------------------------------------------------------------------------------- /debian/patches/clang16.patch: -------------------------------------------------------------------------------- 1 | author: Andres Salomon 2 | 3 | This is some clang-18 stuff. For clang-16, the compiler chokes on these 4 | flags. These used to only be enabled when llvm_force_head_revision=true, 5 | but now they're enabled unconditionally. 6 | 7 | --- a/build/config/compiler/BUILD.gn 8 | +++ b/build/config/compiler/BUILD.gn 9 | @@ -621,15 +621,10 @@ config("compiler") { 10 | # TODO(crbug.com/1491036): This isn't supported by Cronet's mainline llvm version. 11 | if (default_toolchain != "//build/toolchain/cros:target" && 12 | !llvm_android_mainline) { 13 | - cflags += [ 14 | - "-mllvm", 15 | - "-split-threshold-for-reg-with-hint=0", 16 | - ] 17 | if (use_thin_lto && is_a_target_toolchain) { 18 | if (is_win) { 19 | ldflags += [ "-mllvm:-split-threshold-for-reg-with-hint=0" ] 20 | } else { 21 | - ldflags += [ "-Wl,-mllvm,-split-threshold-for-reg-with-hint=0" ] 22 | } 23 | } 24 | } 25 | @@ -1878,10 +1873,8 @@ config("default_warnings") { 26 | "-Wno-vla-extension", 27 | 28 | # TODO(https://crbug.com/1490607): Fix and re-enable. 29 | - "-Wno-thread-safety-reference-return", 30 | 31 | # TODO(crbug.com/1495100): Evaluate and possibly enable. 32 | - "-Wno-delayed-template-parsing-in-cxx20", 33 | ] 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /debian/patches/constcountrycode.patch: -------------------------------------------------------------------------------- 1 | author: Andres Salomon 2 | 3 | Work around the following with libstdc++ 12: 4 | 5 | ./../components/autofill/core/browser/data_model/autofill_i18n_api.h:18:30: error: constexpr variable 'kLegacyHierarchyCountryCodeString' must be initialized by a constant expression 6 | constexpr inline std::string kLegacyHierarchyCountryCodeString{"XX"}; 7 | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8 | 9 | Index: chromium-120.0.6099.71/components/autofill/core/browser/data_model/autofill_i18n_api.h 10 | =================================================================== 11 | --- a/components/autofill/core/browser/data_model/autofill_i18n_api.h 12 | +++ b/components/autofill/core/browser/data_model/autofill_i18n_api.h 13 | @@ -15,8 +15,8 @@ namespace autofill::i18n_model_definitio 14 | // Country code that represents autofill's legacy address hierarchy model as 15 | // stored `kAutofillModelRules`. As a workaround for GCC we declare the 16 | // std::string constexpr first. 17 | -constexpr inline std::string kLegacyHierarchyCountryCodeString{"XX"}; 18 | -constexpr AddressCountryCode kLegacyHierarchyCountryCode = 19 | +const inline std::string kLegacyHierarchyCountryCodeString{"XX"}; 20 | +const AddressCountryCode kLegacyHierarchyCountryCode = 21 | AddressCountryCode(kLegacyHierarchyCountryCodeString); 22 | 23 | // Creates an instance of the address hierarchy model corresponding to the 24 | -------------------------------------------------------------------------------- /debian/patches/freetype-COLRV1.patch: -------------------------------------------------------------------------------- 1 | --- a/third_party/skia/src/ports/SkFontHost_FreeType_common.cpp 2 | +++ b/third_party/skia/src/ports/SkFontHost_FreeType_common.cpp 3 | @@ -55,14 +55,7 @@ 4 | // FT_PaintRadialGradient changed size and layout at VER-2-11-0-147-gd3d3ff76d 5 | // FT_STATIC_CAST introduced VER-2-11-0-172-g9079c5d91 6 | // So undefine TT_SUPPORT_COLRV1 before 2.11.1 but not if FT_STATIC_CAST is defined. 7 | -#if (((FREETYPE_MAJOR) < 2) || \ 8 | - ((FREETYPE_MAJOR) == 2 && (FREETYPE_MINOR) < 11) || \ 9 | - ((FREETYPE_MAJOR) == 2 && (FREETYPE_MINOR) == 11 && (FREETYPE_PATCH) < 1)) && \ 10 | - !defined(FT_STATIC_CAST) 11 | # undef TT_SUPPORT_COLRV1 12 | -#else 13 | -# include "src/base/SkScopeExit.h" 14 | -#endif 15 | #endif 16 | 17 | // FT_OUTLINE_OVERLAP was added in FreeType 2.10.3 18 | --- a/third_party/skia/src/ports/SkFontHost_FreeType.cpp 19 | +++ b/third_party/skia/src/ports/SkFontHost_FreeType.cpp 20 | @@ -92,13 +92,8 @@ 21 | // FT_PaintRadialGradient changed size and layout at VER-2-11-0-147-gd3d3ff76d 22 | // FT_STATIC_CAST introduced VER-2-11-0-172-g9079c5d91 23 | // So undefine TT_SUPPORT_COLRV1 before 2.11.1 but not if FT_STATIC_CAST is defined. 24 | -#if (((FREETYPE_MAJOR) < 2) || \ 25 | - ((FREETYPE_MAJOR) == 2 && (FREETYPE_MINOR) < 11) || \ 26 | - ((FREETYPE_MAJOR) == 2 && (FREETYPE_MINOR) == 11 && (FREETYPE_PATCH) < 1)) && \ 27 | - !defined(FT_STATIC_CAST) 28 | # undef TT_SUPPORT_COLRV1 29 | #endif 30 | -#endif 31 | 32 | //#define ENABLE_GLYPH_SPEW // for tracing calls 33 | //#define DUMP_STRIKE_CREATION 34 | -------------------------------------------------------------------------------- /convert/replace-name.pl: -------------------------------------------------------------------------------- 1 | # replace-name.pl 2 | # 3 | # This script operates on files under the debian/ directory. It (very) 4 | # selectively replaces instances of "chromium" and "Chromium" to $name 5 | # and $display_name, respectively. It also makes a few additional edits 6 | # related to this name change. 7 | # 8 | 9 | use strict; 10 | use warnings; 11 | 12 | my $name = 'ungoogled-chromium'; 13 | my $display_name = 'Ungoogled-Chromium'; 14 | 15 | s,\b( apps 16 | | bin 17 | | bug 18 | | debian 19 | | etc 20 | | lib 21 | | pixmaps 22 | | scripts 23 | | share 24 | )/(chromium)\b,$1/$name,gx; 25 | 26 | s,\b( CHROME_DESKTOP="? 27 | | Icon= 28 | | StartupWMClass= 29 | | man[ ] 30 | )(chromium)\b,$1$name,gx; 31 | 32 | s,( 33 | | 34 | | \$dest/ 35 | )(chromium)\b,$1$name,gx; 36 | 37 | s,()(Chromium)\b,$1$display_name,g; 38 | 39 | # for man page and associated postprocessing in debian/rules 40 | if (m,^\tsed -e s/\@\@PACKAGE\@\@/,) 41 | { 42 | my $orig_exprs = $_; 43 | $orig_exprs =~ s/\bsed\b/ /; 44 | $orig_exprs =~ s,\b(chromium)\b,$name,g; 45 | # don't change the user config/cache directory locations 46 | s#-e .+$#-r -e 's,(\\\$HOME/\\.[a-z]+/\@\@)PACKAGE(\@\@),\\1CONFIGNAME\\2,g' \\#; 47 | $_ .= "\t -e s/\@\@CONFIGNAME\@\@/chromium/ \\\n"; 48 | $_ .= $orig_exprs; 49 | } 50 | # 51 | s,\b(out/Release)/(chromium)\.(\d)\b,$1/$name.$3,g; 52 | 53 | # for .bug-control file 54 | /^report-with:/ and s/\b(chromium)\b/$name/g; 55 | 56 | # for .desktop file 57 | /^Name(\[\w+\])?=/ and s,\b(Chromium)\b,$display_name,g; 58 | 59 | # for launcher script 60 | if (/^APPNAME=(chromium)$/) 61 | { 62 | s/=/_INT=/; 63 | $_ = "APPNAME=$name\n" . $_; 64 | } 65 | # 66 | /\$(CHROMIUM_FLAGS|GDB)/ and s,(\$LIBDIR/\$APPNAME)\b,${1}_INT,g; 67 | 68 | # EOF 69 | -------------------------------------------------------------------------------- /debian/control.in: -------------------------------------------------------------------------------- 1 | Source: ungoogled-chromium 2 | Section: web 3 | Priority: optional 4 | Maintainer: @@AUTHOR@@ 5 | Homepage: https://github.com/Eloston/ungoogled-chromium 6 | Standards-Version: 4.5.0 7 | Build-Depends: 8 | debhelper (>= 12), 9 | dh-exec, 10 | lsb-release, 11 | apt, 12 | clang-16, 13 | lld-16, 14 | llvm-16-dev, 15 | libc++-16-dev, 16 | libclang-rt-16-dev, 17 | python-is-python3, 18 | ninja-build, 19 | generate-ninja, 20 | pkg-config, 21 | gperf, 22 | libncurses-dev, 23 | libcups2-dev, 24 | libdrm-dev, 25 | libnss3-dev, 26 | libkrb5-dev, 27 | libcurl4-openssl-dev, 28 | libgtk-3-dev, 29 | qtbase5-dev, 30 | libfontconfig-dev, 31 | libx11-xcb-dev, 32 | libxshmfence-dev, 33 | libgbm-dev, 34 | mesa-common-dev, 35 | libva-dev, 36 | libpulse-dev, 37 | libasound2-dev, 38 | libpci-dev, 39 | libxml2-dev, 40 | libopus-dev, 41 | libwebp-dev, 42 | libjpeg-dev, 43 | libxslt1-dev, 44 | libflac-dev, 45 | libsnappy-dev, 46 | libminizip-dev, 47 | libevent-dev, 48 | liblcms2-dev, 49 | libopenjp2-7-dev, 50 | libjsoncpp-dev 51 | 52 | Package: ungoogled-chromium 53 | Architecture: any 54 | Multi-Arch: foreign 55 | Provides: www-browser, gnome-www-browser, chromium, chromium-browser, ungoogled-chromium-l10n, ungoogled-chromium-shell, ungoogled-chromium-driver, ungoogled-chromium-common, ungoogled-chromium-sandbox 56 | Replaces: chromium, chromium-browser, ungoogled-chromium-l10n, ungoogled-chromium-shell, ungoogled-chromium-driver, ungoogled-chromium-common, ungoogled-chromium-sandbox 57 | Conflicts: chromium, chromium-browser, ungoogled-chromium-l10n, ungoogled-chromium-shell, ungoogled-chromium-driver, ungoogled-chromium-common, ungoogled-chromium-sandbox 58 | Depends: ${misc:Depends}, ${shlibs:Depends} 59 | Description: web browser 60 | Web browser that aims to build a safer, faster, and more stable internet 61 | browsing experience. 62 | 63 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Source: http://www.chromium.org/Home 3 | Upstream-Name: chromium 4 | 5 | Files: * 6 | Copyright: Copyright 2015 The Chromium Authors. All rights reserved. 7 | License: BSD-3-clause 8 | Copyright 2015 The Chromium Authors. All rights reserved. 9 | . 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions are 12 | met: 13 | . 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above 17 | copyright notice, this list of conditions and the following disclaimer 18 | in the documentation and/or other materials provided with the 19 | distribution. 20 | * Neither the name of Google Inc. nor the names of its 21 | contributors may be used to endorse or promote products derived from 22 | this software without specific prior written permission. 23 | . 24 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 30 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | 36 | -------------------------------------------------------------------------------- /debian/patches/material-utils.patch: -------------------------------------------------------------------------------- 1 | ./../third_party/material_color_utilities/src/cpp/palettes/tones.cc:59:27: note: use function 'std::abs' instead 2 | double smallest_delta = abs(smallest_delta_hct.get_chroma() - chroma); 3 | ^~~ 4 | std::abs 5 | ../../third_party/material_color_utilities/src/cpp/palettes/tones.cc:70:9: error: use of undeclared identifier 'round' 6 | if (round(chroma) == round(smallest_delta_hct.get_chroma())) { 7 | ^ 8 | 9 | --- a/third_party/material_color_utilities/src/cpp/palettes/tones.cc 10 | +++ b/third_party/material_color_utilities/src/cpp/palettes/tones.cc 11 | @@ -16,6 +16,8 @@ 12 | 13 | #include "cpp/palettes/tones.h" 14 | 15 | +#include 16 | + 17 | #include "cpp/cam/cam.h" 18 | #include "cpp/cam/hct.h" 19 | 20 | @@ -55,7 +57,7 @@ Argb TonalPalette::get(double tone) cons 21 | Hct TonalPalette::createKeyColor(double hue, double chroma) { 22 | double start_tone = 50.0; 23 | Hct smallest_delta_hct(hue, chroma, start_tone); 24 | - double smallest_delta = abs(smallest_delta_hct.get_chroma() - chroma); 25 | + double smallest_delta = std::abs(smallest_delta_hct.get_chroma() - chroma); 26 | // Starting from T50, check T+/-delta to see if they match the requested 27 | // chroma. 28 | // 29 | @@ -71,13 +73,13 @@ Hct TonalPalette::createKeyColor(double 30 | return smallest_delta_hct; 31 | } 32 | Hct hct_add(hue, chroma, start_tone + delta); 33 | - double hct_add_delta = abs(hct_add.get_chroma() - chroma); 34 | + double hct_add_delta = std::abs(hct_add.get_chroma() - chroma); 35 | if (hct_add_delta < smallest_delta) { 36 | smallest_delta = hct_add_delta; 37 | smallest_delta_hct = hct_add; 38 | } 39 | Hct hct_subtract(hue, chroma, start_tone - delta); 40 | - double hct_subtract_delta = abs(hct_subtract.get_chroma() - chroma); 41 | + double hct_subtract_delta = std::abs(hct_subtract.get_chroma() - chroma); 42 | if (hct_subtract_delta < smallest_delta) { 43 | smallest_delta = hct_subtract_delta; 44 | smallest_delta_hct = hct_subtract; 45 | -------------------------------------------------------------------------------- /.github/README.md: -------------------------------------------------------------------------------- 1 | # ungoogled-chromium-debian 2 | 3 | This repository contains files to build Debian packages of 4 | [ungoogled-chromium](//github.com/Eloston/ungoogled-chromium). 5 | 6 | These are the new unified packaging files which are designed to be built 7 | directly from the git repository and serve as a single set of packaging 8 | files for all Debian or Ubuntu releases newer than and including the 9 | currently oldest supported release, `Jammy`. 10 | 11 | Even so we will only be supporting a subset of the available distributions. 12 | These are currently: 13 | - Debian Sid 14 | - Ubuntu Jammy 15 | - Ubuntu Lunar 16 | 17 | All releases shall be supported on a best-effort basis. `x86_64` is the only 18 | architecture we can be reliably test so any other architectures will only be 19 | guaranteed to be buildable at best. Older releases may be dropped at any time 20 | if they are too difficult to continue to support due to how bleeding edge 21 | Chromium tends to be. 22 | 23 | ## Getting OBS packages 24 | 25 | We now defer to here: 26 | [OBS Setup Instructions](https://software.opensuse.org//download.html?project=home%3Aungoogled_chromium&package=ungoogled-chromium) 27 | 28 | Also note, if you have added the repository previously, you may eventually 29 | get errors about expired keys. This is due to how OBS generates repository 30 | keys and we have no known way to control it. At present the only known 31 | solution is to redo the steps for adding the repository key as OBS does 32 | regenerate it eventually with a new expiration date. 33 | 34 | ## Building a binary package 35 | 36 | ```sh 37 | # Install initial packages 38 | sudo apt install -y devscripts equivs 39 | 40 | # Clone repository and switch to it (optional if are already in it) 41 | git clone https://github.com/ungoogled-software/ungoogled-chromium-debian.git 42 | cd ungoogled-chromium-debian 43 | 44 | # Initiate the submodules (optional if they are already initiated) 45 | git submodule update --init --recursive 46 | 47 | # Prepare the local source 48 | debian/rules setup 49 | 50 | # Install missing packages 51 | sudo mk-build-deps -i debian/control 52 | rm ungoogled-chromium-build-deps_* 53 | 54 | # Build the package 55 | dpkg-buildpackage -b -uc 56 | ``` 57 | -------------------------------------------------------------------------------- /convert/editcontrol.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | # editcontrol.pl 3 | # 4 | # Script to simplify automated editing of Debian control files 5 | # (see deb-src-control(5) for information on the format) 6 | # 7 | # Usage samples: 8 | # 9 | # editcontrol -e '$package =~ /foo/ and s/foo/bar/' control >control.new 10 | # 11 | # editcontrol -i -e 's/foo/bar/;' -e 's/bar/qux/' debian/control 12 | # 13 | # editcontrol -i=.orig -f script.pl debian/control 14 | # 15 | 16 | use strict; 17 | use warnings; 18 | 19 | use Dpkg::Control::Info; 20 | use Getopt::Long; 21 | 22 | my @expr_list = (); 23 | my $script_file; 24 | my $inplace; 25 | 26 | sub load_script_file 27 | { 28 | my ($opt_name, $opt_value) = @_; 29 | open(F, $opt_value) or die "$opt_value: $!"; 30 | local $/; 31 | my $script = ; 32 | close(F); 33 | push @expr_list, $script; 34 | } 35 | 36 | GetOptions( 37 | 'expr=s' => \@expr_list, 38 | 'file=s' => \&load_script_file, 39 | 'inplace:s' => \$inplace 40 | ) or exit 1; 41 | 42 | push @expr_list, ';1;'; 43 | my $expr = join("\n", @expr_list); 44 | my $input_file = $ARGV[0]; 45 | 46 | my $control_info = Dpkg::Control::Info->new(filename => $input_file); 47 | my $in_order_ref = ${$control_info->get_source()}->{'in_order'}; 48 | 49 | foreach our $control (@{$control_info}) 50 | { 51 | my $source = $control->{'Source'} || ''; 52 | my $package = $control->{'Package'} || ''; 53 | my $INPUT_FIELD_NUMBER = 0; 54 | 55 | # Subroutine callable from the user expression 56 | # 57 | sub set_field($$) { 58 | my ($name, $value) = @_; 59 | my $is_new = !exists($control->{$name}); 60 | $control->{$name} = $value; 61 | if ($is_new) 62 | { 63 | # Insert new field after the current one 64 | splice @{$in_order_ref}, $INPUT_FIELD_NUMBER, 0, ($name); 65 | pop @{$in_order_ref}; 66 | } 67 | } 68 | 69 | foreach my $field (keys(%{$control})) 70 | { 71 | local $_ = $control->{$field}; 72 | ++$INPUT_FIELD_NUMBER; 73 | 74 | eval $expr or die $@; 75 | 76 | if (defined($_)) { $control->{$field} = $_; } 77 | else { delete $control->{$field}; } 78 | } 79 | } 80 | 81 | my $out = $control_info->output() or die; 82 | 83 | if (defined($inplace)) 84 | { 85 | local @ARGV = $input_file; 86 | local $^I = $inplace; 87 | local $/; 88 | my $orig = <>; 89 | print($out); 90 | } 91 | else 92 | { 93 | print($out); 94 | } 95 | 96 | exit 0; 97 | 98 | # end editcontrol.pl 99 | -------------------------------------------------------------------------------- /debian/ungoogled-chromium.install: -------------------------------------------------------------------------------- 1 | #!/usr/bin/dh-exec 2 | out/Release/chrome_sandbox usr/lib/chromium 3 | out/Release/chrome usr/lib/chromium 4 | out/Release/chromedriver usr/lib/chromium 5 | out/Release/libEGL.so usr/lib/chromium 6 | out/Release/libGLESv2.so usr/lib/chromium 7 | out/Release/libvk_swiftshader.so usr/lib/chromium 8 | out/Release/vk_swiftshader_icd.json usr/lib/chromium 9 | out/Release/chrome_*_percent.pak usr/lib/chromium 10 | out/Release/chrome_crashpad_handler usr/lib/chromium 11 | out/Release/v8_context_snapshot.bin usr/lib/chromium 12 | out/Release/icudtl.dat usr/lib/chromium 13 | out/Release/resources.pak usr/lib/chromium 14 | out/Release/locales/*.pak usr/lib/chromium/locales 15 | debian/submodules/chromium-launcher/chromium usr/bin 16 | debian/chromium-flags.conf etc 17 | debian/initial_preferences usr/lib/chromium 18 | chrome/installer/linux/common/desktop.template => usr/share/applications/chromium.desktop 19 | chrome/app/resources/manpage.1.in => usr/share/man/man1/chromium.1 20 | chrome/installer/linux/common/chromium-browser/chromium-browser.appdata.xml => usr/share/metainfo/chromium.appdata.xml 21 | chrome/app/theme/default_100_percent/chromium/product_logo_16.png => usr/share/icons/hicolor/16x16/apps/chromium.png 22 | chrome/app/theme/chromium/product_logo_24.png => usr/share/icons/hicolor/24x24/apps/chromium.png 23 | chrome/app/theme/default_100_percent/chromium/product_logo_32.png => usr/share/icons/hicolor/32x32/apps/chromium.png 24 | chrome/app/theme/chromium/product_logo_48.png => usr/share/icons/hicolor/48x48/apps/chromium.png 25 | chrome/app/theme/chromium/product_logo_64.png => usr/share/icons/hicolor/64x64/apps/chromium.png 26 | chrome/app/theme/chromium/product_logo_128.png => usr/share/icons/hicolor/128x128/apps/chromium.png 27 | chrome/app/theme/chromium/product_logo_256.png => usr/share/icons/hicolor/256x256/apps/chromium.png 28 | -------------------------------------------------------------------------------- /convert/compare.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # This script helps to review the differences between the original 4 | # (Debian) chromium and ungoogled-chromium source package trees, with 5 | # renamed files properly taken into account (unlike what "diff -ru" 6 | # would do). If an ungoogled-chromium project tree is also provided, 7 | # this script will additionally show any changes made to the patches. 8 | # 9 | # Note that this only looks at the files in the debian/ subdirectory, 10 | # because everything else comes from the original upstream source tarball 11 | # and should be exactly the same (provided no patches have been applied). 12 | # 13 | 14 | case "$#" in 15 | 2) 16 | UG_PROJECT= 17 | ORIG_CHROMIUM="$1" 18 | UG_CHROMIUM="$2" 19 | ;; 20 | 21 | 3) 22 | UG_PROJECT="$1" 23 | ORIG_CHROMIUM="$2" 24 | UG_CHROMIUM="$3" 25 | ;; 26 | 27 | *) 28 | name=$(basename $0) 29 | cat < 51 | 52 | .SH ENVIRONMENT 53 | -@@MENUNAME@@ obeys the following environment variables: 54 | +Chromium obeys the following environment variables: 55 | 56 | .TP 57 | .B all_proxy 58 | @@ -145,11 +145,11 @@ 59 | 60 | .SH FILES 61 | .TP 62 | -.I $HOME/.config/@@PACKAGE@@ 63 | +.I $HOME/.config/chromium 64 | Default directory for configuration data. 65 | 66 | .TP 67 | -.I $HOME/.cache/@@PACKAGE@@ 68 | +.I $HOME/.cache/chromium 69 | Default directory for cache data. (Why? See 70 | .) 71 | 72 | --- a/chrome/installer/linux/common/chromium-browser/chromium-browser.appdata.xml 73 | +++ b/chrome/installer/linux/common/chromium-browser/chromium-browser.appdata.xml 74 | @@ -1,8 +1,6 @@ 75 | - 76 | 77 | 78 | - chromium-browser.desktop 79 | - chromium-dev@chromium.org 80 | + chromium.desktop 81 | CC0-1.0 82 | BSD-3-Clause and LGPL-2.1+ and Apache-2.0 and IJG and MIT and GPL-2.0+ and ISC and OpenSSL and (MPL-1.1 or GPL-2.0 or LGPL-2.0) 83 | Chromium Web Browser 84 | @@ -12,17 +10,8 @@ 85 | Chromium is an open-source browser project that aims to build a safer, faster, 86 | and more stable way to experience the web. 87 |

88 | -

89 | - We invite you to join our effort to build a powerful platform for developing a 90 | - new generation of web applications. 91 | -

92 | -

93 | - Chromium supports Vorbis, Theora, WebM and HTML5 audio and video standards, but 94 | - does not include the non-free AAC, H.264, MP3 or Adobe Flash code that is found 95 | - in Chrome. 96 | -

97 | 98 | https://www.chromium.org/Home 99 | 100 | 101 | https://www.gstatic.com/chrome/appstream/chrome-2.png 102 | --- a/chrome/installer/linux/common/desktop.template 103 | +++ b/chrome/installer/linux/common/desktop.template 104 | @@ -1,6 +1,6 @@ 105 | [Desktop Entry] 106 | Version=1.0 107 | -Name=@@MENUNAME@@ 108 | +Name=Chromium 109 | # Only KDE 4 seems to use GenericName, so we reuse the KDE strings. 110 | # From Ubuntu's language-pack-kde-XX-base packages, version 9.04-20090413. 111 | GenericName=Web Browser 112 | @@ -105,10 +105,10 @@ 113 | Comment[zh_CN]=访问互联网 114 | Comment[zh_HK]=連線到網際網路 115 | Comment[zh_TW]=連線到網際網路 116 | -Exec=/usr/bin/@@USR_BIN_SYMLINK_NAME@@ %U 117 | +Exec=/usr/bin/chromium %U 118 | StartupNotify=true 119 | Terminal=false 120 | -Icon=@@PACKAGE@@ 121 | +Icon=chromium 122 | Type=Application 123 | Categories=Network;WebBrowser; 124 | MimeType=application/pdf;application/rdf+xml;application/rss+xml;application/xhtml+xml;application/xhtml_xml;application/xml;image/gif;image/jpeg;image/png;image/webp;text/html;text/xml;x-scheme-handler/http;x-scheme-handler/https; 125 | @@ -166,7 +166,7 @@ 126 | Name[vi]=Cửa sổ Mới 127 | Name[zh_CN]=新建窗口 128 | Name[zh_TW]=開新視窗 129 | -Exec=/usr/bin/@@USR_BIN_SYMLINK_NAME@@ 130 | +Exec=/usr/bin/chromium 131 | 132 | [Desktop Action new-private-window] 133 | Name=New Incognito Window 134 | @@ -218,4 +218,4 @@ 135 | Name[vi]=Cửa sổ ẩn danh mới 136 | Name[zh_CN]=新建隐身窗口 137 | Name[zh_TW]=新增無痕式視窗 138 | -Exec=/usr/bin/@@USR_BIN_SYMLINK_NAME@@ --incognito 139 | ++Exec=/usr/bin/chromium --incognito 140 | -------------------------------------------------------------------------------- /.github/workflows/obs-upload.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | RT_DIR="$PWD" 5 | DB_DIR="$RT_DIR/debian" 6 | UC_DIR="$DB_DIR/submodules/ungoogled-chromium" 7 | 8 | for i in OBS_API_USERNAME OBS_API_PASSWORD 9 | do 10 | if test -z "$(eval echo \$$i)" 11 | then 12 | echo "$i is not in the environment. Aborting." 13 | exit 1 14 | fi 15 | done 16 | 17 | PROJECT="${OBS_API_PROJECT:-home:$OBS_API_USERNAME}" 18 | 19 | case "$GITHUB_EVENT_NAME" in 20 | workflow_dispatch) REPOSITORY="$PROJECT:testing" ;; 21 | push) REPOSITORY="$PROJECT" ;; 22 | *) echo "Not running as part of a GitHub workflow. Aborting."; exit 1 ;; 23 | esac 24 | 25 | curl() 26 | { 27 | for i in `seq 1 5` 28 | do 29 | { 30 | command curl -sS -K - "$@" << EOF 31 | user="$OBS_API_USERNAME:$OBS_API_PASSWORD" 32 | EOF 33 | } && return 0 || sleep 30s 34 | done 35 | return 1 36 | } 37 | 38 | debian/rules changelog control 39 | 40 | read UC_VERSION < $UC_DIR/chromium_version.txt 41 | AUTHOR=`grep 'AUTHOR *:=' $DB_DIR/rules | cut -f 2 -d '=' | sed -r 's;^ *| *$;;g'` 42 | NODE_VERSION=`grep 'NODE_VERSION *:=' $DB_DIR/rules | cut -f 2 -d '=' | sed -r 's;^ *| *$;;g'` 43 | 44 | cat > _service << EOF 45 | 46 | 47 | https://commondatastorage.googleapis.com/chromium-browser-official/chromium-$UC_VERSION.tar.xz 48 | 49 | 50 | https://commondatastorage.googleapis.com/chromium-browser-official/chromium-$UC_VERSION.tar.xz.hashes 51 | 52 | 53 | https://nodejs.org/dist/$NODE_VERSION/node-$NODE_VERSION-linux-x64.tar.xz 54 | 55 | 56 | https://nodejs.org/dist/$NODE_VERSION/node-$NODE_VERSION-linux-armv7l.tar.xz 57 | 58 | 59 | https://nodejs.org/dist/$NODE_VERSION/node-$NODE_VERSION-linux-arm64.tar.xz 60 | 61 | 62 | https://nodejs.org/dist/$NODE_VERSION/SHASUMS256.txt 63 | node-$NODE_VERSION.sha256sum 64 | 65 | 66 | EOF 67 | 68 | tar -c -T/dev/null | xz -9 > ungoogled-chromium_$UC_VERSION.orig.tar.xz 69 | tar -c -T/dev/null | xz -9 > ungoogled-chromium_$UC_VERSION.debian.tar.xz 70 | tar -c --exclude-vcs --exclude='download_cache/*' -C $RT_DIR debian/ | xz -9 > ungoogled-chromium.tar.xz 71 | 72 | cat > ungoogled-chromium.dsc << EOF 73 | Format: 3.0 (quilt) 74 | Source: ungoogled-chromium 75 | Binary: ungoogled-chromium 76 | Architecture: any 77 | Version: $UC_VERSION 78 | Maintainer: $AUTHOR 79 | Homepage: https://github.com/Eloston/ungoogled-chromium 80 | Standards-Version: 4.5.0 81 | Build-Depends: $(sed -n '/^Build-Depends:/,/^$/p' < $DB_DIR/control | tr -d '\n' | cut -f 2 -d : | sed -r 's;^ *| *$;;g') 82 | Package-List: 83 | ungoogled-chromium deb web optional arch=any 84 | Checksums-Sha1: 85 | $(sha1sum < ungoogled-chromium_$UC_VERSION.orig.tar.xz | cut -f 1 -d ' ') $(stat -c '%s' ungoogled-chromium_$UC_VERSION.orig.tar.xz) ungoogled-chromium_$UC_VERSION.orig.tar.xz 86 | $(sha1sum < ungoogled-chromium_$UC_VERSION.debian.tar.xz | cut -f 1 -d ' ') $(stat -c '%s' ungoogled-chromium_$UC_VERSION.debian.tar.xz) ungoogled-chromium_$UC_VERSION.debian.tar.xz 87 | Checksums-Sha256: 88 | $(sha256sum < ungoogled-chromium_$UC_VERSION.orig.tar.xz | cut -f 1 -d ' ') $(stat -c '%s' ungoogled-chromium_$UC_VERSION.orig.tar.xz) ungoogled-chromium_$UC_VERSION.orig.tar.xz 89 | $(sha256sum < ungoogled-chromium_$UC_VERSION.debian.tar.xz | cut -f 1 -d ' ') $(stat -c '%s' ungoogled-chromium_$UC_VERSION.debian.tar.xz) ungoogled-chromium_$UC_VERSION.debian.tar.xz 90 | Files: 91 | $(md5sum < ungoogled-chromium_$UC_VERSION.orig.tar.xz | cut -f 1 -d ' ') $(stat -c '%s' ungoogled-chromium_$UC_VERSION.orig.tar.xz) ungoogled-chromium_$UC_VERSION.orig.tar.xz 92 | $(md5sum < ungoogled-chromium_$UC_VERSION.debian.tar.xz | cut -f 1 -d ' ') $(stat -c '%s' ungoogled-chromium_$UC_VERSION.debian.tar.xz) ungoogled-chromium_$UC_VERSION.debian.tar.xz 93 | EOF 94 | 95 | cat > build.script << EOF 96 | export LANG=C.UTF-8 97 | 98 | JOBS="\${DEB_BUILD_OPTIONS#*=}" 99 | case "\$(uname -m)" in 100 | aarch64) DEB_BUILD_OPTIONS="parallel=\$(("\$JOBS" / 2))" ;; 101 | esac 102 | JOBS= 103 | 104 | tar -x -f ../SOURCES/ungoogled-chromium.tar.xz 105 | mkdir -p debian/download_cache 106 | ln -s ../../../SOURCES/chromium-$UC_VERSION.tar.xz debian/download_cache/chromium-$UC_VERSION.tar.xz 107 | ln -s ../../../SOURCES/chromium-$UC_VERSION.tar.xz.hashes debian/download_cache/chromium-$UC_VERSION.tar.xz.hashes 108 | ln -s ../../../SOURCES/node-$NODE_VERSION-linux-x64.tar.xz debian/download_cache/node-$NODE_VERSION-linux-x64.tar.xz 109 | ln -s ../../../SOURCES/node-$NODE_VERSION-linux-armv7l.tar.xz debian/download_cache/node-$NODE_VERSION-linux-armv7l.tar.xz 110 | ln -s ../../../SOURCES/node-$NODE_VERSION-linux-arm64.tar.xz debian/download_cache/node-$NODE_VERSION-linux-arm64.tar.xz 111 | ln -s ../../../SOURCES/node-$NODE_VERSION.sha256sum debian/download_cache/node-$NODE_VERSION.sha256sum 112 | 113 | debian/rules setup 114 | 115 | dpkg-buildpackage -b -uc 116 | EOF 117 | 118 | PACKAGE="ungoogled-chromium-debian" 119 | 120 | curl "https://api.opensuse.org/source/$REPOSITORY/$PACKAGE" -F 'cmd=deleteuploadrev' 121 | 122 | curl "https://api.opensuse.org/source/$REPOSITORY/$PACKAGE" > directory.xml 123 | 124 | xmlstarlet sel -t -v '//entry/@name' < directory.xml | while read FILENAME 125 | do 126 | curl "https://api.opensuse.org/source/$REPOSITORY/$PACKAGE/$FILENAME?rev=upload" -X DELETE 127 | done 128 | 129 | for FILENAME in _service ungoogled-chromium_$UC_VERSION.orig.tar.xz ungoogled-chromium_$UC_VERSION.debian.tar.xz ungoogled-chromium.tar.xz ungoogled-chromium.dsc build.script 130 | do 131 | curl "https://api.opensuse.org/source/$REPOSITORY/$PACKAGE/$FILENAME?rev=upload" -T "$FILENAME" 132 | done 133 | 134 | curl "https://api.opensuse.org/source/$REPOSITORY/$PACKAGE" -F 'cmd=commit' 135 | 136 | rm -f _service ungoogled-chromium_$UC_VERSION.orig.tar.xz ungoogled-chromium_$UC_VERSION.debian.tar.xz ungoogled-chromium.tar.xz ungoogled-chromium.dsc build.script directory.xml 137 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | RT_DIR := $(CURDIR) 4 | DB_DIR := $(RT_DIR)/debian 5 | SH_DIR := $(DB_DIR)/shims 6 | CL_DIR := $(DB_DIR)/submodules/chromium-launcher 7 | UC_DIR := $(DB_DIR)/submodules/ungoogled-chromium 8 | UL_DIR := $(UC_DIR)/utils 9 | UP_DIR := $(UC_DIR)/patches 10 | DL_CACHE := $(DB_DIR)/download_cache 11 | DS_CACHE := $(DB_DIR)/domsubcache.tar.gz 12 | OUT_DIR := out/Release 13 | 14 | # Changelog and control template variables 15 | VERSION := $(file < $(UC_DIR)/chromium_version.txt)-1 16 | RELEASE := bookworm 17 | AUTHOR := ungoogled-chromium Maintainers 18 | DATETIME := $(shell date -R) 19 | 20 | # Assign the clang toolchain to use 21 | LLVM_VERSION ?= 16 22 | export AR := llvm-ar-$(LLVM_VERSION) 23 | export NM := llvm-nm-$(LLVM_VERSION) 24 | export CC := clang-$(LLVM_VERSION) 25 | export CXX := clang++-$(LLVM_VERSION) 26 | 27 | # Setup compiler and linkers flags 28 | export DEB_BUILD_MAINT_OPTIONS := hardening=+all optimize=-lto 29 | export DEB_CXXFLAGS_MAINT_STRIP := -g 30 | export CXXFLAGS := $(shell dpkg-buildflags --get CXXFLAGS) \ 31 | -Wno-unknown-warning-option \ 32 | -Wno-deprecated-declarations 33 | export CFLAGS := $(CXXFLAGS) 34 | 35 | # Use parallel jobs if requested 36 | ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) 37 | JOBS := $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) 38 | else 39 | JOBS := 1 40 | endif 41 | 42 | # Version of node to install 43 | NODE_VERSION := v16.13.0 44 | 45 | # Find the distribution codename for this release 46 | CODENAME := $(patsubst %:,,$(shell lsb_release -c)) 47 | 48 | # Start with the upstream Ungoogled Chromium flags 49 | GN_FLAGS := $(shell tr "\n" " " < $(UC_DIR)/flags.gn | sed 's/"/\\"/g') 50 | 51 | # Add our downstream Debian flags 52 | GN_FLAGS += \ 53 | custom_toolchain=\"//build/toolchain/linux/unbundle:default\" \ 54 | host_toolchain=\"//build/toolchain/linux/unbundle:default\" \ 55 | use_custom_libcxx=false \ 56 | is_official_build=true \ 57 | is_debug=false \ 58 | symbol_level=1 \ 59 | blink_enable_generated_code_formatting=false \ 60 | is_cfi=false \ 61 | use_thin_lto=false \ 62 | use_sysroot=false \ 63 | ffmpeg_branding=\"Chrome\" \ 64 | proprietary_codecs=true \ 65 | use_pulseaudio=true \ 66 | link_pulseaudio=true \ 67 | use_vaapi=true \ 68 | use_ozone=true \ 69 | use_goma=false \ 70 | enable_vr=false \ 71 | enable_iterator_debugging=false \ 72 | optimize_webui=true \ 73 | use_gio=true \ 74 | use_lld=true \ 75 | is_clang=true \ 76 | use_kerberos=false \ 77 | use_cups=true \ 78 | v8_enable_backtrace=true \ 79 | enable_rust=false \ 80 | 81 | # Currently omitted from base (jammy): icu, harfbuzz-ng, ffmpeg, openh264, libvpx 82 | SYS_LIBS := \ 83 | flac \ 84 | fontconfig \ 85 | freetype \ 86 | jsoncpp \ 87 | libdrm \ 88 | libevent \ 89 | libjpeg \ 90 | libpng \ 91 | libwebp \ 92 | libxml \ 93 | libxslt \ 94 | opus \ 95 | snappy \ 96 | zlib \ 97 | 98 | # Add extra flags for system libs 99 | GN_FLAGS += \ 100 | perfetto_use_system_zlib=true \ 101 | use_system_lcms2=true \ 102 | use_system_libopenjpeg2=true \ 103 | use_system_libpng=true \ 104 | use_system_zlib=true \ 105 | use_system_libjpeg=true \ 106 | use_system_libtiff=true \ 107 | 108 | %: 109 | dh $@ 110 | 111 | changelog: 112 | sed -e "s;@@VERSION@@;$(VERSION);g" -e "s;@@RELEASE@@;$(RELEASE);g" -e "s;@@AUTHOR@@;$(AUTHOR);g" -e "s;@@DATETIME@@;$(DATETIME);g" < $(DB_DIR)/changelog.in > $(DB_DIR)/changelog 113 | 114 | control: 115 | sed -e "s;@@AUTHOR@@;$(AUTHOR);g" < $(DB_DIR)/control.in > $(DB_DIR)/control 116 | 117 | download: 118 | mkdir -p $(DL_CACHE) 119 | $(UL_DIR)/downloads.py retrieve -i $(UC_DIR)/downloads.ini -c $(DL_CACHE) 120 | test -f $(DL_CACHE)/node-$(NODE_VERSION)-linux-x64.tar.xz || curl "https://nodejs.org/dist/$(NODE_VERSION)/node-$(NODE_VERSION)-linux-x64.tar.xz" -o $(DL_CACHE)/node-$(NODE_VERSION)-linux-x64.tar.xz 121 | test -f $(DL_CACHE)/node-$(NODE_VERSION)-linux-armv7l.tar.xz || curl "https://nodejs.org/dist/$(NODE_VERSION)/node-$(NODE_VERSION)-linux-armv7l.tar.xz" -o $(DL_CACHE)/node-$(NODE_VERSION)-linux-armv7l.tar.xz 122 | test -f $(DL_CACHE)/node-$(NODE_VERSION)-linux-arm64.tar.xz || curl "https://nodejs.org/dist/$(NODE_VERSION)/node-$(NODE_VERSION)-linux-arm64.tar.xz" -o $(DL_CACHE)/node-$(NODE_VERSION)-linux-arm64.tar.xz 123 | test -f $(DL_CACHE)/node-$(NODE_VERSION).sha256sum || curl "https://nodejs.org/dist/$(NODE_VERSION)/SHASUMS256.txt" -o $(DL_CACHE)/node-$(NODE_VERSION).sha256sum 124 | cd $(DL_CACHE); sha256sum --ignore-missing -c node-$(NODE_VERSION).sha256sum 125 | 126 | setup: changelog control download 127 | test ! -d $(RT_DIR)/.git || git clean -xfd -e debian/changelog -e debian/control -e debian/download_cache/ 128 | $(UL_DIR)/downloads.py unpack -i $(UC_DIR)/downloads.ini -c $(DL_CACHE) $(RT_DIR) 129 | $(UL_DIR)/prune_binaries.py $(RT_DIR) $(UC_DIR)/pruning.list 130 | for lib in $(subst libevent,,$(subst libjpeg,libjpeg_turbo,$(SYS_LIBS))); do find "third_party/$$lib" -type f ! -path "third_party/$$lib/chromium/*" ! -path "third_party/$$lib/google/*" ! -name "*.gn" ! -name "*.gni" ! -name "*.isolate" -delete; done 131 | tar -C third_party/node/linux -xf $(DL_CACHE)/node-$(NODE_VERSION)-linux-x64.tar.xz --transform=s/^node-$(NODE_VERSION)-linux-x64/node-linux-x64/ 132 | tar -C third_party/node/linux -xf $(DL_CACHE)/node-$(NODE_VERSION)-linux-armv7l.tar.xz --transform=s/^node-$(NODE_VERSION)-linux-armv7l/node-linux-armv7l/ 133 | tar -C third_party/node/linux -xf $(DL_CACHE)/node-$(NODE_VERSION)-linux-arm64.tar.xz --transform=s/^node-$(NODE_VERSION)-linux-arm64/node-linux-arm64/ 134 | 135 | override_dh_auto_configure: 136 | $(UL_DIR)/patches.py apply $(RT_DIR) $(UP_DIR) 137 | $(UL_DIR)/domain_substitution.py apply -r $(UC_DIR)/domain_regex.list -f $(UC_DIR)/domain_substitution.list -c $(DS_CACHE) $(RT_DIR) 138 | cp $(SH_DIR)/jsoncpp.gn build/linux/unbundle 139 | build/linux/unbundle/replace_gn_files.py --system-libraries $(SYS_LIBS) 140 | 141 | override_dh_auto_build: 142 | gn gen $(OUT_DIR) --args="$(GN_FLAGS)" --fail-on-unused-args 143 | ninja -j $(JOBS) -C $(OUT_DIR) chrome chrome_sandbox chromedriver 144 | make -C $(CL_DIR) CFLAGS="$(CFLAGS) -pie -fPIE" CHROMIUM_BINARY=/usr/lib/chromium/chrome chromium 145 | 146 | override_dh_prep: 147 | for file in `find -name "*.gn.orig" -o -name "*.gni.orig"`; do mv $$file $${file%.orig}; done 148 | rm -f build/linux/unbundle/jsoncpp.gn 149 | $(UL_DIR)/domain_substitution.py revert -c $(DS_CACHE) $(RT_DIR) 150 | for patch in `tac $(UP_DIR)/series`; do printf "Info: Reverting %s...\n" $$patch; patch -RNp1 -i $(UP_DIR)/$$patch; done 151 | dh_prep 152 | 153 | override_dh_fixperms: 154 | dh_fixperms --exclude chrome_sandbox 155 | 156 | override_dh_auto_clean: 157 | rm -rf out 158 | make -C $(CL_DIR) clean 159 | find -name "*.pyc" -delete 160 | dh_auto_clean 161 | -------------------------------------------------------------------------------- /debian/patches/sql-virtual-cursor.patch: -------------------------------------------------------------------------------- 1 | description: In order to build w/ libstdc++ >= 11 and clang, this patch is needed. 2 | author: https://bugs.gentoo.org/786597#c14 3 | --- a/sql/recover_module/btree.cc 4 | +++ b/sql/recover_module/btree.cc 5 | @@ -136,16 +136,25 @@ static_assert(std::is_trivially_destruct 6 | "Move the destructor to the .cc file if it's non-trival"); 7 | #endif // !DCHECK_IS_ON() 8 | 9 | -LeafPageDecoder::LeafPageDecoder(DatabasePageReader* db_reader) noexcept 10 | - : page_id_(db_reader->page_id()), 11 | - db_reader_(db_reader), 12 | - cell_count_(ComputeCellCount(db_reader)), 13 | - next_read_index_(0), 14 | - last_record_size_(0) { 15 | +void LeafPageDecoder::Initialize(DatabasePageReader* db_reader) { 16 | + DCHECK(db_reader); 17 | DCHECK(IsOnValidPage(db_reader)); 18 | + page_id_ = db_reader->page_id(); 19 | + db_reader_ = db_reader; 20 | + cell_count_ = ComputeCellCount(db_reader); 21 | + next_read_index_ = 0; 22 | + last_record_size_ = 0; 23 | DCHECK(DatabasePageReader::IsValidPageId(page_id_)); 24 | } 25 | 26 | +void LeafPageDecoder::Reset() { 27 | + db_reader_ = nullptr; 28 | + page_id_ = 0; 29 | + cell_count_ = 0; 30 | + next_read_index_ = 0; 31 | + last_record_size_ = 0; 32 | +} 33 | + 34 | bool LeafPageDecoder::TryAdvance() { 35 | DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 36 | DCHECK(CanAdvance()); 37 | --- a/sql/recover_module/btree.h 38 | +++ b/sql/recover_module/btree.h 39 | @@ -106,7 +106,7 @@ class LeafPageDecoder { 40 | // 41 | // |db_reader| must have been used to read an inner page of a table B-tree. 42 | // |db_reader| must outlive this instance. 43 | - explicit LeafPageDecoder(DatabasePageReader* db_reader) noexcept; 44 | + explicit LeafPageDecoder() noexcept = default; 45 | ~LeafPageDecoder() noexcept = default; 46 | 47 | LeafPageDecoder(const LeafPageDecoder&) = delete; 48 | @@ -154,6 +154,15 @@ class LeafPageDecoder { 49 | // read as long as CanAdvance() returns true. 50 | bool TryAdvance(); 51 | 52 | + // Initialize with DatabasePageReader 53 | + void Initialize(DatabasePageReader* db_reader); 54 | + 55 | + // Reset internal DatabasePageReader 56 | + void Reset(); 57 | + 58 | + // True if DatabasePageReader is valid 59 | + bool IsValid() { return (db_reader_ != nullptr); } 60 | + 61 | // True if the given reader may point to an inner page in a table B-tree. 62 | // 63 | // The last ReadPage() call on |db_reader| must have succeeded. 64 | @@ -167,16 +176,16 @@ class LeafPageDecoder { 65 | static int ComputeCellCount(DatabasePageReader* db_reader); 66 | 67 | // The number of the B-tree page this reader is reading. 68 | - const int64_t page_id_; 69 | + int64_t page_id_; 70 | // Used to read the tree page. 71 | // 72 | // Raw pointer usage is acceptable because this instance's owner is expected 73 | // to ensure that the DatabasePageReader outlives this. 74 | // This field is not a raw_ptr<> because it caused a 75 | // std::is_trivially_destructible static_assert failure. 76 | - RAW_PTR_EXCLUSION DatabasePageReader* const db_reader_; 77 | + RAW_PTR_EXCLUSION DatabasePageReader* db_reader_; 78 | // Caches the ComputeCellCount() value for this reader's page. 79 | - const int cell_count_ = ComputeCellCount(db_reader_); 80 | + int cell_count_; 81 | 82 | // The reader's cursor state. 83 | // 84 | --- a/sql/recover_module/cursor.cc 85 | +++ b/sql/recover_module/cursor.cc 86 | @@ -28,7 +28,7 @@ VirtualCursor::~VirtualCursor() { 87 | int VirtualCursor::First() { 88 | DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 89 | inner_decoders_.clear(); 90 | - leaf_decoder_ = nullptr; 91 | + leaf_decoder_.Reset(); 92 | 93 | AppendPageDecoder(table_->root_page_id()); 94 | return Next(); 95 | @@ -38,18 +38,18 @@ int VirtualCursor::Next() { 96 | DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 97 | record_reader_.Reset(); 98 | 99 | - while (!inner_decoders_.empty() || leaf_decoder_.get()) { 100 | - if (leaf_decoder_.get()) { 101 | - if (!leaf_decoder_->CanAdvance()) { 102 | + while (!inner_decoders_.empty() || leaf_decoder_.IsValid()) { 103 | + if (leaf_decoder_.IsValid()) { 104 | + if (!leaf_decoder_.CanAdvance()) { 105 | // The leaf has been exhausted. Remove it from the DFS stack. 106 | - leaf_decoder_ = nullptr; 107 | + leaf_decoder_.Reset(); 108 | continue; 109 | } 110 | - if (!leaf_decoder_->TryAdvance()) 111 | + if (!leaf_decoder_.TryAdvance()) 112 | continue; 113 | 114 | - if (!payload_reader_.Initialize(leaf_decoder_->last_record_size(), 115 | - leaf_decoder_->last_record_offset())) { 116 | + if (!payload_reader_.Initialize(leaf_decoder_.last_record_size(), 117 | + leaf_decoder_.last_record_offset())) { 118 | continue; 119 | } 120 | if (!record_reader_.Initialize()) 121 | @@ -101,13 +101,13 @@ int VirtualCursor::ReadColumn(int column 122 | int64_t VirtualCursor::RowId() { 123 | DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 124 | DCHECK(record_reader_.IsInitialized()); 125 | - DCHECK(leaf_decoder_.get()); 126 | - return leaf_decoder_->last_record_rowid(); 127 | + DCHECK(leaf_decoder_.IsValid()); 128 | + return leaf_decoder_.last_record_rowid(); 129 | } 130 | 131 | void VirtualCursor::AppendPageDecoder(int page_id) { 132 | DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 133 | - DCHECK(leaf_decoder_.get() == nullptr) 134 | + DCHECK(!leaf_decoder_.IsValid()) 135 | << __func__ 136 | << " must only be called when the current path has no leaf decoder"; 137 | 138 | @@ -115,7 +115,7 @@ void VirtualCursor::AppendPageDecoder(in 139 | return; 140 | 141 | if (LeafPageDecoder::IsOnValidPage(&db_reader_)) { 142 | - leaf_decoder_ = std::make_unique(&db_reader_); 143 | + leaf_decoder_.Initialize(&db_reader_); 144 | return; 145 | } 146 | 147 | --- a/sql/recover_module/cursor.h 148 | +++ b/sql/recover_module/cursor.h 149 | @@ -128,7 +128,7 @@ class VirtualCursor { 150 | std::vector> inner_decoders_; 151 | 152 | // Decodes the leaf page containing records. 153 | - std::unique_ptr leaf_decoder_; 154 | + LeafPageDecoder leaf_decoder_; 155 | 156 | SEQUENCE_CHECKER(sequence_checker_); 157 | }; 158 | --- a/sql/recover_module/pager.cc 159 | +++ b/sql/recover_module/pager.cc 160 | @@ -23,8 +23,7 @@ static_assert(DatabasePageReader::kMaxPa 161 | "ints are not appropriate for representing page IDs"); 162 | 163 | DatabasePageReader::DatabasePageReader(VirtualTable* table) 164 | - : page_data_(std::make_unique(table->page_size())), 165 | - table_(table) { 166 | + : page_data_(), table_(table) { 167 | DCHECK(table != nullptr); 168 | DCHECK(IsValidPageSize(table->page_size())); 169 | } 170 | @@ -57,8 +56,8 @@ int DatabasePageReader::ReadPage(int pag 171 | std::numeric_limits::max(), 172 | "The |read_offset| computation above may overflow"); 173 | 174 | - int sqlite_status = 175 | - RawRead(sqlite_file, read_size, read_offset, page_data_.get()); 176 | + int sqlite_status = RawRead(sqlite_file, read_size, read_offset, 177 | + const_cast(page_data_.data())); 178 | 179 | // |page_id_| needs to be set to kInvalidPageId if the read failed. 180 | // Otherwise, future ReadPage() calls with the previous |page_id_| value 181 | --- a/sql/recover_module/pager.h 182 | +++ b/sql/recover_module/pager.h 183 | @@ -5,6 +5,7 @@ 184 | #ifndef SQL_RECOVER_MODULE_PAGER_H_ 185 | #define SQL_RECOVER_MODULE_PAGER_H_ 186 | 187 | +#include 188 | #include 189 | #include 190 | #include 191 | @@ -72,7 +73,7 @@ class DatabasePageReader { 192 | DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 193 | DCHECK_NE(page_id_, kInvalidPageId) 194 | << "Successful ReadPage() required before accessing pager state"; 195 | - return page_data_.get(); 196 | + return page_data_.data(); 197 | } 198 | 199 | // The number of bytes in the page read by the last ReadPage() call. 200 | @@ -139,7 +140,7 @@ class DatabasePageReader { 201 | int page_id_ = kInvalidPageId; 202 | // Stores the bytes of the last page successfully read by ReadPage(). 203 | // The content is undefined if the last call to ReadPage() did not succeed. 204 | - const std::unique_ptr page_data_; 205 | + const std::array page_data_; 206 | // Raw pointer usage is acceptable because this instance's owner is expected 207 | // to ensure that the VirtualTable outlives this. 208 | const raw_ptr table_; 209 | -------------------------------------------------------------------------------- /convert/Makefile: -------------------------------------------------------------------------------- 1 | # convert/Makefile 2 | # This makefile requires GNU Make. 3 | 4 | # Version of and paths to pristine Debian Chromium source tree + tarball, 5 | # obtainable by running "apt-get source chromium" on a Debian system 6 | # 7 | VERSION = 143.0.7499.40 8 | ORIG_SOURCE = chromium-$(VERSION) 9 | ORIG_TARBALL = chromium_$(VERSION).orig.tar.xz 10 | 11 | # Uncomment this if you wish to modify $(ORIG_SOURCE), otherwise the 12 | # conversion process will operate on a copy. 13 | # 14 | #INPLACE = 1 15 | 16 | # Path to local ungoogled-chromium Git repo 17 | # https://github.com/ungoogled-software/ungoogled-chromium 18 | # 19 | UNGOOGLED = $(PWD)/ungoogled-chromium 20 | UNGOOGLED_PATCHES = $(UNGOOGLED)/patches 21 | 22 | # Path to convert/ subdir of ungoogled-chromium-debian Git repo 23 | # https://github.com/ungoogled-software/ungoogled-chromium-debian 24 | # (where this makefile comes from) 25 | # 26 | DEBIAN_CONVERT = . 27 | 28 | # Append this to the Debian package version string 29 | # 30 | ADD_VERSION_SUFFIX = 31 | 32 | # Target distribution (e.g. bookworm, jammy) 33 | # If unset, the distribution will be set to UNRELEASED. 34 | # 35 | DISTRIBUTION = jammy 36 | 37 | # Uncomment this if you are converting the Debian stable release of 38 | # Chromium. It sometimes requires (slightly) different settings. 39 | # 40 | #DEBIAN_STABLE = 1 41 | 42 | # Package maintainer (i.e. you) contact info 43 | # 44 | export DEBFULLNAME ?= Emmanuel Goldstein 45 | export DEBEMAIL ?= cereal@example.com 46 | 47 | # List of patches to drop from the patch series to avoid conflicts. 48 | # This list should be as short as possible; run the check-patch-drop-list 49 | # target to verify this. 50 | # 51 | PATCH_DROP_LIST = 52 | 53 | # The edits in this patch are included in 54 | # ungoogled-upstream/core/ungoogled-chromium/fix-building-with-prunned-binaries.patch 55 | # 56 | PATCH_DROP_LIST += disable/tests.patch 57 | 58 | # One unapplied edit (inline_login_handler_impl.cc) and one conflicting 59 | # edit (primary_account_manager.cc) vis-a-vis 60 | # ungoogled-upstream/core/ungoogled-chromium/remove-unused-preferences-fields.patch 61 | # 62 | PATCH_DROP_LIST += disable/signin.patch 63 | 64 | # Edit is included in 65 | # ungoogled-upstream/extra/inox-patchset/0006-modify-default-prefs.patch 66 | # 67 | PATCH_DROP_LIST += disable/third-party-cookies.patch 68 | 69 | # Debian's imported copy of 70 | # ungoogled-upstream/core/ungoogled-chromium/disable-privacy-sandbox.patch 71 | # 72 | PATCH_DROP_LIST += ungoogled/disable-privacy-sandbox.patch 73 | 74 | # Ungoogled-chromium's imported copy of 75 | # disable/google-api-warning.patch 76 | # 77 | PATCH_DROP_LIST += ungoogled-upstream/extra/debian/disable/google-api-warning.patch 78 | 79 | ifdef DEBIAN_STABLE 80 | # No additional patches to drop at this time 81 | #PATCH_DROP_LIST += 82 | endif 83 | 84 | # quilt(1) setup 85 | # 86 | QUILT = quilt --quiltrc /dev/null 87 | export QUILT_DIFF_OPTS = -p 88 | export QUILT_PATCHES = debian/patches 89 | export QUILT_REFRESH_ARGS = -p ab --no-index --no-timestamps 90 | 91 | TIME = env time -p 92 | 93 | orig_changelog = $(ORIG_SOURCE)/debian/changelog 94 | ifneq ($(wildcard $(orig_changelog)),) 95 | debian_version := $(shell dpkg-parsechangelog --file $(orig_changelog) --show-field Version) 96 | ifndef URGENCY 97 | URGENCY := $(shell dpkg-parsechangelog --file $(orig_changelog) --show-field Urgency) 98 | endif 99 | endif 100 | 101 | ################ 102 | 103 | work := $(shell pwd) 104 | 105 | ifdef INPLACE 106 | ug_source = $(ORIG_SOURCE) 107 | else 108 | ug_source = ungoogled-chromium-src 109 | endif 110 | 111 | ug_tarball = ungoogled-chromium_$(VERSION).orig.tar.xz 112 | 113 | # These are used to symbolically specify a dependency on a certain 114 | # variant of Chromium source tree 115 | # 116 | orig_tree_dep = $(ORIG_SOURCE)/debian/source/format 117 | ug_tree_dep = $(ug_source)/debian/source/format 118 | 119 | # Avoid weird locale-dependent sort orders 120 | # 121 | export LC_COLLATE = C 122 | 123 | # A bit of tooling around quilt(1) to apply all patches and automatically 124 | # refresh the ones which need it (unlike "quilt push -a --refresh", which 125 | # refreshes everything unconditionally) 126 | # 127 | # https://savannah.nongnu.org/bugs/?63986 128 | # 129 | quilt_auto_refresh = \ 130 | while :; do \ 131 | (set -x; $(QUILT) push -afq --fuzz=0) | tee tmp.quilt.out; \ 132 | ! grep -q 'FAILED -- saving rejects' tmp.quilt.out || exit; \ 133 | if tail -n 1 tmp.quilt.out | grep -q 'forced; needs refresh'; then \ 134 | (set -x; $(QUILT) refresh) || exit; \ 135 | else \ 136 | tail -n 1 tmp.quilt.out | grep -q '^Now at patch' || exit; \ 137 | break; \ 138 | fi; \ 139 | done \ 140 | && rm -f tmp.quilt.out 141 | 142 | ################ 143 | 144 | .PHONY: all 145 | all: convert source-package 146 | 147 | .PHONY: convert 148 | convert: stage-5.stamp 149 | 150 | .PHONY: source-package 151 | source-package: stage-6.stamp 152 | 153 | # Stage 1 154 | # 155 | # * Create a new ungoogled-chromium source tree 156 | # * Copy in the ungoogled-chromium patches 157 | # * Append the ungoogled-chromium patches to the patch series 158 | # 159 | stage-1.stamp: $(orig_tree_dep) series.add 160 | test ! -f stage-2.stamp 161 | @$(MAKE) -f $(lastword $(MAKEFILE_LIST)) check-git_warning 162 | ifndef INPLACE 163 | # Note: Can't speed this up using hardlinks, alas: 164 | # https://savannah.nongnu.org/bugs/?63994 165 | rsync -a --inplace --delete $(ORIG_SOURCE)/ $(ug_source) 166 | endif 167 | touch $(ug_source)/__UNGOOGLED_CHROMIUM_CONVERSION_INCOMPLETE__ 168 | cp -a $(UNGOOGLED_PATCHES) $(ug_source)/debian/patches/ungoogled-upstream 169 | rm -f $(ug_source)/debian/patches/ungoogled/series 170 | cat series.add >>$(ug_source)/debian/patches/series 171 | touch $@ 172 | 173 | # Stage 2 174 | # 175 | # * Back out any/all applied patches in the source tree 176 | # * Comment out the patches in PATCH_DROP_LIST from the series 177 | # * Apply and refresh all patches (this should consist mainly of removing 178 | # u-c hunks that refer to files absent from the Debian tree) 179 | # 180 | # If any patches fail to apply due to file changes, then this rule 181 | # will error out. 182 | # 183 | stage-2.stamp: stage-1.stamp $(new_tree_dep) 184 | test ! -f stage-3.stamp 185 | ! grep '^#ungoogled#' $(ug_source)/debian/patches/series 186 | cd $(ug_source) && ($(QUILT) pop -afq || test $$? -eq 2) 187 | for p in $(PATCH_DROP_LIST); do \ 188 | echo "checking $$p"; \ 189 | grep -Fqx "$$p" $(ug_source)/debian/patches/series || exit; \ 190 | done 191 | for p in $(PATCH_DROP_LIST); do \ 192 | perl -pi -e '$$a=$$_; chomp($$a); $$a eq "'"$$p"'" and s/^/#ungoogled#/' \ 193 | $(ug_source)/debian/patches/series; \ 194 | done 195 | cd $(ug_source) && $(quilt_auto_refresh) 196 | touch $@ 197 | 198 | stage_3_deps = \ 199 | stage-2.stamp \ 200 | $(new_tree_dep) \ 201 | ungoogled-domain-substitution.sh \ 202 | rules.add 203 | 204 | # Stage 3 205 | # 206 | # * Add the domain-substitution script 207 | # * Append ungoogled-chromium section to debian/rules 208 | # * Hook the (un)patch targets into the "build-arch" and "clean" targets 209 | # * Add a line to rename-via-copy the chromedriver binary, as it will 210 | # be installed in /usr/bin/ and thus cannot keep the original name 211 | # * Update the package changelog 212 | # 213 | stage-3.stamp: $(stage_3_deps) 214 | test ! -f stage-4.stamp 215 | cp ungoogled-domain-substitution.sh $(ug_source)/debian/ 216 | cat rules.add >>$(ug_source)/debian/rules 217 | 218 | perl -pi \ 219 | -e '/^override_dh_auto_build-arch:/ and s/$$/ patch/;' \ 220 | -e '/^override_dh_auto_clean:/ and s/$$/ unpatch/' \ 221 | $(ug_source)/debian/rules 222 | 223 | perl -pi -e 'm,^\tcp (out/Release)/chrome_sandbox , and' \ 224 | -e '$$_.="\tcp $$1/chromedriver $$1/ungoogled-chromedriver\n"' \ 225 | $(ug_source)/debian/rules 226 | grep -q ungoogled-chromedriver $(ug_source)/debian/rules 227 | 228 | test -n '$(debian_version)' 229 | cd $(ug_source) && debchange \ 230 | --no-conf \ 231 | --package ungoogled-chromium \ 232 | --newversion $(debian_version)$(ADD_VERSION_SUFFIX) \ 233 | --force-bad-version \ 234 | $(if $(DISTRIBUTION),--distribution $(DISTRIBUTION)) \ 235 | $(if $(URGENCY),--urgency $(URGENCY)) \ 236 | --no-auto-nmu \ 237 | 'Apply ungoogled-chromium modifications.' 238 | 239 | touch $@ 240 | 241 | stage_4_deps = \ 242 | stage-3.stamp \ 243 | $(new_tree_dep) \ 244 | $(DEBIAN_CONVERT)/replace-name.pl \ 245 | $(DEBIAN_CONVERT)/editcontrol.pl 246 | 247 | # Stage 4 248 | # 249 | # * Modify the files under debian/ to refer to "ungoogled-chromium" 250 | # instead of "chromium" where appropriate. Note that we have to do 251 | # this selectively, or else things will break! 252 | # * As a special case, due to being a binary installed in /usr/bin/, 253 | # "chromedriver" needs to become "ungoogled-chromedriver". 254 | # 255 | stage-4.stamp: $(stage_4_deps) 256 | test ! -f stage-5.stamp 257 | perl -pi $(DEBIAN_CONVERT)/replace-name.pl \ 258 | $(ug_source)/debian/*.bug-control \ 259 | $(ug_source)/debian/*.desktop \ 260 | $(ug_source)/debian/*.dirs \ 261 | $(ug_source)/debian/*.install \ 262 | $(ug_source)/debian/*.links \ 263 | $(ug_source)/debian/*.lintian-overrides \ 264 | $(ug_source)/debian/*.manpages \ 265 | $(ug_source)/debian/*.postinst \ 266 | $(ug_source)/debian/*.prerm \ 267 | $(ug_source)/debian/*.xml \ 268 | $(ug_source)/debian/etc/master_preferences \ 269 | $(ug_source)/debian/rules \ 270 | $(ug_source)/debian/scripts/* 271 | 272 | perl -pi -e 's/\b(chromedriver)\b/ungoogled-$$1/' \ 273 | $(ug_source)/debian/chromium-driver.install 274 | 275 | $(DEBIAN_CONVERT)/editcontrol.pl -i \ 276 | -e '$$field =~ /^(Source|Package|Breaks|Depends|Recommends|Replaces|Suggests)$$/ and s/\b(chromium)\b/ungoogled-$$1/g;' \ 277 | -e '$$field eq "Uploaders" and undef $$_;' \ 278 | $(ug_source)/debian/control 279 | 280 | if ! grep '^Maintainer:' $(ug_source)/debian/control | grep -Fq '<$(DEBEMAIL)>'; \ 281 | then \ 282 | $(DEBIAN_CONVERT)/editcontrol.pl -i \ 283 | -e 'if ($$field eq "Maintainer") { set_field("XSBC-Original-Maintainer", $$_); $$_="__UGC_MAINTAINER__"; }' \ 284 | $(ug_source)/debian/control || exit; \ 285 | sed -i 's#__UGC_MAINTAINER__#$(DEBFULLNAME) <$(DEBEMAIL)>#' \ 286 | $(ug_source)/debian/control; \ 287 | sed -i 's/^Xsbc-/XSBC-/' $(ug_source)/debian/control; \ 288 | fi 289 | 290 | # Check for any double-replacement snafus 291 | ! grep -ri --exclude-dir=patches ungoogled.ungoogled \ 292 | $(ug_source)/debian 293 | 294 | touch $@ 295 | 296 | # Stage 5 297 | # 298 | # * Rename all files under debian/ beginning with "chromium" to 299 | # "ungoogled-chromium", using the file-map script 300 | # * The ungoogled-chromium source conversion is complete 301 | # 302 | stage-5.stamp: stage-4.stamp $(new_tree_dep) debian-file-map.sh 303 | test ! -f stage-6.stamp 304 | op1=: op2='mv -fv' \ 305 | debian_a=$(ug_source)/debian \ 306 | debian_b=$(ug_source)/debian \ 307 | sh -e debian-file-map.sh 308 | rm -f $(ug_source)/__UNGOOGLED_CHROMIUM_CONVERSION_INCOMPLETE__ 309 | touch $@ 310 | 311 | # Stage 6 312 | # 313 | # * Build the Debian source package 314 | # 315 | stage-6.stamp: stage-5.stamp $(new_tree_dep) $(ug_tarball) 316 | dpkg-source --abort-on-upstream-changes --build $(ug_source) 317 | touch $@ 318 | ls -Ll ungoogled-chromium_$(VERSION)* 319 | 320 | ################ 321 | 322 | # Addendum to debian/patches/series 323 | # 324 | series.add: $(UNGOOGLED_PATCHES)/series 325 | (printf '\n#\n# ungoogled-chromium addendum\n#\n\n'; \ 326 | perl -pe '/^\w/ and s,^,ungoogled-upstream/,' $< \ 327 | ) >$@ 328 | 329 | # Addendum to debian/rules 330 | # 331 | rules.add: $(UNGOOGLED)/flags.gn 332 | (printf '\n#\n# ungoogled-chromium addendum\n#\n\n'; \ 333 | perl -p -e 's/"/\\"/g; $$p = ($$.==1) ? "defines+=" : " "x9;' \ 334 | -e 's/(.*)/$$p$$1 \\/' \ 335 | $(UNGOOGLED)/flags.gn; \ 336 | printf '\npatch:\n'; \ 337 | printf '\ttest -f ungoogled-domain-substitution.orig.tar \\\n'; \ 338 | printf '\t|| debian/ungoogled-domain-substitution.sh\n\n'; \ 339 | printf 'unpatch:\n'; \ 340 | printf '\ttest ! -f ungoogled-domain-substitution.orig.tar \\\n'; \ 341 | printf '\t|| tar xf ungoogled-domain-substitution.orig.tar\n'; \ 342 | printf '\trm -f ungoogled-domain-substitution.orig.tar\n' \ 343 | ) >$@ 344 | 345 | # Script that maps files from the original debian/ subdirectory to the 346 | # new one, taking renames into account. The script can be run with the 347 | # following variables set: 348 | # 349 | # op1 = operation to perform on files which DO NOT change name 350 | # op2 = operation to perform on files which DO change name 351 | # debian_a = path to first debian/ subdirectory 352 | # debian_b = path to second debian/ subdirectory 353 | # 354 | debian-file-map.sh: $(orig_tree_dep) 355 | (cd $(ORIG_SOURCE) && find debian -type f) \ 356 | | grep -v '^debian/patches/' \ 357 | | sort \ 358 | | perl -n \ 359 | -e 'chomp; s/^/\$$/; $$src=$$_;' \ 360 | -e 's,/(chromium),/ungoogled-$$1,;' \ 361 | -e '$$n = $$_ eq $$src ? "1" : "2";' \ 362 | -e '$$src =~ s/^(.debian)/$${1}_a/;' \ 363 | -e 's/^(.debian)/$${1}_b/;' \ 364 | -e 'print "\$$op$$n\t$$src\t$$_\n"' \ 365 | >$@ 366 | 367 | # ungoogled-chromium uses the exact same .orig.tar file as chromium, 368 | # so just symlink it 369 | # 370 | $(ug_tarball): $(ORIG_TARBALL) 371 | ln -s $(ORIG_TARBALL) $(ug_tarball) 372 | 373 | .PHONY: ug-tarball 374 | ug-tarball: $(ug_tarball) 375 | 376 | ################ 377 | 378 | ## Domain substitution 379 | 380 | # Script to apply the domain substitutions during the Debian package build 381 | # (invoked from the debian/rules "patch" target) 382 | # 383 | ungoogled-domain-substitution.sh: $(UNGOOGLED)/domain_regex.list domain_substitution.list 384 | rm -f $@.new 385 | $(UNGOOGLED)/utils/make_domsub_script.py \ 386 | --regex $(UNGOOGLED)/domain_regex.list \ 387 | --files domain_substitution.list \ 388 | --output $@.new 389 | perl -pi -e 's/^(backup)=/$$1=ungoogled-/' $@.new 390 | chmod 755 $@.new 391 | mv -f $@.new $@ 392 | 393 | # List of files that, after all the patches have been applied, still 394 | # contain Google-related domain names that need to be neutered. 395 | # 396 | domain_substitution.list: $(UNGOOGLED)/domain_regex.list stage-2.stamp $(new_tree_dep) 397 | $(UNGOOGLED)/devutils/update_lists.py \ 398 | --pruning pruning.list \ 399 | --domain-substitution $@ \ 400 | --domain-regex $(UNGOOGLED)/domain_regex.list \ 401 | --domain-exclude-prefix .pc/ \ 402 | --domain-exclude-prefix debian/ \ 403 | --no-error-unused \ 404 | --tree $(ug_source) 405 | 406 | # Create a tar file containing all the source files modified by the 407 | # domain substitution process. 408 | # 409 | domain_substitution.files.tar: domain_substitution.list stage-2.stamp $(new_tree_dep) 410 | tar cf - -C $(ug_source) \ 411 | --verbatim-files-from \ 412 | --files-from=$(work)/domain_substitution.list \ 413 | >$@ 414 | 415 | # Alternate rule to generate a patch containing the domain substitutions 416 | # 417 | # NOTE: The generated patch is huge (over 30 MB!) and hard to review. 418 | # It is better to use the script if at all possible. 419 | # 420 | ungoogled-domain-substitution.patch: domain_substitution.files.tar domain_substitution.list 421 | mkdir tmp.src.a tmp.src.b 422 | cd tmp.src.a && tar xf ../domain_substitution.files.tar 423 | cd tmp.src.b && tar xf ../domain_substitution.files.tar 424 | 425 | $(UNGOOGLED)/utils/domain_substitution.py \ 426 | apply \ 427 | --regex $(UNGOOGLED)/domain_regex.list \ 428 | --files domain_substitution.list \ 429 | tmp.src.b 430 | 431 | ! diff -ru tmp.src.a tmp.src.b >tmp.patch 432 | rm -rf tmp.src.? 433 | tail -n +2 tmp.patch \ 434 | | perl -pe 'if(/^(---|\+\+\+) /){s/ tmp\.src\./ /;s/\t.*//}' \ 435 | >$@ 436 | rm -f tmp.patch 437 | 438 | ################ 439 | 440 | ## Checks 441 | 442 | # Check that the Git repo containing $(UNGOOGLED_PATCHES) is checked out 443 | # to a commit matching $(VERSION). This ensures that we are using the 444 | # specific revision of the patches intended for the version of Chromium 445 | # being converted here. 446 | # 447 | .PHONY: check-git check-git_warning 448 | check-git check-git_warning: $(UNGOOGLED_PATCHES)/series 449 | @cd $(UNGOOGLED_PATCHES) && git show -s >/dev/null 2>&1 || exit 0; \ 450 | ucver=`git cat-file --textconv HEAD:chromium_version.txt`; \ 451 | echo; \ 452 | echo 'target Chromium source version: $(VERSION)'; \ 453 | echo " ungoogled-chromium patches: $$ucver"; \ 454 | echo; \ 455 | if [ '$(VERSION)' = "$$ucver" ]; then echo '==== $@ OK ===='; exit 0; fi; \ 456 | case $@ in \ 457 | *_warning) \ 458 | echo 'Warning: The patches are not matched to this version of Chromium. The conversion process may fail.' | fmt; \ 459 | echo \ 460 | ;; \ 461 | *) \ 462 | echo 'Please checkout the appropriate Git tag in the ungoogled-chromium repo containing $(UNGOOGLED_PATCHES)/ .' | fmt; \ 463 | echo; \ 464 | exit 1 \ 465 | ;; \ 466 | esac 467 | 468 | # Check that every patch listed in PATCH_DROP_LIST needs to be dropped 469 | # in order for the ungoogled-chromium patch series to apply cleanly. 470 | # That is, verify that PATCH_DROP_LIST is minimal, so that we don't drop 471 | # any patches unnecessarily. 472 | # 473 | # (All this does is attempt to apply the combined patch series multiple 474 | # times, each time enabling one of the dropped patches, and verifying 475 | # that the expected conflicts result.) 476 | # 477 | .PHONY: check-patch-drop-list 478 | check-patch-drop-list: stage-2.stamp 479 | ! find $(ug_source) -type f -name \*.rej | grep . 480 | : >tmp.check-pdl.out 481 | cd $(ug_source)/debian/patches && cp -p series series.orig 482 | for p in $(PATCH_DROP_LIST); do \ 483 | (cd $(ug_source) && set -x && $(QUILT) pop -afq); \ 484 | echo "==== checking $$p drop ===="; \ 485 | (cd $(ug_source)/debian/patches && cp -fp series.orig series); \ 486 | perl -pi -e '$$a=$$_; $$a =~ s/^#ungoogled#|\n$$//g; $$a eq "'"$$p"'" and $$_="$$a\n"' \ 487 | $(ug_source)/debian/patches/series; \ 488 | if (cd $(ug_source) && set -x && $(QUILT) push -afq --fuzz=0); then \ 489 | echo "==== $$p drop NOT NEEDED ===="; \ 490 | echo "$$p: remove from PATCH_DROP_LIST" >>tmp.check-pdl.out; \ 491 | else \ 492 | echo "==== $$p drop OK ===="; \ 493 | fi; \ 494 | done 495 | cd $(ug_source)/debian/patches && mv -f series.orig series 496 | find $(ug_source) -type f -name \*.rej -delete 497 | cd $(ug_source) && $(QUILT) pop -afq 498 | cd $(ug_source) && $(QUILT) push -afq --fuzz=0 499 | @echo; ! grep . tmp.check-pdl.out 500 | rm -f tmp.check-pdl.out 501 | @echo '==== $@ OK ====' 502 | 503 | check_domsub_deps = \ 504 | domain_substitution.list \ 505 | domain_substitution.files.tar \ 506 | ungoogled-domain-substitution.sh \ 507 | $(UNGOOGLED)/utils/domain_substitution.py 508 | 509 | # Check that the modifications made by domain_substitution.py and those 510 | # made by the script created by make_domsub_script.py are identical. 511 | # 512 | .PHONY: check-domsub 513 | check-domsub: $(check_domsub_deps) 514 | rm -rf tmp.src.? 515 | mkdir tmp.src.a tmp.src.b 516 | cd tmp.src.a && tar xf ../domain_substitution.files.tar 517 | cd tmp.src.b && tar xf ../domain_substitution.files.tar 518 | 519 | $(TIME) $(UNGOOGLED)/utils/domain_substitution.py \ 520 | apply \ 521 | --regex $(UNGOOGLED)/domain_regex.list \ 522 | --files domain_substitution.list \ 523 | tmp.src.a 524 | 525 | cd tmp.src.b && $(TIME) ../ungoogled-domain-substitution.sh 526 | rm tmp.src.b/ungoogled-domain-substitution.orig.tar 527 | 528 | diff -ru tmp.src.a tmp.src.b 529 | rm -rf tmp.src.? 530 | @echo '==== $@ OK ====' 531 | 532 | .PHONY: check 533 | check: check-git check-patch-drop-list check-domsub 534 | 535 | # Compare the GN flags used by Debian versus those specified by 536 | # ungoogled-chromium. Each output line is in one of two (tab-separated) 537 | # columns: column 1 has flags that are unique to Debian, column 2 has 538 | # flags that are unique to ungoogled-chromium. Flags that occur 539 | # identically in both projects are not shown. 540 | # 541 | .PHONY: compare-flags 542 | compare-flags: $(ORIG_SOURCE)/debian/rules $(UNGOOGLED)/flags.gn 543 | printf 'getflags:\n\tfor d in $$(defines); do echo "$$$$d"; done\n\ninclude %s\n' $< >tmp.getflags.mk 544 | $(MAKE) --silent -f tmp.getflags.mk >tmp.flags-debian.txt 545 | rm -f tmp.getflags.mk 546 | sort -u tmp.flags-debian.txt >tmp.flags-debian-s.txt 547 | sort -u $(UNGOOGLED)/flags.gn >tmp.flags-ungoogled-s.txt 548 | echo; comm -3 tmp.flags-debian-s.txt tmp.flags-ungoogled-s.txt; echo 549 | rm -f tmp.flags*.txt 550 | 551 | ################ 552 | 553 | .PHONY: unpatch 554 | unpatch: 555 | cd $(ug_source) && $(QUILT) pop -afq 556 | rm -rf $(ug_source)/.pc 557 | 558 | .PHONY: clean 559 | clean: 560 | rm -f stage-?.stamp 561 | rm -f check-domsub.diff 562 | rm -f debian-file-map.sh 563 | rm -f domain_substitution.list pruning.list 564 | rm -f domain_substitution.files.tar 565 | rm -f rules.add series.add 566 | rm -f ungoogled-domain-substitution.patch 567 | rm -f ungoogled-domain-substitution.sh 568 | ifndef KEEP_TREE 569 | rm -rf ungoogled-chromium-src 570 | endif 571 | # dpkg-source(1) temporary dir 572 | rm -rf ungoogled-chromium-src.orig.* 573 | rm -rf tmp.* 574 | 575 | .PHONY: clean-more 576 | clean-more: clean 577 | rm -f ungoogled-chromium_$(VERSION).orig.tar.xz 578 | rm -f ungoogled-chromium_$(VERSION)-*.debian.tar.xz 579 | rm -f ungoogled-chromium_$(VERSION)-*.dsc 580 | 581 | .DELETE_ON_ERROR: 582 | 583 | # end convert/Makefile 584 | -------------------------------------------------------------------------------- /debian/patches/absl-optional.patch: -------------------------------------------------------------------------------- 1 | author: Andres Salomon 2 | description: work around a clang bug with libstdc++ 3 | 4 | Chromium 119 used absl's 'optional' implementation. Chromium 120 switched to 5 | aliasing absl::optional to std::optional. In theory that should be all fine 6 | and good, except for the fact that there's a bug in clang: 7 | 8 | https://github.com/llvm/llvm-project/issues/50248 9 | 10 | This bug is worked around in libc++, but not in libstdc++. There's (so far) 11 | two types of errors we hit. The first is specifically with 12 | absl::optional::emplace() - 13 | 14 | >> gen/ui/gfx/x/randr.cc:482:13: error: no matching member function for call to 'emplace' 15 | >> data.lc.emplace(); 16 | >> ~~~~~~~~^~~~~~~ 17 | >> /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/optional:914:2: note: candidate template ignored: requirement 'is_constructible_v' was not satisfied [with _Args = <>] 18 | >> emplace(_Args&&... __args) 19 | >> 20 | 21 | ..and a similar error with just a few calls to absl::make_optional() - 22 | 23 | >> ./../third_party/blink/renderer/core/loader/history_item.cc:185:19: error: no matching function for call to 'make_optional' 24 | >> view_state_ = absl::make_optional(); 25 | 26 | We can't simply revert to using absl's optional implmentation, because a) they 27 | are planning to remove it (), and 28 | b) chromium devs, having switched over and viewing absl::optional and 29 | std::optional as aliases, play fast and loose with those namespace. We end up 30 | playing an ever-worsening game of whack-a-mole trying to fix build errors which 31 | are just inability to do implicit conversions. 32 | 33 | Another option (which some other distributions have chosen to do) is to simply 34 | switch to building against libc++. However, that means bundling a bunch more 35 | libraries that build statically against libc++. That's undesirable. 36 | 37 | This patch provides the option of providing a workaround for libstdc++. Instead 38 | of using the official libstdc++ header for optional, we provide our own with 39 | the is_constructible assertions removed. There's no logic changes, it just 40 | removes an assertion we _know_ is met, but the compiler too broken to know it. 41 | 42 | I just copied over /usr/include/c++/13/optional, and changed a few of the 43 | functions (where you see an '#if 0' commenting out the original function). 44 | We'll need to update this patch with major libstdc++ upgrades. 45 | 46 | --- /dev/null 47 | +++ b/optional 48 | @@ -0,0 +1,1549 @@ 49 | +// -*- C++ -*- 50 | + 51 | +// Copyright (C) 2013-2023 Free Software Foundation, Inc. 52 | +// Copyright The GNU Toolchain Authors. 53 | +// 54 | +// This file is part of the GNU ISO C++ Library. This library is free 55 | +// software; you can redistribute it and/or modify it under the 56 | +// terms of the GNU General Public License as published by the 57 | +// Free Software Foundation; either version 3, or (at your option) 58 | +// any later version. 59 | + 60 | +// This library is distributed in the hope that it will be useful, 61 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of 62 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 63 | +// GNU General Public License for more details. 64 | + 65 | +// Under Section 7 of GPL version 3, you are granted additional 66 | +// permissions described in the GCC Runtime Library Exception, version 67 | +// 3.1, as published by the Free Software Foundation. 68 | + 69 | +// You should have received a copy of the GNU General Public License and 70 | +// a copy of the GCC Runtime Library Exception along with this program; 71 | +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 72 | +// . 73 | + 74 | +/** @file include/optional 75 | + * This is a Standard C++ Library header. 76 | + */ 77 | + 78 | +#ifndef _GLIBCXX_OPTIONAL 79 | +#define _GLIBCXX_OPTIONAL 1 80 | + 81 | +#pragma GCC system_header 82 | + 83 | +#if __cplusplus >= 201703L 84 | + 85 | +#include 86 | +#include 87 | +#include 88 | +#include 89 | +#include 90 | +#include 91 | +#include 92 | +#include // _Construct 93 | +#include // in_place_t 94 | +#if __cplusplus > 201703L 95 | +# include 96 | +# include // std::__invoke 97 | +#endif 98 | +#if __cplusplus > 202002L 99 | +# include 100 | +#endif 101 | + 102 | +namespace std _GLIBCXX_VISIBILITY(default) 103 | +{ 104 | +_GLIBCXX_BEGIN_NAMESPACE_VERSION 105 | + 106 | + /** 107 | + * @addtogroup utilities 108 | + * @{ 109 | + */ 110 | + 111 | +#if __cplusplus > 202002L && __cpp_lib_concepts 112 | +# define __cpp_lib_optional 202110L 113 | +#elif __cplusplus >= 202002L 114 | +# define __cpp_lib_optional 202106L 115 | +#else 116 | +# define __cpp_lib_optional 201606L 117 | +#endif 118 | + 119 | + template 120 | + class optional; 121 | + 122 | + /// Tag type to disengage optional objects. 123 | + struct nullopt_t 124 | + { 125 | + // Do not user-declare default constructor at all for 126 | + // optional_value = {} syntax to work. 127 | + // nullopt_t() = delete; 128 | + 129 | + // Used for constructing nullopt. 130 | + enum class _Construct { _Token }; 131 | + 132 | + // Must be constexpr for nullopt_t to be literal. 133 | + explicit constexpr nullopt_t(_Construct) noexcept { } 134 | + }; 135 | + 136 | + /// Tag to disengage optional objects. 137 | + inline constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token }; 138 | + 139 | + template struct _Optional_func { _Fn& _M_f; }; 140 | + 141 | + /** 142 | + * @brief Exception class thrown when a disengaged optional object is 143 | + * dereferenced. 144 | + * @ingroup exceptions 145 | + */ 146 | + class bad_optional_access : public exception 147 | + { 148 | + public: 149 | + bad_optional_access() = default; 150 | + virtual ~bad_optional_access() = default; 151 | + 152 | + const char* what() const noexcept override 153 | + { return "bad optional access"; } 154 | + }; 155 | + 156 | + // XXX Does not belong here. 157 | + [[__noreturn__]] inline void 158 | + __throw_bad_optional_access() 159 | + { _GLIBCXX_THROW_OR_ABORT(bad_optional_access()); } 160 | + 161 | + // This class template manages construction/destruction of 162 | + // the contained value for a std::optional. 163 | + template 164 | + struct _Optional_payload_base 165 | + { 166 | + using _Stored_type = remove_const_t<_Tp>; 167 | + 168 | + _Optional_payload_base() = default; 169 | + ~_Optional_payload_base() = default; 170 | + 171 | + template 172 | + constexpr 173 | + _Optional_payload_base(in_place_t __tag, _Args&&... __args) 174 | + : _M_payload(__tag, std::forward<_Args>(__args)...), 175 | + _M_engaged(true) 176 | + { } 177 | + 178 | + template 179 | + constexpr 180 | + _Optional_payload_base(std::initializer_list<_Up> __il, 181 | + _Args&&... __args) 182 | + : _M_payload(__il, std::forward<_Args>(__args)...), 183 | + _M_engaged(true) 184 | + { } 185 | + 186 | + // Constructor used by _Optional_base copy constructor when the 187 | + // contained value is not trivially copy constructible. 188 | + constexpr 189 | + _Optional_payload_base(bool /* __engaged */, 190 | + const _Optional_payload_base& __other) 191 | + { 192 | + if (__other._M_engaged) 193 | + this->_M_construct(__other._M_get()); 194 | + } 195 | + 196 | + // Constructor used by _Optional_base move constructor when the 197 | + // contained value is not trivially move constructible. 198 | + constexpr 199 | + _Optional_payload_base(bool /* __engaged */, 200 | + _Optional_payload_base&& __other) 201 | + { 202 | + if (__other._M_engaged) 203 | + this->_M_construct(std::move(__other._M_get())); 204 | + } 205 | + 206 | + // Copy constructor is only used to when the contained value is 207 | + // trivially copy constructible. 208 | + _Optional_payload_base(const _Optional_payload_base&) = default; 209 | + 210 | + // Move constructor is only used to when the contained value is 211 | + // trivially copy constructible. 212 | + _Optional_payload_base(_Optional_payload_base&&) = default; 213 | + 214 | + _Optional_payload_base& 215 | + operator=(const _Optional_payload_base&) = default; 216 | + 217 | + _Optional_payload_base& 218 | + operator=(_Optional_payload_base&&) = default; 219 | + 220 | + // used to perform non-trivial copy assignment. 221 | + constexpr void 222 | + _M_copy_assign(const _Optional_payload_base& __other) 223 | + { 224 | + if (this->_M_engaged && __other._M_engaged) 225 | + this->_M_get() = __other._M_get(); 226 | + else 227 | + { 228 | + if (__other._M_engaged) 229 | + this->_M_construct(__other._M_get()); 230 | + else 231 | + this->_M_reset(); 232 | + } 233 | + } 234 | + 235 | + // used to perform non-trivial move assignment. 236 | + constexpr void 237 | + _M_move_assign(_Optional_payload_base&& __other) 238 | + noexcept(__and_v, 239 | + is_nothrow_move_assignable<_Tp>>) 240 | + { 241 | + if (this->_M_engaged && __other._M_engaged) 242 | + this->_M_get() = std::move(__other._M_get()); 243 | + else 244 | + { 245 | + if (__other._M_engaged) 246 | + this->_M_construct(std::move(__other._M_get())); 247 | + else 248 | + this->_M_reset(); 249 | + } 250 | + } 251 | + 252 | + struct _Empty_byte { }; 253 | + 254 | + template> 255 | + union _Storage 256 | + { 257 | + constexpr _Storage() noexcept : _M_empty() { } 258 | + 259 | + template 260 | + constexpr 261 | + _Storage(in_place_t, _Args&&... __args) 262 | + : _M_value(std::forward<_Args>(__args)...) 263 | + { } 264 | + 265 | + template 266 | + constexpr 267 | + _Storage(std::initializer_list<_Vp> __il, _Args&&... __args) 268 | + : _M_value(__il, std::forward<_Args>(__args)...) 269 | + { } 270 | + 271 | +#if __cplusplus >= 202002L 272 | + template 273 | + constexpr 274 | + _Storage(_Optional_func<_Fn> __f, _Arg&& __arg) 275 | + : _M_value(std::__invoke(std::forward<_Fn>(__f._M_f), 276 | + std::forward<_Arg>(__arg))) 277 | + { } 278 | +#endif 279 | + 280 | + _Empty_byte _M_empty; 281 | + _Up _M_value; 282 | + }; 283 | + 284 | + template 285 | + union _Storage<_Up, false> 286 | + { 287 | + constexpr _Storage() noexcept : _M_empty() { } 288 | + 289 | + template 290 | + constexpr 291 | + _Storage(in_place_t, _Args&&... __args) 292 | + : _M_value(std::forward<_Args>(__args)...) 293 | + { } 294 | + 295 | + template 296 | + constexpr 297 | + _Storage(std::initializer_list<_Vp> __il, _Args&&... __args) 298 | + : _M_value(__il, std::forward<_Args>(__args)...) 299 | + { } 300 | + 301 | +#if __cplusplus >= 202002L 302 | + template 303 | + constexpr 304 | + _Storage(_Optional_func<_Fn> __f, _Arg&& __arg) 305 | + : _M_value(std::__invoke(std::forward<_Fn>(__f._M_f), 306 | + std::forward<_Arg>(__arg))) 307 | + { } 308 | +#endif 309 | + 310 | + // User-provided destructor is needed when _Up has non-trivial dtor. 311 | + _GLIBCXX20_CONSTEXPR ~_Storage() { } 312 | + 313 | + _Empty_byte _M_empty; 314 | + _Up _M_value; 315 | + }; 316 | + 317 | + _Storage<_Stored_type> _M_payload; 318 | + 319 | + bool _M_engaged = false; 320 | + 321 | + template 322 | + constexpr void 323 | + _M_construct(_Args&&... __args) 324 | + noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>) 325 | + { 326 | + std::_Construct(std::__addressof(this->_M_payload._M_value), 327 | + std::forward<_Args>(__args)...); 328 | + this->_M_engaged = true; 329 | + } 330 | + 331 | + constexpr void 332 | + _M_destroy() noexcept 333 | + { 334 | + _M_engaged = false; 335 | + _M_payload._M_value.~_Stored_type(); 336 | + } 337 | + 338 | +#if __cplusplus >= 202002L 339 | + template 340 | + constexpr void 341 | + _M_apply(_Optional_func<_Fn> __f, _Up&& __x) 342 | + { 343 | + std::construct_at(std::__addressof(this->_M_payload), 344 | + __f, std::forward<_Up>(__x)); 345 | + _M_engaged = true; 346 | + } 347 | +#endif 348 | + 349 | + // The _M_get() operations have _M_engaged as a precondition. 350 | + // They exist to access the contained value with the appropriate 351 | + // const-qualification, because _M_payload has had the const removed. 352 | + 353 | + constexpr _Tp& 354 | + _M_get() noexcept 355 | + { return this->_M_payload._M_value; } 356 | + 357 | + constexpr const _Tp& 358 | + _M_get() const noexcept 359 | + { return this->_M_payload._M_value; } 360 | + 361 | + // _M_reset is a 'safe' operation with no precondition. 362 | + constexpr void 363 | + _M_reset() noexcept 364 | + { 365 | + if (this->_M_engaged) 366 | + _M_destroy(); 367 | + } 368 | + }; 369 | + 370 | + // Class template that manages the payload for optionals. 371 | + template , 374 | + bool /*_HasTrivialCopy */ = 375 | + is_trivially_copy_assignable_v<_Tp> 376 | + && is_trivially_copy_constructible_v<_Tp>, 377 | + bool /*_HasTrivialMove */ = 378 | + is_trivially_move_assignable_v<_Tp> 379 | + && is_trivially_move_constructible_v<_Tp>> 380 | + struct _Optional_payload; 381 | + 382 | + // Payload for potentially-constexpr optionals (trivial copy/move/destroy). 383 | + template 384 | + struct _Optional_payload<_Tp, true, true, true> 385 | + : _Optional_payload_base<_Tp> 386 | + { 387 | + using _Optional_payload_base<_Tp>::_Optional_payload_base; 388 | + 389 | + _Optional_payload() = default; 390 | + }; 391 | + 392 | + // Payload for optionals with non-trivial copy construction/assignment. 393 | + template 394 | + struct _Optional_payload<_Tp, true, false, true> 395 | + : _Optional_payload_base<_Tp> 396 | + { 397 | + using _Optional_payload_base<_Tp>::_Optional_payload_base; 398 | + 399 | + _Optional_payload() = default; 400 | + ~_Optional_payload() = default; 401 | + _Optional_payload(const _Optional_payload&) = default; 402 | + _Optional_payload(_Optional_payload&&) = default; 403 | + _Optional_payload& operator=(_Optional_payload&&) = default; 404 | + 405 | + // Non-trivial copy assignment. 406 | + constexpr 407 | + _Optional_payload& 408 | + operator=(const _Optional_payload& __other) 409 | + { 410 | + this->_M_copy_assign(__other); 411 | + return *this; 412 | + } 413 | + }; 414 | + 415 | + // Payload for optionals with non-trivial move construction/assignment. 416 | + template 417 | + struct _Optional_payload<_Tp, true, true, false> 418 | + : _Optional_payload_base<_Tp> 419 | + { 420 | + using _Optional_payload_base<_Tp>::_Optional_payload_base; 421 | + 422 | + _Optional_payload() = default; 423 | + ~_Optional_payload() = default; 424 | + _Optional_payload(const _Optional_payload&) = default; 425 | + _Optional_payload(_Optional_payload&&) = default; 426 | + _Optional_payload& operator=(const _Optional_payload&) = default; 427 | + 428 | + // Non-trivial move assignment. 429 | + constexpr 430 | + _Optional_payload& 431 | + operator=(_Optional_payload&& __other) 432 | + noexcept(__and_v, 433 | + is_nothrow_move_assignable<_Tp>>) 434 | + { 435 | + this->_M_move_assign(std::move(__other)); 436 | + return *this; 437 | + } 438 | + }; 439 | + 440 | + // Payload for optionals with non-trivial copy and move assignment. 441 | + template 442 | + struct _Optional_payload<_Tp, true, false, false> 443 | + : _Optional_payload_base<_Tp> 444 | + { 445 | + using _Optional_payload_base<_Tp>::_Optional_payload_base; 446 | + 447 | + _Optional_payload() = default; 448 | + ~_Optional_payload() = default; 449 | + _Optional_payload(const _Optional_payload&) = default; 450 | + _Optional_payload(_Optional_payload&&) = default; 451 | + 452 | + // Non-trivial copy assignment. 453 | + constexpr 454 | + _Optional_payload& 455 | + operator=(const _Optional_payload& __other) 456 | + { 457 | + this->_M_copy_assign(__other); 458 | + return *this; 459 | + } 460 | + 461 | + // Non-trivial move assignment. 462 | + constexpr 463 | + _Optional_payload& 464 | + operator=(_Optional_payload&& __other) 465 | + noexcept(__and_v, 466 | + is_nothrow_move_assignable<_Tp>>) 467 | + { 468 | + this->_M_move_assign(std::move(__other)); 469 | + return *this; 470 | + } 471 | + }; 472 | + 473 | + // Payload for optionals with non-trivial destructors. 474 | + template 475 | + struct _Optional_payload<_Tp, false, _Copy, _Move> 476 | + : _Optional_payload<_Tp, true, false, false> 477 | + { 478 | + // Base class implements all the constructors and assignment operators: 479 | + using _Optional_payload<_Tp, true, false, false>::_Optional_payload; 480 | + _Optional_payload() = default; 481 | + _Optional_payload(const _Optional_payload&) = default; 482 | + _Optional_payload(_Optional_payload&&) = default; 483 | + _Optional_payload& operator=(const _Optional_payload&) = default; 484 | + _Optional_payload& operator=(_Optional_payload&&) = default; 485 | + 486 | + // Destructor needs to destroy the contained value: 487 | + _GLIBCXX20_CONSTEXPR ~_Optional_payload() { this->_M_reset(); } 488 | + }; 489 | + 490 | + // Common base class for _Optional_base to avoid repeating these 491 | + // member functions in each specialization. 492 | + template 493 | + class _Optional_base_impl 494 | + { 495 | + protected: 496 | + using _Stored_type = remove_const_t<_Tp>; 497 | + 498 | + // The _M_construct operation has !_M_engaged as a precondition 499 | + // while _M_destruct has _M_engaged as a precondition. 500 | + template 501 | + constexpr void 502 | + _M_construct(_Args&&... __args) 503 | + noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>) 504 | + { 505 | + static_cast<_Dp*>(this)->_M_payload._M_construct( 506 | + std::forward<_Args>(__args)...); 507 | + } 508 | + 509 | + constexpr void 510 | + _M_destruct() noexcept 511 | + { static_cast<_Dp*>(this)->_M_payload._M_destroy(); } 512 | + 513 | + // _M_reset is a 'safe' operation with no precondition. 514 | + constexpr void 515 | + _M_reset() noexcept 516 | + { static_cast<_Dp*>(this)->_M_payload._M_reset(); } 517 | + 518 | + constexpr bool _M_is_engaged() const noexcept 519 | + { return static_cast(this)->_M_payload._M_engaged; } 520 | + 521 | + // The _M_get operations have _M_engaged as a precondition. 522 | + constexpr _Tp& 523 | + _M_get() noexcept 524 | + { 525 | + __glibcxx_assert(this->_M_is_engaged()); 526 | + return static_cast<_Dp*>(this)->_M_payload._M_get(); 527 | + } 528 | + 529 | + constexpr const _Tp& 530 | + _M_get() const noexcept 531 | + { 532 | + __glibcxx_assert(this->_M_is_engaged()); 533 | + return static_cast(this)->_M_payload._M_get(); 534 | + } 535 | + }; 536 | + 537 | + /** 538 | + * @brief Class template that provides copy/move constructors of optional. 539 | + * 540 | + * Such a separate base class template is necessary in order to 541 | + * conditionally make copy/move constructors trivial. 542 | + * 543 | + * When the contained value is trivially copy/move constructible, 544 | + * the copy/move constructors of _Optional_base will invoke the 545 | + * trivial copy/move constructor of _Optional_payload. Otherwise, 546 | + * they will invoke _Optional_payload(bool, const _Optional_payload&) 547 | + * or _Optional_payload(bool, _Optional_payload&&) to initialize 548 | + * the contained value, if copying/moving an engaged optional. 549 | + * 550 | + * Whether the other special members are trivial is determined by the 551 | + * _Optional_payload<_Tp> specialization used for the _M_payload member. 552 | + * 553 | + * @see optional, _Enable_special_members 554 | + */ 555 | + template, 557 | + bool = is_trivially_move_constructible_v<_Tp>> 558 | + struct _Optional_base 559 | + : _Optional_base_impl<_Tp, _Optional_base<_Tp>> 560 | + { 561 | + // Constructors for disengaged optionals. 562 | + constexpr _Optional_base() = default; 563 | + 564 | + // Constructors for engaged optionals. 565 | +#if 0 566 | + template, bool> = false> 568 | +#else 569 | +// Drop is_constructible_v to work around a clang bug 570 | + template 571 | +#endif 572 | + constexpr explicit 573 | + _Optional_base(in_place_t, _Args&&... __args) 574 | + : _M_payload(in_place, std::forward<_Args>(__args)...) 575 | + { } 576 | + 577 | + template&, 580 | + _Args...>, bool> = false> 581 | + constexpr explicit 582 | + _Optional_base(in_place_t, 583 | + initializer_list<_Up> __il, 584 | + _Args&&... __args) 585 | + : _M_payload(in_place, __il, std::forward<_Args>(__args)...) 586 | + { } 587 | + 588 | + // Copy and move constructors. 589 | + constexpr 590 | + _Optional_base(const _Optional_base& __other) 591 | + : _M_payload(__other._M_payload._M_engaged, __other._M_payload) 592 | + { } 593 | + 594 | + constexpr 595 | + _Optional_base(_Optional_base&& __other) 596 | + noexcept(is_nothrow_move_constructible_v<_Tp>) 597 | + : _M_payload(__other._M_payload._M_engaged, 598 | + std::move(__other._M_payload)) 599 | + { } 600 | + 601 | + // Assignment operators. 602 | + _Optional_base& operator=(const _Optional_base&) = default; 603 | + _Optional_base& operator=(_Optional_base&&) = default; 604 | + 605 | + _Optional_payload<_Tp> _M_payload; 606 | + }; 607 | + 608 | + template 609 | + struct _Optional_base<_Tp, false, true> 610 | + : _Optional_base_impl<_Tp, _Optional_base<_Tp>> 611 | + { 612 | + // Constructors for disengaged optionals. 613 | + constexpr _Optional_base() = default; 614 | + 615 | + // Constructors for engaged optionals. 616 | + template, bool> = false> 618 | + constexpr explicit 619 | + _Optional_base(in_place_t, _Args&&... __args) 620 | + : _M_payload(in_place, std::forward<_Args>(__args)...) 621 | + { } 622 | + 623 | + template&, 626 | + _Args...>, bool> = false> 627 | + constexpr explicit 628 | + _Optional_base(in_place_t, 629 | + initializer_list<_Up> __il, 630 | + _Args... __args) 631 | + : _M_payload(in_place, __il, std::forward<_Args>(__args)...) 632 | + { } 633 | + 634 | + // Copy and move constructors. 635 | + constexpr _Optional_base(const _Optional_base& __other) 636 | + : _M_payload(__other._M_payload._M_engaged, __other._M_payload) 637 | + { } 638 | + 639 | + constexpr _Optional_base(_Optional_base&& __other) = default; 640 | + 641 | + // Assignment operators. 642 | + _Optional_base& operator=(const _Optional_base&) = default; 643 | + _Optional_base& operator=(_Optional_base&&) = default; 644 | + 645 | + _Optional_payload<_Tp> _M_payload; 646 | + }; 647 | + 648 | + template 649 | + struct _Optional_base<_Tp, true, false> 650 | + : _Optional_base_impl<_Tp, _Optional_base<_Tp>> 651 | + { 652 | + // Constructors for disengaged optionals. 653 | + constexpr _Optional_base() = default; 654 | + 655 | + // Constructors for engaged optionals. 656 | + template, bool> = false> 658 | + constexpr explicit 659 | + _Optional_base(in_place_t, _Args&&... __args) 660 | + : _M_payload(in_place, std::forward<_Args>(__args)...) 661 | + { } 662 | + 663 | + template&, 666 | + _Args...>, bool> = false> 667 | + constexpr explicit 668 | + _Optional_base(in_place_t, 669 | + initializer_list<_Up> __il, 670 | + _Args&&... __args) 671 | + : _M_payload(in_place, __il, std::forward<_Args>(__args)...) 672 | + { } 673 | + 674 | + // Copy and move constructors. 675 | + constexpr _Optional_base(const _Optional_base& __other) = default; 676 | + 677 | + constexpr 678 | + _Optional_base(_Optional_base&& __other) 679 | + noexcept(is_nothrow_move_constructible_v<_Tp>) 680 | + : _M_payload(__other._M_payload._M_engaged, 681 | + std::move(__other._M_payload)) 682 | + { } 683 | + 684 | + // Assignment operators. 685 | + _Optional_base& operator=(const _Optional_base&) = default; 686 | + _Optional_base& operator=(_Optional_base&&) = default; 687 | + 688 | + _Optional_payload<_Tp> _M_payload; 689 | + }; 690 | + 691 | + template 692 | + struct _Optional_base<_Tp, true, true> 693 | + : _Optional_base_impl<_Tp, _Optional_base<_Tp>> 694 | + { 695 | + // Constructors for disengaged optionals. 696 | + constexpr _Optional_base() = default; 697 | + 698 | + // Constructors for engaged optionals. 699 | + template, bool> = false> 701 | + constexpr explicit 702 | + _Optional_base(in_place_t, _Args&&... __args) 703 | + : _M_payload(in_place, std::forward<_Args>(__args)...) 704 | + { } 705 | + 706 | + template&, 709 | + _Args...>, bool> = false> 710 | + constexpr explicit 711 | + _Optional_base(in_place_t, 712 | + initializer_list<_Up> __il, 713 | + _Args&&... __args) 714 | + : _M_payload(in_place, __il, std::forward<_Args>(__args)...) 715 | + { } 716 | + 717 | + // Copy and move constructors. 718 | + constexpr _Optional_base(const _Optional_base& __other) = default; 719 | + constexpr _Optional_base(_Optional_base&& __other) = default; 720 | + 721 | + // Assignment operators. 722 | + _Optional_base& operator=(const _Optional_base&) = default; 723 | + _Optional_base& operator=(_Optional_base&&) = default; 724 | + 725 | + _Optional_payload<_Tp> _M_payload; 726 | + }; 727 | + 728 | + template 729 | + class optional; 730 | + 731 | + template 732 | + inline constexpr bool __is_optional_v = false; 733 | + template 734 | + inline constexpr bool __is_optional_v> = true; 735 | + 736 | + template 737 | + using __converts_from_optional = 738 | + __or_&>, 739 | + is_constructible<_Tp, optional<_Up>&>, 740 | + is_constructible<_Tp, const optional<_Up>&&>, 741 | + is_constructible<_Tp, optional<_Up>&&>, 742 | + is_convertible&, _Tp>, 743 | + is_convertible&, _Tp>, 744 | + is_convertible&&, _Tp>, 745 | + is_convertible&&, _Tp>>; 746 | + 747 | + template 748 | + using __assigns_from_optional = 749 | + __or_&>, 750 | + is_assignable<_Tp&, optional<_Up>&>, 751 | + is_assignable<_Tp&, const optional<_Up>&&>, 752 | + is_assignable<_Tp&, optional<_Up>&&>>; 753 | + 754 | + /** 755 | + * @brief Class template for optional values. 756 | + */ 757 | + template 758 | + class optional 759 | + : private _Optional_base<_Tp>, 760 | + private _Enable_copy_move< 761 | + // Copy constructor. 762 | + is_copy_constructible_v<_Tp>, 763 | + // Copy assignment. 764 | + __and_v, is_copy_assignable<_Tp>>, 765 | + // Move constructor. 766 | + is_move_constructible_v<_Tp>, 767 | + // Move assignment. 768 | + __and_v, is_move_assignable<_Tp>>, 769 | + // Unique tag type. 770 | + optional<_Tp>> 771 | + { 772 | + static_assert(!is_same_v, nullopt_t>); 773 | + static_assert(!is_same_v, in_place_t>); 774 | + static_assert(is_object_v<_Tp> && !is_array_v<_Tp>); 775 | + 776 | + private: 777 | + using _Base = _Optional_base<_Tp>; 778 | + 779 | + // SFINAE helpers 780 | + template 781 | + using __not_self = __not_>>; 782 | + template 783 | + using __not_tag = __not_>>; 784 | + template 785 | + using _Requires = enable_if_t<__and_v<_Cond...>, bool>; 786 | + 787 | + public: 788 | + using value_type = _Tp; 789 | + 790 | + constexpr optional() noexcept { } 791 | + 792 | + constexpr optional(nullopt_t) noexcept { } 793 | + 794 | + // Converting constructors for engaged optionals. 795 | + template, __not_tag<_Up>, 797 | + is_constructible<_Tp, _Up>, 798 | + is_convertible<_Up, _Tp>> = true> 799 | + constexpr 800 | + optional(_Up&& __t) 801 | + noexcept(is_nothrow_constructible_v<_Tp, _Up>) 802 | + : _Base(std::in_place, std::forward<_Up>(__t)) { } 803 | + 804 | + template, __not_tag<_Up>, 806 | + is_constructible<_Tp, _Up>, 807 | + __not_>> = false> 808 | + explicit constexpr 809 | + optional(_Up&& __t) 810 | + noexcept(is_nothrow_constructible_v<_Tp, _Up>) 811 | + : _Base(std::in_place, std::forward<_Up>(__t)) { } 812 | + 813 | + template>, 815 | + is_constructible<_Tp, const _Up&>, 816 | + is_convertible, 817 | + __not_<__converts_from_optional<_Tp, _Up>>> = true> 818 | + constexpr 819 | + optional(const optional<_Up>& __t) 820 | + noexcept(is_nothrow_constructible_v<_Tp, const _Up&>) 821 | + { 822 | + if (__t) 823 | + emplace(*__t); 824 | + } 825 | + 826 | + template>, 828 | + is_constructible<_Tp, const _Up&>, 829 | + __not_>, 830 | + __not_<__converts_from_optional<_Tp, _Up>>> = false> 831 | + explicit constexpr 832 | + optional(const optional<_Up>& __t) 833 | + noexcept(is_nothrow_constructible_v<_Tp, const _Up&>) 834 | + { 835 | + if (__t) 836 | + emplace(*__t); 837 | + } 838 | + 839 | + template>, 841 | + is_constructible<_Tp, _Up>, 842 | + is_convertible<_Up, _Tp>, 843 | + __not_<__converts_from_optional<_Tp, _Up>>> = true> 844 | + constexpr 845 | + optional(optional<_Up>&& __t) 846 | + noexcept(is_nothrow_constructible_v<_Tp, _Up>) 847 | + { 848 | + if (__t) 849 | + emplace(std::move(*__t)); 850 | + } 851 | + 852 | + template>, 854 | + is_constructible<_Tp, _Up>, 855 | + __not_>, 856 | + __not_<__converts_from_optional<_Tp, _Up>>> = false> 857 | + explicit constexpr 858 | + optional(optional<_Up>&& __t) 859 | + noexcept(is_nothrow_constructible_v<_Tp, _Up>) 860 | + { 861 | + if (__t) 862 | + emplace(std::move(*__t)); 863 | + } 864 | + 865 | +#if 0 866 | + template> = false> 868 | + explicit constexpr 869 | + optional(in_place_t, _Args&&... __args) 870 | + noexcept(is_nothrow_constructible_v<_Tp, _Args...>) 871 | +#else 872 | +// Drop the constructible checks 873 | + template 874 | + explicit constexpr 875 | + optional(in_place_t, _Args&&... __args) 876 | +#endif 877 | + : _Base(std::in_place, std::forward<_Args>(__args)...) { } 878 | + 879 | + template&, 882 | + _Args...>> = false> 883 | + explicit constexpr 884 | + optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args) 885 | + noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, 886 | + _Args...>) 887 | + : _Base(std::in_place, __il, std::forward<_Args>(__args)...) { } 888 | + 889 | + 890 | + // Assignment operators. 891 | + _GLIBCXX20_CONSTEXPR optional& 892 | + operator=(nullopt_t) noexcept 893 | + { 894 | + this->_M_reset(); 895 | + return *this; 896 | + } 897 | + 898 | + template 899 | + _GLIBCXX20_CONSTEXPR 900 | + enable_if_t<__and_v<__not_self<_Up>, 901 | + __not_<__and_, 902 | + is_same<_Tp, decay_t<_Up>>>>, 903 | + is_constructible<_Tp, _Up>, 904 | + is_assignable<_Tp&, _Up>>, 905 | + optional&> 906 | + operator=(_Up&& __u) 907 | + noexcept(__and_v, 908 | + is_nothrow_assignable<_Tp&, _Up>>) 909 | + { 910 | + if (this->_M_is_engaged()) 911 | + this->_M_get() = std::forward<_Up>(__u); 912 | + else 913 | + this->_M_construct(std::forward<_Up>(__u)); 914 | + 915 | + return *this; 916 | + } 917 | + 918 | + template 919 | + _GLIBCXX20_CONSTEXPR 920 | + enable_if_t<__and_v<__not_>, 921 | + is_constructible<_Tp, const _Up&>, 922 | + is_assignable<_Tp&, const _Up&>, 923 | + __not_<__converts_from_optional<_Tp, _Up>>, 924 | + __not_<__assigns_from_optional<_Tp, _Up>>>, 925 | + optional&> 926 | + operator=(const optional<_Up>& __u) 927 | + noexcept(__and_v, 928 | + is_nothrow_assignable<_Tp&, const _Up&>>) 929 | + { 930 | + if (__u) 931 | + { 932 | + if (this->_M_is_engaged()) 933 | + this->_M_get() = *__u; 934 | + else 935 | + this->_M_construct(*__u); 936 | + } 937 | + else 938 | + { 939 | + this->_M_reset(); 940 | + } 941 | + return *this; 942 | + } 943 | + 944 | + template 945 | + _GLIBCXX20_CONSTEXPR 946 | + enable_if_t<__and_v<__not_>, 947 | + is_constructible<_Tp, _Up>, 948 | + is_assignable<_Tp&, _Up>, 949 | + __not_<__converts_from_optional<_Tp, _Up>>, 950 | + __not_<__assigns_from_optional<_Tp, _Up>>>, 951 | + optional&> 952 | + operator=(optional<_Up>&& __u) 953 | + noexcept(__and_v, 954 | + is_nothrow_assignable<_Tp&, _Up>>) 955 | + { 956 | + if (__u) 957 | + { 958 | + if (this->_M_is_engaged()) 959 | + this->_M_get() = std::move(*__u); 960 | + else 961 | + this->_M_construct(std::move(*__u)); 962 | + } 963 | + else 964 | + { 965 | + this->_M_reset(); 966 | + } 967 | + 968 | + return *this; 969 | + } 970 | + 971 | + template 972 | + _GLIBCXX20_CONSTEXPR 973 | +#if 0 974 | + enable_if_t, _Tp&> 975 | + emplace(_Args&&... __args) 976 | + noexcept(is_nothrow_constructible_v<_Tp, _Args...>) 977 | +#else 978 | +// Drop the constructible checks 979 | + _Tp& emplace(_Args&&... __args) 980 | +#endif 981 | + { 982 | + this->_M_reset(); 983 | + this->_M_construct(std::forward<_Args>(__args)...); 984 | + return this->_M_get(); 985 | + } 986 | + 987 | + template 988 | + _GLIBCXX20_CONSTEXPR 989 | + enable_if_t&, _Args...>, 990 | + _Tp&> 991 | + emplace(initializer_list<_Up> __il, _Args&&... __args) 992 | + noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, 993 | + _Args...>) 994 | + { 995 | + this->_M_reset(); 996 | + this->_M_construct(__il, std::forward<_Args>(__args)...); 997 | + return this->_M_get(); 998 | + } 999 | + 1000 | + // Destructor is implicit, implemented in _Optional_base. 1001 | + 1002 | + // Swap. 1003 | + _GLIBCXX20_CONSTEXPR void 1004 | + swap(optional& __other) 1005 | + noexcept(is_nothrow_move_constructible_v<_Tp> 1006 | + && is_nothrow_swappable_v<_Tp>) 1007 | + { 1008 | + using std::swap; 1009 | + 1010 | + if (this->_M_is_engaged() && __other._M_is_engaged()) 1011 | + swap(this->_M_get(), __other._M_get()); 1012 | + else if (this->_M_is_engaged()) 1013 | + { 1014 | + __other._M_construct(std::move(this->_M_get())); 1015 | + this->_M_destruct(); 1016 | + } 1017 | + else if (__other._M_is_engaged()) 1018 | + { 1019 | + this->_M_construct(std::move(__other._M_get())); 1020 | + __other._M_destruct(); 1021 | + } 1022 | + } 1023 | + 1024 | + // Observers. 1025 | + constexpr const _Tp* 1026 | + operator->() const noexcept 1027 | + { return std::__addressof(this->_M_get()); } 1028 | + 1029 | + constexpr _Tp* 1030 | + operator->() noexcept 1031 | + { return std::__addressof(this->_M_get()); } 1032 | + 1033 | + constexpr const _Tp& 1034 | + operator*() const& noexcept 1035 | + { return this->_M_get(); } 1036 | + 1037 | + constexpr _Tp& 1038 | + operator*()& noexcept 1039 | + { return this->_M_get(); } 1040 | + 1041 | + constexpr _Tp&& 1042 | + operator*()&& noexcept 1043 | + { return std::move(this->_M_get()); } 1044 | + 1045 | + constexpr const _Tp&& 1046 | + operator*() const&& noexcept 1047 | + { return std::move(this->_M_get()); } 1048 | + 1049 | + constexpr explicit operator bool() const noexcept 1050 | + { return this->_M_is_engaged(); } 1051 | + 1052 | + constexpr bool has_value() const noexcept 1053 | + { return this->_M_is_engaged(); } 1054 | + 1055 | + constexpr const _Tp& 1056 | + value() const& 1057 | + { 1058 | + if (this->_M_is_engaged()) 1059 | + return this->_M_get(); 1060 | + __throw_bad_optional_access(); 1061 | + } 1062 | + 1063 | + constexpr _Tp& 1064 | + value()& 1065 | + { 1066 | + if (this->_M_is_engaged()) 1067 | + return this->_M_get(); 1068 | + __throw_bad_optional_access(); 1069 | + } 1070 | + 1071 | + constexpr _Tp&& 1072 | + value()&& 1073 | + { 1074 | + if (this->_M_is_engaged()) 1075 | + return std::move(this->_M_get()); 1076 | + __throw_bad_optional_access(); 1077 | + } 1078 | + 1079 | + constexpr const _Tp&& 1080 | + value() const&& 1081 | + { 1082 | + if (this->_M_is_engaged()) 1083 | + return std::move(this->_M_get()); 1084 | + __throw_bad_optional_access(); 1085 | + } 1086 | + 1087 | + template 1088 | + constexpr _Tp 1089 | + value_or(_Up&& __u) const& 1090 | + { 1091 | + static_assert(is_copy_constructible_v<_Tp>); 1092 | + static_assert(is_convertible_v<_Up&&, _Tp>); 1093 | + 1094 | + if (this->_M_is_engaged()) 1095 | + return this->_M_get(); 1096 | + else 1097 | + return static_cast<_Tp>(std::forward<_Up>(__u)); 1098 | + } 1099 | + 1100 | + template 1101 | + constexpr _Tp 1102 | + value_or(_Up&& __u) && 1103 | + { 1104 | + static_assert(is_move_constructible_v<_Tp>); 1105 | + static_assert(is_convertible_v<_Up&&, _Tp>); 1106 | + 1107 | + if (this->_M_is_engaged()) 1108 | + return std::move(this->_M_get()); 1109 | + else 1110 | + return static_cast<_Tp>(std::forward<_Up>(__u)); 1111 | + } 1112 | + 1113 | +#if __cpp_lib_optional >= 202110L 1114 | + // [optional.monadic] 1115 | + 1116 | + template 1117 | + constexpr auto 1118 | + and_then(_Fn&& __f) & 1119 | + { 1120 | + using _Up = remove_cvref_t>; 1121 | + static_assert(__is_optional_v>, 1122 | + "the function passed to std::optional::and_then " 1123 | + "must return a std::optional"); 1124 | + if (has_value()) 1125 | + return std::__invoke(std::forward<_Fn>(__f), **this); 1126 | + else 1127 | + return _Up(); 1128 | + } 1129 | + 1130 | + template 1131 | + constexpr auto 1132 | + and_then(_Fn&& __f) const & 1133 | + { 1134 | + using _Up = remove_cvref_t>; 1135 | + static_assert(__is_optional_v<_Up>, 1136 | + "the function passed to std::optional::and_then " 1137 | + "must return a std::optional"); 1138 | + if (has_value()) 1139 | + return std::__invoke(std::forward<_Fn>(__f), **this); 1140 | + else 1141 | + return _Up(); 1142 | + } 1143 | + 1144 | + template 1145 | + constexpr auto 1146 | + and_then(_Fn&& __f) && 1147 | + { 1148 | + using _Up = remove_cvref_t>; 1149 | + static_assert(__is_optional_v>, 1150 | + "the function passed to std::optional::and_then " 1151 | + "must return a std::optional"); 1152 | + if (has_value()) 1153 | + return std::__invoke(std::forward<_Fn>(__f), std::move(**this)); 1154 | + else 1155 | + return _Up(); 1156 | + } 1157 | + 1158 | + template 1159 | + constexpr auto 1160 | + and_then(_Fn&& __f) const && 1161 | + { 1162 | + using _Up = remove_cvref_t>; 1163 | + static_assert(__is_optional_v>, 1164 | + "the function passed to std::optional::and_then " 1165 | + "must return a std::optional"); 1166 | + if (has_value()) 1167 | + return std::__invoke(std::forward<_Fn>(__f), std::move(**this)); 1168 | + else 1169 | + return _Up(); 1170 | + } 1171 | + 1172 | + template 1173 | + constexpr auto 1174 | + transform(_Fn&& __f) & 1175 | + { 1176 | + using _Up = remove_cv_t>; 1177 | + if (has_value()) 1178 | + return optional<_Up>(_Optional_func<_Fn>{__f}, **this); 1179 | + else 1180 | + return optional<_Up>(); 1181 | + } 1182 | + 1183 | + template 1184 | + constexpr auto 1185 | + transform(_Fn&& __f) const & 1186 | + { 1187 | + using _Up = remove_cv_t>; 1188 | + if (has_value()) 1189 | + return optional<_Up>(_Optional_func<_Fn>{__f}, **this); 1190 | + else 1191 | + return optional<_Up>(); 1192 | + } 1193 | + 1194 | + template 1195 | + constexpr auto 1196 | + transform(_Fn&& __f) && 1197 | + { 1198 | + using _Up = remove_cv_t>; 1199 | + if (has_value()) 1200 | + return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(**this)); 1201 | + else 1202 | + return optional<_Up>(); 1203 | + } 1204 | + 1205 | + template 1206 | + constexpr auto 1207 | + transform(_Fn&& __f) const && 1208 | + { 1209 | + using _Up = remove_cv_t>; 1210 | + if (has_value()) 1211 | + return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(**this)); 1212 | + else 1213 | + return optional<_Up>(); 1214 | + } 1215 | + 1216 | + template requires invocable<_Fn> && copy_constructible<_Tp> 1217 | + constexpr optional 1218 | + or_else(_Fn&& __f) const& 1219 | + { 1220 | + using _Up = invoke_result_t<_Fn>; 1221 | + static_assert(is_same_v, optional>, 1222 | + "the function passed to std::optional::or_else " 1223 | + "must return a std::optional"); 1224 | + 1225 | + if (has_value()) 1226 | + return *this; 1227 | + else 1228 | + return std::forward<_Fn>(__f)(); 1229 | + } 1230 | + 1231 | + template requires invocable<_Fn> && move_constructible<_Tp> 1232 | + constexpr optional 1233 | + or_else(_Fn&& __f) && 1234 | + { 1235 | + using _Up = invoke_result_t<_Fn>; 1236 | + static_assert(is_same_v, optional>, 1237 | + "the function passed to std::optional::or_else " 1238 | + "must return a std::optional"); 1239 | + 1240 | + if (has_value()) 1241 | + return std::move(*this); 1242 | + else 1243 | + return std::forward<_Fn>(__f)(); 1244 | + } 1245 | +#endif 1246 | + 1247 | + _GLIBCXX20_CONSTEXPR void reset() noexcept { this->_M_reset(); } 1248 | + 1249 | + private: 1250 | +#if __cplusplus >= 202002L 1251 | + template friend class optional; 1252 | + 1253 | + template 1254 | + explicit constexpr 1255 | + optional(_Optional_func<_Fn> __f, _Value&& __v) 1256 | + { 1257 | + this->_M_payload._M_apply(__f, std::forward<_Value>(__v)); 1258 | + } 1259 | +#endif 1260 | + }; 1261 | + 1262 | + template 1263 | + using __optional_relop_t = 1264 | + enable_if_t::value, bool>; 1265 | + 1266 | + template 1267 | + using __optional_eq_t = __optional_relop_t< 1268 | + decltype(std::declval() == std::declval()) 1269 | + >; 1270 | + 1271 | + template 1272 | + using __optional_ne_t = __optional_relop_t< 1273 | + decltype(std::declval() != std::declval()) 1274 | + >; 1275 | + 1276 | + template 1277 | + using __optional_lt_t = __optional_relop_t< 1278 | + decltype(std::declval() < std::declval()) 1279 | + >; 1280 | + 1281 | + template 1282 | + using __optional_gt_t = __optional_relop_t< 1283 | + decltype(std::declval() > std::declval()) 1284 | + >; 1285 | + 1286 | + template 1287 | + using __optional_le_t = __optional_relop_t< 1288 | + decltype(std::declval() <= std::declval()) 1289 | + >; 1290 | + 1291 | + template 1292 | + using __optional_ge_t = __optional_relop_t< 1293 | + decltype(std::declval() >= std::declval()) 1294 | + >; 1295 | + 1296 | + // Comparisons between optional values. 1297 | + template 1298 | + constexpr auto 1299 | + operator==(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) 1300 | + -> __optional_eq_t<_Tp, _Up> 1301 | + { 1302 | + return static_cast(__lhs) == static_cast(__rhs) 1303 | + && (!__lhs || *__lhs == *__rhs); 1304 | + } 1305 | + 1306 | + template 1307 | + constexpr auto 1308 | + operator!=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) 1309 | + -> __optional_ne_t<_Tp, _Up> 1310 | + { 1311 | + return static_cast(__lhs) != static_cast(__rhs) 1312 | + || (static_cast(__lhs) && *__lhs != *__rhs); 1313 | + } 1314 | + 1315 | + template 1316 | + constexpr auto 1317 | + operator<(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) 1318 | + -> __optional_lt_t<_Tp, _Up> 1319 | + { 1320 | + return static_cast(__rhs) && (!__lhs || *__lhs < *__rhs); 1321 | + } 1322 | + 1323 | + template 1324 | + constexpr auto 1325 | + operator>(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) 1326 | + -> __optional_gt_t<_Tp, _Up> 1327 | + { 1328 | + return static_cast(__lhs) && (!__rhs || *__lhs > *__rhs); 1329 | + } 1330 | + 1331 | + template 1332 | + constexpr auto 1333 | + operator<=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) 1334 | + -> __optional_le_t<_Tp, _Up> 1335 | + { 1336 | + return !__lhs || (static_cast(__rhs) && *__lhs <= *__rhs); 1337 | + } 1338 | + 1339 | + template 1340 | + constexpr auto 1341 | + operator>=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) 1342 | + -> __optional_ge_t<_Tp, _Up> 1343 | + { 1344 | + return !__rhs || (static_cast(__lhs) && *__lhs >= *__rhs); 1345 | + } 1346 | + 1347 | +#ifdef __cpp_lib_three_way_comparison 1348 | + template _Up> 1349 | + constexpr compare_three_way_result_t<_Tp, _Up> 1350 | + operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y) 1351 | + { 1352 | + return __x && __y ? *__x <=> *__y : bool(__x) <=> bool(__y); 1353 | + } 1354 | +#endif 1355 | + 1356 | + // Comparisons with nullopt. 1357 | + template 1358 | + constexpr bool 1359 | + operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept 1360 | + { return !__lhs; } 1361 | + 1362 | +#ifdef __cpp_lib_three_way_comparison 1363 | + template 1364 | + constexpr strong_ordering 1365 | + operator<=>(const optional<_Tp>& __x, nullopt_t) noexcept 1366 | + { return bool(__x) <=> false; } 1367 | +#else 1368 | + template 1369 | + constexpr bool 1370 | + operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept 1371 | + { return !__rhs; } 1372 | + 1373 | + template 1374 | + constexpr bool 1375 | + operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept 1376 | + { return static_cast(__lhs); } 1377 | + 1378 | + template 1379 | + constexpr bool 1380 | + operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept 1381 | + { return static_cast(__rhs); } 1382 | + 1383 | + template 1384 | + constexpr bool 1385 | + operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept 1386 | + { return false; } 1387 | + 1388 | + template 1389 | + constexpr bool 1390 | + operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept 1391 | + { return static_cast(__rhs); } 1392 | + 1393 | + template 1394 | + constexpr bool 1395 | + operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept 1396 | + { return static_cast(__lhs); } 1397 | + 1398 | + template 1399 | + constexpr bool 1400 | + operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept 1401 | + { return false; } 1402 | + 1403 | + template 1404 | + constexpr bool 1405 | + operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept 1406 | + { return !__lhs; } 1407 | + 1408 | + template 1409 | + constexpr bool 1410 | + operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept 1411 | + { return true; } 1412 | + 1413 | + template 1414 | + constexpr bool 1415 | + operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept 1416 | + { return true; } 1417 | + 1418 | + template 1419 | + constexpr bool 1420 | + operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept 1421 | + { return !__rhs; } 1422 | +#endif // three-way-comparison 1423 | + 1424 | + // Comparisons with value type. 1425 | + template 1426 | + constexpr auto 1427 | + operator==(const optional<_Tp>& __lhs, const _Up& __rhs) 1428 | + -> __optional_eq_t<_Tp, _Up> 1429 | + { return __lhs && *__lhs == __rhs; } 1430 | + 1431 | + template 1432 | + constexpr auto 1433 | + operator==(const _Up& __lhs, const optional<_Tp>& __rhs) 1434 | + -> __optional_eq_t<_Up, _Tp> 1435 | + { return __rhs && __lhs == *__rhs; } 1436 | + 1437 | + template 1438 | + constexpr auto 1439 | + operator!=(const optional<_Tp>& __lhs, const _Up& __rhs) 1440 | + -> __optional_ne_t<_Tp, _Up> 1441 | + { return !__lhs || *__lhs != __rhs; } 1442 | + 1443 | + template 1444 | + constexpr auto 1445 | + operator!=(const _Up& __lhs, const optional<_Tp>& __rhs) 1446 | + -> __optional_ne_t<_Up, _Tp> 1447 | + { return !__rhs || __lhs != *__rhs; } 1448 | + 1449 | + template 1450 | + constexpr auto 1451 | + operator<(const optional<_Tp>& __lhs, const _Up& __rhs) 1452 | + -> __optional_lt_t<_Tp, _Up> 1453 | + { return !__lhs || *__lhs < __rhs; } 1454 | + 1455 | + template 1456 | + constexpr auto 1457 | + operator<(const _Up& __lhs, const optional<_Tp>& __rhs) 1458 | + -> __optional_lt_t<_Up, _Tp> 1459 | + { return __rhs && __lhs < *__rhs; } 1460 | + 1461 | + template 1462 | + constexpr auto 1463 | + operator>(const optional<_Tp>& __lhs, const _Up& __rhs) 1464 | + -> __optional_gt_t<_Tp, _Up> 1465 | + { return __lhs && *__lhs > __rhs; } 1466 | + 1467 | + template 1468 | + constexpr auto 1469 | + operator>(const _Up& __lhs, const optional<_Tp>& __rhs) 1470 | + -> __optional_gt_t<_Up, _Tp> 1471 | + { return !__rhs || __lhs > *__rhs; } 1472 | + 1473 | + template 1474 | + constexpr auto 1475 | + operator<=(const optional<_Tp>& __lhs, const _Up& __rhs) 1476 | + -> __optional_le_t<_Tp, _Up> 1477 | + { return !__lhs || *__lhs <= __rhs; } 1478 | + 1479 | + template 1480 | + constexpr auto 1481 | + operator<=(const _Up& __lhs, const optional<_Tp>& __rhs) 1482 | + -> __optional_le_t<_Up, _Tp> 1483 | + { return __rhs && __lhs <= *__rhs; } 1484 | + 1485 | + template 1486 | + constexpr auto 1487 | + operator>=(const optional<_Tp>& __lhs, const _Up& __rhs) 1488 | + -> __optional_ge_t<_Tp, _Up> 1489 | + { return __lhs && *__lhs >= __rhs; } 1490 | + 1491 | + template 1492 | + constexpr auto 1493 | + operator>=(const _Up& __lhs, const optional<_Tp>& __rhs) 1494 | + -> __optional_ge_t<_Up, _Tp> 1495 | + { return !__rhs || __lhs >= *__rhs; } 1496 | + 1497 | +#ifdef __cpp_lib_three_way_comparison 1498 | + template 1499 | + requires (!__is_optional_v<_Up>) 1500 | + && three_way_comparable_with<_Tp, _Up> 1501 | + constexpr compare_three_way_result_t<_Tp, _Up> 1502 | + operator<=>(const optional<_Tp>& __x, const _Up& __v) 1503 | + { return bool(__x) ? *__x <=> __v : strong_ordering::less; } 1504 | +#endif 1505 | + 1506 | + // Swap and creation functions. 1507 | + 1508 | + // _GLIBCXX_RESOLVE_LIB_DEFECTS 1509 | + // 2748. swappable traits for optionals 1510 | + template 1511 | + _GLIBCXX20_CONSTEXPR 1512 | + inline enable_if_t && is_swappable_v<_Tp>> 1513 | + swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs) 1514 | + noexcept(noexcept(__lhs.swap(__rhs))) 1515 | + { __lhs.swap(__rhs); } 1516 | + 1517 | + template 1518 | + enable_if_t && is_swappable_v<_Tp>)> 1519 | + swap(optional<_Tp>&, optional<_Tp>&) = delete; 1520 | + 1521 | + template 1522 | + constexpr 1523 | + enable_if_t, _Tp>, 1524 | + optional>> 1525 | + make_optional(_Tp&& __t) 1526 | + noexcept(is_nothrow_constructible_v>, _Tp>) 1527 | + { return optional>{ std::forward<_Tp>(__t) }; } 1528 | + 1529 | +#if 0 1530 | + template 1531 | + constexpr 1532 | + enable_if_t, 1533 | + optional<_Tp>> 1534 | + make_optional(_Args&&... __args) 1535 | + noexcept(is_nothrow_constructible_v<_Tp, _Args...>) 1536 | +#else 1537 | +// Drop is_constructible assertions, that's all that's needed 1538 | + template 1539 | + constexpr 1540 | + optional<_Tp> 1541 | + make_optional(_Args&&... __args) 1542 | +#endif 1543 | + { return optional<_Tp>{ in_place, std::forward<_Args>(__args)... }; } 1544 | + 1545 | + template 1546 | + constexpr 1547 | + enable_if_t&, _Args...>, 1548 | + optional<_Tp>> 1549 | + make_optional(initializer_list<_Up> __il, _Args&&... __args) 1550 | + noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>) 1551 | + { return optional<_Tp>{ in_place, __il, std::forward<_Args>(__args)... }; } 1552 | + 1553 | + // Hash. 1554 | + 1555 | + template, 1556 | + bool = __poison_hash<_Up>::__enable_hash_call> 1557 | + struct __optional_hash_call_base 1558 | + { 1559 | + size_t 1560 | + operator()(const optional<_Tp>& __t) const 1561 | + noexcept(noexcept(hash<_Up>{}(*__t))) 1562 | + { 1563 | + // We pick an arbitrary hash for disengaged optionals which hopefully 1564 | + // usual values of _Tp won't typically hash to. 1565 | + constexpr size_t __magic_disengaged_hash = static_cast(-3333); 1566 | + return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash; 1567 | + } 1568 | + }; 1569 | + 1570 | + template 1571 | + struct __optional_hash_call_base<_Tp, _Up, false> {}; 1572 | + 1573 | + template 1574 | + struct hash> 1575 | + : private __poison_hash>, 1576 | + public __optional_hash_call_base<_Tp> 1577 | + { 1578 | + using result_type [[__deprecated__]] = size_t; 1579 | + using argument_type [[__deprecated__]] = optional<_Tp>; 1580 | + }; 1581 | + 1582 | + template 1583 | + struct __is_fast_hash>> : __is_fast_hash> 1584 | + { }; 1585 | + 1586 | + /// @} 1587 | + 1588 | +#if __cpp_deduction_guides >= 201606 1589 | + template optional(_Tp) -> optional<_Tp>; 1590 | +#endif 1591 | + 1592 | +_GLIBCXX_END_NAMESPACE_VERSION 1593 | +} // namespace std 1594 | + 1595 | +#endif // C++17 1596 | + 1597 | +#endif // _GLIBCXX_OPTIONAL 1598 | --------------------------------------------------------------------------------