├── .gitignore ├── CHANGELOG ├── LICENSE ├── Makefile ├── Makefile_nro ├── Makefile_sys ├── README.md ├── config.json ├── examples └── quadratic.js ├── icon.jpg ├── include ├── duk_config.h ├── duktape.h ├── md5.h ├── nxsh.h └── sysmodule.h └── source ├── acc.c ├── cat.c ├── cd.c ├── chmod.c ├── cp.c ├── cwd.c ├── duktape.c ├── echo.c ├── fetch.c ├── hash.c ├── log.c ├── ls.c ├── main.c ├── md5.c ├── mkdir.c ├── mount.c ├── mv.c ├── passwd.c ├── pm.c ├── power.c ├── prompt.c ├── realpath.c ├── rm.c ├── script.c ├── sysmodule.c ├── touch.c └── util.c /.gitignore: -------------------------------------------------------------------------------- 1 | build/* 2 | release/* 3 | *.elf 4 | *.nro 5 | *.pfs0 6 | *.nacp 7 | *.nso 8 | *.nsp 9 | *.npdm -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | ======= Version 0.1.2 alpha (Nov 2, 2018) ======= 2 | * Added cp command 3 | * Added mv command 4 | * Fixed some uninteresting bugs 5 | * Updated help menu 6 | * Fixed PuTTY "command not found" issue 7 | 8 | NOTE: File operations on the SD card seem to be very slow 9 | 10 | ======= Version 0.1.3 alpha (Nov 2, 2018) ======= 11 | * Fixed sporadic segfault when trying to delete directory without -r switch 12 | * Clarified some usage messages 13 | 14 | ======= Version 0.1.4 alpha (Nov 5, 2018) ======= 15 | * Adding logging functionality 16 | * Updated prompt to be more traditionally unix-like 17 | 18 | ======= Version 0.1.5 alpha (Nov 5, 2018) ======= 19 | * Added fetch command to fetch files from remote server 20 | * Added chmod (however it's not functional on the switch, so I'm investigating that) 21 | 22 | ======= Version 0.1.6 alpha (Nov 5, 2018) ======= 23 | * Added password authentication (see the passwd command) 24 | 25 | ======= Version 0.1.7 beta (Nov 14, 2018) ======= 26 | * Added JS scripting functionality via duktape. You can now write 27 | scripts and execute them, provided they are ECMAScript 5.1 compliant. 28 | See the examples/ directory for a bit more information. 29 | * Added native print(), readFile(), and writeFile() functions (see above) 30 | 31 | ======= Version 0.1.8 beta (Feb 2, 2018) ======= 32 | * Implemented NAND browsing (see mount command) 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Cesura 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: clean all sys nro rebuild dist 2 | 3 | all: nro sys 4 | 5 | nro: 6 | @$(MAKE) rebuild 7 | @$(MAKE) -f Makefile_nro 8 | 9 | sys: 10 | @$(MAKE) rebuild 11 | @$(MAKE) -f Makefile_sys 12 | 13 | dist: 14 | @$(MAKE) rebuild 15 | @$(MAKE) -f Makefile_nro dist 16 | @$(MAKE) rebuild 17 | @$(MAKE) -f Makefile_sys dist 18 | 19 | clean: 20 | @$(MAKE) -f Makefile_sys clean 21 | @$(MAKE) -f Makefile_nro clean 22 | @rm -rf release 23 | 24 | files := $(wildcard source/*) $(wildcard include/*) 25 | REBUILD := $(foreach f, $(files), $(if $(findstring __SYS__, $(shell cat $(f))), $(f))) # Gets a list of all the files that have __SYS__ in them 26 | 27 | rebuild: 28 | @touch $(REBUILD) # Renews the last modified date for all the files in REBUILD so that they get rebuilt 29 | -------------------------------------------------------------------------------- /Makefile_nro: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | .SUFFIXES: 3 | #--------------------------------------------------------------------------------- 4 | 5 | ifeq ($(strip $(DEVKITPRO)),) 6 | $(error "Please set DEVKITPRO in your environment. export DEVKITPRO=/devkitpro") 7 | endif 8 | 9 | TOPDIR ?= $(CURDIR) 10 | include $(DEVKITPRO)/libnx/switch_rules 11 | 12 | #--------------------------------------------------------------------------------- 13 | # TARGET is the name of the output 14 | # BUILD is the directory where object files & intermediate files will be placed 15 | # SOURCES is a list of directories containing source code 16 | # DATA is a list of directories containing data files 17 | # INCLUDES is a list of directories containing header files 18 | # EXEFS_SRC is the optional input directory containing data copied into exefs, if anything this normally should only contain "main.npdm". 19 | # ROMFS is the directory containing data to be added to RomFS, relative to the Makefile (Optional) 20 | # 21 | # NO_ICON: if set to anything, do not use icon. 22 | # NO_NACP: if set to anything, no .nacp file is generated. 23 | # APP_TITLE is the name of the app stored in the .nacp file (Optional) 24 | # APP_AUTHOR is the author of the app stored in the .nacp file (Optional) 25 | # APP_VERSION is the version of the app stored in the .nacp file (Optional) 26 | # APP_TITLEID is the titleID of the app stored in the .nacp file (Optional) 27 | # ICON is the filename of the icon (.jpg), relative to the project folder. 28 | # If not set, it attempts to use one of the following (in this order): 29 | # - .jpg 30 | # - icon.jpg 31 | # - /default_icon.jpg 32 | #--------------------------------------------------------------------------------- 33 | TARGET := $(notdir $(CURDIR)) 34 | BUILD := build 35 | SOURCES := source 36 | DATA := data 37 | INCLUDES := include 38 | EXEFS_SRC := exefs_src 39 | #ROMFS := romfs 40 | 41 | #--------------------------------------------------------------------------------- 42 | # options for code generation 43 | #--------------------------------------------------------------------------------- 44 | ARCH := -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE 45 | 46 | CFLAGS := -g -Wall -O2 -ffunction-sections -lcurl -lm \ 47 | $(ARCH) $(DEFINES) 48 | 49 | CFLAGS += $(INCLUDE) -D__SWITCH__ 50 | 51 | CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions 52 | 53 | ASFLAGS := -g $(ARCH) 54 | LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) 55 | 56 | LIBS := -lcurl -lmbedtls -lmbedx509 -lmbedcrypto -lnx -lz -lm 57 | 58 | #--------------------------------------------------------------------------------- 59 | # list of directories containing libraries, this must be the top level containing 60 | # include and lib 61 | #--------------------------------------------------------------------------------- 62 | LIBDIRS := $(PORTLIBS) $(LIBNX) 63 | 64 | 65 | #--------------------------------------------------------------------------------- 66 | # no real need to edit anything past this point unless you need to add additional 67 | # rules for different file extensions 68 | #--------------------------------------------------------------------------------- 69 | ifneq ($(BUILD),$(notdir $(CURDIR))) 70 | #--------------------------------------------------------------------------------- 71 | 72 | export OUTPUT := $(CURDIR)/$(TARGET) 73 | export TOPDIR := $(CURDIR) 74 | 75 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 76 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) 77 | 78 | export DEPSDIR := $(CURDIR)/$(BUILD) 79 | 80 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 81 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 82 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 83 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 84 | 85 | #--------------------------------------------------------------------------------- 86 | # use CXX for linking C++ projects, CC for standard C 87 | #--------------------------------------------------------------------------------- 88 | ifeq ($(strip $(CPPFILES)),) 89 | #--------------------------------------------------------------------------------- 90 | export LD := $(CC) 91 | #--------------------------------------------------------------------------------- 92 | else 93 | #--------------------------------------------------------------------------------- 94 | export LD := $(CXX) 95 | #--------------------------------------------------------------------------------- 96 | endif 97 | #--------------------------------------------------------------------------------- 98 | 99 | 100 | export OFILES_BIN := $(addsuffix .o,$(BINFILES)) 101 | export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) 102 | export OFILES := $(OFILES_BIN) $(OFILES_SRC) 103 | export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES))) 104 | 105 | export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ 106 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 107 | -I$(CURDIR)/$(BUILD) 108 | 109 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 110 | 111 | export BUILD_EXEFS_SRC := $(TOPDIR)/$(EXEFS_SRC) 112 | 113 | ifeq ($(strip $(ICON)),) 114 | icons := $(wildcard *.jpg) 115 | ifneq (,$(findstring $(TARGET).jpg,$(icons))) 116 | export APP_ICON := $(TOPDIR)/$(TARGET).jpg 117 | else 118 | ifneq (,$(findstring icon.jpg,$(icons))) 119 | export APP_ICON := $(TOPDIR)/icon.jpg 120 | endif 121 | endif 122 | else 123 | export APP_ICON := $(TOPDIR)/$(ICON) 124 | endif 125 | 126 | ifeq ($(strip $(NO_ICON)),) 127 | export NROFLAGS += --icon=$(APP_ICON) 128 | endif 129 | 130 | ifeq ($(strip $(NO_NACP)),) 131 | export NROFLAGS += --nacp=$(CURDIR)/$(TARGET).nacp 132 | endif 133 | 134 | ifneq ($(APP_TITLEID),) 135 | export NACPFLAGS += --titleid=$(APP_TITLEID) 136 | endif 137 | 138 | ifneq ($(APP_AUTHOR),) 139 | export NACPFLAGS += --author=$(APP_AUTHOR) 140 | endif 141 | 142 | ifneq ($(APP_VERSION),) 143 | export NACPFLAGS += --version=$(APP_VERSION) 144 | endif 145 | 146 | ifneq ($(ROMFS),) 147 | export NROFLAGS += --romfsdir=$(CURDIR)/$(ROMFS) 148 | endif 149 | 150 | .PHONY: $(BUILD) clean all 151 | 152 | #--------------------------------------------------------------------------------- 153 | all: $(BUILD) 154 | 155 | $(BUILD): 156 | @[ -d $@ ] || mkdir -p $@ 157 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile_nro 158 | 159 | dist: all 160 | @mkdir -p release 161 | @cp $(TARGET).nro release 162 | 163 | #--------------------------------------------------------------------------------- 164 | clean: 165 | @echo clean ... 166 | @rm -fr $(BUILD) $(TARGET).pfs0 $(TARGET).nso $(TARGET).nro $(TARGET).nacp $(TARGET).elf 167 | 168 | 169 | #--------------------------------------------------------------------------------- 170 | else 171 | .PHONY: all 172 | 173 | DEPENDS := $(OFILES:.o=.d) 174 | 175 | #--------------------------------------------------------------------------------- 176 | # main targets 177 | #--------------------------------------------------------------------------------- 178 | all : $(OUTPUT).pfs0 $(OUTPUT).nro 179 | 180 | $(OUTPUT).pfs0 : $(OUTPUT).nso 181 | 182 | $(OUTPUT).nso : $(OUTPUT).elf 183 | 184 | ifeq ($(strip $(NO_NACP)),) 185 | $(OUTPUT).nro : $(OUTPUT).elf $(OUTPUT).nacp 186 | else 187 | $(OUTPUT).nro : $(OUTPUT).elf 188 | endif 189 | 190 | $(OUTPUT).elf : $(OFILES) 191 | 192 | $(OFILES_SRC) : $(HFILES_BIN) 193 | 194 | #--------------------------------------------------------------------------------- 195 | # you need a rule like this for each extension you use as binary data 196 | #--------------------------------------------------------------------------------- 197 | %.bin.o %_bin.h : %.bin 198 | #--------------------------------------------------------------------------------- 199 | @echo $(notdir $<) 200 | @$(bin2o) 201 | 202 | -include $(DEPENDS) 203 | 204 | #--------------------------------------------------------------------------------------- 205 | endif 206 | #--------------------------------------------------------------------------------------- 207 | -------------------------------------------------------------------------------- /Makefile_sys: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | .SUFFIXES: 3 | #--------------------------------------------------------------------------------- 4 | 5 | ifeq ($(strip $(DEVKITPRO)),) 6 | $(error "Please set DEVKITPRO in your environment. export DEVKITPRO=/devkitpro") 7 | endif 8 | 9 | TOPDIR ?= $(CURDIR) 10 | include $(DEVKITPRO)/libnx/switch_rules 11 | 12 | #--------------------------------------------------------------------------------- 13 | # TARGET is the name of the output 14 | # BUILD is the directory where object files & intermediate files will be placed 15 | # SOURCES is a list of directories containing source code 16 | # DATA is a list of directories containing data files 17 | # INCLUDES is a list of directories containing header files 18 | # EXEFS_SRC is the optional input directory containing data copied into exefs, if anything this normally should only contain "main.npdm". 19 | #--------------------------------------------------------------------------------- 20 | TARGET := $(notdir $(CURDIR)) 21 | BUILD := build 22 | SOURCES := source 23 | DATA := data 24 | INCLUDES := include 25 | EXEFS_SRC := exefs_src 26 | TITLE_ID := 43000000000000FF 27 | 28 | #--------------------------------------------------------------------------------- 29 | # options for code generation 30 | #--------------------------------------------------------------------------------- 31 | ARCH := -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE 32 | 33 | CFLAGS := -g -Wall -O2 -ffunction-sections \ 34 | $(ARCH) $(DEFINES) 35 | 36 | CFLAGS += $(INCLUDE) -D__SWITCH__ -D__SYS__ 37 | 38 | CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions 39 | 40 | ASFLAGS := -g $(ARCH) 41 | LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) 42 | 43 | LIBS := -lcurl -lmbedtls -lmbedx509 -lmbedcrypto -lnx -lz -lm 44 | 45 | #--------------------------------------------------------------------------------- 46 | # list of directories containing libraries, this must be the top level containing 47 | # include and lib 48 | #--------------------------------------------------------------------------------- 49 | LIBDIRS := $(PORTLIBS) $(LIBNX) 50 | 51 | 52 | #--------------------------------------------------------------------------------- 53 | # no real need to edit anything past this point unless you need to add additional 54 | # rules for different file extensions 55 | #--------------------------------------------------------------------------------- 56 | ifneq ($(BUILD),$(notdir $(CURDIR))) 57 | #--------------------------------------------------------------------------------- 58 | 59 | export OUTPUT := $(CURDIR)/$(TARGET) 60 | export TOPDIR := $(CURDIR) 61 | 62 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 63 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) 64 | 65 | export DEPSDIR := $(CURDIR)/$(BUILD) 66 | 67 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 68 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 69 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 70 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 71 | 72 | #--------------------------------------------------------------------------------- 73 | # use CXX for linking C++ projects, CC for standard C 74 | #--------------------------------------------------------------------------------- 75 | ifeq ($(strip $(CPPFILES)),) 76 | #--------------------------------------------------------------------------------- 77 | export LD := $(CC) 78 | #--------------------------------------------------------------------------------- 79 | else 80 | #--------------------------------------------------------------------------------- 81 | export LD := $(CXX) 82 | #--------------------------------------------------------------------------------- 83 | endif 84 | #--------------------------------------------------------------------------------- 85 | 86 | export OFILES_BIN := $(addsuffix .o,$(BINFILES)) 87 | export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) 88 | export OFILES := $(OFILES_BIN) $(OFILES_SRC) 89 | export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES))) 90 | 91 | export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ 92 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 93 | -I$(CURDIR)/$(BUILD) 94 | 95 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 96 | 97 | export BUILD_EXEFS_SRC := $(TOPDIR)/$(EXEFS_SRC) 98 | 99 | ifeq ($(strip $(CONFIG_JSON)),) 100 | jsons := $(wildcard *.json) 101 | ifneq (,$(findstring $(TARGET).json,$(jsons))) 102 | export APP_JSON := $(TOPDIR)/$(TARGET).json 103 | else 104 | ifneq (,$(findstring config.json,$(jsons))) 105 | export APP_JSON := $(TOPDIR)/config.json 106 | endif 107 | endif 108 | else 109 | export APP_JSON := $(TOPDIR)/$(CONFIG_JSON) 110 | endif 111 | 112 | ifeq ($(strip $(ICON)),) 113 | icons := $(wildcard *.jpg) 114 | ifneq (,$(findstring $(TARGET).jpg,$(icons))) 115 | export APP_ICON := $(TOPDIR)/$(TARGET).jpg 116 | else 117 | ifneq (,$(findstring icon.jpg,$(icons))) 118 | export APP_ICON := $(TOPDIR)/icon.jpg 119 | endif 120 | endif 121 | else 122 | export APP_ICON := $(TOPDIR)/$(ICON) 123 | endif 124 | 125 | ifneq ($(APP_TITLEID),) 126 | export NACPFLAGS += --titleid=$(APP_TITLEID) 127 | endif 128 | 129 | .PHONY: $(BUILD) clean dist all 130 | 131 | #--------------------------------------------------------------------------------- 132 | all: $(BUILD) 133 | 134 | $(BUILD): 135 | @[ -d $@ ] || mkdir -p $@ 136 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile_sys 137 | 138 | dist: all 139 | @mkdir -p $(TITLE_ID)/flags 140 | @cp $(TARGET).nsp $(TITLE_ID)/exefs.nsp 141 | @touch $(TITLE_ID)/flags/boot2.flag 142 | @zip -r $(TITLE_ID) $(TITLE_ID) 143 | @mkdir -p release 144 | @mv $(TITLE_ID).zip release 145 | @rm -rf $(TITLE_ID) 146 | 147 | #--------------------------------------------------------------------------------- 148 | clean: 149 | @echo clean ... 150 | @rm -fr $(BUILD) $(TARGET).nsp $(TARGET).nso $(TARGET).nacp $(TARGET).npdm $(TARGET).elf 151 | 152 | 153 | #--------------------------------------------------------------------------------- 154 | else 155 | .PHONY: all 156 | 157 | DEPENDS := $(OFILES:.o=.d) 158 | 159 | #--------------------------------------------------------------------------------- 160 | # main targets 161 | #--------------------------------------------------------------------------------- 162 | all : $(OUTPUT).nsp 163 | 164 | ifeq ($(strip $(APP_JSON)),) 165 | $(OUTPUT).nsp : $(OUTPUT).nso 166 | else 167 | $(OUTPUT).nsp : $(OUTPUT).nso $(OUTPUT).npdm 168 | endif 169 | 170 | $(OUTPUT).nso : $(OUTPUT).elf 171 | 172 | $(OUTPUT).elf : $(OFILES) 173 | 174 | $(OFILES_SRC) : $(HFILES_BIN) 175 | 176 | #--------------------------------------------------------------------------------- 177 | # you need a rule like this for each extension you use as binary data 178 | #--------------------------------------------------------------------------------- 179 | %.bin.o %_bin.h : %.bin 180 | #--------------------------------------------------------------------------------- 181 | @echo $(notdir $<) 182 | @$(bin2o) 183 | 184 | -include $(DEPENDS) 185 | 186 | #--------------------------------------------------------------------------------------- 187 | endif 188 | #--------------------------------------------------------------------------------------- 189 | 190 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nxsh 2 | BusyBox-like remote shell for the Nintendo Switch over telnet 3 | 4 | Switch view: 5 | 6 | ![screenshot_1](https://i.imgur.com/qBBy9M4.jpg) 7 | 8 | Remote view: 9 | 10 | ![screenshot_2](https://i.imgur.com/SaL7JNQ.png) 11 | 12 | 13 | ## Installation 14 | 15 | ### Prebuilt 16 | 17 | For a basic installation, grab the latest nxsh.nro version from the "Releases" tab above. You *can* build it from source if you so choose, in which case you should check out the section below. 18 | 19 | To make the application available at the root of your homebrew menu, simply copy the nxsh.nro file to the /switch directory of your SD card. You can do this directly, but I recommend using one of the many ftpd applications that are available on the homebrew app store. 20 | 21 | ### Building from source (Unix) 22 | 23 | If you choose to compile the application from source, clone the latest code from GitHub and build: 24 | ``` 25 | $ git clone https://github.com/Cesura/nxsh.git 26 | $ cd nxsh 27 | $ make nro 28 | ``` 29 | 30 | To build the sysmodule version, instead run: 31 | ``` 32 | $ make sys 33 | ``` 34 | 35 | To build binaries in a ready-to-release format, run: 36 | ``` 37 | $ make dist 38 | ``` 39 | 40 | I've included a Makefile for simplifying the build process, but you *will* need to have an aarch64 cross compiler installed, as well as the latest version of libnx and devkitpro. As of version 0.1.5 alpha, you'll need to link it against libcurl and zlib as well. More information on how to set up a proper build environment can be found [here](https://switchbrew.org/wiki/Setting_up_Development_Environment). 41 | 42 | ## Connecting 43 | 44 | Once started, the application will listen on port 23 for incoming connections. If the socket initializes correctly, the listen address will be displayed on your Switch's screen. Unfortunately, until multithreading is fully supported for Switch homebrew apps, the shell cannot accept more than 1 simultaneous connection. 45 | 46 | ### Linux/BSD/Mac OS 47 | 48 | First ensure that you have the "telnet" client installed on your local machine (it may or may not be bundled with your base distribution). For Mac users, I recommend installing the client via the Homebrew package manager 49 | ``` 50 | $ brew install telnet 51 | ``` 52 | 53 | From there, connecting to nxsh is as simple as: 54 | ``` 55 | $ telnet [address] 56 | ``` 57 | where address is your Switch's IP. 58 | 59 | ### Windows 60 | 61 | The built-in Windows telnet client does not play nicely with nxsh, so I recommend installing [PuTTY](https://www.putty.org/). Note that connecting via a "raw" connection instead of a "telnet" one will avoid a pesky "command not found" message upon initialization of the shell. The telnet protocol sends some garbage text as it's negotiating the connection, so if you want a clean-looking shell, ditch that and go for a raw socket. 62 | 63 | ## Usage 64 | 65 | nxsh bundles its own implementations of basic coreutils, such as (but not necessarily limited to): 66 | * cat 67 | * ls 68 | * rm 69 | * cp 70 | * mv 71 | 72 | etc. etc. 73 | 74 | For a full list of commands supported by your current version of nxsh, type "help" in the prompt. 75 | 76 | ## Scripting 77 | 78 | As of version 0.1.7 beta, nxsh supports scripting via an ECMAScript-compliant engine named duktape. You can execute scripts in the following way: 79 | ``` 80 | $ ./script_name.js 81 | ``` 82 | 83 | See examples/quadratic.js for an basic example script that works with the shell. As many of the more desirable JS features are non-standard and machine-dependent (such as file I/O), I am slowly but surely writing my own implementations of them. 84 | 85 | ## In Progress 86 | 87 | Right now, I'm working on: 88 | * Passing command line arguments to JS scripts 89 | * Smoothing out general stability of the shell 90 | * Executing other NROs from within the shell 91 | * Any other requests you'd like to throw my way 92 | 93 | ## Bugs 94 | 95 | As this is an alpha release, there are bound to be many unforeseen bugs in the software. If it segfaults or something, I take no responsibility, but I *would* be very appreciative of a little nudge in the way of a new GitHub issue pointing out your problem. ;) 96 | 97 | ## License 98 | 99 | This project is licensed under the BSD 3-clause license. 100 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nxsh", 3 | "title_id": "0x43000000000000FF", 4 | "title_id_range_min": "0x43000000000000FF", 5 | "title_id_range_max": "0x43000000000000FF", 6 | "main_thread_stack_size": "0x24000", 7 | "main_thread_priority": 49, 8 | "default_cpu_id": 3, 9 | "process_category": 0, 10 | "is_retail": true, 11 | "pool_partition": 2, 12 | "is_64_bit": true, 13 | "address_space_type": 3, 14 | "filesystem_access": { 15 | "permissions": "0xffffffffffffffff" 16 | }, 17 | "service_access": ["*"], 18 | "service_host": ["*"], 19 | "kernel_capabilities": [ 20 | { 21 | "type": "kernel_flags", 22 | "value": { 23 | "highest_thread_priority": 63, 24 | "lowest_thread_priority": 24, 25 | "lowest_cpu_id": 3, 26 | "highest_cpu_id": 3 27 | } 28 | }, 29 | { 30 | "type": "syscalls", 31 | "value": { 32 | "svcUnknown00": "0x00", 33 | "svcSetHeapSize": "0x01", 34 | "svcSetMemoryPermission": "0x02", 35 | "svcSetMemoryAttribute": "0x03", 36 | "svcMapMemory": "0x04", 37 | "svcUnmapMemory": "0x05", 38 | "svcQueryMemory": "0x06", 39 | "svcExitProcess": "0x07", 40 | "svcCreateThread": "0x08", 41 | "svcStartThread": "0x09", 42 | "svcExitThread": "0x0A", 43 | "svcSleepThread": "0x0B", 44 | "svcGetThreadPriority": "0x0C", 45 | "svcSetThreadPriority": "0x0D", 46 | "svcGetThreadCoreMask": "0x0E", 47 | "svcSetThreadCoreMask": "0x0F", 48 | "svcGetCurrentProcessorNumber": "0x10", 49 | "svcSignalEvent": "0x11", 50 | "svcClearEvent": "0x12", 51 | "svcMapSharedMemory": "0x13", 52 | "svcUnmapSharedMemory": "0x14", 53 | "svcCreateTransferMemory": "0x15", 54 | "svcCloseHandle": "0x16", 55 | "svcResetSignal": "0x17", 56 | "svcWaitSynchronization": "0x18", 57 | "svcCancelSynchronization": "0x19", 58 | "svcArbitrateLock": "0x1A", 59 | "svcArbitrateUnlock": "0x1B", 60 | "svcWaitProcessWideKeyAtomic": "0x1C", 61 | "svcSignalProcessWideKey": "0x1D", 62 | "svcGetSystemTick": "0x1E", 63 | "svcConnectToNamedPort": "0x1F", 64 | "svcSendSyncRequestLight": "0x20", 65 | "svcSendSyncRequest": "0x21", 66 | "svcSendSyncRequestWithUserBuffer": "0x22", 67 | "svcSendAsyncRequestWithUserBuffer": "0x23", 68 | "svcGetProcessId": "0x24", 69 | "svcGetThreadId": "0x25", 70 | "svcBreak": "0x26", 71 | "svcOutputDebugString": "0x27", 72 | "svcReturnFromException": "0x28", 73 | "svcGetInfo": "0x29", 74 | "svcFlushEntireDataCache": "0x2A", 75 | "svcFlushDataCache": "0x2B", 76 | "svcMapPhysicalMemory": "0x2C", 77 | "svcUnmapPhysicalMemory": "0x2D", 78 | "svcGetFutureThreadInfo": "0x2E", 79 | "svcGetLastThreadInfo": "0x2F", 80 | "svcGetResourceLimitLimitValue": "0x30", 81 | "svcGetResourceLimitCurrentValue": "0x31", 82 | "svcSetThreadActivity": "0x32", 83 | "svcGetThreadContext3": "0x33", 84 | "svcWaitForAddress": "0x34", 85 | "svcSignalToAddress": "0x35", 86 | "svcUnknown36": "0x36", 87 | "svcUnknown37": "0x37", 88 | "svcUnknown38": "0x38", 89 | "svcUnknown39": "0x39", 90 | "svcUnknown3a": "0x3A", 91 | "svcUnknown3b": "0x3B", 92 | "svcDumpInfo": "0x3C", 93 | "svcDumpInfoNew": "0x3D", 94 | "svcUnknown3e": "0x3E", 95 | "svcUnknown3f": "0x3F", 96 | "svcCreateSession": "0x40", 97 | "svcAcceptSession": "0x41", 98 | "svcReplyAndReceiveLight": "0x42", 99 | "svcReplyAndReceive": "0x43", 100 | "svcReplyAndReceiveWithUserBuffer": "0x44", 101 | "svcCreateEvent": "0x45", 102 | "svcUnknown46": "0x46", 103 | "svcUnknown47": "0x47", 104 | "svcMapPhysicalMemoryUnsafe": "0x48", 105 | "svcUnmapPhysicalMemoryUnsafe": "0x49", 106 | "svcSetUnsafeLimit": "0x4A", 107 | "svcCreateCodeMemory": "0x4B", 108 | "svcControlCodeMemory": "0x4C", 109 | "svcSleepSystem": "0x4D", 110 | "svcReadWriteRegister": "0x4E", 111 | "svcSetProcessActivity": "0x4F", 112 | "svcCreateSharedMemory": "0x50", 113 | "svcMapTransferMemory": "0x51", 114 | "svcUnmapTransferMemory": "0x52", 115 | "svcDebugActiveProcess": "0x60", 116 | "svcBreakDebugProcess": "0x61", 117 | "svcTerminateDebugProcess": "0x62", 118 | "svcGetDebugEvent": "0x63", 119 | "svcContinueDebugEvent": "0x64", 120 | "svcGetProcessList": "0x65", 121 | "svcGetThreadList": "0x66", 122 | "svcGetDebugThreadContext": "0x67", 123 | "svcSetDebugThreadContext": "0x68", 124 | "svcQueryDebugProcessMemory": "0x69", 125 | "svcReadDebugProcessMemory": "0x6A", 126 | "svcWriteDebugProcessMemory": "0x6B", 127 | "svcSetHardwareBreakPoint": "0x6C", 128 | "svcGetDebugThreadParam": "0x6D", 129 | "svcConnectToPort": "0x72", 130 | "svcSetProcessMemoryPermission": "0x73", 131 | "svcMapProcessMemory": "0x74", 132 | "svcUnmapProcessMemory": "0x75", 133 | "svcQueryProcessMemory": "0x76", 134 | "svcMapProcessCodeMemory": "0x77", 135 | "svcUnmapProcessCodeMemory": "0x78" 136 | } 137 | }, 138 | { 139 | "type": "min_kernel_version", 140 | "value": "0x0030" 141 | }, 142 | { 143 | "type": "handle_table_size", 144 | "value": 1023 145 | }, 146 | { 147 | "type": "debug_flags", 148 | "value": { 149 | "allow_debug": false, 150 | "force_debug": true 151 | } 152 | } 153 | ] 154 | } 155 | -------------------------------------------------------------------------------- /examples/quadratic.js: -------------------------------------------------------------------------------- 1 | /* 2 | This is a very basic example script that can be parsed by the 3 | built-in ECMAScript 5.1 engine (duktape). 4 | */ 5 | 6 | // 6x² + 11x - 35 = 0 7 | var a = 6; 8 | var b = 11; 9 | var c = -35; 10 | 11 | // Calculate quadratic roots 12 | var pos_root = ((-1 * b) + Math.sqrt(Math.pow(b, 2) - (4 * a * c))) / (2 * a); 13 | var neg_root = ((-1 * b) - Math.sqrt(Math.pow(b, 2) - (4 * a * c))) / (2 * a); 14 | 15 | // Write the output to a file 16 | var output = "The roots are: " + pos_root + " and " + neg_root; 17 | writeFile("roots.txt", output); 18 | 19 | // Read from the file and print 20 | print(readFile("roots.txt")); -------------------------------------------------------------------------------- /icon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cesura/nxsh/457cc49e46f46401a120edeee79a99e38a85698f/icon.jpg -------------------------------------------------------------------------------- /include/duktape.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Duktape public API for Duktape 2.3.0. 3 | * 4 | * See the API reference for documentation on call semantics. The exposed, 5 | * supported API is between the "BEGIN PUBLIC API" and "END PUBLIC API" 6 | * comments. Other parts of the header are Duktape internal and related to 7 | * e.g. platform/compiler/feature detection. 8 | * 9 | * Git commit external (external). 10 | * Git branch external. 11 | * 12 | * See Duktape AUTHORS.rst and LICENSE.txt for copyright and 13 | * licensing information. 14 | */ 15 | 16 | /* LICENSE.txt */ 17 | /* 18 | * =============== 19 | * Duktape license 20 | * =============== 21 | * 22 | * (http://opensource.org/licenses/MIT) 23 | * 24 | * Copyright (c) 2013-2018 by Duktape authors (see AUTHORS.rst) 25 | * 26 | * Permission is hereby granted, free of charge, to any person obtaining a copy 27 | * of this software and associated documentation files (the "Software"), to deal 28 | * in the Software without restriction, including without limitation the rights 29 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 30 | * copies of the Software, and to permit persons to whom the Software is 31 | * furnished to do so, subject to the following conditions: 32 | * 33 | * The above copyright notice and this permission notice shall be included in 34 | * all copies or substantial portions of the Software. 35 | * 36 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 37 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 38 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 39 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 40 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 41 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 42 | * THE SOFTWARE. 43 | */ 44 | 45 | /* AUTHORS.rst */ 46 | /* 47 | * =============== 48 | * Duktape authors 49 | * =============== 50 | * 51 | * Copyright 52 | * ========= 53 | * 54 | * Duktape copyrights are held by its authors. Each author has a copyright 55 | * to their contribution, and agrees to irrevocably license the contribution 56 | * under the Duktape ``LICENSE.txt``. 57 | * 58 | * Authors 59 | * ======= 60 | * 61 | * Please include an e-mail address, a link to your GitHub profile, or something 62 | * similar to allow your contribution to be identified accurately. 63 | * 64 | * The following people have contributed code, website contents, or Wiki contents, 65 | * and agreed to irrevocably license their contributions under the Duktape 66 | * ``LICENSE.txt`` (in order of appearance): 67 | * 68 | * * Sami Vaarala 69 | * * Niki Dobrev 70 | * * Andreas \u00d6man 71 | * * L\u00e1szl\u00f3 Lang\u00f3 72 | * * Legimet 73 | * * Karl Skomski 74 | * * Bruce Pascoe 75 | * * Ren\u00e9 Hollander 76 | * * Julien Hamaide (https://github.com/crazyjul) 77 | * * Sebastian G\u00f6tte (https://github.com/jaseg) 78 | * * Tomasz Magulski (https://github.com/magul) 79 | * * \D. Bohdan (https://github.com/dbohdan) 80 | * * Ond\u0159ej Jirman (https://github.com/megous) 81 | * * Sa\u00fal Ibarra Corretg\u00e9 82 | * * Jeremy HU 83 | * * Ole Andr\u00e9 Vadla Ravn\u00e5s (https://github.com/oleavr) 84 | * * Harold Brenes (https://github.com/harold-b) 85 | * * Oliver Crow (https://github.com/ocrow) 86 | * * Jakub Ch\u0142api\u0144ski (https://github.com/jchlapinski) 87 | * * Brett Vickers (https://github.com/beevik) 88 | * * Dominik Okwieka (https://github.com/okitec) 89 | * * Remko Tron\u00e7on (https://el-tramo.be) 90 | * * Romero Malaquias (rbsm@ic.ufal.br) 91 | * * Michael Drake 92 | * * Steven Don (https://github.com/shdon) 93 | * * Simon Stone (https://github.com/sstone1) 94 | * * \J. McC. (https://github.com/jmhmccr) 95 | * * Jakub Nowakowski (https://github.com/jimvonmoon) 96 | * * Tommy Nguyen (https://github.com/tn0502) 97 | * * Fabrice Fontaine (https://github.com/ffontaine) 98 | * * Christopher Hiller (https://github.com/boneskull) 99 | * * Gonzalo Diethelm (https://github.com/gonzus) 100 | * * Michal Kasperek (https://github.com/michalkas) 101 | * * Andrew Janke (https://github.com/apjanke) 102 | * * Steve Fan (https://github.com/stevefan1999) 103 | * 104 | * Other contributions 105 | * =================== 106 | * 107 | * The following people have contributed something other than code (e.g. reported 108 | * bugs, provided ideas, etc; roughly in order of appearance): 109 | * 110 | * * Greg Burns 111 | * * Anthony Rabine 112 | * * Carlos Costa 113 | * * Aur\u00e9lien Bouilland 114 | * * Preet Desai (Pris Matic) 115 | * * judofyr (http://www.reddit.com/user/judofyr) 116 | * * Jason Woofenden 117 | * * Micha\u0142 Przyby\u015b 118 | * * Anthony Howe 119 | * * Conrad Pankoff 120 | * * Jim Schimpf 121 | * * Rajaran Gaunker (https://github.com/zimbabao) 122 | * * Andreas \u00d6man 123 | * * Doug Sanden 124 | * * Josh Engebretson (https://github.com/JoshEngebretson) 125 | * * Remo Eichenberger (https://github.com/remoe) 126 | * * Mamod Mehyar (https://github.com/mamod) 127 | * * David Demelier (https://github.com/markand) 128 | * * Tim Caswell (https://github.com/creationix) 129 | * * Mitchell Blank Jr (https://github.com/mitchblank) 130 | * * https://github.com/yushli 131 | * * Seo Sanghyeon (https://github.com/sanxiyn) 132 | * * Han ChoongWoo (https://github.com/tunz) 133 | * * Joshua Peek (https://github.com/josh) 134 | * * Bruce E. Pascoe (https://github.com/fatcerberus) 135 | * * https://github.com/Kelledin 136 | * * https://github.com/sstruchtrup 137 | * * Michael Drake (https://github.com/tlsa) 138 | * * https://github.com/chris-y 139 | * * Laurent Zubiaur (https://github.com/lzubiaur) 140 | * * Neil Kolban (https://github.com/nkolban) 141 | * * Wilhelm Wanecek (https://github.com/wanecek) 142 | * * Andrew Janke (https://github.com/apjanke) 143 | * 144 | * If you are accidentally missing from this list, send me an e-mail 145 | * (``sami.vaarala@iki.fi``) and I'll fix the omission. 146 | */ 147 | 148 | #if !defined(DUKTAPE_H_INCLUDED) 149 | #define DUKTAPE_H_INCLUDED 150 | 151 | #define DUK_SINGLE_FILE 152 | 153 | /* 154 | * BEGIN PUBLIC API 155 | */ 156 | 157 | /* 158 | * Version and Git commit identification 159 | */ 160 | 161 | /* Duktape version, (major * 10000) + (minor * 100) + patch. Allows C code 162 | * to #if (DUK_VERSION >= NNN) against Duktape API version. The same value 163 | * is also available to ECMAScript code in Duktape.version. Unofficial 164 | * development snapshots have 99 for patch level (e.g. 0.10.99 would be a 165 | * development version after 0.10.0 but before the next official release). 166 | */ 167 | #define DUK_VERSION 20300L 168 | 169 | /* Git commit, describe, and branch for Duktape build. Useful for 170 | * non-official snapshot builds so that application code can easily log 171 | * which Duktape snapshot was used. Not available in the ECMAScript 172 | * environment. 173 | */ 174 | #define DUK_GIT_COMMIT "external" 175 | #define DUK_GIT_DESCRIBE "external" 176 | #define DUK_GIT_BRANCH "external" 177 | 178 | /* External duk_config.h provides platform/compiler/OS dependent 179 | * typedefs and macros, and DUK_USE_xxx config options so that 180 | * the rest of Duktape doesn't need to do any feature detection. 181 | * DUK_VERSION is defined before including so that configuration 182 | * snippets can react to it. 183 | */ 184 | #include "duk_config.h" 185 | 186 | /* 187 | * Avoid C++ name mangling 188 | */ 189 | 190 | #if defined(__cplusplus) 191 | extern "C" { 192 | #endif 193 | 194 | /* 195 | * Some defines forwarded from feature detection 196 | */ 197 | 198 | #undef DUK_API_VARIADIC_MACROS 199 | #if defined(DUK_USE_VARIADIC_MACROS) 200 | #define DUK_API_VARIADIC_MACROS 201 | #endif 202 | 203 | #define DUK_API_NORETURN(decl) DUK_NORETURN(decl) 204 | 205 | /* 206 | * Public API specific typedefs 207 | * 208 | * Many types are wrapped by Duktape for portability to rare platforms 209 | * where e.g. 'int' is a 16-bit type. See practical typing discussion 210 | * in Duktape web documentation. 211 | */ 212 | 213 | struct duk_thread_state; 214 | struct duk_memory_functions; 215 | struct duk_function_list_entry; 216 | struct duk_number_list_entry; 217 | struct duk_time_components; 218 | 219 | /* duk_context is now defined in duk_config.h because it may also be 220 | * referenced there by prototypes. 221 | */ 222 | typedef struct duk_thread_state duk_thread_state; 223 | typedef struct duk_memory_functions duk_memory_functions; 224 | typedef struct duk_function_list_entry duk_function_list_entry; 225 | typedef struct duk_number_list_entry duk_number_list_entry; 226 | typedef struct duk_time_components duk_time_components; 227 | 228 | typedef duk_ret_t (*duk_c_function)(duk_context *ctx); 229 | typedef void *(*duk_alloc_function) (void *udata, duk_size_t size); 230 | typedef void *(*duk_realloc_function) (void *udata, void *ptr, duk_size_t size); 231 | typedef void (*duk_free_function) (void *udata, void *ptr); 232 | typedef void (*duk_fatal_function) (void *udata, const char *msg); 233 | typedef void (*duk_decode_char_function) (void *udata, duk_codepoint_t codepoint); 234 | typedef duk_codepoint_t (*duk_map_char_function) (void *udata, duk_codepoint_t codepoint); 235 | typedef duk_ret_t (*duk_safe_call_function) (duk_context *ctx, void *udata); 236 | typedef duk_size_t (*duk_debug_read_function) (void *udata, char *buffer, duk_size_t length); 237 | typedef duk_size_t (*duk_debug_write_function) (void *udata, const char *buffer, duk_size_t length); 238 | typedef duk_size_t (*duk_debug_peek_function) (void *udata); 239 | typedef void (*duk_debug_read_flush_function) (void *udata); 240 | typedef void (*duk_debug_write_flush_function) (void *udata); 241 | typedef duk_idx_t (*duk_debug_request_function) (duk_context *ctx, void *udata, duk_idx_t nvalues); 242 | typedef void (*duk_debug_detached_function) (duk_context *ctx, void *udata); 243 | 244 | struct duk_thread_state { 245 | /* XXX: Enough space to hold internal suspend/resume structure. 246 | * This is rather awkward and to be fixed when the internal 247 | * structure is visible for the public API header. 248 | */ 249 | char data[128]; 250 | }; 251 | 252 | struct duk_memory_functions { 253 | duk_alloc_function alloc_func; 254 | duk_realloc_function realloc_func; 255 | duk_free_function free_func; 256 | void *udata; 257 | }; 258 | 259 | struct duk_function_list_entry { 260 | const char *key; 261 | duk_c_function value; 262 | duk_idx_t nargs; 263 | }; 264 | 265 | struct duk_number_list_entry { 266 | const char *key; 267 | duk_double_t value; 268 | }; 269 | 270 | struct duk_time_components { 271 | duk_double_t year; /* year, e.g. 2016, ECMAScript year range */ 272 | duk_double_t month; /* month: 1-12 */ 273 | duk_double_t day; /* day: 1-31 */ 274 | duk_double_t hours; /* hour: 0-59 */ 275 | duk_double_t minutes; /* minute: 0-59 */ 276 | duk_double_t seconds; /* second: 0-59 (in POSIX time no leap second) */ 277 | duk_double_t milliseconds; /* may contain sub-millisecond fractions */ 278 | duk_double_t weekday; /* weekday: 0-6, 0=Sunday, 1=Monday, ..., 6=Saturday */ 279 | }; 280 | 281 | /* 282 | * Constants 283 | */ 284 | 285 | /* Duktape debug protocol version used by this build. */ 286 | #define DUK_DEBUG_PROTOCOL_VERSION 2 287 | 288 | /* Used to represent invalid index; if caller uses this without checking, 289 | * this index will map to a non-existent stack entry. Also used in some 290 | * API calls as a marker to denote "no value". 291 | */ 292 | #define DUK_INVALID_INDEX DUK_IDX_MIN 293 | 294 | /* Indicates that a native function does not have a fixed number of args, 295 | * and the argument stack should not be capped/extended at all. 296 | */ 297 | #define DUK_VARARGS ((duk_int_t) (-1)) 298 | 299 | /* Number of value stack entries (in addition to actual call arguments) 300 | * guaranteed to be allocated on entry to a Duktape/C function. 301 | */ 302 | #define DUK_API_ENTRY_STACK 64U 303 | 304 | /* Value types, used by e.g. duk_get_type() */ 305 | #define DUK_TYPE_MIN 0U 306 | #define DUK_TYPE_NONE 0U /* no value, e.g. invalid index */ 307 | #define DUK_TYPE_UNDEFINED 1U /* ECMAScript undefined */ 308 | #define DUK_TYPE_NULL 2U /* ECMAScript null */ 309 | #define DUK_TYPE_BOOLEAN 3U /* ECMAScript boolean: 0 or 1 */ 310 | #define DUK_TYPE_NUMBER 4U /* ECMAScript number: double */ 311 | #define DUK_TYPE_STRING 5U /* ECMAScript string: CESU-8 / extended UTF-8 encoded */ 312 | #define DUK_TYPE_OBJECT 6U /* ECMAScript object: includes objects, arrays, functions, threads */ 313 | #define DUK_TYPE_BUFFER 7U /* fixed or dynamic, garbage collected byte buffer */ 314 | #define DUK_TYPE_POINTER 8U /* raw void pointer */ 315 | #define DUK_TYPE_LIGHTFUNC 9U /* lightweight function pointer */ 316 | #define DUK_TYPE_MAX 9U 317 | 318 | /* Value mask types, used by e.g. duk_get_type_mask() */ 319 | #define DUK_TYPE_MASK_NONE (1U << DUK_TYPE_NONE) 320 | #define DUK_TYPE_MASK_UNDEFINED (1U << DUK_TYPE_UNDEFINED) 321 | #define DUK_TYPE_MASK_NULL (1U << DUK_TYPE_NULL) 322 | #define DUK_TYPE_MASK_BOOLEAN (1U << DUK_TYPE_BOOLEAN) 323 | #define DUK_TYPE_MASK_NUMBER (1U << DUK_TYPE_NUMBER) 324 | #define DUK_TYPE_MASK_STRING (1U << DUK_TYPE_STRING) 325 | #define DUK_TYPE_MASK_OBJECT (1U << DUK_TYPE_OBJECT) 326 | #define DUK_TYPE_MASK_BUFFER (1U << DUK_TYPE_BUFFER) 327 | #define DUK_TYPE_MASK_POINTER (1U << DUK_TYPE_POINTER) 328 | #define DUK_TYPE_MASK_LIGHTFUNC (1U << DUK_TYPE_LIGHTFUNC) 329 | #define DUK_TYPE_MASK_THROW (1U << 10) /* internal flag value: throw if mask doesn't match */ 330 | #define DUK_TYPE_MASK_PROMOTE (1U << 11) /* internal flag value: promote to object if mask matches */ 331 | 332 | /* Coercion hints */ 333 | #define DUK_HINT_NONE 0 /* prefer number, unless input is a Date, in which 334 | * case prefer string (E5 Section 8.12.8) 335 | */ 336 | #define DUK_HINT_STRING 1 /* prefer string */ 337 | #define DUK_HINT_NUMBER 2 /* prefer number */ 338 | 339 | /* Enumeration flags for duk_enum() */ 340 | #define DUK_ENUM_INCLUDE_NONENUMERABLE (1U << 0) /* enumerate non-numerable properties in addition to enumerable */ 341 | #define DUK_ENUM_INCLUDE_HIDDEN (1U << 1) /* enumerate hidden symbols too (in Duktape 1.x called internal properties) */ 342 | #define DUK_ENUM_INCLUDE_SYMBOLS (1U << 2) /* enumerate symbols */ 343 | #define DUK_ENUM_EXCLUDE_STRINGS (1U << 3) /* exclude strings */ 344 | #define DUK_ENUM_OWN_PROPERTIES_ONLY (1U << 4) /* don't walk prototype chain, only check own properties */ 345 | #define DUK_ENUM_ARRAY_INDICES_ONLY (1U << 5) /* only enumerate array indices */ 346 | /* XXX: misleading name */ 347 | #define DUK_ENUM_SORT_ARRAY_INDICES (1U << 6) /* sort array indices (applied to full enumeration result, including inherited array indices); XXX: misleading name */ 348 | #define DUK_ENUM_NO_PROXY_BEHAVIOR (1U << 7) /* enumerate a proxy object itself without invoking proxy behavior */ 349 | 350 | /* Compilation flags for duk_compile() and duk_eval() */ 351 | /* DUK_COMPILE_xxx bits 0-2 are reserved for an internal 'nargs' argument. 352 | */ 353 | #define DUK_COMPILE_EVAL (1U << 3) /* compile eval code (instead of global code) */ 354 | #define DUK_COMPILE_FUNCTION (1U << 4) /* compile function code (instead of global code) */ 355 | #define DUK_COMPILE_STRICT (1U << 5) /* use strict (outer) context for global, eval, or function code */ 356 | #define DUK_COMPILE_SHEBANG (1U << 6) /* allow shebang ('#! ...') comment on first line of source */ 357 | #define DUK_COMPILE_SAFE (1U << 7) /* (internal) catch compilation errors */ 358 | #define DUK_COMPILE_NORESULT (1U << 8) /* (internal) omit eval result */ 359 | #define DUK_COMPILE_NOSOURCE (1U << 9) /* (internal) no source string on stack */ 360 | #define DUK_COMPILE_STRLEN (1U << 10) /* (internal) take strlen() of src_buffer (avoids double evaluation in macro) */ 361 | #define DUK_COMPILE_NOFILENAME (1U << 11) /* (internal) no filename on stack */ 362 | #define DUK_COMPILE_FUNCEXPR (1U << 12) /* (internal) source is a function expression (used for Function constructor) */ 363 | 364 | /* Flags for duk_def_prop() and its variants; base flags + a lot of convenience shorthands */ 365 | #define DUK_DEFPROP_WRITABLE (1U << 0) /* set writable (effective if DUK_DEFPROP_HAVE_WRITABLE set) */ 366 | #define DUK_DEFPROP_ENUMERABLE (1U << 1) /* set enumerable (effective if DUK_DEFPROP_HAVE_ENUMERABLE set) */ 367 | #define DUK_DEFPROP_CONFIGURABLE (1U << 2) /* set configurable (effective if DUK_DEFPROP_HAVE_CONFIGURABLE set) */ 368 | #define DUK_DEFPROP_HAVE_WRITABLE (1U << 3) /* set/clear writable */ 369 | #define DUK_DEFPROP_HAVE_ENUMERABLE (1U << 4) /* set/clear enumerable */ 370 | #define DUK_DEFPROP_HAVE_CONFIGURABLE (1U << 5) /* set/clear configurable */ 371 | #define DUK_DEFPROP_HAVE_VALUE (1U << 6) /* set value (given on value stack) */ 372 | #define DUK_DEFPROP_HAVE_GETTER (1U << 7) /* set getter (given on value stack) */ 373 | #define DUK_DEFPROP_HAVE_SETTER (1U << 8) /* set setter (given on value stack) */ 374 | #define DUK_DEFPROP_FORCE (1U << 9) /* force change if possible, may still fail for e.g. virtual properties */ 375 | #define DUK_DEFPROP_SET_WRITABLE (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_WRITABLE) 376 | #define DUK_DEFPROP_CLEAR_WRITABLE DUK_DEFPROP_HAVE_WRITABLE 377 | #define DUK_DEFPROP_SET_ENUMERABLE (DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE) 378 | #define DUK_DEFPROP_CLEAR_ENUMERABLE DUK_DEFPROP_HAVE_ENUMERABLE 379 | #define DUK_DEFPROP_SET_CONFIGURABLE (DUK_DEFPROP_HAVE_CONFIGURABLE | DUK_DEFPROP_CONFIGURABLE) 380 | #define DUK_DEFPROP_CLEAR_CONFIGURABLE DUK_DEFPROP_HAVE_CONFIGURABLE 381 | #define DUK_DEFPROP_W DUK_DEFPROP_WRITABLE 382 | #define DUK_DEFPROP_E DUK_DEFPROP_ENUMERABLE 383 | #define DUK_DEFPROP_C DUK_DEFPROP_CONFIGURABLE 384 | #define DUK_DEFPROP_WE (DUK_DEFPROP_WRITABLE | DUK_DEFPROP_ENUMERABLE) 385 | #define DUK_DEFPROP_WC (DUK_DEFPROP_WRITABLE | DUK_DEFPROP_CONFIGURABLE) 386 | #define DUK_DEFPROP_WEC (DUK_DEFPROP_WRITABLE | DUK_DEFPROP_ENUMERABLE | DUK_DEFPROP_CONFIGURABLE) 387 | #define DUK_DEFPROP_HAVE_W DUK_DEFPROP_HAVE_WRITABLE 388 | #define DUK_DEFPROP_HAVE_E DUK_DEFPROP_HAVE_ENUMERABLE 389 | #define DUK_DEFPROP_HAVE_C DUK_DEFPROP_HAVE_CONFIGURABLE 390 | #define DUK_DEFPROP_HAVE_WE (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE) 391 | #define DUK_DEFPROP_HAVE_WC (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_CONFIGURABLE) 392 | #define DUK_DEFPROP_HAVE_WEC (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_HAVE_CONFIGURABLE) 393 | #define DUK_DEFPROP_SET_W DUK_DEFPROP_SET_WRITABLE 394 | #define DUK_DEFPROP_SET_E DUK_DEFPROP_SET_ENUMERABLE 395 | #define DUK_DEFPROP_SET_C DUK_DEFPROP_SET_CONFIGURABLE 396 | #define DUK_DEFPROP_SET_WE (DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_ENUMERABLE) 397 | #define DUK_DEFPROP_SET_WC (DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_CONFIGURABLE) 398 | #define DUK_DEFPROP_SET_WEC (DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_ENUMERABLE | DUK_DEFPROP_SET_CONFIGURABLE) 399 | #define DUK_DEFPROP_CLEAR_W DUK_DEFPROP_CLEAR_WRITABLE 400 | #define DUK_DEFPROP_CLEAR_E DUK_DEFPROP_CLEAR_ENUMERABLE 401 | #define DUK_DEFPROP_CLEAR_C DUK_DEFPROP_CLEAR_CONFIGURABLE 402 | #define DUK_DEFPROP_CLEAR_WE (DUK_DEFPROP_CLEAR_WRITABLE | DUK_DEFPROP_CLEAR_ENUMERABLE) 403 | #define DUK_DEFPROP_CLEAR_WC (DUK_DEFPROP_CLEAR_WRITABLE | DUK_DEFPROP_CLEAR_CONFIGURABLE) 404 | #define DUK_DEFPROP_CLEAR_WEC (DUK_DEFPROP_CLEAR_WRITABLE | DUK_DEFPROP_CLEAR_ENUMERABLE | DUK_DEFPROP_CLEAR_CONFIGURABLE) 405 | #define DUK_DEFPROP_ATTR_W (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_W) 406 | #define DUK_DEFPROP_ATTR_E (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_E) 407 | #define DUK_DEFPROP_ATTR_C (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_C) 408 | #define DUK_DEFPROP_ATTR_WE (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_WE) 409 | #define DUK_DEFPROP_ATTR_WC (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_WC) 410 | #define DUK_DEFPROP_ATTR_WEC (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_WEC) 411 | 412 | /* Flags for duk_push_thread_raw() */ 413 | #define DUK_THREAD_NEW_GLOBAL_ENV (1U << 0) /* create a new global environment */ 414 | 415 | /* Flags for duk_gc() */ 416 | #define DUK_GC_COMPACT (1U << 0) /* compact heap objects */ 417 | 418 | /* Error codes (must be 8 bits at most, see duk_error.h) */ 419 | #define DUK_ERR_NONE 0 /* no error (e.g. from duk_get_error_code()) */ 420 | #define DUK_ERR_ERROR 1 /* Error */ 421 | #define DUK_ERR_EVAL_ERROR 2 /* EvalError */ 422 | #define DUK_ERR_RANGE_ERROR 3 /* RangeError */ 423 | #define DUK_ERR_REFERENCE_ERROR 4 /* ReferenceError */ 424 | #define DUK_ERR_SYNTAX_ERROR 5 /* SyntaxError */ 425 | #define DUK_ERR_TYPE_ERROR 6 /* TypeError */ 426 | #define DUK_ERR_URI_ERROR 7 /* URIError */ 427 | 428 | /* Return codes for C functions (shortcut for throwing an error) */ 429 | #define DUK_RET_ERROR (-DUK_ERR_ERROR) 430 | #define DUK_RET_EVAL_ERROR (-DUK_ERR_EVAL_ERROR) 431 | #define DUK_RET_RANGE_ERROR (-DUK_ERR_RANGE_ERROR) 432 | #define DUK_RET_REFERENCE_ERROR (-DUK_ERR_REFERENCE_ERROR) 433 | #define DUK_RET_SYNTAX_ERROR (-DUK_ERR_SYNTAX_ERROR) 434 | #define DUK_RET_TYPE_ERROR (-DUK_ERR_TYPE_ERROR) 435 | #define DUK_RET_URI_ERROR (-DUK_ERR_URI_ERROR) 436 | 437 | /* Return codes for protected calls (duk_safe_call(), duk_pcall()) */ 438 | #define DUK_EXEC_SUCCESS 0 439 | #define DUK_EXEC_ERROR 1 440 | 441 | /* Debug levels for DUK_USE_DEBUG_WRITE(). */ 442 | #define DUK_LEVEL_DEBUG 0 443 | #define DUK_LEVEL_DDEBUG 1 444 | #define DUK_LEVEL_DDDEBUG 2 445 | 446 | /* 447 | * Macros to create Symbols as C statically constructed strings. 448 | * 449 | * Call e.g. as DUK_HIDDEN_SYMBOL("myProperty") <=> ("\xFF" "myProperty"). 450 | * Local symbols have a unique suffix, caller should take care to avoid 451 | * conflicting with the Duktape internal representation by e.g. prepending 452 | * a '!' character: DUK_LOCAL_SYMBOL("myLocal", "!123"). 453 | * 454 | * Note that these can only be used for string constants, not dynamically 455 | * created strings. 456 | */ 457 | 458 | #define DUK_HIDDEN_SYMBOL(x) ("\xFF" x) 459 | #define DUK_GLOBAL_SYMBOL(x) ("\x80" x) 460 | #define DUK_LOCAL_SYMBOL(x,uniq) ("\x81" x "\xff" uniq) 461 | #define DUK_WELLKNOWN_SYMBOL(x) ("\x81" x "\xff") 462 | 463 | /* 464 | * If no variadic macros, __FILE__ and __LINE__ are passed through globals 465 | * which is ugly and not thread safe. 466 | */ 467 | 468 | #if !defined(DUK_API_VARIADIC_MACROS) 469 | DUK_EXTERNAL_DECL const char *duk_api_global_filename; 470 | DUK_EXTERNAL_DECL duk_int_t duk_api_global_line; 471 | #endif 472 | 473 | /* 474 | * Context management 475 | */ 476 | 477 | DUK_EXTERNAL_DECL 478 | duk_context *duk_create_heap(duk_alloc_function alloc_func, 479 | duk_realloc_function realloc_func, 480 | duk_free_function free_func, 481 | void *heap_udata, 482 | duk_fatal_function fatal_handler); 483 | DUK_EXTERNAL_DECL void duk_destroy_heap(duk_context *ctx); 484 | 485 | DUK_EXTERNAL_DECL void duk_suspend(duk_context *ctx, duk_thread_state *state); 486 | DUK_EXTERNAL_DECL void duk_resume(duk_context *ctx, const duk_thread_state *state); 487 | 488 | #define duk_create_heap_default() \ 489 | duk_create_heap(NULL, NULL, NULL, NULL, NULL) 490 | 491 | /* 492 | * Memory management 493 | * 494 | * Raw functions have no side effects (cannot trigger GC). 495 | */ 496 | 497 | DUK_EXTERNAL_DECL void *duk_alloc_raw(duk_context *ctx, duk_size_t size); 498 | DUK_EXTERNAL_DECL void duk_free_raw(duk_context *ctx, void *ptr); 499 | DUK_EXTERNAL_DECL void *duk_realloc_raw(duk_context *ctx, void *ptr, duk_size_t size); 500 | DUK_EXTERNAL_DECL void *duk_alloc(duk_context *ctx, duk_size_t size); 501 | DUK_EXTERNAL_DECL void duk_free(duk_context *ctx, void *ptr); 502 | DUK_EXTERNAL_DECL void *duk_realloc(duk_context *ctx, void *ptr, duk_size_t size); 503 | DUK_EXTERNAL_DECL void duk_get_memory_functions(duk_context *ctx, duk_memory_functions *out_funcs); 504 | DUK_EXTERNAL_DECL void duk_gc(duk_context *ctx, duk_uint_t flags); 505 | 506 | /* 507 | * Error handling 508 | */ 509 | 510 | DUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_throw_raw(duk_context *ctx)); 511 | #define duk_throw(ctx) \ 512 | (duk_throw_raw((ctx)), (duk_ret_t) 0) 513 | DUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_fatal_raw(duk_context *ctx, const char *err_msg)); 514 | #define duk_fatal(ctx,err_msg) \ 515 | (duk_fatal_raw((ctx), (err_msg)), (duk_ret_t) 0) 516 | DUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_error_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...)); 517 | 518 | #if defined(DUK_API_VARIADIC_MACROS) 519 | #define duk_error(ctx,err_code,...) \ 520 | (duk_error_raw((ctx), (duk_errcode_t) (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0) 521 | #define duk_generic_error(ctx,...) \ 522 | (duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0) 523 | #define duk_eval_error(ctx,...) \ 524 | (duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_EVAL_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0) 525 | #define duk_range_error(ctx,...) \ 526 | (duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_RANGE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0) 527 | #define duk_reference_error(ctx,...) \ 528 | (duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_REFERENCE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0) 529 | #define duk_syntax_error(ctx,...) \ 530 | (duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_SYNTAX_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0) 531 | #define duk_type_error(ctx,...) \ 532 | (duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_TYPE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0) 533 | #define duk_uri_error(ctx,...) \ 534 | (duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_URI_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0) 535 | #else /* DUK_API_VARIADIC_MACROS */ 536 | /* For legacy compilers without variadic macros a macro hack is used to allow 537 | * variable arguments. While the macro allows "return duk_error(...)", it 538 | * will fail with e.g. "(void) duk_error(...)". The calls are noreturn but 539 | * with a return value to allow the "return duk_error(...)" idiom. This may 540 | * cause some compiler warnings, but without noreturn the generated code is 541 | * often worse. The same approach as with variadic macros (using 542 | * "(duk_error(...), 0)") won't work due to the macro hack structure. 543 | */ 544 | DUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_error_stash(duk_context *ctx, duk_errcode_t err_code, const char *fmt, ...)); 545 | DUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_generic_error_stash(duk_context *ctx, const char *fmt, ...)); 546 | DUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_eval_error_stash(duk_context *ctx, const char *fmt, ...)); 547 | DUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_range_error_stash(duk_context *ctx, const char *fmt, ...)); 548 | DUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_reference_error_stash(duk_context *ctx, const char *fmt, ...)); 549 | DUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_syntax_error_stash(duk_context *ctx, const char *fmt, ...)); 550 | DUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_type_error_stash(duk_context *ctx, const char *fmt, ...)); 551 | DUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_uri_error_stash(duk_context *ctx, const char *fmt, ...)); 552 | #define duk_error \ 553 | (duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \ 554 | duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \ 555 | duk_error_stash) /* last value is func pointer, arguments follow in parens */ 556 | #define duk_generic_error \ 557 | (duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \ 558 | duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \ 559 | duk_generic_error_stash) 560 | #define duk_eval_error \ 561 | (duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \ 562 | duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \ 563 | duk_eval_error_stash) 564 | #define duk_range_error \ 565 | (duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \ 566 | duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \ 567 | duk_range_error_stash) 568 | #define duk_reference_error \ 569 | (duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \ 570 | duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \ 571 | duk_reference_error_stash) 572 | #define duk_syntax_error \ 573 | (duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \ 574 | duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \ 575 | duk_syntax_error_stash) 576 | #define duk_type_error \ 577 | (duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \ 578 | duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \ 579 | duk_type_error_stash) 580 | #define duk_uri_error \ 581 | (duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \ 582 | duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \ 583 | duk_uri_error_stash) 584 | #endif /* DUK_API_VARIADIC_MACROS */ 585 | 586 | DUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_error_va_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap)); 587 | 588 | #define duk_error_va(ctx,err_code,fmt,ap) \ 589 | (duk_error_va_raw((ctx), (duk_errcode_t) (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0) 590 | #define duk_generic_error_va(ctx,fmt,ap) \ 591 | (duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0) 592 | #define duk_eval_error_va(ctx,fmt,ap) \ 593 | (duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_EVAL_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0) 594 | #define duk_range_error_va(ctx,fmt,ap) \ 595 | (duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_RANGE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0) 596 | #define duk_reference_error_va(ctx,fmt,ap) \ 597 | (duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_REFERENCE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0) 598 | #define duk_syntax_error_va(ctx,fmt,ap) \ 599 | (duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_SYNTAX_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0) 600 | #define duk_type_error_va(ctx,fmt,ap) \ 601 | (duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_TYPE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0) 602 | #define duk_uri_error_va(ctx,fmt,ap) \ 603 | (duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_URI_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0) 604 | 605 | /* 606 | * Other state related functions 607 | */ 608 | 609 | DUK_EXTERNAL_DECL duk_bool_t duk_is_strict_call(duk_context *ctx); 610 | DUK_EXTERNAL_DECL duk_bool_t duk_is_constructor_call(duk_context *ctx); 611 | 612 | /* 613 | * Stack management 614 | */ 615 | 616 | DUK_EXTERNAL_DECL duk_idx_t duk_normalize_index(duk_context *ctx, duk_idx_t idx); 617 | DUK_EXTERNAL_DECL duk_idx_t duk_require_normalize_index(duk_context *ctx, duk_idx_t idx); 618 | DUK_EXTERNAL_DECL duk_bool_t duk_is_valid_index(duk_context *ctx, duk_idx_t idx); 619 | DUK_EXTERNAL_DECL void duk_require_valid_index(duk_context *ctx, duk_idx_t idx); 620 | 621 | DUK_EXTERNAL_DECL duk_idx_t duk_get_top(duk_context *ctx); 622 | DUK_EXTERNAL_DECL void duk_set_top(duk_context *ctx, duk_idx_t idx); 623 | DUK_EXTERNAL_DECL duk_idx_t duk_get_top_index(duk_context *ctx); 624 | DUK_EXTERNAL_DECL duk_idx_t duk_require_top_index(duk_context *ctx); 625 | 626 | /* Although extra/top could be an unsigned type here, using a signed type 627 | * makes the API more robust to calling code calculation errors or corner 628 | * cases (where caller might occasionally come up with negative values). 629 | * Negative values are treated as zero, which is better than casting them 630 | * to a large unsigned number. (This principle is used elsewhere in the 631 | * API too.) 632 | */ 633 | DUK_EXTERNAL_DECL duk_bool_t duk_check_stack(duk_context *ctx, duk_idx_t extra); 634 | DUK_EXTERNAL_DECL void duk_require_stack(duk_context *ctx, duk_idx_t extra); 635 | DUK_EXTERNAL_DECL duk_bool_t duk_check_stack_top(duk_context *ctx, duk_idx_t top); 636 | DUK_EXTERNAL_DECL void duk_require_stack_top(duk_context *ctx, duk_idx_t top); 637 | 638 | /* 639 | * Stack manipulation (other than push/pop) 640 | */ 641 | 642 | DUK_EXTERNAL_DECL void duk_swap(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2); 643 | DUK_EXTERNAL_DECL void duk_swap_top(duk_context *ctx, duk_idx_t idx); 644 | DUK_EXTERNAL_DECL void duk_dup(duk_context *ctx, duk_idx_t from_idx); 645 | DUK_EXTERNAL_DECL void duk_dup_top(duk_context *ctx); 646 | DUK_EXTERNAL_DECL void duk_insert(duk_context *ctx, duk_idx_t to_idx); 647 | DUK_EXTERNAL_DECL void duk_replace(duk_context *ctx, duk_idx_t to_idx); 648 | DUK_EXTERNAL_DECL void duk_copy(duk_context *ctx, duk_idx_t from_idx, duk_idx_t to_idx); 649 | DUK_EXTERNAL_DECL void duk_remove(duk_context *ctx, duk_idx_t idx); 650 | DUK_EXTERNAL_DECL void duk_xcopymove_raw(duk_context *to_ctx, duk_context *from_ctx, duk_idx_t count, duk_bool_t is_copy); 651 | 652 | #define duk_xmove_top(to_ctx,from_ctx,count) \ 653 | duk_xcopymove_raw((to_ctx), (from_ctx), (count), 0 /*is_copy*/) 654 | #define duk_xcopy_top(to_ctx,from_ctx,count) \ 655 | duk_xcopymove_raw((to_ctx), (from_ctx), (count), 1 /*is_copy*/) 656 | 657 | /* 658 | * Push operations 659 | * 660 | * Push functions return the absolute (relative to bottom of frame) 661 | * position of the pushed value for convenience. 662 | * 663 | * Note: duk_dup() is technically a push. 664 | */ 665 | 666 | DUK_EXTERNAL_DECL void duk_push_undefined(duk_context *ctx); 667 | DUK_EXTERNAL_DECL void duk_push_null(duk_context *ctx); 668 | DUK_EXTERNAL_DECL void duk_push_boolean(duk_context *ctx, duk_bool_t val); 669 | DUK_EXTERNAL_DECL void duk_push_true(duk_context *ctx); 670 | DUK_EXTERNAL_DECL void duk_push_false(duk_context *ctx); 671 | DUK_EXTERNAL_DECL void duk_push_number(duk_context *ctx, duk_double_t val); 672 | DUK_EXTERNAL_DECL void duk_push_nan(duk_context *ctx); 673 | DUK_EXTERNAL_DECL void duk_push_int(duk_context *ctx, duk_int_t val); 674 | DUK_EXTERNAL_DECL void duk_push_uint(duk_context *ctx, duk_uint_t val); 675 | DUK_EXTERNAL_DECL const char *duk_push_string(duk_context *ctx, const char *str); 676 | DUK_EXTERNAL_DECL const char *duk_push_lstring(duk_context *ctx, const char *str, duk_size_t len); 677 | DUK_EXTERNAL_DECL void duk_push_pointer(duk_context *ctx, void *p); 678 | DUK_EXTERNAL_DECL const char *duk_push_sprintf(duk_context *ctx, const char *fmt, ...); 679 | DUK_EXTERNAL_DECL const char *duk_push_vsprintf(duk_context *ctx, const char *fmt, va_list ap); 680 | 681 | /* duk_push_literal() may evaluate its argument (a C string literal) more than 682 | * once on purpose. When speed is preferred, sizeof() avoids an unnecessary 683 | * strlen() at runtime. Sizeof("foo") == 4, so subtract 1. The argument 684 | * must be non-NULL and should not contain internal NUL characters as the 685 | * behavior will then depend on config options. 686 | */ 687 | #if defined(DUK_USE_PREFER_SIZE) 688 | #define duk_push_literal(ctx,cstring) duk_push_string((ctx), (cstring)) 689 | #else 690 | DUK_EXTERNAL_DECL const char *duk_push_literal_raw(duk_context *ctx, const char *str, duk_size_t len); 691 | #define duk_push_literal(ctx,cstring) duk_push_literal_raw((ctx), (cstring), sizeof((cstring)) - 1U) 692 | #endif 693 | 694 | DUK_EXTERNAL_DECL void duk_push_this(duk_context *ctx); 695 | DUK_EXTERNAL_DECL void duk_push_new_target(duk_context *ctx); 696 | DUK_EXTERNAL_DECL void duk_push_current_function(duk_context *ctx); 697 | DUK_EXTERNAL_DECL void duk_push_current_thread(duk_context *ctx); 698 | DUK_EXTERNAL_DECL void duk_push_global_object(duk_context *ctx); 699 | DUK_EXTERNAL_DECL void duk_push_heap_stash(duk_context *ctx); 700 | DUK_EXTERNAL_DECL void duk_push_global_stash(duk_context *ctx); 701 | DUK_EXTERNAL_DECL void duk_push_thread_stash(duk_context *ctx, duk_context *target_ctx); 702 | 703 | DUK_EXTERNAL_DECL duk_idx_t duk_push_object(duk_context *ctx); 704 | DUK_EXTERNAL_DECL duk_idx_t duk_push_bare_object(duk_context *ctx); 705 | DUK_EXTERNAL_DECL duk_idx_t duk_push_array(duk_context *ctx); 706 | DUK_EXTERNAL_DECL duk_idx_t duk_push_c_function(duk_context *ctx, duk_c_function func, duk_idx_t nargs); 707 | DUK_EXTERNAL_DECL duk_idx_t duk_push_c_lightfunc(duk_context *ctx, duk_c_function func, duk_idx_t nargs, duk_idx_t length, duk_int_t magic); 708 | DUK_EXTERNAL_DECL duk_idx_t duk_push_thread_raw(duk_context *ctx, duk_uint_t flags); 709 | DUK_EXTERNAL_DECL duk_idx_t duk_push_proxy(duk_context *ctx, duk_uint_t proxy_flags); 710 | 711 | #define duk_push_thread(ctx) \ 712 | duk_push_thread_raw((ctx), 0 /*flags*/) 713 | 714 | #define duk_push_thread_new_globalenv(ctx) \ 715 | duk_push_thread_raw((ctx), DUK_THREAD_NEW_GLOBAL_ENV /*flags*/) 716 | 717 | DUK_EXTERNAL_DECL duk_idx_t duk_push_error_object_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...); 718 | 719 | #if defined(DUK_API_VARIADIC_MACROS) 720 | #define duk_push_error_object(ctx,err_code,...) \ 721 | duk_push_error_object_raw((ctx), (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__) 722 | #else 723 | DUK_EXTERNAL_DECL duk_idx_t duk_push_error_object_stash(duk_context *ctx, duk_errcode_t err_code, const char *fmt, ...); 724 | /* Note: parentheses are required so that the comma expression works in assignments. */ 725 | #define duk_push_error_object \ 726 | (duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \ 727 | duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \ 728 | duk_push_error_object_stash) /* last value is func pointer, arguments follow in parens */ 729 | #endif 730 | 731 | DUK_EXTERNAL_DECL duk_idx_t duk_push_error_object_va_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap); 732 | #define duk_push_error_object_va(ctx,err_code,fmt,ap) \ 733 | duk_push_error_object_va_raw((ctx), (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)) 734 | 735 | #define DUK_BUF_FLAG_DYNAMIC (1 << 0) /* internal flag: dynamic buffer */ 736 | #define DUK_BUF_FLAG_EXTERNAL (1 << 1) /* internal flag: external buffer */ 737 | #define DUK_BUF_FLAG_NOZERO (1 << 2) /* internal flag: don't zero allocated buffer */ 738 | 739 | DUK_EXTERNAL_DECL void *duk_push_buffer_raw(duk_context *ctx, duk_size_t size, duk_small_uint_t flags); 740 | 741 | #define duk_push_buffer(ctx,size,dynamic) \ 742 | duk_push_buffer_raw((ctx), (size), (dynamic) ? DUK_BUF_FLAG_DYNAMIC : 0) 743 | #define duk_push_fixed_buffer(ctx,size) \ 744 | duk_push_buffer_raw((ctx), (size), 0 /*flags*/) 745 | #define duk_push_dynamic_buffer(ctx,size) \ 746 | duk_push_buffer_raw((ctx), (size), DUK_BUF_FLAG_DYNAMIC /*flags*/) 747 | #define duk_push_external_buffer(ctx) \ 748 | ((void) duk_push_buffer_raw((ctx), 0, DUK_BUF_FLAG_DYNAMIC | DUK_BUF_FLAG_EXTERNAL)) 749 | 750 | #define DUK_BUFOBJ_ARRAYBUFFER 0 751 | #define DUK_BUFOBJ_NODEJS_BUFFER 1 752 | #define DUK_BUFOBJ_DATAVIEW 2 753 | #define DUK_BUFOBJ_INT8ARRAY 3 754 | #define DUK_BUFOBJ_UINT8ARRAY 4 755 | #define DUK_BUFOBJ_UINT8CLAMPEDARRAY 5 756 | #define DUK_BUFOBJ_INT16ARRAY 6 757 | #define DUK_BUFOBJ_UINT16ARRAY 7 758 | #define DUK_BUFOBJ_INT32ARRAY 8 759 | #define DUK_BUFOBJ_UINT32ARRAY 9 760 | #define DUK_BUFOBJ_FLOAT32ARRAY 10 761 | #define DUK_BUFOBJ_FLOAT64ARRAY 11 762 | 763 | DUK_EXTERNAL_DECL void duk_push_buffer_object(duk_context *ctx, duk_idx_t idx_buffer, duk_size_t byte_offset, duk_size_t byte_length, duk_uint_t flags); 764 | 765 | DUK_EXTERNAL_DECL duk_idx_t duk_push_heapptr(duk_context *ctx, void *ptr); 766 | 767 | /* 768 | * Pop operations 769 | */ 770 | 771 | DUK_EXTERNAL_DECL void duk_pop(duk_context *ctx); 772 | DUK_EXTERNAL_DECL void duk_pop_n(duk_context *ctx, duk_idx_t count); 773 | DUK_EXTERNAL_DECL void duk_pop_2(duk_context *ctx); 774 | DUK_EXTERNAL_DECL void duk_pop_3(duk_context *ctx); 775 | 776 | /* 777 | * Type checks 778 | * 779 | * duk_is_none(), which would indicate whether index it outside of stack, 780 | * is not needed; duk_is_valid_index() gives the same information. 781 | */ 782 | 783 | DUK_EXTERNAL_DECL duk_int_t duk_get_type(duk_context *ctx, duk_idx_t idx); 784 | DUK_EXTERNAL_DECL duk_bool_t duk_check_type(duk_context *ctx, duk_idx_t idx, duk_int_t type); 785 | DUK_EXTERNAL_DECL duk_uint_t duk_get_type_mask(duk_context *ctx, duk_idx_t idx); 786 | DUK_EXTERNAL_DECL duk_bool_t duk_check_type_mask(duk_context *ctx, duk_idx_t idx, duk_uint_t mask); 787 | 788 | DUK_EXTERNAL_DECL duk_bool_t duk_is_undefined(duk_context *ctx, duk_idx_t idx); 789 | DUK_EXTERNAL_DECL duk_bool_t duk_is_null(duk_context *ctx, duk_idx_t idx); 790 | #define duk_is_null_or_undefined(ctx, idx) \ 791 | ((duk_get_type_mask((ctx), (idx)) & (DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_UNDEFINED)) ? 1 : 0) 792 | 793 | DUK_EXTERNAL_DECL duk_bool_t duk_is_boolean(duk_context *ctx, duk_idx_t idx); 794 | DUK_EXTERNAL_DECL duk_bool_t duk_is_number(duk_context *ctx, duk_idx_t idx); 795 | DUK_EXTERNAL_DECL duk_bool_t duk_is_nan(duk_context *ctx, duk_idx_t idx); 796 | DUK_EXTERNAL_DECL duk_bool_t duk_is_string(duk_context *ctx, duk_idx_t idx); 797 | DUK_EXTERNAL_DECL duk_bool_t duk_is_object(duk_context *ctx, duk_idx_t idx); 798 | DUK_EXTERNAL_DECL duk_bool_t duk_is_buffer(duk_context *ctx, duk_idx_t idx); 799 | DUK_EXTERNAL_DECL duk_bool_t duk_is_buffer_data(duk_context *ctx, duk_idx_t idx); 800 | DUK_EXTERNAL_DECL duk_bool_t duk_is_pointer(duk_context *ctx, duk_idx_t idx); 801 | DUK_EXTERNAL_DECL duk_bool_t duk_is_lightfunc(duk_context *ctx, duk_idx_t idx); 802 | 803 | DUK_EXTERNAL_DECL duk_bool_t duk_is_symbol(duk_context *ctx, duk_idx_t idx); 804 | DUK_EXTERNAL_DECL duk_bool_t duk_is_array(duk_context *ctx, duk_idx_t idx); 805 | DUK_EXTERNAL_DECL duk_bool_t duk_is_function(duk_context *ctx, duk_idx_t idx); 806 | DUK_EXTERNAL_DECL duk_bool_t duk_is_c_function(duk_context *ctx, duk_idx_t idx); 807 | DUK_EXTERNAL_DECL duk_bool_t duk_is_ecmascript_function(duk_context *ctx, duk_idx_t idx); 808 | DUK_EXTERNAL_DECL duk_bool_t duk_is_bound_function(duk_context *ctx, duk_idx_t idx); 809 | DUK_EXTERNAL_DECL duk_bool_t duk_is_thread(duk_context *ctx, duk_idx_t idx); 810 | 811 | #define duk_is_callable(ctx,idx) \ 812 | duk_is_function((ctx), (idx)) 813 | DUK_EXTERNAL_DECL duk_bool_t duk_is_constructable(duk_context *ctx, duk_idx_t idx); 814 | 815 | DUK_EXTERNAL_DECL duk_bool_t duk_is_dynamic_buffer(duk_context *ctx, duk_idx_t idx); 816 | DUK_EXTERNAL_DECL duk_bool_t duk_is_fixed_buffer(duk_context *ctx, duk_idx_t idx); 817 | DUK_EXTERNAL_DECL duk_bool_t duk_is_external_buffer(duk_context *ctx, duk_idx_t idx); 818 | 819 | /* Buffers and lightfuncs are not considered primitive because they mimic 820 | * objects and e.g. duk_to_primitive() will coerce them instead of returning 821 | * them as is. Symbols are represented as strings internally. 822 | */ 823 | #define duk_is_primitive(ctx,idx) \ 824 | duk_check_type_mask((ctx), (idx), DUK_TYPE_MASK_UNDEFINED | \ 825 | DUK_TYPE_MASK_NULL | \ 826 | DUK_TYPE_MASK_BOOLEAN | \ 827 | DUK_TYPE_MASK_NUMBER | \ 828 | DUK_TYPE_MASK_STRING | \ 829 | DUK_TYPE_MASK_POINTER) 830 | 831 | /* Symbols are object coercible, covered by DUK_TYPE_MASK_STRING. */ 832 | #define duk_is_object_coercible(ctx,idx) \ 833 | duk_check_type_mask((ctx), (idx), DUK_TYPE_MASK_BOOLEAN | \ 834 | DUK_TYPE_MASK_NUMBER | \ 835 | DUK_TYPE_MASK_STRING | \ 836 | DUK_TYPE_MASK_OBJECT | \ 837 | DUK_TYPE_MASK_BUFFER | \ 838 | DUK_TYPE_MASK_POINTER | \ 839 | DUK_TYPE_MASK_LIGHTFUNC) 840 | 841 | DUK_EXTERNAL_DECL duk_errcode_t duk_get_error_code(duk_context *ctx, duk_idx_t idx); 842 | #define duk_is_error(ctx,idx) \ 843 | (duk_get_error_code((ctx), (idx)) != 0) 844 | #define duk_is_eval_error(ctx,idx) \ 845 | (duk_get_error_code((ctx), (idx)) == DUK_ERR_EVAL_ERROR) 846 | #define duk_is_range_error(ctx,idx) \ 847 | (duk_get_error_code((ctx), (idx)) == DUK_ERR_RANGE_ERROR) 848 | #define duk_is_reference_error(ctx,idx) \ 849 | (duk_get_error_code((ctx), (idx)) == DUK_ERR_REFERENCE_ERROR) 850 | #define duk_is_syntax_error(ctx,idx) \ 851 | (duk_get_error_code((ctx), (idx)) == DUK_ERR_SYNTAX_ERROR) 852 | #define duk_is_type_error(ctx,idx) \ 853 | (duk_get_error_code((ctx), (idx)) == DUK_ERR_TYPE_ERROR) 854 | #define duk_is_uri_error(ctx,idx) \ 855 | (duk_get_error_code((ctx), (idx)) == DUK_ERR_URI_ERROR) 856 | 857 | /* 858 | * Get operations: no coercion, returns default value for invalid 859 | * indices and invalid value types. 860 | * 861 | * duk_get_undefined() and duk_get_null() would be pointless and 862 | * are not included. 863 | */ 864 | 865 | DUK_EXTERNAL_DECL duk_bool_t duk_get_boolean(duk_context *ctx, duk_idx_t idx); 866 | DUK_EXTERNAL_DECL duk_double_t duk_get_number(duk_context *ctx, duk_idx_t idx); 867 | DUK_EXTERNAL_DECL duk_int_t duk_get_int(duk_context *ctx, duk_idx_t idx); 868 | DUK_EXTERNAL_DECL duk_uint_t duk_get_uint(duk_context *ctx, duk_idx_t idx); 869 | DUK_EXTERNAL_DECL const char *duk_get_string(duk_context *ctx, duk_idx_t idx); 870 | DUK_EXTERNAL_DECL const char *duk_get_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len); 871 | DUK_EXTERNAL_DECL void *duk_get_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size); 872 | DUK_EXTERNAL_DECL void *duk_get_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size); 873 | DUK_EXTERNAL_DECL void *duk_get_pointer(duk_context *ctx, duk_idx_t idx); 874 | DUK_EXTERNAL_DECL duk_c_function duk_get_c_function(duk_context *ctx, duk_idx_t idx); 875 | DUK_EXTERNAL_DECL duk_context *duk_get_context(duk_context *ctx, duk_idx_t idx); 876 | DUK_EXTERNAL_DECL void *duk_get_heapptr(duk_context *ctx, duk_idx_t idx); 877 | 878 | /* 879 | * Get-with-explicit default operations: like get operations but with an 880 | * explicit default value. 881 | */ 882 | 883 | DUK_EXTERNAL_DECL duk_bool_t duk_get_boolean_default(duk_context *ctx, duk_idx_t idx, duk_bool_t def_value); 884 | DUK_EXTERNAL_DECL duk_double_t duk_get_number_default(duk_context *ctx, duk_idx_t idx, duk_double_t def_value); 885 | DUK_EXTERNAL_DECL duk_int_t duk_get_int_default(duk_context *ctx, duk_idx_t idx, duk_int_t def_value); 886 | DUK_EXTERNAL_DECL duk_uint_t duk_get_uint_default(duk_context *ctx, duk_idx_t idx, duk_uint_t def_value); 887 | DUK_EXTERNAL_DECL const char *duk_get_string_default(duk_context *ctx, duk_idx_t idx, const char *def_value); 888 | DUK_EXTERNAL_DECL const char *duk_get_lstring_default(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len); 889 | DUK_EXTERNAL_DECL void *duk_get_buffer_default(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len); 890 | DUK_EXTERNAL_DECL void *duk_get_buffer_data_default(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len); 891 | DUK_EXTERNAL_DECL void *duk_get_pointer_default(duk_context *ctx, duk_idx_t idx, void *def_value); 892 | DUK_EXTERNAL_DECL duk_c_function duk_get_c_function_default(duk_context *ctx, duk_idx_t idx, duk_c_function def_value); 893 | DUK_EXTERNAL_DECL duk_context *duk_get_context_default(duk_context *ctx, duk_idx_t idx, duk_context *def_value); 894 | DUK_EXTERNAL_DECL void *duk_get_heapptr_default(duk_context *ctx, duk_idx_t idx, void *def_value); 895 | 896 | /* 897 | * Opt operations: like require operations but with an explicit default value 898 | * when value is undefined or index is invalid, null and non-matching types 899 | * cause a TypeError. 900 | */ 901 | 902 | DUK_EXTERNAL_DECL duk_bool_t duk_opt_boolean(duk_context *ctx, duk_idx_t idx, duk_bool_t def_value); 903 | DUK_EXTERNAL_DECL duk_double_t duk_opt_number(duk_context *ctx, duk_idx_t idx, duk_double_t def_value); 904 | DUK_EXTERNAL_DECL duk_int_t duk_opt_int(duk_context *ctx, duk_idx_t idx, duk_int_t def_value); 905 | DUK_EXTERNAL_DECL duk_uint_t duk_opt_uint(duk_context *ctx, duk_idx_t idx, duk_uint_t def_value); 906 | DUK_EXTERNAL_DECL const char *duk_opt_string(duk_context *ctx, duk_idx_t idx, const char *def_ptr); 907 | DUK_EXTERNAL_DECL const char *duk_opt_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len); 908 | DUK_EXTERNAL_DECL void *duk_opt_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size); 909 | DUK_EXTERNAL_DECL void *duk_opt_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size); 910 | DUK_EXTERNAL_DECL void *duk_opt_pointer(duk_context *ctx, duk_idx_t idx, void *def_value); 911 | DUK_EXTERNAL_DECL duk_c_function duk_opt_c_function(duk_context *ctx, duk_idx_t idx, duk_c_function def_value); 912 | DUK_EXTERNAL_DECL duk_context *duk_opt_context(duk_context *ctx, duk_idx_t idx, duk_context *def_value); 913 | DUK_EXTERNAL_DECL void *duk_opt_heapptr(duk_context *ctx, duk_idx_t idx, void *def_value); 914 | 915 | /* 916 | * Require operations: no coercion, throw error if index or type 917 | * is incorrect. No defaulting. 918 | */ 919 | 920 | #define duk_require_type_mask(ctx,idx,mask) \ 921 | ((void) duk_check_type_mask((ctx), (idx), (mask) | DUK_TYPE_MASK_THROW)) 922 | 923 | DUK_EXTERNAL_DECL void duk_require_undefined(duk_context *ctx, duk_idx_t idx); 924 | DUK_EXTERNAL_DECL void duk_require_null(duk_context *ctx, duk_idx_t idx); 925 | DUK_EXTERNAL_DECL duk_bool_t duk_require_boolean(duk_context *ctx, duk_idx_t idx); 926 | DUK_EXTERNAL_DECL duk_double_t duk_require_number(duk_context *ctx, duk_idx_t idx); 927 | DUK_EXTERNAL_DECL duk_int_t duk_require_int(duk_context *ctx, duk_idx_t idx); 928 | DUK_EXTERNAL_DECL duk_uint_t duk_require_uint(duk_context *ctx, duk_idx_t idx); 929 | DUK_EXTERNAL_DECL const char *duk_require_string(duk_context *ctx, duk_idx_t idx); 930 | DUK_EXTERNAL_DECL const char *duk_require_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len); 931 | DUK_EXTERNAL_DECL void duk_require_object(duk_context *ctx, duk_idx_t idx); 932 | DUK_EXTERNAL_DECL void *duk_require_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size); 933 | DUK_EXTERNAL_DECL void *duk_require_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size); 934 | DUK_EXTERNAL_DECL void *duk_require_pointer(duk_context *ctx, duk_idx_t idx); 935 | DUK_EXTERNAL_DECL duk_c_function duk_require_c_function(duk_context *ctx, duk_idx_t idx); 936 | DUK_EXTERNAL_DECL duk_context *duk_require_context(duk_context *ctx, duk_idx_t idx); 937 | DUK_EXTERNAL_DECL void duk_require_function(duk_context *ctx, duk_idx_t idx); 938 | #define duk_require_callable(ctx,idx) \ 939 | duk_require_function((ctx), (idx)) 940 | DUK_EXTERNAL_DECL void *duk_require_heapptr(duk_context *ctx, duk_idx_t idx); 941 | 942 | /* Symbols are object coercible and covered by DUK_TYPE_MASK_STRING. */ 943 | #define duk_require_object_coercible(ctx,idx) \ 944 | ((void) duk_check_type_mask((ctx), (idx), DUK_TYPE_MASK_BOOLEAN | \ 945 | DUK_TYPE_MASK_NUMBER | \ 946 | DUK_TYPE_MASK_STRING | \ 947 | DUK_TYPE_MASK_OBJECT | \ 948 | DUK_TYPE_MASK_BUFFER | \ 949 | DUK_TYPE_MASK_POINTER | \ 950 | DUK_TYPE_MASK_LIGHTFUNC | \ 951 | DUK_TYPE_MASK_THROW)) 952 | 953 | /* 954 | * Coercion operations: in-place coercion, return coerced value where 955 | * applicable. If index is invalid, throw error. Some coercions may 956 | * throw an expected error (e.g. from a toString() or valueOf() call) 957 | * or an internal error (e.g. from out of memory). 958 | */ 959 | 960 | DUK_EXTERNAL_DECL void duk_to_undefined(duk_context *ctx, duk_idx_t idx); 961 | DUK_EXTERNAL_DECL void duk_to_null(duk_context *ctx, duk_idx_t idx); 962 | DUK_EXTERNAL_DECL duk_bool_t duk_to_boolean(duk_context *ctx, duk_idx_t idx); 963 | DUK_EXTERNAL_DECL duk_double_t duk_to_number(duk_context *ctx, duk_idx_t idx); 964 | DUK_EXTERNAL_DECL duk_int_t duk_to_int(duk_context *ctx, duk_idx_t idx); 965 | DUK_EXTERNAL_DECL duk_uint_t duk_to_uint(duk_context *ctx, duk_idx_t idx); 966 | DUK_EXTERNAL_DECL duk_int32_t duk_to_int32(duk_context *ctx, duk_idx_t idx); 967 | DUK_EXTERNAL_DECL duk_uint32_t duk_to_uint32(duk_context *ctx, duk_idx_t idx); 968 | DUK_EXTERNAL_DECL duk_uint16_t duk_to_uint16(duk_context *ctx, duk_idx_t idx); 969 | DUK_EXTERNAL_DECL const char *duk_to_string(duk_context *ctx, duk_idx_t idx); 970 | DUK_EXTERNAL_DECL const char *duk_to_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len); 971 | DUK_EXTERNAL_DECL void *duk_to_buffer_raw(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, duk_uint_t flags); 972 | DUK_EXTERNAL_DECL void *duk_to_pointer(duk_context *ctx, duk_idx_t idx); 973 | DUK_EXTERNAL_DECL void duk_to_object(duk_context *ctx, duk_idx_t idx); 974 | DUK_EXTERNAL_DECL void duk_to_primitive(duk_context *ctx, duk_idx_t idx, duk_int_t hint); 975 | 976 | #define DUK_BUF_MODE_FIXED 0 /* internal: request fixed buffer result */ 977 | #define DUK_BUF_MODE_DYNAMIC 1 /* internal: request dynamic buffer result */ 978 | #define DUK_BUF_MODE_DONTCARE 2 /* internal: don't care about fixed/dynamic nature */ 979 | 980 | #define duk_to_buffer(ctx,idx,out_size) \ 981 | duk_to_buffer_raw((ctx), (idx), (out_size), DUK_BUF_MODE_DONTCARE) 982 | #define duk_to_fixed_buffer(ctx,idx,out_size) \ 983 | duk_to_buffer_raw((ctx), (idx), (out_size), DUK_BUF_MODE_FIXED) 984 | #define duk_to_dynamic_buffer(ctx,idx,out_size) \ 985 | duk_to_buffer_raw((ctx), (idx), (out_size), DUK_BUF_MODE_DYNAMIC) 986 | 987 | /* safe variants of a few coercion operations */ 988 | DUK_EXTERNAL_DECL const char *duk_safe_to_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len); 989 | #define duk_safe_to_string(ctx,idx) \ 990 | duk_safe_to_lstring((ctx), (idx), NULL) 991 | 992 | /* 993 | * Value length 994 | */ 995 | 996 | DUK_EXTERNAL_DECL duk_size_t duk_get_length(duk_context *ctx, duk_idx_t idx); 997 | DUK_EXTERNAL_DECL void duk_set_length(duk_context *ctx, duk_idx_t idx, duk_size_t len); 998 | #if 0 999 | /* duk_require_length()? */ 1000 | /* duk_opt_length()? */ 1001 | #endif 1002 | 1003 | /* 1004 | * Misc conversion 1005 | */ 1006 | 1007 | DUK_EXTERNAL_DECL const char *duk_base64_encode(duk_context *ctx, duk_idx_t idx); 1008 | DUK_EXTERNAL_DECL void duk_base64_decode(duk_context *ctx, duk_idx_t idx); 1009 | DUK_EXTERNAL_DECL const char *duk_hex_encode(duk_context *ctx, duk_idx_t idx); 1010 | DUK_EXTERNAL_DECL void duk_hex_decode(duk_context *ctx, duk_idx_t idx); 1011 | DUK_EXTERNAL_DECL const char *duk_json_encode(duk_context *ctx, duk_idx_t idx); 1012 | DUK_EXTERNAL_DECL void duk_json_decode(duk_context *ctx, duk_idx_t idx); 1013 | 1014 | DUK_EXTERNAL_DECL const char *duk_buffer_to_string(duk_context *ctx, duk_idx_t idx); 1015 | 1016 | /* 1017 | * Buffer 1018 | */ 1019 | 1020 | DUK_EXTERNAL_DECL void *duk_resize_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t new_size); 1021 | DUK_EXTERNAL_DECL void *duk_steal_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size); 1022 | DUK_EXTERNAL_DECL void duk_config_buffer(duk_context *ctx, duk_idx_t idx, void *ptr, duk_size_t len); 1023 | 1024 | /* 1025 | * Property access 1026 | * 1027 | * The basic function assumes key is on stack. The _(l)string variant takes 1028 | * a C string as a property name; the _literal variant takes a C literal. 1029 | * The _index variant takes an array index as a property name (e.g. 123 is 1030 | * equivalent to the key "123"). The _heapptr variant takes a raw, borrowed 1031 | * heap pointer. 1032 | */ 1033 | 1034 | DUK_EXTERNAL_DECL duk_bool_t duk_get_prop(duk_context *ctx, duk_idx_t obj_idx); 1035 | DUK_EXTERNAL_DECL duk_bool_t duk_get_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key); 1036 | DUK_EXTERNAL_DECL duk_bool_t duk_get_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len); 1037 | #if defined(DUK_USE_PREFER_SIZE) 1038 | #define duk_get_prop_literal(ctx,obj_idx,key) duk_get_prop_string((ctx), (obj_idx), (key)) 1039 | #else 1040 | DUK_EXTERNAL_DECL duk_bool_t duk_get_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len); 1041 | #define duk_get_prop_literal(ctx,obj_idx,key) duk_get_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U) 1042 | #endif 1043 | DUK_EXTERNAL_DECL duk_bool_t duk_get_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx); 1044 | DUK_EXTERNAL_DECL duk_bool_t duk_get_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr); 1045 | DUK_EXTERNAL_DECL duk_bool_t duk_put_prop(duk_context *ctx, duk_idx_t obj_idx); 1046 | DUK_EXTERNAL_DECL duk_bool_t duk_put_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key); 1047 | DUK_EXTERNAL_DECL duk_bool_t duk_put_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len); 1048 | #if defined(DUK_USE_PREFER_SIZE) 1049 | #define duk_put_prop_literal(ctx,obj_idx,key) duk_put_prop_string((ctx), (obj_idx), (key)) 1050 | #else 1051 | DUK_EXTERNAL_DECL duk_bool_t duk_put_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len); 1052 | #define duk_put_prop_literal(ctx,obj_idx,key) duk_put_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U) 1053 | #endif 1054 | DUK_EXTERNAL_DECL duk_bool_t duk_put_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx); 1055 | DUK_EXTERNAL_DECL duk_bool_t duk_put_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr); 1056 | DUK_EXTERNAL_DECL duk_bool_t duk_del_prop(duk_context *ctx, duk_idx_t obj_idx); 1057 | DUK_EXTERNAL_DECL duk_bool_t duk_del_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key); 1058 | DUK_EXTERNAL_DECL duk_bool_t duk_del_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len); 1059 | #if defined(DUK_USE_PREFER_SIZE) 1060 | #define duk_del_prop_literal(ctx,obj_idx,key) duk_del_prop_string((ctx), (obj_idx), (key)) 1061 | #else 1062 | DUK_EXTERNAL_DECL duk_bool_t duk_del_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len); 1063 | #define duk_del_prop_literal(ctx,obj_idx,key) duk_del_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U) 1064 | #endif 1065 | DUK_EXTERNAL_DECL duk_bool_t duk_del_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx); 1066 | DUK_EXTERNAL_DECL duk_bool_t duk_del_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr); 1067 | DUK_EXTERNAL_DECL duk_bool_t duk_has_prop(duk_context *ctx, duk_idx_t obj_idx); 1068 | DUK_EXTERNAL_DECL duk_bool_t duk_has_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key); 1069 | DUK_EXTERNAL_DECL duk_bool_t duk_has_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len); 1070 | #if defined(DUK_USE_PREFER_SIZE) 1071 | #define duk_has_prop_literal(ctx,obj_idx,key) duk_has_prop_string((ctx), (obj_idx), (key)) 1072 | #else 1073 | DUK_EXTERNAL_DECL duk_bool_t duk_has_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len); 1074 | #define duk_has_prop_literal(ctx,obj_idx,key) duk_has_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U) 1075 | #endif 1076 | DUK_EXTERNAL_DECL duk_bool_t duk_has_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx); 1077 | DUK_EXTERNAL_DECL duk_bool_t duk_has_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr); 1078 | 1079 | DUK_EXTERNAL_DECL void duk_get_prop_desc(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t flags); 1080 | DUK_EXTERNAL_DECL void duk_def_prop(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t flags); 1081 | 1082 | DUK_EXTERNAL_DECL duk_bool_t duk_get_global_string(duk_context *ctx, const char *key); 1083 | DUK_EXTERNAL_DECL duk_bool_t duk_get_global_lstring(duk_context *ctx, const char *key, duk_size_t key_len); 1084 | #if defined(DUK_USE_PREFER_SIZE) 1085 | #define duk_get_global_literal(ctx,key) duk_get_global_string((ctx), (key)) 1086 | #else 1087 | DUK_EXTERNAL_DECL duk_bool_t duk_get_global_literal_raw(duk_context *ctx, const char *key, duk_size_t key_len); 1088 | #define duk_get_global_literal(ctx,key) duk_get_global_literal_raw((ctx), (key), sizeof((key)) - 1U) 1089 | #endif 1090 | DUK_EXTERNAL_DECL duk_bool_t duk_get_global_heapptr(duk_context *ctx, void *ptr); 1091 | DUK_EXTERNAL_DECL duk_bool_t duk_put_global_string(duk_context *ctx, const char *key); 1092 | DUK_EXTERNAL_DECL duk_bool_t duk_put_global_lstring(duk_context *ctx, const char *key, duk_size_t key_len); 1093 | #if defined(DUK_USE_PREFER_SIZE) 1094 | #define duk_put_global_literal(ctx,key) duk_put_global_string((ctx), (key)) 1095 | #else 1096 | DUK_EXTERNAL_DECL duk_bool_t duk_put_global_literal_raw(duk_context *ctx, const char *key, duk_size_t key_len); 1097 | #define duk_put_global_literal(ctx,key) duk_put_global_literal_raw((ctx), (key), sizeof((key)) - 1U) 1098 | #endif 1099 | DUK_EXTERNAL_DECL duk_bool_t duk_put_global_heapptr(duk_context *ctx, void *ptr); 1100 | 1101 | /* 1102 | * Inspection 1103 | */ 1104 | 1105 | DUK_EXTERNAL_DECL void duk_inspect_value(duk_context *ctx, duk_idx_t idx); 1106 | DUK_EXTERNAL_DECL void duk_inspect_callstack_entry(duk_context *ctx, duk_int_t level); 1107 | 1108 | /* 1109 | * Object prototype 1110 | */ 1111 | 1112 | DUK_EXTERNAL_DECL void duk_get_prototype(duk_context *ctx, duk_idx_t idx); 1113 | DUK_EXTERNAL_DECL void duk_set_prototype(duk_context *ctx, duk_idx_t idx); 1114 | 1115 | /* 1116 | * Object finalizer 1117 | */ 1118 | 1119 | DUK_EXTERNAL_DECL void duk_get_finalizer(duk_context *ctx, duk_idx_t idx); 1120 | DUK_EXTERNAL_DECL void duk_set_finalizer(duk_context *ctx, duk_idx_t idx); 1121 | 1122 | /* 1123 | * Global object 1124 | */ 1125 | 1126 | DUK_EXTERNAL_DECL void duk_set_global_object(duk_context *ctx); 1127 | 1128 | /* 1129 | * Duktape/C function magic value 1130 | */ 1131 | 1132 | DUK_EXTERNAL_DECL duk_int_t duk_get_magic(duk_context *ctx, duk_idx_t idx); 1133 | DUK_EXTERNAL_DECL void duk_set_magic(duk_context *ctx, duk_idx_t idx, duk_int_t magic); 1134 | DUK_EXTERNAL_DECL duk_int_t duk_get_current_magic(duk_context *ctx); 1135 | 1136 | /* 1137 | * Module helpers: put multiple function or constant properties 1138 | */ 1139 | 1140 | DUK_EXTERNAL_DECL void duk_put_function_list(duk_context *ctx, duk_idx_t obj_idx, const duk_function_list_entry *funcs); 1141 | DUK_EXTERNAL_DECL void duk_put_number_list(duk_context *ctx, duk_idx_t obj_idx, const duk_number_list_entry *numbers); 1142 | 1143 | /* 1144 | * Object operations 1145 | */ 1146 | 1147 | DUK_EXTERNAL_DECL void duk_compact(duk_context *ctx, duk_idx_t obj_idx); 1148 | DUK_EXTERNAL_DECL void duk_enum(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t enum_flags); 1149 | DUK_EXTERNAL_DECL duk_bool_t duk_next(duk_context *ctx, duk_idx_t enum_idx, duk_bool_t get_value); 1150 | DUK_EXTERNAL_DECL void duk_seal(duk_context *ctx, duk_idx_t obj_idx); 1151 | DUK_EXTERNAL_DECL void duk_freeze(duk_context *ctx, duk_idx_t obj_idx); 1152 | 1153 | /* 1154 | * String manipulation 1155 | */ 1156 | 1157 | DUK_EXTERNAL_DECL void duk_concat(duk_context *ctx, duk_idx_t count); 1158 | DUK_EXTERNAL_DECL void duk_join(duk_context *ctx, duk_idx_t count); 1159 | DUK_EXTERNAL_DECL void duk_decode_string(duk_context *ctx, duk_idx_t idx, duk_decode_char_function callback, void *udata); 1160 | DUK_EXTERNAL_DECL void duk_map_string(duk_context *ctx, duk_idx_t idx, duk_map_char_function callback, void *udata); 1161 | DUK_EXTERNAL_DECL void duk_substring(duk_context *ctx, duk_idx_t idx, duk_size_t start_char_offset, duk_size_t end_char_offset); 1162 | DUK_EXTERNAL_DECL void duk_trim(duk_context *ctx, duk_idx_t idx); 1163 | DUK_EXTERNAL_DECL duk_codepoint_t duk_char_code_at(duk_context *ctx, duk_idx_t idx, duk_size_t char_offset); 1164 | 1165 | /* 1166 | * ECMAScript operators 1167 | */ 1168 | 1169 | DUK_EXTERNAL_DECL duk_bool_t duk_equals(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2); 1170 | DUK_EXTERNAL_DECL duk_bool_t duk_strict_equals(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2); 1171 | DUK_EXTERNAL_DECL duk_bool_t duk_samevalue(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2); 1172 | DUK_EXTERNAL_DECL duk_bool_t duk_instanceof(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2); 1173 | 1174 | /* 1175 | * Random 1176 | */ 1177 | 1178 | DUK_EXTERNAL_DECL duk_double_t duk_random(duk_context *ctx); 1179 | 1180 | /* 1181 | * Function (method) calls 1182 | */ 1183 | 1184 | DUK_EXTERNAL_DECL void duk_call(duk_context *ctx, duk_idx_t nargs); 1185 | DUK_EXTERNAL_DECL void duk_call_method(duk_context *ctx, duk_idx_t nargs); 1186 | DUK_EXTERNAL_DECL void duk_call_prop(duk_context *ctx, duk_idx_t obj_idx, duk_idx_t nargs); 1187 | DUK_EXTERNAL_DECL duk_int_t duk_pcall(duk_context *ctx, duk_idx_t nargs); 1188 | DUK_EXTERNAL_DECL duk_int_t duk_pcall_method(duk_context *ctx, duk_idx_t nargs); 1189 | DUK_EXTERNAL_DECL duk_int_t duk_pcall_prop(duk_context *ctx, duk_idx_t obj_idx, duk_idx_t nargs); 1190 | DUK_EXTERNAL_DECL void duk_new(duk_context *ctx, duk_idx_t nargs); 1191 | DUK_EXTERNAL_DECL duk_int_t duk_pnew(duk_context *ctx, duk_idx_t nargs); 1192 | DUK_EXTERNAL_DECL duk_int_t duk_safe_call(duk_context *ctx, duk_safe_call_function func, void *udata, duk_idx_t nargs, duk_idx_t nrets); 1193 | 1194 | /* 1195 | * Thread management 1196 | */ 1197 | 1198 | /* There are currently no native functions to yield/resume, due to the internal 1199 | * limitations on coroutine handling. These will be added later. 1200 | */ 1201 | 1202 | /* 1203 | * Compilation and evaluation 1204 | */ 1205 | 1206 | DUK_EXTERNAL_DECL duk_int_t duk_eval_raw(duk_context *ctx, const char *src_buffer, duk_size_t src_length, duk_uint_t flags); 1207 | DUK_EXTERNAL_DECL duk_int_t duk_compile_raw(duk_context *ctx, const char *src_buffer, duk_size_t src_length, duk_uint_t flags); 1208 | 1209 | /* plain */ 1210 | #define duk_eval(ctx) \ 1211 | ((void) duk_eval_raw((ctx), NULL, 0, 1 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOFILENAME)) 1212 | 1213 | #define duk_eval_noresult(ctx) \ 1214 | ((void) duk_eval_raw((ctx), NULL, 0, 1 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME)) 1215 | 1216 | #define duk_peval(ctx) \ 1217 | (duk_eval_raw((ctx), NULL, 0, 1 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOFILENAME)) 1218 | 1219 | #define duk_peval_noresult(ctx) \ 1220 | (duk_eval_raw((ctx), NULL, 0, 1 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME)) 1221 | 1222 | #define duk_compile(ctx,flags) \ 1223 | ((void) duk_compile_raw((ctx), NULL, 0, 2 /*args*/ | (flags))) 1224 | 1225 | #define duk_pcompile(ctx,flags) \ 1226 | (duk_compile_raw((ctx), NULL, 0, 2 /*args*/ | (flags) | DUK_COMPILE_SAFE)) 1227 | 1228 | /* string */ 1229 | #define duk_eval_string(ctx,src) \ 1230 | ((void) duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NOFILENAME)) 1231 | 1232 | #define duk_eval_string_noresult(ctx,src) \ 1233 | ((void) duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME)) 1234 | 1235 | #define duk_peval_string(ctx,src) \ 1236 | (duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NOFILENAME)) 1237 | 1238 | #define duk_peval_string_noresult(ctx,src) \ 1239 | (duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME)) 1240 | 1241 | #define duk_compile_string(ctx,flags,src) \ 1242 | ((void) duk_compile_raw((ctx), (src), 0, 0 /*args*/ | (flags) | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NOFILENAME)) 1243 | 1244 | #define duk_compile_string_filename(ctx,flags,src) \ 1245 | ((void) duk_compile_raw((ctx), (src), 0, 1 /*args*/ | (flags) | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN)) 1246 | 1247 | #define duk_pcompile_string(ctx,flags,src) \ 1248 | (duk_compile_raw((ctx), (src), 0, 0 /*args*/ | (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NOFILENAME)) 1249 | 1250 | #define duk_pcompile_string_filename(ctx,flags,src) \ 1251 | (duk_compile_raw((ctx), (src), 0, 1 /*args*/ | (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN)) 1252 | 1253 | /* lstring */ 1254 | #define duk_eval_lstring(ctx,buf,len) \ 1255 | ((void) duk_eval_raw((ctx), buf, len, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NOFILENAME)) 1256 | 1257 | #define duk_eval_lstring_noresult(ctx,buf,len) \ 1258 | ((void) duk_eval_raw((ctx), buf, len, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME)) 1259 | 1260 | #define duk_peval_lstring(ctx,buf,len) \ 1261 | (duk_eval_raw((ctx), buf, len, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_SAFE | DUK_COMPILE_NOFILENAME)) 1262 | 1263 | #define duk_peval_lstring_noresult(ctx,buf,len) \ 1264 | (duk_eval_raw((ctx), buf, len, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME)) 1265 | 1266 | #define duk_compile_lstring(ctx,flags,buf,len) \ 1267 | ((void) duk_compile_raw((ctx), buf, len, 0 /*args*/ | (flags) | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NOFILENAME)) 1268 | 1269 | #define duk_compile_lstring_filename(ctx,flags,buf,len) \ 1270 | ((void) duk_compile_raw((ctx), buf, len, 1 /*args*/ | (flags) | DUK_COMPILE_NOSOURCE)) 1271 | 1272 | #define duk_pcompile_lstring(ctx,flags,buf,len) \ 1273 | (duk_compile_raw((ctx), buf, len, 0 /*args*/ | (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NOFILENAME)) 1274 | 1275 | #define duk_pcompile_lstring_filename(ctx,flags,buf,len) \ 1276 | (duk_compile_raw((ctx), buf, len, 1 /*args*/ | (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE)) 1277 | 1278 | /* 1279 | * Bytecode load/dump 1280 | */ 1281 | 1282 | DUK_EXTERNAL_DECL void duk_dump_function(duk_context *ctx); 1283 | DUK_EXTERNAL_DECL void duk_load_function(duk_context *ctx); 1284 | 1285 | /* 1286 | * Debugging 1287 | */ 1288 | 1289 | DUK_EXTERNAL_DECL void duk_push_context_dump(duk_context *ctx); 1290 | 1291 | /* 1292 | * Debugger (debug protocol) 1293 | */ 1294 | 1295 | DUK_EXTERNAL_DECL void duk_debugger_attach(duk_context *ctx, 1296 | duk_debug_read_function read_cb, 1297 | duk_debug_write_function write_cb, 1298 | duk_debug_peek_function peek_cb, 1299 | duk_debug_read_flush_function read_flush_cb, 1300 | duk_debug_write_flush_function write_flush_cb, 1301 | duk_debug_request_function request_cb, 1302 | duk_debug_detached_function detached_cb, 1303 | void *udata); 1304 | DUK_EXTERNAL_DECL void duk_debugger_detach(duk_context *ctx); 1305 | DUK_EXTERNAL_DECL void duk_debugger_cooperate(duk_context *ctx); 1306 | DUK_EXTERNAL_DECL duk_bool_t duk_debugger_notify(duk_context *ctx, duk_idx_t nvalues); 1307 | DUK_EXTERNAL_DECL void duk_debugger_pause(duk_context *ctx); 1308 | 1309 | /* 1310 | * Time handling 1311 | */ 1312 | 1313 | DUK_EXTERNAL_DECL duk_double_t duk_get_now(duk_context *ctx); 1314 | DUK_EXTERNAL_DECL void duk_time_to_components(duk_context *ctx, duk_double_t timeval, duk_time_components *comp); 1315 | DUK_EXTERNAL_DECL duk_double_t duk_components_to_time(duk_context *ctx, duk_time_components *comp); 1316 | 1317 | /* 1318 | * Date provider related constants 1319 | * 1320 | * NOTE: These are "semi public" - you should only use these if you write 1321 | * your own platform specific Date provider, see doc/datetime.rst. 1322 | */ 1323 | 1324 | /* Millisecond count constants. */ 1325 | #define DUK_DATE_MSEC_SECOND 1000L 1326 | #define DUK_DATE_MSEC_MINUTE (60L * 1000L) 1327 | #define DUK_DATE_MSEC_HOUR (60L * 60L * 1000L) 1328 | #define DUK_DATE_MSEC_DAY (24L * 60L * 60L * 1000L) 1329 | 1330 | /* ECMAScript date range is 100 million days from Epoch: 1331 | * > 100e6 * 24 * 60 * 60 * 1000 // 100M days in millisecs 1332 | * 8640000000000000 1333 | * (= 8.64e15) 1334 | */ 1335 | #define DUK_DATE_MSEC_100M_DAYS (8.64e15) 1336 | #define DUK_DATE_MSEC_100M_DAYS_LEEWAY (8.64e15 + 24 * 3600e3) 1337 | 1338 | /* ECMAScript year range: 1339 | * > new Date(100e6 * 24 * 3600e3).toISOString() 1340 | * '+275760-09-13T00:00:00.000Z' 1341 | * > new Date(-100e6 * 24 * 3600e3).toISOString() 1342 | * '-271821-04-20T00:00:00.000Z' 1343 | */ 1344 | #define DUK_DATE_MIN_ECMA_YEAR (-271821L) 1345 | #define DUK_DATE_MAX_ECMA_YEAR 275760L 1346 | 1347 | /* Part indices for internal breakdowns. Part order from DUK_DATE_IDX_YEAR 1348 | * to DUK_DATE_IDX_MILLISECOND matches argument ordering of ECMAScript API 1349 | * calls (like Date constructor call). Some functions in duk_bi_date.c 1350 | * depend on the specific ordering, so change with care. 16 bits are not 1351 | * enough for all parts (year, specifically). 1352 | * 1353 | * Must be in-sync with genbuiltins.py. 1354 | */ 1355 | #define DUK_DATE_IDX_YEAR 0 /* year */ 1356 | #define DUK_DATE_IDX_MONTH 1 /* month: 0 to 11 */ 1357 | #define DUK_DATE_IDX_DAY 2 /* day within month: 0 to 30 */ 1358 | #define DUK_DATE_IDX_HOUR 3 1359 | #define DUK_DATE_IDX_MINUTE 4 1360 | #define DUK_DATE_IDX_SECOND 5 1361 | #define DUK_DATE_IDX_MILLISECOND 6 1362 | #define DUK_DATE_IDX_WEEKDAY 7 /* weekday: 0 to 6, 0=sunday, 1=monday, etc */ 1363 | #define DUK_DATE_IDX_NUM_PARTS 8 1364 | 1365 | /* Internal API call flags, used for various functions in duk_bi_date.c. 1366 | * Certain flags are used by only certain functions, but since the flags 1367 | * don't overlap, a single flags value can be passed around to multiple 1368 | * functions. 1369 | * 1370 | * The unused top bits of the flags field are also used to pass values 1371 | * to helpers (duk__get_part_helper() and duk__set_part_helper()). 1372 | * 1373 | * Must be in-sync with genbuiltins.py. 1374 | */ 1375 | 1376 | /* NOTE: when writing a Date provider you only need a few specific 1377 | * flags from here, the rest are internal. Avoid using anything you 1378 | * don't need. 1379 | */ 1380 | 1381 | #define DUK_DATE_FLAG_NAN_TO_ZERO (1 << 0) /* timeval breakdown: internal time value NaN -> zero */ 1382 | #define DUK_DATE_FLAG_NAN_TO_RANGE_ERROR (1 << 1) /* timeval breakdown: internal time value NaN -> RangeError (toISOString) */ 1383 | #define DUK_DATE_FLAG_ONEBASED (1 << 2) /* timeval breakdown: convert month and day-of-month parts to one-based (default is zero-based) */ 1384 | #define DUK_DATE_FLAG_EQUIVYEAR (1 << 3) /* timeval breakdown: replace year with equivalent year in the [1971,2037] range for DST calculations */ 1385 | #define DUK_DATE_FLAG_LOCALTIME (1 << 4) /* convert time value to local time */ 1386 | #define DUK_DATE_FLAG_SUB1900 (1 << 5) /* getter: subtract 1900 from year when getting year part */ 1387 | #define DUK_DATE_FLAG_TOSTRING_DATE (1 << 6) /* include date part in string conversion result */ 1388 | #define DUK_DATE_FLAG_TOSTRING_TIME (1 << 7) /* include time part in string conversion result */ 1389 | #define DUK_DATE_FLAG_TOSTRING_LOCALE (1 << 8) /* use locale specific formatting if available */ 1390 | #define DUK_DATE_FLAG_TIMESETTER (1 << 9) /* setter: call is a time setter (affects hour, min, sec, ms); otherwise date setter (affects year, month, day-in-month) */ 1391 | #define DUK_DATE_FLAG_YEAR_FIXUP (1 << 10) /* setter: perform 2-digit year fixup (00...99 -> 1900...1999) */ 1392 | #define DUK_DATE_FLAG_SEP_T (1 << 11) /* string conversion: use 'T' instead of ' ' as a separator */ 1393 | #define DUK_DATE_FLAG_VALUE_SHIFT 12 /* additional values begin at bit 12 */ 1394 | 1395 | /* 1396 | * ROM pointer compression 1397 | */ 1398 | 1399 | /* Support array for ROM pointer compression. Only declared when ROM 1400 | * pointer compression is active. 1401 | */ 1402 | #if defined(DUK_USE_ROM_OBJECTS) && defined(DUK_USE_HEAPPTR16) 1403 | DUK_EXTERNAL_DECL const void * const duk_rom_compressed_pointers[]; 1404 | #endif 1405 | 1406 | /* 1407 | * C++ name mangling 1408 | */ 1409 | 1410 | #if defined(__cplusplus) 1411 | /* end 'extern "C"' wrapper */ 1412 | } 1413 | #endif 1414 | 1415 | /* 1416 | * END PUBLIC API 1417 | */ 1418 | 1419 | #endif /* DUKTAPE_H_INCLUDED */ 1420 | -------------------------------------------------------------------------------- /include/md5.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. 3 | * MD5 Message-Digest Algorithm (RFC 1321). 4 | * 5 | * Homepage: 6 | * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 7 | * 8 | * Author: 9 | * Alexander Peslyak, better known as Solar Designer 10 | * 11 | * This software was written by Alexander Peslyak in 2001. No copyright is 12 | * claimed, and the software is hereby placed in the public domain. 13 | * In case this attempt to disclaim copyright and place the software in the 14 | * public domain is deemed null and void, then the software is 15 | * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the 16 | * general public under the following terms: 17 | * 18 | * Redistribution and use in source and binary forms, with or without 19 | * modification, are permitted. 20 | * 21 | * There's ABSOLUTELY NO WARRANTY, express or implied. 22 | * 23 | * See md5.c for more information. 24 | */ 25 | 26 | #ifdef HAVE_OPENSSL 27 | #include 28 | #elif !defined(_MD5_H) 29 | #define _MD5_H 30 | 31 | /* Any 32-bit or wider unsigned integer data type will do */ 32 | typedef unsigned int MD5_u32plus; 33 | 34 | typedef struct { 35 | MD5_u32plus lo, hi; 36 | MD5_u32plus a, b, c, d; 37 | unsigned char buffer[64]; 38 | MD5_u32plus block[16]; 39 | } MD5_CTX; 40 | 41 | extern void MD5_Init(MD5_CTX *ctx); 42 | extern void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size); 43 | extern void MD5_Final(unsigned char *result, MD5_CTX *ctx); 44 | 45 | #endif -------------------------------------------------------------------------------- /include/nxsh.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #ifndef NXSH_H 6 | #define NXSH_H 7 | 8 | /* Useful constants */ 9 | #define NXSH_WELCOME "Welcome to nxsh! Type 'help' for a list of available commands.\r\n" 10 | #define NXSH_SEPARATOR "-------------------------------------------------------------\r\n" 11 | #define NXSH_HELP "List of available commands:\r\n" \ 12 | "\tls - get a directory listing\r\n" \ 13 | "\tcd - change directory\r\n" \ 14 | "\tmkdir - make directory\r\n" \ 15 | "\trm - remove file or directory\r\n" \ 16 | "\tcp - copy file or directory\r\n" \ 17 | "\tcat - print file on standard output\r\n" \ 18 | "\tpasswd - set/update/clear password\r\n" \ 19 | "\tlog - enable/disable logging\r\n" \ 20 | "\tfetch - download file from remote server\r\n" \ 21 | "\tmount - mount a filesystem to a device\r\n" \ 22 | "\tumount - unmount device\r\n" \ 23 | "\tcommit-dev - commit changes to a device\r\n" \ 24 | "\treboot - reboots the console\r\n" \ 25 | "\tshutdown - turns off the console\r\n" \ 26 | "\techo - echo the arguments\r\n" \ 27 | "\ttouch - create file or update modification date of a file\r\n" \ 28 | "\tmd5sum - get the md5 hash of a file\r\n" \ 29 | "\tsha1sum - get the sha1 hash of a file\r\n" \ 30 | "\tsha256sum - get the sha256 hash of a file\r\n" \ 31 | "\tpm - interact with the PM sysmodule\r\n" \ 32 | "\tacc - interact with accounts\r\n" \ 33 | "\trealpath - resolve the absolute path\r\n" \ 34 | "\tversion - display NXSH version\r\n" \ 35 | "\thelp - print this message\r\n\r\n" \ 36 | "\tInvoke script files by their path (./script.js)\r\n" 37 | 38 | #define NXSH_DIR "/nxsh" 39 | 40 | #define NXSH_VERSION "0.1.8 beta" 41 | 42 | #define NXSH_PORT 23 43 | 44 | extern int NXSH_LOGGING_ENABLED; 45 | extern int NXSH_FD_LOCK; 46 | 47 | /* Functions in main.c */ 48 | void nxsh_session(int connfd); 49 | char *nxsh_command(int connfd, char *command, int argc, char **argv); 50 | 51 | /* Basic shell commands */ 52 | char *nxsh_ls(int argc, char **argv); 53 | char *nxsh_cd(int argc, char **argv); 54 | char *nxsh_mkdir(int argc, char **argv); 55 | char *nxsh_rm(int argc, char **argv); 56 | char *nxsh_cp(int argc, char **argv); 57 | char *nxsh_mv(int argc, char **argv); 58 | char *nxsh_chmod(int argc, char **argv); 59 | char *nxsh_cat(int argc, char **argv); 60 | char *nxsh_log(int argc, char **argv); 61 | char *nxsh_passwd(int argc, char **argv); 62 | char *nxsh_fetch(int argc, char **argv, int connfd); 63 | char *nxsh_script(char *path, int argc, char **argv, int connfd); 64 | char *nxsh_mount(int argc, char **argv); 65 | char *nxsh_umount(int argc, char **argv); 66 | char *nxsh_reboot(int argc, char **argv, int connfd); 67 | char *nxsh_shutdown(int connfd); 68 | char *nxsh_echo(int argc, char **argv); 69 | char *nxsh_touch(int argc, char **argv); 70 | char *nxsh_hash(int argc, char **argv, const char *type); 71 | char *nxsh_pm(int argc, char **argv); 72 | char *nxsh_acc(int argc, char **argv); 73 | char *nxsh_commit_dev(int argc, char **argv); 74 | char *nxsh_realpath(int argc, char **argv); 75 | 76 | /* Behind the scenes */ 77 | char *nxsh_cwd(); 78 | char *nxsh_prompt(); 79 | int nxsh_authenticate(char *password); 80 | 81 | /* Logging functions */ 82 | int logging_enabled(); 83 | void write_log(char *input); 84 | void write_log_raw(char *input); 85 | 86 | /* Utility functions */ 87 | void trim(char *input); 88 | void delete_end(char *input); 89 | char *error(char *msg); 90 | int is_file(char *name); 91 | int is_dir_empty(char *dir); 92 | int exists(char *name); 93 | char *filename(char *fullpath); 94 | char *strip_prefix(char *inpath); 95 | char *hash(void *input, size_t size, const char *type); 96 | char *format_acc_uid_hex(AccountUid uid); 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /include/sysmodule.h: -------------------------------------------------------------------------------- 1 | #ifdef __SYS__ 2 | #include 3 | 4 | #define TITLE_ID 0x43000000000000FF // This should be a purposeful number 5 | #define HEAP_SIZE 0x280000 6 | 7 | //setup a fake heap 8 | char fake_heap[HEAP_SIZE]; 9 | 10 | void __libnx_initheap(void); 11 | 12 | void __libnx_init_time(void); 13 | 14 | void __appInit(void); 15 | 16 | void __appExit(void); 17 | #endif 18 | -------------------------------------------------------------------------------- /source/acc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | #define ACC_USAGE "Usage: acc