mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-06-02 23:59:49 -04:00
libstratosphere: use from /atmosphere/libraries
This commit is contained in:
parent
0105455086
commit
d4f99ddb4d
338 changed files with 293 additions and 30662 deletions
|
@ -1,6 +1,6 @@
|
|||
MODULES := loader pm sm boot ams_mitm spl eclct.stub ro creport fatal dmnt boot2
|
||||
|
||||
SUBFOLDERS := libstratosphere $(MODULES)
|
||||
SUBFOLDERS := $(MODULES)
|
||||
|
||||
TOPTARGETS := all clean
|
||||
|
||||
|
@ -9,6 +9,4 @@ $(TOPTARGETS): $(SUBFOLDERS)
|
|||
$(SUBFOLDERS):
|
||||
$(MAKE) -C $@ $(MAKECMDGOALS)
|
||||
|
||||
$(MODULES): libstratosphere
|
||||
|
||||
.PHONY: $(TOPTARGETS) $(SUBFOLDERS)
|
||||
|
|
|
@ -1,76 +1,7 @@
|
|||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
# pull in common stratosphere sysmodule configuration
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
|
||||
endif
|
||||
|
||||
TOPDIR ?= $(CURDIR)
|
||||
include $(DEVKITPRO)/libnx/switch_rules
|
||||
|
||||
AMSBRANCH := $(shell git symbolic-ref --short HEAD)
|
||||
AMSREV := $(AMSBRANCH)-$(shell git rev-parse --short HEAD)
|
||||
|
||||
ifneq (, $(strip $(shell git status --porcelain 2>/dev/null)))
|
||||
AMSREV := $(AMSREV)-dirty
|
||||
endif
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# DATA is a list of directories containing data files
|
||||
# INCLUDES is a list of directories containing header files
|
||||
# EXEFS_SRC is the optional input directory containing data copied into exefs, if anything this normally should only contain "main.npdm".
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := $(notdir $(CURDIR))
|
||||
BUILD := build
|
||||
SOURCES := source source/fs_mitm source/set_mitm source/bpc_mitm source/ns_mitm source/hid_mitm
|
||||
DATA := data
|
||||
INCLUDES := include ../../common/include
|
||||
EXEFS_SRC := exefs_src
|
||||
|
||||
DEFINES := -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\"
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE
|
||||
|
||||
CFLAGS := -g -Wall -O2 -ffunction-sections \
|
||||
$(ARCH) $(DEFINES)
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17
|
||||
|
||||
CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
|
||||
-Wl,--wrap,__cxa_throw \
|
||||
-Wl,--wrap,__cxa_rethrow \
|
||||
-Wl,--wrap,__cxa_allocate_exception \
|
||||
-Wl,--wrap,__cxa_free_exception \
|
||||
-Wl,--wrap,__cxa_begin_catch \
|
||||
-Wl,--wrap,__cxa_end_catch \
|
||||
-Wl,--wrap,__cxa_call_unexpected \
|
||||
-Wl,--wrap,__cxa_call_terminate \
|
||||
-Wl,--wrap,__gxx_personality_v0 \
|
||||
-Wl,--wrap,_Unwind_Resume \
|
||||
-Wl,--wrap,_ZSt19__throw_logic_errorPKc \
|
||||
-Wl,--wrap,_ZSt20__throw_length_errorPKc \
|
||||
-Wl,--wrap,_ZNSt11logic_errorC2EPKc
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS := -lstratosphere -lnx
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(PORTLIBS) $(LIBNX) $(CURDIR)/../libstratosphere
|
||||
|
||||
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../../libraries/config/templates/stratosphere.mk
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
|
@ -87,9 +18,25 @@ export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
|||
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.c)) $(notdir $(wildcard $(dir)/*.board.*.c)) $(notdir $(wildcard $(dir)/*.os.*.c)), \
|
||||
$(notdir $(wildcard $(dir)/*.c))))
|
||||
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).c)))
|
||||
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).c)))
|
||||
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).c)))
|
||||
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.cpp)) $(notdir $(wildcard $(dir)/*.board.*.cpp)) $(notdir $(wildcard $(dir)/*.os.*.cpp)), \
|
||||
$(notdir $(wildcard $(dir)/*.cpp))))
|
||||
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).cpp)))
|
||||
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).cpp)))
|
||||
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).cpp)))
|
||||
|
||||
SFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.s)) $(notdir $(wildcard $(dir)/*.board.*.s)) $(notdir $(wildcard $(dir)/*.os.*.s)), \
|
||||
$(notdir $(wildcard $(dir)/*.s))))
|
||||
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).s)))
|
||||
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).s)))
|
||||
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).s)))
|
||||
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
|
|
|
@ -1,83 +1,7 @@
|
|||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
# pull in common stratosphere sysmodule configuration
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
|
||||
endif
|
||||
|
||||
TOPDIR ?= $(CURDIR)
|
||||
include $(DEVKITPRO)/libnx/switch_rules
|
||||
|
||||
AMSBRANCH := $(shell git symbolic-ref --short HEAD)
|
||||
AMSREV := $(AMSBRANCH)-$(shell git rev-parse --short HEAD)
|
||||
|
||||
ifneq (, $(strip $(shell git status --porcelain 2>/dev/null)))
|
||||
AMSREV := $(AMSREV)-dirty
|
||||
endif
|
||||
|
||||
define _bin2o
|
||||
bin2s $< | $(AS) -o $(@)
|
||||
echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _ | tr - _)`"_end[];" > `(echo $(<F) | tr . _ | tr - _)`.h
|
||||
echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _ | tr - _)`"[];" >> `(echo $(<F) | tr . _ | tr - _)`.h
|
||||
echo "extern const u32" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _ | tr - _)`_size";" >> `(echo $(<F) | tr . _ | tr - _)`.h
|
||||
endef
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# DATA is a list of directories containing data files
|
||||
# INCLUDES is a list of directories containing header files
|
||||
# EXEFS_SRC is the optional input directory containing data copied into exefs, if anything this normally should only contain "main.npdm".
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := $(notdir $(CURDIR))
|
||||
BUILD := build
|
||||
SOURCES := source source/i2c source/i2c/driver source/i2c/driver/impl source/gpio source/pinmux
|
||||
DATA := data
|
||||
INCLUDES := include ../../common/include
|
||||
EXEFS_SRC := exefs_src
|
||||
|
||||
DEFINES := -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\"
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE
|
||||
|
||||
CFLAGS := -g -Wall -O2 -ffunction-sections \
|
||||
$(ARCH) $(DEFINES)
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17
|
||||
|
||||
CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
|
||||
-Wl,--wrap,__cxa_throw \
|
||||
-Wl,--wrap,__cxa_rethrow \
|
||||
-Wl,--wrap,__cxa_allocate_exception \
|
||||
-Wl,--wrap,__cxa_free_exception \
|
||||
-Wl,--wrap,__cxa_begin_catch \
|
||||
-Wl,--wrap,__cxa_end_catch \
|
||||
-Wl,--wrap,__cxa_call_unexpected \
|
||||
-Wl,--wrap,__cxa_call_terminate \
|
||||
-Wl,--wrap,__gxx_personality_v0 \
|
||||
-Wl,--wrap,_Unwind_Resume \
|
||||
-Wl,--wrap,_ZSt19__throw_logic_errorPKc \
|
||||
-Wl,--wrap,_ZSt20__throw_length_errorPKc \
|
||||
-Wl,--wrap,_ZNSt11logic_errorC2EPKc
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS := -lstratosphere -lnx
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(PORTLIBS) $(LIBNX) $(CURDIR)/../libstratosphere
|
||||
|
||||
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../../libraries/config/templates/stratosphere.mk
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
|
@ -94,11 +18,37 @@ export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
|||
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.c)) $(notdir $(wildcard $(dir)/*.board.*.c)) $(notdir $(wildcard $(dir)/*.os.*.c)), \
|
||||
$(notdir $(wildcard $(dir)/*.c))))
|
||||
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).c)))
|
||||
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).c)))
|
||||
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).c)))
|
||||
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.cpp)) $(notdir $(wildcard $(dir)/*.board.*.cpp)) $(notdir $(wildcard $(dir)/*.os.*.cpp)), \
|
||||
$(notdir $(wildcard $(dir)/*.cpp))))
|
||||
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).cpp)))
|
||||
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).cpp)))
|
||||
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).cpp)))
|
||||
|
||||
SFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.s)) $(notdir $(wildcard $(dir)/*.board.*.s)) $(notdir $(wildcard $(dir)/*.os.*.s)), \
|
||||
$(notdir $(wildcard $(dir)/*.s))))
|
||||
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).s)))
|
||||
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).s)))
|
||||
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).s)))
|
||||
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) fusee-primary.bin
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# boot has a custom bin2o rule for fusee-primary -> fusee_primary
|
||||
#---------------------------------------------------------------------------------
|
||||
define _bin2o
|
||||
bin2s $< | $(AS) -o $(@)
|
||||
echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _ | tr - _)`"_end[];" > `(echo $(<F) | tr . _ | tr - _)`.h
|
||||
echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _ | tr - _)`"[];" >> `(echo $(<F) | tr . _ | tr - _)`.h
|
||||
echo "extern const u32" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _ | tr - _)`_size";" >> `(echo $(<F) | tr . _ | tr - _)`.h
|
||||
endef
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
|
|
|
@ -1,76 +1,7 @@
|
|||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
# pull in common stratosphere sysmodule configuration
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
|
||||
endif
|
||||
|
||||
TOPDIR ?= $(CURDIR)
|
||||
include $(DEVKITPRO)/libnx/switch_rules
|
||||
|
||||
AMSBRANCH := $(shell git symbolic-ref --short HEAD)
|
||||
AMSREV := $(AMSBRANCH)-$(shell git rev-parse --short HEAD)
|
||||
|
||||
ifneq (, $(strip $(shell git status --porcelain 2>/dev/null)))
|
||||
AMSREV := $(AMSREV)-dirty
|
||||
endif
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# DATA is a list of directories containing data files
|
||||
# INCLUDES is a list of directories containing header files
|
||||
# EXEFS_SRC is the optional input directory containing data copied into exefs, if anything this normally should only contain "main.npdm".
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := $(notdir $(CURDIR))
|
||||
BUILD := build
|
||||
SOURCES := source
|
||||
DATA := data
|
||||
INCLUDES := include ../../common/include
|
||||
EXEFS_SRC := exefs_src
|
||||
|
||||
DEFINES := -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" -DINI_MAX_LINE=768
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE
|
||||
|
||||
CFLAGS := -g -Wall -O2 -ffunction-sections \
|
||||
$(ARCH) $(DEFINES)
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17
|
||||
|
||||
CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
|
||||
-Wl,--wrap,__cxa_throw \
|
||||
-Wl,--wrap,__cxa_rethrow \
|
||||
-Wl,--wrap,__cxa_allocate_exception \
|
||||
-Wl,--wrap,__cxa_free_exception \
|
||||
-Wl,--wrap,__cxa_begin_catch \
|
||||
-Wl,--wrap,__cxa_end_catch \
|
||||
-Wl,--wrap,__cxa_call_unexpected \
|
||||
-Wl,--wrap,__cxa_call_terminate \
|
||||
-Wl,--wrap,__gxx_personality_v0 \
|
||||
-Wl,--wrap,_Unwind_Resume \
|
||||
-Wl,--wrap,_ZSt19__throw_logic_errorPKc \
|
||||
-Wl,--wrap,_ZSt20__throw_length_errorPKc \
|
||||
-Wl,--wrap,_ZNSt11logic_errorC2EPKc
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS := -lstratosphere -lnx
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(PORTLIBS) $(LIBNX) $(CURDIR)/../libstratosphere
|
||||
|
||||
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../../libraries/config/templates/stratosphere.mk
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
|
@ -87,9 +18,25 @@ export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
|||
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.c)) $(notdir $(wildcard $(dir)/*.board.*.c)) $(notdir $(wildcard $(dir)/*.os.*.c)), \
|
||||
$(notdir $(wildcard $(dir)/*.c))))
|
||||
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).c)))
|
||||
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).c)))
|
||||
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).c)))
|
||||
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.cpp)) $(notdir $(wildcard $(dir)/*.board.*.cpp)) $(notdir $(wildcard $(dir)/*.os.*.cpp)), \
|
||||
$(notdir $(wildcard $(dir)/*.cpp))))
|
||||
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).cpp)))
|
||||
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).cpp)))
|
||||
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).cpp)))
|
||||
|
||||
SFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.s)) $(notdir $(wildcard $(dir)/*.board.*.s)) $(notdir $(wildcard $(dir)/*.os.*.s)), \
|
||||
$(notdir $(wildcard $(dir)/*.s))))
|
||||
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).s)))
|
||||
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).s)))
|
||||
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).s)))
|
||||
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
|
|
|
@ -1,76 +1,7 @@
|
|||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
# pull in common stratosphere sysmodule configuration
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
|
||||
endif
|
||||
|
||||
TOPDIR ?= $(CURDIR)
|
||||
include $(DEVKITPRO)/libnx/switch_rules
|
||||
|
||||
AMSBRANCH := $(shell git symbolic-ref --short HEAD)
|
||||
AMSREV := $(AMSBRANCH)-$(shell git rev-parse --short HEAD)
|
||||
|
||||
ifneq (, $(strip $(shell git status --porcelain 2>/dev/null)))
|
||||
AMSREV := $(AMSREV)-dirty
|
||||
endif
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# DATA is a list of directories containing data files
|
||||
# INCLUDES is a list of directories containing header files
|
||||
# EXEFS_SRC is the optional input directory containing data copied into exefs, if anything this normally should only contain "main.npdm".
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := $(notdir $(CURDIR))
|
||||
BUILD := build
|
||||
SOURCES := source
|
||||
DATA := data
|
||||
INCLUDES := include ../../common/include
|
||||
EXEFS_SRC := exefs_src
|
||||
|
||||
DEFINES := -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\"
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE
|
||||
|
||||
CFLAGS := -g -Wall -O2 -ffunction-sections \
|
||||
$(ARCH) $(DEFINES)
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17
|
||||
|
||||
CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
|
||||
-Wl,--wrap,__cxa_throw \
|
||||
-Wl,--wrap,__cxa_rethrow \
|
||||
-Wl,--wrap,__cxa_allocate_exception \
|
||||
-Wl,--wrap,__cxa_free_exception \
|
||||
-Wl,--wrap,__cxa_begin_catch \
|
||||
-Wl,--wrap,__cxa_end_catch \
|
||||
-Wl,--wrap,__cxa_call_unexpected \
|
||||
-Wl,--wrap,__cxa_call_terminate \
|
||||
-Wl,--wrap,__gxx_personality_v0 \
|
||||
-Wl,--wrap,_Unwind_Resume \
|
||||
-Wl,--wrap,_ZSt19__throw_logic_errorPKc \
|
||||
-Wl,--wrap,_ZSt20__throw_length_errorPKc \
|
||||
-Wl,--wrap,_ZNSt11logic_errorC2EPKc
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS := -lstratosphere -lnx
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(PORTLIBS) $(LIBNX) $(CURDIR)/../libstratosphere
|
||||
|
||||
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../../libraries/config/templates/stratosphere.mk
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
|
@ -87,9 +18,25 @@ export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
|||
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.c)) $(notdir $(wildcard $(dir)/*.board.*.c)) $(notdir $(wildcard $(dir)/*.os.*.c)), \
|
||||
$(notdir $(wildcard $(dir)/*.c))))
|
||||
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).c)))
|
||||
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).c)))
|
||||
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).c)))
|
||||
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.cpp)) $(notdir $(wildcard $(dir)/*.board.*.cpp)) $(notdir $(wildcard $(dir)/*.os.*.cpp)), \
|
||||
$(notdir $(wildcard $(dir)/*.cpp))))
|
||||
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).cpp)))
|
||||
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).cpp)))
|
||||
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).cpp)))
|
||||
|
||||
SFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.s)) $(notdir $(wildcard $(dir)/*.board.*.s)) $(notdir $(wildcard $(dir)/*.os.*.s)), \
|
||||
$(notdir $(wildcard $(dir)/*.s))))
|
||||
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).s)))
|
||||
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).s)))
|
||||
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).s)))
|
||||
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
|
|
|
@ -1,76 +1,7 @@
|
|||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
# pull in common stratosphere sysmodule configuration
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
|
||||
endif
|
||||
|
||||
TOPDIR ?= $(CURDIR)
|
||||
include $(DEVKITPRO)/libnx/switch_rules
|
||||
|
||||
AMSBRANCH := $(shell git symbolic-ref --short HEAD)
|
||||
AMSREV := $(AMSBRANCH)-$(shell git rev-parse --short HEAD)
|
||||
|
||||
ifneq (, $(strip $(shell git status --porcelain 2>/dev/null)))
|
||||
AMSREV := $(AMSREV)-dirty
|
||||
endif
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# DATA is a list of directories containing data files
|
||||
# INCLUDES is a list of directories containing header files
|
||||
# EXEFS_SRC is the optional input directory containing data copied into exefs, if anything this normally should only contain "main.npdm".
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := $(notdir $(CURDIR))
|
||||
BUILD := build
|
||||
SOURCES := source source/cheat source/cheat/impl
|
||||
DATA := data
|
||||
INCLUDES := include ../../common/include
|
||||
EXEFS_SRC := exefs_src
|
||||
|
||||
DEFINES := -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\"
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE
|
||||
|
||||
CFLAGS := -g -Wall -O2 -ffunction-sections \
|
||||
$(ARCH) $(DEFINES)
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17
|
||||
|
||||
CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
|
||||
-Wl,--wrap,__cxa_throw \
|
||||
-Wl,--wrap,__cxa_rethrow \
|
||||
-Wl,--wrap,__cxa_allocate_exception \
|
||||
-Wl,--wrap,__cxa_free_exception \
|
||||
-Wl,--wrap,__cxa_begin_catch \
|
||||
-Wl,--wrap,__cxa_end_catch \
|
||||
-Wl,--wrap,__cxa_call_unexpected \
|
||||
-Wl,--wrap,__cxa_call_terminate \
|
||||
-Wl,--wrap,__gxx_personality_v0 \
|
||||
-Wl,--wrap,_Unwind_Resume \
|
||||
-Wl,--wrap,_ZSt19__throw_logic_errorPKc \
|
||||
-Wl,--wrap,_ZSt20__throw_length_errorPKc \
|
||||
-Wl,--wrap,_ZNSt11logic_errorC2EPKc
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS := -lstratosphere -lnx
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(PORTLIBS) $(LIBNX) $(CURDIR)/../libstratosphere
|
||||
|
||||
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../../libraries/config/templates/stratosphere.mk
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
|
@ -87,9 +18,25 @@ export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
|||
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.c)) $(notdir $(wildcard $(dir)/*.board.*.c)) $(notdir $(wildcard $(dir)/*.os.*.c)), \
|
||||
$(notdir $(wildcard $(dir)/*.c))))
|
||||
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).c)))
|
||||
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).c)))
|
||||
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).c)))
|
||||
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.cpp)) $(notdir $(wildcard $(dir)/*.board.*.cpp)) $(notdir $(wildcard $(dir)/*.os.*.cpp)), \
|
||||
$(notdir $(wildcard $(dir)/*.cpp))))
|
||||
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).cpp)))
|
||||
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).cpp)))
|
||||
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).cpp)))
|
||||
|
||||
SFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.s)) $(notdir $(wildcard $(dir)/*.board.*.s)) $(notdir $(wildcard $(dir)/*.os.*.s)), \
|
||||
$(notdir $(wildcard $(dir)/*.s))))
|
||||
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).s)))
|
||||
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).s)))
|
||||
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).s)))
|
||||
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
|
|
|
@ -1,76 +1,7 @@
|
|||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
# pull in common stratosphere sysmodule configuration
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
|
||||
endif
|
||||
|
||||
TOPDIR ?= $(CURDIR)
|
||||
include $(DEVKITPRO)/libnx/switch_rules
|
||||
|
||||
AMSBRANCH := $(shell git symbolic-ref --short HEAD)
|
||||
AMSREV := $(AMSBRANCH)-$(shell git rev-parse --short HEAD)
|
||||
|
||||
ifneq (, $(strip $(shell git status --porcelain 2>/dev/null)))
|
||||
AMSREV := $(AMSREV)-dirty
|
||||
endif
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# DATA is a list of directories containing data files
|
||||
# INCLUDES is a list of directories containing header files
|
||||
# EXEFS_SRC is the optional input directory containing data copied into exefs, if anything this normally should only contain "main.npdm".
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := $(notdir $(CURDIR))
|
||||
BUILD := build
|
||||
SOURCES := source
|
||||
DATA := data
|
||||
INCLUDES := include ../../common/include
|
||||
EXEFS_SRC := exefs_src
|
||||
|
||||
DEFINES := -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\" -DINI_MAX_LINE=768
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE
|
||||
|
||||
CFLAGS := -g -Wall -O2 -ffunction-sections \
|
||||
$(ARCH) $(DEFINES)
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17
|
||||
|
||||
CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
|
||||
-Wl,--wrap,__cxa_throw \
|
||||
-Wl,--wrap,__cxa_rethrow \
|
||||
-Wl,--wrap,__cxa_allocate_exception \
|
||||
-Wl,--wrap,__cxa_free_exception \
|
||||
-Wl,--wrap,__cxa_begin_catch \
|
||||
-Wl,--wrap,__cxa_end_catch \
|
||||
-Wl,--wrap,__cxa_call_unexpected \
|
||||
-Wl,--wrap,__cxa_call_terminate \
|
||||
-Wl,--wrap,__gxx_personality_v0 \
|
||||
-Wl,--wrap,_Unwind_Resume \
|
||||
-Wl,--wrap,_ZSt19__throw_logic_errorPKc \
|
||||
-Wl,--wrap,_ZSt20__throw_length_errorPKc \
|
||||
-Wl,--wrap,_ZNSt11logic_errorC2EPKc
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS := -lstratosphere -lnx
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(PORTLIBS) $(LIBNX) $(CURDIR)/../libstratosphere
|
||||
|
||||
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../../libraries/config/templates/stratosphere.mk
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
|
@ -87,9 +18,25 @@ export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
|||
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.c)) $(notdir $(wildcard $(dir)/*.board.*.c)) $(notdir $(wildcard $(dir)/*.os.*.c)), \
|
||||
$(notdir $(wildcard $(dir)/*.c))))
|
||||
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).c)))
|
||||
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).c)))
|
||||
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).c)))
|
||||
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.cpp)) $(notdir $(wildcard $(dir)/*.board.*.cpp)) $(notdir $(wildcard $(dir)/*.os.*.cpp)), \
|
||||
$(notdir $(wildcard $(dir)/*.cpp))))
|
||||
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).cpp)))
|
||||
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).cpp)))
|
||||
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).cpp)))
|
||||
|
||||
SFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.s)) $(notdir $(wildcard $(dir)/*.board.*.s)) $(notdir $(wildcard $(dir)/*.os.*.s)), \
|
||||
$(notdir $(wildcard $(dir)/*.s))))
|
||||
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).s)))
|
||||
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).s)))
|
||||
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).s)))
|
||||
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
|
|
|
@ -1,76 +1,14 @@
|
|||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
# pull in common stratosphere sysmodule configuration
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
|
||||
endif
|
||||
|
||||
TOPDIR ?= $(CURDIR)
|
||||
include $(DEVKITPRO)/libnx/switch_rules
|
||||
|
||||
AMSBRANCH := $(shell git symbolic-ref --short HEAD)
|
||||
AMSREV := $(AMSBRANCH)-$(shell git rev-parse --short HEAD)
|
||||
|
||||
ifneq (, $(strip $(shell git status --porcelain 2>/dev/null)))
|
||||
AMSREV := $(AMSREV)-dirty
|
||||
endif
|
||||
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../../libraries/config/templates/stratosphere.mk
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# DATA is a list of directories containing data files
|
||||
# INCLUDES is a list of directories containing header files
|
||||
# EXEFS_SRC is the optional input directory containing data copied into exefs, if anything this normally should only contain "main.npdm".
|
||||
# atmosphere-fatal needs freetype.
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := $(notdir $(CURDIR))
|
||||
BUILD := build
|
||||
SOURCES := source
|
||||
DATA := data
|
||||
INCLUDES := include ../../common/include
|
||||
EXEFS_SRC := exefs_src
|
||||
|
||||
DEFINES := -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\"
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE
|
||||
|
||||
CFLAGS := -g -Wall -O2 -ffunction-sections \
|
||||
$(ARCH) $(DEFINES)
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__ `freetype-config --cflags`
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17
|
||||
|
||||
CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
|
||||
-Wl,--wrap,__cxa_throw \
|
||||
-Wl,--wrap,__cxa_rethrow \
|
||||
-Wl,--wrap,__cxa_allocate_exception \
|
||||
-Wl,--wrap,__cxa_free_exception \
|
||||
-Wl,--wrap,__cxa_begin_catch \
|
||||
-Wl,--wrap,__cxa_end_catch \
|
||||
-Wl,--wrap,__cxa_call_unexpected \
|
||||
-Wl,--wrap,__cxa_call_terminate \
|
||||
-Wl,--wrap,__gxx_personality_v0 \
|
||||
-Wl,--wrap,_Unwind_Resume \
|
||||
-Wl,--wrap,_ZSt19__throw_logic_errorPKc \
|
||||
-Wl,--wrap,_ZSt20__throw_length_errorPKc \
|
||||
-Wl,--wrap,_ZNSt11logic_errorC2EPKc
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS := `freetype-config --libs` -lstratosphere -lnx
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(PORTLIBS) $(LIBNX) $(CURDIR)/../libstratosphere
|
||||
|
||||
LIBS += `freetype-config --libs`
|
||||
CFLAGS += `freetype-config --cflags`
|
||||
CXXFLAGS += `freetype-config --cflags`
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
|
@ -87,9 +25,25 @@ export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
|||
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.c)) $(notdir $(wildcard $(dir)/*.board.*.c)) $(notdir $(wildcard $(dir)/*.os.*.c)), \
|
||||
$(notdir $(wildcard $(dir)/*.c))))
|
||||
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).c)))
|
||||
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).c)))
|
||||
CFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).c)))
|
||||
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.cpp)) $(notdir $(wildcard $(dir)/*.board.*.cpp)) $(notdir $(wildcard $(dir)/*.os.*.cpp)), \
|
||||
$(notdir $(wildcard $(dir)/*.cpp))))
|
||||
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).cpp)))
|
||||
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).cpp)))
|
||||
CPPFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).cpp)))
|
||||
|
||||
SFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.s)) $(notdir $(wildcard $(dir)/*.board.*.s)) $(notdir $(wildcard $(dir)/*.os.*.s)), \
|
||||
$(notdir $(wildcard $(dir)/*.s))))
|
||||
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATMOSPHERE_ARCH_NAME).s)))
|
||||
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).s)))
|
||||
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).s)))
|
||||
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
|
|
74
stratosphere/libstratosphere/.gitignore
vendored
74
stratosphere/libstratosphere/.gitignore
vendored
|
@ -1,74 +0,0 @@
|
|||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
*.lst
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# Switch Executables
|
||||
*.nso
|
||||
*.nro
|
||||
*.nacp
|
||||
*.npdm
|
||||
*.pfs0
|
||||
*.nsp
|
||||
*.kip
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
# Distribution files
|
||||
*.tgz
|
||||
*.zip
|
||||
|
||||
.**/
|
||||
|
||||
# NOTE: make sure to make exceptions to this pattern when needed!
|
||||
*.bin
|
||||
|
||||
**/out
|
||||
**/build
|
0
stratosphere/libstratosphere/.gitmodules
vendored
0
stratosphere/libstratosphere/.gitmodules
vendored
|
@ -1,12 +0,0 @@
|
|||
; DO NOT EDIT (unless you know what you are doing)
|
||||
;
|
||||
; This subdirectory is a git "subrepo", and this file is maintained by the
|
||||
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
|
||||
;
|
||||
[subrepo]
|
||||
remote = https://github.com/Atmosphere-NX/libstratosphere
|
||||
branch = master
|
||||
commit = 303fc400dda9e592acbcb405153dd0dbde36281d
|
||||
parent = 9d7b52e2d4c0112f0f6d708faa66ea53f53961e4
|
||||
method = merge
|
||||
cmdver = 0.4.0
|
|
@ -1,339 +0,0 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
|
@ -1,142 +0,0 @@
|
|||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
|
||||
endif
|
||||
|
||||
TOPDIR ?= $(CURDIR)
|
||||
include $(DEVKITPRO)/libnx/switch_rules
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# SOURCES is a list of directories containing source code
|
||||
# DATA is a list of directories containing data files
|
||||
# INCLUDES is a list of directories containing header files
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := $(notdir $(CURDIR))
|
||||
SOURCES ?= $(shell find source -type d)
|
||||
DATA := data
|
||||
INCLUDES := include
|
||||
|
||||
DEFINES :=
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE
|
||||
|
||||
CFLAGS := -g -Wall -O2 -ffunction-sections \
|
||||
$(ARCH) $(DEFINES)
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17 -flto
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS := -lnx
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(PORTLIBS) $(LIBNX)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
# rules for different file extensions
|
||||
#---------------------------------------------------------------------------------
|
||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(CPPFILES)),)
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CC)
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CXX)
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
||||
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
||||
export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I. \
|
||||
-iquote $(CURDIR)/include/switch/
|
||||
|
||||
.PHONY: clean all
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
all: lib/$(TARGET).a
|
||||
|
||||
lib:
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
|
||||
release:
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
|
||||
lib/$(TARGET).a : lib release $(SOURCES) $(INCLUDES)
|
||||
@$(MAKE) BUILD=release OUTPUT=$(CURDIR)/$@ \
|
||||
BUILD_CFLAGS="-DNDEBUG=1 -O2" \
|
||||
DEPSDIR=$(CURDIR)/release \
|
||||
--no-print-directory -C release \
|
||||
-f $(CURDIR)/Makefile
|
||||
|
||||
dist-bin: all
|
||||
@tar --exclude=*~ -cjf $(TARGET).tar.bz2 include lib
|
||||
|
||||
dist-src:
|
||||
@tar --exclude=*~ -cjf $(TARGET)-src.tar.bz2 include source Makefile
|
||||
|
||||
dist: dist-src dist-bin
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -fr release lib *.bz2
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
$(OUTPUT) : $(OFILES)
|
||||
|
||||
$(OFILES_SRC) : $(HFILES)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
%_bin.h %.bin.o : %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
||||
|
|
@ -1,31 +0,0 @@
|
|||

|
||||
|
||||
libstratosphere is a work-in-progress C++ library for development of system modules for the Nintendo Switch.
|
||||
|
||||
It is built around extending [libnx](https://github.com/switchbrew/libnx).
|
||||
|
||||
It also provides bindings for custom extensions to Horizon OS implemented by [Atmosphère](https://github.com/Atmosphere-NX).
|
||||
|
||||
Licensing
|
||||
=====
|
||||
|
||||
This software is licensed under the terms of the GPLv2, with exemptions for specific projects noted below.
|
||||
|
||||
You can find a copy of the license in the [LICENSE file](LICENSE).
|
||||
|
||||
Exemptions:
|
||||
* The [yuzu emulator project](https://github.com/yuzu-emu/yuzu) is exempt from GPLv2 licensing and may (at its option) instead license any source code authored for the libstratosphere project as GPLv2 or later.
|
||||
|
||||
Credits
|
||||
=====
|
||||
|
||||
libstratosphere is currently being developed and maintained by __SciresM__.<br>
|
||||
|
||||
In addition to those credited in [Atmosphère's credits](https://github.com/Atmosphere-NX/Atmosphere/blob/master/README.md#Credits), we would like to thank for contributing to libstratosphere in some significant way:
|
||||
|
||||
* __hthh__
|
||||
* __fincs__
|
||||
* __lioncash__
|
||||
* __misson20000__
|
||||
* __neobrain__
|
||||
* __yellows8__
|
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "common_includes.hpp"
|
||||
#include "defines.hpp"
|
||||
#include "util.hpp"
|
||||
#include "results.hpp"
|
||||
#include "svc.hpp"
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/* C headers. */
|
||||
#include <cstdint>
|
||||
#include <cstdarg>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <climits>
|
||||
#include <cctype>
|
||||
|
||||
/* C++ headers. */
|
||||
#include <type_traits>
|
||||
#include <limits>
|
||||
#include <atomic>
|
||||
#include <utility>
|
||||
#include <iterator>
|
||||
#include <optional>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <tuple>
|
||||
#include <array>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <set>
|
||||
|
||||
/* Libnx. */
|
||||
#include <switch.h>
|
||||
|
||||
/* Atmosphere meta. */
|
||||
#if __has_include(<atmosphere.h>)
|
||||
#include <atmosphere.h>
|
||||
#endif
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "common_includes.hpp"
|
||||
|
||||
/* Any broadly useful language defines should go here. */
|
||||
|
||||
#define AMS_ASSERT(expr) do { if (!(expr)) { std::abort(); } } while (0)
|
||||
|
||||
#define AMS_UNREACHABLE_DEFAULT_CASE() default: std::abort()
|
||||
|
||||
#define NON_COPYABLE(cls) \
|
||||
cls(const cls&) = delete; \
|
||||
cls& operator=(const cls&) = delete
|
||||
|
||||
#define NON_MOVEABLE(cls) \
|
||||
cls(cls&&) = delete; \
|
||||
cls& operator=(cls&&) = delete
|
||||
|
||||
#define ALIGNED(algn) __attribute__((aligned(algn)))
|
||||
#define NORETURN __attribute__((noreturn))
|
||||
#define WEAK __attribute__((weak))
|
||||
|
||||
|
||||
#define CONCATENATE_IMPL(S1, s2) s1##s2
|
||||
#define CONCATENATE(s1, s2) CONCATENATE_IMPL(s1, s2)
|
||||
|
||||
#ifdef __COUNTER__
|
||||
#define ANONYMOUS_VARIABLE(pref) CONCATENATE(pref, __COUNTER__)
|
||||
#else
|
||||
#define ANONYMOUS_VARIABLE(pref) CONCATENATE(pref, __LINE__)
|
||||
#endif
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "defines.hpp"
|
||||
#include "util.hpp"
|
||||
|
||||
/* Utilities. */
|
||||
#include "results/results_common.hpp"
|
||||
|
||||
/* Official. */
|
||||
#include "results/cal_results.hpp"
|
||||
#include "results/creport_results.hpp"
|
||||
#include "results/debug_results.hpp"
|
||||
#include "results/dmnt_results.hpp"
|
||||
#include "results/err_results.hpp"
|
||||
#include "results/fatal_results.hpp"
|
||||
#include "results/fs_results.hpp"
|
||||
#include "results/hipc_results.hpp"
|
||||
#include "results/i2c_results.hpp"
|
||||
#include "results/kvdb_results.hpp"
|
||||
#include "results/loader_results.hpp"
|
||||
#include "results/lr_results.hpp"
|
||||
#include "results/os_results.hpp"
|
||||
#include "results/ncm_results.hpp"
|
||||
#include "results/pm_results.hpp"
|
||||
#include "results/ro_results.hpp"
|
||||
#include "results/settings_results.hpp"
|
||||
#include "results/sf_results.hpp"
|
||||
#include "results/sm_results.hpp"
|
||||
#include "results/spl_results.hpp"
|
||||
#include "results/svc_results.hpp"
|
||||
#include "results/updater_results.hpp"
|
||||
#include "results/vi_results.hpp"
|
||||
|
||||
/* Unofficial. */
|
||||
#include "results/exosphere_results.hpp"
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "results_common.hpp"
|
||||
|
||||
namespace ams::cal {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(198);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(CalibrationDataCrcError, 101);
|
||||
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "results_common.hpp"
|
||||
|
||||
namespace ams::creport {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(168);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(UndefinedInstruction, 0);
|
||||
R_DEFINE_ERROR_RESULT(InstructionAbort, 1);
|
||||
R_DEFINE_ERROR_RESULT(DataAbort, 2);
|
||||
R_DEFINE_ERROR_RESULT(AlignmentFault, 3);
|
||||
R_DEFINE_ERROR_RESULT(DebuggerAttached, 4);
|
||||
R_DEFINE_ERROR_RESULT(BreakPoint, 5);
|
||||
R_DEFINE_ERROR_RESULT(UserBreak, 6);
|
||||
R_DEFINE_ERROR_RESULT(DebuggerBreak, 7);
|
||||
R_DEFINE_ERROR_RESULT(UndefinedSystemCall, 8);
|
||||
R_DEFINE_ERROR_RESULT(SystemMemoryError, 9);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(IncompleteReport, 99);
|
||||
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "results_common.hpp"
|
||||
|
||||
namespace ams::dbg {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(183);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(CannotDebug, 1);
|
||||
R_DEFINE_ERROR_RESULT(AlreadyAttached, 2);
|
||||
R_DEFINE_ERROR_RESULT(Cancelled, 3);
|
||||
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "results_common.hpp"
|
||||
|
||||
namespace ams::dmnt {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(13);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(Unknown, 1);
|
||||
R_DEFINE_ERROR_RESULT(DebuggingDisabled, 2);
|
||||
|
||||
/* Atmosphere extension. */
|
||||
namespace cheat {
|
||||
|
||||
R_DEFINE_ABSTRACT_ERROR_RANGE(CheatError, 6500, 6599);
|
||||
R_DEFINE_ERROR_RESULT(CheatNotAttached, 6500);
|
||||
R_DEFINE_ERROR_RESULT(CheatNullBuffer, 6501);
|
||||
R_DEFINE_ERROR_RESULT(CheatInvalidBuffer, 6502);
|
||||
R_DEFINE_ERROR_RESULT(CheatUnknownId, 6503);
|
||||
R_DEFINE_ERROR_RESULT(CheatOutOfResource, 6504);
|
||||
R_DEFINE_ERROR_RESULT(CheatInvalid, 6505);
|
||||
R_DEFINE_ERROR_RESULT(CheatCannotDisable, 6506);
|
||||
|
||||
R_DEFINE_ABSTRACT_ERROR_RANGE(FrozenAddressError, 6600, 6699);
|
||||
R_DEFINE_ERROR_RESULT(FrozenAddressInvalidWidth, 6600);
|
||||
R_DEFINE_ERROR_RESULT(FrozenAddressAlreadyExists, 6601);
|
||||
R_DEFINE_ERROR_RESULT(FrozenAddressNotFound, 6602);
|
||||
R_DEFINE_ERROR_RESULT(FrozenAddressOutOfResource, 6603);
|
||||
|
||||
R_DEFINE_ABSTRACT_ERROR_RANGE(VirtualMachineError, 6700, 6799);
|
||||
R_DEFINE_ERROR_RESULT(VirtualMachineInvalidConditionDepth, 6700);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "results_common.hpp"
|
||||
|
||||
namespace ams::err {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(162);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ApplicationAborted, 1);
|
||||
R_DEFINE_ERROR_RESULT(SystemModuleAborted, 2);
|
||||
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "results_common.hpp"
|
||||
|
||||
namespace ams::exosphere {
|
||||
|
||||
/* Please note: These results are all custom, and not official. */
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(444);
|
||||
|
||||
|
||||
/* Result 1-1000 reserved for Atmosphere. */
|
||||
R_DEFINE_ERROR_RESULT(NotPresent, 1);
|
||||
R_DEFINE_ERROR_RESULT(VersionMismatch, 2);
|
||||
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "results_common.hpp"
|
||||
|
||||
namespace ams::fatal {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(163);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(AllocationFailed, 1);
|
||||
R_DEFINE_ERROR_RESULT(NullGraphicsBuffer, 2);
|
||||
R_DEFINE_ERROR_RESULT(AlreadyThrown, 3);
|
||||
R_DEFINE_ERROR_RESULT(TooManyEvents, 4);
|
||||
R_DEFINE_ERROR_RESULT(InRepairWithoutVolHeld, 5);
|
||||
R_DEFINE_ERROR_RESULT(InRepairWithoutTimeReviserCartridge, 6);
|
||||
|
||||
}
|
|
@ -1,124 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "results_common.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(2);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(PathNotFound, 1);
|
||||
R_DEFINE_ERROR_RESULT(PathAlreadyExists, 2);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(TargetLocked, 7);
|
||||
R_DEFINE_ERROR_RESULT(DirectoryNotEmpty, 8);
|
||||
|
||||
R_DEFINE_ERROR_RANGE (NotEnoughFreeSpace, 30, 45);
|
||||
R_DEFINE_ERROR_RANGE(NotEnoughFreeSpaceBis, 34, 38);
|
||||
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisCalibration, 35);
|
||||
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisSafe, 36);
|
||||
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisUser, 37);
|
||||
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisSystem, 38);
|
||||
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceSdCard, 39);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(MountNameAlreadyExists, 60);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(TargetNotFound, 1002);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(SdCardAccessFailed, 2000, 2499);
|
||||
R_DEFINE_ERROR_RESULT(SdCardNotPresent, 2001);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(GameCardAccessFailed, 2500, 2999);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(NotImplemented, 3001);
|
||||
R_DEFINE_ERROR_RESULT(OutOfRange, 3005);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(AllocationFailure, 3200, 3499);
|
||||
R_DEFINE_ERROR_RESULT(AllocationFailureInDirectorySaveDataFileSystem, 3321);
|
||||
R_DEFINE_ERROR_RESULT(AllocationFailureInSubDirectoryFileSystem, 3355);
|
||||
R_DEFINE_ERROR_RESULT(AllocationFailureInPathNormalizer, 3367);
|
||||
R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemInterfaceAdapter, 3407);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(MmcAccessFailed, 3500, 3999);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(DataCorrupted, 4000, 4999);
|
||||
R_DEFINE_ERROR_RANGE(RomCorrupted, 4001, 4299);
|
||||
R_DEFINE_ERROR_RANGE(SaveDataCorrupted, 4301, 4499);
|
||||
R_DEFINE_ERROR_RANGE(NcaCorrupted, 4501, 4599);
|
||||
R_DEFINE_ERROR_RANGE(IntegrityVerificationStorageCorrupted, 4601, 4639);
|
||||
R_DEFINE_ERROR_RANGE(PartitionFileSystemCorrupted, 4641, 4659);
|
||||
R_DEFINE_ERROR_RANGE(BuiltInStorageCorrupted, 4661, 4679);
|
||||
R_DEFINE_ERROR_RANGE(HostFileSystemCorrupted, 4701, 4719);
|
||||
R_DEFINE_ERROR_RANGE(DatabaseCorrupted, 4721, 4739);
|
||||
R_DEFINE_ERROR_RANGE(AesXtsFileSystemCorrupted, 4741, 4759);
|
||||
R_DEFINE_ERROR_RANGE(SaveDataTransferDataCorrupted, 4761, 4769);
|
||||
R_DEFINE_ERROR_RANGE(SignedSystemPartitionDataCorrupted, 4771, 4779);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(GameCardLogoDataCorrupted, 4781);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(Unexpected, 5000, 5999);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(PreconditionViolation, 6000, 6499);
|
||||
R_DEFINE_ERROR_RANGE(InvalidArgument, 6001, 6199);
|
||||
R_DEFINE_ERROR_RANGE(InvalidPath, 6002, 6029);
|
||||
R_DEFINE_ERROR_RESULT(TooLongPath, 6003);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCharacter, 6004);
|
||||
R_DEFINE_ERROR_RESULT(InvalidPathFormat, 6005);
|
||||
R_DEFINE_ERROR_RESULT(DirectoryUnobtainable, 6006);
|
||||
R_DEFINE_ERROR_RESULT(NotNormalized, 6007);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(InvalidPathForOperation, 6030, 6059);
|
||||
R_DEFINE_ERROR_RESULT(DirectoryNotDeletable, 6031);
|
||||
R_DEFINE_ERROR_RESULT(DirectoryNotRenamable, 6032);
|
||||
R_DEFINE_ERROR_RESULT(IncompatiblePath, 6033);
|
||||
R_DEFINE_ERROR_RESULT(RenameToOtherFileSystem, 6034);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidOffset, 6061);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSize, 6062);
|
||||
R_DEFINE_ERROR_RESULT(NullptrArgument, 6063);
|
||||
R_DEFINE_ERROR_RESULT(InvalidAlignment, 6064);
|
||||
R_DEFINE_ERROR_RESULT(InvalidMountName, 6065);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ExtensionSizeTooLarge, 6066);
|
||||
R_DEFINE_ERROR_RESULT(ExtensionSizeInvalid, 6067);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(InvalidEnumValue, 6080, 6099);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSaveDataState, 6081);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSaveDataSpaceId, 6082);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(InvalidOperationForOpenMode, 6200, 6299);
|
||||
R_DEFINE_ERROR_RESULT(FileExtensionWithoutOpenModeAllowAppend, 6201);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(UnsupportedOperation, 6300, 6399);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(PermissionDenied, 6400, 6449);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(WriteModeFileNotClosed, 6457);
|
||||
R_DEFINE_ERROR_RESULT(AllocatorAlignmentViolation, 6461);
|
||||
R_DEFINE_ERROR_RESULT(UserNotExist, 6465);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(OutOfResource, 6700, 6799);
|
||||
R_DEFINE_ERROR_RESULT(MappingTableFull, 6706);
|
||||
R_DEFINE_ERROR_RESULT(OpenCountLimit, 6709);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(MappingFailed, 6800, 6899);
|
||||
R_DEFINE_ERROR_RESULT(MapFull, 6811);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(BadState, 6900, 6999);
|
||||
R_DEFINE_ERROR_RESULT(NotMounted, 6905);
|
||||
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "results_common.hpp"
|
||||
|
||||
namespace ams::sf::hipc {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(11);
|
||||
|
||||
R_DEFINE_ABSTRACT_ERROR_RANGE(OutOfResource, 100, 299);
|
||||
R_DEFINE_ERROR_RESULT(OutOfSessionMemory, 102);
|
||||
R_DEFINE_ERROR_RANGE (OutOfSessions, 131, 139);
|
||||
R_DEFINE_ERROR_RESULT(PointerBufferTooSmall, 141);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OutOfDomains, 200);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(SessionClosed, 301);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidRequestSize, 402);
|
||||
R_DEFINE_ERROR_RESULT(UnknownCommandType, 403);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidCmifRequest, 420);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(TargetNotDomain, 491);
|
||||
R_DEFINE_ERROR_RESULT(DomainObjectNotFound, 492);
|
||||
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "results_common.hpp"
|
||||
|
||||
namespace ams::i2c {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(101);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(NoAck, 1);
|
||||
R_DEFINE_ERROR_RESULT(BusBusy, 2);
|
||||
R_DEFINE_ERROR_RESULT(FullCommandList, 3);
|
||||
R_DEFINE_ERROR_RESULT(TimedOut, 4);
|
||||
R_DEFINE_ERROR_RESULT(UnknownDevice, 5);
|
||||
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "results_common.hpp"
|
||||
|
||||
namespace ams::kvdb {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(20);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OutOfKeyResource, 1);
|
||||
R_DEFINE_ERROR_RESULT(KeyNotFound, 2);
|
||||
R_DEFINE_ERROR_RESULT(AllocationFailed, 4);
|
||||
R_DEFINE_ERROR_RESULT(InvalidKeyValue, 5);
|
||||
R_DEFINE_ERROR_RESULT(BufferInsufficient, 6);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidFilesystemState, 8);
|
||||
R_DEFINE_ERROR_RESULT(NotCreated, 9);
|
||||
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "results_common.hpp"
|
||||
|
||||
namespace ams::ldr {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(9);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(TooLongArgument, 1);
|
||||
R_DEFINE_ERROR_RESULT(TooManyArguments, 2);
|
||||
R_DEFINE_ERROR_RESULT(TooLargeMeta, 3);
|
||||
R_DEFINE_ERROR_RESULT(InvalidMeta, 4);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNso, 5);
|
||||
R_DEFINE_ERROR_RESULT(InvalidPath, 6);
|
||||
R_DEFINE_ERROR_RESULT(TooManyProcesses, 7);
|
||||
R_DEFINE_ERROR_RESULT(NotPinned, 8);
|
||||
R_DEFINE_ERROR_RESULT(InvalidProgramId, 9);
|
||||
R_DEFINE_ERROR_RESULT(InvalidVersion, 10);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InsufficientAddressSpace, 51);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNro, 52);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNrr, 53);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSignature, 54);
|
||||
R_DEFINE_ERROR_RESULT(InsufficientNroRegistrations, 55);
|
||||
R_DEFINE_ERROR_RESULT(InsufficientNrrRegistrations, 56);
|
||||
R_DEFINE_ERROR_RESULT(NroAlreadyLoaded, 57);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidAddress, 81);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSize, 82);
|
||||
R_DEFINE_ERROR_RESULT(NotLoaded, 84);
|
||||
R_DEFINE_ERROR_RESULT(NotRegistered, 85);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSession, 86);
|
||||
R_DEFINE_ERROR_RESULT(InvalidProcess, 87);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(UnknownCapability, 100);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilityKernelFlags, 103);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilitySyscallMask, 104);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilityMapRange, 106);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilityMapPage, 107);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilityInterruptPair, 111);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilityApplicationType, 113);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilityKernelVersion, 114);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilityHandleTable, 115);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilityDebugFlags, 116);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InternalError, 200);
|
||||
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "results_common.hpp"
|
||||
|
||||
namespace ams::lr {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(8);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ProgramNotFound, 2);
|
||||
R_DEFINE_ERROR_RESULT(DataNotFound, 3);
|
||||
R_DEFINE_ERROR_RESULT(UnknownStorageId, 4);
|
||||
R_DEFINE_ERROR_RESULT(HtmlDocumentNotFound, 6);
|
||||
R_DEFINE_ERROR_RESULT(AddOnContentNotFound, 7);
|
||||
R_DEFINE_ERROR_RESULT(ControlNotFound, 8);
|
||||
R_DEFINE_ERROR_RESULT(LegalInformationNotFound, 9);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(TooManyRegisteredPaths, 90);
|
||||
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "results_common.hpp"
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(5);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(PlaceHolderAlreadyExists, 2);
|
||||
R_DEFINE_ERROR_RESULT(PlaceHolderNotFound, 3);
|
||||
R_DEFINE_ERROR_RESULT(ContentAlreadyExists, 4);
|
||||
R_DEFINE_ERROR_RESULT(ContentNotFound, 5);
|
||||
R_DEFINE_ERROR_RESULT(ContentMetaNotFound, 7);
|
||||
R_DEFINE_ERROR_RESULT(AllocationFailed, 8);
|
||||
R_DEFINE_ERROR_RESULT(UnknownStorage, 12);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidContentStorage, 100);
|
||||
R_DEFINE_ERROR_RESULT(InvalidContentMetaDatabase, 110);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(BufferInsufficient, 180);
|
||||
R_DEFINE_ERROR_RESULT(InvalidContentMetaKey, 240);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(ContentStorageNotActive, 250, 258);
|
||||
R_DEFINE_ERROR_RESULT(GameCardContentStorageNotActive, 251);
|
||||
R_DEFINE_ERROR_RESULT(NandSystemContentStorageNotActive, 252);
|
||||
R_DEFINE_ERROR_RESULT(NandUserContentStorageNotActive, 253);
|
||||
R_DEFINE_ERROR_RESULT(SdCardContentStorageNotActive, 254);
|
||||
R_DEFINE_ERROR_RESULT(UnknownContentStorageNotActive, 258);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(ContentMetaDatabaseNotActive, 260, 268);
|
||||
R_DEFINE_ERROR_RESULT(GameCardContentMetaDatabaseNotActive, 261);
|
||||
R_DEFINE_ERROR_RESULT(NandSystemContentMetaDatabaseNotActive, 262);
|
||||
R_DEFINE_ERROR_RESULT(NandUserContentMetaDatabaseNotActive, 263);
|
||||
R_DEFINE_ERROR_RESULT(SdCardContentMetaDatabaseNotActive, 264);
|
||||
R_DEFINE_ERROR_RESULT(UnknownContentMetaDatabaseNotActive, 268);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(InvalidArgument, 8181, 8191);
|
||||
R_DEFINE_ERROR_RESULT(InvalidOffset, 8182);
|
||||
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "results_common.hpp"
|
||||
|
||||
namespace ams::os {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(3);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(Busy, 4);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OutOfMemory, 8);
|
||||
R_DEFINE_ERROR_RESULT(OutOfResource, 9);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OutOfVirtualAddressSpace, 12);
|
||||
R_DEFINE_ERROR_RESULT(ResourceLimit, 13);
|
||||
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "results_common.hpp"
|
||||
|
||||
namespace ams::pm {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(15);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ProcessNotFound, 1);
|
||||
R_DEFINE_ERROR_RESULT(AlreadyStarted, 2);
|
||||
R_DEFINE_ERROR_RESULT(NotExited, 3);
|
||||
R_DEFINE_ERROR_RESULT(DebugHookInUse, 4);
|
||||
R_DEFINE_ERROR_RESULT(ApplicationRunning, 5);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSize, 6);
|
||||
|
||||
}
|
|
@ -1,289 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../defines.hpp"
|
||||
|
||||
namespace ams {
|
||||
|
||||
namespace result::impl {
|
||||
|
||||
class ResultTraits {
|
||||
public:
|
||||
using BaseType = u32;
|
||||
static_assert(std::is_same<BaseType, ::Result>::value, "std::is_same<BaseType, ::Result>::value");
|
||||
static constexpr BaseType SuccessValue = BaseType();
|
||||
static constexpr BaseType ModuleBits = 9;
|
||||
static constexpr BaseType DescriptionBits = 13;
|
||||
static constexpr BaseType ReservedBits = 10;
|
||||
static_assert(ModuleBits + DescriptionBits + ReservedBits == sizeof(BaseType) * CHAR_BIT, "ModuleBits + DescriptionBits + ReservedBits == sizeof(BaseType) * CHAR_BIT");
|
||||
public:
|
||||
NX_CONSTEXPR BaseType MakeValue(BaseType module, BaseType description) {
|
||||
return (module) | (description << ModuleBits);
|
||||
}
|
||||
|
||||
template<BaseType module, BaseType description>
|
||||
struct MakeStaticValue : public std::integral_constant<BaseType, MakeValue(module, description)> {
|
||||
static_assert(module < (1 << ModuleBits), "Invalid Module");
|
||||
static_assert(description < (1 << DescriptionBits), "Invalid Description");
|
||||
};
|
||||
|
||||
NX_CONSTEXPR BaseType GetModuleFromValue(BaseType value) {
|
||||
return value & ~(~BaseType() << ModuleBits);
|
||||
}
|
||||
|
||||
NX_CONSTEXPR BaseType GetDescriptionFromValue(BaseType value) {
|
||||
return ((value >> ModuleBits) & ~(~BaseType() << DescriptionBits));
|
||||
}
|
||||
};
|
||||
|
||||
/* Use CRTP for Results. */
|
||||
template<typename Self>
|
||||
class ResultBase {
|
||||
public:
|
||||
using BaseType = typename ResultTraits::BaseType;
|
||||
static constexpr BaseType SuccessValue = ResultTraits::SuccessValue;
|
||||
public:
|
||||
constexpr inline BaseType GetModule() const { return ResultTraits::GetModuleFromValue(static_cast<const Self *>(this)->GetValue()); }
|
||||
constexpr inline BaseType GetDescription() const { return ResultTraits::GetDescriptionFromValue(static_cast<const Self *>(this)->GetValue()); }
|
||||
};
|
||||
|
||||
class ResultConstructor;
|
||||
|
||||
}
|
||||
|
||||
class ResultSuccess;
|
||||
|
||||
class Result final : public result::impl::ResultBase<Result> {
|
||||
friend class ResultConstructor;
|
||||
public:
|
||||
using Base = typename result::impl::ResultBase<Result>;
|
||||
private:
|
||||
typename Base::BaseType value;
|
||||
private:
|
||||
/* TODO: Maybe one-day, the result constructor. */
|
||||
public:
|
||||
Result() { /* ... */ }
|
||||
|
||||
/* TODO: It sure would be nice to make this private. */
|
||||
constexpr Result(typename Base::BaseType v) : value(v) { static_assert(std::is_same<typename Base::BaseType, ::Result>::value); }
|
||||
|
||||
constexpr inline operator ResultSuccess() const;
|
||||
NX_CONSTEXPR bool CanAccept(Result result) { return true; }
|
||||
|
||||
constexpr inline bool IsSuccess() const { return this->GetValue() == Base::SuccessValue; }
|
||||
constexpr inline bool IsFailure() const { return !this->IsSuccess(); }
|
||||
constexpr inline typename Base::BaseType GetModule() const { return Base::GetModule(); }
|
||||
constexpr inline typename Base::BaseType GetDescription() const { return Base::GetDescription(); }
|
||||
|
||||
constexpr inline typename Base::BaseType GetValue() const { return this->value; }
|
||||
};
|
||||
static_assert(sizeof(Result) == sizeof(Result::Base::BaseType), "sizeof(Result) == sizeof(Result::Base::BaseType)");
|
||||
static_assert(std::is_trivially_destructible<Result>::value, "std::is_trivially_destructible<Result>::value");
|
||||
|
||||
namespace result::impl {
|
||||
|
||||
class ResultConstructor {
|
||||
public:
|
||||
static constexpr inline Result MakeResult(ResultTraits::BaseType value) {
|
||||
return Result(value);
|
||||
}
|
||||
};
|
||||
|
||||
constexpr inline Result MakeResult(ResultTraits::BaseType value) {
|
||||
return ResultConstructor::MakeResult(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ResultSuccess final : public result::impl::ResultBase<ResultSuccess> {
|
||||
public:
|
||||
using Base = typename result::impl::ResultBase<ResultSuccess>;
|
||||
public:
|
||||
constexpr operator Result() const { return result::impl::MakeResult(Base::SuccessValue); }
|
||||
NX_CONSTEXPR bool CanAccept(Result result) { return result.IsSuccess(); }
|
||||
|
||||
constexpr inline bool IsSuccess() const { return true; }
|
||||
constexpr inline bool IsFailure() const { return !this->IsSuccess(); }
|
||||
constexpr inline typename Base::BaseType GetModule() const { return Base::GetModule(); }
|
||||
constexpr inline typename Base::BaseType GetDescription() const { return Base::GetDescription(); }
|
||||
|
||||
constexpr inline typename Base::BaseType GetValue() const { return Base::SuccessValue; }
|
||||
};
|
||||
|
||||
namespace result::impl {
|
||||
|
||||
NORETURN void OnResultAssertion(Result result);
|
||||
|
||||
}
|
||||
|
||||
constexpr inline Result::operator ResultSuccess() const {
|
||||
if (!ResultSuccess::CanAccept(*this)) {
|
||||
result::impl::OnResultAssertion(*this);
|
||||
}
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
namespace result::impl {
|
||||
|
||||
template<ResultTraits::BaseType _Module, ResultTraits::BaseType _Description>
|
||||
class ResultErrorBase : public ResultBase<ResultErrorBase<_Module, _Description>> {
|
||||
public:
|
||||
using Base = typename result::impl::ResultBase<ResultErrorBase<_Module, _Description>>;
|
||||
static constexpr typename Base::BaseType Module = _Module;
|
||||
static constexpr typename Base::BaseType Description = _Description;
|
||||
static constexpr typename Base::BaseType Value = ResultTraits::MakeStaticValue<Module, Description>::value;
|
||||
static_assert(Value != Base::SuccessValue, "Value != Base::SuccessValue");
|
||||
public:
|
||||
constexpr operator Result() const { return MakeResult(Value); }
|
||||
constexpr operator ResultSuccess() const { OnResultAssertion(Value); }
|
||||
|
||||
constexpr inline bool IsSuccess() const { return false; }
|
||||
constexpr inline bool IsFailure() const { return !this->IsSuccess(); }
|
||||
|
||||
constexpr inline typename Base::BaseType GetValue() const { return Value; }
|
||||
};
|
||||
|
||||
template<ResultTraits::BaseType _Module, ResultTraits::BaseType DescStart, ResultTraits::BaseType DescEnd>
|
||||
class ResultErrorRangeBase {
|
||||
public:
|
||||
static constexpr ResultTraits::BaseType Module = _Module;
|
||||
static constexpr ResultTraits::BaseType DescriptionStart = DescStart;
|
||||
static constexpr ResultTraits::BaseType DescriptionEnd = DescEnd;
|
||||
static_assert(DescriptionStart <= DescriptionEnd, "DescriptionStart <= DescriptionEnd");
|
||||
static constexpr typename ResultTraits::BaseType StartValue = ResultTraits::MakeStaticValue<Module, DescriptionStart>::value;
|
||||
static constexpr typename ResultTraits::BaseType EndValue = ResultTraits::MakeStaticValue<Module, DescriptionEnd>::value;
|
||||
public:
|
||||
NX_CONSTEXPR bool Includes(Result result) {
|
||||
return StartValue <= result.GetValue() && result.GetValue() <= EndValue;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Macros for defining new results. */
|
||||
#define R_DEFINE_NAMESPACE_RESULT_MODULE(value) namespace impl::result { static constexpr inline ::ams::result::impl::ResultTraits::BaseType ResultModuleId = value; }
|
||||
#define R_CURRENT_NAMESPACE_RESULT_MODULE impl::result::ResultModuleId
|
||||
#define R_NAMESPACE_MODULE_ID(nmspc) nmspc::R_CURRENT_NAMESPACE_RESULT_MODULE
|
||||
|
||||
#define R_MAKE_NAMESPACE_RESULT(nmspc, desc) static_cast<::ams::Result>(::ams::result::impl::ResultTraits::MakeValue(R_NAMESPACE_MODULE_ID(nmspc), desc))
|
||||
|
||||
#define R_DEFINE_ERROR_RESULT_IMPL(name, desc_start, desc_end) \
|
||||
class Result##name final : public ::ams::result::impl::ResultErrorBase<R_CURRENT_NAMESPACE_RESULT_MODULE, desc_start>, public ::ams::result::impl::ResultErrorRangeBase<R_CURRENT_NAMESPACE_RESULT_MODULE, desc_start, desc_end> {}
|
||||
|
||||
#define R_DEFINE_ABSTRACT_ERROR_RESULT_IMPL(name, desc_start, desc_end) \
|
||||
class Result##name final : public ::ams::result::impl::ResultErrorRangeBase<R_CURRENT_NAMESPACE_RESULT_MODULE, desc_start, desc_end> {}
|
||||
|
||||
|
||||
#define R_DEFINE_ERROR_RESULT(name, desc) R_DEFINE_ERROR_RESULT_IMPL(name, desc, desc)
|
||||
#define R_DEFINE_ERROR_RANGE(name, start, end) R_DEFINE_ERROR_RESULT_IMPL(name, start, end)
|
||||
|
||||
#define R_DEFINE_ABSTRACT_ERROR_RESULT(name, desc) R_DEFINE_ABSTRACT_ERROR_RESULT_IMPL(name, desc, desc)
|
||||
#define R_DEFINE_ABSTRACT_ERROR_RANGE(name, start, end) R_DEFINE_ABSTRACT_ERROR_RESULT_IMPL(name, start, end)
|
||||
|
||||
/* Remove libnx macros, replace with our own. */
|
||||
#ifndef R_SUCCEEDED
|
||||
#error "R_SUCCEEDED not defined."
|
||||
#endif
|
||||
|
||||
#undef R_SUCCEEDED
|
||||
|
||||
#ifndef R_FAILED
|
||||
#error "R_FAILED not defined"
|
||||
#endif
|
||||
|
||||
#undef R_FAILED
|
||||
|
||||
#define R_SUCCEEDED(res) (static_cast<::ams::Result>(res).IsSuccess())
|
||||
#define R_FAILED(res) (static_cast<::ams::Result>(res).IsFailure())
|
||||
|
||||
|
||||
/// Evaluates an expression that returns a result, and returns the result if it would fail.
|
||||
#define R_TRY(res_expr) \
|
||||
({ \
|
||||
const auto _tmp_r_try_rc = res_expr; \
|
||||
if (R_FAILED(_tmp_r_try_rc)) { \
|
||||
return _tmp_r_try_rc; \
|
||||
} \
|
||||
})
|
||||
|
||||
/// Evaluates an expression that returns a result, and fatals the result if it would fail.
|
||||
#define R_ASSERT(res_expr) \
|
||||
({ \
|
||||
const auto _tmp_r_assert_rc = res_expr; \
|
||||
if (R_FAILED(_tmp_r_assert_rc)) { \
|
||||
::ams::result::impl::OnResultAssertion(_tmp_r_assert_rc); \
|
||||
} \
|
||||
})
|
||||
|
||||
/// Evaluates a boolean expression, and returns a result unless that expression is true.
|
||||
#define R_UNLESS(expr, res) \
|
||||
({ \
|
||||
if (!(expr)) { \
|
||||
return static_cast<::ams::Result>(res); \
|
||||
} \
|
||||
})
|
||||
|
||||
/// Helpers for pattern-matching on a result expression, if the result would fail.
|
||||
#define R_CURRENT_RESULT _tmp_r_current_result
|
||||
|
||||
#define R_TRY_CATCH(res_expr) \
|
||||
({ \
|
||||
const auto R_CURRENT_RESULT = res_expr; \
|
||||
if (R_FAILED(R_CURRENT_RESULT)) { \
|
||||
if (false)
|
||||
|
||||
namespace ams::result::impl {
|
||||
|
||||
template<typename... Rs>
|
||||
NX_CONSTEXPR bool AnyIncludes(Result result) {
|
||||
return (Rs::Includes(result) || ...);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#define R_CATCH(...) \
|
||||
} else if (::ams::result::impl::AnyIncludes<__VA_ARGS__>(R_CURRENT_RESULT)) { \
|
||||
if (true)
|
||||
|
||||
#define R_CONVERT(catch_type, convert_type) \
|
||||
R_CATCH(catch_type) { return static_cast<::ams::Result>(convert_type); }
|
||||
|
||||
#define R_CATCH_ALL() \
|
||||
} else if (R_FAILED(R_CURRENT_RESULT)) { \
|
||||
if (true)
|
||||
|
||||
#define R_CONVERT_ALL(convert_type) \
|
||||
R_CATCH_ALL() { return static_cast<::ams::Result>(convert_type); }
|
||||
|
||||
#define R_CATCH_RETHROW(catch_type) \
|
||||
R_CONVERT(catch_type, R_CURRENT_RESULT)
|
||||
|
||||
#define R_END_TRY_CATCH \
|
||||
else if (R_FAILED(R_CURRENT_RESULT)) { \
|
||||
return R_CURRENT_RESULT; \
|
||||
} \
|
||||
} \
|
||||
})
|
||||
|
||||
#define R_END_TRY_CATCH_WITH_ASSERT \
|
||||
else { \
|
||||
R_ASSERT(R_CURRENT_RESULT); \
|
||||
} \
|
||||
} \
|
||||
})
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "results_common.hpp"
|
||||
|
||||
namespace ams::ro {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(22);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(RoError, 1, 1023);
|
||||
R_DEFINE_ERROR_RESULT(OutOfAddressSpace, 2);
|
||||
R_DEFINE_ERROR_RESULT(AlreadyLoaded, 3);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNro, 4);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidNrr, 6);
|
||||
R_DEFINE_ERROR_RESULT(TooManyNro, 7);
|
||||
R_DEFINE_ERROR_RESULT(TooManyNrr, 8);
|
||||
R_DEFINE_ERROR_RESULT(NotAuthorized, 9);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNrrType, 10);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InternalError, 1023);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidAddress, 1025);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSize, 1026);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(NotLoaded, 1028);
|
||||
R_DEFINE_ERROR_RESULT(NotRegistered, 1029);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSession, 1030);
|
||||
R_DEFINE_ERROR_RESULT(InvalidProcess, 1031);
|
||||
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "results_common.hpp"
|
||||
|
||||
namespace ams::settings {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(105);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemNotFound, 11);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(InternalError, 100, 149);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemKeyAllocationFailed, 101);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemValueAllocationFailed, 102);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(InvalidArgument, 200, 399);
|
||||
R_DEFINE_ERROR_RESULT(SettingsNameNull, 201);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemKeyNull, 202);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemValueNull, 203);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemKeyBufferNull, 204);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemValueBufferNull, 205);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(SettingsNameEmpty, 221);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemKeyEmpty, 222);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(SettingsNameTooLong, 241);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemKeyTooLong, 242);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(SettingsNameInvalidFormat, 261);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemKeyInvalidFormat, 262);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemValueInvalidFormat, 263);
|
||||
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "results_common.hpp"
|
||||
|
||||
namespace ams::sf {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(10);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(NotSupported, 1);
|
||||
R_DEFINE_ERROR_RESULT(PreconditionViolation, 3);
|
||||
|
||||
namespace cmif {
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidHeaderSize, 202);
|
||||
R_DEFINE_ERROR_RESULT(InvalidInHeader, 211);
|
||||
R_DEFINE_ERROR_RESULT(UnknownCommandId, 221);
|
||||
R_DEFINE_ERROR_RESULT(InvalidOutRawSize, 232);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNumInObjects, 235);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNumOutObjects, 236);
|
||||
R_DEFINE_ERROR_RESULT(InvalidInObject, 239);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(TargetNotFound, 261);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OutOfDomainEntries, 301);
|
||||
|
||||
}
|
||||
|
||||
namespace impl {
|
||||
|
||||
R_DEFINE_ABSTRACT_ERROR_RANGE(RequestContextChanged, 800, 899);
|
||||
R_DEFINE_ABSTRACT_ERROR_RANGE(RequestInvalidated, 801, 809);
|
||||
R_DEFINE_ERROR_RESULT(RequestInvalidatedByUser, 802);
|
||||
|
||||
}
|
||||
|
||||
R_DEFINE_ABSTRACT_ERROR_RANGE(RequestDeferred, 811, 819);
|
||||
R_DEFINE_ERROR_RESULT(RequestDeferredByUser, 812);
|
||||
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "results_common.hpp"
|
||||
|
||||
namespace ams::sm {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(21);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OutOfProcesses, 1);
|
||||
R_DEFINE_ERROR_RESULT(InvalidClient, 2);
|
||||
R_DEFINE_ERROR_RESULT(OutOfSessions, 3);
|
||||
R_DEFINE_ERROR_RESULT(AlreadyRegistered, 4);
|
||||
R_DEFINE_ERROR_RESULT(OutOfServices, 5);
|
||||
R_DEFINE_ERROR_RESULT(InvalidServiceName, 6);
|
||||
R_DEFINE_ERROR_RESULT(NotRegistered, 7);
|
||||
R_DEFINE_ERROR_RESULT(NotAllowed, 8);
|
||||
R_DEFINE_ERROR_RESULT(TooLargeAccessControl, 9);
|
||||
|
||||
/* Results 1000-2000 used as extension for Atmosphere Mitm. */
|
||||
namespace mitm {
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ShouldForwardToSession, 1000);
|
||||
R_DEFINE_ERROR_RESULT(ProcessNotAssociated, 1100);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "results_common.hpp"
|
||||
|
||||
namespace ams::spl {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(26);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(SecureMonitorError, 0, 99);
|
||||
R_DEFINE_ERROR_RESULT(SecureMonitorNotImplemented, 1);
|
||||
R_DEFINE_ERROR_RESULT(SecureMonitorInvalidArgument, 2);
|
||||
R_DEFINE_ERROR_RESULT(SecureMonitorBusy, 3);
|
||||
R_DEFINE_ERROR_RESULT(SecureMonitorNoAsyncOperation, 4);
|
||||
R_DEFINE_ERROR_RESULT(SecureMonitorInvalidAsyncOperation, 5);
|
||||
R_DEFINE_ERROR_RESULT(SecureMonitorNotPermitted, 6);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidSize, 100);
|
||||
R_DEFINE_ERROR_RESULT(UnknownSecureMonitorError, 101);
|
||||
R_DEFINE_ERROR_RESULT(DecryptionFailed, 102);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OutOfKeyslots, 104);
|
||||
R_DEFINE_ERROR_RESULT(InvalidKeyslot, 105);
|
||||
R_DEFINE_ERROR_RESULT(BootReasonAlreadySet, 106);
|
||||
R_DEFINE_ERROR_RESULT(BootReasonNotSet, 107);
|
||||
R_DEFINE_ERROR_RESULT(InvalidArgument, 108);
|
||||
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "results_common.hpp"
|
||||
|
||||
namespace ams::svc {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(1);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OutOfSessions, 7);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidArgument, 14);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(NotImplemented, 33);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ThreadTerminating, 59);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(NoEvent, 70);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidSize, 101);
|
||||
R_DEFINE_ERROR_RESULT(InvalidAddress, 102);
|
||||
R_DEFINE_ERROR_RESULT(OutOfResource, 103);
|
||||
R_DEFINE_ERROR_RESULT(OutOfMemory, 104);
|
||||
R_DEFINE_ERROR_RESULT(OutOfHandles, 105);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCurrentMemoryState, 106);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidNewMemoryPermissions, 108);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidMemoryRegion, 110);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidPriority, 112);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCoreId, 113);
|
||||
R_DEFINE_ERROR_RESULT(InvalidHandle, 114);
|
||||
R_DEFINE_ERROR_RESULT(InvalidPointer, 115);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCombination, 116);
|
||||
R_DEFINE_ERROR_RESULT(TimedOut, 117);
|
||||
R_DEFINE_ERROR_RESULT(Cancelled, 118);
|
||||
R_DEFINE_ERROR_RESULT(OutOfRange, 119);
|
||||
R_DEFINE_ERROR_RESULT(InvalidEnumValue, 120);
|
||||
R_DEFINE_ERROR_RESULT(NotFound, 121);
|
||||
R_DEFINE_ERROR_RESULT(Busy, 122);
|
||||
R_DEFINE_ERROR_RESULT(SessionClosed, 123);
|
||||
R_DEFINE_ERROR_RESULT(NotHandled, 124);
|
||||
R_DEFINE_ERROR_RESULT(InvalidState, 125);
|
||||
R_DEFINE_ERROR_RESULT(ReservedValue, 126);
|
||||
R_DEFINE_ERROR_RESULT(NotSupported, 127);
|
||||
R_DEFINE_ERROR_RESULT(Debug, 128);
|
||||
R_DEFINE_ERROR_RESULT(ThreadNotOwned, 129);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(PortClosed, 131);
|
||||
R_DEFINE_ERROR_RESULT(LimitReached, 132);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ReceiveListBroken, 258);
|
||||
R_DEFINE_ERROR_RESULT(OutOfAddressSpace, 259);
|
||||
R_DEFINE_ERROR_RESULT(MessageTooLarge, 260);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ProcessTerminated, 520);
|
||||
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "results_common.hpp"
|
||||
|
||||
namespace ams::updater {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(158);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(BootImagePackageNotFound, 2);
|
||||
R_DEFINE_ERROR_RESULT(InvalidBootImagePackage, 3);
|
||||
R_DEFINE_ERROR_RESULT(TooSmallWorkBuffer, 4);
|
||||
R_DEFINE_ERROR_RESULT(NotAlignedWorkBuffer, 5);
|
||||
R_DEFINE_ERROR_RESULT(NeedsRepairBootImages, 6);
|
||||
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "results_common.hpp"
|
||||
|
||||
namespace ams::vi {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(114);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OperationFailed, 1);
|
||||
R_DEFINE_ERROR_RESULT(NotSupported, 6);
|
||||
R_DEFINE_ERROR_RESULT(NotFound, 7);
|
||||
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "defines.hpp"
|
||||
#include "results.hpp"
|
||||
|
||||
#include "svc/svc_types.hpp"
|
|
@ -1,208 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../results.hpp"
|
||||
|
||||
namespace ams::svc {
|
||||
|
||||
/* Debug event types. */
|
||||
enum class DebugEventType : u32 {
|
||||
AttachProcess = 0,
|
||||
AttachThread = 1,
|
||||
ExitProcess = 2,
|
||||
ExitThread = 3,
|
||||
Exception = 4,
|
||||
};
|
||||
|
||||
struct DebugInfoAttachProcess {
|
||||
u64 program_id;
|
||||
u64 process_id;
|
||||
char name[0xC];
|
||||
u32 flags;
|
||||
u64 user_exception_context_address; /* 5.0.0+ */
|
||||
};
|
||||
|
||||
struct DebugInfoAttachThread {
|
||||
u64 thread_id;
|
||||
u64 tls_address;
|
||||
u64 entrypoint;
|
||||
};
|
||||
|
||||
enum class ExitProcessReason : u32 {
|
||||
ExitProcess = 0,
|
||||
TerminateProcess = 1,
|
||||
Exception = 2,
|
||||
};
|
||||
|
||||
struct DebugInfoExitProcess {
|
||||
ExitProcessReason reason;
|
||||
};
|
||||
|
||||
enum class ExitThreadReason : u32 {
|
||||
ExitThread = 0,
|
||||
TerminateThread = 1,
|
||||
ExitProcess = 2,
|
||||
TerminateProcess = 3,
|
||||
};
|
||||
|
||||
struct DebugInfoExitThread {
|
||||
ExitThreadReason reason;
|
||||
};
|
||||
|
||||
enum class DebugExceptionType : u32 {
|
||||
UndefinedInstruction = 0,
|
||||
InstructionAbort = 1,
|
||||
DataAbort = 2,
|
||||
AlignmentFault = 3,
|
||||
DebuggerAttached = 4,
|
||||
BreakPoint = 5,
|
||||
UserBreak = 6,
|
||||
DebuggerBreak = 7,
|
||||
UndefinedSystemCall = 8,
|
||||
SystemMemoryError = 9,
|
||||
};
|
||||
|
||||
struct DebugInfoUndefinedInstructionException {
|
||||
u32 insn;
|
||||
};
|
||||
|
||||
struct DebugInfoDataAbortException {
|
||||
u64 address;
|
||||
};
|
||||
|
||||
struct DebugInfoAligntmentFaultException {
|
||||
u64 address;
|
||||
};
|
||||
|
||||
enum class BreakPointType : u32 {
|
||||
BreakPoint = 0,
|
||||
WatchPoint = 1,
|
||||
};
|
||||
|
||||
struct DebugInfoBreakPointException {
|
||||
BreakPointType type;
|
||||
u64 address;
|
||||
};
|
||||
|
||||
struct DebugInfoUserBreakException {
|
||||
u32 break_reason; /* TODO: enum? */
|
||||
u64 address;
|
||||
u64 size;
|
||||
};
|
||||
|
||||
struct DebugInfoDebuggerBreakException {
|
||||
u64 active_thread_ids[4];
|
||||
};
|
||||
|
||||
struct DebugInfoUndefinedSystemCallException {
|
||||
u32 id;
|
||||
};
|
||||
|
||||
union DebugInfoSpecificException {
|
||||
DebugInfoUndefinedInstructionException undefined_instruction;
|
||||
DebugInfoDataAbortException data_abort;
|
||||
DebugInfoAligntmentFaultException alignment_fault;
|
||||
DebugInfoBreakPointException break_point;
|
||||
DebugInfoUserBreakException user_break;
|
||||
DebugInfoDebuggerBreakException debugger_break;
|
||||
DebugInfoUndefinedSystemCallException undefined_system_call;
|
||||
u64 raw;
|
||||
};
|
||||
|
||||
struct DebugInfoException {
|
||||
DebugExceptionType type;
|
||||
u64 address;
|
||||
DebugInfoSpecificException specific;
|
||||
};
|
||||
|
||||
union DebugInfo {
|
||||
DebugInfoAttachProcess attach_process;
|
||||
DebugInfoAttachThread attach_thread;
|
||||
DebugInfoExitProcess exit_process;
|
||||
DebugInfoExitThread exit_thread;
|
||||
DebugInfoException exception;
|
||||
};
|
||||
|
||||
struct DebugEventInfo {
|
||||
DebugEventType type;
|
||||
u32 flags;
|
||||
u64 thread_id;
|
||||
DebugInfo info;
|
||||
};
|
||||
static_assert(sizeof(DebugEventInfo) >= 0x40, "DebugEventInfo definition!");
|
||||
|
||||
/* Thread State, for svcGetDebugThreadParam. */
|
||||
enum class ThreadState : u32 {
|
||||
Waiting = 0,
|
||||
Running = 1,
|
||||
Terminated = 4,
|
||||
Initializing = 5,
|
||||
};
|
||||
|
||||
enum ThreadContextFlag : u32 {
|
||||
ThreadContextFlag_General = (1 << 0),
|
||||
ThreadContextFlag_Control = (1 << 1),
|
||||
ThreadContextFlag_Fpu = (1 << 2),
|
||||
ThreadContextFlag_FpuControl = (1 << 3),
|
||||
|
||||
ThreadContextFlag_All = (ThreadContextFlag_General | ThreadContextFlag_Control | ThreadContextFlag_Fpu | ThreadContextFlag_FpuControl),
|
||||
};
|
||||
|
||||
/* Flags for svcCreateProcess. */
|
||||
enum CreateProcessFlag : u32 {
|
||||
/* Is 64 bit? */
|
||||
CreateProcessFlag_Is64Bit = (1 << 0),
|
||||
|
||||
/* What kind of address space? */
|
||||
CreateProcessFlag_AddressSpaceShift = 1,
|
||||
CreateProcessFlag_AddressSpaceMask = (7 << CreateProcessFlag_AddressSpaceShift),
|
||||
CreateProcessFlag_AddressSpace32Bit = (0 << CreateProcessFlag_AddressSpaceShift),
|
||||
CreateProcessFlag_AddressSpace64BitDeprecated = (1 << CreateProcessFlag_AddressSpaceShift),
|
||||
CreateProcessFlag_AddressSpace32BitWithoutAlias = (2 << CreateProcessFlag_AddressSpaceShift),
|
||||
CreateProcessFlag_AddressSpace64Bit = (3 << CreateProcessFlag_AddressSpaceShift),
|
||||
|
||||
/* Should JIT debug be done on crash? */
|
||||
CreateProcessFlag_EnableDebug = (1 << 4),
|
||||
|
||||
/* Should ASLR be enabled for the process? */
|
||||
CreateProcessFlag_EnableAslr = (1 << 5),
|
||||
|
||||
/* Is the process an application? */
|
||||
CreateProcessFlag_IsApplication = (1 << 6),
|
||||
|
||||
/* 4.x deprecated: Should use secure memory? */
|
||||
CreateProcessFlag_DeprecatedUseSecureMemory = (1 << 7),
|
||||
|
||||
/* 5.x+ Pool partition type. */
|
||||
CreateProcessFlag_PoolPartitionShift = 7,
|
||||
CreateProcessFlag_PoolPartitionMask = (0xF << CreateProcessFlag_PoolPartitionShift),
|
||||
CreateProcessFlag_PoolPartitionApplication = (0 << CreateProcessFlag_PoolPartitionShift),
|
||||
CreateProcessFlag_PoolPartitionApplet = (1 << CreateProcessFlag_PoolPartitionShift),
|
||||
CreateProcessFlag_PoolPartitionSystem = (2 << CreateProcessFlag_PoolPartitionShift),
|
||||
CreateProcessFlag_PoolPartitionSystemNonSecure = (3 << CreateProcessFlag_PoolPartitionShift),
|
||||
|
||||
/* 7.x+ Should memory allocation be optimized? This requires IsApplication. */
|
||||
CreateProcessFlag_OptimizeMemoryAllocation = (1 << 11),
|
||||
};
|
||||
|
||||
/* Type for svcCreateInterruptEvent. */
|
||||
enum InterruptType : u32 {
|
||||
InterruptType_Edge = 0,
|
||||
InterruptType_Level = 1,
|
||||
};
|
||||
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "defines.hpp"
|
||||
|
||||
#include "util/util_alignment.hpp"
|
||||
#include "util/util_size.hpp"
|
||||
#include "util/util_scope_guard.hpp"
|
||||
#include "util/util_typed_storage.hpp"
|
||||
#include "util/util_intrusive_list.hpp"
|
||||
#include "util/util_intrusive_red_black_tree.hpp"
|
||||
#include "util/util_compression.hpp"
|
||||
#include "util/util_ini.hpp"
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../defines.hpp"
|
||||
|
||||
namespace ams::util {
|
||||
|
||||
/* Utilities for alignment to power of two. */
|
||||
|
||||
template<typename T>
|
||||
constexpr inline T AlignUp(T value, size_t alignment) {
|
||||
using U = typename std::make_unsigned<T>::type;
|
||||
const U invmask = static_cast<U>(alignment - 1);
|
||||
return static_cast<T>((value + invmask) & ~invmask);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr inline T AlignDown(T value, size_t alignment) {
|
||||
using U = typename std::make_unsigned<T>::type;
|
||||
const U invmask = static_cast<U>(alignment - 1);
|
||||
return static_cast<T>(value & ~invmask);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr inline bool IsAligned(T value, size_t alignment) {
|
||||
using U = typename std::make_unsigned<T>::type;
|
||||
const U invmask = static_cast<U>(alignment - 1);
|
||||
return (value & invmask) == 0;
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr inline void *AlignUp<void *>(void *value, size_t alignment) {
|
||||
return reinterpret_cast<void *>(AlignUp(reinterpret_cast<uintptr_t>(value), alignment));
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr inline const void *AlignUp<const void *>(const void *value, size_t alignment) {
|
||||
return reinterpret_cast<const void *>(AlignUp(reinterpret_cast<uintptr_t>(value), alignment));
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr inline void *AlignDown<void *>(void *value, size_t alignment) {
|
||||
return reinterpret_cast<void *>(AlignDown(reinterpret_cast<uintptr_t>(value), alignment));
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr inline const void *AlignDown<const void *>(const void *value, size_t alignment) {
|
||||
return reinterpret_cast<void *>(AlignDown(reinterpret_cast<uintptr_t>(value), alignment));
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr inline bool IsAligned<void *>(void *value, size_t alignment) {
|
||||
return IsAligned(reinterpret_cast<uintptr_t>(value), alignment);
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr inline bool IsAligned<const void *>(const void *value, size_t alignment) {
|
||||
return IsAligned(reinterpret_cast<uintptr_t>(value), alignment);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../defines.hpp"
|
||||
|
||||
namespace ams::util {
|
||||
|
||||
/* Compression utilities. */
|
||||
int CompressLZ4(void *dst, size_t dst_size, const void *src, size_t src_size);
|
||||
|
||||
/* Decompression utilities. */
|
||||
int DecompressLZ4(void *dst, size_t dst_size, const void *src, size_t src_size);
|
||||
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../defines.hpp"
|
||||
|
||||
namespace ams::util::ini {
|
||||
|
||||
/* Ini handler type. */
|
||||
using Handler = int (*)(void *user_ctx, const char *section, const char *name, const char *value);
|
||||
|
||||
/* Utilities for dealing with INI file configuration. */
|
||||
int ParseString(const char *ini_str, void *user_ctx, Handler h);
|
||||
int ParseFile(FILE *f, void *user_ctx, Handler h);
|
||||
int ParseFile(FsFile *f, void *user_ctx, Handler h);
|
||||
int ParseFile(const char *path, void *user_ctx, Handler h);
|
||||
|
||||
}
|
|
@ -1,595 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "util_parent_of_member.hpp"
|
||||
|
||||
namespace ams::util {
|
||||
|
||||
/* Forward declare implementation class for Node. */
|
||||
namespace impl {
|
||||
|
||||
class IntrusiveListImpl;
|
||||
|
||||
}
|
||||
|
||||
class IntrusiveListNode {
|
||||
NON_COPYABLE(IntrusiveListNode);
|
||||
private:
|
||||
friend class impl::IntrusiveListImpl;
|
||||
|
||||
IntrusiveListNode *prev;
|
||||
IntrusiveListNode *next;
|
||||
public:
|
||||
IntrusiveListNode() {
|
||||
this->prev = this;
|
||||
this->next = this;
|
||||
}
|
||||
|
||||
bool IsLinked() const {
|
||||
return this->next != this;
|
||||
}
|
||||
private:
|
||||
void LinkPrev(IntrusiveListNode *node) {
|
||||
/* We can't link an already linked node. */
|
||||
AMS_ASSERT(!node->IsLinked());
|
||||
this->SplicePrev(node, node);
|
||||
}
|
||||
|
||||
void SplicePrev(IntrusiveListNode *first, IntrusiveListNode *last) {
|
||||
/* Splice a range into the list. */
|
||||
auto last_prev = last->prev;
|
||||
first->prev = this->prev;
|
||||
this->prev->next = first;
|
||||
last_prev->next = this;
|
||||
this->prev = last_prev;
|
||||
}
|
||||
|
||||
void LinkNext(IntrusiveListNode *node) {
|
||||
/* We can't link an already linked node. */
|
||||
AMS_ASSERT(!node->IsLinked());
|
||||
return this->SpliceNext(node, node);
|
||||
}
|
||||
|
||||
void SpliceNext(IntrusiveListNode *first, IntrusiveListNode *last) {
|
||||
/* Splice a range into the list. */
|
||||
auto last_prev = last->prev;
|
||||
first->prev = this;
|
||||
this->next = first;
|
||||
last_prev->next = next;
|
||||
this->next->prev = last_prev;
|
||||
}
|
||||
|
||||
void Unlink() {
|
||||
this->Unlink(this->next);
|
||||
}
|
||||
|
||||
void Unlink(IntrusiveListNode *last) {
|
||||
/* Unlink a node from a next node. */
|
||||
auto last_prev = last->prev;
|
||||
this->prev->next = last;
|
||||
last->prev = this->prev;
|
||||
last_prev->next = this;
|
||||
this->prev = last_prev;
|
||||
}
|
||||
|
||||
IntrusiveListNode *GetPrev() {
|
||||
return this->prev;
|
||||
}
|
||||
|
||||
const IntrusiveListNode *GetPrev() const {
|
||||
return this->prev;
|
||||
}
|
||||
|
||||
IntrusiveListNode *GetNext() {
|
||||
return this->next;
|
||||
}
|
||||
|
||||
const IntrusiveListNode *GetNext() const {
|
||||
return this->next;
|
||||
}
|
||||
};
|
||||
|
||||
namespace impl {
|
||||
|
||||
class IntrusiveListImpl {
|
||||
NON_COPYABLE(IntrusiveListImpl);
|
||||
private:
|
||||
IntrusiveListNode root_node;
|
||||
public:
|
||||
template<bool Const>
|
||||
class Iterator;
|
||||
|
||||
using value_type = IntrusiveListNode;
|
||||
using size_type = size_t;
|
||||
using difference_type = ptrdiff_t;
|
||||
using pointer = value_type *;
|
||||
using const_pointer = const value_type *;
|
||||
using reference = value_type &;
|
||||
using const_reference = const value_type &;
|
||||
using iterator = Iterator<false>;
|
||||
using const_iterator = Iterator<true>;
|
||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
|
||||
template<bool Const>
|
||||
class Iterator {
|
||||
public:
|
||||
using iterator_category = std::bidirectional_iterator_tag;
|
||||
using value_type = typename IntrusiveListImpl::value_type;
|
||||
using difference_type = typename IntrusiveListImpl::difference_type;
|
||||
using pointer = typename std::conditional<Const, IntrusiveListImpl::const_pointer, IntrusiveListImpl::pointer>::type;
|
||||
using reference = typename std::conditional<Const, IntrusiveListImpl::const_reference, IntrusiveListImpl::reference>::type;
|
||||
private:
|
||||
pointer node;
|
||||
public:
|
||||
explicit Iterator(pointer n) : node(n) { /* ... */ }
|
||||
|
||||
bool operator==(const Iterator &rhs) const {
|
||||
return this->node == rhs.node;
|
||||
}
|
||||
|
||||
bool operator!=(const Iterator &rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
pointer operator->() const {
|
||||
return this->node;
|
||||
}
|
||||
|
||||
reference operator*() const {
|
||||
return *this->node;
|
||||
}
|
||||
|
||||
Iterator &operator++() {
|
||||
this->node = this->node->next;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator &operator--() {
|
||||
this->node = this->node->prev;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator operator++(int) {
|
||||
const Iterator it{*this};
|
||||
++(*this);
|
||||
return it;
|
||||
}
|
||||
|
||||
Iterator operator--(int) {
|
||||
const Iterator it{*this};
|
||||
--(*this);
|
||||
return it;
|
||||
}
|
||||
|
||||
operator Iterator<true>() const {
|
||||
return Iterator<true>(this->node);
|
||||
}
|
||||
|
||||
Iterator<false> GetNonConstIterator() const {
|
||||
return Iterator<false>(const_cast<IntrusiveListImpl::pointer>(this->node));
|
||||
}
|
||||
};
|
||||
public:
|
||||
IntrusiveListImpl() : root_node() { /* ... */ }
|
||||
|
||||
/* Iterator accessors. */
|
||||
iterator begin() {
|
||||
return iterator(this->root_node.GetNext());
|
||||
}
|
||||
|
||||
const_iterator begin() const {
|
||||
return const_iterator(this->root_node.GetNext());
|
||||
}
|
||||
|
||||
iterator end() {
|
||||
return iterator(&this->root_node);
|
||||
}
|
||||
|
||||
const_iterator end() const {
|
||||
return const_iterator(&this->root_node);
|
||||
}
|
||||
|
||||
iterator iterator_to(reference v) {
|
||||
/* Only allow iterator_to for values in lists. */
|
||||
AMS_ASSERT(v.IsLinked());
|
||||
return iterator(&v);
|
||||
}
|
||||
|
||||
const_iterator iterator_to(const_reference v) const {
|
||||
/* Only allow iterator_to for values in lists. */
|
||||
AMS_ASSERT(v.IsLinked());
|
||||
return const_iterator(&v);
|
||||
}
|
||||
|
||||
/* Content management. */
|
||||
bool empty() const {
|
||||
return !this->root_node.IsLinked();
|
||||
}
|
||||
|
||||
size_type size() const {
|
||||
return static_cast<size_type>(std::distance(this->begin(), this->end()));
|
||||
}
|
||||
|
||||
reference back() {
|
||||
return *this->root_node.GetPrev();
|
||||
}
|
||||
|
||||
const_reference back() const {
|
||||
return *this->root_node.GetPrev();
|
||||
}
|
||||
|
||||
reference front() {
|
||||
return *this->root_node.GetNext();
|
||||
}
|
||||
|
||||
const_reference front() const {
|
||||
return *this->root_node.GetNext();
|
||||
}
|
||||
|
||||
void push_back(reference node) {
|
||||
this->root_node.LinkPrev(&node);
|
||||
}
|
||||
|
||||
void push_front(reference node) {
|
||||
this->root_node.LinkNext(&node);
|
||||
}
|
||||
|
||||
void pop_back() {
|
||||
this->root_node.GetPrev()->Unlink();
|
||||
}
|
||||
|
||||
void pop_front() {
|
||||
this->root_node.GetNext()->Unlink();
|
||||
}
|
||||
|
||||
iterator insert(const_iterator pos, reference node) {
|
||||
pos.GetNonConstIterator()->LinkPrev(&node);
|
||||
return iterator(&node);
|
||||
}
|
||||
|
||||
void splice(const_iterator pos, IntrusiveListImpl &o) {
|
||||
splice_impl(pos, o.begin(), o.end());
|
||||
}
|
||||
|
||||
void splice(const_iterator pos, IntrusiveListImpl &o, const_iterator first) {
|
||||
const_iterator last(first);
|
||||
std::advance(last, 1);
|
||||
splice_impl(pos, first, last);
|
||||
}
|
||||
|
||||
void splice(const_iterator pos, IntrusiveListImpl &o, const_iterator first, const_iterator last) {
|
||||
splice_impl(pos, first, last);
|
||||
}
|
||||
|
||||
iterator erase(const iterator pos) {
|
||||
if (pos == this->end()) {
|
||||
return this->end();
|
||||
}
|
||||
iterator it(pos.GetNonConstIterator());
|
||||
(it++)->Unlink();
|
||||
return it;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
while (!this->empty()) {
|
||||
this->pop_front();
|
||||
}
|
||||
}
|
||||
private:
|
||||
void splice_impl(const_iterator _pos, const_iterator _first, const_iterator _last) {
|
||||
if (_first == _last) {
|
||||
return;
|
||||
}
|
||||
iterator pos(_pos.GetNonConstIterator());
|
||||
iterator first(_first.GetNonConstIterator());
|
||||
iterator last(_last.GetNonConstIterator());
|
||||
first->Unlink(&*last);
|
||||
pos->SplicePrev(&*first, &*first);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<class T, class Traits>
|
||||
class IntrusiveList {
|
||||
NON_COPYABLE(IntrusiveList);
|
||||
private:
|
||||
impl::IntrusiveListImpl impl;
|
||||
public:
|
||||
template<bool Const>
|
||||
class Iterator;
|
||||
|
||||
using value_type = T;
|
||||
using size_type = size_t;
|
||||
using difference_type = ptrdiff_t;
|
||||
using pointer = value_type *;
|
||||
using const_pointer = const value_type *;
|
||||
using reference = value_type &;
|
||||
using const_reference = const value_type &;
|
||||
using iterator = Iterator<false>;
|
||||
using const_iterator = Iterator<true>;
|
||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
|
||||
template<bool Const>
|
||||
class Iterator {
|
||||
public:
|
||||
friend class ams::util::IntrusiveList<T, Traits>;
|
||||
|
||||
using ImplIterator = typename std::conditional<Const, ams::util::impl::IntrusiveListImpl::const_iterator, ams::util::impl::IntrusiveListImpl::iterator>::type;
|
||||
|
||||
using iterator_category = std::bidirectional_iterator_tag;
|
||||
using value_type = typename IntrusiveList::value_type;
|
||||
using difference_type = typename IntrusiveList::difference_type;
|
||||
using pointer = typename std::conditional<Const, IntrusiveList::const_pointer, IntrusiveList::pointer>::type;
|
||||
using reference = typename std::conditional<Const, IntrusiveList::const_reference, IntrusiveList::reference>::type;
|
||||
private:
|
||||
ImplIterator iterator;
|
||||
private:
|
||||
explicit Iterator(ImplIterator it) : iterator(it) { /* ... */ }
|
||||
|
||||
ImplIterator GetImplIterator() const {
|
||||
return this->iterator;
|
||||
}
|
||||
public:
|
||||
bool operator==(const Iterator &rhs) const {
|
||||
return this->iterator == rhs.iterator;
|
||||
}
|
||||
|
||||
bool operator!=(const Iterator &rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
pointer operator->() const {
|
||||
return &Traits::GetParent(*this->iterator);
|
||||
}
|
||||
|
||||
reference operator*() const {
|
||||
return Traits::GetParent(*this->iterator);
|
||||
}
|
||||
|
||||
Iterator &operator++() {
|
||||
++this->iterator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator &operator--() {
|
||||
--this->iterator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator operator++(int) {
|
||||
const Iterator it{*this};
|
||||
++this->iterator;
|
||||
return it;
|
||||
}
|
||||
|
||||
Iterator operator--(int) {
|
||||
const Iterator it{*this};
|
||||
--this->iterator;
|
||||
return it;
|
||||
}
|
||||
|
||||
operator Iterator<true>() const {
|
||||
return Iterator<true>(this->iterator);
|
||||
}
|
||||
};
|
||||
private:
|
||||
static constexpr IntrusiveListNode &GetNode(reference ref) {
|
||||
return Traits::GetNode(ref);
|
||||
}
|
||||
|
||||
static constexpr IntrusiveListNode const &GetNode(const_reference ref) {
|
||||
return Traits::GetNode(ref);
|
||||
}
|
||||
|
||||
static constexpr reference GetParent(IntrusiveListNode &node) {
|
||||
return Traits::GetParent(node);
|
||||
}
|
||||
|
||||
static constexpr const_reference GetParent(IntrusiveListNode const &node) {
|
||||
return Traits::GetParent(node);
|
||||
}
|
||||
public:
|
||||
IntrusiveList() : impl() { /* ... */ }
|
||||
|
||||
/* Iterator accessors. */
|
||||
iterator begin() {
|
||||
return iterator(this->impl.begin());
|
||||
}
|
||||
|
||||
const_iterator begin() const {
|
||||
return const_iterator(this->impl.begin());
|
||||
}
|
||||
|
||||
iterator end() {
|
||||
return iterator(this->impl.end());
|
||||
}
|
||||
|
||||
const_iterator end() const {
|
||||
return const_iterator(this->impl.end());
|
||||
}
|
||||
|
||||
const_iterator cbegin() const {
|
||||
return this->begin();
|
||||
}
|
||||
|
||||
const_iterator cend() const {
|
||||
return this->end();
|
||||
}
|
||||
|
||||
reverse_iterator rbegin() {
|
||||
return reverse_iterator(this->end());
|
||||
}
|
||||
|
||||
const_reverse_iterator rbegin() const {
|
||||
return const_reverse_iterator(this->end());
|
||||
}
|
||||
|
||||
reverse_iterator rend() {
|
||||
return reverse_iterator(this->begin());
|
||||
}
|
||||
|
||||
const_reverse_iterator rend() const {
|
||||
return const_reverse_iterator(this->begin());
|
||||
}
|
||||
|
||||
const_reverse_iterator crbegin() const {
|
||||
return this->rbegin();
|
||||
}
|
||||
|
||||
const_reverse_iterator crend() const {
|
||||
return this->rend();
|
||||
}
|
||||
|
||||
iterator iterator_to(reference v) {
|
||||
return iterator(this->impl.iterator_to(GetNode(v)));
|
||||
}
|
||||
|
||||
const_iterator iterator_to(const_reference v) const {
|
||||
return const_iterator(this->impl.iterator_to(GetNode(v)));
|
||||
}
|
||||
|
||||
/* Content management. */
|
||||
bool empty() const {
|
||||
return this->impl.empty();
|
||||
}
|
||||
|
||||
size_type size() const {
|
||||
return this->impl.size();
|
||||
}
|
||||
|
||||
reference back() {
|
||||
AMS_ASSERT(!this->impl.empty());
|
||||
return GetParent(this->impl.back());
|
||||
}
|
||||
|
||||
const_reference back() const {
|
||||
AMS_ASSERT(!this->impl.empty());
|
||||
return GetParent(this->impl.back());
|
||||
}
|
||||
|
||||
reference front() {
|
||||
AMS_ASSERT(!this->impl.empty());
|
||||
return GetParent(this->impl.front());
|
||||
}
|
||||
|
||||
const_reference front() const {
|
||||
AMS_ASSERT(!this->impl.empty());
|
||||
return GetParent(this->impl.front());
|
||||
}
|
||||
|
||||
void push_back(reference ref) {
|
||||
this->impl.push_back(GetNode(ref));
|
||||
}
|
||||
|
||||
void push_front(reference ref) {
|
||||
this->impl.push_back(GetNode(ref));
|
||||
}
|
||||
|
||||
void pop_back() {
|
||||
AMS_ASSERT(!this->impl.empty());
|
||||
this->impl.pop_back();
|
||||
}
|
||||
|
||||
void pop_front() {
|
||||
AMS_ASSERT(!this->impl.empty());
|
||||
this->impl.pop_front();
|
||||
}
|
||||
|
||||
iterator insert(const_iterator pos, reference ref) {
|
||||
return iterator(this->impl.insert(pos.GetImplIterator(), GetNode(ref)));
|
||||
}
|
||||
|
||||
void splice(const_iterator pos, IntrusiveList &o) {
|
||||
this->impl.splice(pos.GetImplIterator(), o.impl);
|
||||
}
|
||||
|
||||
void splice(const_iterator pos, IntrusiveList &o, const_iterator first) {
|
||||
this->impl.splice(pos.GetImplIterator(), o.impl, first.GetImplIterator());
|
||||
}
|
||||
|
||||
void splice(const_iterator pos, IntrusiveList &o, const_iterator first, const_iterator last) {
|
||||
this->impl.splice(pos.GetImplIterator(), o.impl, first.GetImplIterator(), last.GetImplIterator());
|
||||
}
|
||||
|
||||
iterator erase(const iterator pos) {
|
||||
return iterator(this->impl.erase(pos.GetImplIterator()));
|
||||
}
|
||||
|
||||
void clear() {
|
||||
this->impl.clear();
|
||||
}
|
||||
};
|
||||
|
||||
template<auto T, class Derived = util::impl::GetParentType<T>>
|
||||
class IntrusiveListMemberTraits;
|
||||
|
||||
template<class Parent, IntrusiveListNode Parent::*Member, class Derived>
|
||||
class IntrusiveListMemberTraits<Member, Derived> {
|
||||
public:
|
||||
using ListType = IntrusiveList<Derived, IntrusiveListMemberTraits>;
|
||||
private:
|
||||
friend class IntrusiveList<Derived, IntrusiveListMemberTraits>;
|
||||
|
||||
static constexpr IntrusiveListNode &GetNode(Derived &parent) {
|
||||
return parent.*Member;
|
||||
}
|
||||
|
||||
static constexpr IntrusiveListNode const &GetNode(Derived const &parent) {
|
||||
return parent.*Member;
|
||||
}
|
||||
|
||||
static constexpr Derived &GetParent(IntrusiveListNode &node) {
|
||||
return static_cast<Derived &>(util::GetParentReference<Member>(&node));
|
||||
}
|
||||
|
||||
static constexpr Derived const &GetParent(IntrusiveListNode const &node) {
|
||||
return static_cast<const Derived &>(util::GetParentReference<Member>(&node));
|
||||
}
|
||||
};
|
||||
|
||||
template<class Derived>
|
||||
class IntrusiveListBaseNode : public IntrusiveListNode{};
|
||||
|
||||
template<class Derived>
|
||||
class IntrusiveListBaseTraits {
|
||||
public:
|
||||
using ListType = IntrusiveList<Derived, IntrusiveListBaseTraits>;
|
||||
private:
|
||||
friend class IntrusiveList<Derived, IntrusiveListBaseTraits>;
|
||||
|
||||
static constexpr IntrusiveListNode &GetNode(Derived &parent) {
|
||||
return static_cast<IntrusiveListNode &>(parent);
|
||||
}
|
||||
|
||||
static constexpr IntrusiveListNode const &GetNode(Derived const &parent) {
|
||||
return static_cast<const IntrusiveListNode &>(parent);
|
||||
}
|
||||
|
||||
static constexpr Derived &GetParent(IntrusiveListNode &node) {
|
||||
return static_cast<Derived &>(node);
|
||||
}
|
||||
|
||||
static constexpr Derived const &GetParent(IntrusiveListNode const &node) {
|
||||
return static_cast<const Derived &>(node);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -1,297 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <freebsd/sys/tree.h>
|
||||
#include "util_parent_of_member.hpp"
|
||||
|
||||
namespace ams::util {
|
||||
|
||||
struct IntrusiveRedBlackTreeNode {
|
||||
NON_COPYABLE(IntrusiveRedBlackTreeNode);
|
||||
private:
|
||||
RB_ENTRY(IntrusiveRedBlackTreeNode) entry;
|
||||
|
||||
template<class, class, class>
|
||||
friend class IntrusiveRedBlackTree;
|
||||
public:
|
||||
IntrusiveRedBlackTreeNode() { /* ... */}
|
||||
};
|
||||
|
||||
template<class T, class Traits, class Comparator>
|
||||
class IntrusiveRedBlackTree {
|
||||
NON_COPYABLE(IntrusiveRedBlackTree);
|
||||
private:
|
||||
RB_HEAD(IntrusiveRedBlackTreeRoot, IntrusiveRedBlackTreeNode);
|
||||
|
||||
IntrusiveRedBlackTreeRoot root;
|
||||
public:
|
||||
template<bool Const>
|
||||
class Iterator;
|
||||
|
||||
using value_type = T;
|
||||
using size_type = size_t;
|
||||
using difference_type = ptrdiff_t;
|
||||
using pointer = T *;
|
||||
using const_pointer = const T *;
|
||||
using reference = T &;
|
||||
using const_reference = const T &;
|
||||
using iterator = Iterator<false>;
|
||||
using const_iterator = Iterator<true>;
|
||||
|
||||
template<bool Const>
|
||||
class Iterator {
|
||||
public:
|
||||
using iterator_category = std::bidirectional_iterator_tag;
|
||||
using value_type = typename IntrusiveRedBlackTree::value_type;
|
||||
using difference_type = typename IntrusiveRedBlackTree::difference_type;
|
||||
using pointer = typename std::conditional<Const, IntrusiveRedBlackTree::const_pointer, IntrusiveRedBlackTree::pointer>::type;
|
||||
using reference = typename std::conditional<Const, IntrusiveRedBlackTree::const_reference, IntrusiveRedBlackTree::reference>::type;
|
||||
private:
|
||||
pointer node;
|
||||
public:
|
||||
explicit Iterator(pointer n) : node(n) { /* ... */ }
|
||||
|
||||
bool operator==(const Iterator &rhs) const {
|
||||
return this->node == rhs.node;
|
||||
}
|
||||
|
||||
bool operator!=(const Iterator &rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
pointer operator->() const {
|
||||
return this->node;
|
||||
}
|
||||
|
||||
reference operator*() const {
|
||||
return *this->node;
|
||||
}
|
||||
|
||||
Iterator &operator++() {
|
||||
this->node = Traits::GetParent(GetNext(Traits::GetNode(this->node)));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator &operator--() {
|
||||
this->node = Traits::GetParent(GetPrev(Traits::GetNode(this->node)));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator operator++(int) {
|
||||
const Iterator it{*this};
|
||||
++(*this);
|
||||
return it;
|
||||
}
|
||||
|
||||
Iterator operator--(int) {
|
||||
const Iterator it{*this};
|
||||
--(*this);
|
||||
return it;
|
||||
}
|
||||
|
||||
operator Iterator<true>() const {
|
||||
return Iterator<true>(this->node);
|
||||
}
|
||||
};
|
||||
private:
|
||||
static int CompareImpl(const IntrusiveRedBlackTreeNode *lhs, const IntrusiveRedBlackTreeNode *rhs) {
|
||||
return Comparator::Compare(*Traits::GetParent(lhs), *Traits::GetParent(rhs));
|
||||
}
|
||||
|
||||
/* Generate static implementations for IntrusiveRedBlackTreeRoot. */
|
||||
RB_GENERATE_STATIC(IntrusiveRedBlackTreeRoot, IntrusiveRedBlackTreeNode, entry, CompareImpl);
|
||||
|
||||
static constexpr inline IntrusiveRedBlackTreeNode *GetNext(IntrusiveRedBlackTreeNode *node) {
|
||||
return RB_NEXT(IntrusiveRedBlackTreeRoot, nullptr, node);
|
||||
}
|
||||
|
||||
static constexpr inline IntrusiveRedBlackTreeNode const *GetNext(IntrusiveRedBlackTreeNode const *node) {
|
||||
return const_cast<const IntrusiveRedBlackTreeNode *>(GetNext(const_cast<IntrusiveRedBlackTreeNode *>(node)));
|
||||
}
|
||||
|
||||
static constexpr inline IntrusiveRedBlackTreeNode *GetPrev(IntrusiveRedBlackTreeNode *node) {
|
||||
return RB_NEXT(IntrusiveRedBlackTreeRoot, nullptr, node);
|
||||
}
|
||||
|
||||
static constexpr inline IntrusiveRedBlackTreeNode const *GetPrev(IntrusiveRedBlackTreeNode const *node) {
|
||||
return const_cast<const IntrusiveRedBlackTreeNode *>(GetPrev(const_cast<IntrusiveRedBlackTreeNode *>(node)));
|
||||
}
|
||||
|
||||
/* Define accessors using RB_* functions. */
|
||||
void InitializeImpl() {
|
||||
RB_INIT(&this->root);
|
||||
}
|
||||
|
||||
bool EmptyImpl() const {
|
||||
return RB_EMPTY(&this->root);
|
||||
}
|
||||
|
||||
IntrusiveRedBlackTreeNode *GetMinImpl() const {
|
||||
return RB_MIN(IntrusiveRedBlackTreeRoot, const_cast<IntrusiveRedBlackTreeRoot *>(&this->root));
|
||||
}
|
||||
|
||||
IntrusiveRedBlackTreeNode *GetMaxImpl() const {
|
||||
return RB_MIN(IntrusiveRedBlackTreeRoot, const_cast<IntrusiveRedBlackTreeRoot *>(&this->root));
|
||||
}
|
||||
|
||||
IntrusiveRedBlackTreeNode *InsertImpl(IntrusiveRedBlackTreeNode *node) {
|
||||
return RB_INSERT(IntrusiveRedBlackTreeRoot, &this->root, node);
|
||||
}
|
||||
|
||||
IntrusiveRedBlackTreeNode *RemoveImpl(IntrusiveRedBlackTreeNode *node) {
|
||||
return RB_REMOVE(IntrusiveRedBlackTreeRoot, &this->root, node);
|
||||
}
|
||||
|
||||
IntrusiveRedBlackTreeNode *FindImpl(IntrusiveRedBlackTreeNode const *node) const {
|
||||
return RB_FIND(IntrusiveRedBlackTreeRoot, const_cast<IntrusiveRedBlackTreeRoot *>(&this->root), const_cast<IntrusiveRedBlackTreeNode *>(node));
|
||||
}
|
||||
|
||||
IntrusiveRedBlackTreeNode *NFindImpl(IntrusiveRedBlackTreeNode const *node) const {
|
||||
return RB_NFIND(IntrusiveRedBlackTreeRoot, const_cast<IntrusiveRedBlackTreeRoot *>(&this->root), const_cast<IntrusiveRedBlackTreeNode *>(node));
|
||||
}
|
||||
|
||||
public:
|
||||
IntrusiveRedBlackTree() {
|
||||
this->InitializeImpl();
|
||||
}
|
||||
|
||||
/* Iterator accessors. */
|
||||
iterator begin() {
|
||||
return iterator(Traits::GetParent(this->GetMinImpl()));
|
||||
}
|
||||
|
||||
const_iterator begin() const {
|
||||
return const_iterator(Traits::GetParent(this->GetMinImpl()));
|
||||
}
|
||||
|
||||
iterator end() {
|
||||
return iterator(Traits::GetParent(static_cast<IntrusiveRedBlackTreeNode *>(nullptr)));
|
||||
}
|
||||
|
||||
const_iterator end() const {
|
||||
return const_iterator(Traits::GetParent(static_cast<IntrusiveRedBlackTreeNode *>(nullptr)));
|
||||
}
|
||||
|
||||
iterator iterator_to(reference ref) {
|
||||
return iterator(&ref);
|
||||
}
|
||||
|
||||
const_iterator iterator_to(const_reference ref) const {
|
||||
return const_iterator(&ref);
|
||||
}
|
||||
|
||||
/* Content management. */
|
||||
bool empty() const {
|
||||
return this->EmptyImpl();
|
||||
}
|
||||
|
||||
reference back() {
|
||||
return Traits::GetParent(this->GetMaxImpl());
|
||||
}
|
||||
|
||||
const_reference back() const {
|
||||
return Traits::GetParent(this->GetMaxImpl());
|
||||
}
|
||||
|
||||
reference front() {
|
||||
return Traits::GetParent(this->GetMinImpl());
|
||||
}
|
||||
|
||||
const_reference front() const {
|
||||
return Traits::GetParent(this->GetMinImpl());
|
||||
}
|
||||
|
||||
iterator insert(reference ref) {
|
||||
this->InsertImpl(Traits::GetNode(&ref));
|
||||
return iterator(&ref);
|
||||
}
|
||||
|
||||
iterator erase(iterator it) {
|
||||
auto cur = Traits::GetNode(&*it);
|
||||
auto next = Traits::GetParent(GetNext(cur));
|
||||
this->RemoveImpl(cur);
|
||||
return iterator(next);
|
||||
}
|
||||
|
||||
iterator find(const_reference ref) const {
|
||||
return iterator(Traits::GetParent(this->FindImpl(Traits::GetNode(&ref))));
|
||||
}
|
||||
|
||||
iterator nfind(const_reference ref) const {
|
||||
return iterator(Traits::GetParent(this->NFindImpl(Traits::GetNode(&ref))));
|
||||
}
|
||||
};
|
||||
|
||||
template<auto T, class Derived = util::impl::GetParentType<T>>
|
||||
class IntrusiveRedBlackTreeMemberTraits;
|
||||
|
||||
template<class Parent, IntrusiveRedBlackTreeNode Parent::*Member, class Derived>
|
||||
class IntrusiveRedBlackTreeMemberTraits<Member, Derived> {
|
||||
public:
|
||||
template<class Comparator>
|
||||
using ListType = IntrusiveRedBlackTree<Derived, IntrusiveRedBlackTreeMemberTraits, Comparator>;
|
||||
private:
|
||||
template<class, class, class>
|
||||
friend class IntrusiveRedBlackTree;
|
||||
|
||||
static constexpr IntrusiveRedBlackTreeNode *GetNode(Derived *parent) {
|
||||
return &(parent->*Member);
|
||||
}
|
||||
|
||||
static constexpr IntrusiveRedBlackTreeNode const *GetNode(Derived const *parent) {
|
||||
return &(parent->*Member);
|
||||
}
|
||||
|
||||
static constexpr Derived *GetParent(IntrusiveRedBlackTreeNode *node) {
|
||||
return static_cast<Derived *>(util::GetParentPointer<Member>(node));
|
||||
}
|
||||
|
||||
static constexpr Derived const *GetParent(IntrusiveRedBlackTreeNode const *node) {
|
||||
return static_cast<const Derived *>(util::GetParentPointer<Member>(node));
|
||||
}
|
||||
};
|
||||
|
||||
template<class Derived>
|
||||
class IntrusiveRedBlackTreeBaseNode : public IntrusiveRedBlackTreeNode{};
|
||||
|
||||
template<class Derived>
|
||||
class IntrusiveRedBlackTreeBaseTraits {
|
||||
public:
|
||||
template<class Comparator>
|
||||
using ListType = IntrusiveRedBlackTree<Derived, IntrusiveRedBlackTreeBaseTraits, Comparator>;
|
||||
private:
|
||||
template<class, class, class>
|
||||
friend class IntrusiveRedBlackTree;
|
||||
|
||||
static constexpr IntrusiveRedBlackTreeNode *GetNode(Derived *parent) {
|
||||
return static_cast<IntrusiveRedBlackTreeNode *>(parent);
|
||||
}
|
||||
|
||||
static constexpr IntrusiveRedBlackTreeNode const *GetNode(Derived const *parent) {
|
||||
return static_cast<const IntrusiveRedBlackTreeNode *>(parent);
|
||||
}
|
||||
|
||||
static constexpr Derived *GetParent(IntrusiveRedBlackTreeNode *node) {
|
||||
return static_cast<Derived *>(node);
|
||||
}
|
||||
|
||||
static constexpr Derived const *GetParent(IntrusiveRedBlackTreeNode const *node) {
|
||||
return static_cast<const Derived *>(node);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../defines.hpp"
|
||||
|
||||
namespace ams::util {
|
||||
|
||||
namespace impl {
|
||||
|
||||
template<typename Parent, typename Member>
|
||||
union OffsetOfImpl {
|
||||
Member Parent::* ptr;
|
||||
intptr_t offset;
|
||||
};
|
||||
|
||||
template<typename Parent, typename Member>
|
||||
constexpr inline Parent *GetParentOfMemberImpl(Member *member, Member Parent::* ptr) {
|
||||
return reinterpret_cast<Parent *>(reinterpret_cast<uintptr_t>(member) - OffsetOfImpl<Parent, Member>{ ptr }.offset);
|
||||
}
|
||||
|
||||
template<typename Parent, typename Member>
|
||||
constexpr inline Parent const *GetParentOfMemberImpl(Member const *member, Member Parent::* ptr) {
|
||||
return reinterpret_cast<Parent *>(reinterpret_cast<uintptr_t>(member) - OffsetOfImpl<Parent, Member>{ ptr }.offset);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct GetMemberPointerTraits;
|
||||
|
||||
template<typename P, typename M>
|
||||
struct GetMemberPointerTraits<M P::*> {
|
||||
using Parent = P;
|
||||
using Member = M;
|
||||
};
|
||||
|
||||
template<auto MemberPtr>
|
||||
using GetParentType = typename GetMemberPointerTraits<decltype(MemberPtr)>::Parent;
|
||||
|
||||
template<auto MemberPtr>
|
||||
using GetMemberType = typename GetMemberPointerTraits<decltype(MemberPtr)>::Member;
|
||||
|
||||
}
|
||||
|
||||
template<auto MemberPtr>
|
||||
constexpr inline impl::GetParentType<MemberPtr> *GetParentPointer(impl::GetMemberType<MemberPtr> *member) {
|
||||
return impl::GetParentOfMemberImpl<impl::GetParentType<MemberPtr>, impl::GetMemberType<MemberPtr>>(member, MemberPtr);
|
||||
}
|
||||
|
||||
template<auto MemberPtr>
|
||||
constexpr inline impl::GetParentType<MemberPtr> const *GetParentPointer(impl::GetMemberType<MemberPtr> const *member) {
|
||||
return impl::GetParentOfMemberImpl<impl::GetParentType<MemberPtr>, impl::GetMemberType<MemberPtr>>(member, MemberPtr);
|
||||
}
|
||||
|
||||
template<auto MemberPtr>
|
||||
constexpr inline impl::GetParentType<MemberPtr> &GetParentReference(impl::GetMemberType<MemberPtr> *member) {
|
||||
return *impl::GetParentOfMemberImpl<impl::GetParentType<MemberPtr>, impl::GetMemberType<MemberPtr>>(member, MemberPtr);
|
||||
}
|
||||
|
||||
template<auto MemberPtr>
|
||||
constexpr inline impl::GetParentType<MemberPtr> const &GetParentReference(impl::GetMemberType<MemberPtr> const *member) {
|
||||
return *impl::GetParentOfMemberImpl<impl::GetParentType<MemberPtr>, impl::GetMemberType<MemberPtr>>(member, MemberPtr);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Scope guard logic lovingly taken from Andrei Alexandrescu's "Systemic Error Handling in C++" */
|
||||
#pragma once
|
||||
#include "../defines.hpp"
|
||||
|
||||
namespace ams::util {
|
||||
|
||||
namespace impl {
|
||||
|
||||
template<class F>
|
||||
class ScopeGuard {
|
||||
NON_COPYABLE(ScopeGuard);
|
||||
private:
|
||||
F f;
|
||||
bool active;
|
||||
public:
|
||||
constexpr ScopeGuard(F f) : f(std::move(f)), active(true) { }
|
||||
~ScopeGuard() { if (active) { f(); } }
|
||||
void Cancel() { active = false; }
|
||||
|
||||
ScopeGuard(ScopeGuard&& rhs) : f(std::move(rhs.f)), active(rhs.active) {
|
||||
rhs.Cancel();
|
||||
}
|
||||
};
|
||||
|
||||
template<class F>
|
||||
constexpr ScopeGuard<F> MakeScopeGuard(F f) {
|
||||
return ScopeGuard<F>(std::move(f));
|
||||
}
|
||||
|
||||
enum class ScopeGuardOnExit {};
|
||||
|
||||
template <typename F>
|
||||
constexpr ScopeGuard<F> operator+(ScopeGuardOnExit, F&& f) {
|
||||
return ScopeGuard<F>(std::forward<F>(f));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#define SCOPE_GUARD ::ams::util::impl::ScopeGuardOnExit() + [&]()
|
||||
#define ON_SCOPE_EXIT auto ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE_) = SCOPE_GUARD
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../defines.hpp"
|
||||
|
||||
namespace ams::util {
|
||||
|
||||
/* std::size() does not support zero-size C arrays. We're fixing that. */
|
||||
template<class C>
|
||||
constexpr auto size(const C& c) -> decltype(c.size()) {
|
||||
return std::size(c);
|
||||
}
|
||||
|
||||
template<class C>
|
||||
constexpr std::size_t size(const C& c) {
|
||||
if constexpr (sizeof(C) == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return std::size(c);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../defines.hpp"
|
||||
|
||||
namespace ams::util {
|
||||
|
||||
template<typename T, size_t Size, size_t Align>
|
||||
struct TypedStorage {
|
||||
typename std::aligned_storage<Size, Align>::type _storage;
|
||||
};
|
||||
|
||||
#define TYPED_STORAGE(T) ::ams::util::TypedStorage<T, sizeof(T), alignof(T)>
|
||||
|
||||
template<typename T>
|
||||
static constexpr inline __attribute__((always_inline)) T *GetPointer(TYPED_STORAGE(T) &ts) {
|
||||
return reinterpret_cast<T *>(&ts._storage);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static constexpr inline __attribute__((always_inline)) const T *GetPointer(const TYPED_STORAGE(T) &ts) {
|
||||
return reinterpret_cast<const T *>(&ts._storage);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static constexpr inline __attribute__((always_inline)) T &GetReference(TYPED_STORAGE(T) &ts) {
|
||||
return *GetPointer(ts);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static constexpr inline __attribute__((always_inline)) const T &GetReference(const TYPED_STORAGE(T) &ts) {
|
||||
return *GetPointer(ts);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,812 +0,0 @@
|
|||
/* $NetBSD: tree.h,v 1.8 2004/03/28 19:38:30 provos Exp $ */
|
||||
/* $OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*-
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_TREE_H_
|
||||
#define _SYS_TREE_H_
|
||||
|
||||
/* FreeBSD <sys/cdefs.h> has a lot of defines we don't really want. */
|
||||
/* tree.h only actually uses __inline and __unused, so we'll just define those. */
|
||||
|
||||
/* #include <sys/cdefs.h> */
|
||||
|
||||
#ifndef __inline
|
||||
#define __inline inline
|
||||
#endif
|
||||
|
||||
#ifndef __unused
|
||||
#define __unused __attribute__((__unused__))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This file defines data structures for different types of trees:
|
||||
* splay trees and red-black trees.
|
||||
*
|
||||
* A splay tree is a self-organizing data structure. Every operation
|
||||
* on the tree causes a splay to happen. The splay moves the requested
|
||||
* node to the root of the tree and partly rebalances it.
|
||||
*
|
||||
* This has the benefit that request locality causes faster lookups as
|
||||
* the requested nodes move to the top of the tree. On the other hand,
|
||||
* every lookup causes memory writes.
|
||||
*
|
||||
* The Balance Theorem bounds the total access time for m operations
|
||||
* and n inserts on an initially empty tree as O((m + n)lg n). The
|
||||
* amortized cost for a sequence of m accesses to a splay tree is O(lg n);
|
||||
*
|
||||
* A red-black tree is a binary search tree with the node color as an
|
||||
* extra attribute. It fulfills a set of conditions:
|
||||
* - every search path from the root to a leaf consists of the
|
||||
* same number of black nodes,
|
||||
* - each red node (except for the root) has a black parent,
|
||||
* - each leaf node is black.
|
||||
*
|
||||
* Every operation on a red-black tree is bounded as O(lg n).
|
||||
* The maximum height of a red-black tree is 2lg (n+1).
|
||||
*/
|
||||
|
||||
#define SPLAY_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *sph_root; /* root of the tree */ \
|
||||
}
|
||||
|
||||
#define SPLAY_INITIALIZER(root) \
|
||||
{ NULL }
|
||||
|
||||
#define SPLAY_INIT(root) do { \
|
||||
(root)->sph_root = NULL; \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#define SPLAY_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *spe_left; /* left element */ \
|
||||
struct type *spe_right; /* right element */ \
|
||||
}
|
||||
|
||||
#define SPLAY_LEFT(elm, field) (elm)->field.spe_left
|
||||
#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right
|
||||
#define SPLAY_ROOT(head) (head)->sph_root
|
||||
#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL)
|
||||
|
||||
/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
|
||||
#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \
|
||||
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \
|
||||
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
|
||||
(head)->sph_root = tmp; \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \
|
||||
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \
|
||||
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
|
||||
(head)->sph_root = tmp; \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#define SPLAY_LINKLEFT(head, tmp, field) do { \
|
||||
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
|
||||
tmp = (head)->sph_root; \
|
||||
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#define SPLAY_LINKRIGHT(head, tmp, field) do { \
|
||||
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
|
||||
tmp = (head)->sph_root; \
|
||||
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \
|
||||
SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \
|
||||
SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\
|
||||
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \
|
||||
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
/* Generates prototypes and inline functions */
|
||||
|
||||
#define SPLAY_PROTOTYPE(name, type, field, cmp) \
|
||||
void name##_SPLAY(struct name *, struct type *); \
|
||||
void name##_SPLAY_MINMAX(struct name *, int); \
|
||||
struct type *name##_SPLAY_INSERT(struct name *, struct type *); \
|
||||
struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \
|
||||
\
|
||||
/* Finds the node with the same key as elm */ \
|
||||
static __inline struct type * \
|
||||
name##_SPLAY_FIND(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
if (SPLAY_EMPTY(head)) \
|
||||
return(NULL); \
|
||||
name##_SPLAY(head, elm); \
|
||||
if ((cmp)(elm, (head)->sph_root) == 0) \
|
||||
return (head->sph_root); \
|
||||
return (NULL); \
|
||||
} \
|
||||
\
|
||||
static __inline struct type * \
|
||||
name##_SPLAY_NEXT(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
name##_SPLAY(head, elm); \
|
||||
if (SPLAY_RIGHT(elm, field) != NULL) { \
|
||||
elm = SPLAY_RIGHT(elm, field); \
|
||||
while (SPLAY_LEFT(elm, field) != NULL) { \
|
||||
elm = SPLAY_LEFT(elm, field); \
|
||||
} \
|
||||
} else \
|
||||
elm = NULL; \
|
||||
return (elm); \
|
||||
} \
|
||||
\
|
||||
static __inline struct type * \
|
||||
name##_SPLAY_MIN_MAX(struct name *head, int val) \
|
||||
{ \
|
||||
name##_SPLAY_MINMAX(head, val); \
|
||||
return (SPLAY_ROOT(head)); \
|
||||
}
|
||||
|
||||
/* Main splay operation.
|
||||
* Moves node close to the key of elm to top
|
||||
*/
|
||||
#define SPLAY_GENERATE(name, type, field, cmp) \
|
||||
struct type * \
|
||||
name##_SPLAY_INSERT(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
if (SPLAY_EMPTY(head)) { \
|
||||
SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \
|
||||
} else { \
|
||||
int __comp; \
|
||||
name##_SPLAY(head, elm); \
|
||||
__comp = (cmp)(elm, (head)->sph_root); \
|
||||
if(__comp < 0) { \
|
||||
SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\
|
||||
SPLAY_RIGHT(elm, field) = (head)->sph_root; \
|
||||
SPLAY_LEFT((head)->sph_root, field) = NULL; \
|
||||
} else if (__comp > 0) { \
|
||||
SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\
|
||||
SPLAY_LEFT(elm, field) = (head)->sph_root; \
|
||||
SPLAY_RIGHT((head)->sph_root, field) = NULL; \
|
||||
} else \
|
||||
return ((head)->sph_root); \
|
||||
} \
|
||||
(head)->sph_root = (elm); \
|
||||
return (NULL); \
|
||||
} \
|
||||
\
|
||||
struct type * \
|
||||
name##_SPLAY_REMOVE(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *__tmp; \
|
||||
if (SPLAY_EMPTY(head)) \
|
||||
return (NULL); \
|
||||
name##_SPLAY(head, elm); \
|
||||
if ((cmp)(elm, (head)->sph_root) == 0) { \
|
||||
if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \
|
||||
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\
|
||||
} else { \
|
||||
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
|
||||
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\
|
||||
name##_SPLAY(head, elm); \
|
||||
SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
|
||||
} \
|
||||
return (elm); \
|
||||
} \
|
||||
return (NULL); \
|
||||
} \
|
||||
\
|
||||
void \
|
||||
name##_SPLAY(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type __node, *__left, *__right, *__tmp; \
|
||||
int __comp; \
|
||||
\
|
||||
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
|
||||
__left = __right = &__node; \
|
||||
\
|
||||
while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) { \
|
||||
if (__comp < 0) { \
|
||||
__tmp = SPLAY_LEFT((head)->sph_root, field); \
|
||||
if (__tmp == NULL) \
|
||||
break; \
|
||||
if ((cmp)(elm, __tmp) < 0){ \
|
||||
SPLAY_ROTATE_RIGHT(head, __tmp, field); \
|
||||
if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
|
||||
break; \
|
||||
} \
|
||||
SPLAY_LINKLEFT(head, __right, field); \
|
||||
} else if (__comp > 0) { \
|
||||
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
|
||||
if (__tmp == NULL) \
|
||||
break; \
|
||||
if ((cmp)(elm, __tmp) > 0){ \
|
||||
SPLAY_ROTATE_LEFT(head, __tmp, field); \
|
||||
if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
|
||||
break; \
|
||||
} \
|
||||
SPLAY_LINKRIGHT(head, __left, field); \
|
||||
} \
|
||||
} \
|
||||
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
|
||||
} \
|
||||
\
|
||||
/* Splay with either the minimum or the maximum element \
|
||||
* Used to find minimum or maximum element in tree. \
|
||||
*/ \
|
||||
void name##_SPLAY_MINMAX(struct name *head, int __comp) \
|
||||
{ \
|
||||
struct type __node, *__left, *__right, *__tmp; \
|
||||
\
|
||||
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
|
||||
__left = __right = &__node; \
|
||||
\
|
||||
while (1) { \
|
||||
if (__comp < 0) { \
|
||||
__tmp = SPLAY_LEFT((head)->sph_root, field); \
|
||||
if (__tmp == NULL) \
|
||||
break; \
|
||||
if (__comp < 0){ \
|
||||
SPLAY_ROTATE_RIGHT(head, __tmp, field); \
|
||||
if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
|
||||
break; \
|
||||
} \
|
||||
SPLAY_LINKLEFT(head, __right, field); \
|
||||
} else if (__comp > 0) { \
|
||||
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
|
||||
if (__tmp == NULL) \
|
||||
break; \
|
||||
if (__comp > 0) { \
|
||||
SPLAY_ROTATE_LEFT(head, __tmp, field); \
|
||||
if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
|
||||
break; \
|
||||
} \
|
||||
SPLAY_LINKRIGHT(head, __left, field); \
|
||||
} \
|
||||
} \
|
||||
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
|
||||
}
|
||||
|
||||
#define SPLAY_NEGINF -1
|
||||
#define SPLAY_INF 1
|
||||
|
||||
#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y)
|
||||
#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y)
|
||||
#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y)
|
||||
#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y)
|
||||
#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \
|
||||
: name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
|
||||
#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \
|
||||
: name##_SPLAY_MIN_MAX(x, SPLAY_INF))
|
||||
|
||||
#define SPLAY_FOREACH(x, name, head) \
|
||||
for ((x) = SPLAY_MIN(name, head); \
|
||||
(x) != NULL; \
|
||||
(x) = SPLAY_NEXT(name, head, x))
|
||||
|
||||
/* Macros that define a red-black tree */
|
||||
#define RB_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *rbh_root; /* root of the tree */ \
|
||||
}
|
||||
|
||||
#define RB_INITIALIZER(root) \
|
||||
{ NULL }
|
||||
|
||||
#define RB_INIT(root) do { \
|
||||
(root)->rbh_root = NULL; \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#define RB_BLACK 0
|
||||
#define RB_RED 1
|
||||
#define RB_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *rbe_left; /* left element */ \
|
||||
struct type *rbe_right; /* right element */ \
|
||||
struct type *rbe_parent; /* parent element */ \
|
||||
int rbe_color; /* node color */ \
|
||||
}
|
||||
|
||||
#define RB_LEFT(elm, field) (elm)->field.rbe_left
|
||||
#define RB_RIGHT(elm, field) (elm)->field.rbe_right
|
||||
#define RB_PARENT(elm, field) (elm)->field.rbe_parent
|
||||
#define RB_COLOR(elm, field) (elm)->field.rbe_color
|
||||
#define RB_ROOT(head) (head)->rbh_root
|
||||
#define RB_EMPTY(head) (RB_ROOT(head) == NULL)
|
||||
|
||||
#define RB_SET(elm, parent, field) do { \
|
||||
RB_PARENT(elm, field) = parent; \
|
||||
RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \
|
||||
RB_COLOR(elm, field) = RB_RED; \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#define RB_SET_BLACKRED(black, red, field) do { \
|
||||
RB_COLOR(black, field) = RB_BLACK; \
|
||||
RB_COLOR(red, field) = RB_RED; \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#ifndef RB_AUGMENT
|
||||
#define RB_AUGMENT(x) do {} while (0)
|
||||
#endif
|
||||
|
||||
#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \
|
||||
(tmp) = RB_RIGHT(elm, field); \
|
||||
if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \
|
||||
RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \
|
||||
} \
|
||||
RB_AUGMENT(elm); \
|
||||
if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \
|
||||
if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
|
||||
RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
|
||||
else \
|
||||
RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
|
||||
} else \
|
||||
(head)->rbh_root = (tmp); \
|
||||
RB_LEFT(tmp, field) = (elm); \
|
||||
RB_PARENT(elm, field) = (tmp); \
|
||||
RB_AUGMENT(tmp); \
|
||||
if ((RB_PARENT(tmp, field))) \
|
||||
RB_AUGMENT(RB_PARENT(tmp, field)); \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \
|
||||
(tmp) = RB_LEFT(elm, field); \
|
||||
if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \
|
||||
RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \
|
||||
} \
|
||||
RB_AUGMENT(elm); \
|
||||
if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \
|
||||
if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
|
||||
RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
|
||||
else \
|
||||
RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
|
||||
} else \
|
||||
(head)->rbh_root = (tmp); \
|
||||
RB_RIGHT(tmp, field) = (elm); \
|
||||
RB_PARENT(elm, field) = (tmp); \
|
||||
RB_AUGMENT(tmp); \
|
||||
if ((RB_PARENT(tmp, field))) \
|
||||
RB_AUGMENT(RB_PARENT(tmp, field)); \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
/* Generates prototypes and inline functions */
|
||||
#define RB_PROTOTYPE(name, type, field, cmp) \
|
||||
RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
|
||||
#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \
|
||||
RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static)
|
||||
#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \
|
||||
RB_PROTOTYPE_INSERT_COLOR(name, type, attr); \
|
||||
RB_PROTOTYPE_REMOVE_COLOR(name, type, attr); \
|
||||
RB_PROTOTYPE_INSERT(name, type, attr); \
|
||||
RB_PROTOTYPE_REMOVE(name, type, attr); \
|
||||
RB_PROTOTYPE_FIND(name, type, attr); \
|
||||
RB_PROTOTYPE_NFIND(name, type, attr); \
|
||||
RB_PROTOTYPE_NEXT(name, type, attr); \
|
||||
RB_PROTOTYPE_PREV(name, type, attr); \
|
||||
RB_PROTOTYPE_MINMAX(name, type, attr);
|
||||
#define RB_PROTOTYPE_INSERT_COLOR(name, type, attr) \
|
||||
attr void name##_RB_INSERT_COLOR(struct name *, struct type *)
|
||||
#define RB_PROTOTYPE_REMOVE_COLOR(name, type, attr) \
|
||||
attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *)
|
||||
#define RB_PROTOTYPE_REMOVE(name, type, attr) \
|
||||
attr struct type *name##_RB_REMOVE(struct name *, struct type *)
|
||||
#define RB_PROTOTYPE_INSERT(name, type, attr) \
|
||||
attr struct type *name##_RB_INSERT(struct name *, struct type *)
|
||||
#define RB_PROTOTYPE_FIND(name, type, attr) \
|
||||
attr struct type *name##_RB_FIND(struct name *, struct type *)
|
||||
#define RB_PROTOTYPE_NFIND(name, type, attr) \
|
||||
attr struct type *name##_RB_NFIND(struct name *, struct type *)
|
||||
#define RB_PROTOTYPE_NEXT(name, type, attr) \
|
||||
attr struct type *name##_RB_NEXT(struct type *)
|
||||
#define RB_PROTOTYPE_PREV(name, type, attr) \
|
||||
attr struct type *name##_RB_PREV(struct type *)
|
||||
#define RB_PROTOTYPE_MINMAX(name, type, attr) \
|
||||
attr struct type *name##_RB_MINMAX(struct name *, int)
|
||||
|
||||
/* Main rb operation.
|
||||
* Moves node close to the key of elm to top
|
||||
*/
|
||||
#define RB_GENERATE(name, type, field, cmp) \
|
||||
RB_GENERATE_INTERNAL(name, type, field, cmp,)
|
||||
#define RB_GENERATE_STATIC(name, type, field, cmp) \
|
||||
RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static)
|
||||
#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \
|
||||
RB_GENERATE_INSERT_COLOR(name, type, field, attr) \
|
||||
RB_GENERATE_REMOVE_COLOR(name, type, field, attr) \
|
||||
RB_GENERATE_INSERT(name, type, field, cmp, attr) \
|
||||
RB_GENERATE_REMOVE(name, type, field, attr) \
|
||||
RB_GENERATE_FIND(name, type, field, cmp, attr) \
|
||||
RB_GENERATE_NFIND(name, type, field, cmp, attr) \
|
||||
RB_GENERATE_NEXT(name, type, field, attr) \
|
||||
RB_GENERATE_PREV(name, type, field, attr) \
|
||||
RB_GENERATE_MINMAX(name, type, field, attr)
|
||||
|
||||
#define RB_GENERATE_INSERT_COLOR(name, type, field, attr) \
|
||||
attr void \
|
||||
name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *parent, *gparent, *tmp; \
|
||||
while ((parent = RB_PARENT(elm, field)) != NULL && \
|
||||
RB_COLOR(parent, field) == RB_RED) { \
|
||||
gparent = RB_PARENT(parent, field); \
|
||||
if (parent == RB_LEFT(gparent, field)) { \
|
||||
tmp = RB_RIGHT(gparent, field); \
|
||||
if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
|
||||
RB_COLOR(tmp, field) = RB_BLACK; \
|
||||
RB_SET_BLACKRED(parent, gparent, field);\
|
||||
elm = gparent; \
|
||||
continue; \
|
||||
} \
|
||||
if (RB_RIGHT(parent, field) == elm) { \
|
||||
RB_ROTATE_LEFT(head, parent, tmp, field);\
|
||||
tmp = parent; \
|
||||
parent = elm; \
|
||||
elm = tmp; \
|
||||
} \
|
||||
RB_SET_BLACKRED(parent, gparent, field); \
|
||||
RB_ROTATE_RIGHT(head, gparent, tmp, field); \
|
||||
} else { \
|
||||
tmp = RB_LEFT(gparent, field); \
|
||||
if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
|
||||
RB_COLOR(tmp, field) = RB_BLACK; \
|
||||
RB_SET_BLACKRED(parent, gparent, field);\
|
||||
elm = gparent; \
|
||||
continue; \
|
||||
} \
|
||||
if (RB_LEFT(parent, field) == elm) { \
|
||||
RB_ROTATE_RIGHT(head, parent, tmp, field);\
|
||||
tmp = parent; \
|
||||
parent = elm; \
|
||||
elm = tmp; \
|
||||
} \
|
||||
RB_SET_BLACKRED(parent, gparent, field); \
|
||||
RB_ROTATE_LEFT(head, gparent, tmp, field); \
|
||||
} \
|
||||
} \
|
||||
RB_COLOR(head->rbh_root, field) = RB_BLACK; \
|
||||
}
|
||||
|
||||
#define RB_GENERATE_REMOVE_COLOR(name, type, field, attr) \
|
||||
attr void \
|
||||
name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
|
||||
{ \
|
||||
struct type *tmp; \
|
||||
while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \
|
||||
elm != RB_ROOT(head)) { \
|
||||
if (RB_LEFT(parent, field) == elm) { \
|
||||
tmp = RB_RIGHT(parent, field); \
|
||||
if (RB_COLOR(tmp, field) == RB_RED) { \
|
||||
RB_SET_BLACKRED(tmp, parent, field); \
|
||||
RB_ROTATE_LEFT(head, parent, tmp, field);\
|
||||
tmp = RB_RIGHT(parent, field); \
|
||||
} \
|
||||
if ((RB_LEFT(tmp, field) == NULL || \
|
||||
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
|
||||
(RB_RIGHT(tmp, field) == NULL || \
|
||||
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
|
||||
RB_COLOR(tmp, field) = RB_RED; \
|
||||
elm = parent; \
|
||||
parent = RB_PARENT(elm, field); \
|
||||
} else { \
|
||||
if (RB_RIGHT(tmp, field) == NULL || \
|
||||
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\
|
||||
struct type *oleft; \
|
||||
if ((oleft = RB_LEFT(tmp, field)) \
|
||||
!= NULL) \
|
||||
RB_COLOR(oleft, field) = RB_BLACK;\
|
||||
RB_COLOR(tmp, field) = RB_RED; \
|
||||
RB_ROTATE_RIGHT(head, tmp, oleft, field);\
|
||||
tmp = RB_RIGHT(parent, field); \
|
||||
} \
|
||||
RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
|
||||
RB_COLOR(parent, field) = RB_BLACK; \
|
||||
if (RB_RIGHT(tmp, field)) \
|
||||
RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\
|
||||
RB_ROTATE_LEFT(head, parent, tmp, field);\
|
||||
elm = RB_ROOT(head); \
|
||||
break; \
|
||||
} \
|
||||
} else { \
|
||||
tmp = RB_LEFT(parent, field); \
|
||||
if (RB_COLOR(tmp, field) == RB_RED) { \
|
||||
RB_SET_BLACKRED(tmp, parent, field); \
|
||||
RB_ROTATE_RIGHT(head, parent, tmp, field);\
|
||||
tmp = RB_LEFT(parent, field); \
|
||||
} \
|
||||
if ((RB_LEFT(tmp, field) == NULL || \
|
||||
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
|
||||
(RB_RIGHT(tmp, field) == NULL || \
|
||||
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
|
||||
RB_COLOR(tmp, field) = RB_RED; \
|
||||
elm = parent; \
|
||||
parent = RB_PARENT(elm, field); \
|
||||
} else { \
|
||||
if (RB_LEFT(tmp, field) == NULL || \
|
||||
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\
|
||||
struct type *oright; \
|
||||
if ((oright = RB_RIGHT(tmp, field)) \
|
||||
!= NULL) \
|
||||
RB_COLOR(oright, field) = RB_BLACK;\
|
||||
RB_COLOR(tmp, field) = RB_RED; \
|
||||
RB_ROTATE_LEFT(head, tmp, oright, field);\
|
||||
tmp = RB_LEFT(parent, field); \
|
||||
} \
|
||||
RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
|
||||
RB_COLOR(parent, field) = RB_BLACK; \
|
||||
if (RB_LEFT(tmp, field)) \
|
||||
RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\
|
||||
RB_ROTATE_RIGHT(head, parent, tmp, field);\
|
||||
elm = RB_ROOT(head); \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
if (elm) \
|
||||
RB_COLOR(elm, field) = RB_BLACK; \
|
||||
}
|
||||
|
||||
#define RB_GENERATE_REMOVE(name, type, field, attr) \
|
||||
attr struct type * \
|
||||
name##_RB_REMOVE(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *child, *parent, *old = elm; \
|
||||
int color; \
|
||||
if (RB_LEFT(elm, field) == NULL) \
|
||||
child = RB_RIGHT(elm, field); \
|
||||
else if (RB_RIGHT(elm, field) == NULL) \
|
||||
child = RB_LEFT(elm, field); \
|
||||
else { \
|
||||
struct type *left; \
|
||||
elm = RB_RIGHT(elm, field); \
|
||||
while ((left = RB_LEFT(elm, field)) != NULL) \
|
||||
elm = left; \
|
||||
child = RB_RIGHT(elm, field); \
|
||||
parent = RB_PARENT(elm, field); \
|
||||
color = RB_COLOR(elm, field); \
|
||||
if (child) \
|
||||
RB_PARENT(child, field) = parent; \
|
||||
if (parent) { \
|
||||
if (RB_LEFT(parent, field) == elm) \
|
||||
RB_LEFT(parent, field) = child; \
|
||||
else \
|
||||
RB_RIGHT(parent, field) = child; \
|
||||
RB_AUGMENT(parent); \
|
||||
} else \
|
||||
RB_ROOT(head) = child; \
|
||||
if (RB_PARENT(elm, field) == old) \
|
||||
parent = elm; \
|
||||
(elm)->field = (old)->field; \
|
||||
if (RB_PARENT(old, field)) { \
|
||||
if (RB_LEFT(RB_PARENT(old, field), field) == old)\
|
||||
RB_LEFT(RB_PARENT(old, field), field) = elm;\
|
||||
else \
|
||||
RB_RIGHT(RB_PARENT(old, field), field) = elm;\
|
||||
RB_AUGMENT(RB_PARENT(old, field)); \
|
||||
} else \
|
||||
RB_ROOT(head) = elm; \
|
||||
RB_PARENT(RB_LEFT(old, field), field) = elm; \
|
||||
if (RB_RIGHT(old, field)) \
|
||||
RB_PARENT(RB_RIGHT(old, field), field) = elm; \
|
||||
if (parent) { \
|
||||
left = parent; \
|
||||
do { \
|
||||
RB_AUGMENT(left); \
|
||||
} while ((left = RB_PARENT(left, field)) != NULL); \
|
||||
} \
|
||||
goto color; \
|
||||
} \
|
||||
parent = RB_PARENT(elm, field); \
|
||||
color = RB_COLOR(elm, field); \
|
||||
if (child) \
|
||||
RB_PARENT(child, field) = parent; \
|
||||
if (parent) { \
|
||||
if (RB_LEFT(parent, field) == elm) \
|
||||
RB_LEFT(parent, field) = child; \
|
||||
else \
|
||||
RB_RIGHT(parent, field) = child; \
|
||||
RB_AUGMENT(parent); \
|
||||
} else \
|
||||
RB_ROOT(head) = child; \
|
||||
color: \
|
||||
if (color == RB_BLACK) \
|
||||
name##_RB_REMOVE_COLOR(head, parent, child); \
|
||||
return (old); \
|
||||
} \
|
||||
|
||||
#define RB_GENERATE_INSERT(name, type, field, cmp, attr) \
|
||||
/* Inserts a node into the RB tree */ \
|
||||
attr struct type * \
|
||||
name##_RB_INSERT(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *tmp; \
|
||||
struct type *parent = NULL; \
|
||||
int comp = 0; \
|
||||
tmp = RB_ROOT(head); \
|
||||
while (tmp) { \
|
||||
parent = tmp; \
|
||||
comp = (cmp)(elm, parent); \
|
||||
if (comp < 0) \
|
||||
tmp = RB_LEFT(tmp, field); \
|
||||
else if (comp > 0) \
|
||||
tmp = RB_RIGHT(tmp, field); \
|
||||
else \
|
||||
return (tmp); \
|
||||
} \
|
||||
RB_SET(elm, parent, field); \
|
||||
if (parent != NULL) { \
|
||||
if (comp < 0) \
|
||||
RB_LEFT(parent, field) = elm; \
|
||||
else \
|
||||
RB_RIGHT(parent, field) = elm; \
|
||||
RB_AUGMENT(parent); \
|
||||
} else \
|
||||
RB_ROOT(head) = elm; \
|
||||
name##_RB_INSERT_COLOR(head, elm); \
|
||||
return (NULL); \
|
||||
}
|
||||
|
||||
#define RB_GENERATE_FIND(name, type, field, cmp, attr) \
|
||||
/* Finds the node with the same key as elm */ \
|
||||
attr struct type * \
|
||||
name##_RB_FIND(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *tmp = RB_ROOT(head); \
|
||||
int comp; \
|
||||
while (tmp) { \
|
||||
comp = cmp(elm, tmp); \
|
||||
if (comp < 0) \
|
||||
tmp = RB_LEFT(tmp, field); \
|
||||
else if (comp > 0) \
|
||||
tmp = RB_RIGHT(tmp, field); \
|
||||
else \
|
||||
return (tmp); \
|
||||
} \
|
||||
return (NULL); \
|
||||
}
|
||||
|
||||
#define RB_GENERATE_NFIND(name, type, field, cmp, attr) \
|
||||
/* Finds the first node greater than or equal to the search key */ \
|
||||
attr struct type * \
|
||||
name##_RB_NFIND(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *tmp = RB_ROOT(head); \
|
||||
struct type *res = NULL; \
|
||||
int comp; \
|
||||
while (tmp) { \
|
||||
comp = cmp(elm, tmp); \
|
||||
if (comp < 0) { \
|
||||
res = tmp; \
|
||||
tmp = RB_LEFT(tmp, field); \
|
||||
} \
|
||||
else if (comp > 0) \
|
||||
tmp = RB_RIGHT(tmp, field); \
|
||||
else \
|
||||
return (tmp); \
|
||||
} \
|
||||
return (res); \
|
||||
}
|
||||
|
||||
#define RB_GENERATE_NEXT(name, type, field, attr) \
|
||||
/* ARGSUSED */ \
|
||||
attr struct type * \
|
||||
name##_RB_NEXT(struct type *elm) \
|
||||
{ \
|
||||
if (RB_RIGHT(elm, field)) { \
|
||||
elm = RB_RIGHT(elm, field); \
|
||||
while (RB_LEFT(elm, field)) \
|
||||
elm = RB_LEFT(elm, field); \
|
||||
} else { \
|
||||
if (RB_PARENT(elm, field) && \
|
||||
(elm == RB_LEFT(RB_PARENT(elm, field), field))) \
|
||||
elm = RB_PARENT(elm, field); \
|
||||
else { \
|
||||
while (RB_PARENT(elm, field) && \
|
||||
(elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
|
||||
elm = RB_PARENT(elm, field); \
|
||||
elm = RB_PARENT(elm, field); \
|
||||
} \
|
||||
} \
|
||||
return (elm); \
|
||||
}
|
||||
|
||||
#define RB_GENERATE_PREV(name, type, field, attr) \
|
||||
/* ARGSUSED */ \
|
||||
attr struct type * \
|
||||
name##_RB_PREV(struct type *elm) \
|
||||
{ \
|
||||
if (RB_LEFT(elm, field)) { \
|
||||
elm = RB_LEFT(elm, field); \
|
||||
while (RB_RIGHT(elm, field)) \
|
||||
elm = RB_RIGHT(elm, field); \
|
||||
} else { \
|
||||
if (RB_PARENT(elm, field) && \
|
||||
(elm == RB_RIGHT(RB_PARENT(elm, field), field))) \
|
||||
elm = RB_PARENT(elm, field); \
|
||||
else { \
|
||||
while (RB_PARENT(elm, field) && \
|
||||
(elm == RB_LEFT(RB_PARENT(elm, field), field)))\
|
||||
elm = RB_PARENT(elm, field); \
|
||||
elm = RB_PARENT(elm, field); \
|
||||
} \
|
||||
} \
|
||||
return (elm); \
|
||||
}
|
||||
|
||||
#define RB_GENERATE_MINMAX(name, type, field, attr) \
|
||||
attr struct type * \
|
||||
name##_RB_MINMAX(struct name *head, int val) \
|
||||
{ \
|
||||
struct type *tmp = RB_ROOT(head); \
|
||||
struct type *parent = NULL; \
|
||||
while (tmp) { \
|
||||
parent = tmp; \
|
||||
if (val < 0) \
|
||||
tmp = RB_LEFT(tmp, field); \
|
||||
else \
|
||||
tmp = RB_RIGHT(tmp, field); \
|
||||
} \
|
||||
return (parent); \
|
||||
}
|
||||
|
||||
#define RB_NEGINF -1
|
||||
#define RB_INF 1
|
||||
|
||||
#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
|
||||
#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
|
||||
#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
|
||||
#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y)
|
||||
#define RB_NEXT(name, x, y) name##_RB_NEXT(y)
|
||||
#define RB_PREV(name, x, y) name##_RB_PREV(y)
|
||||
#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF)
|
||||
#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF)
|
||||
|
||||
#define RB_FOREACH(x, name, head) \
|
||||
for ((x) = RB_MIN(name, head); \
|
||||
(x) != NULL; \
|
||||
(x) = name##_RB_NEXT(x))
|
||||
|
||||
#define RB_FOREACH_FROM(x, name, y) \
|
||||
for ((x) = (y); \
|
||||
((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \
|
||||
(x) = (y))
|
||||
|
||||
#define RB_FOREACH_SAFE(x, name, head, y) \
|
||||
for ((x) = RB_MIN(name, head); \
|
||||
((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \
|
||||
(x) = (y))
|
||||
|
||||
#define RB_FOREACH_REVERSE(x, name, head) \
|
||||
for ((x) = RB_MAX(name, head); \
|
||||
(x) != NULL; \
|
||||
(x) = name##_RB_PREV(x))
|
||||
|
||||
#define RB_FOREACH_REVERSE_FROM(x, name, y) \
|
||||
for ((x) = (y); \
|
||||
((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \
|
||||
(x) = (y))
|
||||
|
||||
#define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \
|
||||
for ((x) = RB_MAX(name, head); \
|
||||
((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \
|
||||
(x) = (y))
|
||||
|
||||
#endif /* _SYS_TREE_H_ */
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/* Pulls in util, svc. */
|
||||
#include "atmosphere/common.hpp"
|
||||
|
||||
/* Critical modules with no dependencies. */
|
||||
#include "stratosphere/ams.hpp"
|
||||
#include "stratosphere/os.hpp"
|
||||
#include "stratosphere/dd.hpp"
|
||||
|
||||
/* Lots of things depend on NCM, for Program IDs. */
|
||||
#include "stratosphere/ncm.hpp"
|
||||
|
||||
/* At this point, just include the rest alphabetically. */
|
||||
/* TODO: Figure out optimal order. */
|
||||
#include "stratosphere/boot2.hpp"
|
||||
#include "stratosphere/cfg.hpp"
|
||||
#include "stratosphere/dmnt.hpp"
|
||||
#include "stratosphere/fatal.hpp"
|
||||
#include "stratosphere/hid.hpp"
|
||||
#include "stratosphere/hos.hpp"
|
||||
#include "stratosphere/kvdb.hpp"
|
||||
#include "stratosphere/ldr.hpp"
|
||||
#include "stratosphere/map.hpp"
|
||||
#include "stratosphere/patcher.hpp"
|
||||
#include "stratosphere/pm.hpp"
|
||||
#include "stratosphere/reg.hpp"
|
||||
#include "stratosphere/rnd.hpp"
|
||||
#include "stratosphere/ro.hpp"
|
||||
#include "stratosphere/settings.hpp"
|
||||
#include "stratosphere/sf.hpp"
|
||||
#include "stratosphere/sm.hpp"
|
||||
#include "stratosphere/spl.hpp"
|
||||
#include "stratosphere/updater.hpp"
|
||||
|
||||
/* Include FS last. */
|
||||
#include "stratosphere/fs.hpp"
|
||||
#include "stratosphere/fssrv.hpp"
|
||||
#include "stratosphere/fssystem.hpp"
|
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ams/ams_types.hpp"
|
||||
#include "ams/ams_exosphere_api.hpp"
|
||||
#include "ams/ams_emummc_api.hpp"
|
||||
#include "ams/ams_environment.hpp"
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "ams_types.hpp"
|
||||
|
||||
namespace ams::emummc {
|
||||
|
||||
/* Get whether emummc is active. */
|
||||
bool IsActive();
|
||||
|
||||
/* Get Nintendo redirection path. */
|
||||
const char *GetNintendoDirPath();
|
||||
|
||||
/* Get Emummc folderpath, NULL if not file-based. */
|
||||
const char *GetFilePath();
|
||||
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "ams_types.hpp"
|
||||
|
||||
namespace ams {
|
||||
|
||||
/* Will be called by libstratosphere on crash. */
|
||||
void CrashHandler(ThreadExceptionDump *ctx);
|
||||
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "ams_types.hpp"
|
||||
|
||||
namespace ams::exosphere {
|
||||
|
||||
ApiInfo GetApiInfo();
|
||||
|
||||
void ForceRebootToRcm();
|
||||
void ForceRebootToIramPayload();
|
||||
void ForceShutdown();
|
||||
|
||||
bool IsRcmBugPatched();
|
||||
|
||||
void CopyToIram(uintptr_t iram_dst, const void *dram_src, size_t size);
|
||||
void CopyFromIram(void *dram_dst, uintptr_t iram_src, size_t size);
|
||||
|
||||
}
|
||||
|
||||
namespace ams {
|
||||
|
||||
/* Version checking utility. */
|
||||
#ifdef ATMOSPHERE_RELEASE_VERSION_MAJOR
|
||||
|
||||
#define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO
|
||||
|
||||
inline void CheckApiVersion() {
|
||||
const u32 runtime_version = exosphere::GetApiInfo().GetVersion();
|
||||
const u32 build_version = exosphere::GetVersion(ATMOSPHERE_RELEASE_VERSION);
|
||||
|
||||
if (runtime_version < build_version) {
|
||||
R_ASSERT(exosphere::ResultVersionMismatch());
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <atmosphere/common.hpp>
|
||||
#include "../sf/sf_buffer_tags.hpp"
|
||||
#include "../hos.hpp"
|
||||
|
||||
namespace ams::exosphere {
|
||||
|
||||
enum TargetFirmware : u32 {
|
||||
TargetFirmware_100 = 1,
|
||||
TargetFirmware_200 = 2,
|
||||
TargetFirmware_300 = 3,
|
||||
TargetFirmware_400 = 4,
|
||||
TargetFirmware_500 = 5,
|
||||
TargetFirmware_600 = 6,
|
||||
TargetFirmware_620 = 7,
|
||||
TargetFirmware_700 = 8,
|
||||
TargetFirmware_800 = 9,
|
||||
TargetFirmware_810 = 10,
|
||||
TargetFirmware_900 = 11,
|
||||
TargetFirmware_910 = 12,
|
||||
};
|
||||
|
||||
#ifdef ATMOSPHERE_H
|
||||
/* #ifdef __has_include(<atmosphere.h>) */
|
||||
|
||||
#define AMS_VALIDATE_TARGET_FIRMWARE_ENUM(n) static_assert(TargetFirmware_##n == ATMOSPHERE_TARGET_FIRMWARE_##n)
|
||||
|
||||
AMS_VALIDATE_TARGET_FIRMWARE_ENUM(100);
|
||||
AMS_VALIDATE_TARGET_FIRMWARE_ENUM(200);
|
||||
AMS_VALIDATE_TARGET_FIRMWARE_ENUM(300);
|
||||
AMS_VALIDATE_TARGET_FIRMWARE_ENUM(400);
|
||||
AMS_VALIDATE_TARGET_FIRMWARE_ENUM(500);
|
||||
AMS_VALIDATE_TARGET_FIRMWARE_ENUM(620);
|
||||
AMS_VALIDATE_TARGET_FIRMWARE_ENUM(700);
|
||||
AMS_VALIDATE_TARGET_FIRMWARE_ENUM(800);
|
||||
AMS_VALIDATE_TARGET_FIRMWARE_ENUM(810);
|
||||
AMS_VALIDATE_TARGET_FIRMWARE_ENUM(900);
|
||||
AMS_VALIDATE_TARGET_FIRMWARE_ENUM(910);
|
||||
|
||||
#undef AMS_VALIDATE_TARGET_FIRMWARE_ENUM
|
||||
|
||||
#endif
|
||||
|
||||
constexpr inline u32 GetVersion(u32 major, u32 minor, u32 micro) {
|
||||
return (major << 16) | (minor << 8) | (micro);
|
||||
}
|
||||
|
||||
struct ApiInfo {
|
||||
u32 major_version;
|
||||
u32 minor_version;
|
||||
u32 micro_version;
|
||||
TargetFirmware target_firmware;
|
||||
u32 master_key_revision;
|
||||
|
||||
constexpr u32 GetVersion() const {
|
||||
return ::ams::exosphere::GetVersion(this->major_version, this->minor_version, this->micro_version);
|
||||
}
|
||||
|
||||
constexpr TargetFirmware GetTargetFirmware() const {
|
||||
return this->target_firmware;
|
||||
}
|
||||
|
||||
constexpr u32 GetMasterKeyRevision() const {
|
||||
return this->master_key_revision;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace ams {
|
||||
|
||||
struct FatalErrorContext : sf::LargeData, sf::PrefersMapAliasTransferMode {
|
||||
static constexpr size_t MaxStackTrace = 0x20;
|
||||
static constexpr size_t MaxStackDumpSize = 0x100;
|
||||
static constexpr size_t NumGprs = 29;
|
||||
static constexpr uintptr_t StdAbortMagicAddress = 0x8;
|
||||
static constexpr u64 StdAbortMagicValue = 0xA55AF00DDEADCAFEul;
|
||||
static constexpr u32 StdAbortErrorDesc = 0xFFE;
|
||||
static constexpr u32 DataAbortErrorDesc = 0x101;
|
||||
static constexpr u32 Magic = 0x31454641;
|
||||
|
||||
u32 magic;
|
||||
u32 error_desc;
|
||||
u64 program_id;
|
||||
union {
|
||||
u64 gprs[32];
|
||||
struct {
|
||||
u64 _gprs[29];
|
||||
u64 fp;
|
||||
u64 lr;
|
||||
u64 sp;
|
||||
};
|
||||
};
|
||||
u64 pc;
|
||||
u64 module_base;
|
||||
u32 pstate;
|
||||
u32 afsr0;
|
||||
u32 afsr1;
|
||||
u32 esr;
|
||||
u64 far;
|
||||
u64 report_identifier; /* Normally just system tick. */
|
||||
u64 stack_trace_size;
|
||||
u64 stack_dump_size;
|
||||
u64 stack_trace[MaxStackTrace];
|
||||
u8 stack_dump[MaxStackDumpSize];
|
||||
};
|
||||
|
||||
static_assert(sizeof(FatalErrorContext) == 0x350, "sizeof(FatalErrorContext)");
|
||||
static_assert(std::is_pod<FatalErrorContext>::value, "FatalErrorContext");
|
||||
|
||||
#ifdef ATMOSPHERE_GIT_BRANCH
|
||||
NX_CONSTEXPR const char *GetGitBranch() {
|
||||
return ATMOSPHERE_GIT_BRANCH;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ATMOSPHERE_GIT_REV
|
||||
NX_CONSTEXPR const char *GetGitRevision() {
|
||||
return ATMOSPHERE_GIT_REV;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "boot2/boot2_api.hpp"
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <atmosphere/common.hpp>
|
||||
|
||||
namespace ams::boot2 {
|
||||
|
||||
/* Boot2 API. */
|
||||
|
||||
/* Normally invoked by PM. */
|
||||
void LaunchPreSdCardBootProgramsAndBoot2();
|
||||
|
||||
/* Normally invoked by boot2. */
|
||||
void LaunchPostSdCardBootPrograms();
|
||||
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cfg/cfg_api.hpp"
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "cfg_types.hpp"
|
||||
#include "cfg_locale_types.hpp"
|
||||
#include "../sm/sm_types.hpp"
|
||||
|
||||
namespace ams::cfg {
|
||||
|
||||
/* Privileged Process configuration. */
|
||||
bool IsInitialProcess();
|
||||
void GetInitialProcessRange(os::ProcessId *out_min, os::ProcessId *out_max);
|
||||
|
||||
/* SD card configuration. */
|
||||
bool IsSdCardRequiredServicesReady();
|
||||
void WaitSdCardRequiredServicesReady();
|
||||
bool IsSdCardInitialized();
|
||||
void WaitSdCardInitialized();
|
||||
|
||||
/* Override key utilities. */
|
||||
OverrideStatus CaptureOverrideStatus(ncm::ProgramId program_id);
|
||||
|
||||
/* Locale utilities. */
|
||||
OverrideLocale GetOverrideLocale(ncm::ProgramId program_id);
|
||||
|
||||
/* Flag utilities. */
|
||||
bool HasFlag(const sm::MitmProcessInfo &process_info, const char *flag);
|
||||
bool HasContentSpecificFlag(ncm::ProgramId program_id, const char *flag);
|
||||
bool HasGlobalFlag(const char *flag);
|
||||
|
||||
/* HBL Configuration utilities. */
|
||||
bool IsHblProgramId(ncm::ProgramId program_id);
|
||||
bool HasHblFlag(const char *flag);
|
||||
const char *GetHblPath();
|
||||
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "cfg_types.hpp"
|
||||
#include "../settings/settings_types.hpp"
|
||||
|
||||
namespace ams::cfg {
|
||||
|
||||
struct OverrideLocale {
|
||||
settings::LanguageCode language_code;
|
||||
settings::RegionCode region_code;
|
||||
};
|
||||
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../os/os_common_types.hpp"
|
||||
#include "../ncm/ncm_types.hpp"
|
||||
|
||||
namespace ams::cfg {
|
||||
|
||||
namespace impl {
|
||||
|
||||
enum OverrideStatusFlag : u64 {
|
||||
OverrideStatusFlag_Hbl = BIT(0),
|
||||
OverrideStatusFlag_ProgramSpecific = BIT(1),
|
||||
OverrideStatusFlag_CheatEnabled = BIT(2),
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
struct OverrideStatus {
|
||||
u64 keys_held;
|
||||
u64 flags;
|
||||
|
||||
constexpr inline u64 GetKeysHeld() const { return this->keys_held; }
|
||||
|
||||
#define DEFINE_FLAG_ACCESSORS(flag) \
|
||||
constexpr inline bool Is##flag() const { return this->flags & impl::OverrideStatusFlag_##flag; } \
|
||||
constexpr inline void Set##flag() { this->flags |= impl::OverrideStatusFlag_##flag; } \
|
||||
constexpr inline void Clear##flag() { this->flags &= ~u64(impl::OverrideStatusFlag_##flag); }
|
||||
|
||||
DEFINE_FLAG_ACCESSORS(Hbl)
|
||||
DEFINE_FLAG_ACCESSORS(ProgramSpecific)
|
||||
DEFINE_FLAG_ACCESSORS(CheatEnabled)
|
||||
|
||||
#undef DEFINE_FLAG_ACCESSORS
|
||||
};
|
||||
|
||||
static_assert(sizeof(OverrideStatus) == 0x10, "sizeof(OverrideStatus)");
|
||||
static_assert(std::is_pod<OverrideStatus>::value, "std::is_pod<OverrideStatus>::value");
|
||||
|
||||
constexpr inline bool operator==(const OverrideStatus &lhs, const OverrideStatus &rhs) {
|
||||
return std::memcmp(&lhs, &rhs, sizeof(lhs)) == 0;
|
||||
}
|
||||
|
||||
constexpr inline bool operator!=(const OverrideStatus &lhs, const OverrideStatus &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "dd/dd_io_mappings.hpp"
|
||||
#include "dd/dd_process_handle.hpp"
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <atmosphere/common.hpp>
|
||||
|
||||
namespace ams::dd {
|
||||
|
||||
uintptr_t QueryIoMapping(uintptr_t phys_addr, size_t size);
|
||||
|
||||
u32 ReadRegister(uintptr_t phys_addr);
|
||||
void WriteRegister(uintptr_t phys_addr, u32 value);
|
||||
u32 ReadWriteRegister(uintptr_t phys_addr, u32 value, u32 mask);
|
||||
|
||||
/* Convenience Helper. */
|
||||
|
||||
inline uintptr_t GetIoMapping(uintptr_t phys_addr, size_t size) {
|
||||
const uintptr_t io_mapping = QueryIoMapping(phys_addr, size);
|
||||
AMS_ASSERT(io_mapping);
|
||||
return io_mapping;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <atmosphere/common.hpp>
|
||||
|
||||
namespace ams::dd {
|
||||
|
||||
::Handle GetCurrentProcessHandle();
|
||||
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "dmnt/dmnt_cheat_types.hpp"
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../os/os_common_types.hpp"
|
||||
#include "../ncm/ncm_types.hpp"
|
||||
#include "../sf/sf_buffer_tags.hpp"
|
||||
|
||||
namespace ams::dmnt::cheat {
|
||||
|
||||
struct CheatProcessMetadata {
|
||||
struct MemoryRegionExtents {
|
||||
u64 base;
|
||||
u64 size;
|
||||
};
|
||||
|
||||
os::ProcessId process_id;
|
||||
ncm::ProgramId program_id;
|
||||
MemoryRegionExtents main_nso_extents;
|
||||
MemoryRegionExtents heap_extents;
|
||||
MemoryRegionExtents alias_extents;
|
||||
MemoryRegionExtents aslr_extents;
|
||||
u8 main_nso_build_id[0x20];
|
||||
};
|
||||
|
||||
static_assert(std::is_pod<CheatProcessMetadata>::value && sizeof(CheatProcessMetadata) == 0x70, "CheatProcessMetadata definition!");
|
||||
|
||||
struct CheatDefinition : sf::LargeData, sf::PrefersMapAliasTransferMode {
|
||||
char readable_name[0x40];
|
||||
uint32_t num_opcodes;
|
||||
uint32_t opcodes[0x100];
|
||||
};
|
||||
|
||||
struct CheatEntry : sf::LargeData, sf::PrefersMapAliasTransferMode {
|
||||
bool enabled;
|
||||
uint32_t cheat_id;
|
||||
CheatDefinition definition;
|
||||
};
|
||||
|
||||
static_assert(std::is_pod<CheatDefinition>::value, "CheatDefinition");
|
||||
static_assert(std::is_pod<CheatEntry>::value, "CheatEntry");
|
||||
|
||||
struct FrozenAddressValue {
|
||||
u64 value;
|
||||
u8 width;
|
||||
};
|
||||
|
||||
struct FrozenAddressEntry {
|
||||
u64 address;
|
||||
FrozenAddressValue value;
|
||||
};
|
||||
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "fatal/fatal_types.hpp"
|
|
@ -1,348 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <atmosphere/common.hpp>
|
||||
#include "../ncm/ncm_types.hpp"
|
||||
#include "../sf/sf_buffer_tags.hpp"
|
||||
|
||||
namespace ams::fatal {
|
||||
|
||||
namespace aarch64 {
|
||||
|
||||
enum RegisterName {
|
||||
RegisterName_X0 = 0,
|
||||
RegisterName_X1 = 1,
|
||||
RegisterName_X2 = 2,
|
||||
RegisterName_X3 = 3,
|
||||
RegisterName_X4 = 4,
|
||||
RegisterName_X5 = 5,
|
||||
RegisterName_X6 = 6,
|
||||
RegisterName_X7 = 7,
|
||||
RegisterName_X8 = 8,
|
||||
RegisterName_X9 = 9,
|
||||
RegisterName_X10 = 10,
|
||||
RegisterName_X11 = 11,
|
||||
RegisterName_X12 = 12,
|
||||
RegisterName_X13 = 13,
|
||||
RegisterName_X14 = 14,
|
||||
RegisterName_X15 = 15,
|
||||
RegisterName_X16 = 16,
|
||||
RegisterName_X17 = 17,
|
||||
RegisterName_X18 = 18,
|
||||
RegisterName_X19 = 19,
|
||||
RegisterName_X20 = 20,
|
||||
RegisterName_X21 = 21,
|
||||
RegisterName_X22 = 22,
|
||||
RegisterName_X23 = 23,
|
||||
RegisterName_X24 = 24,
|
||||
RegisterName_X25 = 25,
|
||||
RegisterName_X26 = 26,
|
||||
RegisterName_X27 = 27,
|
||||
RegisterName_X28 = 28,
|
||||
RegisterName_FP = 29,
|
||||
RegisterName_LR = 30,
|
||||
|
||||
RegisterName_SP = 31,
|
||||
RegisterName_PC = 32,
|
||||
|
||||
RegisterName_GeneralPurposeCount,
|
||||
|
||||
RegisterName_PState = 33,
|
||||
RegisterName_Afsr0 = 34,
|
||||
RegisterName_Afsr1 = 35,
|
||||
RegisterName_Esr = 36,
|
||||
RegisterName_Far = 37,
|
||||
|
||||
RegisterName_Count,
|
||||
};
|
||||
|
||||
struct CpuContext {
|
||||
using RegisterType = u64;
|
||||
static constexpr size_t MaxStackTraceDepth = 0x20;
|
||||
|
||||
static constexpr const char *RegisterNameStrings[RegisterName_Count] = {
|
||||
u8"X0",
|
||||
u8"X1",
|
||||
u8"X2",
|
||||
u8"X3",
|
||||
u8"X4",
|
||||
u8"X5",
|
||||
u8"X6",
|
||||
u8"X7",
|
||||
u8"X8",
|
||||
u8"X9",
|
||||
u8"X10",
|
||||
u8"X11",
|
||||
u8"X12",
|
||||
u8"X13",
|
||||
u8"X14",
|
||||
u8"X15",
|
||||
u8"X16",
|
||||
u8"X17",
|
||||
u8"X18",
|
||||
u8"X19",
|
||||
u8"X20",
|
||||
u8"X21",
|
||||
u8"X22",
|
||||
u8"X23",
|
||||
u8"X24",
|
||||
u8"X25",
|
||||
u8"X26",
|
||||
u8"X27",
|
||||
u8"X28",
|
||||
u8"FP",
|
||||
u8"LR",
|
||||
u8"SP",
|
||||
u8"PC",
|
||||
u8"PState",
|
||||
u8"Afsr0",
|
||||
u8"Afsr1",
|
||||
u8"Esr",
|
||||
u8"Far",
|
||||
};
|
||||
|
||||
/* Registers, exception context. N left names for these fields in fatal .rodata. */
|
||||
union {
|
||||
struct {
|
||||
union {
|
||||
RegisterType x[RegisterName_GeneralPurposeCount];
|
||||
struct {
|
||||
RegisterType _x[RegisterName_FP];
|
||||
RegisterType fp;
|
||||
RegisterType lr;
|
||||
RegisterType sp;
|
||||
RegisterType pc;
|
||||
};
|
||||
};
|
||||
RegisterType pstate;
|
||||
RegisterType afsr0;
|
||||
RegisterType afsr1;
|
||||
RegisterType esr;
|
||||
RegisterType far;
|
||||
};
|
||||
RegisterType registers[RegisterName_Count];
|
||||
};
|
||||
|
||||
/* Misc. */
|
||||
RegisterType stack_trace[MaxStackTraceDepth];
|
||||
RegisterType base_address;
|
||||
RegisterType register_set_flags;
|
||||
u32 stack_trace_size;
|
||||
|
||||
void ClearState() {
|
||||
std::memset(this, 0, sizeof(*this));
|
||||
}
|
||||
|
||||
void SetProgramIdForAtmosphere(ncm::ProgramId program_id) {
|
||||
/* Right now, we mux program ID in through afsr when creport. */
|
||||
/* TODO: Better way to do this? */
|
||||
this->afsr0 = static_cast<RegisterType>(program_id);
|
||||
}
|
||||
|
||||
ncm::ProgramId GetProgramIdForAtmosphere() const {
|
||||
return ncm::ProgramId{this->afsr0};
|
||||
}
|
||||
|
||||
void SetRegisterValue(RegisterName name, RegisterType value) {
|
||||
this->registers[name] = value;
|
||||
this->register_set_flags |= (RegisterType(1) << name);
|
||||
}
|
||||
|
||||
bool HasRegisterValue(RegisterName name) const {
|
||||
return this->register_set_flags & (RegisterType(1) << name);
|
||||
}
|
||||
|
||||
void SetBaseAddress(RegisterType base_addr) {
|
||||
this->base_address = base_addr;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace aarch32 {
|
||||
|
||||
enum RegisterName {
|
||||
RegisterName_R0 = 0,
|
||||
RegisterName_R1 = 1,
|
||||
RegisterName_R2 = 2,
|
||||
RegisterName_R3 = 3,
|
||||
RegisterName_R4 = 4,
|
||||
RegisterName_R5 = 5,
|
||||
RegisterName_R6 = 6,
|
||||
RegisterName_R7 = 7,
|
||||
RegisterName_R8 = 8,
|
||||
RegisterName_R9 = 9,
|
||||
RegisterName_R10 = 10,
|
||||
RegisterName_FP = 11,
|
||||
RegisterName_IP = 12,
|
||||
RegisterName_LR = 13,
|
||||
RegisterName_SP = 14,
|
||||
RegisterName_PC = 15,
|
||||
|
||||
RegisterName_GeneralPurposeCount,
|
||||
|
||||
RegisterName_PState = 16,
|
||||
RegisterName_Afsr0 = 17,
|
||||
RegisterName_Afsr1 = 18,
|
||||
RegisterName_Esr = 29,
|
||||
RegisterName_Far = 20,
|
||||
|
||||
RegisterName_Count,
|
||||
};
|
||||
|
||||
struct CpuContext {
|
||||
using RegisterType = u32;
|
||||
static constexpr size_t MaxStackTraceDepth = 0x20;
|
||||
|
||||
static constexpr const char *RegisterNameStrings[RegisterName_Count] = {
|
||||
u8"R0",
|
||||
u8"R1",
|
||||
u8"R2",
|
||||
u8"R3",
|
||||
u8"R4",
|
||||
u8"R5",
|
||||
u8"R6",
|
||||
u8"R7",
|
||||
u8"R8",
|
||||
u8"R9",
|
||||
u8"R10",
|
||||
u8"FP",
|
||||
u8"IP",
|
||||
u8"LR",
|
||||
u8"SP",
|
||||
u8"PC",
|
||||
u8"PState",
|
||||
u8"Afsr0",
|
||||
u8"Afsr1",
|
||||
u8"Esr",
|
||||
u8"Far",
|
||||
};
|
||||
|
||||
/* Registers, exception context. N left names for these fields in fatal .rodata. */
|
||||
union {
|
||||
struct {
|
||||
union {
|
||||
RegisterType r[RegisterName_GeneralPurposeCount];
|
||||
struct {
|
||||
RegisterType _x[RegisterName_FP];
|
||||
RegisterType fp;
|
||||
RegisterType ip;
|
||||
RegisterType lr;
|
||||
RegisterType sp;
|
||||
RegisterType pc;
|
||||
};
|
||||
};
|
||||
RegisterType pstate;
|
||||
RegisterType afsr0;
|
||||
RegisterType afsr1;
|
||||
RegisterType esr;
|
||||
RegisterType far;
|
||||
};
|
||||
RegisterType registers[RegisterName_Count];
|
||||
};
|
||||
|
||||
/* Misc. Yes, stack_trace_size is really laid out differently than aarch64... */
|
||||
RegisterType stack_trace[MaxStackTraceDepth];
|
||||
u32 stack_trace_size;
|
||||
RegisterType base_address;
|
||||
RegisterType register_set_flags;
|
||||
|
||||
void ClearState() {
|
||||
std::memset(this, 0, sizeof(*this));
|
||||
}
|
||||
|
||||
void SetProgramIdForAtmosphere(ncm::ProgramId program_id) {
|
||||
/* Right now, we mux program ID in through afsr when creport. */
|
||||
/* TODO: Better way to do this? */
|
||||
this->afsr0 = static_cast<RegisterType>(static_cast<u64>(program_id) >> 0);
|
||||
this->afsr1 = static_cast<RegisterType>(static_cast<u64>(program_id) >> 32);
|
||||
}
|
||||
|
||||
ncm::ProgramId GetProgramIdForAtmosphere() const {
|
||||
return ncm::ProgramId{(static_cast<u64>(this->afsr1) << 32ul) | (static_cast<u64>(this->afsr0) << 0ul)};
|
||||
}
|
||||
|
||||
void SetRegisterValue(RegisterName name, RegisterType value) {
|
||||
this->registers[name] = value;
|
||||
this->register_set_flags |= (RegisterType(1) << name);
|
||||
}
|
||||
|
||||
bool HasRegisterValue(RegisterName name) const {
|
||||
return this->register_set_flags & (RegisterType(1) << name);
|
||||
}
|
||||
|
||||
void SetBaseAddress(RegisterType base_addr) {
|
||||
this->base_address = base_addr;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
struct CpuContext : sf::LargeData, sf::PrefersMapAliasTransferMode {
|
||||
enum Architecture {
|
||||
Architecture_Aarch64 = 0,
|
||||
Architecture_Aarch32 = 1,
|
||||
};
|
||||
|
||||
union {
|
||||
aarch64::CpuContext aarch64_ctx;
|
||||
aarch32::CpuContext aarch32_ctx;
|
||||
};
|
||||
|
||||
Architecture architecture;
|
||||
u32 type;
|
||||
|
||||
void ClearState() {
|
||||
std::memset(this, 0, sizeof(*this));
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(std::is_pod<aarch64::CpuContext>::value && sizeof(aarch64::CpuContext) == 0x248, "aarch64::CpuContext definition!");
|
||||
static_assert(std::is_pod<aarch32::CpuContext>::value && sizeof(aarch32::CpuContext) == 0xE0, "aarch32::CpuContext definition!");
|
||||
static_assert(std::is_pod<CpuContext>::value && sizeof(CpuContext) == 0x250, "CpuContext definition!");
|
||||
|
||||
namespace srv {
|
||||
|
||||
struct ThrowContext {
|
||||
Result result;
|
||||
ncm::ProgramId program_id;
|
||||
char proc_name[0xD];
|
||||
bool is_creport;
|
||||
CpuContext cpu_ctx;
|
||||
bool generate_error_report;
|
||||
Event erpt_event;
|
||||
Event battery_event;
|
||||
size_t stack_dump_size;
|
||||
u8 stack_dump[0x100];
|
||||
|
||||
void ClearState() {
|
||||
this->result = ResultSuccess();
|
||||
this->program_id = ncm::ProgramId::Invalid;
|
||||
std::memset(this->proc_name, 0, sizeof(this->proc_name));
|
||||
this->is_creport = false;
|
||||
std::memset(&this->cpu_ctx, 0, sizeof(this->cpu_ctx));
|
||||
this->generate_error_report = false;
|
||||
std::memset(&this->erpt_event, 0, sizeof(this->erpt_event));
|
||||
std::memset(&this->battery_event, 0, sizeof(this->battery_event));
|
||||
this->stack_dump_size = 0;
|
||||
std::memset(this->stack_dump, 0, sizeof(this->stack_dump));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "fs/fs_common.hpp"
|
||||
#include "fs/fsa/fs_ifile.hpp"
|
||||
#include "fs/fsa/fs_idirectory.hpp"
|
||||
#include "fs/fsa/fs_ifilesystem.hpp"
|
||||
#include "fs/fs_remote_filesystem.hpp"
|
||||
#include "fs/fs_istorage.hpp"
|
||||
#include "fs/fs_remote_storage.hpp"
|
||||
#include "fs/fs_file_storage.hpp"
|
||||
#include "fs/fs_query_range.hpp"
|
||||
#include "fs/fs_path_tool.hpp"
|
||||
#include "fs/fs_path_utils.hpp"
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <atmosphere/common.hpp>
|
||||
#include "../os.hpp"
|
||||
#include "../ncm.hpp"
|
||||
#include "../sf.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* TODO: Better place for this? */
|
||||
constexpr inline size_t MountNameLengthMax = 15;
|
||||
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "fs_common.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
constexpr inline size_t EntryNameLengthMax = 0x300;
|
||||
|
||||
using DirectoryEntry = ::FsDirectoryEntry;
|
||||
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "fs_common.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
struct ReadOption {
|
||||
u32 value;
|
||||
|
||||
static const ReadOption None;
|
||||
};
|
||||
|
||||
inline constexpr const ReadOption ReadOption::None = {FsReadOption_None};
|
||||
|
||||
inline constexpr bool operator==(const ReadOption &lhs, const ReadOption &rhs) {
|
||||
return lhs.value == rhs.value;
|
||||
}
|
||||
|
||||
inline constexpr bool operator!=(const ReadOption &lhs, const ReadOption &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
static_assert(std::is_pod<ReadOption>::value && sizeof(ReadOption) == sizeof(u32));
|
||||
|
||||
struct WriteOption {
|
||||
u32 value;
|
||||
|
||||
constexpr inline bool HasFlushFlag() const {
|
||||
return this->value & FsWriteOption_Flush;
|
||||
}
|
||||
|
||||
static const WriteOption None;
|
||||
static const WriteOption Flush;
|
||||
};
|
||||
|
||||
inline constexpr const WriteOption WriteOption::None = {FsWriteOption_None};
|
||||
inline constexpr const WriteOption WriteOption::Flush = {FsWriteOption_Flush};
|
||||
|
||||
inline constexpr bool operator==(const WriteOption &lhs, const WriteOption &rhs) {
|
||||
return lhs.value == rhs.value;
|
||||
}
|
||||
|
||||
inline constexpr bool operator!=(const WriteOption &lhs, const WriteOption &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
static_assert(std::is_pod<WriteOption>::value && sizeof(WriteOption) == sizeof(u32));
|
||||
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "fs_common.hpp"
|
||||
#include "fs_istorage.hpp"
|
||||
#include "fsa/fs_ifile.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
class FileStorage : public IStorage {
|
||||
private:
|
||||
static constexpr s64 InvalidSize = -1;
|
||||
private:
|
||||
std::unique_ptr<fsa::IFile> unique_file;
|
||||
std::shared_ptr<fsa::IFile> shared_file;
|
||||
fsa::IFile *base_file;
|
||||
s64 size;
|
||||
public:
|
||||
FileStorage(fsa::IFile *f) : unique_file(f), size(InvalidSize) {
|
||||
this->base_file = this->unique_file.get();
|
||||
}
|
||||
|
||||
FileStorage(std::unique_ptr<fsa::IFile> f) : unique_file(std::move(f)), size(InvalidSize) {
|
||||
this->base_file = this->unique_file.get();
|
||||
}
|
||||
|
||||
FileStorage(std::shared_ptr<fsa::IFile> f) : shared_file(f), size(InvalidSize) {
|
||||
this->base_file = this->shared_file.get();
|
||||
}
|
||||
|
||||
virtual ~FileStorage() { /* ... */ }
|
||||
protected:
|
||||
Result UpdateSize();
|
||||
public:
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) override;
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override;
|
||||
virtual Result Flush() override;
|
||||
virtual Result GetSize(s64 *out_size) override;
|
||||
virtual Result SetSize(s64 size) override;
|
||||
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override;
|
||||
};
|
||||
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "fs_common.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
enum OpenMode {
|
||||
OpenMode_Read = ::FsOpenMode_Read,
|
||||
OpenMode_Write = ::FsOpenMode_Write,
|
||||
OpenMode_Append = ::FsOpenMode_Append,
|
||||
|
||||
OpenMode_ReadWrite = (OpenMode_Read | OpenMode_Write),
|
||||
OpenMode_All = (OpenMode_ReadWrite | OpenMode_Append),
|
||||
};
|
||||
|
||||
enum OpenDirectoryMode {
|
||||
OpenDirectoryMode_Directory = ::FsDirOpenMode_ReadDirs,
|
||||
OpenDirectoryMode_File = ::FsDirOpenMode_ReadFiles,
|
||||
|
||||
OpenDirectoryMode_All = (OpenDirectoryMode_Directory | OpenDirectoryMode_File),
|
||||
|
||||
/* TODO: Separate enum, like N? */
|
||||
OpenDirectoryMode_NotRequireFileSize = ::FsDirOpenMode_NoFileSize,
|
||||
};
|
||||
|
||||
enum DirectoryEntryType {
|
||||
DirectoryEntryType_Directory = ::FsDirEntryType_Dir,
|
||||
DirectoryEntryType_File = ::FsDirEntryType_File,
|
||||
};
|
||||
|
||||
enum CreateOption {
|
||||
CreateOption_None = 0,
|
||||
CreateOption_BigFile = ::FsCreateOption_BigFile,
|
||||
};
|
||||
|
||||
using FileTimeStampRaw = ::FsTimeStampRaw;
|
||||
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "fs_common.hpp"
|
||||
#include "fs_file.hpp"
|
||||
#include "fs_operate_range.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
class IStorage {
|
||||
public:
|
||||
virtual ~IStorage() { /* ... */ }
|
||||
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) = 0;
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) {
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
|
||||
virtual Result Flush() = 0;
|
||||
|
||||
virtual Result SetSize(s64 size) {
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
|
||||
virtual Result GetSize(s64 *out) = 0;
|
||||
|
||||
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) {
|
||||
return fs::ResultUnsupportedOperation();
|
||||
}
|
||||
|
||||
virtual Result OperateRange(OperationId op_id, s64 offset, s64 size) {
|
||||
return this->OperateRange(nullptr, 0, op_id, offset, size, nullptr, 0);
|
||||
}
|
||||
public:
|
||||
static inline bool IsRangeValid(s64 offset, s64 size, s64 total_size) {
|
||||
return offset >= 0 &&
|
||||
size >= 0 &&
|
||||
size <= total_size &&
|
||||
offset <= (total_size - size);
|
||||
}
|
||||
|
||||
static inline bool IsRangeValid(s64 offset, size_t size, s64 total_size) {
|
||||
return IsRangeValid(offset, static_cast<s64>(size), total_size);
|
||||
}
|
||||
|
||||
static inline bool IsOffsetAndSizeValid(s64 offset, s64 size) {
|
||||
return offset >= 0 &&
|
||||
size >= 0 &&
|
||||
offset <= (offset + size);
|
||||
}
|
||||
|
||||
static inline bool IsOffsetAndSizeValid(s64 offset, size_t size) {
|
||||
return IsOffsetAndSizeValid(offset, static_cast<s64>(size));
|
||||
}
|
||||
};
|
||||
|
||||
class ReadOnlyStorageAdapter : public IStorage {
|
||||
private:
|
||||
std::shared_ptr<IStorage> shared_storage;
|
||||
std::unique_ptr<IStorage> unique_storage;
|
||||
IStorage *storage;
|
||||
public:
|
||||
ReadOnlyStorageAdapter(IStorage *s) : unique_storage(s) {
|
||||
this->storage = this->unique_storage.get();
|
||||
}
|
||||
ReadOnlyStorageAdapter(std::shared_ptr<IStorage> s) : shared_storage(s) {
|
||||
this->storage = this->shared_storage.get();
|
||||
}
|
||||
ReadOnlyStorageAdapter(std::unique_ptr<IStorage> s) : unique_storage(std::move(s)) {
|
||||
this->storage = this->unique_storage.get();
|
||||
}
|
||||
|
||||
virtual ~ReadOnlyStorageAdapter() { /* ... */ }
|
||||
public:
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) {
|
||||
return this->storage->Read(offset, buffer, size);
|
||||
}
|
||||
|
||||
virtual Result Flush() {
|
||||
return this->storage->Flush();
|
||||
}
|
||||
|
||||
virtual Result GetSize(s64 *out) {
|
||||
return this->storage->GetSize(out);
|
||||
}
|
||||
|
||||
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override {
|
||||
return this->storage->OperateRange(dst, dst_size, op_id, offset, size, src, src_size);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "fs_common.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
enum class OperationId : u64 {
|
||||
Clear = ::FsOperationId_Clear,
|
||||
ClearSignature = ::FsOperationId_ClearSignature,
|
||||
InvalidateCache = ::FsOperationId_InvalidateCache,
|
||||
QueryRange = ::FsOperationId_QueryRange,
|
||||
};
|
||||
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "fs_common.hpp"
|
||||
#include "../fssrv/fssrv_sf_path.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
namespace StringTraits {
|
||||
|
||||
constexpr inline char DirectorySeparator = '/';
|
||||
constexpr inline char DriveSeparator = ':';
|
||||
constexpr inline char Dot = '.';
|
||||
constexpr inline char NullTerminator = '\x00';
|
||||
|
||||
}
|
||||
|
||||
class PathTool {
|
||||
public:
|
||||
static constexpr const char RootPath[] = "/";
|
||||
public:
|
||||
static constexpr inline bool IsSeparator(char c) {
|
||||
return c == StringTraits::DirectorySeparator;
|
||||
}
|
||||
|
||||
static constexpr inline bool IsNullTerminator(char c) {
|
||||
return c == StringTraits::NullTerminator;
|
||||
}
|
||||
|
||||
static constexpr inline bool IsDot(char c) {
|
||||
return c == StringTraits::Dot;
|
||||
}
|
||||
|
||||
static constexpr inline bool IsWindowsDriveCharacter(char c) {
|
||||
return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
|
||||
}
|
||||
|
||||
static constexpr inline bool IsDriveSeparator(char c) {
|
||||
return c == StringTraits::DriveSeparator;
|
||||
}
|
||||
|
||||
static constexpr inline bool IsWindowsAbsolutePath(const char *p) {
|
||||
return IsWindowsDriveCharacter(p[0]) && IsDriveSeparator(p[1]);
|
||||
}
|
||||
|
||||
static constexpr inline bool IsCurrentDirectory(const char *p) {
|
||||
return IsDot(p[0]) && (IsSeparator(p[1]) || IsNullTerminator(p[1]));
|
||||
}
|
||||
|
||||
static constexpr inline bool IsParentDirectory(const char *p) {
|
||||
return IsDot(p[0]) && IsDot(p[1]) && (IsSeparator(p[2]) || IsNullTerminator(p[2]));
|
||||
}
|
||||
|
||||
static Result Normalize(char *out, size_t *out_len, const char *src, size_t max_out_size, bool unc_preserved = false);
|
||||
static Result IsNormalized(bool *out, const char *path);
|
||||
|
||||
static bool IsSubPath(const char *lhs, const char *rhs);
|
||||
};
|
||||
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "fs_common.hpp"
|
||||
#include "../fssrv/fssrv_sf_path.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
inline void Replace(char *dst, size_t dst_size, char old_char, char new_char) {
|
||||
for (char *cur = dst; cur < dst + dst_size && *cur != '\x00'; cur++) {
|
||||
if (*cur == old_char) {
|
||||
*cur = new_char;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline Result FspPathPrintf(fssrv::sf::FspPath *dst, const char *format, ...) {
|
||||
/* Format the path. */
|
||||
std::va_list va_list;
|
||||
va_start(va_list, format);
|
||||
const size_t len = std::vsnprintf(dst->str, sizeof(dst->str), format, va_list);
|
||||
va_end(va_list);
|
||||
|
||||
/* Validate length. */
|
||||
R_UNLESS(len < sizeof(dst->str), fs::ResultTooLongPath());
|
||||
|
||||
/* Fix slashes. */
|
||||
Replace(dst->str, sizeof(dst->str) - 1, '\\', '/');
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result VerifyPath(const char *path, size_t max_path_len, size_t max_name_len);
|
||||
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "fs_common.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
struct QueryRangeInfo {
|
||||
u32 aes_ctr_key_type;
|
||||
u32 speed_emulation_type;
|
||||
u32 reserved[0x38 / sizeof(u32)];
|
||||
|
||||
void Clear() {
|
||||
this->aes_ctr_key_type = 0;
|
||||
this->speed_emulation_type = 0;
|
||||
std::memset(this->reserved, 0, sizeof(this->reserved));
|
||||
}
|
||||
|
||||
void Merge(const QueryRangeInfo &rhs) {
|
||||
this->aes_ctr_key_type |= rhs.aes_ctr_key_type;
|
||||
this->speed_emulation_type |= rhs.speed_emulation_type;
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(std::is_pod<QueryRangeInfo>::value);
|
||||
static_assert(sizeof(QueryRangeInfo) == 0x40);
|
||||
static_assert(sizeof(QueryRangeInfo) == sizeof(::FsRangeInfo));
|
||||
|
||||
using FileQueryRangeInfo = QueryRangeInfo;
|
||||
using StorageQueryRangeInfo = QueryRangeInfo;
|
||||
|
||||
}
|
|
@ -1,179 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "fs_common.hpp"
|
||||
#include "fsa/fs_ifile.hpp"
|
||||
#include "fsa/fs_idirectory.hpp"
|
||||
#include "fsa/fs_ifilesystem.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
class RemoteFile : public fsa::IFile {
|
||||
private:
|
||||
std::unique_ptr<::FsFile> base_file;
|
||||
public:
|
||||
RemoteFile(::FsFile *f) : base_file(f) { /* ... */ }
|
||||
RemoteFile(std::unique_ptr<::FsFile> f) : base_file(std::move(f)) { /* ... */ }
|
||||
RemoteFile(::FsFile f) {
|
||||
this->base_file = std::make_unique<::FsFile>(f);
|
||||
}
|
||||
|
||||
virtual ~RemoteFile() { fsFileClose(this->base_file.get()); }
|
||||
public:
|
||||
virtual Result ReadImpl(size_t *out, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) override final {
|
||||
return fsFileRead(this->base_file.get(), offset, buffer, size, option.value, out);
|
||||
}
|
||||
|
||||
virtual Result GetSizeImpl(s64 *out) override final {
|
||||
return fsFileGetSize(this->base_file.get(), out);
|
||||
}
|
||||
|
||||
virtual Result FlushImpl() override final {
|
||||
return fsFileFlush(this->base_file.get());
|
||||
}
|
||||
|
||||
virtual Result WriteImpl(s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) override final {
|
||||
return fsFileWrite(this->base_file.get(), offset, buffer, size, option.value);
|
||||
}
|
||||
|
||||
virtual Result SetSizeImpl(s64 size) override final {
|
||||
return fsFileSetSize(this->base_file.get(), size);
|
||||
}
|
||||
|
||||
virtual Result OperateRangeImpl(void *dst, size_t dst_size, fs::OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override final {
|
||||
/* TODO: How should this be handled? */
|
||||
return fs::ResultNotImplemented();
|
||||
}
|
||||
public:
|
||||
virtual sf::cmif::DomainObjectId GetDomainObjectId() const override {
|
||||
return sf::cmif::DomainObjectId{serviceGetObjectId(&this->base_file->s)};
|
||||
}
|
||||
};
|
||||
|
||||
class RemoteDirectory : public fsa::IDirectory {
|
||||
private:
|
||||
std::unique_ptr<::FsDir> base_dir;
|
||||
public:
|
||||
RemoteDirectory(::FsDir *d) : base_dir(d) { /* ... */ }
|
||||
RemoteDirectory(std::unique_ptr<::FsDir> d) : base_dir(std::move(d)) { /* ... */ }
|
||||
RemoteDirectory(::FsDir d) {
|
||||
this->base_dir = std::make_unique<::FsDir>(d);
|
||||
}
|
||||
|
||||
virtual ~RemoteDirectory() { fsDirClose(this->base_dir.get()); }
|
||||
public:
|
||||
virtual Result ReadImpl(s64 *out_count, DirectoryEntry *out_entries, s64 max_entries) override final {
|
||||
return fsDirRead(this->base_dir.get(), out_count, max_entries, out_entries);
|
||||
}
|
||||
|
||||
virtual Result GetEntryCountImpl(s64 *out) override final {
|
||||
return fsDirGetEntryCount(this->base_dir.get(), out);
|
||||
}
|
||||
public:
|
||||
virtual sf::cmif::DomainObjectId GetDomainObjectId() const override {
|
||||
return sf::cmif::DomainObjectId{serviceGetObjectId(&this->base_dir->s)};
|
||||
}
|
||||
};
|
||||
|
||||
class RemoteFileSystem : public fsa::IFileSystem {
|
||||
private:
|
||||
std::unique_ptr<::FsFileSystem> base_fs;
|
||||
public:
|
||||
RemoteFileSystem(::FsFileSystem *fs) : base_fs(fs) { /* ... */ }
|
||||
RemoteFileSystem(std::unique_ptr<::FsFileSystem> fs) : base_fs(std::move(fs)) { /* ... */ }
|
||||
RemoteFileSystem(::FsFileSystem fs) {
|
||||
this->base_fs = std::make_unique<::FsFileSystem>(fs);
|
||||
}
|
||||
|
||||
virtual ~RemoteFileSystem() { fsFsClose(this->base_fs.get()); }
|
||||
public:
|
||||
virtual Result CreateFileImpl(const char *path, s64 size, int flags) override final {
|
||||
return fsFsCreateFile(this->base_fs.get(), path, size, flags);
|
||||
}
|
||||
|
||||
virtual Result DeleteFileImpl(const char *path) override final {
|
||||
return fsFsDeleteFile(this->base_fs.get(), path);
|
||||
}
|
||||
|
||||
virtual Result CreateDirectoryImpl(const char *path) override final {
|
||||
return fsFsCreateDirectory(this->base_fs.get(), path);
|
||||
}
|
||||
|
||||
virtual Result DeleteDirectoryImpl(const char *path) override final {
|
||||
return fsFsDeleteDirectory(this->base_fs.get(), path);
|
||||
}
|
||||
|
||||
virtual Result DeleteDirectoryRecursivelyImpl(const char *path) override final {
|
||||
return fsFsDeleteDirectoryRecursively(this->base_fs.get(), path);
|
||||
}
|
||||
|
||||
virtual Result RenameFileImpl(const char *old_path, const char *new_path) override final {
|
||||
return fsFsRenameFile(this->base_fs.get(), old_path, new_path);
|
||||
}
|
||||
|
||||
virtual Result RenameDirectoryImpl(const char *old_path, const char *new_path) override final {
|
||||
return fsFsRenameDirectory(this->base_fs.get(), old_path, new_path);
|
||||
}
|
||||
|
||||
virtual Result GetEntryTypeImpl(DirectoryEntryType *out, const char *path) override final {
|
||||
static_assert(sizeof(::FsDirEntryType) == sizeof(DirectoryEntryType));
|
||||
return fsFsGetEntryType(this->base_fs.get(), path, reinterpret_cast<::FsDirEntryType *>(out));
|
||||
}
|
||||
|
||||
virtual Result OpenFileImpl(std::unique_ptr<fsa::IFile> *out_file, const char *path, OpenMode mode) override final {
|
||||
FsFile f;
|
||||
R_TRY(fsFsOpenFile(this->base_fs.get(), path, mode, &f));
|
||||
|
||||
*out_file = std::make_unique<RemoteFile>(f);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result OpenDirectoryImpl(std::unique_ptr<fsa::IDirectory> *out_dir, const char *path, OpenDirectoryMode mode) override final {
|
||||
FsDir d;
|
||||
R_TRY(fsFsOpenDirectory(this->base_fs.get(), path, mode, &d));
|
||||
|
||||
*out_dir = std::make_unique<RemoteDirectory>(d);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result CommitImpl() override final {
|
||||
return fsFsCommit(this->base_fs.get());
|
||||
}
|
||||
|
||||
|
||||
virtual Result GetFreeSpaceSizeImpl(s64 *out, const char *path) {
|
||||
return fsFsGetFreeSpace(this->base_fs.get(), path, out);
|
||||
}
|
||||
|
||||
virtual Result GetTotalSpaceSizeImpl(s64 *out, const char *path) {
|
||||
return fsFsGetTotalSpace(this->base_fs.get(), path, out);
|
||||
}
|
||||
|
||||
virtual Result CleanDirectoryRecursivelyImpl(const char *path) {
|
||||
return fsFsCleanDirectoryRecursively(this->base_fs.get(), path);
|
||||
}
|
||||
|
||||
virtual Result GetFileTimeStampRawImpl(FileTimeStampRaw *out, const char *path) {
|
||||
static_assert(sizeof(FileTimeStampRaw) == sizeof(::FsTimeStampRaw));
|
||||
return fsFsGetFileTimeStampRaw(this->base_fs.get(), path, reinterpret_cast<::FsTimeStampRaw *>(out));
|
||||
}
|
||||
|
||||
virtual Result QueryEntryImpl(char *dst, size_t dst_size, const char *src, size_t src_size, fsa::QueryId query, const char *path) {
|
||||
return fsFsQueryEntry(this->base_fs.get(), dst, dst_size, src, src_size, path, static_cast<FsFileSystemQueryId>(query));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "fs_common.hpp"
|
||||
#include "fs_istorage.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
class RemoteStorage : public IStorage {
|
||||
private:
|
||||
std::unique_ptr<::FsStorage> base_storage;
|
||||
public:
|
||||
RemoteStorage(::FsStorage *s) : base_storage(s) { /* ... */ }
|
||||
RemoteStorage(std::unique_ptr<::FsStorage> s) : base_storage(std::move(s)) { /* ... */ }
|
||||
RemoteStorage(::FsStorage s) {
|
||||
this->base_storage = std::make_unique<::FsStorage>(s);
|
||||
}
|
||||
|
||||
virtual ~RemoteStorage() { fsStorageClose(this->base_storage.get()); }
|
||||
public:
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) override {
|
||||
return fsStorageRead(this->base_storage.get(), offset, buffer, size);
|
||||
};
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||
return fsStorageWrite(this->base_storage.get(), offset, buffer, size);
|
||||
};
|
||||
|
||||
virtual Result Flush() override {
|
||||
return fsStorageFlush(this->base_storage.get());
|
||||
};
|
||||
|
||||
virtual Result GetSize(s64 *out_size) override {
|
||||
return fsStorageGetSize(this->base_storage.get(), out_size);
|
||||
};
|
||||
|
||||
virtual Result SetSize(s64 size) override {
|
||||
return fsStorageSetSize(this->base_storage.get(), size);
|
||||
};
|
||||
|
||||
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override {
|
||||
/* TODO: How to deal with this? */
|
||||
return fs::ResultUnsupportedOperation();
|
||||
};
|
||||
};
|
||||
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../fs_common.hpp"
|
||||
#include "../fs_directory.hpp"
|
||||
|
||||
namespace ams::fs::fsa {
|
||||
|
||||
class IDirectory {
|
||||
public:
|
||||
virtual ~IDirectory() { /* ... */ }
|
||||
|
||||
Result Read(s64 *out_count, DirectoryEntry *out_entries, s64 max_entries) {
|
||||
R_UNLESS(out_count != nullptr, fs::ResultNullptrArgument());
|
||||
if (max_entries == 0) {
|
||||
*out_count = 0;
|
||||
return ResultSuccess();
|
||||
}
|
||||
R_UNLESS(out_entries != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS(max_entries > 0, fs::ResultInvalidArgument());
|
||||
return this->ReadImpl(out_count, out_entries, max_entries);
|
||||
}
|
||||
|
||||
Result GetEntryCount(s64 *out) {
|
||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
||||
return this->GetEntryCountImpl(out);
|
||||
}
|
||||
public:
|
||||
/* TODO: This is a hack to allow the mitm API to work. Find a better way? */
|
||||
virtual sf::cmif::DomainObjectId GetDomainObjectId() const = 0;
|
||||
protected:
|
||||
/* ...? */
|
||||
private:
|
||||
virtual Result ReadImpl(s64 *out_count, DirectoryEntry *out_entries, s64 max_entries) = 0;
|
||||
virtual Result GetEntryCountImpl(s64 *out) = 0;
|
||||
};
|
||||
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "../fs_common.hpp"
|
||||
#include "../fs_file.hpp"
|
||||
#include "../fs_operate_range.hpp"
|
||||
|
||||
namespace ams::fs::fsa {
|
||||
|
||||
class IFile {
|
||||
public:
|
||||
virtual ~IFile() { /* ... */ }
|
||||
|
||||
Result Read(size_t *out, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) {
|
||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
||||
if (size == 0) {
|
||||
*out = 0;
|
||||
return ResultSuccess();
|
||||
}
|
||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS(offset >= 0, fs::ResultOutOfRange());
|
||||
const s64 signed_size = static_cast<s64>(size);
|
||||
R_UNLESS(signed_size >= 0, fs::ResultOutOfRange());
|
||||
R_UNLESS((std::numeric_limits<s64>::max() - offset) >= signed_size, fs::ResultOutOfRange());
|
||||
return this->ReadImpl(out, offset, buffer, size, option);
|
||||
}
|
||||
|
||||
Result Read(size_t *out, s64 offset, void *buffer, size_t size) {
|
||||
return this->Read(out, offset, buffer, size, ReadOption::None);
|
||||
}
|
||||
|
||||
Result GetSize(s64 *out) {
|
||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
||||
return this->GetSizeImpl(out);
|
||||
}
|
||||
|
||||
Result Flush() {
|
||||
return this->FlushImpl();
|
||||
}
|
||||
|
||||
Result Write(s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) {
|
||||
if (size == 0) {
|
||||
if (option.HasFlushFlag()) {
|
||||
R_TRY(this->Flush());
|
||||
}
|
||||
return ResultSuccess();
|
||||
}
|
||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS(offset >= 0, fs::ResultOutOfRange());
|
||||
const s64 signed_size = static_cast<s64>(size);
|
||||
R_UNLESS(signed_size >= 0, fs::ResultOutOfRange());
|
||||
R_UNLESS((std::numeric_limits<s64>::max() - offset) >= signed_size, fs::ResultOutOfRange());
|
||||
return this->WriteImpl(offset, buffer, size, option);
|
||||
}
|
||||
|
||||
Result SetSize(s64 size) {
|
||||
R_UNLESS(size >= 0, fs::ResultOutOfRange());
|
||||
return this->SetSizeImpl(size);
|
||||
}
|
||||
|
||||
Result OperateRange(void *dst, size_t dst_size, fs::OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) {
|
||||
return this->OperateRangeImpl(dst, dst_size, op_id, offset, size, src, src_size);
|
||||
}
|
||||
|
||||
Result OperateRange(fs::OperationId op_id, s64 offset, s64 size) {
|
||||
return this->OperateRangeImpl(nullptr, 0, op_id, offset, size, nullptr, 0);
|
||||
}
|
||||
public:
|
||||
/* TODO: This is a hack to allow the mitm API to work. Find a better way? */
|
||||
virtual sf::cmif::DomainObjectId GetDomainObjectId() const = 0;
|
||||
protected:
|
||||
/* ...? */
|
||||
private:
|
||||
virtual Result ReadImpl(size_t *out, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) = 0;
|
||||
virtual Result GetSizeImpl(s64 *out) = 0;
|
||||
virtual Result FlushImpl() = 0;
|
||||
virtual Result WriteImpl(s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) = 0;
|
||||
virtual Result SetSizeImpl(s64 size) = 0;
|
||||
virtual Result OperateRangeImpl(void *dst, size_t dst_size, fs::OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) = 0;
|
||||
};
|
||||
|
||||
}
|
|
@ -1,191 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../fs_common.hpp"
|
||||
#include "../fs_filesystem.hpp"
|
||||
|
||||
namespace ams::fs::fsa {
|
||||
|
||||
class IFile;
|
||||
class IDirectory;
|
||||
|
||||
enum class QueryId {
|
||||
SetConcatenationFileAttribute = FsFileSystemQueryId_SetConcatenationFileAttribute
|
||||
};
|
||||
|
||||
class IFileSystem {
|
||||
public:
|
||||
virtual ~IFileSystem() { /* ... */ }
|
||||
|
||||
Result CreateFile(const char *path, s64 size, int option) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
R_UNLESS(size >= 0, fs::ResultOutOfRange());
|
||||
return this->CreateFileImpl(path, size, option);
|
||||
}
|
||||
|
||||
Result CreateFile(const char *path, s64 size) {
|
||||
return this->CreateFile(path, size, 0);
|
||||
}
|
||||
|
||||
Result DeleteFile(const char *path) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
return this->DeleteFileImpl(path);
|
||||
}
|
||||
|
||||
Result CreateDirectory(const char *path) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
return this->CreateDirectoryImpl(path);
|
||||
}
|
||||
|
||||
Result DeleteDirectory(const char *path) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
return this->DeleteDirectoryImpl(path);
|
||||
}
|
||||
|
||||
Result DeleteDirectoryRecursively(const char *path) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
return this->DeleteDirectoryRecursivelyImpl(path);
|
||||
}
|
||||
|
||||
Result RenameFile(const char *old_path, const char *new_path) {
|
||||
R_UNLESS(old_path != nullptr, fs::ResultInvalidPath());
|
||||
R_UNLESS(new_path != nullptr, fs::ResultInvalidPath());
|
||||
return this->RenameFileImpl(old_path, new_path);
|
||||
}
|
||||
|
||||
Result RenameDirectory(const char *old_path, const char *new_path) {
|
||||
R_UNLESS(old_path != nullptr, fs::ResultInvalidPath());
|
||||
R_UNLESS(new_path != nullptr, fs::ResultInvalidPath());
|
||||
return this->RenameDirectoryImpl(old_path, new_path);
|
||||
}
|
||||
|
||||
Result GetEntryType(DirectoryEntryType *out, const char *path) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
||||
return this->GetEntryTypeImpl(out, path);
|
||||
}
|
||||
|
||||
Result OpenFile(std::unique_ptr<IFile> *out_file, const char *path, OpenMode mode) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
R_UNLESS(out_file != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS((mode & OpenMode_ReadWrite) != 0, fs::ResultInvalidArgument());
|
||||
R_UNLESS((mode & ~OpenMode_All) == 0, fs::ResultInvalidArgument());
|
||||
return this->OpenFileImpl(out_file, path, mode);
|
||||
}
|
||||
|
||||
Result OpenDirectory(std::unique_ptr<IDirectory> *out_dir, const char *path, OpenDirectoryMode mode) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
R_UNLESS(out_dir != nullptr, fs::ResultNullptrArgument());
|
||||
R_UNLESS((mode & OpenDirectoryMode_All) != 0, fs::ResultInvalidArgument());
|
||||
R_UNLESS((mode & ~OpenDirectoryMode_All) == 0, fs::ResultInvalidArgument());
|
||||
return this->OpenDirectoryImpl(out_dir, path, mode);
|
||||
}
|
||||
|
||||
Result Commit() {
|
||||
return this->CommitImpl();
|
||||
}
|
||||
|
||||
Result GetFreeSpaceSize(s64 *out, const char *path) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
||||
return this->GetFreeSpaceSizeImpl(out, path);
|
||||
}
|
||||
|
||||
Result GetTotalSpaceSize(s64 *out, const char *path) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
||||
return this->GetTotalSpaceSizeImpl(out, path);
|
||||
}
|
||||
|
||||
Result CleanDirectoryRecursively(const char *path) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
return this->CleanDirectoryRecursivelyImpl(path);
|
||||
}
|
||||
|
||||
Result GetFileTimeStampRaw(FileTimeStampRaw *out, const char *path) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
|
||||
return this->GetFileTimeStampRawImpl(out, path);
|
||||
}
|
||||
|
||||
Result QueryEntry(char *dst, size_t dst_size, const char *src, size_t src_size, QueryId query, const char *path) {
|
||||
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
|
||||
return this->QueryEntryImpl(dst, dst_size, src, src_size, query, path);
|
||||
}
|
||||
|
||||
/* These aren't accessible as commands. */
|
||||
|
||||
Result CommitProvisionally(s64 counter) {
|
||||
return this->CommitProvisionallyImpl(counter);
|
||||
}
|
||||
|
||||
Result Rollback() {
|
||||
return this->RollbackImpl();
|
||||
}
|
||||
|
||||
Result Flush() {
|
||||
return this->FlushImpl();
|
||||
}
|
||||
|
||||
protected:
|
||||
/* ...? */
|
||||
private:
|
||||
virtual Result CreateFileImpl(const char *path, s64 size, int flags) = 0;
|
||||
virtual Result DeleteFileImpl(const char *path) = 0;
|
||||
virtual Result CreateDirectoryImpl(const char *path) = 0;
|
||||
virtual Result DeleteDirectoryImpl(const char *path) = 0;
|
||||
virtual Result DeleteDirectoryRecursivelyImpl(const char *path) = 0;
|
||||
virtual Result RenameFileImpl(const char *old_path, const char *new_path) = 0;
|
||||
virtual Result RenameDirectoryImpl(const char *old_path, const char *new_path) = 0;
|
||||
virtual Result GetEntryTypeImpl(fs::DirectoryEntryType *out, const char *path) = 0;
|
||||
virtual Result OpenFileImpl(std::unique_ptr<fs::fsa::IFile> *out_file, const char *path, fs::OpenMode mode) = 0;
|
||||
virtual Result OpenDirectoryImpl(std::unique_ptr<fs::fsa::IDirectory> *out_dir, const char *path, fs::OpenDirectoryMode mode) = 0;
|
||||
virtual Result CommitImpl() = 0;
|
||||
|
||||
virtual Result GetFreeSpaceSizeImpl(s64 *out, const char *path) {
|
||||
return fs::ResultNotImplemented();
|
||||
}
|
||||
|
||||
virtual Result GetTotalSpaceSizeImpl(s64 *out, const char *path) {
|
||||
return fs::ResultNotImplemented();
|
||||
}
|
||||
|
||||
virtual Result CleanDirectoryRecursivelyImpl(const char *path) = 0;
|
||||
|
||||
virtual Result GetFileTimeStampRawImpl(fs::FileTimeStampRaw *out, const char *path) {
|
||||
return fs::ResultNotImplemented();
|
||||
}
|
||||
|
||||
virtual Result QueryEntryImpl(char *dst, size_t dst_size, const char *src, size_t src_size, fs::fsa::QueryId query, const char *path) {
|
||||
return fs::ResultNotImplemented();
|
||||
}
|
||||
|
||||
/* These aren't accessible as commands. */
|
||||
virtual Result CommitProvisionallyImpl(s64 counter) {
|
||||
return fs::ResultNotImplemented();
|
||||
}
|
||||
|
||||
virtual Result RollbackImpl() {
|
||||
return fs::ResultNotImplemented();
|
||||
}
|
||||
|
||||
virtual Result FlushImpl() {
|
||||
return fs::ResultNotImplemented();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "fssrv/fssrv_sf_path.hpp"
|
||||
#include "fssrv/fssrv_path_normalizer.hpp"
|
|
@ -1,18 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "interface_adapters/fssrv_storage_interface_adapter.hpp"
|
||||
#include "interface_adapters/fssrv_filesystem_interface_adapter.hpp"
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "../fs/fs_common.hpp"
|
||||
|
||||
namespace ams::fssrv {
|
||||
|
||||
/* This is in fssrv::detail in official code. */
|
||||
/* TODO: Consider moving to ::impl? */
|
||||
|
||||
class PathNormalizer {
|
||||
public:
|
||||
enum Option : u32 {
|
||||
Option_None = BIT(0),
|
||||
Option_PreserveUnc = BIT(1),
|
||||
Option_PreserveTailSeparator = BIT(2),
|
||||
Option_HasMountName = BIT(3),
|
||||
Option_AcceptEmpty = BIT(4),
|
||||
};
|
||||
private:
|
||||
using Buffer = std::unique_ptr<char[]>;
|
||||
private:
|
||||
Buffer buffer;
|
||||
const char *path;
|
||||
Result result;
|
||||
private:
|
||||
static Result Normalize(const char **out_path, Buffer *out_buf, const char *path, bool preserve_unc, bool preserve_tail_sep, bool has_mount_name);
|
||||
public:
|
||||
explicit PathNormalizer(const char *p) : buffer(), path(nullptr), result(ResultSuccess()) {
|
||||
this->result = Normalize(&this->path, &this->buffer, p, false, false, false);
|
||||
}
|
||||
|
||||
PathNormalizer(const char *p, u32 option) : buffer(), path(nullptr), result(ResultSuccess()) {
|
||||
if ((option & Option_AcceptEmpty) && p[0] == '\x00') {
|
||||
this->path = path;
|
||||
} else {
|
||||
const bool preserve_unc = (option & Option_PreserveUnc);
|
||||
const bool preserve_tail_sep = (option & Option_PreserveTailSeparator);
|
||||
const bool has_mount_name = (option & Option_HasMountName);
|
||||
this->result = Normalize(&this->path, &this->buffer, p, preserve_unc, preserve_tail_sep, has_mount_name);
|
||||
}
|
||||
}
|
||||
|
||||
inline Result GetResult() const {
|
||||
return this->result;
|
||||
}
|
||||
|
||||
inline const char * GetPath() const {
|
||||
return this->path;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "../fs/fs_common.hpp"
|
||||
#include "../fs/fs_directory.hpp"
|
||||
#include "../sf/sf_buffer_tags.hpp"
|
||||
|
||||
namespace ams::fssrv::sf {
|
||||
|
||||
struct Path : ams::sf::LargeData {
|
||||
char str[fs::EntryNameLengthMax + 1];
|
||||
|
||||
static constexpr Path Encode(const char *p) {
|
||||
Path path = {};
|
||||
for (size_t i = 0; i < sizeof(path) - 1; i++) {
|
||||
path.str[i] = p[i];
|
||||
if (p[i] == '\x00') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
static constexpr size_t GetPathLength(const Path &path) {
|
||||
size_t len = 0;
|
||||
for (size_t i = 0; i < sizeof(path) - 1 && path.str[i] != '\x00'; i++) {
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(std::is_pod<Path>::value && sizeof(Path) == FS_MAX_PATH);
|
||||
|
||||
using FspPath = Path;
|
||||
|
||||
}
|
|
@ -1,192 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "../../fs/fs_common.hpp"
|
||||
#include "../../fs/fs_file.hpp"
|
||||
#include "../../fs/fs_directory.hpp"
|
||||
#include "../../fs/fs_filesystem.hpp"
|
||||
#include "../../fs/fs_query_range.hpp"
|
||||
#include "../../fssrv/fssrv_sf_path.hpp"
|
||||
#include "../../fssystem/fssystem_utility.hpp"
|
||||
|
||||
namespace ams::fs::fsa {
|
||||
|
||||
class IFile;
|
||||
class IDirectory;
|
||||
class IFileSystem;
|
||||
|
||||
}
|
||||
|
||||
namespace ams::fssrv::impl {
|
||||
|
||||
class FileSystemInterfaceAdapter;
|
||||
|
||||
class FileInterfaceAdapter final : public ams::sf::IServiceObject {
|
||||
NON_COPYABLE(FileInterfaceAdapter);
|
||||
public:
|
||||
enum class CommandId {
|
||||
Read = 0,
|
||||
Write = 1,
|
||||
Flush = 2,
|
||||
SetSize = 3,
|
||||
GetSize = 4,
|
||||
OperateRange = 5,
|
||||
};
|
||||
private:
|
||||
std::shared_ptr<FileSystemInterfaceAdapter> parent_filesystem;
|
||||
std::unique_ptr<fs::fsa::IFile> base_file;
|
||||
std::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
|
||||
public:
|
||||
FileInterfaceAdapter(std::unique_ptr<fs::fsa::IFile> &&file, std::shared_ptr<FileSystemInterfaceAdapter> &&parent, std::unique_lock<fssystem::SemaphoreAdapter> &&sema);
|
||||
~FileInterfaceAdapter();
|
||||
private:
|
||||
void InvalidateCache();
|
||||
public:
|
||||
/* Command API. */
|
||||
Result Read(ams::sf::Out<s64> out, s64 offset, const ams::sf::OutNonSecureBuffer &buffer, s64 size, fs::ReadOption option);
|
||||
Result Write(s64 offset, const ams::sf::InNonSecureBuffer &buffer, s64 size, fs::WriteOption option);
|
||||
Result Flush();
|
||||
Result SetSize(s64 size);
|
||||
Result GetSize(ams::sf::Out<s64> out);
|
||||
Result OperateRange(ams::sf::Out<fs::FileQueryRangeInfo> out, s32 op_id, s64 offset, s64 size);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
/* 1.0.0- */
|
||||
MAKE_SERVICE_COMMAND_META(Read),
|
||||
MAKE_SERVICE_COMMAND_META(Write),
|
||||
MAKE_SERVICE_COMMAND_META(Flush),
|
||||
MAKE_SERVICE_COMMAND_META(SetSize),
|
||||
MAKE_SERVICE_COMMAND_META(GetSize),
|
||||
|
||||
/* 4.0.0- */
|
||||
MAKE_SERVICE_COMMAND_META(OperateRange, hos::Version_400),
|
||||
};
|
||||
};
|
||||
|
||||
class DirectoryInterfaceAdapter final : public ams::sf::IServiceObject {
|
||||
NON_COPYABLE(DirectoryInterfaceAdapter);
|
||||
public:
|
||||
enum class CommandId {
|
||||
Read = 0,
|
||||
GetEntryCount = 1,
|
||||
};
|
||||
private:
|
||||
std::shared_ptr<FileSystemInterfaceAdapter> parent_filesystem;
|
||||
std::unique_ptr<fs::fsa::IDirectory> base_dir;
|
||||
std::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
|
||||
public:
|
||||
DirectoryInterfaceAdapter(std::unique_ptr<fs::fsa::IDirectory> &&dir, std::shared_ptr<FileSystemInterfaceAdapter> &&parent, std::unique_lock<fssystem::SemaphoreAdapter> &&sema);
|
||||
~DirectoryInterfaceAdapter();
|
||||
public:
|
||||
/* Command API */
|
||||
Result Read(ams::sf::Out<s64> out, const ams::sf::OutBuffer &out_entries);
|
||||
Result GetEntryCount(ams::sf::Out<s64> out);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(Read),
|
||||
MAKE_SERVICE_COMMAND_META(GetEntryCount),
|
||||
};
|
||||
};
|
||||
|
||||
class FileSystemInterfaceAdapter final : public std::enable_shared_from_this<FileSystemInterfaceAdapter>, public ams::sf::IServiceObject {
|
||||
NON_COPYABLE(FileSystemInterfaceAdapter);
|
||||
public:
|
||||
enum class CommandId {
|
||||
/* 1.0.0+ */
|
||||
CreateFile = 0,
|
||||
DeleteFile = 1,
|
||||
CreateDirectory = 2,
|
||||
DeleteDirectory = 3,
|
||||
DeleteDirectoryRecursively = 4,
|
||||
RenameFile = 5,
|
||||
RenameDirectory = 6,
|
||||
GetEntryType = 7,
|
||||
OpenFile = 8,
|
||||
OpenDirectory = 9,
|
||||
Commit = 10,
|
||||
GetFreeSpaceSize = 11,
|
||||
GetTotalSpaceSize = 12,
|
||||
|
||||
/* 3.0.0+ */
|
||||
CleanDirectoryRecursively = 13,
|
||||
GetFileTimeStampRaw = 14,
|
||||
|
||||
/* 4.0.0+ */
|
||||
QueryEntry = 15,
|
||||
};
|
||||
private:
|
||||
std::shared_ptr<fs::fsa::IFileSystem> base_fs;
|
||||
std::unique_lock<fssystem::SemaphoreAdapter> mount_count_semaphore;
|
||||
os::ReadWriteLock invalidation_lock;
|
||||
bool open_count_limited;
|
||||
bool deep_retry_enabled = false;
|
||||
public:
|
||||
FileSystemInterfaceAdapter(std::shared_ptr<fs::fsa::IFileSystem> &&fs, bool open_limited);
|
||||
/* TODO: Other constructors. */
|
||||
|
||||
~FileSystemInterfaceAdapter();
|
||||
public:
|
||||
bool IsDeepRetryEnabled() const;
|
||||
bool IsAccessFailureDetectionObserved() const;
|
||||
std::optional<std::shared_lock<os::ReadWriteLock>> AcquireCacheInvalidationReadLock();
|
||||
os::ReadWriteLock &GetReadWriteLockForCacheInvalidation();
|
||||
public:
|
||||
/* Command API. */
|
||||
Result CreateFile(const fssrv::sf::Path &path, s64 size, s32 option);
|
||||
Result DeleteFile(const fssrv::sf::Path &path);
|
||||
Result CreateDirectory(const fssrv::sf::Path &path);
|
||||
Result DeleteDirectory(const fssrv::sf::Path &path);
|
||||
Result DeleteDirectoryRecursively(const fssrv::sf::Path &path);
|
||||
Result RenameFile(const fssrv::sf::Path &old_path, const fssrv::sf::Path &new_path);
|
||||
Result RenameDirectory(const fssrv::sf::Path &old_path, const fssrv::sf::Path &new_path);
|
||||
Result GetEntryType(ams::sf::Out<u32> out, const fssrv::sf::Path &path);
|
||||
Result OpenFile(ams::sf::Out<std::shared_ptr<FileInterfaceAdapter>> out, const fssrv::sf::Path &path, u32 mode);
|
||||
Result OpenDirectory(ams::sf::Out<std::shared_ptr<DirectoryInterfaceAdapter>> out, const fssrv::sf::Path &path, u32 mode);
|
||||
Result Commit();
|
||||
Result GetFreeSpaceSize(ams::sf::Out<s64> out, const fssrv::sf::Path &path);
|
||||
Result GetTotalSpaceSize(ams::sf::Out<s64> out, const fssrv::sf::Path &path);
|
||||
|
||||
Result CleanDirectoryRecursively(const fssrv::sf::Path &path);
|
||||
Result GetFileTimeStampRaw(ams::sf::Out<fs::FileTimeStampRaw> out, const fssrv::sf::Path &path);
|
||||
|
||||
Result QueryEntry(const ams::sf::OutBuffer &out_buf, const ams::sf::InBuffer &in_buf, s32 query_id, const fssrv::sf::Path &path);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
/* 1.0.0- */
|
||||
MAKE_SERVICE_COMMAND_META(CreateFile),
|
||||
MAKE_SERVICE_COMMAND_META(DeleteFile),
|
||||
MAKE_SERVICE_COMMAND_META(CreateDirectory),
|
||||
MAKE_SERVICE_COMMAND_META(DeleteDirectory),
|
||||
MAKE_SERVICE_COMMAND_META(DeleteDirectoryRecursively),
|
||||
MAKE_SERVICE_COMMAND_META(RenameFile),
|
||||
MAKE_SERVICE_COMMAND_META(RenameDirectory),
|
||||
MAKE_SERVICE_COMMAND_META(GetEntryType),
|
||||
MAKE_SERVICE_COMMAND_META(OpenFile),
|
||||
MAKE_SERVICE_COMMAND_META(OpenDirectory),
|
||||
MAKE_SERVICE_COMMAND_META(Commit),
|
||||
MAKE_SERVICE_COMMAND_META(GetFreeSpaceSize),
|
||||
MAKE_SERVICE_COMMAND_META(GetTotalSpaceSize),
|
||||
|
||||
/* 3.0.0- */
|
||||
MAKE_SERVICE_COMMAND_META(CleanDirectoryRecursively, hos::Version_300),
|
||||
MAKE_SERVICE_COMMAND_META(GetFileTimeStampRaw, hos::Version_300),
|
||||
|
||||
/* 4.0.0- */
|
||||
MAKE_SERVICE_COMMAND_META(QueryEntry, hos::Version_400),
|
||||
};
|
||||
};
|
||||
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "../../fs/fs_common.hpp"
|
||||
#include "../../fs/fs_query_range.hpp"
|
||||
#include "../../fssystem/fssystem_utility.hpp"
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
class IStorage;
|
||||
|
||||
}
|
||||
|
||||
namespace ams::fssrv::impl {
|
||||
|
||||
class StorageInterfaceAdapter final : public ams::sf::IServiceObject {
|
||||
NON_COPYABLE(StorageInterfaceAdapter);
|
||||
public:
|
||||
enum class CommandId {
|
||||
Read = 0,
|
||||
Write = 1,
|
||||
Flush = 2,
|
||||
SetSize = 3,
|
||||
GetSize = 4,
|
||||
OperateRange = 5,
|
||||
};
|
||||
private:
|
||||
/* TODO: Nintendo uses fssystem::AsynchronousAccessStorage here. */
|
||||
std::shared_ptr<fs::IStorage> base_storage;
|
||||
std::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
|
||||
os::ReadWriteLock invalidation_lock;
|
||||
/* TODO: DataStorageContext. */
|
||||
bool deep_retry_enabled = false;
|
||||
public:
|
||||
StorageInterfaceAdapter(fs::IStorage *storage);
|
||||
StorageInterfaceAdapter(std::unique_ptr<fs::IStorage> storage);
|
||||
explicit StorageInterfaceAdapter(std::shared_ptr<fs::IStorage> &&storage);
|
||||
/* TODO: Other constructors. */
|
||||
|
||||
~StorageInterfaceAdapter();
|
||||
private:
|
||||
std::optional<std::shared_lock<os::ReadWriteLock>> AcquireCacheInvalidationReadLock();
|
||||
private:
|
||||
/* Command API. */
|
||||
Result Read(s64 offset, const ams::sf::OutNonSecureBuffer &buffer, s64 size);
|
||||
Result Write(s64 offset, const ams::sf::InNonSecureBuffer &buffer, s64 size);
|
||||
Result Flush();
|
||||
Result SetSize(s64 size);
|
||||
Result GetSize(ams::sf::Out<s64> out);
|
||||
Result OperateRange(ams::sf::Out<fs::StorageQueryRangeInfo> out, s32 op_id, s64 offset, s64 size);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
/* 1.0.0- */
|
||||
MAKE_SERVICE_COMMAND_META(Read),
|
||||
MAKE_SERVICE_COMMAND_META(Write),
|
||||
MAKE_SERVICE_COMMAND_META(Flush),
|
||||
MAKE_SERVICE_COMMAND_META(SetSize),
|
||||
MAKE_SERVICE_COMMAND_META(GetSize),
|
||||
|
||||
/* 4.0.0- */
|
||||
MAKE_SERVICE_COMMAND_META(OperateRange, hos::Version_400),
|
||||
};
|
||||
};
|
||||
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "fssystem/fssystem_utility.hpp"
|
||||
#include "fssystem/fssystem_path_tool.hpp"
|
||||
#include "fssystem/fssystem_subdirectory_filesystem.hpp"
|
||||
#include "fssystem/fssystem_directory_redirection_filesystem.hpp"
|
||||
#include "fssystem/fssystem_directory_savedata_filesystem.hpp"
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "impl/fssystem_path_resolution_filesystem.hpp"
|
||||
|
||||
namespace ams::fssystem {
|
||||
|
||||
class DirectoryRedirectionFileSystem : public impl::IPathResolutionFileSystem<DirectoryRedirectionFileSystem> {
|
||||
NON_COPYABLE(DirectoryRedirectionFileSystem);
|
||||
private:
|
||||
using PathResolutionFileSystem = impl::IPathResolutionFileSystem<DirectoryRedirectionFileSystem>;
|
||||
friend class impl::IPathResolutionFileSystem<DirectoryRedirectionFileSystem>;
|
||||
private:
|
||||
char *before_dir;
|
||||
size_t before_dir_len;
|
||||
char *after_dir;
|
||||
size_t after_dir_len;
|
||||
public:
|
||||
DirectoryRedirectionFileSystem(std::shared_ptr<fs::fsa::IFileSystem> fs, const char *before, const char *after, bool unc = false);
|
||||
DirectoryRedirectionFileSystem(std::unique_ptr<fs::fsa::IFileSystem> fs, const char *before, const char *after, bool unc = false);
|
||||
|
||||
virtual ~DirectoryRedirectionFileSystem();
|
||||
protected:
|
||||
inline std::optional<std::scoped_lock<os::Mutex>> GetAccessorLock() const {
|
||||
/* No accessor lock is needed. */
|
||||
return std::nullopt;
|
||||
}
|
||||
private:
|
||||
Result GetNormalizedDirectoryPath(char **out, size_t *out_size, const char *dir);
|
||||
Result Initialize(const char *before, const char *after);
|
||||
Result ResolveFullPath(char *out, size_t out_size, const char *relative_path);
|
||||
};
|
||||
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "impl/fssystem_path_resolution_filesystem.hpp"
|
||||
|
||||
namespace ams::fssystem {
|
||||
|
||||
class DirectorySaveDataFileSystem : public impl::IPathResolutionFileSystem<DirectorySaveDataFileSystem> {
|
||||
NON_COPYABLE(DirectorySaveDataFileSystem);
|
||||
private:
|
||||
using PathResolutionFileSystem = impl::IPathResolutionFileSystem<DirectorySaveDataFileSystem>;
|
||||
friend class impl::IPathResolutionFileSystem<DirectorySaveDataFileSystem>;
|
||||
private:
|
||||
os::Mutex accessor_mutex;
|
||||
s32 open_writable_files;
|
||||
public:
|
||||
DirectorySaveDataFileSystem(std::shared_ptr<fs::fsa::IFileSystem> fs);
|
||||
DirectorySaveDataFileSystem(std::unique_ptr<fs::fsa::IFileSystem> fs);
|
||||
Result Initialize();
|
||||
|
||||
virtual ~DirectorySaveDataFileSystem();
|
||||
protected:
|
||||
inline std::optional<std::scoped_lock<os::Mutex>> GetAccessorLock() {
|
||||
/* We have a real accessor lock that we want to use. */
|
||||
return std::make_optional<std::scoped_lock<os::Mutex>>(this->accessor_mutex);
|
||||
}
|
||||
private:
|
||||
Result AllocateWorkBuffer(std::unique_ptr<u8[]> *out, size_t *out_size, size_t ideal_size);
|
||||
Result SynchronizeDirectory(const char *dst, const char *src);
|
||||
Result ResolveFullPath(char *out, size_t out_size, const char *relative_path);
|
||||
public:
|
||||
void OnWritableFileClose();
|
||||
Result CopySaveFromFileSystem(fs::fsa::IFileSystem *save_fs);
|
||||
public:
|
||||
/* Overridden from IPathResolutionFileSystem */
|
||||
virtual Result OpenFileImpl(std::unique_ptr<fs::fsa::IFile> *out_file, const char *path, fs::OpenMode mode) override;
|
||||
virtual Result CommitImpl() override;
|
||||
|
||||
/* Overridden from IPathResolutionFileSystem but not commands. */
|
||||
virtual Result CommitProvisionallyImpl(s64 counter) override;
|
||||
virtual Result RollbackImpl() override;
|
||||
|
||||
/* Explicitly overridden to be not implemented. */
|
||||
virtual Result GetFreeSpaceSizeImpl(s64 *out, const char *path) override;
|
||||
virtual Result GetTotalSpaceSizeImpl(s64 *out, const char *path) override;
|
||||
virtual Result GetFileTimeStampRawImpl(fs::FileTimeStampRaw *out, const char *path) override;
|
||||
virtual Result QueryEntryImpl(char *dst, size_t dst_size, const char *src, size_t src_size, fs::fsa::QueryId query, const char *path) override;
|
||||
virtual Result FlushImpl() override;
|
||||
};
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue