mirror of
				https://github.com/Xahau/xahaud.git
				synced 2025-11-04 10:45:50 +00:00 
			
		
		
		
	Compare commits
	
		
			237 Commits
		
	
	
		
			849d447a20
			...
			nd-gcc-13-
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					9d4bda0968 | ||
| 
						 | 
					d8c9e89043 | ||
| 
						 | 
					285ea1d4e6 | ||
| 
						 | 
					b619d03b22 | ||
| 
						 | 
					34fd31dabe | ||
| 
						 | 
					7a790246fb | ||
| 
						 | 
					1a3d2db8ef | ||
| 
						 | 
					2fc912d54d | ||
| 
						 | 
					a6c4e39235 | ||
| 
						 | 
					50a6499112 | ||
| 
						 | 
					429f3289d8 | ||
| 
						 | 
					257c46ec9c | ||
| 
						 | 
					637d626518 | ||
| 
						 | 
					cce9d372e7 | ||
| 
						 | 
					aa571df467 | ||
| 
						 | 
					ae8f6a16ed | ||
| 
						 | 
					64441f7f40 | ||
| 
						 | 
					0bf50c5dc7 | ||
| 
						 | 
					8b0592ce06 | ||
| 
						 | 
					c27e2a9c05 | ||
| 
						 | 
					f8d22bbc24 | ||
| 
						 | 
					95ab35a185 | ||
| 
						 | 
					313ad7134b | ||
| 
						 | 
					859dcbcabf | ||
| 
						 | 
					a8e9448b1a | ||
| 
						 | 
					cab4d63a07 | ||
| 
						 | 
					9a90a7ffdc | ||
| 
						 | 
					ddbbe91e5a | ||
| 
						 | 
					2d9ac91cd1 | ||
| 
						 | 
					9532ea7dec | ||
| 
						 | 
					ed243745f8 | ||
| 
						 | 
					5eac2d3e44 | ||
| 
						 | 
					245cf4a676 | ||
| 
						 | 
					864734f607 | ||
| 
						 | 
					689740d818 | ||
| 
						 | 
					a8c80e99c0 | ||
| 
						 | 
					486003f1a8 | ||
| 
						 | 
					c9f0fe02a1 | ||
| 
						 | 
					a9c096e59c | ||
| 
						 | 
					a83a157058 | ||
| 
						 | 
					5e255e560f | ||
| 
						 | 
					c953ee326d | ||
| 
						 | 
					053a10a236 | ||
| 
						 | 
					c53dcf1422 | ||
| 
						 | 
					34b148bda0 | ||
| 
						 | 
					19111a3739 | ||
| 
						 | 
					3f98c15910 | ||
| 
						 | 
					942227f8c3 | ||
| 
						 | 
					e9461c827c | ||
| 
						 | 
					3d9423dda6 | ||
| 
						 | 
					5d41688e36 | ||
| 
						 | 
					9bd6d2244e | ||
| 
						 | 
					48919f028c | ||
| 
						 | 
					46d745b43f | ||
| 
						 | 
					5365bbcfe8 | ||
| 
						 | 
					9c26f1f213 | ||
| 
						 | 
					69b7728b2d | ||
| 
						 | 
					15b679b1a7 | ||
| 
						 | 
					9178aa9d8a | ||
| 
						 | 
					17fdd09640 | ||
| 
						 | 
					40dc69d642 | ||
| 
						 | 
					e8560c2198 | ||
| 
						 | 
					ca7533c14a | ||
| 
						 | 
					eba913a68e | ||
| 
						 | 
					ec849e0899 | ||
| 
						 | 
					314fb6c9e0 | ||
| 
						 | 
					643cd9fef1 | ||
| 
						 | 
					3593d67df9 | ||
| 
						 | 
					5571827be2 | ||
| 
						 | 
					cfbfd762e8 | ||
| 
						 | 
					c25fd875a8 | ||
| 
						 | 
					043f1e96b6 | ||
| 
						 | 
					17dfca6e61 | ||
| 
						 | 
					74681718dd | ||
| 
						 | 
					167417bfed | ||
| 
						 | 
					2dd22648e8 | ||
| 
						 | 
					e89aa05a2a | ||
| 
						 | 
					8a5ccbf870 | ||
| 
						 | 
					f6f87e468a | ||
| 
						 | 
					d7167a9ebe | ||
| 
						 | 
					7446dddddb | ||
| 
						 | 
					d9388e1e51 | ||
| 
						 | 
					73c1748241 | ||
| 
						 | 
					58e3840345 | ||
| 
						 | 
					61135c0ecb | ||
| 
						 | 
					42a44d0cb8 | ||
| 
						 | 
					d37039897e | ||
| 
						 | 
					2061d6d44c | ||
| 
						 | 
					8ea35ace02 | ||
| 
						 | 
					a203314c68 | ||
| 
						 | 
					092a29cd18 | ||
| 
						 | 
					1ba18875ac | ||
| 
						 | 
					2da58fe18f | ||
| 
						 | 
					8d7cc68bda | ||
| 
						 | 
					b73dd584e7 | ||
| 
						 | 
					0726789d77 | ||
| 
						 | 
					05bd9c6ea8 | ||
| 
						 | 
					f9e7ea95fd | ||
| 
						 | 
					618a933241 | ||
| 
						 | 
					752dbf34ee | ||
| 
						 | 
					fcf3848814 | ||
| 
						 | 
					e4a6aecc18 | ||
| 
						 | 
					1c4ebfe3ad | ||
| 
						 | 
					f97165e4bc | ||
| 
						 | 
					fc50c0fb0a | ||
| 
						 | 
					1b12b400d7 | ||
| 
						 | 
					f3ee0dd322 | ||
| 
						 | 
					d9659dc226 | ||
| 
						 | 
					fb7af36cef | ||
| 
						 | 
					4bfe27d11f | ||
| 
						 | 
					eaa2cc9e5c | ||
| 
						 | 
					6aa1ff87b9 | ||
| 
						 | 
					5ef3795cea | ||
| 
						 | 
					da5f1d189b | ||
| 
						 | 
					6fdf788b13 | ||
| 
						 | 
					61f45055a7 | ||
| 
						 | 
					f9e7fed929 | ||
| 
						 | 
					5cfe566489 | ||
| 
						 | 
					04409616ed | ||
| 
						 | 
					ca04c2a802 | ||
| 
						 | 
					f868b4d6e6 | ||
| 
						 | 
					5502453de8 | ||
| 
						 | 
					359ab70ba0 | ||
| 
						 | 
					d82f60705d | ||
| 
						 | 
					15515b84f8 | ||
| 
						 | 
					8b29fc5ee1 | ||
| 
						 | 
					92be8146e8 | ||
| 
						 | 
					c0f55d0b00 | ||
| 
						 | 
					802ea6c568 | ||
| 
						 | 
					ecc779346e | ||
| 
						 | 
					680c6095d4 | ||
| 
						 | 
					6858861660 | ||
| 
						 | 
					9faef17407 | ||
| 
						 | 
					ee68cc2cd2 | ||
| 
						 | 
					7c360bad33 | ||
| 
						 | 
					26a66bc2ef | ||
| 
						 | 
					4b93e1657f | ||
| 
						 | 
					cd45285cab | ||
| 
						 | 
					b7acfb9803 | ||
| 
						 | 
					97a10d6556 | ||
| 
						 | 
					fe43029272 | ||
| 
						 | 
					bf33b6f637 | ||
| 
						 | 
					c27518b846 | ||
| 
						 | 
					7d8f5de93d | ||
| 
						 | 
					858ea1bf25 | ||
| 
						 | 
					7162fe0497 | ||
| 
						 | 
					56c0e0dd5f | ||
| 
						 | 
					20ca066454 | ||
| 
						 | 
					171610d1a9 | ||
| 
						 | 
					2f6cf0ab4b | ||
| 
						 | 
					71884ad48a | ||
| 
						 | 
					799a056313 | ||
| 
						 | 
					eec61f16c9 | ||
| 
						 | 
					1bed7f1196 | ||
| 
						 | 
					211e63c568 | ||
| 
						 | 
					81413a5ce8 | ||
| 
						 | 
					36d630bed3 | ||
| 
						 | 
					4f901788f4 | ||
| 
						 | 
					72e773cbff | ||
| 
						 | 
					39ec8fb901 | ||
| 
						 | 
					534870f2f0 | ||
| 
						 | 
					db245d237c | ||
| 
						 | 
					f3118ef8fa | ||
| 
						 | 
					ee21449757 | ||
| 
						 | 
					9e7bee5564 | ||
| 
						 | 
					8cb2bbb693 | ||
| 
						 | 
					c240c1553b | ||
| 
						 | 
					a498ebeac4 | ||
| 
						 | 
					b13cab4ced | ||
| 
						 | 
					783bff75a0 | ||
| 
						 | 
					c1610a6dda | ||
| 
						 | 
					f829a79d54 | ||
| 
						 | 
					f35704c91f | ||
| 
						 | 
					9db9ad2123 | ||
| 
						 | 
					f96daa0014 | ||
| 
						 | 
					5c7ec5f36f | ||
| 
						 | 
					c662a8b0d2 | ||
| 
						 | 
					a983120b5d | ||
| 
						 | 
					f12b8cbb2d | ||
| 
						 | 
					f591290589 | ||
| 
						 | 
					f2becaf140 | ||
| 
						 | 
					e4c6add794 | ||
| 
						 | 
					78280e4b8c | ||
| 
						 | 
					178fdbaff6 | ||
| 
						 | 
					34d7435ff3 | ||
| 
						 | 
					6429ec609d | ||
| 
						 | 
					bea1697baa | ||
| 
						 | 
					2b111b7f23 | ||
| 
						 | 
					5254595063 | ||
| 
						 | 
					52456a2d51 | ||
| 
						 | 
					b340824711 | ||
| 
						 | 
					f5bb779f61 | ||
| 
						 | 
					bf99a1b05d | ||
| 
						 | 
					d1e5eb87f5 | ||
| 
						 | 
					b650d72f0b | ||
| 
						 | 
					7567277dd8 | ||
| 
						 | 
					13719a1357 | ||
| 
						 | 
					033dedf979 | ||
| 
						 | 
					6973540d52 | ||
| 
						 | 
					c9dcff90fa | ||
| 
						 | 
					71675c4fed | ||
| 
						 | 
					70bc2d3283 | ||
| 
						 | 
					c4d0fc0e0f | ||
| 
						 | 
					5d61eea709 | ||
| 
						 | 
					f4ffe4a3e0 | ||
| 
						 | 
					59ecbd9932 | ||
| 
						 | 
					6c3da46a1b | ||
| 
						 | 
					46308e33b0 | ||
| 
						 | 
					1f7355719d | ||
| 
						 | 
					7cc395b284 | ||
| 
						 | 
					a634318e8d | ||
| 
						 | 
					82e754d180 | ||
| 
						 | 
					9e72931bbb | ||
| 
						 | 
					842a0388d1 | ||
| 
						 | 
					280ba7d5de | ||
| 
						 | 
					7b0bc67242 | ||
| 
						 | 
					8e172e1846 | ||
| 
						 | 
					7497d619bf | ||
| 
						 | 
					34a159b662 | ||
| 
						 | 
					663910c78a | ||
| 
						 | 
					40b9aa7aed | ||
| 
						 | 
					ec7d603bf9 | ||
| 
						 | 
					f9137000e3 | ||
| 
						 | 
					c3cf4b5999 | ||
| 
						 | 
					6954abdd04 | ||
| 
						 | 
					38a4b3c1b9 | ||
| 
						 | 
					7e12b46169 | ||
| 
						 | 
					4e91d5887f | ||
| 
						 | 
					f051b87176 | ||
| 
						 | 
					98d39db305 | ||
| 
						 | 
					80df3adac7 | ||
| 
						 | 
					a2c3567caf | ||
| 
						 | 
					206773dcf4 | ||
| 
						 | 
					54c00d0364 | ||
| 
						 | 
					71a6f9c4d5 | ||
| 
						 | 
					9ab33d580d | ||
| 
						 | 
					0bd65bbb56 | 
							
								
								
									
										3
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							@@ -11,3 +11,6 @@ LICENSE binary
 | 
			
		||||
*.vcxproj   text eol=crlf
 | 
			
		||||
*.props     text eol=crlf
 | 
			
		||||
*.filters   text eol=crlf
 | 
			
		||||
 | 
			
		||||
# Mark it as generated and folded out by default
 | 
			
		||||
src/test/app/SetJSHook_wasm.h linguist-generated=true
 | 
			
		||||
							
								
								
									
										1
									
								
								.github/actions/xahau-ga-build/action.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/actions/xahau-ga-build/action.yml
									
									
									
									
										vendored
									
									
								
							@@ -59,7 +59,6 @@ runs:
 | 
			
		||||
          ${{ runner.os }}-ccache-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-${{ inputs.configuration }}-${{ inputs.main_branch }}
 | 
			
		||||
          ${{ runner.os }}-ccache-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-${{ inputs.configuration }}-
 | 
			
		||||
          ${{ runner.os }}-ccache-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-
 | 
			
		||||
          ${{ runner.os }}-ccache-v${{ inputs.cache_version }}-
 | 
			
		||||
 | 
			
		||||
    - name: Configure project
 | 
			
		||||
      shell: bash
 | 
			
		||||
 
 | 
			
		||||
@@ -54,13 +54,12 @@ runs:
 | 
			
		||||
        restore-keys: |
 | 
			
		||||
          ${{ runner.os }}-conan-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-${{ hashFiles('**/conanfile.txt', '**/conanfile.py') }}-
 | 
			
		||||
          ${{ runner.os }}-conan-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-
 | 
			
		||||
          ${{ runner.os }}-conan-v${{ inputs.cache_version }}-
 | 
			
		||||
 | 
			
		||||
    - name: Export custom recipes
 | 
			
		||||
      shell: bash
 | 
			
		||||
      run: |
 | 
			
		||||
        conan export external/snappy snappy/1.1.9@
 | 
			
		||||
        conan export external/soci soci/4.0.3@
 | 
			
		||||
        conan export external/snappy snappy/1.1.10@xahaud/stable
 | 
			
		||||
        conan export external/soci soci/4.0.3@xahaud/stable
 | 
			
		||||
 | 
			
		||||
    - name: Install dependencies
 | 
			
		||||
      shell: bash
 | 
			
		||||
@@ -83,4 +82,4 @@ runs:
 | 
			
		||||
        path: |
 | 
			
		||||
          ~/.conan
 | 
			
		||||
          ~/.conan2
 | 
			
		||||
        key: ${{ steps.cache-restore-conan.outputs.cache-primary-key }}
 | 
			
		||||
        key: ${{ steps.cache-restore-conan.outputs.cache-primary-key }}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								.github/workflows/build-in-docker.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								.github/workflows/build-in-docker.yml
									
									
									
									
										vendored
									
									
								
							@@ -32,19 +32,9 @@ jobs:
 | 
			
		||||
          clean: true
 | 
			
		||||
          fetch-depth: 2 # Only get the last 2 commits, to avoid fetching all history
 | 
			
		||||
 | 
			
		||||
  checkpatterns:
 | 
			
		||||
    runs-on: [self-hosted, vanity]
 | 
			
		||||
    needs: checkout
 | 
			
		||||
    defaults:
 | 
			
		||||
      run:
 | 
			
		||||
        working-directory: ${{ needs.checkout.outputs.checkout_path }}
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Check for suspicious patterns
 | 
			
		||||
        run: /bin/bash suspicious_patterns.sh
 | 
			
		||||
 | 
			
		||||
  build:
 | 
			
		||||
    runs-on: [self-hosted, vanity]
 | 
			
		||||
    needs: [checkpatterns, checkout]
 | 
			
		||||
    needs: [checkout]
 | 
			
		||||
    defaults:
 | 
			
		||||
      run:
 | 
			
		||||
        working-directory: ${{ needs.checkout.outputs.checkout_path }}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								.github/workflows/xahau-ga-nix.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								.github/workflows/xahau-ga-nix.yml
									
									
									
									
										vendored
									
									
								
							@@ -22,13 +22,14 @@ jobs:
 | 
			
		||||
        configuration: [Debug]
 | 
			
		||||
        include:
 | 
			
		||||
          - compiler: gcc
 | 
			
		||||
            cc: gcc-11
 | 
			
		||||
            cxx: g++-11
 | 
			
		||||
            compiler_id: gcc-11
 | 
			
		||||
            cc: gcc-13
 | 
			
		||||
            cxx: g++-13
 | 
			
		||||
            compiler_id: gcc-13
 | 
			
		||||
            compiler_version: 13
 | 
			
		||||
    env:
 | 
			
		||||
      build_dir: .build
 | 
			
		||||
      # Bump this number to invalidate all caches globally.
 | 
			
		||||
      CACHE_VERSION: 1
 | 
			
		||||
      CACHE_VERSION: 2
 | 
			
		||||
      MAIN_BRANCH_NAME: dev
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Checkout
 | 
			
		||||
@@ -58,12 +59,8 @@ jobs:
 | 
			
		||||
          conan profile update env.CXX=/usr/bin/${{ matrix.cxx }} default
 | 
			
		||||
          conan profile update conf.tools.build:compiler_executables='{"c": "/usr/bin/${{ matrix.cc }}", "cpp": "/usr/bin/${{ matrix.cxx }}"}' default
 | 
			
		||||
 | 
			
		||||
          # Set correct compiler version based on matrix.compiler
 | 
			
		||||
          if [ "${{ matrix.compiler }}" = "gcc" ]; then
 | 
			
		||||
            conan profile update settings.compiler.version=11 default
 | 
			
		||||
          elif [ "${{ matrix.compiler }}" = "clang" ]; then
 | 
			
		||||
            conan profile update settings.compiler.version=14 default
 | 
			
		||||
          fi
 | 
			
		||||
          # Set compiler version from matrix
 | 
			
		||||
          conan profile update settings.compiler.version=${{ matrix.compiler_version }} default
 | 
			
		||||
          # Display profile for verification
 | 
			
		||||
          conan profile show default
 | 
			
		||||
 | 
			
		||||
@@ -120,4 +117,4 @@ jobs:
 | 
			
		||||
          else
 | 
			
		||||
             echo "Error: rippled executable not found in ${{ env.build_dir }}"
 | 
			
		||||
             exit 1
 | 
			
		||||
          fi
 | 
			
		||||
          fi
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										7
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -24,6 +24,11 @@ bin/project-cache.jam
 | 
			
		||||
 | 
			
		||||
build/docker
 | 
			
		||||
 | 
			
		||||
# Ignore release builder files
 | 
			
		||||
.env
 | 
			
		||||
release-build
 | 
			
		||||
cmake-*.tar.gz
 | 
			
		||||
 | 
			
		||||
# Ignore object files.
 | 
			
		||||
*.o
 | 
			
		||||
build
 | 
			
		||||
@@ -115,4 +120,6 @@ pkg
 | 
			
		||||
CMakeUserPresets.json
 | 
			
		||||
bld.rippled/
 | 
			
		||||
 | 
			
		||||
# binary
 | 
			
		||||
qjsc
 | 
			
		||||
generated
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								BUILD.md
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								BUILD.md
									
									
									
									
									
								
							@@ -117,14 +117,14 @@ can't build earlier Boost versions.
 | 
			
		||||
   which allows you to statically link it with GCC, if you want.
 | 
			
		||||
 | 
			
		||||
   ```
 | 
			
		||||
   conan export external/snappy snappy/1.1.9@
 | 
			
		||||
   conan export external/snappy snappy/1.1.10@xahaud/stable
 | 
			
		||||
   ```
 | 
			
		||||
 | 
			
		||||
5. Export our [Conan recipe for SOCI](./external/soci).
 | 
			
		||||
   It patches their CMake to correctly import its dependencies.
 | 
			
		||||
 | 
			
		||||
   ```
 | 
			
		||||
   conan export external/soci soci/4.0.3@
 | 
			
		||||
   conan export external/soci soci/4.0.3@xahaud/stable
 | 
			
		||||
   ```
 | 
			
		||||
 | 
			
		||||
### Build and Test
 | 
			
		||||
 
 | 
			
		||||
@@ -150,6 +150,7 @@ target_link_libraries (xrpl_core
 | 
			
		||||
    OpenSSL::Crypto
 | 
			
		||||
    Ripple::boost
 | 
			
		||||
    wasmedge::wasmedge
 | 
			
		||||
    NIH::quickjs
 | 
			
		||||
    Ripple::syslibs
 | 
			
		||||
    secp256k1::secp256k1
 | 
			
		||||
    ed25519::ed25519
 | 
			
		||||
@@ -777,6 +778,9 @@ if (tests)
 | 
			
		||||
    src/test/app/ValidatorKeys_test.cpp
 | 
			
		||||
    src/test/app/ValidatorList_test.cpp
 | 
			
		||||
    src/test/app/ValidatorSite_test.cpp
 | 
			
		||||
    src/test/app/SetHook_test.cpp
 | 
			
		||||
    src/test/app/SetJSHook_test.cpp
 | 
			
		||||
    src/test/app/SetHookTSH_test.cpp
 | 
			
		||||
    src/test/app/Wildcard_test.cpp
 | 
			
		||||
    src/test/app/XahauGenesis_test.cpp
 | 
			
		||||
    src/test/app/tx/apply_test.cpp
 | 
			
		||||
@@ -1068,6 +1072,11 @@ target_link_libraries (rippled
 | 
			
		||||
  Ripple::opts
 | 
			
		||||
  Ripple::libs
 | 
			
		||||
  Ripple::xrpl_core
 | 
			
		||||
  # Workaround for a Conan 1.x bug that prevents static linking of libstdc++
 | 
			
		||||
  # when a dependency (snappy) modifies system_libs. See the comment in
 | 
			
		||||
  # external/snappy/conanfile.py for a full explanation.
 | 
			
		||||
  # This is likely not strictly necessary, but listed explicitly as a good practice.
 | 
			
		||||
  m
 | 
			
		||||
  )
 | 
			
		||||
exclude_if_included (rippled)
 | 
			
		||||
# define a macro for tests that might need to
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@
 | 
			
		||||
 | 
			
		||||
install (
 | 
			
		||||
  TARGETS
 | 
			
		||||
    quickjs
 | 
			
		||||
    common
 | 
			
		||||
    opts
 | 
			
		||||
    ripple_syslibs
 | 
			
		||||
 
 | 
			
		||||
@@ -1,33 +0,0 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH prefix path..this is where we will download
 | 
			
		||||
   and build any ExternalProjects, and they will hopefully
 | 
			
		||||
   survive across build directory deletion (manual cleans)
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
string (REGEX REPLACE "[ \\/%]+" "_" gen_for_path ${CMAKE_GENERATOR})
 | 
			
		||||
string (TOLOWER ${gen_for_path} gen_for_path)
 | 
			
		||||
# HACK: trying to shorten paths for windows CI (which hits 260 MAXPATH easily)
 | 
			
		||||
# @see:  https://issues.jenkins-ci.org/browse/JENKINS-38706?focusedCommentId=339847
 | 
			
		||||
string (REPLACE "visual_studio" "vs" gen_for_path ${gen_for_path})
 | 
			
		||||
if (NOT DEFINED NIH_CACHE_ROOT)
 | 
			
		||||
  if (DEFINED ENV{NIH_CACHE_ROOT})
 | 
			
		||||
    set (NIH_CACHE_ROOT $ENV{NIH_CACHE_ROOT})
 | 
			
		||||
  else ()
 | 
			
		||||
    set (NIH_CACHE_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/.nih_c")
 | 
			
		||||
  endif ()
 | 
			
		||||
endif ()
 | 
			
		||||
set (nih_cache_path
 | 
			
		||||
  "${NIH_CACHE_ROOT}/${gen_for_path}/${CMAKE_CXX_COMPILER_ID}_${CMAKE_CXX_COMPILER_VERSION}")
 | 
			
		||||
if (NOT is_multiconfig)
 | 
			
		||||
  set (nih_cache_path "${nih_cache_path}/${CMAKE_BUILD_TYPE}")
 | 
			
		||||
endif ()
 | 
			
		||||
file(TO_CMAKE_PATH "${nih_cache_path}" nih_cache_path)
 | 
			
		||||
message (STATUS "NIH-EP cache path: ${nih_cache_path}")
 | 
			
		||||
## two convenience variables:
 | 
			
		||||
set (ep_lib_prefix ${CMAKE_STATIC_LIBRARY_PREFIX})
 | 
			
		||||
set (ep_lib_suffix ${CMAKE_STATIC_LIBRARY_SUFFIX})
 | 
			
		||||
 | 
			
		||||
# this is a setting for FetchContent and needs to be
 | 
			
		||||
# a cache variable
 | 
			
		||||
# https://cmake.org/cmake/help/latest/module/FetchContent.html#populating-the-content
 | 
			
		||||
set (FETCHCONTENT_BASE_DIR ${nih_cache_path} CACHE STRING "" FORCE)
 | 
			
		||||
@@ -1,52 +0,0 @@
 | 
			
		||||
find_package(Boost 1.83 REQUIRED
 | 
			
		||||
  COMPONENTS
 | 
			
		||||
    chrono
 | 
			
		||||
    container
 | 
			
		||||
    context
 | 
			
		||||
    coroutine
 | 
			
		||||
    date_time
 | 
			
		||||
    filesystem
 | 
			
		||||
    program_options
 | 
			
		||||
    regex
 | 
			
		||||
    system
 | 
			
		||||
    thread
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
add_library(ripple_boost INTERFACE)
 | 
			
		||||
add_library(Ripple::boost ALIAS ripple_boost)
 | 
			
		||||
if(XCODE)
 | 
			
		||||
  target_include_directories(ripple_boost BEFORE INTERFACE ${Boost_INCLUDE_DIRS})
 | 
			
		||||
  target_compile_options(ripple_boost INTERFACE --system-header-prefix="boost/")
 | 
			
		||||
else()
 | 
			
		||||
  target_include_directories(ripple_boost SYSTEM BEFORE INTERFACE ${Boost_INCLUDE_DIRS})
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
target_link_libraries(ripple_boost
 | 
			
		||||
  INTERFACE
 | 
			
		||||
    Boost::boost
 | 
			
		||||
    Boost::chrono
 | 
			
		||||
    Boost::container
 | 
			
		||||
    Boost::coroutine
 | 
			
		||||
    Boost::date_time
 | 
			
		||||
    Boost::filesystem
 | 
			
		||||
    Boost::program_options
 | 
			
		||||
    Boost::regex
 | 
			
		||||
    Boost::system
 | 
			
		||||
    Boost::iostreams
 | 
			
		||||
    Boost::thread)
 | 
			
		||||
if(Boost_COMPILER)
 | 
			
		||||
  target_link_libraries(ripple_boost INTERFACE Boost::disable_autolinking)
 | 
			
		||||
endif()
 | 
			
		||||
if(san AND is_clang)
 | 
			
		||||
  # TODO: gcc does not support -fsanitize-blacklist...can we do something else
 | 
			
		||||
  # for gcc ?
 | 
			
		||||
  if(NOT Boost_INCLUDE_DIRS AND TARGET Boost::headers)
 | 
			
		||||
    get_target_property(Boost_INCLUDE_DIRS Boost::headers INTERFACE_INCLUDE_DIRECTORIES)
 | 
			
		||||
  endif()
 | 
			
		||||
  message(STATUS "Adding [${Boost_INCLUDE_DIRS}] to sanitizer blacklist")
 | 
			
		||||
  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/san_bl.txt "src:${Boost_INCLUDE_DIRS}/*")
 | 
			
		||||
  target_compile_options(opts
 | 
			
		||||
    INTERFACE
 | 
			
		||||
      # ignore boost headers for sanitizing
 | 
			
		||||
      -fsanitize-blacklist=${CMAKE_CURRENT_BINARY_DIR}/san_bl.txt)
 | 
			
		||||
endif()
 | 
			
		||||
@@ -1,22 +0,0 @@
 | 
			
		||||
find_package(Protobuf 3.8)
 | 
			
		||||
 | 
			
		||||
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/proto_gen)
 | 
			
		||||
set(ccbd ${CMAKE_CURRENT_BINARY_DIR})
 | 
			
		||||
set(CMAKE_CURRENT_BINARY_DIR ${CMAKE_BINARY_DIR}/proto_gen)
 | 
			
		||||
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS src/ripple/proto/ripple.proto)
 | 
			
		||||
set(CMAKE_CURRENT_BINARY_DIR ${ccbd})
 | 
			
		||||
 | 
			
		||||
add_library(pbufs STATIC ${PROTO_SRCS} ${PROTO_HDRS})
 | 
			
		||||
target_include_directories(pbufs SYSTEM PUBLIC
 | 
			
		||||
  ${CMAKE_BINARY_DIR}/proto_gen
 | 
			
		||||
  ${CMAKE_BINARY_DIR}/proto_gen/src/ripple/proto
 | 
			
		||||
)
 | 
			
		||||
target_link_libraries(pbufs protobuf::libprotobuf)
 | 
			
		||||
target_compile_options(pbufs
 | 
			
		||||
  PUBLIC
 | 
			
		||||
    $<$<BOOL:${XCODE}>:
 | 
			
		||||
      --system-header-prefix="google/protobuf"
 | 
			
		||||
      -Wno-deprecated-dynamic-exception-spec
 | 
			
		||||
    >
 | 
			
		||||
)
 | 
			
		||||
add_library(Ripple::pbufs ALIAS pbufs)
 | 
			
		||||
@@ -1,62 +0,0 @@
 | 
			
		||||
find_package(gRPC 1.23)
 | 
			
		||||
 | 
			
		||||
#[=================================[
 | 
			
		||||
   generate protobuf sources for
 | 
			
		||||
   grpc defs and bundle into a
 | 
			
		||||
   static lib
 | 
			
		||||
#]=================================]
 | 
			
		||||
set(GRPC_GEN_DIR "${CMAKE_BINARY_DIR}/proto_gen_grpc")
 | 
			
		||||
file(MAKE_DIRECTORY ${GRPC_GEN_DIR})
 | 
			
		||||
set(GRPC_PROTO_SRCS)
 | 
			
		||||
set(GRPC_PROTO_HDRS)
 | 
			
		||||
set(GRPC_PROTO_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/src/ripple/proto/org")
 | 
			
		||||
file(GLOB_RECURSE GRPC_DEFINITION_FILES LIST_DIRECTORIES false "${GRPC_PROTO_ROOT}/*.proto")
 | 
			
		||||
foreach(file ${GRPC_DEFINITION_FILES})
 | 
			
		||||
  get_filename_component(_abs_file ${file} ABSOLUTE)
 | 
			
		||||
  get_filename_component(_abs_dir ${_abs_file} DIRECTORY)
 | 
			
		||||
  get_filename_component(_basename ${file} NAME_WE)
 | 
			
		||||
  get_filename_component(_proto_inc ${GRPC_PROTO_ROOT} DIRECTORY) # updir one level
 | 
			
		||||
  file(RELATIVE_PATH _rel_root_file ${_proto_inc} ${_abs_file})
 | 
			
		||||
  get_filename_component(_rel_root_dir ${_rel_root_file} DIRECTORY)
 | 
			
		||||
  file(RELATIVE_PATH _rel_dir ${CMAKE_CURRENT_SOURCE_DIR} ${_abs_dir})
 | 
			
		||||
 | 
			
		||||
  set(src_1 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.grpc.pb.cc")
 | 
			
		||||
  set(src_2 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.pb.cc")
 | 
			
		||||
  set(hdr_1 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.grpc.pb.h")
 | 
			
		||||
  set(hdr_2 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.pb.h")
 | 
			
		||||
  add_custom_command(
 | 
			
		||||
    OUTPUT ${src_1} ${src_2} ${hdr_1} ${hdr_2}
 | 
			
		||||
    COMMAND protobuf::protoc
 | 
			
		||||
    ARGS --grpc_out=${GRPC_GEN_DIR}
 | 
			
		||||
         --cpp_out=${GRPC_GEN_DIR}
 | 
			
		||||
         --plugin=protoc-gen-grpc=$<TARGET_FILE:gRPC::grpc_cpp_plugin>
 | 
			
		||||
         -I ${_proto_inc} -I ${_rel_dir}
 | 
			
		||||
         ${_abs_file}
 | 
			
		||||
    DEPENDS ${_abs_file} protobuf::protoc gRPC::grpc_cpp_plugin
 | 
			
		||||
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
 | 
			
		||||
    COMMENT "Running gRPC C++ protocol buffer compiler on ${file}"
 | 
			
		||||
    VERBATIM)
 | 
			
		||||
    set_source_files_properties(${src_1} ${src_2} ${hdr_1} ${hdr_2} PROPERTIES GENERATED TRUE)
 | 
			
		||||
    list(APPEND GRPC_PROTO_SRCS ${src_1} ${src_2})
 | 
			
		||||
    list(APPEND GRPC_PROTO_HDRS ${hdr_1} ${hdr_2})
 | 
			
		||||
endforeach()
 | 
			
		||||
 | 
			
		||||
add_library(grpc_pbufs STATIC ${GRPC_PROTO_SRCS} ${GRPC_PROTO_HDRS})
 | 
			
		||||
#target_include_directories(grpc_pbufs PRIVATE src)
 | 
			
		||||
target_include_directories(grpc_pbufs SYSTEM PUBLIC ${GRPC_GEN_DIR})
 | 
			
		||||
target_link_libraries(grpc_pbufs
 | 
			
		||||
  "gRPC::grpc++"
 | 
			
		||||
  # libgrpc is missing references.
 | 
			
		||||
  absl::random_random
 | 
			
		||||
)
 | 
			
		||||
target_compile_options(grpc_pbufs
 | 
			
		||||
  PRIVATE
 | 
			
		||||
    $<$<BOOL:${MSVC}>:-wd4065>
 | 
			
		||||
    $<$<NOT:$<BOOL:${MSVC}>>:-Wno-deprecated-declarations>
 | 
			
		||||
  PUBLIC
 | 
			
		||||
    $<$<BOOL:${MSVC}>:-wd4996>
 | 
			
		||||
    $<$<BOOL:${XCODE}>:
 | 
			
		||||
      --system-header-prefix="google/protobuf"
 | 
			
		||||
      -Wno-deprecated-dynamic-exception-spec
 | 
			
		||||
    >)
 | 
			
		||||
add_library(Ripple::grpc_pbufs ALIAS grpc_pbufs)
 | 
			
		||||
@@ -1,51 +1,3 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH dep: boost
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
if((NOT DEFINED BOOST_ROOT) AND(DEFINED ENV{BOOST_ROOT}))
 | 
			
		||||
  set(BOOST_ROOT $ENV{BOOST_ROOT})
 | 
			
		||||
endif()
 | 
			
		||||
if((NOT DEFINED BOOST_LIBRARYDIR) AND(DEFINED ENV{BOOST_LIBRARYDIR}))
 | 
			
		||||
  set(BOOST_LIBRARYDIR $ENV{BOOST_LIBRARYDIR})
 | 
			
		||||
endif()
 | 
			
		||||
file(TO_CMAKE_PATH "${BOOST_ROOT}" BOOST_ROOT)
 | 
			
		||||
if(WIN32 OR CYGWIN)
 | 
			
		||||
  # Workaround for MSVC having two boost versions - x86 and x64 on same PC in stage folders
 | 
			
		||||
  if((NOT DEFINED BOOST_LIBRARYDIR) AND (DEFINED BOOST_ROOT))
 | 
			
		||||
    if(IS_DIRECTORY ${BOOST_ROOT}/stage64/lib)
 | 
			
		||||
      set(BOOST_LIBRARYDIR ${BOOST_ROOT}/stage64/lib)
 | 
			
		||||
    elseif(IS_DIRECTORY ${BOOST_ROOT}/stage/lib)
 | 
			
		||||
      set(BOOST_LIBRARYDIR ${BOOST_ROOT}/stage/lib)
 | 
			
		||||
    elseif(IS_DIRECTORY ${BOOST_ROOT}/lib)
 | 
			
		||||
      set(BOOST_LIBRARYDIR ${BOOST_ROOT}/lib)
 | 
			
		||||
    else()
 | 
			
		||||
      message(WARNING "Did not find expected boost library dir. "
 | 
			
		||||
        "Defaulting to ${BOOST_ROOT}")
 | 
			
		||||
      set(BOOST_LIBRARYDIR ${BOOST_ROOT})
 | 
			
		||||
    endif()
 | 
			
		||||
  endif()
 | 
			
		||||
endif()
 | 
			
		||||
message(STATUS "BOOST_ROOT: ${BOOST_ROOT}")
 | 
			
		||||
message(STATUS "BOOST_LIBRARYDIR: ${BOOST_LIBRARYDIR}")
 | 
			
		||||
 | 
			
		||||
# uncomment the following as needed to debug FindBoost issues:
 | 
			
		||||
#set(Boost_DEBUG ON)
 | 
			
		||||
 | 
			
		||||
#[=========================================================[
 | 
			
		||||
   boost dynamic libraries don't trivially support @rpath
 | 
			
		||||
   linking right now (cmake's default), so just force
 | 
			
		||||
   static linking for macos, or if requested on linux by flag
 | 
			
		||||
#]=========================================================]
 | 
			
		||||
if(static)
 | 
			
		||||
  set(Boost_USE_STATIC_LIBS ON)
 | 
			
		||||
endif()
 | 
			
		||||
set(Boost_USE_MULTITHREADED ON)
 | 
			
		||||
if(static AND NOT APPLE)
 | 
			
		||||
  set(Boost_USE_STATIC_RUNTIME ON)
 | 
			
		||||
else()
 | 
			
		||||
  set(Boost_USE_STATIC_RUNTIME OFF)
 | 
			
		||||
endif()
 | 
			
		||||
# TBD:
 | 
			
		||||
# Boost_USE_DEBUG_RUNTIME:  When ON, uses Boost libraries linked against the
 | 
			
		||||
find_package(Boost 1.86 REQUIRED
 | 
			
		||||
  COMPONENTS
 | 
			
		||||
    chrono
 | 
			
		||||
@@ -57,12 +9,12 @@ find_package(Boost 1.86 REQUIRED
 | 
			
		||||
    program_options
 | 
			
		||||
    regex
 | 
			
		||||
    system
 | 
			
		||||
    iostreams
 | 
			
		||||
    thread)
 | 
			
		||||
    thread
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
add_library(ripple_boost INTERFACE)
 | 
			
		||||
add_library(Ripple::boost ALIAS ripple_boost)
 | 
			
		||||
if(is_xcode)
 | 
			
		||||
if(XCODE)
 | 
			
		||||
  target_include_directories(ripple_boost BEFORE INTERFACE ${Boost_INCLUDE_DIRS})
 | 
			
		||||
  target_compile_options(ripple_boost INTERFACE --system-header-prefix="boost/")
 | 
			
		||||
else()
 | 
			
		||||
@@ -77,10 +29,10 @@ target_link_libraries(ripple_boost
 | 
			
		||||
    Boost::coroutine
 | 
			
		||||
    Boost::date_time
 | 
			
		||||
    Boost::filesystem
 | 
			
		||||
    Boost::iostreams
 | 
			
		||||
    Boost::program_options
 | 
			
		||||
    Boost::regex
 | 
			
		||||
    Boost::system
 | 
			
		||||
    Boost::iostreams
 | 
			
		||||
    Boost::thread)
 | 
			
		||||
if(Boost_COMPILER)
 | 
			
		||||
  target_link_libraries(ripple_boost INTERFACE Boost::disable_autolinking)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,28 +0,0 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH dep: ed25519-donna
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
add_library (ed25519-donna STATIC
 | 
			
		||||
  src/ed25519-donna/ed25519.c)
 | 
			
		||||
target_include_directories (ed25519-donna
 | 
			
		||||
  PUBLIC
 | 
			
		||||
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
 | 
			
		||||
    $<INSTALL_INTERFACE:include>
 | 
			
		||||
  PRIVATE
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/src/ed25519-donna)
 | 
			
		||||
#[=========================================================[
 | 
			
		||||
   NOTE for macos:
 | 
			
		||||
   https://github.com/floodyberry/ed25519-donna/issues/29
 | 
			
		||||
   our source for ed25519-donna-portable.h has been
 | 
			
		||||
   patched to workaround this.
 | 
			
		||||
#]=========================================================]
 | 
			
		||||
target_link_libraries (ed25519-donna PUBLIC OpenSSL::SSL)
 | 
			
		||||
add_library (NIH::ed25519-donna ALIAS ed25519-donna)
 | 
			
		||||
target_link_libraries (ripple_libs INTERFACE NIH::ed25519-donna)
 | 
			
		||||
#[===========================[
 | 
			
		||||
   headers installation
 | 
			
		||||
#]===========================]
 | 
			
		||||
install (
 | 
			
		||||
  FILES
 | 
			
		||||
    src/ed25519-donna/ed25519.h
 | 
			
		||||
  DESTINATION include/ed25519-donna)
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,47 +0,0 @@
 | 
			
		||||
# - Try to find jemalloc
 | 
			
		||||
# Once done this will define
 | 
			
		||||
#  JEMALLOC_FOUND - System has jemalloc
 | 
			
		||||
#  JEMALLOC_INCLUDE_DIRS - The jemalloc include directories
 | 
			
		||||
#  JEMALLOC_LIBRARIES - The libraries needed to use jemalloc
 | 
			
		||||
 | 
			
		||||
if(NOT USE_BUNDLED_JEMALLOC)
 | 
			
		||||
  find_package(PkgConfig)
 | 
			
		||||
  if (PKG_CONFIG_FOUND)
 | 
			
		||||
    pkg_check_modules(PC_JEMALLOC QUIET jemalloc)
 | 
			
		||||
  endif()
 | 
			
		||||
else()
 | 
			
		||||
  set(PC_JEMALLOC_INCLUDEDIR)
 | 
			
		||||
  set(PC_JEMALLOC_INCLUDE_DIRS)
 | 
			
		||||
  set(PC_JEMALLOC_LIBDIR)
 | 
			
		||||
  set(PC_JEMALLOC_LIBRARY_DIRS)
 | 
			
		||||
  set(LIMIT_SEARCH NO_DEFAULT_PATH)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
set(JEMALLOC_DEFINITIONS ${PC_JEMALLOC_CFLAGS_OTHER})
 | 
			
		||||
 | 
			
		||||
find_path(JEMALLOC_INCLUDE_DIR jemalloc/jemalloc.h
 | 
			
		||||
          PATHS ${PC_JEMALLOC_INCLUDEDIR} ${PC_JEMALLOC_INCLUDE_DIRS}
 | 
			
		||||
          ${LIMIT_SEARCH})
 | 
			
		||||
 | 
			
		||||
# If we're asked to use static linkage, add libjemalloc.a as a preferred library name.
 | 
			
		||||
if(JEMALLOC_USE_STATIC)
 | 
			
		||||
  list(APPEND JEMALLOC_NAMES
 | 
			
		||||
    "${CMAKE_STATIC_LIBRARY_PREFIX}jemalloc${CMAKE_STATIC_LIBRARY_SUFFIX}")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
list(APPEND JEMALLOC_NAMES jemalloc)
 | 
			
		||||
 | 
			
		||||
find_library(JEMALLOC_LIBRARY NAMES ${JEMALLOC_NAMES}
 | 
			
		||||
  HINTS ${PC_JEMALLOC_LIBDIR} ${PC_JEMALLOC_LIBRARY_DIRS}
 | 
			
		||||
  ${LIMIT_SEARCH})
 | 
			
		||||
 | 
			
		||||
set(JEMALLOC_LIBRARIES ${JEMALLOC_LIBRARY})
 | 
			
		||||
set(JEMALLOC_INCLUDE_DIRS ${JEMALLOC_INCLUDE_DIR})
 | 
			
		||||
 | 
			
		||||
include(FindPackageHandleStandardArgs)
 | 
			
		||||
# handle the QUIETLY and REQUIRED arguments and set JEMALLOC_FOUND to TRUE
 | 
			
		||||
# if all listed variables are TRUE
 | 
			
		||||
find_package_handle_standard_args(JeMalloc DEFAULT_MSG
 | 
			
		||||
  JEMALLOC_LIBRARY JEMALLOC_INCLUDE_DIR)
 | 
			
		||||
 | 
			
		||||
mark_as_advanced(JEMALLOC_INCLUDE_DIR JEMALLOC_LIBRARY)
 | 
			
		||||
@@ -1,22 +0,0 @@
 | 
			
		||||
find_package (PkgConfig REQUIRED)
 | 
			
		||||
pkg_search_module (libarchive_PC QUIET libarchive>=3.4.3)
 | 
			
		||||
 | 
			
		||||
if(static)
 | 
			
		||||
  set(LIBARCHIVE_LIB libarchive.a)
 | 
			
		||||
else()
 | 
			
		||||
  set(LIBARCHIVE_LIB archive)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
find_library (archive
 | 
			
		||||
  NAMES ${LIBARCHIVE_LIB}
 | 
			
		||||
  HINTS
 | 
			
		||||
    ${libarchive_PC_LIBDIR}
 | 
			
		||||
    ${libarchive_PC_LIBRARY_DIRS}
 | 
			
		||||
  NO_DEFAULT_PATH)
 | 
			
		||||
 | 
			
		||||
find_path (LIBARCHIVE_INCLUDE_DIR
 | 
			
		||||
  NAMES archive.h
 | 
			
		||||
  HINTS
 | 
			
		||||
    ${libarchive_PC_INCLUDEDIR}
 | 
			
		||||
    ${libarchive_PC_INCLUDEDIRS}
 | 
			
		||||
  NO_DEFAULT_PATH)
 | 
			
		||||
@@ -1,24 +0,0 @@
 | 
			
		||||
find_package (PkgConfig)
 | 
			
		||||
if (PKG_CONFIG_FOUND)
 | 
			
		||||
  pkg_search_module (lz4_PC QUIET liblz4>=1.9)
 | 
			
		||||
endif ()
 | 
			
		||||
 | 
			
		||||
if(static)
 | 
			
		||||
  set(LZ4_LIB liblz4.a)
 | 
			
		||||
else()
 | 
			
		||||
  set(LZ4_LIB lz4.so)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
find_library (lz4
 | 
			
		||||
  NAMES ${LZ4_LIB}
 | 
			
		||||
  HINTS
 | 
			
		||||
    ${lz4_PC_LIBDIR}
 | 
			
		||||
    ${lz4_PC_LIBRARY_DIRS}
 | 
			
		||||
  NO_DEFAULT_PATH)
 | 
			
		||||
 | 
			
		||||
find_path (LZ4_INCLUDE_DIR
 | 
			
		||||
  NAMES lz4.h
 | 
			
		||||
  HINTS
 | 
			
		||||
    ${lz4_PC_INCLUDEDIR}
 | 
			
		||||
    ${lz4_PC_INCLUDEDIRS}
 | 
			
		||||
  NO_DEFAULT_PATH)
 | 
			
		||||
@@ -1,24 +0,0 @@
 | 
			
		||||
find_package (PkgConfig)
 | 
			
		||||
if (PKG_CONFIG_FOUND)
 | 
			
		||||
  pkg_search_module (secp256k1_PC QUIET libsecp256k1)
 | 
			
		||||
endif ()
 | 
			
		||||
 | 
			
		||||
if(static)
 | 
			
		||||
  set(SECP256K1_LIB libsecp256k1.a)
 | 
			
		||||
else()
 | 
			
		||||
  set(SECP256K1_LIB secp256k1)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
find_library(secp256k1
 | 
			
		||||
  NAMES ${SECP256K1_LIB}
 | 
			
		||||
  HINTS
 | 
			
		||||
    ${secp256k1_PC_LIBDIR}
 | 
			
		||||
    ${secp256k1_PC_LIBRARY_PATHS}
 | 
			
		||||
  NO_DEFAULT_PATH)
 | 
			
		||||
 | 
			
		||||
find_path (SECP256K1_INCLUDE_DIR
 | 
			
		||||
  NAMES secp256k1.h
 | 
			
		||||
  HINTS
 | 
			
		||||
    ${secp256k1_PC_INCLUDEDIR}
 | 
			
		||||
    ${secp256k1_PC_INCLUDEDIRS}
 | 
			
		||||
  NO_DEFAULT_PATH)
 | 
			
		||||
@@ -1,24 +0,0 @@
 | 
			
		||||
find_package (PkgConfig)
 | 
			
		||||
if (PKG_CONFIG_FOUND)
 | 
			
		||||
  pkg_search_module (snappy_PC QUIET snappy>=1.1.7)
 | 
			
		||||
endif ()
 | 
			
		||||
 | 
			
		||||
if(static)
 | 
			
		||||
  set(SNAPPY_LIB libsnappy.a)
 | 
			
		||||
else()
 | 
			
		||||
  set(SNAPPY_LIB libsnappy.so)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
find_library (snappy
 | 
			
		||||
  NAMES ${SNAPPY_LIB}
 | 
			
		||||
  HINTS
 | 
			
		||||
    ${snappy_PC_LIBDIR}
 | 
			
		||||
    ${snappy_PC_LIBRARY_DIRS}
 | 
			
		||||
  NO_DEFAULT_PATH)
 | 
			
		||||
 | 
			
		||||
find_path (SNAPPY_INCLUDE_DIR
 | 
			
		||||
  NAMES snappy.h
 | 
			
		||||
  HINTS
 | 
			
		||||
    ${snappy_PC_INCLUDEDIR}
 | 
			
		||||
    ${snappy_PC_INCLUDEDIRS}
 | 
			
		||||
  NO_DEFAULT_PATH)
 | 
			
		||||
@@ -1,19 +0,0 @@
 | 
			
		||||
find_package (PkgConfig)
 | 
			
		||||
if (PKG_CONFIG_FOUND)
 | 
			
		||||
  # TBD - currently no soci pkgconfig
 | 
			
		||||
  #pkg_search_module (soci_PC QUIET libsoci_core>=3.2)
 | 
			
		||||
endif ()
 | 
			
		||||
 | 
			
		||||
if(static)
 | 
			
		||||
  set(SOCI_LIB libsoci.a)
 | 
			
		||||
else()
 | 
			
		||||
  set(SOCI_LIB libsoci_core.so)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
find_library (soci
 | 
			
		||||
  NAMES ${SOCI_LIB})
 | 
			
		||||
 | 
			
		||||
find_path (SOCI_INCLUDE_DIR
 | 
			
		||||
  NAMES soci/soci.h)
 | 
			
		||||
 | 
			
		||||
message("SOCI FOUND AT: ${SOCI_LIB}")
 | 
			
		||||
@@ -1,24 +0,0 @@
 | 
			
		||||
find_package (PkgConfig)
 | 
			
		||||
if (PKG_CONFIG_FOUND)
 | 
			
		||||
  pkg_search_module (sqlite_PC QUIET sqlite3>=3.26.0)
 | 
			
		||||
endif ()
 | 
			
		||||
 | 
			
		||||
if(static)
 | 
			
		||||
  set(SQLITE_LIB libsqlite3.a)
 | 
			
		||||
else()
 | 
			
		||||
  set(SQLITE_LIB sqlite3.so)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
find_library (sqlite3
 | 
			
		||||
  NAMES ${SQLITE_LIB}
 | 
			
		||||
  HINTS
 | 
			
		||||
    ${sqlite_PC_LIBDIR}
 | 
			
		||||
    ${sqlite_PC_LIBRARY_DIRS}
 | 
			
		||||
  NO_DEFAULT_PATH)
 | 
			
		||||
 | 
			
		||||
find_path (SQLITE_INCLUDE_DIR
 | 
			
		||||
  NAMES sqlite3.h
 | 
			
		||||
  HINTS
 | 
			
		||||
    ${sqlite_PC_INCLUDEDIR}
 | 
			
		||||
    ${sqlite_PC_INCLUDEDIRS}
 | 
			
		||||
  NO_DEFAULT_PATH)
 | 
			
		||||
@@ -1,163 +0,0 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH dep: libarchive
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
option (local_libarchive "use local build of libarchive." OFF)
 | 
			
		||||
add_library (archive_lib UNKNOWN IMPORTED GLOBAL)
 | 
			
		||||
 | 
			
		||||
if (NOT local_libarchive)
 | 
			
		||||
  if (NOT WIN32)
 | 
			
		||||
    find_package(libarchive_pc REQUIRED)
 | 
			
		||||
  endif ()
 | 
			
		||||
  if (archive)
 | 
			
		||||
    message (STATUS "Found libarchive using pkg-config. Using ${archive}.")
 | 
			
		||||
    set_target_properties (archive_lib PROPERTIES
 | 
			
		||||
      IMPORTED_LOCATION_DEBUG
 | 
			
		||||
        ${archive}
 | 
			
		||||
      IMPORTED_LOCATION_RELEASE
 | 
			
		||||
        ${archive}
 | 
			
		||||
      INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
        ${LIBARCHIVE_INCLUDE_DIR})
 | 
			
		||||
      # pkg-config can return extra info for static lib linking
 | 
			
		||||
      # this is probably needed/useful generally, but apply
 | 
			
		||||
      # to APPLE for now (mostly for homebrew)
 | 
			
		||||
      if (APPLE AND static AND libarchive_PC_STATIC_LIBRARIES)
 | 
			
		||||
        message(STATUS "NOTE: libarchive static libs: ${libarchive_PC_STATIC_LIBRARIES}")
 | 
			
		||||
        # also, APPLE seems to need iconv...maybe linux does too (TBD)
 | 
			
		||||
        target_link_libraries (archive_lib
 | 
			
		||||
          INTERFACE iconv ${libarchive_PC_STATIC_LIBRARIES})
 | 
			
		||||
      endif ()
 | 
			
		||||
  else ()
 | 
			
		||||
    ## now try searching using the minimal find module that cmake provides
 | 
			
		||||
    find_package(LibArchive 3.4.3 QUIET)
 | 
			
		||||
    if (LibArchive_FOUND)
 | 
			
		||||
      if (static)
 | 
			
		||||
        # find module doesn't find static libs currently, so we re-search
 | 
			
		||||
        get_filename_component(_loc ${LibArchive_LIBRARY} DIRECTORY)
 | 
			
		||||
        find_library(_la_static
 | 
			
		||||
          NAMES libarchive.a archive_static.lib archive.lib
 | 
			
		||||
          PATHS ${_loc})
 | 
			
		||||
        if (_la_static)
 | 
			
		||||
          set (_la_lib ${_la_static})
 | 
			
		||||
        else ()
 | 
			
		||||
          message (WARNING "unable to find libarchive static lib - switching to local build")
 | 
			
		||||
          set (local_libarchive ON CACHE BOOL "" FORCE)
 | 
			
		||||
        endif ()
 | 
			
		||||
      else ()
 | 
			
		||||
        set (_la_lib ${LibArchive_LIBRARY})
 | 
			
		||||
      endif ()
 | 
			
		||||
      if (NOT local_libarchive)
 | 
			
		||||
        message (STATUS "Found libarchive using module/config. Using ${_la_lib}.")
 | 
			
		||||
        set_target_properties (archive_lib PROPERTIES
 | 
			
		||||
          IMPORTED_LOCATION_DEBUG
 | 
			
		||||
            ${_la_lib}
 | 
			
		||||
          IMPORTED_LOCATION_RELEASE
 | 
			
		||||
            ${_la_lib}
 | 
			
		||||
          INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
            ${LibArchive_INCLUDE_DIRS})
 | 
			
		||||
      endif ()
 | 
			
		||||
    else ()
 | 
			
		||||
      set (local_libarchive ON CACHE BOOL "" FORCE)
 | 
			
		||||
    endif ()
 | 
			
		||||
  endif ()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if (local_libarchive)
 | 
			
		||||
  set (lib_post "")
 | 
			
		||||
  if (MSVC)
 | 
			
		||||
    set (lib_post "_static")
 | 
			
		||||
  endif ()
 | 
			
		||||
  ExternalProject_Add (libarchive
 | 
			
		||||
    PREFIX ${nih_cache_path}
 | 
			
		||||
    GIT_REPOSITORY https://github.com/libarchive/libarchive.git
 | 
			
		||||
    GIT_TAG v3.4.3
 | 
			
		||||
    CMAKE_ARGS
 | 
			
		||||
      # passing the compiler seems to be needed for windows CI, sadly
 | 
			
		||||
      -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
 | 
			
		||||
      -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
 | 
			
		||||
      $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-DCMAKE_VERBOSE_MAKEFILE=ON>
 | 
			
		||||
      -DCMAKE_DEBUG_POSTFIX=_d
 | 
			
		||||
      $<$<NOT:$<BOOL:${is_multiconfig}>>:-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}>
 | 
			
		||||
      -DENABLE_LZ4=ON
 | 
			
		||||
      -ULZ4_*
 | 
			
		||||
      -DLZ4_INCLUDE_DIR=$<JOIN:$<TARGET_PROPERTY:lz4_lib,INTERFACE_INCLUDE_DIRECTORIES>,::>
 | 
			
		||||
      # because we are building a static lib, this lz4 library doesn't
 | 
			
		||||
      # actually matter since you can't generally link static libs to other static
 | 
			
		||||
      # libs. The include files are needed, but the library itself is not (until
 | 
			
		||||
      # we link our application, at which point we use the lz4 we built above).
 | 
			
		||||
      # nonetheless, we need to provide a library to libarchive else it will
 | 
			
		||||
      # NOT include lz4 support when configuring
 | 
			
		||||
      -DLZ4_LIBRARY=$<IF:$<CONFIG:Debug>,$<TARGET_PROPERTY:lz4_lib,IMPORTED_LOCATION_DEBUG>,$<TARGET_PROPERTY:lz4_lib,IMPORTED_LOCATION_RELEASE>>
 | 
			
		||||
      -DENABLE_WERROR=OFF
 | 
			
		||||
      -DENABLE_TAR=OFF
 | 
			
		||||
      -DENABLE_TAR_SHARED=OFF
 | 
			
		||||
      -DENABLE_INSTALL=ON
 | 
			
		||||
      -DENABLE_NETTLE=OFF
 | 
			
		||||
      -DENABLE_OPENSSL=OFF
 | 
			
		||||
      -DENABLE_LZO=OFF
 | 
			
		||||
      -DENABLE_LZMA=OFF
 | 
			
		||||
      -DENABLE_ZLIB=OFF
 | 
			
		||||
      -DENABLE_BZip2=OFF
 | 
			
		||||
      -DENABLE_LIBXML2=OFF
 | 
			
		||||
      -DENABLE_EXPAT=OFF
 | 
			
		||||
      -DENABLE_PCREPOSIX=OFF
 | 
			
		||||
      -DENABLE_LibGCC=OFF
 | 
			
		||||
      -DENABLE_CNG=OFF
 | 
			
		||||
      -DENABLE_CPIO=OFF
 | 
			
		||||
      -DENABLE_CPIO_SHARED=OFF
 | 
			
		||||
      -DENABLE_CAT=OFF
 | 
			
		||||
      -DENABLE_CAT_SHARED=OFF
 | 
			
		||||
      -DENABLE_XATTR=OFF
 | 
			
		||||
      -DENABLE_ACL=OFF
 | 
			
		||||
      -DENABLE_ICONV=OFF
 | 
			
		||||
      -DENABLE_TEST=OFF
 | 
			
		||||
      -DENABLE_COVERAGE=OFF
 | 
			
		||||
      $<$<BOOL:${MSVC}>:
 | 
			
		||||
        "-DCMAKE_C_FLAGS=-GR -Gd -fp:precise -FS -MP"
 | 
			
		||||
        "-DCMAKE_C_FLAGS_DEBUG=-MTd"
 | 
			
		||||
        "-DCMAKE_C_FLAGS_RELEASE=-MT"
 | 
			
		||||
      >
 | 
			
		||||
    LIST_SEPARATOR ::
 | 
			
		||||
    LOG_BUILD ON
 | 
			
		||||
    LOG_CONFIGURE ON
 | 
			
		||||
    BUILD_COMMAND
 | 
			
		||||
      ${CMAKE_COMMAND}
 | 
			
		||||
      --build .
 | 
			
		||||
      --config $<CONFIG>
 | 
			
		||||
      --target archive_static
 | 
			
		||||
      --parallel ${ep_procs}
 | 
			
		||||
      $<$<BOOL:${is_multiconfig}>:
 | 
			
		||||
        COMMAND
 | 
			
		||||
          ${CMAKE_COMMAND} -E copy
 | 
			
		||||
            <BINARY_DIR>/libarchive/$<CONFIG>/${ep_lib_prefix}archive${lib_post}$<$<CONFIG:Debug>:_d>${ep_lib_suffix}
 | 
			
		||||
            <BINARY_DIR>/libarchive
 | 
			
		||||
        >
 | 
			
		||||
    TEST_COMMAND ""
 | 
			
		||||
    INSTALL_COMMAND ""
 | 
			
		||||
    DEPENDS lz4_lib
 | 
			
		||||
    BUILD_BYPRODUCTS
 | 
			
		||||
      <BINARY_DIR>/libarchive/${ep_lib_prefix}archive${lib_post}${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/libarchive/${ep_lib_prefix}archive${lib_post}_d${ep_lib_suffix}
 | 
			
		||||
  )
 | 
			
		||||
  ExternalProject_Get_Property (libarchive BINARY_DIR)
 | 
			
		||||
  ExternalProject_Get_Property (libarchive SOURCE_DIR)
 | 
			
		||||
  if (CMAKE_VERBOSE_MAKEFILE)
 | 
			
		||||
    print_ep_logs (libarchive)
 | 
			
		||||
  endif ()
 | 
			
		||||
  file (MAKE_DIRECTORY ${SOURCE_DIR}/libarchive)
 | 
			
		||||
  set_target_properties (archive_lib PROPERTIES
 | 
			
		||||
    IMPORTED_LOCATION_DEBUG
 | 
			
		||||
      ${BINARY_DIR}/libarchive/${ep_lib_prefix}archive${lib_post}_d${ep_lib_suffix}
 | 
			
		||||
    IMPORTED_LOCATION_RELEASE
 | 
			
		||||
      ${BINARY_DIR}/libarchive/${ep_lib_prefix}archive${lib_post}${ep_lib_suffix}
 | 
			
		||||
    INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
      ${SOURCE_DIR}/libarchive
 | 
			
		||||
    INTERFACE_COMPILE_DEFINITIONS
 | 
			
		||||
      LIBARCHIVE_STATIC)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
add_dependencies (archive_lib libarchive)
 | 
			
		||||
target_link_libraries (archive_lib INTERFACE lz4_lib)
 | 
			
		||||
target_link_libraries (ripple_libs INTERFACE archive_lib)
 | 
			
		||||
exclude_if_included (libarchive)
 | 
			
		||||
exclude_if_included (archive_lib)
 | 
			
		||||
@@ -1,79 +0,0 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH dep: lz4
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
add_library (lz4_lib STATIC IMPORTED GLOBAL)
 | 
			
		||||
 | 
			
		||||
if (NOT WIN32)
 | 
			
		||||
  find_package(lz4)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(lz4)
 | 
			
		||||
  set_target_properties (lz4_lib PROPERTIES
 | 
			
		||||
    IMPORTED_LOCATION_DEBUG
 | 
			
		||||
      ${lz4}
 | 
			
		||||
    IMPORTED_LOCATION_RELEASE
 | 
			
		||||
      ${lz4}
 | 
			
		||||
    INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
      ${LZ4_INCLUDE_DIR})
 | 
			
		||||
 | 
			
		||||
else()
 | 
			
		||||
  ExternalProject_Add (lz4
 | 
			
		||||
    PREFIX ${nih_cache_path}
 | 
			
		||||
    GIT_REPOSITORY https://github.com/lz4/lz4.git
 | 
			
		||||
    GIT_TAG v1.9.2
 | 
			
		||||
    SOURCE_SUBDIR contrib/cmake_unofficial
 | 
			
		||||
    CMAKE_ARGS
 | 
			
		||||
      -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
 | 
			
		||||
      -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
 | 
			
		||||
      $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-DCMAKE_VERBOSE_MAKEFILE=ON>
 | 
			
		||||
      -DCMAKE_DEBUG_POSTFIX=_d
 | 
			
		||||
      $<$<NOT:$<BOOL:${is_multiconfig}>>:-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}>
 | 
			
		||||
      -DBUILD_STATIC_LIBS=ON
 | 
			
		||||
      -DBUILD_SHARED_LIBS=OFF
 | 
			
		||||
      $<$<BOOL:${MSVC}>:
 | 
			
		||||
        "-DCMAKE_C_FLAGS=-GR -Gd -fp:precise -FS -MP"
 | 
			
		||||
        "-DCMAKE_C_FLAGS_DEBUG=-MTd"
 | 
			
		||||
        "-DCMAKE_C_FLAGS_RELEASE=-MT"
 | 
			
		||||
      >
 | 
			
		||||
    LOG_BUILD ON
 | 
			
		||||
    LOG_CONFIGURE ON
 | 
			
		||||
    BUILD_COMMAND
 | 
			
		||||
      ${CMAKE_COMMAND}
 | 
			
		||||
      --build .
 | 
			
		||||
      --config $<CONFIG>
 | 
			
		||||
      --target lz4_static
 | 
			
		||||
      --parallel ${ep_procs}
 | 
			
		||||
      $<$<BOOL:${is_multiconfig}>:
 | 
			
		||||
        COMMAND
 | 
			
		||||
          ${CMAKE_COMMAND} -E copy
 | 
			
		||||
          <BINARY_DIR>/$<CONFIG>/${ep_lib_prefix}lz4$<$<CONFIG:Debug>:_d>${ep_lib_suffix}
 | 
			
		||||
          <BINARY_DIR>
 | 
			
		||||
        >
 | 
			
		||||
    TEST_COMMAND ""
 | 
			
		||||
    INSTALL_COMMAND ""
 | 
			
		||||
    BUILD_BYPRODUCTS
 | 
			
		||||
      <BINARY_DIR>/${ep_lib_prefix}lz4${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/${ep_lib_prefix}lz4_d${ep_lib_suffix}
 | 
			
		||||
  )
 | 
			
		||||
  ExternalProject_Get_Property (lz4 BINARY_DIR)
 | 
			
		||||
  ExternalProject_Get_Property (lz4 SOURCE_DIR)
 | 
			
		||||
 | 
			
		||||
  file (MAKE_DIRECTORY ${SOURCE_DIR}/lz4)
 | 
			
		||||
  set_target_properties (lz4_lib PROPERTIES
 | 
			
		||||
    IMPORTED_LOCATION_DEBUG
 | 
			
		||||
      ${BINARY_DIR}/${ep_lib_prefix}lz4_d${ep_lib_suffix}
 | 
			
		||||
    IMPORTED_LOCATION_RELEASE
 | 
			
		||||
      ${BINARY_DIR}/${ep_lib_prefix}lz4${ep_lib_suffix}
 | 
			
		||||
    INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
      ${SOURCE_DIR}/lib)
 | 
			
		||||
 | 
			
		||||
  if (CMAKE_VERBOSE_MAKEFILE)
 | 
			
		||||
    print_ep_logs (lz4)
 | 
			
		||||
  endif ()
 | 
			
		||||
  add_dependencies (lz4_lib lz4)
 | 
			
		||||
  target_link_libraries (ripple_libs INTERFACE lz4_lib)
 | 
			
		||||
  exclude_if_included (lz4)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
exclude_if_included (lz4_lib)
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH dep: nudb
 | 
			
		||||
 | 
			
		||||
   NuDB is header-only, thus is an INTERFACE lib in CMake.
 | 
			
		||||
   TODO: move the library definition into NuDB repo and add
 | 
			
		||||
   proper targets and export/install
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
if (is_root_project) # NuDB not needed in the case of xrpl_core inclusion build
 | 
			
		||||
  add_library (nudb INTERFACE)
 | 
			
		||||
  FetchContent_Declare(
 | 
			
		||||
    nudb_src
 | 
			
		||||
    GIT_REPOSITORY https://github.com/CPPAlliance/NuDB.git
 | 
			
		||||
    GIT_TAG        2.0.5
 | 
			
		||||
  )
 | 
			
		||||
  FetchContent_GetProperties(nudb_src)
 | 
			
		||||
  if(NOT nudb_src_POPULATED)
 | 
			
		||||
    message (STATUS "Pausing to download NuDB...")
 | 
			
		||||
    FetchContent_Populate(nudb_src)
 | 
			
		||||
  endif()
 | 
			
		||||
 | 
			
		||||
  file(TO_CMAKE_PATH "${nudb_src_SOURCE_DIR}" nudb_src_SOURCE_DIR)
 | 
			
		||||
  # specify as system includes so as to avoid warnings
 | 
			
		||||
  target_include_directories (nudb SYSTEM INTERFACE ${nudb_src_SOURCE_DIR}/include)
 | 
			
		||||
  target_link_libraries (nudb
 | 
			
		||||
    INTERFACE
 | 
			
		||||
      Boost::thread
 | 
			
		||||
      Boost::system)
 | 
			
		||||
  add_library (NIH::nudb ALIAS nudb)
 | 
			
		||||
  target_link_libraries (ripple_libs INTERFACE NIH::nudb)
 | 
			
		||||
endif ()
 | 
			
		||||
@@ -1,48 +0,0 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH dep: openssl
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
#[===============================================[
 | 
			
		||||
  OPENSSL_ROOT_DIR is the only variable that
 | 
			
		||||
  FindOpenSSL honors for locating, so convert any
 | 
			
		||||
  OPENSSL_ROOT vars to this
 | 
			
		||||
#]===============================================]
 | 
			
		||||
if (NOT DEFINED OPENSSL_ROOT_DIR)
 | 
			
		||||
  if (DEFINED ENV{OPENSSL_ROOT})
 | 
			
		||||
    set (OPENSSL_ROOT_DIR $ENV{OPENSSL_ROOT})
 | 
			
		||||
  elseif (HOMEBREW)
 | 
			
		||||
    execute_process (COMMAND ${HOMEBREW} --prefix openssl
 | 
			
		||||
      OUTPUT_VARIABLE OPENSSL_ROOT_DIR
 | 
			
		||||
      OUTPUT_STRIP_TRAILING_WHITESPACE)
 | 
			
		||||
  endif ()
 | 
			
		||||
  file (TO_CMAKE_PATH "${OPENSSL_ROOT_DIR}" OPENSSL_ROOT_DIR)
 | 
			
		||||
endif ()
 | 
			
		||||
 | 
			
		||||
if (static)
 | 
			
		||||
  set (OPENSSL_USE_STATIC_LIBS ON)
 | 
			
		||||
endif ()
 | 
			
		||||
set (OPENSSL_MSVC_STATIC_RT ON)
 | 
			
		||||
find_package (OpenSSL 1.1.1 REQUIRED)
 | 
			
		||||
target_link_libraries (ripple_libs
 | 
			
		||||
  INTERFACE
 | 
			
		||||
    OpenSSL::SSL
 | 
			
		||||
    OpenSSL::Crypto)
 | 
			
		||||
# disable SSLv2...this can also be done when building/configuring OpenSSL
 | 
			
		||||
set_target_properties(OpenSSL::SSL PROPERTIES
 | 
			
		||||
    INTERFACE_COMPILE_DEFINITIONS OPENSSL_NO_SSL2)
 | 
			
		||||
#[=========================================================[
 | 
			
		||||
   https://gitlab.kitware.com/cmake/cmake/issues/16885
 | 
			
		||||
   depending on how openssl is built, it might depend
 | 
			
		||||
   on zlib. In fact, the openssl find package should
 | 
			
		||||
   figure this out for us, but it does not currently...
 | 
			
		||||
   so let's add zlib ourselves to the lib list
 | 
			
		||||
   TODO: investigate linking to static zlib for static
 | 
			
		||||
   build option
 | 
			
		||||
#]=========================================================]
 | 
			
		||||
find_package (ZLIB)
 | 
			
		||||
set (has_zlib FALSE)
 | 
			
		||||
if (TARGET ZLIB::ZLIB)
 | 
			
		||||
  set_target_properties(OpenSSL::Crypto PROPERTIES
 | 
			
		||||
    INTERFACE_LINK_LIBRARIES ZLIB::ZLIB)
 | 
			
		||||
  set (has_zlib TRUE)
 | 
			
		||||
endif ()
 | 
			
		||||
@@ -1,70 +0,0 @@
 | 
			
		||||
if(reporting)
 | 
			
		||||
    find_package(PostgreSQL)
 | 
			
		||||
    if(NOT PostgreSQL_FOUND)
 | 
			
		||||
        message("find_package did not find postgres")
 | 
			
		||||
        find_library(postgres NAMES pq libpq libpq-dev pq-dev postgresql-devel)
 | 
			
		||||
        find_path(libpq-fe NAMES libpq-fe.h PATH_SUFFIXES postgresql pgsql include)
 | 
			
		||||
 | 
			
		||||
        if(NOT libpq-fe_FOUND OR NOT postgres_FOUND)
 | 
			
		||||
            message("No system installed Postgres found. Will build")
 | 
			
		||||
            add_library(postgres SHARED IMPORTED GLOBAL)
 | 
			
		||||
            add_library(pgport SHARED IMPORTED GLOBAL)
 | 
			
		||||
            add_library(pgcommon SHARED IMPORTED GLOBAL)
 | 
			
		||||
            ExternalProject_Add(postgres_src
 | 
			
		||||
                PREFIX ${nih_cache_path}
 | 
			
		||||
                GIT_REPOSITORY https://github.com/postgres/postgres.git
 | 
			
		||||
                GIT_TAG REL_14_5
 | 
			
		||||
                CONFIGURE_COMMAND ./configure --without-readline > /dev/null
 | 
			
		||||
                BUILD_COMMAND ${CMAKE_COMMAND} -E env --unset=MAKELEVEL make
 | 
			
		||||
                UPDATE_COMMAND ""
 | 
			
		||||
                BUILD_IN_SOURCE 1
 | 
			
		||||
                INSTALL_COMMAND ""
 | 
			
		||||
                BUILD_BYPRODUCTS
 | 
			
		||||
                    <BINARY_DIR>/src/interfaces/libpq/${ep_lib_prefix}pq.a
 | 
			
		||||
                    <BINARY_DIR>/src/common/${ep_lib_prefix}pgcommon.a
 | 
			
		||||
                    <BINARY_DIR>/src/port/${ep_lib_prefix}pgport.a
 | 
			
		||||
                LOG_BUILD TRUE
 | 
			
		||||
                )
 | 
			
		||||
            ExternalProject_Get_Property (postgres_src SOURCE_DIR)
 | 
			
		||||
            ExternalProject_Get_Property (postgres_src BINARY_DIR)
 | 
			
		||||
 | 
			
		||||
            set (postgres_src_SOURCE_DIR "${SOURCE_DIR}")
 | 
			
		||||
            file (MAKE_DIRECTORY ${postgres_src_SOURCE_DIR})
 | 
			
		||||
            list(APPEND INCLUDE_DIRS
 | 
			
		||||
                ${SOURCE_DIR}/src/include
 | 
			
		||||
                ${SOURCE_DIR}/src/interfaces/libpq
 | 
			
		||||
                )
 | 
			
		||||
            set_target_properties(postgres PROPERTIES
 | 
			
		||||
                IMPORTED_LOCATION
 | 
			
		||||
                    ${BINARY_DIR}/src/interfaces/libpq/${ep_lib_prefix}pq.a
 | 
			
		||||
                INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
                    "${INCLUDE_DIRS}"
 | 
			
		||||
                )
 | 
			
		||||
            set_target_properties(pgcommon PROPERTIES
 | 
			
		||||
                IMPORTED_LOCATION
 | 
			
		||||
                    ${BINARY_DIR}/src/common/${ep_lib_prefix}pgcommon.a
 | 
			
		||||
                INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
                    "${INCLUDE_DIRS}"
 | 
			
		||||
                )
 | 
			
		||||
            set_target_properties(pgport PROPERTIES
 | 
			
		||||
                IMPORTED_LOCATION
 | 
			
		||||
                    ${BINARY_DIR}/src/port/${ep_lib_prefix}pgport.a
 | 
			
		||||
                INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
                    "${INCLUDE_DIRS}"
 | 
			
		||||
                )
 | 
			
		||||
            add_dependencies(postgres postgres_src)
 | 
			
		||||
            add_dependencies(pgcommon postgres_src)
 | 
			
		||||
            add_dependencies(pgport postgres_src)
 | 
			
		||||
            file(TO_CMAKE_PATH "${postgres_src_SOURCE_DIR}" postgres_src_SOURCE_DIR)
 | 
			
		||||
            target_link_libraries(ripple_libs INTERFACE postgres pgcommon pgport)
 | 
			
		||||
        else()
 | 
			
		||||
            message("Found system installed Postgres via find_libary")
 | 
			
		||||
            target_include_directories(ripple_libs INTERFACE ${libpq-fe})
 | 
			
		||||
            target_link_libraries(ripple_libs INTERFACE ${postgres})
 | 
			
		||||
        endif()
 | 
			
		||||
    else()
 | 
			
		||||
        message("Found system installed Postgres via find_package")
 | 
			
		||||
        target_include_directories(ripple_libs INTERFACE ${PostgreSQL_INCLUDE_DIRS})
 | 
			
		||||
        target_link_libraries(ripple_libs INTERFACE ${PostgreSQL_LIBRARIES})
 | 
			
		||||
    endif()
 | 
			
		||||
endif()
 | 
			
		||||
@@ -1,155 +1,22 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   import protobuf (lib and compiler) and create a lib
 | 
			
		||||
   from our proto message definitions. If the system protobuf
 | 
			
		||||
   is not found, fallback on EP to download and build a version
 | 
			
		||||
   from official source.
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
find_package(Protobuf 3.8)
 | 
			
		||||
 | 
			
		||||
if (static)
 | 
			
		||||
  set (Protobuf_USE_STATIC_LIBS ON)
 | 
			
		||||
endif ()
 | 
			
		||||
find_package (Protobuf 3.8)
 | 
			
		||||
if (is_multiconfig)
 | 
			
		||||
    set(protobuf_protoc_lib ${Protobuf_PROTOC_LIBRARIES})
 | 
			
		||||
else ()
 | 
			
		||||
    string(TOUPPER ${CMAKE_BUILD_TYPE} upper_cmake_build_type)
 | 
			
		||||
    set(protobuf_protoc_lib ${Protobuf_PROTOC_LIBRARY_${upper_cmake_build_type}})
 | 
			
		||||
endif ()
 | 
			
		||||
if (local_protobuf OR NOT (Protobuf_FOUND AND Protobuf_PROTOC_EXECUTABLE AND protobuf_protoc_lib))
 | 
			
		||||
  include (GNUInstallDirs)
 | 
			
		||||
  message (STATUS "using local protobuf build.")
 | 
			
		||||
  set(protobuf_reqs Protobuf_PROTOC_EXECUTABLE protobuf_protoc_lib)
 | 
			
		||||
  foreach(lib ${protobuf_reqs})
 | 
			
		||||
    if(NOT ${lib})
 | 
			
		||||
      message(STATUS "Couldn't find ${lib}")
 | 
			
		||||
    endif()
 | 
			
		||||
  endforeach()
 | 
			
		||||
  if (WIN32)
 | 
			
		||||
    # protobuf prepends lib even on windows
 | 
			
		||||
    set (pbuf_lib_pre "lib")
 | 
			
		||||
  else ()
 | 
			
		||||
    set (pbuf_lib_pre ${ep_lib_prefix})
 | 
			
		||||
  endif ()
 | 
			
		||||
  # for the external project build of protobuf, we currently ignore the
 | 
			
		||||
  # static option and always build static libs here. This is consistent
 | 
			
		||||
  # with our other EP builds. Dynamic libs in an EP would add complexity
 | 
			
		||||
  # because we'd need to get them into the runtime path, and probably
 | 
			
		||||
  # install them.
 | 
			
		||||
  ExternalProject_Add (protobuf_src
 | 
			
		||||
    PREFIX ${nih_cache_path}
 | 
			
		||||
    GIT_REPOSITORY https://github.com/protocolbuffers/protobuf.git
 | 
			
		||||
    GIT_TAG v3.8.0
 | 
			
		||||
    SOURCE_SUBDIR cmake
 | 
			
		||||
    CMAKE_ARGS
 | 
			
		||||
      -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
 | 
			
		||||
      -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
 | 
			
		||||
      -DCMAKE_INSTALL_PREFIX=<BINARY_DIR>/_installed_
 | 
			
		||||
      -Dprotobuf_BUILD_TESTS=OFF
 | 
			
		||||
      -Dprotobuf_BUILD_EXAMPLES=OFF
 | 
			
		||||
      -Dprotobuf_BUILD_PROTOC_BINARIES=ON
 | 
			
		||||
      -Dprotobuf_MSVC_STATIC_RUNTIME=ON
 | 
			
		||||
      -DBUILD_SHARED_LIBS=OFF
 | 
			
		||||
      -Dprotobuf_BUILD_SHARED_LIBS=OFF
 | 
			
		||||
      -DCMAKE_DEBUG_POSTFIX=_d
 | 
			
		||||
      -Dprotobuf_DEBUG_POSTFIX=_d
 | 
			
		||||
      -Dprotobuf_WITH_ZLIB=$<IF:$<BOOL:${has_zlib}>,ON,OFF>
 | 
			
		||||
      $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-DCMAKE_VERBOSE_MAKEFILE=ON>
 | 
			
		||||
      $<$<BOOL:${unity}>:-DCMAKE_UNITY_BUILD=ON}>
 | 
			
		||||
      $<$<NOT:$<BOOL:${is_multiconfig}>>:-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}>
 | 
			
		||||
      $<$<BOOL:${MSVC}>:
 | 
			
		||||
	"-DCMAKE_CXX_FLAGS=-GR -Gd -fp:precise -FS -EHa -MP"
 | 
			
		||||
      >
 | 
			
		||||
    LOG_BUILD ON
 | 
			
		||||
    LOG_CONFIGURE ON
 | 
			
		||||
    BUILD_COMMAND
 | 
			
		||||
      ${CMAKE_COMMAND}
 | 
			
		||||
      --build .
 | 
			
		||||
      --config $<CONFIG>
 | 
			
		||||
      --parallel ${ep_procs}
 | 
			
		||||
    TEST_COMMAND ""
 | 
			
		||||
    INSTALL_COMMAND
 | 
			
		||||
      ${CMAKE_COMMAND} -E env --unset=DESTDIR ${CMAKE_COMMAND} --build . --config $<CONFIG> --target install
 | 
			
		||||
    BUILD_BYPRODUCTS
 | 
			
		||||
      <BINARY_DIR>/_installed_/${CMAKE_INSTALL_LIBDIR}/${pbuf_lib_pre}protobuf${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/_installed_/${CMAKE_INSTALL_LIBDIR}/${pbuf_lib_pre}protobuf_d${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/_installed_/${CMAKE_INSTALL_LIBDIR}/${pbuf_lib_pre}protoc${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/_installed_/${CMAKE_INSTALL_LIBDIR}/${pbuf_lib_pre}protoc_d${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/_installed_/bin/protoc${CMAKE_EXECUTABLE_SUFFIX}
 | 
			
		||||
  )
 | 
			
		||||
  ExternalProject_Get_Property (protobuf_src BINARY_DIR)
 | 
			
		||||
  ExternalProject_Get_Property (protobuf_src SOURCE_DIR)
 | 
			
		||||
  if (CMAKE_VERBOSE_MAKEFILE)
 | 
			
		||||
    print_ep_logs (protobuf_src)
 | 
			
		||||
  endif ()
 | 
			
		||||
  exclude_if_included (protobuf_src)
 | 
			
		||||
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/proto_gen)
 | 
			
		||||
set(ccbd ${CMAKE_CURRENT_BINARY_DIR})
 | 
			
		||||
set(CMAKE_CURRENT_BINARY_DIR ${CMAKE_BINARY_DIR}/proto_gen)
 | 
			
		||||
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS src/ripple/proto/ripple.proto)
 | 
			
		||||
set(CMAKE_CURRENT_BINARY_DIR ${ccbd})
 | 
			
		||||
 | 
			
		||||
  if (NOT TARGET protobuf::libprotobuf)
 | 
			
		||||
    add_library (protobuf::libprotobuf STATIC IMPORTED GLOBAL)
 | 
			
		||||
  endif ()
 | 
			
		||||
  file (MAKE_DIRECTORY ${BINARY_DIR}/_installed_/include)
 | 
			
		||||
  set_target_properties (protobuf::libprotobuf PROPERTIES
 | 
			
		||||
    IMPORTED_LOCATION_DEBUG
 | 
			
		||||
      ${BINARY_DIR}/_installed_/${CMAKE_INSTALL_LIBDIR}/${pbuf_lib_pre}protobuf_d${ep_lib_suffix}
 | 
			
		||||
    IMPORTED_LOCATION_RELEASE
 | 
			
		||||
      ${BINARY_DIR}/_installed_/${CMAKE_INSTALL_LIBDIR}/${pbuf_lib_pre}protobuf${ep_lib_suffix}
 | 
			
		||||
    INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
      ${BINARY_DIR}/_installed_/include)
 | 
			
		||||
  add_dependencies (protobuf::libprotobuf protobuf_src)
 | 
			
		||||
  exclude_if_included (protobuf::libprotobuf)
 | 
			
		||||
 | 
			
		||||
  if (NOT TARGET protobuf::libprotoc)
 | 
			
		||||
    add_library (protobuf::libprotoc STATIC IMPORTED GLOBAL)
 | 
			
		||||
  endif ()
 | 
			
		||||
  set_target_properties (protobuf::libprotoc PROPERTIES
 | 
			
		||||
    IMPORTED_LOCATION_DEBUG
 | 
			
		||||
      ${BINARY_DIR}/_installed_/${CMAKE_INSTALL_LIBDIR}/${pbuf_lib_pre}protoc_d${ep_lib_suffix}
 | 
			
		||||
    IMPORTED_LOCATION_RELEASE
 | 
			
		||||
      ${BINARY_DIR}/_installed_/${CMAKE_INSTALL_LIBDIR}/${pbuf_lib_pre}protoc${ep_lib_suffix}
 | 
			
		||||
    INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
      ${BINARY_DIR}/_installed_/include)
 | 
			
		||||
  add_dependencies (protobuf::libprotoc protobuf_src)
 | 
			
		||||
  exclude_if_included (protobuf::libprotoc)
 | 
			
		||||
 | 
			
		||||
  if (NOT TARGET protobuf::protoc)
 | 
			
		||||
    add_executable (protobuf::protoc IMPORTED)
 | 
			
		||||
    exclude_if_included (protobuf::protoc)
 | 
			
		||||
  endif ()
 | 
			
		||||
  set_target_properties (protobuf::protoc PROPERTIES
 | 
			
		||||
    IMPORTED_LOCATION "${BINARY_DIR}/_installed_/bin/protoc${CMAKE_EXECUTABLE_SUFFIX}")
 | 
			
		||||
  add_dependencies (protobuf::protoc protobuf_src)
 | 
			
		||||
else ()
 | 
			
		||||
  if (NOT TARGET protobuf::protoc)
 | 
			
		||||
    if (EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
 | 
			
		||||
      add_executable (protobuf::protoc IMPORTED)
 | 
			
		||||
      set_target_properties (protobuf::protoc PROPERTIES
 | 
			
		||||
        IMPORTED_LOCATION "${Protobuf_PROTOC_EXECUTABLE}")
 | 
			
		||||
    else ()
 | 
			
		||||
      message (FATAL_ERROR "Protobuf import failed")
 | 
			
		||||
    endif ()
 | 
			
		||||
  endif ()
 | 
			
		||||
endif ()
 | 
			
		||||
 | 
			
		||||
file (MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/proto_gen)
 | 
			
		||||
set (save_CBD ${CMAKE_CURRENT_BINARY_DIR})
 | 
			
		||||
set (CMAKE_CURRENT_BINARY_DIR ${CMAKE_BINARY_DIR}/proto_gen)
 | 
			
		||||
protobuf_generate_cpp (
 | 
			
		||||
  PROTO_SRCS
 | 
			
		||||
  PROTO_HDRS
 | 
			
		||||
  src/ripple/proto/ripple.proto)
 | 
			
		||||
set (CMAKE_CURRENT_BINARY_DIR ${save_CBD})
 | 
			
		||||
 | 
			
		||||
add_library (pbufs STATIC ${PROTO_SRCS} ${PROTO_HDRS})
 | 
			
		||||
 | 
			
		||||
target_include_directories (pbufs PRIVATE src)
 | 
			
		||||
target_include_directories (pbufs
 | 
			
		||||
  SYSTEM PUBLIC ${CMAKE_BINARY_DIR}/proto_gen)
 | 
			
		||||
target_link_libraries (pbufs protobuf::libprotobuf)
 | 
			
		||||
target_compile_options (pbufs
 | 
			
		||||
add_library(pbufs STATIC ${PROTO_SRCS} ${PROTO_HDRS})
 | 
			
		||||
target_include_directories(pbufs SYSTEM PUBLIC
 | 
			
		||||
  ${CMAKE_BINARY_DIR}/proto_gen
 | 
			
		||||
  ${CMAKE_BINARY_DIR}/proto_gen/src/ripple/proto
 | 
			
		||||
)
 | 
			
		||||
target_link_libraries(pbufs protobuf::libprotobuf)
 | 
			
		||||
target_compile_options(pbufs
 | 
			
		||||
  PUBLIC
 | 
			
		||||
    $<$<BOOL:${is_xcode}>:
 | 
			
		||||
    $<$<BOOL:${XCODE}>:
 | 
			
		||||
      --system-header-prefix="google/protobuf"
 | 
			
		||||
      -Wno-deprecated-dynamic-exception-spec
 | 
			
		||||
    >)
 | 
			
		||||
add_library (Ripple::pbufs ALIAS pbufs)
 | 
			
		||||
target_link_libraries (ripple_libs INTERFACE Ripple::pbufs)
 | 
			
		||||
exclude_if_included (pbufs)
 | 
			
		||||
    >
 | 
			
		||||
)
 | 
			
		||||
add_library(Ripple::pbufs ALIAS pbufs)
 | 
			
		||||
@@ -1,177 +0,0 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH dep: rocksdb
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
add_library (rocksdb_lib UNKNOWN IMPORTED GLOBAL)
 | 
			
		||||
set_target_properties (rocksdb_lib
 | 
			
		||||
  PROPERTIES INTERFACE_COMPILE_DEFINITIONS RIPPLE_ROCKSDB_AVAILABLE=1)
 | 
			
		||||
 | 
			
		||||
option (local_rocksdb "use local build of rocksdb." OFF)
 | 
			
		||||
if (NOT local_rocksdb)
 | 
			
		||||
  find_package (RocksDB 6.27 QUIET CONFIG)
 | 
			
		||||
  if (TARGET RocksDB::rocksdb)
 | 
			
		||||
    message (STATUS "Found RocksDB using config.")
 | 
			
		||||
    get_target_property (_rockslib_l RocksDB::rocksdb IMPORTED_LOCATION_DEBUG)
 | 
			
		||||
    if (_rockslib_l)
 | 
			
		||||
      set_target_properties (rocksdb_lib PROPERTIES IMPORTED_LOCATION_DEBUG ${_rockslib_l})
 | 
			
		||||
    endif ()
 | 
			
		||||
    get_target_property (_rockslib_l RocksDB::rocksdb IMPORTED_LOCATION_RELEASE)
 | 
			
		||||
    if (_rockslib_l)
 | 
			
		||||
      set_target_properties (rocksdb_lib PROPERTIES IMPORTED_LOCATION_RELEASE ${_rockslib_l})
 | 
			
		||||
    endif ()
 | 
			
		||||
    get_target_property (_rockslib_l RocksDB::rocksdb IMPORTED_LOCATION)
 | 
			
		||||
    if (_rockslib_l)
 | 
			
		||||
      set_target_properties (rocksdb_lib PROPERTIES IMPORTED_LOCATION ${_rockslib_l})
 | 
			
		||||
    endif ()
 | 
			
		||||
    get_target_property (_rockslib_i RocksDB::rocksdb INTERFACE_INCLUDE_DIRECTORIES)
 | 
			
		||||
    if (_rockslib_i)
 | 
			
		||||
      set_target_properties (rocksdb_lib PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${_rockslib_i})
 | 
			
		||||
    endif ()
 | 
			
		||||
    target_link_libraries (ripple_libs INTERFACE RocksDB::rocksdb)
 | 
			
		||||
  else ()
 | 
			
		||||
    # using a find module with rocksdb is difficult because
 | 
			
		||||
    # you have no idea how it was configured (transitive dependencies).
 | 
			
		||||
    # the code below will generally find rocksdb using the module, but
 | 
			
		||||
    # will then result in linker errors for static linkage since the
 | 
			
		||||
    # transitive dependencies are unknown. force local build here for now, but leave the code as
 | 
			
		||||
    # a placeholder for future investigation.
 | 
			
		||||
    if (static)
 | 
			
		||||
      set (local_rocksdb ON CACHE BOOL "" FORCE)
 | 
			
		||||
      # TBD if there is some way to extract transitive deps..then:
 | 
			
		||||
      #set (RocksDB_USE_STATIC ON)
 | 
			
		||||
    else ()
 | 
			
		||||
      find_package (RocksDB 6.27 MODULE)
 | 
			
		||||
      if (ROCKSDB_FOUND)
 | 
			
		||||
        if (RocksDB_LIBRARY_DEBUG)
 | 
			
		||||
          set_target_properties (rocksdb_lib PROPERTIES IMPORTED_LOCATION_DEBUG ${RocksDB_LIBRARY_DEBUG})
 | 
			
		||||
        endif ()
 | 
			
		||||
        set_target_properties (rocksdb_lib PROPERTIES IMPORTED_LOCATION_RELEASE ${RocksDB_LIBRARIES})
 | 
			
		||||
        set_target_properties (rocksdb_lib PROPERTIES IMPORTED_LOCATION ${RocksDB_LIBRARIES})
 | 
			
		||||
        set_target_properties (rocksdb_lib PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${RocksDB_INCLUDE_DIRS})
 | 
			
		||||
      else ()
 | 
			
		||||
        set (local_rocksdb ON CACHE BOOL "" FORCE)
 | 
			
		||||
      endif ()
 | 
			
		||||
    endif ()
 | 
			
		||||
  endif ()
 | 
			
		||||
endif ()
 | 
			
		||||
 | 
			
		||||
if (local_rocksdb)
 | 
			
		||||
  message (STATUS "Using local build of RocksDB.")
 | 
			
		||||
  ExternalProject_Add (rocksdb
 | 
			
		||||
    PREFIX ${nih_cache_path}
 | 
			
		||||
    GIT_REPOSITORY https://github.com/facebook/rocksdb.git
 | 
			
		||||
    GIT_TAG v6.27.3
 | 
			
		||||
    PATCH_COMMAND
 | 
			
		||||
      # only used by windows build
 | 
			
		||||
      ${CMAKE_COMMAND} -E copy_if_different
 | 
			
		||||
      ${CMAKE_CURRENT_SOURCE_DIR}/Builds/CMake/rocks_thirdparty.inc
 | 
			
		||||
      <SOURCE_DIR>/thirdparty.inc
 | 
			
		||||
    COMMAND
 | 
			
		||||
      # fixup their build version file to keep the values
 | 
			
		||||
      # from changing always
 | 
			
		||||
      ${CMAKE_COMMAND} -E copy_if_different
 | 
			
		||||
      ${CMAKE_CURRENT_SOURCE_DIR}/Builds/CMake/rocksdb_build_version.cc.in
 | 
			
		||||
      <SOURCE_DIR>/util/build_version.cc.in
 | 
			
		||||
    CMAKE_ARGS
 | 
			
		||||
      -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
 | 
			
		||||
      -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
 | 
			
		||||
      $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-DCMAKE_VERBOSE_MAKEFILE=ON>
 | 
			
		||||
      $<$<BOOL:${unity}>:-DCMAKE_UNITY_BUILD=ON}>
 | 
			
		||||
      -DCMAKE_DEBUG_POSTFIX=_d
 | 
			
		||||
      $<$<NOT:$<BOOL:${is_multiconfig}>>:-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}>
 | 
			
		||||
      -DBUILD_SHARED_LIBS=OFF
 | 
			
		||||
      -DCMAKE_POSITION_INDEPENDENT_CODE=ON
 | 
			
		||||
      -DWITH_JEMALLOC=$<IF:$<BOOL:${jemalloc}>,ON,OFF>
 | 
			
		||||
      -DWITH_SNAPPY=ON
 | 
			
		||||
      -DWITH_LZ4=ON
 | 
			
		||||
      -DWITH_ZLIB=OFF
 | 
			
		||||
      -DUSE_RTTI=ON
 | 
			
		||||
      -DWITH_ZSTD=OFF
 | 
			
		||||
      -DWITH_GFLAGS=OFF
 | 
			
		||||
      -DWITH_BZ2=OFF
 | 
			
		||||
      -ULZ4_*
 | 
			
		||||
      -Ulz4_*
 | 
			
		||||
      -Dlz4_INCLUDE_DIRS=$<JOIN:$<TARGET_PROPERTY:lz4_lib,INTERFACE_INCLUDE_DIRECTORIES>,::>
 | 
			
		||||
      -Dlz4_LIBRARIES=$<IF:$<CONFIG:Debug>,$<TARGET_PROPERTY:lz4_lib,IMPORTED_LOCATION_DEBUG>,$<TARGET_PROPERTY:lz4_lib,IMPORTED_LOCATION_RELEASE>>
 | 
			
		||||
      -Dlz4_FOUND=ON
 | 
			
		||||
      -USNAPPY_*
 | 
			
		||||
      -Usnappy_*
 | 
			
		||||
      -USnappy_*
 | 
			
		||||
      -Dsnappy_INCLUDE_DIRS=$<JOIN:$<TARGET_PROPERTY:snappy_lib,INTERFACE_INCLUDE_DIRECTORIES>,::>
 | 
			
		||||
      -Dsnappy_LIBRARIES=$<IF:$<CONFIG:Debug>,$<TARGET_PROPERTY:snappy_lib,IMPORTED_LOCATION_DEBUG>,$<TARGET_PROPERTY:snappy_lib,IMPORTED_LOCATION_RELEASE>>
 | 
			
		||||
      -Dsnappy_FOUND=ON
 | 
			
		||||
      -DSnappy_INCLUDE_DIRS=$<JOIN:$<TARGET_PROPERTY:snappy_lib,INTERFACE_INCLUDE_DIRECTORIES>,::>
 | 
			
		||||
      -DSnappy_LIBRARIES=$<IF:$<CONFIG:Debug>,$<TARGET_PROPERTY:snappy_lib,IMPORTED_LOCATION_DEBUG>,$<TARGET_PROPERTY:snappy_lib,IMPORTED_LOCATION_RELEASE>>
 | 
			
		||||
      -DSnappy_FOUND=ON
 | 
			
		||||
      -DWITH_MD_LIBRARY=OFF
 | 
			
		||||
      -DWITH_RUNTIME_DEBUG=$<IF:$<CONFIG:Debug>,ON,OFF>
 | 
			
		||||
      -DFAIL_ON_WARNINGS=OFF
 | 
			
		||||
      -DWITH_ASAN=OFF
 | 
			
		||||
      -DWITH_TSAN=OFF
 | 
			
		||||
      -DWITH_UBSAN=OFF
 | 
			
		||||
      -DWITH_NUMA=OFF
 | 
			
		||||
      -DWITH_TBB=OFF
 | 
			
		||||
      -DWITH_WINDOWS_UTF8_FILENAMES=OFF
 | 
			
		||||
      -DWITH_XPRESS=OFF
 | 
			
		||||
      -DPORTABLE=ON
 | 
			
		||||
      -DFORCE_SSE42=OFF
 | 
			
		||||
      -DDISABLE_STALL_NOTIF=OFF
 | 
			
		||||
      -DOPTDBG=ON
 | 
			
		||||
      -DROCKSDB_LITE=OFF
 | 
			
		||||
      -DWITH_FALLOCATE=ON
 | 
			
		||||
      -DWITH_LIBRADOS=OFF
 | 
			
		||||
      -DWITH_JNI=OFF
 | 
			
		||||
      -DROCKSDB_INSTALL_ON_WINDOWS=OFF
 | 
			
		||||
      -DWITH_TESTS=OFF
 | 
			
		||||
      -DWITH_TOOLS=OFF
 | 
			
		||||
      $<$<BOOL:${MSVC}>:
 | 
			
		||||
        "-DCMAKE_CXX_FLAGS=-GR -Gd -fp:precise -FS -MP /DNDEBUG"
 | 
			
		||||
      >
 | 
			
		||||
      $<$<NOT:$<BOOL:${MSVC}>>:
 | 
			
		||||
        "-DCMAKE_CXX_FLAGS=-DNDEBUG"
 | 
			
		||||
      >
 | 
			
		||||
    LOG_BUILD ON
 | 
			
		||||
    LOG_CONFIGURE ON
 | 
			
		||||
    BUILD_COMMAND
 | 
			
		||||
      ${CMAKE_COMMAND}
 | 
			
		||||
      --build .
 | 
			
		||||
      --config $<CONFIG>
 | 
			
		||||
      --parallel ${ep_procs}
 | 
			
		||||
      $<$<BOOL:${is_multiconfig}>:
 | 
			
		||||
        COMMAND
 | 
			
		||||
          ${CMAKE_COMMAND} -E copy
 | 
			
		||||
          <BINARY_DIR>/$<CONFIG>/${ep_lib_prefix}rocksdb$<$<CONFIG:Debug>:_d>${ep_lib_suffix}
 | 
			
		||||
          <BINARY_DIR>
 | 
			
		||||
        >
 | 
			
		||||
    LIST_SEPARATOR ::
 | 
			
		||||
    TEST_COMMAND ""
 | 
			
		||||
    INSTALL_COMMAND ""
 | 
			
		||||
    DEPENDS snappy_lib lz4_lib
 | 
			
		||||
    BUILD_BYPRODUCTS
 | 
			
		||||
      <BINARY_DIR>/${ep_lib_prefix}rocksdb${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/${ep_lib_prefix}rocksdb_d${ep_lib_suffix}
 | 
			
		||||
  )
 | 
			
		||||
  ExternalProject_Get_Property (rocksdb BINARY_DIR)
 | 
			
		||||
  ExternalProject_Get_Property (rocksdb SOURCE_DIR)
 | 
			
		||||
  if (CMAKE_VERBOSE_MAKEFILE)
 | 
			
		||||
    print_ep_logs (rocksdb)
 | 
			
		||||
  endif ()
 | 
			
		||||
  file (MAKE_DIRECTORY ${SOURCE_DIR}/include)
 | 
			
		||||
  set_target_properties (rocksdb_lib PROPERTIES
 | 
			
		||||
    IMPORTED_LOCATION_DEBUG
 | 
			
		||||
      ${BINARY_DIR}/${ep_lib_prefix}rocksdb_d${ep_lib_suffix}
 | 
			
		||||
    IMPORTED_LOCATION_RELEASE
 | 
			
		||||
      ${BINARY_DIR}/${ep_lib_prefix}rocksdb${ep_lib_suffix}
 | 
			
		||||
    INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
      ${SOURCE_DIR}/include)
 | 
			
		||||
  add_dependencies (rocksdb_lib rocksdb)
 | 
			
		||||
  exclude_if_included (rocksdb)
 | 
			
		||||
endif ()
 | 
			
		||||
 | 
			
		||||
target_link_libraries (rocksdb_lib
 | 
			
		||||
  INTERFACE
 | 
			
		||||
    snappy_lib
 | 
			
		||||
    lz4_lib
 | 
			
		||||
    $<$<BOOL:${MSVC}>:rpcrt4>)
 | 
			
		||||
exclude_if_included (rocksdb_lib)
 | 
			
		||||
target_link_libraries (ripple_libs INTERFACE rocksdb_lib)
 | 
			
		||||
@@ -1,58 +0,0 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH dep: secp256k1
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
add_library (secp256k1_lib STATIC IMPORTED GLOBAL)
 | 
			
		||||
 | 
			
		||||
if (NOT WIN32)
 | 
			
		||||
  find_package(secp256k1)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(secp256k1)
 | 
			
		||||
  set_target_properties (secp256k1_lib PROPERTIES
 | 
			
		||||
    IMPORTED_LOCATION_DEBUG
 | 
			
		||||
      ${secp256k1}
 | 
			
		||||
    IMPORTED_LOCATION_RELEASE
 | 
			
		||||
      ${secp256k1}
 | 
			
		||||
    INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
      ${SECP256K1_INCLUDE_DIR})
 | 
			
		||||
 | 
			
		||||
  add_library (secp256k1 ALIAS secp256k1_lib)
 | 
			
		||||
  add_library (NIH::secp256k1 ALIAS secp256k1_lib)
 | 
			
		||||
 | 
			
		||||
else()
 | 
			
		||||
  set(INSTALL_SECP256K1 true)
 | 
			
		||||
 | 
			
		||||
  add_library (secp256k1 STATIC
 | 
			
		||||
    src/secp256k1/src/secp256k1.c)
 | 
			
		||||
  target_compile_definitions (secp256k1
 | 
			
		||||
    PRIVATE
 | 
			
		||||
      USE_NUM_NONE
 | 
			
		||||
      USE_FIELD_10X26
 | 
			
		||||
      USE_FIELD_INV_BUILTIN
 | 
			
		||||
      USE_SCALAR_8X32
 | 
			
		||||
      USE_SCALAR_INV_BUILTIN)
 | 
			
		||||
  target_include_directories (secp256k1
 | 
			
		||||
    PUBLIC
 | 
			
		||||
      $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
 | 
			
		||||
      $<INSTALL_INTERFACE:include>
 | 
			
		||||
    PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/secp256k1)
 | 
			
		||||
  target_compile_options (secp256k1
 | 
			
		||||
    PRIVATE
 | 
			
		||||
      $<$<BOOL:${MSVC}>:-wd4319>
 | 
			
		||||
      $<$<NOT:$<BOOL:${MSVC}>>:
 | 
			
		||||
        -Wno-deprecated-declarations
 | 
			
		||||
        -Wno-unused-function
 | 
			
		||||
      >
 | 
			
		||||
      $<$<BOOL:${is_gcc}>:-Wno-nonnull-compare>)
 | 
			
		||||
  target_link_libraries (ripple_libs INTERFACE NIH::secp256k1)
 | 
			
		||||
#[===========================[
 | 
			
		||||
     headers installation
 | 
			
		||||
#]===========================]
 | 
			
		||||
  install (
 | 
			
		||||
    FILES
 | 
			
		||||
      src/secp256k1/include/secp256k1.h
 | 
			
		||||
  DESTINATION include/secp256k1/include)
 | 
			
		||||
 | 
			
		||||
  add_library (NIH::secp256k1 ALIAS secp256k1)
 | 
			
		||||
endif()
 | 
			
		||||
@@ -1,77 +0,0 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH dep: snappy
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
add_library (snappy_lib STATIC IMPORTED GLOBAL)
 | 
			
		||||
 | 
			
		||||
if (NOT WIN32)
 | 
			
		||||
  find_package(snappy)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(snappy)
 | 
			
		||||
  set_target_properties (snappy_lib PROPERTIES
 | 
			
		||||
    IMPORTED_LOCATION_DEBUG
 | 
			
		||||
      ${snappy}
 | 
			
		||||
    IMPORTED_LOCATION_RELEASE
 | 
			
		||||
      ${snappy}
 | 
			
		||||
    INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
    ${SNAPPY_INCLUDE_DIR})
 | 
			
		||||
 | 
			
		||||
else()
 | 
			
		||||
  ExternalProject_Add (snappy
 | 
			
		||||
    PREFIX ${nih_cache_path}
 | 
			
		||||
    GIT_REPOSITORY https://github.com/google/snappy.git
 | 
			
		||||
    GIT_TAG 1.1.7
 | 
			
		||||
    CMAKE_ARGS
 | 
			
		||||
      -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
 | 
			
		||||
      -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
 | 
			
		||||
      $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-DCMAKE_VERBOSE_MAKEFILE=ON>
 | 
			
		||||
      -DCMAKE_DEBUG_POSTFIX=_d
 | 
			
		||||
      $<$<NOT:$<BOOL:${is_multiconfig}>>:-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}>
 | 
			
		||||
      -DBUILD_SHARED_LIBS=OFF
 | 
			
		||||
      -DCMAKE_POSITION_INDEPENDENT_CODE=ON
 | 
			
		||||
      -DSNAPPY_BUILD_TESTS=OFF
 | 
			
		||||
      $<$<BOOL:${MSVC}>:
 | 
			
		||||
        "-DCMAKE_CXX_FLAGS=-GR -Gd -fp:precise -FS -EHa -MP"
 | 
			
		||||
        "-DCMAKE_CXX_FLAGS_DEBUG=-MTd"
 | 
			
		||||
        "-DCMAKE_CXX_FLAGS_RELEASE=-MT"
 | 
			
		||||
      >
 | 
			
		||||
    LOG_BUILD ON
 | 
			
		||||
    LOG_CONFIGURE ON
 | 
			
		||||
    BUILD_COMMAND
 | 
			
		||||
      ${CMAKE_COMMAND}
 | 
			
		||||
      --build .
 | 
			
		||||
      --config $<CONFIG>
 | 
			
		||||
      --parallel ${ep_procs}
 | 
			
		||||
      $<$<BOOL:${is_multiconfig}>:
 | 
			
		||||
        COMMAND
 | 
			
		||||
          ${CMAKE_COMMAND} -E copy
 | 
			
		||||
          <BINARY_DIR>/$<CONFIG>/${ep_lib_prefix}snappy$<$<CONFIG:Debug>:_d>${ep_lib_suffix}
 | 
			
		||||
          <BINARY_DIR>
 | 
			
		||||
        >
 | 
			
		||||
    TEST_COMMAND ""
 | 
			
		||||
    INSTALL_COMMAND
 | 
			
		||||
      ${CMAKE_COMMAND} -E copy_if_different <BINARY_DIR>/config.h <BINARY_DIR>/snappy-stubs-public.h <SOURCE_DIR>
 | 
			
		||||
    BUILD_BYPRODUCTS
 | 
			
		||||
      <BINARY_DIR>/${ep_lib_prefix}snappy${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/${ep_lib_prefix}snappy_d${ep_lib_suffix}
 | 
			
		||||
  )
 | 
			
		||||
  ExternalProject_Get_Property (snappy BINARY_DIR)
 | 
			
		||||
  ExternalProject_Get_Property (snappy SOURCE_DIR)
 | 
			
		||||
  if (CMAKE_VERBOSE_MAKEFILE)
 | 
			
		||||
    print_ep_logs (snappy)
 | 
			
		||||
  endif ()
 | 
			
		||||
  file (MAKE_DIRECTORY ${SOURCE_DIR}/snappy)
 | 
			
		||||
  set_target_properties (snappy_lib PROPERTIES
 | 
			
		||||
    IMPORTED_LOCATION_DEBUG
 | 
			
		||||
      ${BINARY_DIR}/${ep_lib_prefix}snappy_d${ep_lib_suffix}
 | 
			
		||||
    IMPORTED_LOCATION_RELEASE
 | 
			
		||||
      ${BINARY_DIR}/${ep_lib_prefix}snappy${ep_lib_suffix}
 | 
			
		||||
    INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
      ${SOURCE_DIR})
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
add_dependencies (snappy_lib snappy)
 | 
			
		||||
target_link_libraries (ripple_libs INTERFACE snappy_lib)
 | 
			
		||||
exclude_if_included (snappy)
 | 
			
		||||
exclude_if_included (snappy_lib)
 | 
			
		||||
@@ -1,165 +0,0 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH dep: soci
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
foreach (_comp core empty sqlite3)
 | 
			
		||||
  add_library ("soci_${_comp}" STATIC IMPORTED GLOBAL)
 | 
			
		||||
endforeach ()
 | 
			
		||||
 | 
			
		||||
if (NOT WIN32)
 | 
			
		||||
  find_package(soci)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if (soci)
 | 
			
		||||
  foreach (_comp core empty sqlite3)
 | 
			
		||||
    set_target_properties ("soci_${_comp}" PROPERTIES
 | 
			
		||||
      IMPORTED_LOCATION_DEBUG
 | 
			
		||||
        ${soci}
 | 
			
		||||
      IMPORTED_LOCATION_RELEASE
 | 
			
		||||
        ${soci}
 | 
			
		||||
      INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
        ${SOCI_INCLUDE_DIR})
 | 
			
		||||
  endforeach ()
 | 
			
		||||
 | 
			
		||||
else()
 | 
			
		||||
  set (soci_lib_pre ${ep_lib_prefix})
 | 
			
		||||
  set (soci_lib_post "")
 | 
			
		||||
  if (WIN32)
 | 
			
		||||
    # for some reason soci on windows still prepends lib (non-standard)
 | 
			
		||||
    set (soci_lib_pre lib)
 | 
			
		||||
    # this version in the name might change if/when we change versions of soci
 | 
			
		||||
    set (soci_lib_post "_4_0")
 | 
			
		||||
  endif ()
 | 
			
		||||
  get_target_property (_boost_incs Boost::date_time INTERFACE_INCLUDE_DIRECTORIES)
 | 
			
		||||
  get_target_property (_boost_dt Boost::date_time IMPORTED_LOCATION)
 | 
			
		||||
  if (NOT _boost_dt)
 | 
			
		||||
    get_target_property (_boost_dt Boost::date_time IMPORTED_LOCATION_RELEASE)
 | 
			
		||||
  endif ()
 | 
			
		||||
  if (NOT _boost_dt)
 | 
			
		||||
    get_target_property (_boost_dt Boost::date_time IMPORTED_LOCATION_DEBUG)
 | 
			
		||||
  endif ()
 | 
			
		||||
 | 
			
		||||
  ExternalProject_Add (soci
 | 
			
		||||
    PREFIX ${nih_cache_path}
 | 
			
		||||
    GIT_REPOSITORY https://github.com/SOCI/soci.git
 | 
			
		||||
    GIT_TAG 04e1870294918d20761736743bb6136314c42dd5
 | 
			
		||||
    # We had an issue with soci integer range checking for boost::optional
 | 
			
		||||
    # and needed to remove the exception that SOCI throws in this case.
 | 
			
		||||
    # This is *probably* a bug in SOCI, but has never been investigated more
 | 
			
		||||
    # nor reported to the maintainers.
 | 
			
		||||
    # This cmake script comments out the lines in question.
 | 
			
		||||
    # This patch process is likely fragile and should be reviewed carefully
 | 
			
		||||
    # whenever we update the GIT_TAG above.
 | 
			
		||||
    PATCH_COMMAND
 | 
			
		||||
      ${CMAKE_COMMAND} -D RIPPLED_SOURCE=${CMAKE_CURRENT_SOURCE_DIR}
 | 
			
		||||
        -P ${CMAKE_CURRENT_SOURCE_DIR}/Builds/CMake/soci_patch.cmake
 | 
			
		||||
    CMAKE_ARGS
 | 
			
		||||
      -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
 | 
			
		||||
      -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
 | 
			
		||||
      $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-DCMAKE_VERBOSE_MAKEFILE=ON>
 | 
			
		||||
      $<$<BOOL:${CMAKE_TOOLCHAIN_FILE}>:-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}>
 | 
			
		||||
      $<$<BOOL:${VCPKG_TARGET_TRIPLET}>:-DVCPKG_TARGET_TRIPLET=${VCPKG_TARGET_TRIPLET}>
 | 
			
		||||
      $<$<BOOL:${unity}>:-DCMAKE_UNITY_BUILD=ON}>
 | 
			
		||||
      -DCMAKE_PREFIX_PATH=${CMAKE_BINARY_DIR}/sqlite3
 | 
			
		||||
      -DCMAKE_MODULE_PATH=${CMAKE_CURRENT_SOURCE_DIR}/Builds/CMake
 | 
			
		||||
      -DCMAKE_INCLUDE_PATH=$<JOIN:$<TARGET_PROPERTY:sqlite,INTERFACE_INCLUDE_DIRECTORIES>,::>
 | 
			
		||||
      -DCMAKE_LIBRARY_PATH=${sqlite_BINARY_DIR}
 | 
			
		||||
      -DCMAKE_DEBUG_POSTFIX=_d
 | 
			
		||||
      $<$<NOT:$<BOOL:${is_multiconfig}>>:-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}>
 | 
			
		||||
      -DSOCI_CXX_C11=ON
 | 
			
		||||
      -DSOCI_STATIC=ON
 | 
			
		||||
      -DSOCI_LIBDIR=lib
 | 
			
		||||
      -DSOCI_SHARED=OFF
 | 
			
		||||
      -DSOCI_TESTS=OFF
 | 
			
		||||
      # hacks to workaround the fact that soci doesn't currently use
 | 
			
		||||
      # boost imported targets in its cmake. If they switch to
 | 
			
		||||
      # proper imported targets, this next line can be removed
 | 
			
		||||
      # (as well as the get_property above that sets _boost_incs)
 | 
			
		||||
      -DBoost_INCLUDE_DIRS=$<JOIN:${_boost_incs},::>
 | 
			
		||||
      -DBoost_INCLUDE_DIR=$<JOIN:${_boost_incs},::>
 | 
			
		||||
      -DBOOST_ROOT=${BOOST_ROOT}
 | 
			
		||||
      -DWITH_BOOST=ON
 | 
			
		||||
      -DBoost_FOUND=ON
 | 
			
		||||
      -DBoost_NO_BOOST_CMAKE=ON
 | 
			
		||||
      -DBoost_DATE_TIME_FOUND=ON
 | 
			
		||||
      -DSOCI_HAVE_BOOST=ON
 | 
			
		||||
      -DSOCI_HAVE_BOOST_DATE_TIME=ON
 | 
			
		||||
      -DBoost_DATE_TIME_LIBRARY=${_boost_dt}
 | 
			
		||||
      -DSOCI_DB2=OFF
 | 
			
		||||
      -DSOCI_FIREBIRD=OFF
 | 
			
		||||
      -DSOCI_MYSQL=OFF
 | 
			
		||||
      -DSOCI_ODBC=OFF
 | 
			
		||||
      -DSOCI_ORACLE=OFF
 | 
			
		||||
      -DSOCI_POSTGRESQL=OFF
 | 
			
		||||
      -DSOCI_SQLITE3=ON
 | 
			
		||||
      -DSQLITE3_INCLUDE_DIR=$<JOIN:$<TARGET_PROPERTY:sqlite,INTERFACE_INCLUDE_DIRECTORIES>,::>
 | 
			
		||||
      -DSQLITE3_LIBRARY=$<IF:$<CONFIG:Debug>,$<TARGET_PROPERTY:sqlite,IMPORTED_LOCATION_DEBUG>,$<TARGET_PROPERTY:sqlite,IMPORTED_LOCATION_RELEASE>>
 | 
			
		||||
      $<$<BOOL:${APPLE}>:-DCMAKE_FIND_FRAMEWORK=LAST>
 | 
			
		||||
      $<$<BOOL:${MSVC}>:
 | 
			
		||||
        "-DCMAKE_CXX_FLAGS=-GR -Gd -fp:precise -FS -EHa -MP"
 | 
			
		||||
        "-DCMAKE_CXX_FLAGS_DEBUG=-MTd"
 | 
			
		||||
        "-DCMAKE_CXX_FLAGS_RELEASE=-MT"
 | 
			
		||||
      >
 | 
			
		||||
      $<$<NOT:$<BOOL:${MSVC}>>:
 | 
			
		||||
        "-DCMAKE_CXX_FLAGS=-Wno-deprecated-declarations"
 | 
			
		||||
      >
 | 
			
		||||
      # SEE: https://github.com/SOCI/soci/issues/640
 | 
			
		||||
      $<$<AND:$<BOOL:${is_gcc}>,$<VERSION_GREATER_EQUAL:${CMAKE_CXX_COMPILER_VERSION},8>>:
 | 
			
		||||
        "-DCMAKE_CXX_FLAGS=-Wno-deprecated-declarations -Wno-error=format-overflow -Wno-format-overflow -Wno-error=format-truncation"
 | 
			
		||||
      >
 | 
			
		||||
    LIST_SEPARATOR ::
 | 
			
		||||
    LOG_BUILD ON
 | 
			
		||||
    LOG_CONFIGURE ON
 | 
			
		||||
    BUILD_COMMAND
 | 
			
		||||
      ${CMAKE_COMMAND}
 | 
			
		||||
      --build .
 | 
			
		||||
      --config $<CONFIG>
 | 
			
		||||
      --parallel ${ep_procs}
 | 
			
		||||
      $<$<BOOL:${is_multiconfig}>:
 | 
			
		||||
        COMMAND
 | 
			
		||||
          ${CMAKE_COMMAND} -E copy
 | 
			
		||||
          <BINARY_DIR>/lib/$<CONFIG>/${soci_lib_pre}soci_core${soci_lib_post}$<$<CONFIG:Debug>:_d>${ep_lib_suffix}
 | 
			
		||||
          <BINARY_DIR>/lib/$<CONFIG>/${soci_lib_pre}soci_empty${soci_lib_post}$<$<CONFIG:Debug>:_d>${ep_lib_suffix}
 | 
			
		||||
          <BINARY_DIR>/lib/$<CONFIG>/${soci_lib_pre}soci_sqlite3${soci_lib_post}$<$<CONFIG:Debug>:_d>${ep_lib_suffix}
 | 
			
		||||
          <BINARY_DIR>/lib
 | 
			
		||||
        >
 | 
			
		||||
    TEST_COMMAND ""
 | 
			
		||||
    INSTALL_COMMAND ""
 | 
			
		||||
    DEPENDS sqlite
 | 
			
		||||
    BUILD_BYPRODUCTS
 | 
			
		||||
      <BINARY_DIR>/lib/${soci_lib_pre}soci_core${soci_lib_post}${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/lib/${soci_lib_pre}soci_core${soci_lib_post}_d${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/lib/${soci_lib_pre}soci_empty${soci_lib_post}${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/lib/${soci_lib_pre}soci_empty${soci_lib_post}_d${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/lib/${soci_lib_pre}soci_sqlite3${soci_lib_post}${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/lib/${soci_lib_pre}soci_sqlite3${soci_lib_post}_d${ep_lib_suffix}
 | 
			
		||||
  )
 | 
			
		||||
  ExternalProject_Get_Property (soci BINARY_DIR)
 | 
			
		||||
  ExternalProject_Get_Property (soci SOURCE_DIR)
 | 
			
		||||
  if (CMAKE_VERBOSE_MAKEFILE)
 | 
			
		||||
    print_ep_logs (soci)
 | 
			
		||||
  endif ()
 | 
			
		||||
  file (MAKE_DIRECTORY ${SOURCE_DIR}/include)
 | 
			
		||||
  file (MAKE_DIRECTORY ${BINARY_DIR}/include)
 | 
			
		||||
  foreach (_comp core empty sqlite3)
 | 
			
		||||
    set_target_properties ("soci_${_comp}" PROPERTIES
 | 
			
		||||
      IMPORTED_LOCATION_DEBUG
 | 
			
		||||
        ${BINARY_DIR}/lib/${soci_lib_pre}soci_${_comp}${soci_lib_post}_d${ep_lib_suffix}
 | 
			
		||||
      IMPORTED_LOCATION_RELEASE
 | 
			
		||||
        ${BINARY_DIR}/lib/${soci_lib_pre}soci_${_comp}${soci_lib_post}${ep_lib_suffix}
 | 
			
		||||
      INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
        "${SOURCE_DIR}/include;${BINARY_DIR}/include")
 | 
			
		||||
    add_dependencies ("soci_${_comp}" soci) # something has to depend on the ExternalProject to trigger it
 | 
			
		||||
    target_link_libraries (ripple_libs INTERFACE "soci_${_comp}")
 | 
			
		||||
    if (NOT _comp STREQUAL "core")
 | 
			
		||||
      target_link_libraries ("soci_${_comp}" INTERFACE soci_core)
 | 
			
		||||
    endif ()
 | 
			
		||||
  endforeach ()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
foreach (_comp core empty sqlite3)
 | 
			
		||||
  exclude_if_included ("soci_${_comp}")
 | 
			
		||||
endforeach ()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
exclude_if_included (soci)
 | 
			
		||||
@@ -1,93 +0,0 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH dep: sqlite
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
add_library (sqlite STATIC IMPORTED GLOBAL)
 | 
			
		||||
 | 
			
		||||
if (NOT WIN32)
 | 
			
		||||
  find_package(sqlite)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if(sqlite3)
 | 
			
		||||
  set_target_properties (sqlite PROPERTIES
 | 
			
		||||
    IMPORTED_LOCATION_DEBUG
 | 
			
		||||
      ${sqlite3}
 | 
			
		||||
    IMPORTED_LOCATION_RELEASE
 | 
			
		||||
      ${sqlite3}
 | 
			
		||||
    INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
    ${SQLITE_INCLUDE_DIR})
 | 
			
		||||
 | 
			
		||||
else()
 | 
			
		||||
  ExternalProject_Add (sqlite3
 | 
			
		||||
    PREFIX ${nih_cache_path}
 | 
			
		||||
    # sqlite doesn't use git, but it provides versioned tarballs
 | 
			
		||||
    URL https://www.sqlite.org/2018/sqlite-amalgamation-3260000.zip
 | 
			
		||||
      http://www.sqlite.org/2018/sqlite-amalgamation-3260000.zip
 | 
			
		||||
      https://www2.sqlite.org/2018/sqlite-amalgamation-3260000.zip
 | 
			
		||||
      http://www2.sqlite.org/2018/sqlite-amalgamation-3260000.zip
 | 
			
		||||
    # ^^^ version is apparent in the URL:  3260000 => 3.26.0
 | 
			
		||||
    URL_HASH SHA256=de5dcab133aa339a4cf9e97c40aa6062570086d6085d8f9ad7bc6ddf8a52096e
 | 
			
		||||
    # Don't need to worry about MITM attacks too much because the download
 | 
			
		||||
    # is checked against a strong hash
 | 
			
		||||
    TLS_VERIFY false
 | 
			
		||||
    # we wrote a very simple CMake file to build sqlite
 | 
			
		||||
    # so that's what we copy here so that we can build with
 | 
			
		||||
    # CMake. sqlite doesn't generally provided a build system
 | 
			
		||||
    # for the single amalgamation source file.
 | 
			
		||||
    PATCH_COMMAND
 | 
			
		||||
      ${CMAKE_COMMAND} -E copy_if_different
 | 
			
		||||
      ${CMAKE_CURRENT_SOURCE_DIR}/Builds/CMake/CMake_sqlite3.txt
 | 
			
		||||
      <SOURCE_DIR>/CMakeLists.txt
 | 
			
		||||
    CMAKE_ARGS
 | 
			
		||||
      -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
 | 
			
		||||
      -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
 | 
			
		||||
      $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-DCMAKE_VERBOSE_MAKEFILE=ON>
 | 
			
		||||
      -DCMAKE_DEBUG_POSTFIX=_d
 | 
			
		||||
      $<$<NOT:$<BOOL:${is_multiconfig}>>:-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}>
 | 
			
		||||
      $<$<BOOL:${MSVC}>:
 | 
			
		||||
        "-DCMAKE_C_FLAGS=-GR -Gd -fp:precise -FS -MP"
 | 
			
		||||
        "-DCMAKE_C_FLAGS_DEBUG=-MTd"
 | 
			
		||||
        "-DCMAKE_C_FLAGS_RELEASE=-MT"
 | 
			
		||||
      >
 | 
			
		||||
    LOG_BUILD ON
 | 
			
		||||
    LOG_CONFIGURE ON
 | 
			
		||||
    BUILD_COMMAND
 | 
			
		||||
      ${CMAKE_COMMAND}
 | 
			
		||||
      --build .
 | 
			
		||||
      --config $<CONFIG>
 | 
			
		||||
      --parallel ${ep_procs}
 | 
			
		||||
      $<$<BOOL:${is_multiconfig}>:
 | 
			
		||||
        COMMAND
 | 
			
		||||
          ${CMAKE_COMMAND} -E copy
 | 
			
		||||
            <BINARY_DIR>/$<CONFIG>/${ep_lib_prefix}sqlite3$<$<CONFIG:Debug>:_d>${ep_lib_suffix}
 | 
			
		||||
            <BINARY_DIR>
 | 
			
		||||
        >
 | 
			
		||||
    TEST_COMMAND ""
 | 
			
		||||
    INSTALL_COMMAND ""
 | 
			
		||||
    BUILD_BYPRODUCTS
 | 
			
		||||
      <BINARY_DIR>/${ep_lib_prefix}sqlite3${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/${ep_lib_prefix}sqlite3_d${ep_lib_suffix}
 | 
			
		||||
  )
 | 
			
		||||
  ExternalProject_Get_Property (sqlite3 BINARY_DIR)
 | 
			
		||||
  ExternalProject_Get_Property (sqlite3 SOURCE_DIR)
 | 
			
		||||
  if (CMAKE_VERBOSE_MAKEFILE)
 | 
			
		||||
    print_ep_logs (sqlite3)
 | 
			
		||||
  endif ()
 | 
			
		||||
 | 
			
		||||
  set_target_properties (sqlite PROPERTIES
 | 
			
		||||
    IMPORTED_LOCATION_DEBUG
 | 
			
		||||
      ${BINARY_DIR}/${ep_lib_prefix}sqlite3_d${ep_lib_suffix}
 | 
			
		||||
    IMPORTED_LOCATION_RELEASE
 | 
			
		||||
      ${BINARY_DIR}/${ep_lib_prefix}sqlite3${ep_lib_suffix}
 | 
			
		||||
    INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
      ${SOURCE_DIR})
 | 
			
		||||
 | 
			
		||||
  add_dependencies (sqlite sqlite3)
 | 
			
		||||
  exclude_if_included (sqlite3)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
target_link_libraries (sqlite INTERFACE $<$<NOT:$<BOOL:${MSVC}>>:dl>)
 | 
			
		||||
target_link_libraries (ripple_libs INTERFACE sqlite)
 | 
			
		||||
exclude_if_included (sqlite)
 | 
			
		||||
set(sqlite_BINARY_DIR ${BINARY_DIR})
 | 
			
		||||
@@ -1,84 +1 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
 NIH dep: wasmedge: web assembly runtime for hooks.
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
find_package(Curses)
 | 
			
		||||
if(CURSES_FOUND)
 | 
			
		||||
  include_directories(${CURSES_INCLUDE_DIR})
 | 
			
		||||
  target_link_libraries(ripple_libs INTERFACE ${CURSES_LIBRARY})
 | 
			
		||||
else()
 | 
			
		||||
  message(WARNING "CURSES library not found... (only important for mac builds)")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
find_package(LLVM REQUIRED CONFIG)
 | 
			
		||||
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
 | 
			
		||||
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
 | 
			
		||||
ExternalProject_Add (wasmedge_src
 | 
			
		||||
  PREFIX ${nih_cache_path}
 | 
			
		||||
  GIT_REPOSITORY https://github.com/WasmEdge/WasmEdge.git
 | 
			
		||||
  GIT_TAG 0.11.2
 | 
			
		||||
  CMAKE_ARGS
 | 
			
		||||
    -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
 | 
			
		||||
    -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
 | 
			
		||||
    $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-DCMAKE_VERBOSE_MAKEFILE=ON>
 | 
			
		||||
    -DCMAKE_DEBUG_POSTFIX=_d
 | 
			
		||||
    -DWASMEDGE_BUILD_SHARED_LIB=OFF
 | 
			
		||||
    -DWASMEDGE_BUILD_STATIC_LIB=ON
 | 
			
		||||
    -DWASMEDGE_BUILD_AOT_RUNTIME=ON
 | 
			
		||||
    -DWASMEDGE_FORCE_DISABLE_LTO=ON
 | 
			
		||||
    -DWASMEDGE_LINK_LLVM_STATIC=ON
 | 
			
		||||
    -DWASMEDGE_LINK_TOOLS_STATIC=ON
 | 
			
		||||
    -DWASMEDGE_BUILD_PLUGINS=OFF
 | 
			
		||||
    -DCMAKE_POSITION_INDEPENDENT_CODE=ON
 | 
			
		||||
    -DLLVM_DIR=${LLVM_DIR}
 | 
			
		||||
    -DLLVM_LIBRARY_DIR=${LLVM_LIBRARY_DIR}
 | 
			
		||||
    -DLLVM_ENABLE_TERMINFO=OFF
 | 
			
		||||
    $<$<NOT:$<BOOL:${is_multiconfig}>>:-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}>
 | 
			
		||||
    $<$<BOOL:${MSVC}>:
 | 
			
		||||
      "-DCMAKE_C_FLAGS=-GR -Gd -fp:precise -FS -MP -march=native"
 | 
			
		||||
      "-DCMAKE_C_FLAGS_DEBUG=-MTd"
 | 
			
		||||
      "-DCMAKE_C_FLAGS_RELEASE=-MT"
 | 
			
		||||
    >  
 | 
			
		||||
  LOG_CONFIGURE ON
 | 
			
		||||
  LOG_BUILD ON
 | 
			
		||||
  LOG_CONFIGURE ON
 | 
			
		||||
  COMMAND
 | 
			
		||||
    pwd
 | 
			
		||||
  BUILD_COMMAND
 | 
			
		||||
    ${CMAKE_COMMAND}
 | 
			
		||||
    --build .
 | 
			
		||||
    --config $<CONFIG>
 | 
			
		||||
    $<$<VERSION_GREATER_EQUAL:${CMAKE_VERSION},3.12>:--parallel ${ep_procs}>
 | 
			
		||||
  TEST_COMMAND ""
 | 
			
		||||
  INSTALL_COMMAND ""
 | 
			
		||||
  BUILD_BYPRODUCTS
 | 
			
		||||
      <BINARY_DIR>/lib/api/libwasmedge.a
 | 
			
		||||
)
 | 
			
		||||
add_library (wasmedge STATIC IMPORTED GLOBAL)
 | 
			
		||||
ExternalProject_Get_Property (wasmedge_src BINARY_DIR)
 | 
			
		||||
ExternalProject_Get_Property (wasmedge_src SOURCE_DIR)
 | 
			
		||||
set (wasmedge_src_BINARY_DIR "${BINARY_DIR}")
 | 
			
		||||
add_dependencies (wasmedge wasmedge_src)
 | 
			
		||||
execute_process(
 | 
			
		||||
    COMMAND
 | 
			
		||||
        mkdir -p "${wasmedge_src_BINARY_DIR}/include/api"
 | 
			
		||||
)
 | 
			
		||||
set_target_properties (wasmedge PROPERTIES
 | 
			
		||||
  IMPORTED_LOCATION_DEBUG
 | 
			
		||||
    "${wasmedge_src_BINARY_DIR}/lib/api/libwasmedge.a"
 | 
			
		||||
  IMPORTED_LOCATION_RELEASE
 | 
			
		||||
    "${wasmedge_src_BINARY_DIR}/lib/api/libwasmedge.a"
 | 
			
		||||
  INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
    "${wasmedge_src_BINARY_DIR}/include/api/"
 | 
			
		||||
)
 | 
			
		||||
target_link_libraries (ripple_libs INTERFACE wasmedge)
 | 
			
		||||
#RH NOTE: some compilers / versions of some libraries need these, most don't
 | 
			
		||||
 | 
			
		||||
find_library(XAR_LIBRARY NAMES xar)
 | 
			
		||||
if(XAR_LIBRARY)
 | 
			
		||||
  target_link_libraries(ripple_libs INTERFACE ${XAR_LIBRARY})
 | 
			
		||||
else()
 | 
			
		||||
  message(WARNING "xar library not found... (only important for mac builds)")
 | 
			
		||||
endif()
 | 
			
		||||
add_library (wasmedge::wasmedge ALIAS wasmedge)
 | 
			
		||||
find_package(wasmedge REQUIRED)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,167 +0,0 @@
 | 
			
		||||
if(reporting)
 | 
			
		||||
    find_library(cassandra NAMES cassandra)
 | 
			
		||||
    if(NOT cassandra)
 | 
			
		||||
 | 
			
		||||
        message("System installed Cassandra cpp driver not found. Will build")
 | 
			
		||||
 | 
			
		||||
        find_library(zlib NAMES zlib1g-dev zlib-devel zlib z)
 | 
			
		||||
        if(NOT zlib)
 | 
			
		||||
            message("zlib not found. will build")
 | 
			
		||||
            add_library(zlib STATIC IMPORTED GLOBAL)
 | 
			
		||||
            ExternalProject_Add(zlib_src
 | 
			
		||||
                PREFIX ${nih_cache_path}
 | 
			
		||||
                GIT_REPOSITORY https://github.com/madler/zlib.git
 | 
			
		||||
                GIT_TAG v1.2.12
 | 
			
		||||
                INSTALL_COMMAND ""
 | 
			
		||||
                BUILD_BYPRODUCTS <BINARY_DIR>/${ep_lib_prefix}z.a
 | 
			
		||||
                LOG_BUILD TRUE
 | 
			
		||||
                LOG_CONFIGURE TRUE
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            ExternalProject_Get_Property (zlib_src SOURCE_DIR)
 | 
			
		||||
            ExternalProject_Get_Property (zlib_src BINARY_DIR)
 | 
			
		||||
            set (zlib_src_SOURCE_DIR "${SOURCE_DIR}")
 | 
			
		||||
            file (MAKE_DIRECTORY ${zlib_src_SOURCE_DIR}/include)
 | 
			
		||||
 | 
			
		||||
            set_target_properties (zlib PROPERTIES
 | 
			
		||||
                IMPORTED_LOCATION
 | 
			
		||||
                ${BINARY_DIR}/${ep_lib_prefix}z.a
 | 
			
		||||
                INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
                ${SOURCE_DIR}/include)
 | 
			
		||||
            add_dependencies(zlib zlib_src)
 | 
			
		||||
 | 
			
		||||
            file(TO_CMAKE_PATH "${zlib_src_SOURCE_DIR}" zlib_src_SOURCE_DIR)
 | 
			
		||||
        endif()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        find_library(krb5 NAMES krb5-dev libkrb5-dev)
 | 
			
		||||
 | 
			
		||||
        if(NOT krb5)
 | 
			
		||||
            message("krb5 not found. will build")
 | 
			
		||||
            add_library(krb5 STATIC IMPORTED GLOBAL)
 | 
			
		||||
            ExternalProject_Add(krb5_src
 | 
			
		||||
                PREFIX ${nih_cache_path}
 | 
			
		||||
                GIT_REPOSITORY https://github.com/krb5/krb5.git
 | 
			
		||||
                GIT_TAG krb5-1.20-final
 | 
			
		||||
                UPDATE_COMMAND ""
 | 
			
		||||
                CONFIGURE_COMMAND autoreconf src && CFLAGS=-fcommon ./src/configure --enable-static --disable-shared > /dev/null
 | 
			
		||||
                BUILD_IN_SOURCE 1
 | 
			
		||||
                BUILD_COMMAND make
 | 
			
		||||
                INSTALL_COMMAND ""
 | 
			
		||||
                BUILD_BYPRODUCTS <SOURCE_DIR>/lib/${ep_lib_prefix}krb5.a
 | 
			
		||||
                LOG_BUILD TRUE
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
            ExternalProject_Get_Property (krb5_src SOURCE_DIR)
 | 
			
		||||
            ExternalProject_Get_Property (krb5_src BINARY_DIR)
 | 
			
		||||
            set (krb5_src_SOURCE_DIR "${SOURCE_DIR}")
 | 
			
		||||
            file (MAKE_DIRECTORY ${krb5_src_SOURCE_DIR}/include)
 | 
			
		||||
 | 
			
		||||
            set_target_properties (krb5 PROPERTIES
 | 
			
		||||
                IMPORTED_LOCATION
 | 
			
		||||
                ${BINARY_DIR}/lib/${ep_lib_prefix}krb5.a
 | 
			
		||||
                INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
                ${SOURCE_DIR}/include)
 | 
			
		||||
            add_dependencies(krb5 krb5_src)
 | 
			
		||||
 | 
			
		||||
            file(TO_CMAKE_PATH "${krb5_src_SOURCE_DIR}" krb5_src_SOURCE_DIR)
 | 
			
		||||
        endif()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        find_library(libuv1 NAMES uv1 libuv1 liubuv1-dev libuv1:amd64)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        if(NOT libuv1)
 | 
			
		||||
            message("libuv1 not found, will build")
 | 
			
		||||
            add_library(libuv1 STATIC IMPORTED GLOBAL)
 | 
			
		||||
            ExternalProject_Add(libuv_src
 | 
			
		||||
                PREFIX ${nih_cache_path}
 | 
			
		||||
                GIT_REPOSITORY https://github.com/libuv/libuv.git
 | 
			
		||||
                GIT_TAG v1.44.2
 | 
			
		||||
                INSTALL_COMMAND ""
 | 
			
		||||
                BUILD_BYPRODUCTS <BINARY_DIR>/${ep_lib_prefix}uv_a.a
 | 
			
		||||
                LOG_BUILD TRUE
 | 
			
		||||
                LOG_CONFIGURE TRUE
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
            ExternalProject_Get_Property (libuv_src SOURCE_DIR)
 | 
			
		||||
            ExternalProject_Get_Property (libuv_src BINARY_DIR)
 | 
			
		||||
            set (libuv_src_SOURCE_DIR "${SOURCE_DIR}")
 | 
			
		||||
            file (MAKE_DIRECTORY ${libuv_src_SOURCE_DIR}/include)
 | 
			
		||||
 | 
			
		||||
            set_target_properties (libuv1 PROPERTIES
 | 
			
		||||
                IMPORTED_LOCATION
 | 
			
		||||
                ${BINARY_DIR}/${ep_lib_prefix}uv_a.a
 | 
			
		||||
                INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
                ${SOURCE_DIR}/include)
 | 
			
		||||
            add_dependencies(libuv1 libuv_src)
 | 
			
		||||
 | 
			
		||||
            file(TO_CMAKE_PATH "${libuv_src_SOURCE_DIR}" libuv_src_SOURCE_DIR)
 | 
			
		||||
        endif()
 | 
			
		||||
 | 
			
		||||
        add_library (cassandra STATIC IMPORTED GLOBAL)
 | 
			
		||||
        ExternalProject_Add(cassandra_src
 | 
			
		||||
            PREFIX ${nih_cache_path}
 | 
			
		||||
            GIT_REPOSITORY https://github.com/datastax/cpp-driver.git
 | 
			
		||||
            GIT_TAG 2.16.2
 | 
			
		||||
            CMAKE_ARGS
 | 
			
		||||
            -DLIBUV_ROOT_DIR=${BINARY_DIR}
 | 
			
		||||
            -DLIBUV_LIBARY=${BINARY_DIR}/libuv_a.a
 | 
			
		||||
            -DLIBUV_INCLUDE_DIR=${SOURCE_DIR}/include
 | 
			
		||||
            -DCASS_BUILD_STATIC=ON
 | 
			
		||||
            -DCASS_BUILD_SHARED=OFF
 | 
			
		||||
            -DOPENSSL_ROOT_DIR=/opt/local/openssl
 | 
			
		||||
            INSTALL_COMMAND ""
 | 
			
		||||
            BUILD_BYPRODUCTS <BINARY_DIR>/${ep_lib_prefix}cassandra_static.a
 | 
			
		||||
            LOG_BUILD TRUE
 | 
			
		||||
            LOG_CONFIGURE TRUE
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
        ExternalProject_Get_Property (cassandra_src SOURCE_DIR)
 | 
			
		||||
        ExternalProject_Get_Property (cassandra_src BINARY_DIR)
 | 
			
		||||
        set (cassandra_src_SOURCE_DIR "${SOURCE_DIR}")
 | 
			
		||||
        file (MAKE_DIRECTORY ${cassandra_src_SOURCE_DIR}/include)
 | 
			
		||||
 | 
			
		||||
        set_target_properties (cassandra PROPERTIES
 | 
			
		||||
            IMPORTED_LOCATION
 | 
			
		||||
            ${BINARY_DIR}/${ep_lib_prefix}cassandra_static.a
 | 
			
		||||
            INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
            ${SOURCE_DIR}/include)
 | 
			
		||||
        add_dependencies(cassandra cassandra_src)
 | 
			
		||||
 | 
			
		||||
        if(NOT libuv1)
 | 
			
		||||
            ExternalProject_Add_StepDependencies(cassandra_src build libuv1)
 | 
			
		||||
            target_link_libraries(cassandra INTERFACE libuv1)
 | 
			
		||||
        else()
 | 
			
		||||
            target_link_libraries(cassandra INTERFACE ${libuv1})
 | 
			
		||||
        endif()
 | 
			
		||||
        if(NOT krb5)
 | 
			
		||||
 | 
			
		||||
            ExternalProject_Add_StepDependencies(cassandra_src build krb5)
 | 
			
		||||
            target_link_libraries(cassandra INTERFACE krb5)
 | 
			
		||||
        else()
 | 
			
		||||
            target_link_libraries(cassandra INTERFACE ${krb5})
 | 
			
		||||
        endif()
 | 
			
		||||
 | 
			
		||||
        if(NOT zlib)
 | 
			
		||||
            ExternalProject_Add_StepDependencies(cassandra_src build zlib)
 | 
			
		||||
            target_link_libraries(cassandra INTERFACE zlib)
 | 
			
		||||
        else()
 | 
			
		||||
            target_link_libraries(cassandra INTERFACE ${zlib})
 | 
			
		||||
        endif()
 | 
			
		||||
 | 
			
		||||
        file(TO_CMAKE_PATH "${cassandra_src_SOURCE_DIR}" cassandra_src_SOURCE_DIR)
 | 
			
		||||
        target_link_libraries(ripple_libs INTERFACE cassandra)
 | 
			
		||||
    else()
 | 
			
		||||
        message("Found system installed cassandra cpp driver")
 | 
			
		||||
 | 
			
		||||
        find_path(cassandra_includes NAMES cassandra.h REQUIRED)
 | 
			
		||||
        target_link_libraries (ripple_libs INTERFACE ${cassandra})
 | 
			
		||||
        target_include_directories(ripple_libs INTERFACE ${cassandra_includes})
 | 
			
		||||
    endif()
 | 
			
		||||
 | 
			
		||||
    exclude_if_included (cassandra)
 | 
			
		||||
endif()
 | 
			
		||||
@@ -1,18 +0,0 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH dep: date
 | 
			
		||||
 | 
			
		||||
   the main library is header-only, thus is an INTERFACE lib in CMake.
 | 
			
		||||
 | 
			
		||||
   NOTE: this has been accepted into c++20 so can likely be replaced
 | 
			
		||||
   when we update to that standard
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
find_package (date QUIET)
 | 
			
		||||
if (NOT TARGET date::date)
 | 
			
		||||
  FetchContent_Declare(
 | 
			
		||||
    hh_date_src
 | 
			
		||||
    GIT_REPOSITORY https://github.com/HowardHinnant/date.git
 | 
			
		||||
    GIT_TAG        fc4cf092f9674f2670fb9177edcdee870399b829
 | 
			
		||||
  )
 | 
			
		||||
  FetchContent_MakeAvailable(hh_date_src)
 | 
			
		||||
endif ()
 | 
			
		||||
@@ -1,324 +1,15 @@
 | 
			
		||||
 | 
			
		||||
# currently linking to unsecure versions...if we switch, we'll
 | 
			
		||||
# need to add ssl as a link dependency to the grpc targets
 | 
			
		||||
option (use_secure_grpc "use TLS version of grpc libs." OFF)
 | 
			
		||||
if (use_secure_grpc)
 | 
			
		||||
  set (grpc_suffix "")
 | 
			
		||||
else ()
 | 
			
		||||
  set (grpc_suffix "_unsecure")
 | 
			
		||||
endif ()
 | 
			
		||||
 | 
			
		||||
find_package (gRPC 1.23 CONFIG QUIET)
 | 
			
		||||
if (TARGET gRPC::gpr AND NOT local_grpc)
 | 
			
		||||
  get_target_property (_grpc_l gRPC::gpr IMPORTED_LOCATION_DEBUG)
 | 
			
		||||
  if (NOT _grpc_l)
 | 
			
		||||
    get_target_property (_grpc_l gRPC::gpr IMPORTED_LOCATION_RELEASE)
 | 
			
		||||
  endif ()
 | 
			
		||||
  if (NOT _grpc_l)
 | 
			
		||||
    get_target_property (_grpc_l gRPC::gpr IMPORTED_LOCATION)
 | 
			
		||||
  endif ()
 | 
			
		||||
  message (STATUS "Found cmake config for gRPC. Using ${_grpc_l}.")
 | 
			
		||||
else ()
 | 
			
		||||
  find_package (PkgConfig QUIET)
 | 
			
		||||
  if (PKG_CONFIG_FOUND)
 | 
			
		||||
    pkg_check_modules (grpc QUIET "grpc${grpc_suffix}>=1.25" "grpc++${grpc_suffix}" gpr)
 | 
			
		||||
  endif ()
 | 
			
		||||
 | 
			
		||||
  if (grpc_FOUND)
 | 
			
		||||
    message (STATUS "Found gRPC using pkg-config. Using ${grpc_gpr_PREFIX}.")
 | 
			
		||||
  endif ()
 | 
			
		||||
 | 
			
		||||
  add_executable (gRPC::grpc_cpp_plugin IMPORTED)
 | 
			
		||||
  exclude_if_included (gRPC::grpc_cpp_plugin)
 | 
			
		||||
 | 
			
		||||
  if (grpc_FOUND AND NOT local_grpc)
 | 
			
		||||
    # use installed grpc (via pkg-config)
 | 
			
		||||
    macro (add_imported_grpc libname_)
 | 
			
		||||
      if (static)
 | 
			
		||||
        set (_search "${CMAKE_STATIC_LIBRARY_PREFIX}${libname_}${CMAKE_STATIC_LIBRARY_SUFFIX}")
 | 
			
		||||
      else ()
 | 
			
		||||
        set (_search "${CMAKE_SHARED_LIBRARY_PREFIX}${libname_}${CMAKE_SHARED_LIBRARY_SUFFIX}")
 | 
			
		||||
      endif()
 | 
			
		||||
      find_library(_found_${libname_}
 | 
			
		||||
        NAMES ${_search}
 | 
			
		||||
        HINTS ${grpc_LIBRARY_DIRS})
 | 
			
		||||
      if (_found_${libname_})
 | 
			
		||||
        message (STATUS "importing ${libname_} as ${_found_${libname_}}")
 | 
			
		||||
      else ()
 | 
			
		||||
        message (FATAL_ERROR "using pkg-config for grpc, can't find ${_search}")
 | 
			
		||||
      endif ()
 | 
			
		||||
      add_library ("gRPC::${libname_}" STATIC IMPORTED GLOBAL)
 | 
			
		||||
      set_target_properties ("gRPC::${libname_}" PROPERTIES IMPORTED_LOCATION ${_found_${libname_}})
 | 
			
		||||
      if (grpc_INCLUDE_DIRS)
 | 
			
		||||
        set_target_properties ("gRPC::${libname_}" PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${grpc_INCLUDE_DIRS})
 | 
			
		||||
      endif ()
 | 
			
		||||
      target_link_libraries (ripple_libs INTERFACE "gRPC::${libname_}")
 | 
			
		||||
      exclude_if_included ("gRPC::${libname_}")
 | 
			
		||||
    endmacro ()
 | 
			
		||||
 | 
			
		||||
    set_target_properties (gRPC::grpc_cpp_plugin PROPERTIES
 | 
			
		||||
        IMPORTED_LOCATION "${grpc_gpr_PREFIX}/bin/grpc_cpp_plugin${CMAKE_EXECUTABLE_SUFFIX}")
 | 
			
		||||
 | 
			
		||||
    pkg_check_modules (cares QUIET libcares)
 | 
			
		||||
    if (cares_FOUND)
 | 
			
		||||
      if (static)
 | 
			
		||||
        set (_search "${CMAKE_STATIC_LIBRARY_PREFIX}cares${CMAKE_STATIC_LIBRARY_SUFFIX}")
 | 
			
		||||
        set (_prefix cares_STATIC)
 | 
			
		||||
        set (_static STATIC)
 | 
			
		||||
      else ()
 | 
			
		||||
        set (_search "${CMAKE_SHARED_LIBRARY_PREFIX}cares${CMAKE_SHARED_LIBRARY_SUFFIX}")
 | 
			
		||||
        set (_prefix cares)
 | 
			
		||||
        set (_static)
 | 
			
		||||
      endif()
 | 
			
		||||
      find_library(_location NAMES ${_search} HINTS ${cares_LIBRARY_DIRS})
 | 
			
		||||
      if (NOT _location)
 | 
			
		||||
        message (FATAL_ERROR "using pkg-config for grpc, can't find c-ares")
 | 
			
		||||
      endif ()
 | 
			
		||||
      if(${_location} MATCHES "\\.a$")
 | 
			
		||||
        add_library(c-ares::cares STATIC IMPORTED GLOBAL)
 | 
			
		||||
      else()
 | 
			
		||||
        add_library(c-ares::cares SHARED IMPORTED GLOBAL)
 | 
			
		||||
      endif()      
 | 
			
		||||
      set_target_properties (c-ares::cares PROPERTIES
 | 
			
		||||
        IMPORTED_LOCATION ${_location}
 | 
			
		||||
        INTERFACE_INCLUDE_DIRECTORIES "${${_prefix}_INCLUDE_DIRS}"
 | 
			
		||||
        INTERFACE_LINK_OPTIONS "${${_prefix}_LDFLAGS}"
 | 
			
		||||
      )
 | 
			
		||||
      exclude_if_included (c-ares::cares)
 | 
			
		||||
    else ()
 | 
			
		||||
      message (FATAL_ERROR "using pkg-config for grpc, can't find c-ares")
 | 
			
		||||
    endif ()
 | 
			
		||||
  else ()
 | 
			
		||||
    #[===========================[
 | 
			
		||||
       c-ares (grpc requires)
 | 
			
		||||
    #]===========================]
 | 
			
		||||
    ExternalProject_Add (c-ares_src
 | 
			
		||||
      PREFIX ${nih_cache_path}
 | 
			
		||||
      GIT_REPOSITORY https://github.com/c-ares/c-ares.git
 | 
			
		||||
      GIT_TAG cares-1_15_0
 | 
			
		||||
      CMAKE_ARGS
 | 
			
		||||
        -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
 | 
			
		||||
        $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-DCMAKE_VERBOSE_MAKEFILE=ON>
 | 
			
		||||
        -DCMAKE_DEBUG_POSTFIX=_d
 | 
			
		||||
        $<$<NOT:$<BOOL:${is_multiconfig}>>:-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}>
 | 
			
		||||
        -DCMAKE_INSTALL_PREFIX=<BINARY_DIR>/_installed_
 | 
			
		||||
        -DCARES_SHARED=OFF
 | 
			
		||||
        -DCARES_STATIC=ON
 | 
			
		||||
        -DCARES_STATIC_PIC=ON
 | 
			
		||||
        -DCARES_INSTALL=ON
 | 
			
		||||
        -DCARES_MSVC_STATIC_RUNTIME=ON
 | 
			
		||||
        $<$<BOOL:${MSVC}>:
 | 
			
		||||
          "-DCMAKE_C_FLAGS=-GR -Gd -fp:precise -FS -MP"
 | 
			
		||||
        >
 | 
			
		||||
      LOG_BUILD ON
 | 
			
		||||
      LOG_CONFIGURE ON
 | 
			
		||||
      BUILD_COMMAND
 | 
			
		||||
        ${CMAKE_COMMAND}
 | 
			
		||||
          --build .
 | 
			
		||||
          --config $<CONFIG>
 | 
			
		||||
          --parallel ${ep_procs}
 | 
			
		||||
      TEST_COMMAND ""
 | 
			
		||||
      INSTALL_COMMAND
 | 
			
		||||
        ${CMAKE_COMMAND} -E env --unset=DESTDIR ${CMAKE_COMMAND} --build . --config $<CONFIG> --target install
 | 
			
		||||
      BUILD_BYPRODUCTS
 | 
			
		||||
        <BINARY_DIR>/_installed_/lib/${ep_lib_prefix}cares${ep_lib_suffix}
 | 
			
		||||
        <BINARY_DIR>/_installed_/lib/${ep_lib_prefix}cares_d${ep_lib_suffix}
 | 
			
		||||
    )
 | 
			
		||||
    exclude_if_included (c-ares_src)
 | 
			
		||||
    ExternalProject_Get_Property (c-ares_src BINARY_DIR)
 | 
			
		||||
    set (cares_binary_dir "${BINARY_DIR}")
 | 
			
		||||
 | 
			
		||||
    add_library (c-ares::cares STATIC IMPORTED GLOBAL)
 | 
			
		||||
    file (MAKE_DIRECTORY ${BINARY_DIR}/_installed_/include)
 | 
			
		||||
    set_target_properties (c-ares::cares PROPERTIES
 | 
			
		||||
      IMPORTED_LOCATION_DEBUG
 | 
			
		||||
        ${BINARY_DIR}/_installed_/lib/${ep_lib_prefix}cares_d${ep_lib_suffix}
 | 
			
		||||
      IMPORTED_LOCATION_RELEASE
 | 
			
		||||
        ${BINARY_DIR}/_installed_/lib/${ep_lib_prefix}cares${ep_lib_suffix}
 | 
			
		||||
      INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
        ${BINARY_DIR}/_installed_/include)
 | 
			
		||||
    add_dependencies (c-ares::cares c-ares_src)
 | 
			
		||||
    exclude_if_included (c-ares::cares)
 | 
			
		||||
 | 
			
		||||
    if (NOT has_zlib)
 | 
			
		||||
      #[===========================[
 | 
			
		||||
         zlib (grpc requires)
 | 
			
		||||
      #]===========================]
 | 
			
		||||
      if (MSVC)
 | 
			
		||||
        set (zlib_debug_postfix "d") # zlib cmake sets this internally for MSVC, so we really don't have a choice
 | 
			
		||||
        set (zlib_base "zlibstatic")
 | 
			
		||||
      else ()
 | 
			
		||||
        set (zlib_debug_postfix "_d")
 | 
			
		||||
        set (zlib_base "z")
 | 
			
		||||
      endif ()
 | 
			
		||||
      ExternalProject_Add (zlib_src
 | 
			
		||||
        PREFIX ${nih_cache_path}
 | 
			
		||||
        GIT_REPOSITORY https://github.com/madler/zlib.git
 | 
			
		||||
        GIT_TAG v1.2.11
 | 
			
		||||
        CMAKE_ARGS
 | 
			
		||||
          -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
 | 
			
		||||
          $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-DCMAKE_VERBOSE_MAKEFILE=ON>
 | 
			
		||||
          -DCMAKE_DEBUG_POSTFIX=${zlib_debug_postfix}
 | 
			
		||||
          $<$<NOT:$<BOOL:${is_multiconfig}>>:-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}>
 | 
			
		||||
          -DCMAKE_INSTALL_PREFIX=<BINARY_DIR>/_installed_
 | 
			
		||||
          -DBUILD_SHARED_LIBS=OFF
 | 
			
		||||
          $<$<BOOL:${MSVC}>:
 | 
			
		||||
            "-DCMAKE_C_FLAGS=-GR -Gd -fp:precise -FS -MP"
 | 
			
		||||
            "-DCMAKE_C_FLAGS_DEBUG=-MTd"
 | 
			
		||||
            "-DCMAKE_C_FLAGS_RELEASE=-MT"
 | 
			
		||||
          >
 | 
			
		||||
        LOG_BUILD ON
 | 
			
		||||
        LOG_CONFIGURE ON
 | 
			
		||||
        BUILD_COMMAND
 | 
			
		||||
          ${CMAKE_COMMAND}
 | 
			
		||||
            --build .
 | 
			
		||||
            --config $<CONFIG>
 | 
			
		||||
            --parallel ${ep_procs}
 | 
			
		||||
        TEST_COMMAND ""
 | 
			
		||||
        INSTALL_COMMAND
 | 
			
		||||
          ${CMAKE_COMMAND} -E env --unset=DESTDIR ${CMAKE_COMMAND} --build . --config $<CONFIG> --target install
 | 
			
		||||
        BUILD_BYPRODUCTS
 | 
			
		||||
          <BINARY_DIR>/_installed_/lib/${ep_lib_prefix}${zlib_base}${ep_lib_suffix}
 | 
			
		||||
          <BINARY_DIR>/_installed_/lib/${ep_lib_prefix}${zlib_base}${zlib_debug_postfix}${ep_lib_suffix}
 | 
			
		||||
      )
 | 
			
		||||
      exclude_if_included (zlib_src)
 | 
			
		||||
      ExternalProject_Get_Property (zlib_src BINARY_DIR)
 | 
			
		||||
      set (zlib_binary_dir "${BINARY_DIR}")
 | 
			
		||||
 | 
			
		||||
      add_library (ZLIB::ZLIB STATIC IMPORTED GLOBAL)
 | 
			
		||||
      file (MAKE_DIRECTORY ${BINARY_DIR}/_installed_/include)
 | 
			
		||||
      set_target_properties (ZLIB::ZLIB PROPERTIES
 | 
			
		||||
        IMPORTED_LOCATION_DEBUG
 | 
			
		||||
          ${BINARY_DIR}/_installed_/lib/${ep_lib_prefix}${zlib_base}${zlib_debug_postfix}${ep_lib_suffix}
 | 
			
		||||
        IMPORTED_LOCATION_RELEASE
 | 
			
		||||
          ${BINARY_DIR}/_installed_/lib/${ep_lib_prefix}${zlib_base}${ep_lib_suffix}
 | 
			
		||||
        INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
          ${BINARY_DIR}/_installed_/include)
 | 
			
		||||
      add_dependencies (ZLIB::ZLIB zlib_src)
 | 
			
		||||
      exclude_if_included (ZLIB::ZLIB)
 | 
			
		||||
    endif ()
 | 
			
		||||
 | 
			
		||||
    #[===========================[
 | 
			
		||||
       grpc
 | 
			
		||||
    #]===========================]
 | 
			
		||||
    ExternalProject_Add (grpc_src
 | 
			
		||||
      PREFIX ${nih_cache_path}
 | 
			
		||||
      GIT_REPOSITORY https://github.com/grpc/grpc.git
 | 
			
		||||
      GIT_TAG v1.25.0
 | 
			
		||||
      CMAKE_ARGS
 | 
			
		||||
        -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
 | 
			
		||||
        -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
 | 
			
		||||
        -DCMAKE_CXX_STANDARD=17
 | 
			
		||||
        $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-DCMAKE_VERBOSE_MAKEFILE=ON>
 | 
			
		||||
        $<$<BOOL:${CMAKE_TOOLCHAIN_FILE}>:-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}>
 | 
			
		||||
        $<$<BOOL:${VCPKG_TARGET_TRIPLET}>:-DVCPKG_TARGET_TRIPLET=${VCPKG_TARGET_TRIPLET}>
 | 
			
		||||
        $<$<BOOL:${unity}>:-DCMAKE_UNITY_BUILD=ON}>
 | 
			
		||||
        -DCMAKE_DEBUG_POSTFIX=_d
 | 
			
		||||
        $<$<NOT:$<BOOL:${is_multiconfig}>>:-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}>
 | 
			
		||||
        -DgRPC_BUILD_TESTS=OFF
 | 
			
		||||
        -DgRPC_BENCHMARK_PROVIDER=""
 | 
			
		||||
        -DgRPC_BUILD_CSHARP_EXT=OFF
 | 
			
		||||
        -DgRPC_MSVC_STATIC_RUNTIME=ON
 | 
			
		||||
        -DgRPC_INSTALL=OFF
 | 
			
		||||
        -DgRPC_CARES_PROVIDER=package
 | 
			
		||||
        -Dc-ares_DIR=${cares_binary_dir}/_installed_/lib/cmake/c-ares
 | 
			
		||||
        -DgRPC_SSL_PROVIDER=package
 | 
			
		||||
        -DOPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR}
 | 
			
		||||
        -DgRPC_PROTOBUF_PROVIDER=package
 | 
			
		||||
        -DProtobuf_USE_STATIC_LIBS=$<IF:$<AND:$<BOOL:${Protobuf_FOUND}>,$<NOT:$<BOOL:${static}>>>,OFF,ON>
 | 
			
		||||
        -DProtobuf_INCLUDE_DIR=$<JOIN:$<TARGET_PROPERTY:protobuf::libprotobuf,INTERFACE_INCLUDE_DIRECTORIES>,:_:>
 | 
			
		||||
        -DProtobuf_LIBRARY=$<IF:$<CONFIG:Debug>,$<TARGET_PROPERTY:protobuf::libprotobuf,IMPORTED_LOCATION_DEBUG>,$<TARGET_PROPERTY:protobuf::libprotobuf,IMPORTED_LOCATION_RELEASE>>
 | 
			
		||||
        -DProtobuf_PROTOC_LIBRARY=$<IF:$<CONFIG:Debug>,$<TARGET_PROPERTY:protobuf::libprotoc,IMPORTED_LOCATION_DEBUG>,$<TARGET_PROPERTY:protobuf::libprotoc,IMPORTED_LOCATION_RELEASE>>
 | 
			
		||||
        -DProtobuf_PROTOC_EXECUTABLE=$<TARGET_PROPERTY:protobuf::protoc,IMPORTED_LOCATION>
 | 
			
		||||
        -DgRPC_ZLIB_PROVIDER=package
 | 
			
		||||
        $<$<NOT:$<BOOL:${has_zlib}>>:-DZLIB_ROOT=${zlib_binary_dir}/_installed_>
 | 
			
		||||
        $<$<BOOL:${MSVC}>:
 | 
			
		||||
          "-DCMAKE_CXX_FLAGS=-GR -Gd -fp:precise -FS -EHa -MP"
 | 
			
		||||
          "-DCMAKE_C_FLAGS=-GR -Gd -fp:precise -FS -MP"
 | 
			
		||||
        >
 | 
			
		||||
      LOG_BUILD ON
 | 
			
		||||
      LOG_CONFIGURE ON
 | 
			
		||||
      BUILD_COMMAND
 | 
			
		||||
        ${CMAKE_COMMAND}
 | 
			
		||||
        --build .
 | 
			
		||||
        --config $<CONFIG>
 | 
			
		||||
        --parallel ${ep_procs}
 | 
			
		||||
        $<$<BOOL:${is_multiconfig}>:
 | 
			
		||||
          COMMAND
 | 
			
		||||
            ${CMAKE_COMMAND} -E copy
 | 
			
		||||
            <BINARY_DIR>/$<CONFIG>/${ep_lib_prefix}grpc${grpc_suffix}$<$<CONFIG:Debug>:_d>${ep_lib_suffix}
 | 
			
		||||
            <BINARY_DIR>/$<CONFIG>/${ep_lib_prefix}grpc++${grpc_suffix}$<$<CONFIG:Debug>:_d>${ep_lib_suffix}
 | 
			
		||||
            <BINARY_DIR>/$<CONFIG>/${ep_lib_prefix}address_sorting$<$<CONFIG:Debug>:_d>${ep_lib_suffix}
 | 
			
		||||
            <BINARY_DIR>/$<CONFIG>/${ep_lib_prefix}gpr$<$<CONFIG:Debug>:_d>${ep_lib_suffix}
 | 
			
		||||
            <BINARY_DIR>/$<CONFIG>/grpc_cpp_plugin${CMAKE_EXECUTABLE_SUFFIX}
 | 
			
		||||
            <BINARY_DIR>
 | 
			
		||||
          >
 | 
			
		||||
      LIST_SEPARATOR :_:
 | 
			
		||||
      TEST_COMMAND ""
 | 
			
		||||
      INSTALL_COMMAND ""
 | 
			
		||||
      DEPENDS c-ares_src
 | 
			
		||||
      BUILD_BYPRODUCTS
 | 
			
		||||
        <BINARY_DIR>/${ep_lib_prefix}grpc${grpc_suffix}${ep_lib_suffix}
 | 
			
		||||
        <BINARY_DIR>/${ep_lib_prefix}grpc${grpc_suffix}_d${ep_lib_suffix}
 | 
			
		||||
        <BINARY_DIR>/${ep_lib_prefix}grpc++${grpc_suffix}${ep_lib_suffix}
 | 
			
		||||
        <BINARY_DIR>/${ep_lib_prefix}grpc++${grpc_suffix}_d${ep_lib_suffix}
 | 
			
		||||
        <BINARY_DIR>/${ep_lib_prefix}address_sorting${ep_lib_suffix}
 | 
			
		||||
        <BINARY_DIR>/${ep_lib_prefix}address_sorting_d${ep_lib_suffix}
 | 
			
		||||
        <BINARY_DIR>/${ep_lib_prefix}gpr${ep_lib_suffix}
 | 
			
		||||
        <BINARY_DIR>/${ep_lib_prefix}gpr_d${ep_lib_suffix}
 | 
			
		||||
        <BINARY_DIR>/grpc_cpp_plugin${CMAKE_EXECUTABLE_SUFFIX}
 | 
			
		||||
    )
 | 
			
		||||
    if (TARGET protobuf_src)
 | 
			
		||||
      ExternalProject_Add_StepDependencies(grpc_src build protobuf_src)
 | 
			
		||||
    endif ()
 | 
			
		||||
    exclude_if_included (grpc_src)
 | 
			
		||||
    ExternalProject_Get_Property (grpc_src BINARY_DIR)
 | 
			
		||||
    ExternalProject_Get_Property (grpc_src SOURCE_DIR)
 | 
			
		||||
    set (grpc_binary_dir "${BINARY_DIR}")
 | 
			
		||||
    set (grpc_source_dir "${SOURCE_DIR}")
 | 
			
		||||
    if (CMAKE_VERBOSE_MAKEFILE)
 | 
			
		||||
      print_ep_logs (grpc_src)
 | 
			
		||||
    endif ()
 | 
			
		||||
    file (MAKE_DIRECTORY ${SOURCE_DIR}/include)
 | 
			
		||||
 | 
			
		||||
    macro (add_imported_grpc libname_)
 | 
			
		||||
      add_library ("gRPC::${libname_}" STATIC IMPORTED GLOBAL)
 | 
			
		||||
      set_target_properties ("gRPC::${libname_}" PROPERTIES
 | 
			
		||||
        IMPORTED_LOCATION_DEBUG
 | 
			
		||||
          ${grpc_binary_dir}/${ep_lib_prefix}${libname_}_d${ep_lib_suffix}
 | 
			
		||||
        IMPORTED_LOCATION_RELEASE
 | 
			
		||||
          ${grpc_binary_dir}/${ep_lib_prefix}${libname_}${ep_lib_suffix}
 | 
			
		||||
        INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
          ${grpc_source_dir}/include)
 | 
			
		||||
      add_dependencies ("gRPC::${libname_}" grpc_src)
 | 
			
		||||
      target_link_libraries (ripple_libs INTERFACE "gRPC::${libname_}")
 | 
			
		||||
      exclude_if_included ("gRPC::${libname_}")
 | 
			
		||||
    endmacro ()
 | 
			
		||||
 | 
			
		||||
    set_target_properties (gRPC::grpc_cpp_plugin PROPERTIES
 | 
			
		||||
        IMPORTED_LOCATION "${grpc_binary_dir}/grpc_cpp_plugin${CMAKE_EXECUTABLE_SUFFIX}")
 | 
			
		||||
    add_dependencies (gRPC::grpc_cpp_plugin grpc_src)
 | 
			
		||||
  endif ()
 | 
			
		||||
 | 
			
		||||
  add_imported_grpc (gpr)
 | 
			
		||||
  add_imported_grpc ("grpc${grpc_suffix}")
 | 
			
		||||
  add_imported_grpc ("grpc++${grpc_suffix}")
 | 
			
		||||
  add_imported_grpc (address_sorting)
 | 
			
		||||
 | 
			
		||||
  target_link_libraries ("gRPC::grpc${grpc_suffix}" INTERFACE c-ares::cares gRPC::gpr gRPC::address_sorting ZLIB::ZLIB)
 | 
			
		||||
  target_link_libraries ("gRPC::grpc++${grpc_suffix}" INTERFACE "gRPC::grpc${grpc_suffix}" gRPC::gpr)
 | 
			
		||||
endif ()
 | 
			
		||||
find_package(gRPC 1.23)
 | 
			
		||||
 | 
			
		||||
#[=================================[
 | 
			
		||||
   generate protobuf sources for
 | 
			
		||||
   grpc defs and bundle into a
 | 
			
		||||
   static lib
 | 
			
		||||
#]=================================]
 | 
			
		||||
set (GRPC_GEN_DIR "${CMAKE_BINARY_DIR}/proto_gen_grpc")
 | 
			
		||||
file (MAKE_DIRECTORY ${GRPC_GEN_DIR})
 | 
			
		||||
set (GRPC_PROTO_SRCS)
 | 
			
		||||
set (GRPC_PROTO_HDRS)
 | 
			
		||||
set (GRPC_PROTO_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/src/ripple/proto/org")
 | 
			
		||||
set(GRPC_GEN_DIR "${CMAKE_BINARY_DIR}/proto_gen_grpc")
 | 
			
		||||
file(MAKE_DIRECTORY ${GRPC_GEN_DIR})
 | 
			
		||||
set(GRPC_PROTO_SRCS)
 | 
			
		||||
set(GRPC_PROTO_HDRS)
 | 
			
		||||
set(GRPC_PROTO_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/src/ripple/proto/org")
 | 
			
		||||
file(GLOB_RECURSE GRPC_DEFINITION_FILES LIST_DIRECTORIES false "${GRPC_PROTO_ROOT}/*.proto")
 | 
			
		||||
foreach(file ${GRPC_DEFINITION_FILES})
 | 
			
		||||
  get_filename_component(_abs_file ${file} ABSOLUTE)
 | 
			
		||||
@@ -329,10 +20,10 @@ foreach(file ${GRPC_DEFINITION_FILES})
 | 
			
		||||
  get_filename_component(_rel_root_dir ${_rel_root_file} DIRECTORY)
 | 
			
		||||
  file(RELATIVE_PATH _rel_dir ${CMAKE_CURRENT_SOURCE_DIR} ${_abs_dir})
 | 
			
		||||
 | 
			
		||||
  set (src_1 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.grpc.pb.cc")
 | 
			
		||||
  set (src_2 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.pb.cc")
 | 
			
		||||
  set (hdr_1 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.grpc.pb.h")
 | 
			
		||||
  set (hdr_2 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.pb.h")
 | 
			
		||||
  set(src_1 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.grpc.pb.cc")
 | 
			
		||||
  set(src_2 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.pb.cc")
 | 
			
		||||
  set(hdr_1 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.grpc.pb.h")
 | 
			
		||||
  set(hdr_2 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.pb.h")
 | 
			
		||||
  add_custom_command(
 | 
			
		||||
    OUTPUT ${src_1} ${src_2} ${hdr_1} ${hdr_2}
 | 
			
		||||
    COMMAND protobuf::protoc
 | 
			
		||||
@@ -350,20 +41,22 @@ foreach(file ${GRPC_DEFINITION_FILES})
 | 
			
		||||
    list(APPEND GRPC_PROTO_HDRS ${hdr_1} ${hdr_2})
 | 
			
		||||
endforeach()
 | 
			
		||||
 | 
			
		||||
add_library (grpc_pbufs STATIC ${GRPC_PROTO_SRCS} ${GRPC_PROTO_HDRS})
 | 
			
		||||
#target_include_directories (grpc_pbufs PRIVATE src)
 | 
			
		||||
target_include_directories (grpc_pbufs SYSTEM PUBLIC ${GRPC_GEN_DIR})
 | 
			
		||||
target_link_libraries (grpc_pbufs protobuf::libprotobuf "gRPC::grpc++${grpc_suffix}")
 | 
			
		||||
target_compile_options (grpc_pbufs
 | 
			
		||||
add_library(grpc_pbufs STATIC ${GRPC_PROTO_SRCS} ${GRPC_PROTO_HDRS})
 | 
			
		||||
#target_include_directories(grpc_pbufs PRIVATE src)
 | 
			
		||||
target_include_directories(grpc_pbufs SYSTEM PUBLIC ${GRPC_GEN_DIR})
 | 
			
		||||
target_link_libraries(grpc_pbufs
 | 
			
		||||
  "gRPC::grpc++"
 | 
			
		||||
  # libgrpc is missing references.
 | 
			
		||||
  absl::random_random
 | 
			
		||||
)
 | 
			
		||||
target_compile_options(grpc_pbufs
 | 
			
		||||
  PRIVATE
 | 
			
		||||
    $<$<BOOL:${MSVC}>:-wd4065>
 | 
			
		||||
    $<$<NOT:$<BOOL:${MSVC}>>:-Wno-deprecated-declarations>
 | 
			
		||||
  PUBLIC
 | 
			
		||||
    $<$<BOOL:${MSVC}>:-wd4996>
 | 
			
		||||
    $<$<BOOL:${is_xcode}>:
 | 
			
		||||
    $<$<BOOL:${XCODE}>:
 | 
			
		||||
      --system-header-prefix="google/protobuf"
 | 
			
		||||
      -Wno-deprecated-dynamic-exception-spec
 | 
			
		||||
    >)
 | 
			
		||||
add_library (Ripple::grpc_pbufs ALIAS grpc_pbufs)
 | 
			
		||||
target_link_libraries (ripple_libs INTERFACE Ripple::grpc_pbufs)
 | 
			
		||||
exclude_if_included (grpc_pbufs)
 | 
			
		||||
add_library(Ripple::grpc_pbufs ALIAS grpc_pbufs)
 | 
			
		||||
							
								
								
									
										52
									
								
								Builds/CMake/deps/quickjs.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								Builds/CMake/deps/quickjs.cmake
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
# QuickJS source files
 | 
			
		||||
set(QUICKJS_SOURCES
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/src/quickjs/libutf.c
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/src/quickjs/qsort_r.c
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/src/quickjs/tutf8e.c
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/src/quickjs/vector.c
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/src/quickjs/char-utils.c
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/src/quickjs/buffer-utils.c
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/src/quickjs/utils.c
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/src/quickjs/ringbuffer.c
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/src/quickjs/libregexp.c
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/src/quickjs/quickjs.c
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/src/quickjs/libregexp.c
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/src/quickjs/libunicode.c
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/src/quickjs/cutils.c
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/src/quickjs/quickjs-libc.c
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/src/quickjs/libbf.c
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/src/quickjs/quickjs-textcode.c
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/src/quickjs/quickjs-internal.c
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/src/quickjs/debug.c
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
# QuickJS include directories
 | 
			
		||||
set(QUICKJS_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/src/quickjs)
 | 
			
		||||
 | 
			
		||||
# RHTODO: Fix this to be dynamic
 | 
			
		||||
set(QUICKJS_VERSION "2023-01-01")
 | 
			
		||||
 | 
			
		||||
# QuickJS compile definitions
 | 
			
		||||
set(QUICKJS_COMPILE_DEFINITIONS
 | 
			
		||||
    _GNU_SOURCE
 | 
			
		||||
    CONFIG_VERSION="${QUICKJS_VERSION}"
 | 
			
		||||
    CONFIG_BIGNUM
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
# Create static library
 | 
			
		||||
add_library(quickjs STATIC ${QUICKJS_SOURCES})
 | 
			
		||||
target_include_directories(quickjs
 | 
			
		||||
  PUBLIC
 | 
			
		||||
    $<BUILD_INTERFACE:${QUICKJS_INCLUDE_DIRS}>
 | 
			
		||||
    $<INSTALL_INTERFACE:include/quickjs>
 | 
			
		||||
)
 | 
			
		||||
target_compile_definitions(quickjs PUBLIC ${QUICKJS_COMPILE_DEFINITIONS})
 | 
			
		||||
 | 
			
		||||
add_library(NIH::quickjs ALIAS quickjs)
 | 
			
		||||
target_link_libraries(ripple_libs INTERFACE NIH::quickjs)
 | 
			
		||||
 | 
			
		||||
install(
 | 
			
		||||
    FILES
 | 
			
		||||
        ${CMAKE_CURRENT_SOURCE_DIR}/src/quickjs/*.h
 | 
			
		||||
    DESTINATION include/quickjs
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										139
									
								
								CMakeLists.txt
									
									
									
									
									
								
							
							
						
						
									
										139
									
								
								CMakeLists.txt
									
									
									
									
									
								
							@@ -50,11 +50,6 @@ if(CMAKE_TOOLCHAIN_FILE)
 | 
			
		||||
  endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if (NOT USE_CONAN)
 | 
			
		||||
  list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/Builds/CMake")
 | 
			
		||||
  list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/Builds/CMake/deps")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
include (CheckCXXCompilerFlag)
 | 
			
		||||
include (FetchContent)
 | 
			
		||||
include (ExternalProject)
 | 
			
		||||
@@ -67,9 +62,7 @@ endif ()
 | 
			
		||||
include(RippledSanity)
 | 
			
		||||
include(RippledVersion)
 | 
			
		||||
include(RippledSettings)
 | 
			
		||||
if (NOT USE_CONAN)
 | 
			
		||||
  include(RippledNIH)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
# this check has to remain in the top-level cmake
 | 
			
		||||
# because of the early return statement
 | 
			
		||||
if (packages_only)
 | 
			
		||||
@@ -81,86 +74,66 @@ endif ()
 | 
			
		||||
include(RippledCompiler)
 | 
			
		||||
include(RippledInterface)
 | 
			
		||||
 | 
			
		||||
###
 | 
			
		||||
if (NOT USE_CONAN)
 | 
			
		||||
  add_subdirectory(src/secp256k1)
 | 
			
		||||
  add_subdirectory(src/ed25519-donna)
 | 
			
		||||
  include(deps/Boost)
 | 
			
		||||
  include(deps/OpenSSL)
 | 
			
		||||
  # include(deps/Secp256k1)
 | 
			
		||||
  # include(deps/Ed25519-donna)
 | 
			
		||||
  include(deps/Lz4)
 | 
			
		||||
  include(deps/Libarchive)
 | 
			
		||||
  include(deps/Sqlite)
 | 
			
		||||
  include(deps/Soci)
 | 
			
		||||
  include(deps/Snappy)
 | 
			
		||||
  include(deps/Rocksdb)
 | 
			
		||||
  include(deps/Nudb)
 | 
			
		||||
  include(deps/date)
 | 
			
		||||
  include(deps/Protobuf)
 | 
			
		||||
  include(deps/gRPC)
 | 
			
		||||
  include(deps/cassandra)
 | 
			
		||||
  include(deps/Postgres)
 | 
			
		||||
  include(deps/WasmEdge)
 | 
			
		||||
else()
 | 
			
		||||
  include(conan/Boost)
 | 
			
		||||
  find_package(OpenSSL 1.1.1 REQUIRED)
 | 
			
		||||
  set_target_properties(OpenSSL::SSL PROPERTIES
 | 
			
		||||
    INTERFACE_COMPILE_DEFINITIONS OPENSSL_NO_SSL2
 | 
			
		||||
include(deps/Boost)
 | 
			
		||||
find_package(OpenSSL 1.1.1 REQUIRED)
 | 
			
		||||
set_target_properties(OpenSSL::SSL PROPERTIES
 | 
			
		||||
  INTERFACE_COMPILE_DEFINITIONS OPENSSL_NO_SSL2
 | 
			
		||||
)
 | 
			
		||||
add_subdirectory(src/secp256k1)
 | 
			
		||||
add_subdirectory(src/ed25519-donna)
 | 
			
		||||
find_package(lz4 REQUIRED)
 | 
			
		||||
# Target names with :: are not allowed in a generator expression.
 | 
			
		||||
# We need to pull the include directories and imported location properties
 | 
			
		||||
# from separate targets.
 | 
			
		||||
find_package(LibArchive REQUIRED)
 | 
			
		||||
find_package(SOCI REQUIRED)
 | 
			
		||||
find_package(SQLite3 REQUIRED)
 | 
			
		||||
find_package(Snappy REQUIRED)
 | 
			
		||||
# find_package(wasmedge REQUIRED)
 | 
			
		||||
option(rocksdb "Enable RocksDB" ON)
 | 
			
		||||
if(rocksdb)
 | 
			
		||||
  find_package(RocksDB REQUIRED)
 | 
			
		||||
  set_target_properties(RocksDB::rocksdb PROPERTIES
 | 
			
		||||
    INTERFACE_COMPILE_DEFINITIONS RIPPLE_ROCKSDB_AVAILABLE=1
 | 
			
		||||
  )
 | 
			
		||||
  add_subdirectory(src/secp256k1)
 | 
			
		||||
  add_subdirectory(src/ed25519-donna)
 | 
			
		||||
  find_package(lz4 REQUIRED)
 | 
			
		||||
  # Target names with :: are not allowed in a generator expression.
 | 
			
		||||
  # We need to pull the include directories and imported location properties
 | 
			
		||||
  # from separate targets.
 | 
			
		||||
  find_package(LibArchive REQUIRED)
 | 
			
		||||
  find_package(SOCI REQUIRED)
 | 
			
		||||
  find_package(SQLite3 REQUIRED)
 | 
			
		||||
  find_package(Snappy REQUIRED)
 | 
			
		||||
  find_package(wasmedge REQUIRED)
 | 
			
		||||
  option(rocksdb "Enable RocksDB" ON)
 | 
			
		||||
  if(rocksdb)
 | 
			
		||||
    find_package(RocksDB REQUIRED)
 | 
			
		||||
    set_target_properties(RocksDB::rocksdb PROPERTIES
 | 
			
		||||
      INTERFACE_COMPILE_DEFINITIONS RIPPLE_ROCKSDB_AVAILABLE=1
 | 
			
		||||
    )
 | 
			
		||||
    target_link_libraries(ripple_libs INTERFACE RocksDB::rocksdb)
 | 
			
		||||
  endif()
 | 
			
		||||
  find_package(nudb REQUIRED)
 | 
			
		||||
  find_package(date REQUIRED)
 | 
			
		||||
  include(conan/Protobuf)
 | 
			
		||||
  include(conan/gRPC)
 | 
			
		||||
    if(TARGET nudb::core)
 | 
			
		||||
    set(nudb nudb::core)
 | 
			
		||||
  elseif(TARGET NuDB::nudb)
 | 
			
		||||
    set(nudb NuDB::nudb)
 | 
			
		||||
  else()
 | 
			
		||||
    message(FATAL_ERROR "unknown nudb target")
 | 
			
		||||
  endif()
 | 
			
		||||
  target_link_libraries(ripple_libs INTERFACE ${nudb})
 | 
			
		||||
  target_link_libraries(ripple_libs INTERFACE RocksDB::rocksdb)
 | 
			
		||||
endif()
 | 
			
		||||
find_package(nudb REQUIRED)
 | 
			
		||||
find_package(date REQUIRED)
 | 
			
		||||
include(deps/Protobuf)
 | 
			
		||||
include(deps/gRPC)
 | 
			
		||||
include(deps/WasmEdge) 
 | 
			
		||||
  if(TARGET nudb::core)
 | 
			
		||||
  set(nudb nudb::core)
 | 
			
		||||
elseif(TARGET NuDB::nudb)
 | 
			
		||||
  set(nudb NuDB::nudb)
 | 
			
		||||
else()
 | 
			
		||||
  message(FATAL_ERROR "unknown nudb target")
 | 
			
		||||
endif()
 | 
			
		||||
target_link_libraries(ripple_libs INTERFACE ${nudb})
 | 
			
		||||
 | 
			
		||||
  if(reporting)
 | 
			
		||||
    find_package(cassandra-cpp-driver REQUIRED)
 | 
			
		||||
    find_package(PostgreSQL REQUIRED)
 | 
			
		||||
    target_link_libraries(ripple_libs INTERFACE
 | 
			
		||||
      cassandra-cpp-driver::cassandra-cpp-driver
 | 
			
		||||
      PostgreSQL::PostgreSQL
 | 
			
		||||
    )
 | 
			
		||||
  endif()
 | 
			
		||||
if(reporting)
 | 
			
		||||
  find_package(cassandra-cpp-driver REQUIRED)
 | 
			
		||||
  find_package(PostgreSQL REQUIRED)
 | 
			
		||||
  target_link_libraries(ripple_libs INTERFACE
 | 
			
		||||
    ed25519::ed25519
 | 
			
		||||
    LibArchive::LibArchive
 | 
			
		||||
    lz4::lz4
 | 
			
		||||
    OpenSSL::Crypto
 | 
			
		||||
    OpenSSL::SSL
 | 
			
		||||
    Ripple::grpc_pbufs
 | 
			
		||||
    Ripple::pbufs
 | 
			
		||||
    secp256k1::secp256k1
 | 
			
		||||
    soci::soci
 | 
			
		||||
    SQLite::SQLite3
 | 
			
		||||
    cassandra-cpp-driver::cassandra-cpp-driver
 | 
			
		||||
    PostgreSQL::PostgreSQL
 | 
			
		||||
  )
 | 
			
		||||
endif()
 | 
			
		||||
target_link_libraries(ripple_libs INTERFACE
 | 
			
		||||
  ed25519::ed25519
 | 
			
		||||
  LibArchive::LibArchive
 | 
			
		||||
  lz4::lz4
 | 
			
		||||
  OpenSSL::Crypto
 | 
			
		||||
  OpenSSL::SSL
 | 
			
		||||
  Ripple::grpc_pbufs
 | 
			
		||||
  Ripple::pbufs
 | 
			
		||||
  secp256k1::secp256k1
 | 
			
		||||
  soci::soci
 | 
			
		||||
  SQLite::SQLite3
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
include(deps/quickjs)
 | 
			
		||||
 | 
			
		||||
###
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,8 +5,6 @@
 | 
			
		||||
# debugging.
 | 
			
		||||
set -ex
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
echo "START INSIDE CONTAINER - CORE"
 | 
			
		||||
 | 
			
		||||
echo "-- BUILD CORES:       $3"
 | 
			
		||||
@@ -27,7 +25,8 @@ if [[ "$?" -ne "0" ]]; then
 | 
			
		||||
  exit 127
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
perl -i -pe "s/^(\\s*)-DBUILD_SHARED_LIBS=OFF/\\1-DBUILD_SHARED_LIBS=OFF\\n\\1-DROCKSDB_BUILD_SHARED=OFF/g" Builds/CMake/deps/Rocksdb.cmake &&
 | 
			
		||||
BUILD_TYPE=Release
 | 
			
		||||
 | 
			
		||||
mv Builds/CMake/deps/WasmEdge.cmake Builds/CMake/deps/WasmEdge.old &&
 | 
			
		||||
echo "find_package(LLVM REQUIRED CONFIG)
 | 
			
		||||
message(STATUS \"Found LLVM \${LLVM_PACKAGE_VERSION}\")
 | 
			
		||||
@@ -38,13 +37,30 @@ target_link_libraries (ripple_libs INTERFACE wasmedge)
 | 
			
		||||
add_library (wasmedge::wasmedge ALIAS wasmedge)
 | 
			
		||||
message(\"WasmEdge DONE\")
 | 
			
		||||
" > Builds/CMake/deps/WasmEdge.cmake &&
 | 
			
		||||
 | 
			
		||||
export LDFLAGS="-static-libstdc++"
 | 
			
		||||
 | 
			
		||||
git config --global --add safe.directory /io &&
 | 
			
		||||
git checkout src/ripple/protocol/impl/BuildInfo.cpp &&
 | 
			
		||||
sed -i s/\"0.0.0\"/\"$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4\"/g src/ripple/protocol/impl/BuildInfo.cpp &&
 | 
			
		||||
sed -i s/\"0.0.0\"/\"$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)$(if [ -n "$4" ]; then echo "+$4"; fi)\"/g src/ripple/protocol/impl/BuildInfo.cpp &&
 | 
			
		||||
conan export external/snappy snappy/1.1.10@xahaud/stable &&
 | 
			
		||||
conan export external/soci soci/4.0.3@xahaud/stable &&
 | 
			
		||||
cd release-build &&
 | 
			
		||||
cmake .. -DCMAKE_BUILD_TYPE=Release -DBoost_NO_BOOST_CMAKE=ON -DLLVM_DIR=/usr/lib64/llvm13/lib/cmake/llvm/ -DLLVM_LIBRARY_DIR=/usr/lib64/llvm13/lib/ -DWasmEdge_LIB=/usr/local/lib64/libwasmedge.a &&
 | 
			
		||||
make -j$3 VERBOSE=1 &&
 | 
			
		||||
strip -s rippled &&
 | 
			
		||||
conan install .. --output-folder . --build missing --settings build_type=$BUILD_TYPE &&
 | 
			
		||||
cmake .. -G Ninja \
 | 
			
		||||
  -DCMAKE_BUILD_TYPE=$BUILD_TYPE \
 | 
			
		||||
  -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
 | 
			
		||||
  -DCMAKE_EXE_LINKER_FLAGS="-static-libstdc++" \
 | 
			
		||||
  -DLLVM_DIR=$LLVM_DIR \
 | 
			
		||||
  -DWasmEdge_LIB=$WasmEdge_LIB \
 | 
			
		||||
  -Dxrpld=TRUE \
 | 
			
		||||
  -Dtests=TRUE &&
 | 
			
		||||
ccache -z &&
 | 
			
		||||
ninja -j $3 &&
 | 
			
		||||
ccache -s &&
 | 
			
		||||
strip -s rippled &&	
 | 
			
		||||
mv rippled xahaud &&
 | 
			
		||||
libcheck xahaud &&
 | 
			
		||||
echo "Build host: `hostname`" > release.info &&
 | 
			
		||||
echo "Build date: `date`" >> release.info &&
 | 
			
		||||
echo "Build md5: `md5sum xahaud`" >> release.info &&
 | 
			
		||||
@@ -69,8 +85,8 @@ fi
 | 
			
		||||
cd ..;
 | 
			
		||||
 | 
			
		||||
mv src/ripple/net/impl/RegisterSSLCerts.cpp.old src/ripple/net/impl/RegisterSSLCerts.cpp;
 | 
			
		||||
mv Builds/CMake/deps/Rocksdb.cmake.old Builds/CMake/deps/Rocksdb.cmake;
 | 
			
		||||
mv Builds/CMake/deps/WasmEdge.old Builds/CMake/deps/WasmEdge.cmake;
 | 
			
		||||
 | 
			
		||||
rm src/certs/certbundle.h;
 | 
			
		||||
git checkout src/ripple/protocol/impl/BuildInfo.cpp;
 | 
			
		||||
 | 
			
		||||
echo "END INSIDE CONTAINER - CORE"
 | 
			
		||||
 
 | 
			
		||||
@@ -3,8 +3,6 @@
 | 
			
		||||
# processes launched or upon any unbound variable.
 | 
			
		||||
# We use set -x to print commands before running them to help with
 | 
			
		||||
# debugging.
 | 
			
		||||
set -ex
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
echo "START INSIDE CONTAINER - FULL"
 | 
			
		||||
@@ -16,13 +14,6 @@ echo "-- GITHUB_RUN_NUMBER: $4"
 | 
			
		||||
 | 
			
		||||
umask 0000;
 | 
			
		||||
 | 
			
		||||
echo "Fixing CentOS 7 EOL"
 | 
			
		||||
 | 
			
		||||
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
 | 
			
		||||
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
 | 
			
		||||
yum clean all
 | 
			
		||||
yum-config-manager --disable centos-sclo-sclo
 | 
			
		||||
 | 
			
		||||
####
 | 
			
		||||
 | 
			
		||||
cd /io;
 | 
			
		||||
@@ -73,92 +64,15 @@ then
 | 
			
		||||
    #endif/g" src/ripple/net/impl/RegisterSSLCerts.cpp &&
 | 
			
		||||
    sed -i "s/#include <ripple\/net\/RegisterSSLCerts.h>/\0\n#include <certs\/certbundle.h>/g" src/ripple/net/impl/RegisterSSLCerts.cpp
 | 
			
		||||
fi
 | 
			
		||||
mkdir -p .nih_c;
 | 
			
		||||
mkdir -p .nih_toolchain;
 | 
			
		||||
cd .nih_toolchain &&
 | 
			
		||||
yum install -y wget lz4 lz4-devel git llvm13-static.x86_64 llvm13-devel.x86_64 devtoolset-10-binutils zlib-static ncurses-static -y \
 | 
			
		||||
  devtoolset-7-gcc-c++ \
 | 
			
		||||
  devtoolset-9-gcc-c++ \
 | 
			
		||||
  devtoolset-10-gcc-c++ \
 | 
			
		||||
  snappy snappy-devel \
 | 
			
		||||
  zlib zlib-devel \
 | 
			
		||||
  lz4-devel \
 | 
			
		||||
  libasan &&
 | 
			
		||||
export PATH=`echo $PATH | sed -E "s/devtoolset-9/devtoolset-7/g"` &&
 | 
			
		||||
echo "-- Install ZStd 1.1.3 --" &&
 | 
			
		||||
yum install epel-release -y &&
 | 
			
		||||
ZSTD_VERSION="1.1.3" &&
 | 
			
		||||
( wget -nc -q -O zstd-${ZSTD_VERSION}.tar.gz https://github.com/facebook/zstd/archive/v${ZSTD_VERSION}.tar.gz; echo "" ) &&
 | 
			
		||||
tar xzvf zstd-${ZSTD_VERSION}.tar.gz &&
 | 
			
		||||
cd zstd-${ZSTD_VERSION} &&
 | 
			
		||||
make -j$3 install &&
 | 
			
		||||
cd .. &&
 | 
			
		||||
echo "-- Install Cmake 3.23.1 --" &&
 | 
			
		||||
pwd &&
 | 
			
		||||
( wget -nc -q https://github.com/Kitware/CMake/releases/download/v3.23.1/cmake-3.23.1-linux-x86_64.tar.gz; echo "" ) &&
 | 
			
		||||
tar -xzf cmake-3.23.1-linux-x86_64.tar.gz -C /hbb/ &&
 | 
			
		||||
echo "-- Install Boost 1.86.0 --" &&
 | 
			
		||||
pwd &&
 | 
			
		||||
( wget -nc -q https://archives.boost.io/release/1.86.0/source/boost_1_86_0.tar.gz; echo "" ) &&
 | 
			
		||||
tar -xzf boost_1_86_0.tar.gz &&
 | 
			
		||||
cd boost_1_86_0 && ./bootstrap.sh && ./b2  link=static -j$3 && ./b2 install &&
 | 
			
		||||
cd ../ &&
 | 
			
		||||
echo "-- Install Protobuf 3.20.0 --" &&
 | 
			
		||||
pwd &&
 | 
			
		||||
( wget -nc -q https://github.com/protocolbuffers/protobuf/releases/download/v3.20.0/protobuf-all-3.20.0.tar.gz; echo "" ) &&
 | 
			
		||||
tar -xzf protobuf-all-3.20.0.tar.gz &&
 | 
			
		||||
cd protobuf-3.20.0/ &&
 | 
			
		||||
./autogen.sh && ./configure --prefix=/usr --disable-shared link=static && make -j$3 && make install &&
 | 
			
		||||
cd .. &&
 | 
			
		||||
echo "-- Build LLD --" &&
 | 
			
		||||
pwd &&
 | 
			
		||||
ln /usr/bin/llvm-config-13 /usr/bin/llvm-config &&
 | 
			
		||||
mv /opt/rh/devtoolset-9/root/usr/bin/ar /opt/rh/devtoolset-9/root/usr/bin/ar-9 &&
 | 
			
		||||
ln /opt/rh/devtoolset-10/root/usr/bin/ar  /opt/rh/devtoolset-9/root/usr/bin/ar &&
 | 
			
		||||
( wget -nc -q https://github.com/llvm/llvm-project/releases/download/llvmorg-13.0.1/lld-13.0.1.src.tar.xz; echo "" ) &&
 | 
			
		||||
( wget -nc -q https://github.com/llvm/llvm-project/releases/download/llvmorg-13.0.1/libunwind-13.0.1.src.tar.xz; echo "" ) &&
 | 
			
		||||
tar -xf lld-13.0.1.src.tar.xz &&
 | 
			
		||||
tar -xf libunwind-13.0.1.src.tar.xz &&
 | 
			
		||||
cp -r libunwind-13.0.1.src/include libunwind-13.0.1.src/src lld-13.0.1.src/ &&
 | 
			
		||||
cd lld-13.0.1.src &&
 | 
			
		||||
rm -rf build CMakeCache.txt &&
 | 
			
		||||
mkdir -p build &&
 | 
			
		||||
cd build &&
 | 
			
		||||
cmake .. -DLLVM_LIBRARY_DIR=/usr/lib64/llvm13/lib/ -DCMAKE_INSTALL_PREFIX=/usr/lib64/llvm13/ -DCMAKE_BUILD_TYPE=Release &&
 | 
			
		||||
make -j$3 install &&
 | 
			
		||||
ln -s /usr/lib64/llvm13/lib/include/lld /usr/include/lld &&
 | 
			
		||||
cp /usr/lib64/llvm13/lib/liblld*.a /usr/local/lib/ &&
 | 
			
		||||
cd ../../ &&
 | 
			
		||||
echo "-- Build WasmEdge --" &&
 | 
			
		||||
( wget -nc -q https://github.com/WasmEdge/WasmEdge/archive/refs/tags/0.11.2.zip; unzip -o 0.11.2.zip; ) &&
 | 
			
		||||
cd WasmEdge-0.11.2 &&
 | 
			
		||||
( mkdir -p build; echo "" ) &&
 | 
			
		||||
cd build &&
 | 
			
		||||
export BOOST_ROOT="/usr/local/src/boost_1_86_0" &&
 | 
			
		||||
export Boost_LIBRARY_DIRS="/usr/local/lib" &&
 | 
			
		||||
export BOOST_INCLUDEDIR="/usr/local/src/boost_1_86_0" &&
 | 
			
		||||
export PATH=`echo $PATH | sed -E "s/devtoolset-7/devtoolset-9/g"` &&
 | 
			
		||||
cmake .. \
 | 
			
		||||
    -DCMAKE_BUILD_TYPE=Release \
 | 
			
		||||
    -DWASMEDGE_BUILD_SHARED_LIB=OFF \
 | 
			
		||||
    -DWASMEDGE_BUILD_STATIC_LIB=ON \
 | 
			
		||||
    -DWASMEDGE_BUILD_AOT_RUNTIME=ON \
 | 
			
		||||
    -DWASMEDGE_FORCE_DISABLE_LTO=ON \
 | 
			
		||||
    -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
 | 
			
		||||
    -DWASMEDGE_LINK_LLVM_STATIC=ON \
 | 
			
		||||
    -DWASMEDGE_BUILD_PLUGINS=OFF \
 | 
			
		||||
    -DWASMEDGE_LINK_TOOLS_STATIC=ON \
 | 
			
		||||
    -DBoost_NO_BOOST_CMAKE=ON -DLLVM_DIR=/usr/lib64/llvm13/lib/cmake/llvm/ -DLLVM_LIBRARY_DIR=/usr/lib64/llvm13/lib/ &&
 | 
			
		||||
make -j$3 install &&
 | 
			
		||||
export PATH=`echo $PATH | sed -E "s/devtoolset-9/devtoolset-10/g"` &&
 | 
			
		||||
cp -r include/api/wasmedge /usr/include/ &&
 | 
			
		||||
cd /io/ &&
 | 
			
		||||
# Environment setup moved to Dockerfile in release-builder.sh
 | 
			
		||||
source /opt/rh/gcc-toolset-11/enable
 | 
			
		||||
export PATH=/usr/local/bin:$PATH
 | 
			
		||||
export CC='ccache gcc' &&
 | 
			
		||||
export CXX='ccache g++' &&
 | 
			
		||||
echo "-- Build Rippled --" &&
 | 
			
		||||
pwd &&
 | 
			
		||||
cp Builds/CMake/deps/Rocksdb.cmake Builds/CMake/deps/Rocksdb.cmake.old &&
 | 
			
		||||
 | 
			
		||||
echo "MOVING TO [ build-core.sh ]"
 | 
			
		||||
cd /io;
 | 
			
		||||
echo "MOVING TO [ build-core.sh ]";
 | 
			
		||||
 | 
			
		||||
printenv > .env.temp;
 | 
			
		||||
cat .env.temp | grep '=' | sed s/\\\(^[^=]\\+=\\\)/\\1\\\"/g|sed s/\$/\\\"/g > .env;
 | 
			
		||||
 
 | 
			
		||||
@@ -62,7 +62,8 @@
 | 
			
		||||
          "3C43D9A973AA4443EF3FC38E42DD306160FBFFDAB901CD8BAA15D09F2597EB87",
 | 
			
		||||
          "0285B7E5E08E1A8E4C15636F0591D87F73CB6A7B6452A932AD72BBC8E5D1CBE3",
 | 
			
		||||
          "6E739F4F8B07BED29FC9FF440DA3C301CD14A180DF45819F658FEC2F7DE31427",
 | 
			
		||||
          "36799EA497B1369B170805C078AEFE6188345F9B3E324C21E9CA3FF574E3C3D6"
 | 
			
		||||
          "36799EA497B1369B170805C078AEFE6188345F9B3E324C21E9CA3FF574E3C3D6",
 | 
			
		||||
          "DD4F86291F142A20761B32B4D0CE4291F86CA33F0B46F0D04171482FBA52E536"
 | 
			
		||||
        ],
 | 
			
		||||
        "Flags": 0,
 | 
			
		||||
        "LedgerEntryType": "Amendments",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
# standalone: ./rippled -a --ledgerfile config/genesis.json --conf config/rippled-standalone.cfg
 | 
			
		||||
# standalone: ./rippled -a --ledgerfile cfg/genesis.json --conf cfg/rippled-standalone.cfg
 | 
			
		||||
[server]
 | 
			
		||||
port_rpc_admin_local
 | 
			
		||||
port_ws_public
 | 
			
		||||
@@ -153,3 +153,4 @@ D686F2538F410C9D0D856788E98E3579595DAF7B38D38887F81ECAC934B06040 HooksUpdate1
 | 
			
		||||
EDB4EE4C524E16BDD91D9A529332DED08DCAAA51CC6DC897ACFA1A0ED131C5B6 fix240819
 | 
			
		||||
8063140E9260799D6716756B891CEC3E7006C4E4F277AB84670663A88F94B9C4 fixPageCap
 | 
			
		||||
88693F108C3CD8A967F3F4253A32DEF5E35F9406ACD2A11B88B11D90865763A9 fix240911
 | 
			
		||||
DD4F86291F142A20761B32B4D0CE4291F86CA33F0B46F0D04171482FBA52E536 JsHooks
 | 
			
		||||
 
 | 
			
		||||
@@ -32,8 +32,8 @@ class Xrpl(ConanFile):
 | 
			
		||||
        'nudb/2.0.8',
 | 
			
		||||
        'openssl/1.1.1u',
 | 
			
		||||
        'protobuf/3.21.9',
 | 
			
		||||
        'snappy/1.1.10',
 | 
			
		||||
        'soci/4.0.3',
 | 
			
		||||
        'snappy/1.1.10@xahaud/stable',
 | 
			
		||||
        'soci/4.0.3@xahaud/stable',
 | 
			
		||||
        'sqlite3/3.42.0',
 | 
			
		||||
        'zlib/1.2.13',
 | 
			
		||||
        'wasmedge/0.11.2',
 | 
			
		||||
 
 | 
			
		||||
@@ -8,4 +8,4 @@ if [[ "$GITHUB_REPOSITORY" == "" ]]; then
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
echo "Mounting $(pwd)/io in ubuntu and running unit tests"
 | 
			
		||||
docker run --rm -i -v $(pwd):/io -e BUILD_CORES=$BUILD_CORES ubuntu sh -c '/io/release-build/xahaud --unittest-jobs $BUILD_CORES -u'
 | 
			
		||||
docker run --rm -i -v $(pwd):/io --platform=linux/amd64 -e BUILD_CORES=$BUILD_CORES ubuntu sh -c '/io/release-build/xahaud --unittest-jobs $BUILD_CORES -u'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								external/snappy/conanfile.py
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								external/snappy/conanfile.py
									
									
									
									
										vendored
									
									
								
							@@ -77,9 +77,14 @@ class SnappyConan(ConanFile):
 | 
			
		||||
        self.cpp_info.set_property("cmake_target_name", "Snappy::snappy")
 | 
			
		||||
        # TODO: back to global scope in conan v2 once cmake_find_package* generators removed
 | 
			
		||||
        self.cpp_info.components["snappylib"].libs = ["snappy"]
 | 
			
		||||
        if not self.options.shared:
 | 
			
		||||
            if self.settings.os in ["Linux", "FreeBSD"]:
 | 
			
		||||
                self.cpp_info.components["snappylib"].system_libs.append("m")
 | 
			
		||||
        # The following block is commented out as a workaround for a bug in the
 | 
			
		||||
        # Conan 1.x CMakeDeps generator. Including system_libs ("m") here
 | 
			
		||||
        # incorrectly triggers a heuristic that adds a dynamic link to `stdc++`
 | 
			
		||||
        # (-lstdc++), preventing a fully static build.
 | 
			
		||||
        # This behavior is expected to be corrected in Conan 2.
 | 
			
		||||
        # if not self.options.shared:
 | 
			
		||||
        #     if self.settings.os in ["Linux", "FreeBSD"]:
 | 
			
		||||
        #         self.cpp_info.components["snappylib"].system_libs.append("m")
 | 
			
		||||
 | 
			
		||||
        # TODO: to remove in conan v2 once cmake_find_package* generators removed
 | 
			
		||||
        self.cpp_info.names["cmake_find_package"] = "Snappy"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								external/soci/conanfile.py
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								external/soci/conanfile.py
									
									
									
									
										vendored
									
									
								
							@@ -154,7 +154,7 @@ class SociConan(ConanFile):
 | 
			
		||||
        self.cpp_info.components["soci_core"].set_property("cmake_target_name", "SOCI::soci_core{}".format(target_suffix))
 | 
			
		||||
        self.cpp_info.components["soci_core"].libs = ["{}soci_core{}".format(lib_prefix, lib_suffix)]
 | 
			
		||||
        if self.options.with_boost:
 | 
			
		||||
            self.cpp_info.components["soci_core"].requires.append("boost::boost")
 | 
			
		||||
            self.cpp_info.components["soci_core"].requires.append("boost::headers")
 | 
			
		||||
 | 
			
		||||
        # soci_empty
 | 
			
		||||
        if self.options.empty:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,8 @@
 | 
			
		||||
#!/bin/bash -u
 | 
			
		||||
#!/bin/bash 
 | 
			
		||||
# We use set -e and bash with -u to bail on first non zero exit code of any
 | 
			
		||||
# processes launched or upon any unbound variable.
 | 
			
		||||
# We use set -x to print commands before running them to help with
 | 
			
		||||
# debugging.
 | 
			
		||||
set -ex
 | 
			
		||||
 | 
			
		||||
echo "START BUILDING (HOST)"
 | 
			
		||||
 | 
			
		||||
@@ -14,7 +13,7 @@ BUILD_CORES=$(echo "scale=0 ; `nproc` / 1.337" | bc)
 | 
			
		||||
 | 
			
		||||
if [[ "$GITHUB_REPOSITORY" == "" ]]; then
 | 
			
		||||
  #Default
 | 
			
		||||
  BUILD_CORES=8
 | 
			
		||||
  BUILD_CORES=${BUILD_CORES:-8} 
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Ensure still works outside of GH Actions by setting these to /dev/null
 | 
			
		||||
@@ -46,29 +45,166 @@ fi
 | 
			
		||||
 | 
			
		||||
STATIC_CONTAINER=$(docker ps -a | grep $CONTAINER_NAME |wc -l)
 | 
			
		||||
 | 
			
		||||
CACHE_VOLUME_NAME="xahau-release-builder-cache"
 | 
			
		||||
 | 
			
		||||
# if [[ "$STATIC_CONTAINER" -gt "0" && "$GITHUB_REPOSITORY" != "" ]]; then
 | 
			
		||||
if false; then
 | 
			
		||||
  echo "Static container, execute in static container to have max. cache"
 | 
			
		||||
  docker start $CONTAINER_NAME
 | 
			
		||||
  docker exec -i $CONTAINER_NAME /hbb_exe/activate-exec bash -x /io/build-core.sh "$GITHUB_REPOSITORY" "$GITHUB_SHA" "$BUILD_CORES" "$GITHUB_RUN_NUMBER"
 | 
			
		||||
  docker exec -i $CONTAINER_NAME /hbb_exe/activate-exec bash -c "source /opt/rh/gcc-toolset-11/enable && bash -x /io/build-core.sh '$GITHUB_REPOSITORY' '$GITHUB_SHA' '$BUILD_CORES' '$GITHUB_RUN_NUMBER'"
 | 
			
		||||
  docker stop $CONTAINER_NAME
 | 
			
		||||
else
 | 
			
		||||
  echo "No static container, build on temp container"
 | 
			
		||||
  rm -rf release-build;
 | 
			
		||||
  mkdir -p release-build;
 | 
			
		||||
 | 
			
		||||
  docker volume create $CACHE_VOLUME_NAME
 | 
			
		||||
 | 
			
		||||
  # Create inline Dockerfile with environment setup for build-full.sh
 | 
			
		||||
  DOCKERFILE_CONTENT=$(cat <<'DOCKERFILE_EOF'
 | 
			
		||||
FROM ghcr.io/phusion/holy-build-box:4.0.1-amd64
 | 
			
		||||
 | 
			
		||||
ARG BUILD_CORES=8
 | 
			
		||||
 | 
			
		||||
# Enable repositories and install dependencies
 | 
			
		||||
RUN /hbb_exe/activate-exec bash -c "dnf install -y epel-release && \
 | 
			
		||||
    dnf config-manager --set-enabled powertools || dnf config-manager --set-enabled crb && \
 | 
			
		||||
    dnf install -y --enablerepo=devel \
 | 
			
		||||
        wget git \
 | 
			
		||||
        gcc-toolset-11-gcc-c++ gcc-toolset-11-binutils gcc-toolset-11-libatomic-devel \
 | 
			
		||||
        lz4 lz4-devel \
 | 
			
		||||
        ncurses-static ncurses-devel \
 | 
			
		||||
        snappy snappy-devel \
 | 
			
		||||
        zlib zlib-devel zlib-static \
 | 
			
		||||
        libasan \
 | 
			
		||||
        python3 python3-pip \
 | 
			
		||||
        ccache \
 | 
			
		||||
        ninja-build \
 | 
			
		||||
        patch \
 | 
			
		||||
        glibc-devel glibc-static \
 | 
			
		||||
        libxml2-devel \
 | 
			
		||||
        autoconf \
 | 
			
		||||
        automake \
 | 
			
		||||
        texinfo \
 | 
			
		||||
        libtool \
 | 
			
		||||
        llvm14-static llvm14-devel && \
 | 
			
		||||
    dnf clean all"
 | 
			
		||||
 | 
			
		||||
# Install Conan and CMake
 | 
			
		||||
RUN /hbb_exe/activate-exec pip3 install "conan==1.66.0" && \
 | 
			
		||||
    /hbb_exe/activate-exec wget -q https://github.com/Kitware/CMake/releases/download/v3.23.1/cmake-3.23.1-linux-x86_64.tar.gz -O cmake.tar.gz && \
 | 
			
		||||
    mkdir cmake && \
 | 
			
		||||
    tar -xzf cmake.tar.gz --strip-components=1 -C cmake && \
 | 
			
		||||
    rm cmake.tar.gz
 | 
			
		||||
 | 
			
		||||
# Install Boost 1.86.0
 | 
			
		||||
RUN /hbb_exe/activate-exec bash -c "cd /tmp && \
 | 
			
		||||
    wget -q https://archives.boost.io/release/1.86.0/source/boost_1_86_0.tar.gz -O boost.tar.gz && \
 | 
			
		||||
    mkdir boost && \
 | 
			
		||||
    tar -xzf boost.tar.gz --strip-components=1 -C boost && \
 | 
			
		||||
    cd boost && \
 | 
			
		||||
    ./bootstrap.sh && \
 | 
			
		||||
    ./b2 link=static -j${BUILD_CORES} && \
 | 
			
		||||
    ./b2 install && \
 | 
			
		||||
    cd /tmp && \
 | 
			
		||||
    rm -rf boost boost.tar.gz"
 | 
			
		||||
 | 
			
		||||
ENV BOOST_ROOT=/usr/local/src/boost_1_86_0
 | 
			
		||||
ENV Boost_LIBRARY_DIRS=/usr/local/lib
 | 
			
		||||
ENV BOOST_INCLUDEDIR=/usr/local/src/boost_1_86_0
 | 
			
		||||
 | 
			
		||||
ENV CMAKE_EXE_LINKER_FLAGS="-static-libstdc++"
 | 
			
		||||
 | 
			
		||||
ENV LLVM_DIR=/usr/lib64/llvm14/lib/cmake/llvm
 | 
			
		||||
ENV WasmEdge_LIB=/usr/local/lib64/libwasmedge.a
 | 
			
		||||
 | 
			
		||||
ENV CC='ccache gcc'
 | 
			
		||||
ENV CXX='ccache g++'
 | 
			
		||||
 | 
			
		||||
# Install LLD
 | 
			
		||||
RUN /hbb_exe/activate-exec bash -c "source /opt/rh/gcc-toolset-11/enable && \
 | 
			
		||||
    cd /tmp && \
 | 
			
		||||
    wget -q https://github.com/llvm/llvm-project/releases/download/llvmorg-14.0.3/lld-14.0.3.src.tar.xz && \
 | 
			
		||||
    wget -q https://github.com/llvm/llvm-project/releases/download/llvmorg-14.0.3/libunwind-14.0.3.src.tar.xz && \
 | 
			
		||||
    tar -xf lld-14.0.3.src.tar.xz && \
 | 
			
		||||
    tar -xf libunwind-14.0.3.src.tar.xz && \
 | 
			
		||||
    cp -r libunwind-14.0.3.src/include libunwind-14.0.3.src/src lld-14.0.3.src/ && \
 | 
			
		||||
    cd lld-14.0.3.src && \
 | 
			
		||||
    mkdir -p build && cd build && \
 | 
			
		||||
    cmake .. \
 | 
			
		||||
        -DLLVM_LIBRARY_DIR=/usr/lib64/llvm14/lib/ \
 | 
			
		||||
        -DCMAKE_INSTALL_PREFIX=/usr/lib64/llvm14/ \
 | 
			
		||||
        -DCMAKE_BUILD_TYPE=Release \
 | 
			
		||||
        -DCMAKE_EXE_LINKER_FLAGS=\"\$CMAKE_EXE_LINKER_FLAGS\" && \
 | 
			
		||||
    make -j${BUILD_CORES} install && \
 | 
			
		||||
    ln -s /usr/lib64/llvm14/lib/include/lld /usr/include/lld && \
 | 
			
		||||
    cp /usr/lib64/llvm14/lib/liblld*.a /usr/local/lib/ && \
 | 
			
		||||
    cd /tmp && rm -rf lld-* libunwind-*"
 | 
			
		||||
 | 
			
		||||
# Build and install WasmEdge (static version)
 | 
			
		||||
# Note: Conan only provides WasmEdge with shared library linking.
 | 
			
		||||
# For a fully static build, we need to manually install:
 | 
			
		||||
# * Boost: Static C++ libraries for filesystem and system operations (built from source above)
 | 
			
		||||
# * LLVM: Static LLVM libraries for WebAssembly compilation (installed via llvm14-static package)
 | 
			
		||||
# * LLD: Static linker to produce the final static binary (built from source above)
 | 
			
		||||
# These were installed above to enable WASMEDGE_LINK_LLVM_STATIC=ON
 | 
			
		||||
RUN cd /tmp && \
 | 
			
		||||
    ( wget -nc -q https://github.com/WasmEdge/WasmEdge/archive/refs/tags/0.11.2.zip; unzip -o 0.11.2.zip; ) && \
 | 
			
		||||
    cd WasmEdge-0.11.2 && \
 | 
			
		||||
    ( mkdir -p build; echo "" ) && \
 | 
			
		||||
    cd build && \
 | 
			
		||||
    /hbb_exe/activate-exec bash -c "source /opt/rh/gcc-toolset-11/enable && \
 | 
			
		||||
    ln -sf /opt/rh/gcc-toolset-11/root/usr/bin/ar /usr/bin/ar && \
 | 
			
		||||
    cmake .. \
 | 
			
		||||
        -DCMAKE_BUILD_TYPE=Release \
 | 
			
		||||
        -DCMAKE_INSTALL_PREFIX=/usr/local \
 | 
			
		||||
        -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
 | 
			
		||||
        -DWASMEDGE_BUILD_SHARED_LIB=OFF \
 | 
			
		||||
        -DWASMEDGE_BUILD_STATIC_LIB=ON \
 | 
			
		||||
        -DWASMEDGE_BUILD_AOT_RUNTIME=ON \
 | 
			
		||||
        -DWASMEDGE_FORCE_DISABLE_LTO=ON \
 | 
			
		||||
        -DWASMEDGE_LINK_LLVM_STATIC=ON \
 | 
			
		||||
        -DWASMEDGE_BUILD_PLUGINS=OFF \
 | 
			
		||||
        -DWASMEDGE_LINK_TOOLS_STATIC=ON \
 | 
			
		||||
        -DBoost_NO_BOOST_CMAKE=ON \
 | 
			
		||||
        -DCMAKE_EXE_LINKER_FLAGS=\"\$CMAKE_EXE_LINKER_FLAGS\" \
 | 
			
		||||
        && \
 | 
			
		||||
    make -j${BUILD_CORES} install" && \
 | 
			
		||||
    cp -r include/api/wasmedge /usr/include/ && \
 | 
			
		||||
    cd /tmp && rm -rf WasmEdge* 0.11.2.zip
 | 
			
		||||
 | 
			
		||||
# Set environment variables
 | 
			
		||||
ENV PATH=/usr/local/bin:$PATH
 | 
			
		||||
 | 
			
		||||
# Configure ccache and Conan
 | 
			
		||||
RUN /hbb_exe/activate-exec bash -c "ccache -M 10G && \
 | 
			
		||||
    ccache -o cache_dir=/cache/ccache && \
 | 
			
		||||
    ccache -o compiler_check=content && \
 | 
			
		||||
    conan config set storage.path=/cache/conan && \
 | 
			
		||||
    (conan profile new default --detect || true) && \
 | 
			
		||||
    conan profile update settings.compiler.libcxx=libstdc++11 default && \
 | 
			
		||||
    conan profile update settings.compiler.cppstd=20 default"
 | 
			
		||||
 | 
			
		||||
DOCKERFILE_EOF
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
  # Build custom Docker image
 | 
			
		||||
  IMAGE_NAME="xahaud-builder:latest"
 | 
			
		||||
  echo "Building custom Docker image with dependencies..."
 | 
			
		||||
  echo "$DOCKERFILE_CONTENT" | docker build --build-arg BUILD_CORES="$BUILD_CORES" -t "$IMAGE_NAME" - || exit 1
 | 
			
		||||
 | 
			
		||||
  if [[ "$GITHUB_REPOSITORY" == "" ]]; then
 | 
			
		||||
    # Non GH, local building
 | 
			
		||||
    echo "Non-GH runner, local building, temp container"
 | 
			
		||||
    docker run -i --user 0:$(id -g) --rm -v /data/builds:/data/builds -v `pwd`:/io --network host ghcr.io/foobarwidget/holy-build-box-x64 /hbb_exe/activate-exec bash -x /io/build-full.sh "$GITHUB_REPOSITORY" "$GITHUB_SHA" "$BUILD_CORES" "$GITHUB_RUN_NUMBER"
 | 
			
		||||
    docker run -i --user 0:$(id -g) --rm -v /data/builds:/data/builds -v `pwd`:/io -v "$CACHE_VOLUME_NAME":/cache --network host "$IMAGE_NAME" /hbb_exe/activate-exec bash -c "source /opt/rh/gcc-toolset-11/enable && bash -x /io/build-full.sh '$GITHUB_REPOSITORY' '$GITHUB_SHA' '$BUILD_CORES' '$GITHUB_RUN_NUMBER'"
 | 
			
		||||
  else
 | 
			
		||||
    # GH Action, runner
 | 
			
		||||
    echo "GH Action, runner, clean & re-create create persistent container"
 | 
			
		||||
    docker rm -f $CONTAINER_NAME
 | 
			
		||||
    echo "echo 'Stopping container: $CONTAINER_NAME'" >> "$JOB_CLEANUP_SCRIPT"
 | 
			
		||||
    echo "docker stop --time=15 \"$CONTAINER_NAME\" || echo 'Failed to stop container or container not running'" >> "$JOB_CLEANUP_SCRIPT"
 | 
			
		||||
    docker run -di --user 0:$(id -g) --name $CONTAINER_NAME -v /data/builds:/data/builds -v `pwd`:/io --network host ghcr.io/foobarwidget/holy-build-box-x64 /hbb_exe/activate-exec bash
 | 
			
		||||
    docker exec -i $CONTAINER_NAME /hbb_exe/activate-exec bash -x /io/build-full.sh "$GITHUB_REPOSITORY" "$GITHUB_SHA" "$BUILD_CORES" "$GITHUB_RUN_NUMBER"
 | 
			
		||||
    docker run -di --user 0:$(id -g) --name $CONTAINER_NAME -v /data/builds:/data/builds -v `pwd`:/io -v "$CACHE_VOLUME_NAME":/cache --network host "$IMAGE_NAME" /hbb_exe/activate-exec bash
 | 
			
		||||
    docker exec -i $CONTAINER_NAME /hbb_exe/activate-exec bash -c "source /opt/rh/gcc-toolset-11/enable && bash -x /io/build-full.sh '$GITHUB_REPOSITORY' '$GITHUB_SHA' '$BUILD_CORES' '$GITHUB_RUN_NUMBER'"
 | 
			
		||||
    docker stop $CONTAINER_NAME
 | 
			
		||||
  fi
 | 
			
		||||
fi
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										820
									
								
								src/quickjs/buffer-utils.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										820
									
								
								src/quickjs/buffer-utils.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,820 @@
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "char-utils.h"
 | 
			
		||||
#include "buffer-utils.h"
 | 
			
		||||
#include "utils.h"
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#elif defined(HAVE_TERMIOS_H)
 | 
			
		||||
#include <termios.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include "debug.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \addtogroup buffer-utils
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
size_t
 | 
			
		||||
ansi_length(const char* str, size_t len) {
 | 
			
		||||
  size_t i, n = 0, p;
 | 
			
		||||
  for(i = 0; i < len;) {
 | 
			
		||||
    if(str[i] == 0x1b && (p = ansi_skip(&str[i], len - i)) > 0) {
 | 
			
		||||
      i += p;
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
    n++;
 | 
			
		||||
    i++;
 | 
			
		||||
  }
 | 
			
		||||
  return n;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
ansi_skip(const char* str, size_t len) {
 | 
			
		||||
  size_t pos = 0;
 | 
			
		||||
  if(str[pos] == 0x1b) {
 | 
			
		||||
    if(++pos < len && str[pos] == '[') {
 | 
			
		||||
      while(++pos < len)
 | 
			
		||||
        if(is_alphanumeric_char(str[pos]))
 | 
			
		||||
          break;
 | 
			
		||||
      if(++pos < len && str[pos] == '~')
 | 
			
		||||
        ++pos;
 | 
			
		||||
      return pos;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
ansi_truncate(const char* str, size_t len, size_t limit) {
 | 
			
		||||
  size_t i, n = 0, p;
 | 
			
		||||
  for(i = 0; i < len;) {
 | 
			
		||||
    if((p = ansi_skip(&str[i], len - i)) > 0) {
 | 
			
		||||
      i += p;
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
    n += is_escape_char(str[i]) ? 2 : 1;
 | 
			
		||||
 | 
			
		||||
    i++;
 | 
			
		||||
    if(n > limit)
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
  return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int64_t
 | 
			
		||||
array_search(void* a, size_t m, size_t elsz, void* needle) {
 | 
			
		||||
  char* ptr = a;
 | 
			
		||||
  int64_t n, ret;
 | 
			
		||||
  n = m / elsz;
 | 
			
		||||
  for(ret = 0; ret < n; ret++) {
 | 
			
		||||
    if(!memcmp(ptr, needle, elsz))
 | 
			
		||||
      return ret;
 | 
			
		||||
 | 
			
		||||
    ptr += elsz;
 | 
			
		||||
  }
 | 
			
		||||
  return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char*
 | 
			
		||||
str_escape(const char* s) {
 | 
			
		||||
  DynBuf dbuf;
 | 
			
		||||
  dbuf_init2(&dbuf, 0, 0);
 | 
			
		||||
  dbuf_put_escaped(&dbuf, s, strlen(s));
 | 
			
		||||
  dbuf_0(&dbuf);
 | 
			
		||||
  return (char*)dbuf.buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char*
 | 
			
		||||
byte_escape(const void* s, size_t n) {
 | 
			
		||||
  DynBuf dbuf;
 | 
			
		||||
  dbuf_init2(&dbuf, 0, 0);
 | 
			
		||||
  dbuf_put_escaped(&dbuf, s, n);
 | 
			
		||||
  dbuf_0(&dbuf);
 | 
			
		||||
  return (char*)dbuf.buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
byte_findb(const void* haystack, size_t hlen, const void* what, size_t wlen) {
 | 
			
		||||
  size_t i, last;
 | 
			
		||||
  const char* s = (const char*)haystack;
 | 
			
		||||
  if(hlen < wlen)
 | 
			
		||||
    return hlen;
 | 
			
		||||
  last = hlen - wlen;
 | 
			
		||||
  for(i = 0; i <= last; i++) {
 | 
			
		||||
    if(byte_equal(s, wlen, what))
 | 
			
		||||
      return i;
 | 
			
		||||
    s++;
 | 
			
		||||
  }
 | 
			
		||||
  return hlen;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
byte_finds(const void* haystack, size_t hlen, const char* what) {
 | 
			
		||||
  return byte_findb(haystack, hlen, what, strlen(what));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
byte_equal(const void* s, size_t n, const void* t) {
 | 
			
		||||
  return memcmp(s, t, n) == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
byte_copy(void* out, size_t len, const void* in) {
 | 
			
		||||
  char* s = (char*)out;
 | 
			
		||||
  const char* t = (const char*)in;
 | 
			
		||||
  size_t i;
 | 
			
		||||
  for(i = 0; i < len; ++i)
 | 
			
		||||
    s[i] = t[i];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
byte_copyr(void* out, size_t len, const void* in) {
 | 
			
		||||
  char* s = (char*)out + len;
 | 
			
		||||
  const char* t = (const char*)in;
 | 
			
		||||
  const char* u = t + len;
 | 
			
		||||
 | 
			
		||||
  for(;;) {
 | 
			
		||||
    if(t >= u)
 | 
			
		||||
      break;
 | 
			
		||||
    --u;
 | 
			
		||||
    --s;
 | 
			
		||||
    *s = *u;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
byte_rchrs(const char* in, size_t len, const char needles[], size_t nn) {
 | 
			
		||||
  const char *s = in, *end = in + len, *found = 0;
 | 
			
		||||
  size_t i;
 | 
			
		||||
  for(; s < end; s++) {
 | 
			
		||||
    for(i = 0; i < nn; ++i) {
 | 
			
		||||
      if(*s == needles[i])
 | 
			
		||||
        found = s;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return (size_t)((found ? found : s) - in);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char*
 | 
			
		||||
dbuf_at_n(const DynBuf* db, size_t i, size_t* n, char sep) {
 | 
			
		||||
  size_t p, l = 0;
 | 
			
		||||
  for(p = 0; p < db->size; ++p) {
 | 
			
		||||
    if(l == i) {
 | 
			
		||||
      *n = byte_chr((const char*)&db->buf[p], db->size - p, sep);
 | 
			
		||||
      return (char*)&db->buf[p];
 | 
			
		||||
    }
 | 
			
		||||
    if(db->buf[p] == sep)
 | 
			
		||||
      ++l;
 | 
			
		||||
  }
 | 
			
		||||
  *n = 0;
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char*
 | 
			
		||||
dbuf_last_line(DynBuf* db, size_t* len) {
 | 
			
		||||
  size_t i;
 | 
			
		||||
 | 
			
		||||
  if((i = byte_rchr(db->buf, db->size, '\n')) < db->size)
 | 
			
		||||
    i++;
 | 
			
		||||
  else
 | 
			
		||||
    i = 0;
 | 
			
		||||
 | 
			
		||||
  if(len)
 | 
			
		||||
    *len = db->size - i;
 | 
			
		||||
 | 
			
		||||
  return (const char*)&db->buf[i];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
dbuf_prepend(DynBuf* s, const uint8_t* data, size_t len) {
 | 
			
		||||
  int ret;
 | 
			
		||||
  if(!(ret = dbuf_reserve_start(s, len)))
 | 
			
		||||
    memcpy(s->buf, data, len);
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
dbuf_put_colorstr(DynBuf* db, const char* str, const char* color, int with_color) {
 | 
			
		||||
  if(with_color)
 | 
			
		||||
    dbuf_putstr(db, color);
 | 
			
		||||
 | 
			
		||||
  dbuf_putstr(db, str);
 | 
			
		||||
  if(with_color)
 | 
			
		||||
    dbuf_putstr(db, COLOR_NONE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
dbuf_put_escaped_pred(DynBuf* db, const char* str, size_t len, int (*pred)(int)) {
 | 
			
		||||
  size_t i = 0, j;
 | 
			
		||||
  char c;
 | 
			
		||||
 | 
			
		||||
  while(i < len) {
 | 
			
		||||
    if((j = predicate_find(&str[i], len - i, pred))) {
 | 
			
		||||
      dbuf_append(db, (const uint8_t*)&str[i], j);
 | 
			
		||||
      i += j;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(i == len)
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    dbuf_putc(db, '\\');
 | 
			
		||||
 | 
			
		||||
    if(str[i] == 0x1b) {
 | 
			
		||||
      dbuf_append(db, (const uint8_t*)"x1b", 3);
 | 
			
		||||
    } else {
 | 
			
		||||
      int r = pred(str[i]);
 | 
			
		||||
 | 
			
		||||
      dbuf_putc(db, (r > 1 && r <= 127) ? r : (c = escape_char_letter(str[i])) ? c : str[i]);
 | 
			
		||||
 | 
			
		||||
      if(r == 'u' || r == 'x')
 | 
			
		||||
        dbuf_printf(db, r == 'u' ? "%04x" : "%02x", str[i]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    i++;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const uint8_t escape_url_tab[256] = {
 | 
			
		||||
    '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%',  '%', '%', '%',
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0x5c, 0,   0,   0,
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   '%',
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,
 | 
			
		||||
    '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%', '%',  '%', '%', '%',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const uint8_t escape_noquote_tab[256] = {
 | 
			
		||||
    'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 0x62, 0x74, 0x6e, 0x76, 0x66, 0x72, 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
 | 
			
		||||
    'x', 'x', 'x', 'x', 0,   0,   0,   0,   0,    0,    0,    0,    0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,   0,    0,    0,    0,    0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,   0x5c, 0,    0,    0,    0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,   0,    0,    0,    0,    0,    0,    0,   'x', 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,   0,    0,    0,    0,    0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,   0,    0,    0,    0,    0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   'u', 'u', 'u', 'u', 'u',
 | 
			
		||||
    'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u',  'u',  'u',  'u',  'u',  'u',  'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const uint8_t escape_singlequote_tab[256] = {
 | 
			
		||||
    'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 0x62, 0x74, 0x6e, 0x76, 0x66, 0x72, 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
 | 
			
		||||
    'x', 'x', 'x', 'x', 0,   0,   0,   0,   0,    0,    0,    0x27, 0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,   0,    0,    0,    0,    0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,   0x5c, 0,    0,    0,    0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,   0,    0,    0,    0,    0,    0,    0,   'x', 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,   0,    0,    0,    0,    0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,   0,    0,    0,    0,    0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   'u', 'u', 'u', 'u', 'u',
 | 
			
		||||
    'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u',  'u',  'u',  'u',  'u',  'u',  'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const uint8_t escape_doublequote_tab[256] = {
 | 
			
		||||
    'x', 'x', 'x', 'x', 'x', 'x', 'x',  'x', 0x62, 0x74, 0x6e, 0x76, 0x66, 0x72, 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
 | 
			
		||||
 | 
			
		||||
    'x', 'x', 'x', 'x', 0,   0,   0x22, 0,   0,    0,    0,    0,    0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,    0,   0,    0,    0,    0,    0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,    0,   0x5c, 0,    0,    0,    0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,    0,   0,    0,    0,    0,    0,    0,    0,   'x', 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,    0,   0,    0,    0,    0,    0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,    0,   0,    0,    0,    0,    0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   'u', 'u', 'u', 'u', 'u',
 | 
			
		||||
    'u', 'u', 'u', 'u', 'u', 'u', 'u',  'u', 'u',  'u',  'u',  'u',  'u',  'u',  'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const uint8_t escape_backquote_tab[256] = {
 | 
			
		||||
    'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 0x62, 0x74, 0,   0x76, 0x66, 0,   'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
 | 
			
		||||
    'x', 'x', 'x', 'x', 0,   0,   0,   0,   0x24, 0,    0,   0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,   0,    0,    0,   0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,   0x5c, 0,    0,   0,    0x60, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,   0,    0,    0,   0,    0,    0,   0,   'x', 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,   0,    0,    0,   0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
    0,   0,   0,   0,   0,   0,   0,   0,   0,    0,    0,   0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   'u', 'u', 'u', 'u', 'u',
 | 
			
		||||
    'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u',  'u',  'u', 'u',  'u',  'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
dbuf_put_escaped_table(DynBuf* db, const char* str, size_t len, const uint8_t table[256]) {
 | 
			
		||||
  size_t i = 0, clen;
 | 
			
		||||
  int32_t c;
 | 
			
		||||
  const uint8_t *pos, *end, *next;
 | 
			
		||||
 | 
			
		||||
  for(pos = (const uint8_t*)str, end = pos + len; pos < end; pos = next) {
 | 
			
		||||
    uint8_t r, ch;
 | 
			
		||||
 | 
			
		||||
    if((c = unicode_from_utf8(pos, end - pos, &next)) < 0)
 | 
			
		||||
      break;
 | 
			
		||||
    clen = next - pos;
 | 
			
		||||
    ch = c;
 | 
			
		||||
    r = (clen >= 2 || c > 0xff) ? 'u' : table[c];
 | 
			
		||||
 | 
			
		||||
    if(r == 'u' && clen > 1 && (c & 0xffffff00) == 0) {
 | 
			
		||||
      r = 'x';
 | 
			
		||||
      // ch = c >> 8;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(r == '%') {
 | 
			
		||||
      static const char hexdigits[] = "0123456789ABCDEF";
 | 
			
		||||
 | 
			
		||||
      dbuf_putc(db, '%');
 | 
			
		||||
      dbuf_putc(db, hexdigits[c >> 4]);
 | 
			
		||||
      dbuf_putc(db, hexdigits[c & 0xf]);
 | 
			
		||||
    } else if(c == 0x1b) {
 | 
			
		||||
      dbuf_putstr(db, "\\x1b");
 | 
			
		||||
    } else if(r == 'u') {
 | 
			
		||||
      dbuf_printf(db, c > 0xffff ? "\\u{%X}" : "\\u%04x", c);
 | 
			
		||||
    } else if(r == 'x') {
 | 
			
		||||
      dbuf_printf(db, "\\x%02x", ch);
 | 
			
		||||
    } else if(r) {
 | 
			
		||||
      dbuf_putc(db, '\\');
 | 
			
		||||
      dbuf_putc(db, (r > 1 && r <= 127) ? r : (c = escape_char_letter(ch)) ? c : ch);
 | 
			
		||||
    } else {
 | 
			
		||||
      dbuf_put(db, pos, next - pos);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    i++;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
dbuf_put_unescaped_pred(DynBuf* db, const char* str, size_t len, int (*pred)(const char*, size_t*)) {
 | 
			
		||||
  size_t i = 0, j;
 | 
			
		||||
  // char c;
 | 
			
		||||
 | 
			
		||||
  while(i < len) {
 | 
			
		||||
    int r = 0;
 | 
			
		||||
    if((j = byte_chr(&str[i], len - i, '\\'))) {
 | 
			
		||||
      dbuf_append(db, (const uint8_t*)&str[i], j);
 | 
			
		||||
      i += j;
 | 
			
		||||
    }
 | 
			
		||||
    if(i == len)
 | 
			
		||||
      break;
 | 
			
		||||
    size_t n = 1;
 | 
			
		||||
 | 
			
		||||
    if(pred) {
 | 
			
		||||
      r = pred(&str[i + 1], &n);
 | 
			
		||||
 | 
			
		||||
      if(!r && n == 1)
 | 
			
		||||
        dbuf_putc(db, '\\');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(r >= 0)
 | 
			
		||||
      dbuf_putc(db, /*n > 1 ||*/ r ? /*(r > 1 && r < 256) ?*/ r : str[i]);
 | 
			
		||||
    i += n;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
hexdigit(char c) {
 | 
			
		||||
  if(c >= '0' && c <= '9')
 | 
			
		||||
    return c - '0';
 | 
			
		||||
 | 
			
		||||
  if(c >= 'a' && c <= 'f')
 | 
			
		||||
    c -= 32;
 | 
			
		||||
 | 
			
		||||
  if(c >= 'A' && c <= 'F')
 | 
			
		||||
    return c - 'A' + 10;
 | 
			
		||||
 | 
			
		||||
  return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
dbuf_put_unescaped_table(DynBuf* db, const char* str, size_t len, const uint8_t table[256]) {
 | 
			
		||||
  size_t i = 0, j;
 | 
			
		||||
  char escape_char = table == escape_url_tab ? '%' : '\\';
 | 
			
		||||
 | 
			
		||||
  while(i < len) {
 | 
			
		||||
    if((j = byte_chr(&str[i], len - i, escape_char))) {
 | 
			
		||||
      dbuf_append(db, (const uint8_t*)&str[i], j);
 | 
			
		||||
      i += j;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(i == len)
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    if(escape_char == '%') {
 | 
			
		||||
      int hi = hexdigit(str[i + 1]), lo = hexdigit(str[i + 2]);
 | 
			
		||||
      uint8_t c = (hi << 4) | (lo & 0xf);
 | 
			
		||||
      dbuf_putc(db, c);
 | 
			
		||||
 | 
			
		||||
      i += 2;
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
      ++i;
 | 
			
		||||
 | 
			
		||||
      uint8_t c;
 | 
			
		||||
 | 
			
		||||
      switch(str[i]) {
 | 
			
		||||
        case 'b': c = '\b'; break;
 | 
			
		||||
        case 't': c = '\t'; break;
 | 
			
		||||
        case 'n': c = '\n'; break;
 | 
			
		||||
        case 'v': c = '\v'; break;
 | 
			
		||||
        case 'f': c = '\f'; break;
 | 
			
		||||
        case 'r': c = '\r'; break;
 | 
			
		||||
        default: c = str[i]; break;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      uint8_t r = table[c];
 | 
			
		||||
 | 
			
		||||
      if(!(r && r != 'x' && r != 'u')) {
 | 
			
		||||
        dbuf_putc(db, '\\');
 | 
			
		||||
        dbuf_putc(db, c);
 | 
			
		||||
      } else {
 | 
			
		||||
        dbuf_putc(db, str[i] == r ? c : r);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ++i;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
dbuf_put_escaped(DynBuf* db, const char* str, size_t len) {
 | 
			
		||||
  return dbuf_put_escaped_table(db, str, len, escape_noquote_tab);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
dbuf_put_value(DynBuf* db, JSContext* ctx, JSValueConst value) {
 | 
			
		||||
  const char* str;
 | 
			
		||||
  size_t len;
 | 
			
		||||
  str = JS_ToCStringLen(ctx, &len, value);
 | 
			
		||||
  dbuf_append(db, str, len);
 | 
			
		||||
  JS_FreeCString(ctx, str);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
dbuf_put_uint32(DynBuf* db, uint32_t num) {
 | 
			
		||||
  char buf[FMT_ULONG];
 | 
			
		||||
  dbuf_put(db, (const uint8_t*)buf, fmt_ulong(buf, num));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
dbuf_put_atom(DynBuf* db, JSContext* ctx, JSAtom atom) {
 | 
			
		||||
  const char* str;
 | 
			
		||||
  str = JS_AtomToCString(ctx, atom);
 | 
			
		||||
  dbuf_putstr(db, str);
 | 
			
		||||
  JS_FreeCString(ctx, str);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
dbuf_reserve_start(DynBuf* s, size_t len) {
 | 
			
		||||
  if(unlikely((s->size + len) > s->allocated_size)) {
 | 
			
		||||
    if(dbuf_realloc(s, s->size + len))
 | 
			
		||||
      return -1;
 | 
			
		||||
  }
 | 
			
		||||
  if(s->size > 0)
 | 
			
		||||
    memcpy(s->buf + len, s->buf, s->size);
 | 
			
		||||
 | 
			
		||||
  s->size += len;
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t*
 | 
			
		||||
dbuf_reserve(DynBuf* s, size_t len) {
 | 
			
		||||
  if(unlikely((s->size + len) > s->allocated_size))
 | 
			
		||||
    if(dbuf_realloc(s, s->size + len))
 | 
			
		||||
      return 0;
 | 
			
		||||
 | 
			
		||||
  return &s->buf[s->size];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
dbuf_token_pop(DynBuf* db, char delim) {
 | 
			
		||||
  size_t n, p, len;
 | 
			
		||||
  len = db->size;
 | 
			
		||||
  for(n = db->size; n > 0;) {
 | 
			
		||||
    if((p = byte_rchr(db->buf, n, delim)) == n) {
 | 
			
		||||
      db->size = 0;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    if(p > 0 && db->buf[p - 1] == '\\') {
 | 
			
		||||
      n = p - 1;
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
    db->size = p;
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
  return len - db->size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
dbuf_token_push(DynBuf* db, const char* str, size_t len, char delim) {
 | 
			
		||||
  size_t pos;
 | 
			
		||||
  if(db->size)
 | 
			
		||||
    dbuf_putc(db, delim);
 | 
			
		||||
 | 
			
		||||
  pos = db->size;
 | 
			
		||||
  dbuf_put_escaped_pred(db, str, len, is_dot_char);
 | 
			
		||||
  return db->size - pos;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSValue
 | 
			
		||||
dbuf_tostring_free(DynBuf* s, JSContext* ctx) {
 | 
			
		||||
  JSValue r;
 | 
			
		||||
  r = JS_NewStringLen(ctx, s->buf ? (const char*)s->buf : "", s->buf ? s->size : 0);
 | 
			
		||||
  dbuf_free(s);
 | 
			
		||||
  return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ssize_t
 | 
			
		||||
dbuf_load(DynBuf* s, const char* filename) {
 | 
			
		||||
  FILE* fp;
 | 
			
		||||
  size_t nbytes = 0;
 | 
			
		||||
  if((fp = fopen(filename, "rb"))) {
 | 
			
		||||
    char buf[4096];
 | 
			
		||||
    size_t r;
 | 
			
		||||
    while(!feof(fp)) {
 | 
			
		||||
      if((r = fread(buf, 1, sizeof(buf), fp)) == 0) {
 | 
			
		||||
        fclose(fp);
 | 
			
		||||
        return -1;
 | 
			
		||||
      }
 | 
			
		||||
      dbuf_put(s, (uint8_t const*)buf, r);
 | 
			
		||||
      nbytes += r;
 | 
			
		||||
    }
 | 
			
		||||
    fclose(fp);
 | 
			
		||||
  }
 | 
			
		||||
  return nbytes;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
dbuf_vprintf(DynBuf* s, const char* fmt, va_list ap) {
 | 
			
		||||
 | 
			
		||||
  s->size += vsnprintf((char*)(s->buf + s->size), s->allocated_size - s->size, fmt, ap);
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
InputBuffer
 | 
			
		||||
js_input_buffer(JSContext* ctx, JSValueConst value) {
 | 
			
		||||
  InputBuffer ret = {{{0, 0}}, 0, &input_buffer_free_default, JS_UNDEFINED, {0, INT64_MAX}};
 | 
			
		||||
 | 
			
		||||
  if(js_is_typedarray(ctx, value)) {
 | 
			
		||||
    ret.value = offset_typedarray(&ret.range, value, ctx);
 | 
			
		||||
  } else if(js_is_arraybuffer(ctx, value) || js_is_sharedarraybuffer(ctx, value)) {
 | 
			
		||||
    ret.value = JS_DupValue(ctx, value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(js_is_arraybuffer(ctx, ret.value) || js_is_sharedarraybuffer(ctx, ret.value)) {
 | 
			
		||||
    block_arraybuffer(&ret.block, ret.value, ctx);
 | 
			
		||||
  } else {
 | 
			
		||||
    JS_ThrowTypeError(ctx, "Invalid type (%s) for input buffer", js_value_typestr(ctx, ret.value));
 | 
			
		||||
    JS_FreeValue(ctx, ret.value);
 | 
			
		||||
    ret.value = JS_EXCEPTION;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#undef free
 | 
			
		||||
 | 
			
		||||
InputBuffer
 | 
			
		||||
js_input_chars(JSContext* ctx, JSValueConst value) {
 | 
			
		||||
  InputBuffer ret = {{{0, 0}}, 0, &input_buffer_free_default, JS_UNDEFINED, OFFSET_INIT()};
 | 
			
		||||
 | 
			
		||||
  if(JS_IsString(value)) {
 | 
			
		||||
    ret.data = (uint8_t*)JS_ToCStringLen(ctx, &ret.size, value);
 | 
			
		||||
    ret.value = JS_DupValue(ctx, value);
 | 
			
		||||
    ret.free = &input_buffer_free_default;
 | 
			
		||||
  } else {
 | 
			
		||||
    ret = js_input_buffer(ctx, value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
InputBuffer
 | 
			
		||||
js_input_args(JSContext* ctx, int argc, JSValueConst argv[]) {
 | 
			
		||||
  InputBuffer input = js_input_chars(ctx, argv[0]);
 | 
			
		||||
 | 
			
		||||
  if(argc > 1)
 | 
			
		||||
    js_offset_length(ctx, input.size, argc - 1, argv + 1, &input.range);
 | 
			
		||||
 | 
			
		||||
  return input;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
InputBuffer
 | 
			
		||||
js_output_args(JSContext* ctx, int argc, JSValueConst argv[]) {
 | 
			
		||||
  InputBuffer output = js_input_buffer(ctx, argv[0]);
 | 
			
		||||
 | 
			
		||||
  if(argc > 1)
 | 
			
		||||
    js_offset_length(ctx, output.size, argc - 1, argv + 1, &output.range);
 | 
			
		||||
 | 
			
		||||
  return output;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BOOL
 | 
			
		||||
input_buffer_valid(const InputBuffer* in) {
 | 
			
		||||
  return !JS_IsException(in->value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
InputBuffer
 | 
			
		||||
input_buffer_clone(const InputBuffer* in, JSContext* ctx) {
 | 
			
		||||
  InputBuffer ret = js_input_buffer(ctx, in->value);
 | 
			
		||||
 | 
			
		||||
  ret.pos = in->pos;
 | 
			
		||||
  ret.size = in->size;
 | 
			
		||||
  ret.free = in->free;
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
input_buffer_dump(const InputBuffer* in, DynBuf* db) {
 | 
			
		||||
  dbuf_printf(db, "(InputBuffer){ .data = %p, .size = %lu, .pos = %lu, .free = %p }", in->data, (unsigned long)in->size, (unsigned long)in->pos, in->free);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
input_buffer_free(InputBuffer* in, JSContext* ctx) {
 | 
			
		||||
  if(in->data) {
 | 
			
		||||
    in->free(ctx, (const char*)in->data, in->value);
 | 
			
		||||
    in->data = 0;
 | 
			
		||||
    in->size = 0;
 | 
			
		||||
    in->pos = 0;
 | 
			
		||||
    in->value = JS_UNDEFINED;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const uint8_t*
 | 
			
		||||
input_buffer_peek(InputBuffer* in, size_t* lenp) {
 | 
			
		||||
  input_buffer_peekc(in, lenp);
 | 
			
		||||
  return input_buffer_data(in) + in->pos;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const uint8_t*
 | 
			
		||||
input_buffer_get(InputBuffer* in, size_t* lenp) {
 | 
			
		||||
  const uint8_t* ret = input_buffer_peek(in, lenp);
 | 
			
		||||
 | 
			
		||||
  in->pos += *lenp;
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char*
 | 
			
		||||
input_buffer_currentline(InputBuffer* in, size_t* len) {
 | 
			
		||||
  size_t i;
 | 
			
		||||
 | 
			
		||||
  if((i = byte_rchr(input_buffer_data(in), in->pos, '\n')) < in->pos)
 | 
			
		||||
    i++;
 | 
			
		||||
 | 
			
		||||
  if(len)
 | 
			
		||||
    *len = in->pos - i;
 | 
			
		||||
 | 
			
		||||
  return (const char*)&input_buffer_data(in)[i];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
input_buffer_column(InputBuffer* in, size_t* len) {
 | 
			
		||||
  size_t i;
 | 
			
		||||
 | 
			
		||||
  if((i = byte_rchr(input_buffer_data(in), in->pos, '\n')) < in->pos)
 | 
			
		||||
    i++;
 | 
			
		||||
 | 
			
		||||
  return in->pos - i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
js_offset_length(JSContext* ctx, int64_t size, int argc, JSValueConst argv[], OffsetLength* off_len_p) {
 | 
			
		||||
  int ret = 0;
 | 
			
		||||
  int64_t off = 0, len = size;
 | 
			
		||||
 | 
			
		||||
  if(argc >= 1 && JS_IsNumber(argv[0])) {
 | 
			
		||||
    if(!JS_ToInt64(ctx, &off, argv[0]))
 | 
			
		||||
      ret = 1;
 | 
			
		||||
 | 
			
		||||
    if(argc >= 2 && JS_IsNumber(argv[1]))
 | 
			
		||||
      if(!JS_ToInt64(ctx, &len, argv[1]))
 | 
			
		||||
        ret = 2;
 | 
			
		||||
 | 
			
		||||
    if(size && off != size)
 | 
			
		||||
      off = ((off % size) + size) % size;
 | 
			
		||||
 | 
			
		||||
    if(len >= 0)
 | 
			
		||||
      len = MIN_NUM(len, size - off);
 | 
			
		||||
    else
 | 
			
		||||
      len = size - off;
 | 
			
		||||
 | 
			
		||||
    if(off_len_p) {
 | 
			
		||||
      off_len_p->offset = off;
 | 
			
		||||
      off_len_p->length = len;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
js_index_range(JSContext* ctx, int64_t size, int argc, JSValueConst argv[], IndexRange* idx_rng_p) {
 | 
			
		||||
  int ret = 0;
 | 
			
		||||
  int64_t start = 0, end = size;
 | 
			
		||||
 | 
			
		||||
  if(argc >= 1 && JS_IsNumber(argv[0])) {
 | 
			
		||||
    if(!JS_ToInt64(ctx, &start, argv[0]))
 | 
			
		||||
      ret = 1;
 | 
			
		||||
 | 
			
		||||
    if(argc >= 2 && JS_IsNumber(argv[1]))
 | 
			
		||||
      if(!JS_ToInt64(ctx, &end, argv[1]))
 | 
			
		||||
        ret = 2;
 | 
			
		||||
 | 
			
		||||
    if(size > 0) {
 | 
			
		||||
      start = ((start % size) + size) % size;
 | 
			
		||||
      end = ((end % size) + size) % size;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(end > size)
 | 
			
		||||
      end = size;
 | 
			
		||||
 | 
			
		||||
    if(idx_rng_p) {
 | 
			
		||||
      idx_rng_p->start = start;
 | 
			
		||||
      idx_rng_p->end = end;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
screen_size(int size[2]) {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
  CONSOLE_SCREEN_BUFFER_INFO csbi;
 | 
			
		||||
 | 
			
		||||
  GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
 | 
			
		||||
  size[0] = csbi.srWindow.Right - csbi.srWindow.Left + 1;
 | 
			
		||||
  size[1] = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
 | 
			
		||||
  return 0;
 | 
			
		||||
 | 
			
		||||
#elif defined(HAVE_TERMIOS_H)
 | 
			
		||||
  {
 | 
			
		||||
    struct winsize w = {.ws_col = -1, .ws_row = -1};
 | 
			
		||||
 | 
			
		||||
    if(isatty(STDIN_FILENO))
 | 
			
		||||
      ioctl(STDIN_FILENO, TIOCGWINSZ, &w);
 | 
			
		||||
    else if(isatty(STDOUT_FILENO))
 | 
			
		||||
      ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
 | 
			
		||||
    else if(isatty(STDERR_FILENO))
 | 
			
		||||
      ioctl(STDERR_FILENO, TIOCGWINSZ, &w);
 | 
			
		||||
 | 
			
		||||
    size[0] = w.ws_col;
 | 
			
		||||
    size[1] = w.ws_row;
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
#else
 | 
			
		||||
  size[0] = 80;
 | 
			
		||||
  size[1] = 25;
 | 
			
		||||
  return 0;
 | 
			
		||||
#endif
 | 
			
		||||
  return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#undef js_realloc_rt
 | 
			
		||||
void
 | 
			
		||||
js_dbuf_allocator(JSContext* ctx, DynBuf* s) {
 | 
			
		||||
  dbuf_init2(s, JS_GetRuntime(ctx), (DynBufReallocFunc*)js_realloc_rt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int
 | 
			
		||||
input_buffer_peekc(InputBuffer* in, size_t* lenp) {
 | 
			
		||||
  const uint8_t *pos, *end, *next;
 | 
			
		||||
  int cp;
 | 
			
		||||
  pos = input_buffer_data(in) + in->pos;
 | 
			
		||||
  end = input_buffer_data(in) + input_buffer_length(in);
 | 
			
		||||
  cp = unicode_from_utf8(pos, end - pos, &next);
 | 
			
		||||
 | 
			
		||||
  *lenp = next - pos;
 | 
			
		||||
 | 
			
		||||
  return cp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int
 | 
			
		||||
input_buffer_putc(InputBuffer* in, unsigned int c, JSContext* ctx) {
 | 
			
		||||
  int len;
 | 
			
		||||
 | 
			
		||||
  if(in->pos + UTF8_CHAR_LEN_MAX > in->size)
 | 
			
		||||
    if(block_realloc(&in->block, in->pos + UTF8_CHAR_LEN_MAX, ctx))
 | 
			
		||||
      return -1;
 | 
			
		||||
 | 
			
		||||
  len = unicode_to_utf8(&in->data[in->pos], c);
 | 
			
		||||
 | 
			
		||||
  in->pos += len;
 | 
			
		||||
 | 
			
		||||
  return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
dbuf_bitflags(DynBuf* db, uint32_t bits, const char* const names[]) {
 | 
			
		||||
  size_t i, n = 0;
 | 
			
		||||
  for(i = 0; i < sizeof(bits) * 8; i++) {
 | 
			
		||||
    if(bits & (1 << i)) {
 | 
			
		||||
      size_t len = strlen(names[i]);
 | 
			
		||||
      if(n) {
 | 
			
		||||
        n++;
 | 
			
		||||
        dbuf_putstr(db, "|");
 | 
			
		||||
      }
 | 
			
		||||
      dbuf_append(db, names[i], len);
 | 
			
		||||
      n += len;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return n;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @}
 | 
			
		||||
 */
 | 
			
		||||
							
								
								
									
										348
									
								
								src/quickjs/buffer-utils.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										348
									
								
								src/quickjs/buffer-utils.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,348 @@
 | 
			
		||||
#ifndef BUFFER_UTILS_H
 | 
			
		||||
#define BUFFER_UTILS_H
 | 
			
		||||
 | 
			
		||||
#include <quickjs.h>
 | 
			
		||||
#include <cutils.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
 | 
			
		||||
#include "char-utils.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \defgroup buffer-utils buffer-utils: Buffer Utilities
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
int64_t array_search(void* a, size_t m, size_t elsz, void* needle);
 | 
			
		||||
#define array_contains(a, m, elsz, needle) (array_search((a), (m), (elsz), (needle)) != -1)
 | 
			
		||||
 | 
			
		||||
size_t ansi_length(const char*, size_t);
 | 
			
		||||
size_t ansi_skip(const char*, size_t);
 | 
			
		||||
size_t ansi_truncate(const char*, size_t, size_t limit);
 | 
			
		||||
int64_t array_search(void*, size_t, size_t elsz, void* needle);
 | 
			
		||||
char* str_escape(const char*);
 | 
			
		||||
 | 
			
		||||
char* byte_escape(const void*, size_t);
 | 
			
		||||
size_t byte_findb(const void*, size_t, const void* what, size_t wlen);
 | 
			
		||||
size_t byte_finds(const void*, size_t, const char* what);
 | 
			
		||||
size_t byte_equal(const void* s, size_t n, const void* t);
 | 
			
		||||
void byte_copy(void* out, size_t len, const void* in);
 | 
			
		||||
void byte_copyr(void* out, size_t len, const void* in);
 | 
			
		||||
size_t byte_rchrs(const char* in, size_t len, const char needles[], size_t nn);
 | 
			
		||||
 | 
			
		||||
#define DBUF_INIT_0() \
 | 
			
		||||
  (DynBuf) { 0, 0, 0, 0, 0, 0 }
 | 
			
		||||
#define DBUF_INIT_CTX(ctx) \
 | 
			
		||||
  (DynBuf) { 0, 0, 0, 0, (DynBufReallocFunc*)js_realloc_rt, JS_GetRuntime(ctx) }
 | 
			
		||||
 | 
			
		||||
extern const uint8_t escape_url_tab[256], escape_noquote_tab[256], escape_singlequote_tab[256], escape_doublequote_tab[256], escape_backquote_tab[256];
 | 
			
		||||
 | 
			
		||||
char* dbuf_at_n(const DynBuf*, size_t, size_t* n, char sep);
 | 
			
		||||
const char* dbuf_last_line(DynBuf*, size_t*);
 | 
			
		||||
int dbuf_prepend(DynBuf*, const uint8_t*, size_t len);
 | 
			
		||||
void dbuf_put_colorstr(DynBuf*, const char*, const char* color, int with_color);
 | 
			
		||||
void dbuf_put_escaped_pred(DynBuf*, const char*, size_t len, int (*pred)(int));
 | 
			
		||||
void dbuf_put_escaped_table(DynBuf*, const char*, size_t len, const uint8_t table[256]);
 | 
			
		||||
void dbuf_put_unescaped_table(DynBuf* db, const char* str, size_t len, const uint8_t table[256]);
 | 
			
		||||
void dbuf_put_unescaped_pred(DynBuf*, const char*, size_t len, int (*pred)());
 | 
			
		||||
void dbuf_put_escaped(DynBuf*, const char*, size_t len);
 | 
			
		||||
void dbuf_put_value(DynBuf*, JSContext*, JSValue value);
 | 
			
		||||
void dbuf_put_uint32(DynBuf* db, uint32_t num);
 | 
			
		||||
void dbuf_put_atom(DynBuf* db, JSContext* ctx, JSAtom atom);
 | 
			
		||||
int dbuf_reserve_start(DynBuf*, size_t);
 | 
			
		||||
uint8_t* dbuf_reserve(DynBuf*, size_t);
 | 
			
		||||
size_t dbuf_token_pop(DynBuf*, char);
 | 
			
		||||
size_t dbuf_token_push(DynBuf*, const char*, size_t len, char delim);
 | 
			
		||||
JSValue dbuf_tostring_free(DynBuf*, JSContext*);
 | 
			
		||||
ssize_t dbuf_load(DynBuf*, const char*);
 | 
			
		||||
int dbuf_vprintf(DynBuf*, const char*, va_list);
 | 
			
		||||
 | 
			
		||||
int screen_size(int size[2]);
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
dbuf_putm(DynBuf* db, ...) {
 | 
			
		||||
  int r = 0;
 | 
			
		||||
  va_list a;
 | 
			
		||||
  const char* s;
 | 
			
		||||
  va_start(a, db);
 | 
			
		||||
  while((s = va_arg(a, char*)))
 | 
			
		||||
    if(dbuf_putstr(db, s))
 | 
			
		||||
      return -1;
 | 
			
		||||
  va_end(a);
 | 
			
		||||
  return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define dbuf_append(d, x, n) dbuf_put((d), (const uint8_t*)(x), (n))
 | 
			
		||||
 | 
			
		||||
static inline size_t
 | 
			
		||||
dbuf_count(DynBuf* db, int ch) {
 | 
			
		||||
  return byte_count(db->buf, db->size, ch);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void
 | 
			
		||||
dbuf_0(DynBuf* db) {
 | 
			
		||||
  dbuf_putc(db, '\0');
 | 
			
		||||
  db->size--;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void
 | 
			
		||||
dbuf_zero(DynBuf* db) {
 | 
			
		||||
  dbuf_realloc(db, 0);
 | 
			
		||||
  db->size = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t dbuf_bitflags(DynBuf* db, uint32_t bits, const char* const names[]);
 | 
			
		||||
 | 
			
		||||
#define js_dbuf_init(ctx, buf) dbuf_init2((buf), (ctx), (realloc_func*)&utils_js_realloc)
 | 
			
		||||
#define js_dbuf_init_rt(rt, buf) dbuf_init2((buf), (rt), (realloc_func*)&utils_js_realloc_rt)
 | 
			
		||||
 | 
			
		||||
void js_dbuf_allocator(JSContext* ctx, DynBuf* s);
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  uint8_t* base;
 | 
			
		||||
  size_t size;
 | 
			
		||||
} MemoryBlock;
 | 
			
		||||
 | 
			
		||||
static inline void
 | 
			
		||||
block_init(MemoryBlock* mb) {
 | 
			
		||||
  mb->base = 0;
 | 
			
		||||
  mb->size = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* clang-format off */
 | 
			
		||||
static inline void* block_data(const MemoryBlock* mb) { return mb->base; }
 | 
			
		||||
static inline size_t block_length(const MemoryBlock* mb) { return mb->size; }
 | 
			
		||||
static inline void* block_begin(const MemoryBlock* mb) { return mb->base; }
 | 
			
		||||
static inline void* block_end(const MemoryBlock* mb) { return mb->base + mb->size; }
 | 
			
		||||
/* clang-format on */
 | 
			
		||||
 | 
			
		||||
static inline BOOL
 | 
			
		||||
block_arraybuffer(MemoryBlock* mb, JSValueConst ab, JSContext* ctx) {
 | 
			
		||||
  mb->base = JS_GetArrayBuffer(ctx, &mb->size, ab);
 | 
			
		||||
  return mb->base != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  uint8_t *start, *end;
 | 
			
		||||
} PointerRange;
 | 
			
		||||
 | 
			
		||||
static inline void
 | 
			
		||||
range_init(PointerRange* pr) {
 | 
			
		||||
  pr->end = pr->start = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline PointerRange
 | 
			
		||||
range_from(const MemoryBlock* mb) {
 | 
			
		||||
  return (PointerRange){mb->base, mb->base + mb->size};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  int64_t start, end;
 | 
			
		||||
} IndexRange;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  int64_t offset, length;
 | 
			
		||||
} OffsetLength;
 | 
			
		||||
 | 
			
		||||
#define OFFSET_INIT() \
 | 
			
		||||
  (OffsetLength) { 0, INT64_MAX }
 | 
			
		||||
 | 
			
		||||
static inline void
 | 
			
		||||
offset_init(OffsetLength* ol) {
 | 
			
		||||
  ol->offset = 0;
 | 
			
		||||
  ol->length = INT64_MAX;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline BOOL
 | 
			
		||||
offset_is_default(const OffsetLength* ol) {
 | 
			
		||||
  return ol->offset == 0 && ol->length == INT64_MAX;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void*
 | 
			
		||||
offset_data(const OffsetLength* ol, const void* x) {
 | 
			
		||||
  return (uint8_t*)x + ol->offset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline size_t
 | 
			
		||||
offset_size(const OffsetLength* ol, size_t n) {
 | 
			
		||||
  if(ol->length == -1)
 | 
			
		||||
    return (signed long)n - ol->offset;
 | 
			
		||||
  return MIN_NUM(ol->length, (signed long)n - ol->offset);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline MemoryBlock
 | 
			
		||||
offset_block(const OffsetLength* ol, const void* x, size_t n) {
 | 
			
		||||
  return (MemoryBlock){offset_data(ol, x), offset_size(ol, n)};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline PointerRange
 | 
			
		||||
offset_range(const OffsetLength* ol, const void* x, size_t n) {
 | 
			
		||||
  MemoryBlock mb = offset_block(ol, x, n);
 | 
			
		||||
  return range_from(&mb);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline OffsetLength
 | 
			
		||||
offset_slice(const OffsetLength ol, int64_t start, int64_t end) {
 | 
			
		||||
  if(start < 0)
 | 
			
		||||
    start = ol.length + (start % ol.length);
 | 
			
		||||
  else if(start > ol.length)
 | 
			
		||||
    start = ol.length;
 | 
			
		||||
  if(end < 0)
 | 
			
		||||
    end = ol.length + (end % ol.length);
 | 
			
		||||
  else if(end > ol.length)
 | 
			
		||||
    end = ol.length;
 | 
			
		||||
 | 
			
		||||
  return (OffsetLength){start, end - start};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline OffsetLength
 | 
			
		||||
offset_offset(const OffsetLength* ol, const OffsetLength* by) {
 | 
			
		||||
  OffsetLength ret;
 | 
			
		||||
  ret.offset = ol->offset + by->offset;
 | 
			
		||||
  ret.length = MIN_NUM(by->length, ol->length - by->offset);
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline OffsetLength
 | 
			
		||||
offset_from_indexrange(const IndexRange* ir) {
 | 
			
		||||
  OffsetLength ret;
 | 
			
		||||
  ret.offset = ir->start;
 | 
			
		||||
  ret.length = ir->end - ir->start;
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline JSValue
 | 
			
		||||
offset_typedarray(OffsetLength* ol, JSValueConst array, JSContext* ctx) {
 | 
			
		||||
  JSValue ret;
 | 
			
		||||
  size_t offset, length;
 | 
			
		||||
 | 
			
		||||
  ret = JS_GetTypedArrayBuffer(ctx, array, &offset, &length, NULL);
 | 
			
		||||
 | 
			
		||||
  if(!JS_IsException(ret)) {
 | 
			
		||||
    ol->offset = offset;
 | 
			
		||||
    ol->length = length;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline IndexRange
 | 
			
		||||
indexrange_from_offset(const OffsetLength* ol) {
 | 
			
		||||
  IndexRange ret;
 | 
			
		||||
  ret.start = ol->offset;
 | 
			
		||||
  ret.end = ol->offset + ol->length;
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline MemoryBlock
 | 
			
		||||
block_range(const MemoryBlock* mb, const OffsetLength* range) {
 | 
			
		||||
  MemoryBlock ret;
 | 
			
		||||
  ret.base = mb->base + range->offset;
 | 
			
		||||
  ret.size = MIN_NUM((size_t)range->length, mb->size - range->offset);
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
block_realloc(MemoryBlock* mb, size_t new_size, JSContext* ctx) {
 | 
			
		||||
  if((mb->base = js_realloc(ctx, mb->base, new_size))) {
 | 
			
		||||
    mb->size = new_size;
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
  return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct InputBuffer {
 | 
			
		||||
  union {
 | 
			
		||||
    MemoryBlock block;
 | 
			
		||||
    struct {
 | 
			
		||||
      uint8_t* data;
 | 
			
		||||
      size_t size;
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
  size_t pos;
 | 
			
		||||
  void (*free)(JSContext*, const char*, JSValue);
 | 
			
		||||
  JSValue value;
 | 
			
		||||
  OffsetLength range;
 | 
			
		||||
} InputBuffer;
 | 
			
		||||
 | 
			
		||||
static inline void
 | 
			
		||||
input_buffer_free_default(JSContext* ctx, const char* str, JSValue val) {
 | 
			
		||||
  if(JS_IsString(val))
 | 
			
		||||
    JS_FreeCString(ctx, str);
 | 
			
		||||
 | 
			
		||||
  if(!JS_IsUndefined(val))
 | 
			
		||||
    JS_FreeValue(ctx, val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
InputBuffer js_input_buffer(JSContext* ctx, JSValueConst value);
 | 
			
		||||
InputBuffer js_input_chars(JSContext* ctx, JSValueConst value);
 | 
			
		||||
InputBuffer js_input_args(JSContext* ctx, int argc, JSValueConst argv[]);
 | 
			
		||||
InputBuffer js_output_args(JSContext* ctx, int argc, JSValueConst argv[]);
 | 
			
		||||
 | 
			
		||||
InputBuffer input_buffer_clone(const InputBuffer* in, JSContext* ctx);
 | 
			
		||||
BOOL input_buffer_valid(const InputBuffer* in);
 | 
			
		||||
void input_buffer_dump(const InputBuffer* in, DynBuf* db);
 | 
			
		||||
void input_buffer_free(InputBuffer* in, JSContext* ctx);
 | 
			
		||||
 | 
			
		||||
static inline uint8_t*
 | 
			
		||||
input_buffer_data(const InputBuffer* in) {
 | 
			
		||||
  return offset_data(&in->range, in->data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline size_t
 | 
			
		||||
input_buffer_length(const InputBuffer* in) {
 | 
			
		||||
  return offset_size(&in->range, in->size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline MemoryBlock
 | 
			
		||||
input_buffer_block(InputBuffer* in) {
 | 
			
		||||
  return (MemoryBlock){input_buffer_data(in), input_buffer_length(in)};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline MemoryBlock*
 | 
			
		||||
input_buffer_blockptr(InputBuffer* in) {
 | 
			
		||||
  return &in->block;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const uint8_t* input_buffer_get(InputBuffer* in, size_t* lenp);
 | 
			
		||||
const uint8_t* input_buffer_peek(InputBuffer* in, size_t* lenp);
 | 
			
		||||
const char* input_buffer_currentline(InputBuffer*, size_t* len);
 | 
			
		||||
size_t input_buffer_column(InputBuffer*, size_t* len);
 | 
			
		||||
 | 
			
		||||
int input_buffer_peekc(InputBuffer* in, size_t* lenp);
 | 
			
		||||
int input_buffer_putc(InputBuffer*, unsigned int, JSContext*);
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
input_buffer_getc(InputBuffer* in) {
 | 
			
		||||
  size_t n;
 | 
			
		||||
  int ret;
 | 
			
		||||
  ret = input_buffer_peekc(in, &n);
 | 
			
		||||
  in->pos += n;
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void*
 | 
			
		||||
input_buffer_begin(const InputBuffer* in) {
 | 
			
		||||
  return input_buffer_data(in);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void*
 | 
			
		||||
input_buffer_end(const InputBuffer* in) {
 | 
			
		||||
  return input_buffer_data(in) + input_buffer_length(in);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline BOOL
 | 
			
		||||
input_buffer_eof(const InputBuffer* in) {
 | 
			
		||||
  return in->pos == input_buffer_length(in);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline size_t
 | 
			
		||||
input_buffer_remain(const InputBuffer* in) {
 | 
			
		||||
  return input_buffer_length(in) - in->pos;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int js_offset_length(JSContext*, int64_t size, int argc, JSValueConst argv[], OffsetLength* off_len_p);
 | 
			
		||||
int js_index_range(JSContext*, int64_t size, int argc, JSValueConst argv[], IndexRange* idx_rng_p);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @}
 | 
			
		||||
 */
 | 
			
		||||
#endif /* defined(BUFFER_UTILS) */
 | 
			
		||||
							
								
								
									
										578
									
								
								src/quickjs/char-utils.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										578
									
								
								src/quickjs/char-utils.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,578 @@
 | 
			
		||||
#include "char-utils.h"
 | 
			
		||||
#include "libutf.h"
 | 
			
		||||
#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MSYS__)
 | 
			
		||||
#include <winnls.h>
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#include <wchar.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \addtogroup char-utils
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
size_t
 | 
			
		||||
token_length(const char* str, size_t len, char delim) {
 | 
			
		||||
  const char *s, *e;
 | 
			
		||||
  size_t pos;
 | 
			
		||||
 | 
			
		||||
  for(s = str, e = s + len; s < e; s += pos + 1) {
 | 
			
		||||
    pos = byte_chr(s, e - s, delim);
 | 
			
		||||
 | 
			
		||||
    if(s + pos == e)
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    if(pos == 0 || s[pos - 1] != '\\') {
 | 
			
		||||
      s += pos;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return s - str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
fmt_ulong(char* dest, uint32_t i) {
 | 
			
		||||
  uint32_t len, tmp, len2;
 | 
			
		||||
 | 
			
		||||
  for(len = 1, tmp = i; tmp > 9; ++len)
 | 
			
		||||
    tmp /= 10;
 | 
			
		||||
 | 
			
		||||
  if(dest)
 | 
			
		||||
    for(tmp = i, dest += len, len2 = len + 1; --len2; tmp /= 10)
 | 
			
		||||
      *--dest = (char)((tmp % 10) + '0');
 | 
			
		||||
 | 
			
		||||
  return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
fmt_longlong(char* dest, int64_t i) {
 | 
			
		||||
  if(i < 0) {
 | 
			
		||||
    if(dest)
 | 
			
		||||
      *dest++ = '-';
 | 
			
		||||
    return fmt_ulonglong(dest, (uint64_t)-i) + 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return fmt_ulonglong(dest, (uint64_t)i);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
fmt_ulonglong(char* dest, uint64_t i) {
 | 
			
		||||
  size_t len;
 | 
			
		||||
  uint64_t tmp, len2;
 | 
			
		||||
 | 
			
		||||
  for(len = 1, tmp = i; tmp > 9ll; ++len)
 | 
			
		||||
    tmp /= 10ll;
 | 
			
		||||
 | 
			
		||||
  if(dest)
 | 
			
		||||
    for(tmp = i, dest += len, len2 = len + 1; --len2; tmp /= 10ll)
 | 
			
		||||
      *--dest = (tmp % 10ll) + '0';
 | 
			
		||||
 | 
			
		||||
  return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define tohex(c) (char)((c) >= 10 ? (c)-10 + 'a' : (c) + '0')
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
fmt_xlonglong(char* dest, uint64_t i) {
 | 
			
		||||
  uint64_t len, tmp;
 | 
			
		||||
 | 
			
		||||
  for(len = 1, tmp = i; tmp > 15ll; ++len)
 | 
			
		||||
    tmp >>= 4ll;
 | 
			
		||||
 | 
			
		||||
  if(dest)
 | 
			
		||||
    for(tmp = i, dest += len;;) {
 | 
			
		||||
      *--dest = tohex(tmp & 15ll);
 | 
			
		||||
 | 
			
		||||
      if(!(tmp >>= 4ll))
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
fmt_xlonglong0(char* dest, uint64_t num, size_t n) {
 | 
			
		||||
  size_t i = 0, len;
 | 
			
		||||
 | 
			
		||||
  if((len = fmt_xlonglong(NULL, num)) < n) {
 | 
			
		||||
    len = n - len;
 | 
			
		||||
 | 
			
		||||
    while(i < len)
 | 
			
		||||
      dest[i++] = '0';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  i += fmt_xlonglong(&dest[i], num);
 | 
			
		||||
  return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
fmt_8long(char* dest, uint32_t i) {
 | 
			
		||||
  uint32_t len, tmp;
 | 
			
		||||
 | 
			
		||||
  /* first count the number of bytes needed */
 | 
			
		||||
  for(len = 1, tmp = i; tmp > 7; ++len)
 | 
			
		||||
    tmp >>= 3;
 | 
			
		||||
 | 
			
		||||
  if(dest)
 | 
			
		||||
    for(tmp = i, dest += len;;) {
 | 
			
		||||
      *--dest = (char)((tmp & 7) + '0');
 | 
			
		||||
 | 
			
		||||
      if(!(tmp >>= 3))
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define tohex(c) (char)((c) >= 10 ? (c)-10 + 'a' : (c) + '0')
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
fmt_xlong(char* dest, uint32_t i) {
 | 
			
		||||
  uint32_t len, tmp;
 | 
			
		||||
 | 
			
		||||
  /* first count the number of bytes needed */
 | 
			
		||||
  for(len = 1, tmp = i; tmp > 15; ++len)
 | 
			
		||||
    tmp >>= 4;
 | 
			
		||||
 | 
			
		||||
  if(dest)
 | 
			
		||||
    for(tmp = i, dest += len;;) {
 | 
			
		||||
      *--dest = tohex(tmp & 15);
 | 
			
		||||
 | 
			
		||||
      if(!(tmp >>= 4))
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
fmt_xlong0(char* dest, uint32_t num, size_t n) {
 | 
			
		||||
  size_t i = 0, len;
 | 
			
		||||
 | 
			
		||||
  if((len = fmt_xlong(NULL, num)) < n) {
 | 
			
		||||
    len = n - len;
 | 
			
		||||
 | 
			
		||||
    while(i < len)
 | 
			
		||||
      dest[i++] = '0';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  i += fmt_xlong(&dest[i], num);
 | 
			
		||||
  return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
scan_ushort(const char* src, uint16_t* dest) {
 | 
			
		||||
  const char* cur;
 | 
			
		||||
  uint16_t l;
 | 
			
		||||
 | 
			
		||||
  for(cur = src, l = 0; *cur >= '0' && *cur <= '9'; ++cur) {
 | 
			
		||||
    uint32_t tmp = l * 10ul + *cur - '0';
 | 
			
		||||
 | 
			
		||||
    if((uint16_t)tmp != tmp)
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    l = tmp;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(cur > src)
 | 
			
		||||
    *dest = l;
 | 
			
		||||
 | 
			
		||||
  return (size_t)(cur - src);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
scan_uint(const char* src, uint32_t* dest) {
 | 
			
		||||
  uint64_t u64;
 | 
			
		||||
  size_t r = scan_ulonglong(src, &u64);
 | 
			
		||||
  *dest = u64;
 | 
			
		||||
  return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
scan_int(const char* src, int32_t* dest) {
 | 
			
		||||
  int64_t i64;
 | 
			
		||||
  size_t r = scan_longlong(src, &i64);
 | 
			
		||||
  *dest = i64;
 | 
			
		||||
  return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifndef MAXLONG
 | 
			
		||||
#define MAXLONG (((uint32_t)-1) >> 1)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
scan_longlong(const char* src, int64_t* dest) {
 | 
			
		||||
  size_t i, o;
 | 
			
		||||
  uint64_t l;
 | 
			
		||||
  char c = src[0];
 | 
			
		||||
  unsigned int neg = c == '-';
 | 
			
		||||
  o = c == '-' || c == '+';
 | 
			
		||||
 | 
			
		||||
  if((i = scan_ulonglong(src + o, &l))) {
 | 
			
		||||
    if(i > 0ll && l > MAXLONG + neg) {
 | 
			
		||||
      l /= 10ll;
 | 
			
		||||
      --i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(i + o)
 | 
			
		||||
      *dest = (int64_t)(c == '-' ? -l : l);
 | 
			
		||||
 | 
			
		||||
    return i + o;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
scan_ulonglong(const char* src, uint64_t* dest) {
 | 
			
		||||
  const char* tmp = src;
 | 
			
		||||
  uint64_t l = 0;
 | 
			
		||||
  unsigned char c;
 | 
			
		||||
 | 
			
		||||
  while((c = (unsigned char)(*tmp - '0')) < 10) {
 | 
			
		||||
    uint64_t n;
 | 
			
		||||
    n = l << 3ll;
 | 
			
		||||
 | 
			
		||||
    if((n >> 3ll) != l)
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    if(n + (l << 1ll) < n)
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    n += l << 1ll;
 | 
			
		||||
 | 
			
		||||
    if(n + c < n)
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    l = n + c;
 | 
			
		||||
    ++tmp;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(tmp - src)
 | 
			
		||||
    *dest = l;
 | 
			
		||||
 | 
			
		||||
  return (size_t)(tmp - src);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
scan_xlonglong(const char* src, uint64_t* dest) {
 | 
			
		||||
  const char* tmp = src;
 | 
			
		||||
  int64_t l = 0;
 | 
			
		||||
  unsigned char c;
 | 
			
		||||
 | 
			
		||||
  while((c = scan_fromhex(*tmp)) < 16) {
 | 
			
		||||
    l = (l << 4) + c;
 | 
			
		||||
    ++tmp;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  *dest = l;
 | 
			
		||||
  return tmp - src;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
scan_8longn(const char* src, size_t n, uint32_t* dest) {
 | 
			
		||||
  const char* tmp = src;
 | 
			
		||||
  uint32_t l = 0;
 | 
			
		||||
  unsigned char c;
 | 
			
		||||
 | 
			
		||||
  while(n-- > 0 && (c = (unsigned char)(*tmp - '0')) < 8) {
 | 
			
		||||
    if(l >> (sizeof(l) * 8 - 3))
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    l = l * 8 + c;
 | 
			
		||||
    ++tmp;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  *dest = l;
 | 
			
		||||
  return (size_t)(tmp - src);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
scan_whitenskip(const char* s, size_t limit) {
 | 
			
		||||
  const char *t, *u;
 | 
			
		||||
 | 
			
		||||
  for(t = s, u = t + limit; t < u; ++t)
 | 
			
		||||
    if(!is_whitespace_char(*t))
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
  return (size_t)(t - s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
scan_nonwhitenskip(const char* s, size_t limit) {
 | 
			
		||||
  const char *t, *u;
 | 
			
		||||
 | 
			
		||||
  for(t = s, u = t + limit; t < u; ++t)
 | 
			
		||||
    if(is_whitespace_char(*t))
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
  return (size_t)(t - s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
scan_line(const char* s, size_t limit) {
 | 
			
		||||
  const char *t, *u;
 | 
			
		||||
 | 
			
		||||
  for(t = s, u = s + limit; t < u; ++t)
 | 
			
		||||
    if(*t == '\n' || *t == '\r')
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
  return (size_t)(t - s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
scan_lineskip(const char* s, size_t limit) {
 | 
			
		||||
  const char *t, *u;
 | 
			
		||||
 | 
			
		||||
  for(t = s, u = s + limit; t < u; ++t)
 | 
			
		||||
    if(*t == '\n') {
 | 
			
		||||
      ++t;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return (size_t)(t - s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
scan_lineskip_escaped(const char* s, size_t limit) {
 | 
			
		||||
  const char *t, *u;
 | 
			
		||||
 | 
			
		||||
  for(t = s, u = s + limit; t < u; ++t) {
 | 
			
		||||
    if(*t == '\\') {
 | 
			
		||||
      ++t;
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
    if(*t == '\n') {
 | 
			
		||||
      ++t;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return (size_t)(t - s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
scan_eolskip(const char* s, size_t limit) {
 | 
			
		||||
  size_t n = 0;
 | 
			
		||||
 | 
			
		||||
  if(n + 1 < limit && s[0] == '\r' && s[1] == '\n')
 | 
			
		||||
    n += 2;
 | 
			
		||||
  else if(n < limit && s[0] == '\n')
 | 
			
		||||
    n += 1;
 | 
			
		||||
 | 
			
		||||
  return n;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
utf8_strlen(const void* in, size_t len) {
 | 
			
		||||
  const uint8_t *pos, *end, *next;
 | 
			
		||||
  size_t i = 0;
 | 
			
		||||
 | 
			
		||||
  for(pos = (const uint8_t*)in, end = pos + len; pos < end; pos = next, ++i)
 | 
			
		||||
    unicode_from_utf8(pos, end - pos, &next);
 | 
			
		||||
 | 
			
		||||
  return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MSYS__)
 | 
			
		||||
wchar_t*
 | 
			
		||||
utf8_towcs(const char* s) {
 | 
			
		||||
  int len = (int)strlen(s);
 | 
			
		||||
  int n = MultiByteToWideChar(CP_UTF8, 0, s, len, NULL, 0);
 | 
			
		||||
  wchar_t* ret;
 | 
			
		||||
 | 
			
		||||
  if((ret = (wchar_t*)malloc((n + 1) * sizeof(wchar_t)))) {
 | 
			
		||||
    MultiByteToWideChar(CP_UTF8, 0, s, len, ret, n);
 | 
			
		||||
    ret[n] = L'\0';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char*
 | 
			
		||||
utf8_fromwcs(const wchar_t* wstr) {
 | 
			
		||||
  int len = (int)wcslen(wstr);
 | 
			
		||||
  int n = WideCharToMultiByte(CP_UTF8, 0, wstr, len, NULL, 0, NULL, NULL);
 | 
			
		||||
  char* ret;
 | 
			
		||||
 | 
			
		||||
  if((ret = malloc((n + 1)))) {
 | 
			
		||||
    WideCharToMultiByte(CP_UTF8, 0, wstr, len, ret, n, NULL, NULL);
 | 
			
		||||
    ret[n] = '\0';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
BOOL
 | 
			
		||||
utf16_multiword(const void* in) {
 | 
			
		||||
  const uint16_t* p16 = in;
 | 
			
		||||
  LibutfC16Type type = libutf_c16_type(p16[0]);
 | 
			
		||||
 | 
			
		||||
  return !((LIBUTF_UTF16_NOT_SURROGATE == type) || (LIBUTF_UTF16_SURROGATE_HIGH != type || LIBUTF_UTF16_SURROGATE_LOW != libutf_c16_type(p16[1])));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
case_lowerc(int c) {
 | 
			
		||||
  if(c >= 'A' && c <= 'Z')
 | 
			
		||||
    c += 'a' - 'A';
 | 
			
		||||
 | 
			
		||||
  return c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
case_starts(const char* a, const char* b) {
 | 
			
		||||
  const char *s, *t;
 | 
			
		||||
 | 
			
		||||
  for(s = a, t = b;; ++s, ++t) {
 | 
			
		||||
    unsigned char x, y;
 | 
			
		||||
 | 
			
		||||
    if(!*t)
 | 
			
		||||
      return 1;
 | 
			
		||||
 | 
			
		||||
    x = case_lowerc(*s);
 | 
			
		||||
    y = case_lowerc(*t);
 | 
			
		||||
 | 
			
		||||
    if(x != y)
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    if(!x)
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
case_diffb(const void* S, size_t len, const void* T) {
 | 
			
		||||
  unsigned char x, y;
 | 
			
		||||
  const char *s, *t;
 | 
			
		||||
 | 
			
		||||
  for(s = (const char*)S, t = (const char*)T; len > 0;) {
 | 
			
		||||
    --len;
 | 
			
		||||
    x = case_lowerc(*s);
 | 
			
		||||
    y = case_lowerc(*t);
 | 
			
		||||
 | 
			
		||||
    ++s;
 | 
			
		||||
    ++t;
 | 
			
		||||
 | 
			
		||||
    if(x != y)
 | 
			
		||||
      return ((int)(unsigned int)x) - ((int)(unsigned int)y);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
case_findb(const void* haystack, size_t hlen, const void* what, size_t wlen) {
 | 
			
		||||
  size_t i, last;
 | 
			
		||||
  const char* s = haystack;
 | 
			
		||||
 | 
			
		||||
  if(hlen < wlen)
 | 
			
		||||
    return hlen;
 | 
			
		||||
 | 
			
		||||
  last = hlen - wlen;
 | 
			
		||||
 | 
			
		||||
  for(i = 0; i <= last; i++, s++)
 | 
			
		||||
    if(!case_diffb(s, wlen, what))
 | 
			
		||||
      return i;
 | 
			
		||||
 | 
			
		||||
  return hlen;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
case_finds(const void* haystack, const char* what) {
 | 
			
		||||
  return case_findb(haystack, strlen(haystack), what, strlen(what));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ssize_t
 | 
			
		||||
write_file(const char* file, const void* buf, size_t len) {
 | 
			
		||||
  FILE* f;
 | 
			
		||||
  ssize_t ret = -1;
 | 
			
		||||
 | 
			
		||||
  if((f = fopen(file, "w+")))
 | 
			
		||||
    switch(fwrite(buf, len, 1, f)) {
 | 
			
		||||
      case 1: {
 | 
			
		||||
        ret = len;
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  fflush(f);
 | 
			
		||||
  ret = ftell(f);
 | 
			
		||||
  fclose(f);
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ssize_t
 | 
			
		||||
puts_file(const char* file, const char* s) {
 | 
			
		||||
  return write_file(file, s, strlen(s));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
u64toa(char* x, uint64_t num, int base) {
 | 
			
		||||
  size_t len = 0;
 | 
			
		||||
  uint64_t n = num;
 | 
			
		||||
 | 
			
		||||
  do {
 | 
			
		||||
    n /= base;
 | 
			
		||||
    len++;
 | 
			
		||||
    x++;
 | 
			
		||||
  } while(n != 0);
 | 
			
		||||
 | 
			
		||||
  *x-- = '\0';
 | 
			
		||||
 | 
			
		||||
  do {
 | 
			
		||||
    char c = num % base;
 | 
			
		||||
    num /= base;
 | 
			
		||||
 | 
			
		||||
    if(c >= 10)
 | 
			
		||||
      c += 'a' - '0' - 10;
 | 
			
		||||
    *x-- = c + '0';
 | 
			
		||||
  } while(num != 0);
 | 
			
		||||
 | 
			
		||||
  return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
i64toa(char* x, int64_t num, int base) {
 | 
			
		||||
  size_t pos = 0, len;
 | 
			
		||||
 | 
			
		||||
  if(num < 0) {
 | 
			
		||||
    x[pos++] = '-';
 | 
			
		||||
    num = -num;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  len = u64toa(&x[pos], num, base);
 | 
			
		||||
 | 
			
		||||
  return pos + len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
str_findb(const char* s1, const char* x, size_t n) {
 | 
			
		||||
  const char* b;
 | 
			
		||||
  size_t i, j, len = strlen(s1);
 | 
			
		||||
 | 
			
		||||
  if(len >= n) {
 | 
			
		||||
    size_t end = len - n + 1;
 | 
			
		||||
 | 
			
		||||
    for(i = 0; i < end; i++) {
 | 
			
		||||
      b = &s1[i];
 | 
			
		||||
 | 
			
		||||
      for(j = 0; x[j] == b[j];)
 | 
			
		||||
        if(++j == n)
 | 
			
		||||
          return i;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
str_find(const void* s, const void* what) {
 | 
			
		||||
  return str_findb(s, what, strlen(what));
 | 
			
		||||
}
 | 
			
		||||
/**
 | 
			
		||||
 * @}
 | 
			
		||||
 */
 | 
			
		||||
							
								
								
									
										441
									
								
								src/quickjs/char-utils.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										441
									
								
								src/quickjs/char-utils.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,441 @@
 | 
			
		||||
#ifndef CHAR_UTILS_H
 | 
			
		||||
#define CHAR_UTILS_H
 | 
			
		||||
 | 
			
		||||
#include <cutils.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "debug.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \defgroup char-utils char-utils: Character Utilities
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
#define is_control_char(c) ((c) == '\a' || (c) == '\b' || (c) == '\t' || (c) == '\n' || (c) == '\v' || (c) == '\f' || (c) == '\r')
 | 
			
		||||
#define is_alphanumeric_char(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
 | 
			
		||||
 | 
			
		||||
#define is_digit_char(c) ((c) >= '0' && (c) <= '9')
 | 
			
		||||
#define is_print_char(c) ((c) >= ' ' && (c) <= '\x7f')
 | 
			
		||||
#define is_newline_char(c) ((c) == '\n')
 | 
			
		||||
#define is_identifier_char(c) (is_alphanumeric_char(c) || is_digit_char(c) || (c) == '$' || (c) == '_')
 | 
			
		||||
#define is_whitespace_char(c) ((c) == ' ' || (c) == '\t' || (c) == '\v' || (c) == '\n' || (c) == '\r')
 | 
			
		||||
 | 
			
		||||
#define str_equal(s, t) (!strcmp((s), (t)))
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
escape_char_pred(int c) {
 | 
			
		||||
  static const unsigned char table[256] = {
 | 
			
		||||
      'x', 'x', 'x', 'x', 'x', 'x',  'x', 'x', 0x62, 0x74, 0x6e, 0x76, 0x66, 0x72, 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
 | 
			
		||||
      'x', 'x', 'x', 0,   0,   0,    0,   0,   0,    0,    0x27, 0,    0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
      0,   0,   0,   0,   0,   0,    0,   0,   0,    0,    0,    0,    0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
      0,   0,   0,   0,   0,   0x5c, 0,   0,   0,    0,    0,    0,    0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
      0,   0,   0,   0,   0,   0,    0,   0,   0,    0,    0,    'x',  0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
      0,   0,   0,   0,   0,   0,    0,   0,   0,    0,    0,    0,    0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
      0,   0,   0,   0,   0,   0,    0,   0,   0,    0,    0,    0,    0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
      0,   0,   0,   0,   0,   0,    0,   0,   0,    0,    0,    0,    0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
      0,   0,   0,   0,   0,   0,    0,   0,   0,    0,    0,    0,    0,    0,    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return table[(unsigned char)c];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
unescape_char_pred(int c) {
 | 
			
		||||
  switch(c) {
 | 
			
		||||
    case 'b': return 8;
 | 
			
		||||
    case 'f': return 12;
 | 
			
		||||
    case 'n': return 10;
 | 
			
		||||
    case 'r': return 13;
 | 
			
		||||
    case 't': return 9;
 | 
			
		||||
    case 'v': return 11;
 | 
			
		||||
    case '\'': return 39;
 | 
			
		||||
    case '\\': return 92;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
is_escape_char(int c) {
 | 
			
		||||
  return is_control_char(c) || c == '\\' || c == '\'' || c == 0x1b || c == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
is_backslash_char(int c) {
 | 
			
		||||
  return c == '\\';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//#define is_dot_char(c) ((c) == '.')0
 | 
			
		||||
//#define is_backslash_char(c) ((c) == '\\')
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
is_dot_char(int c) {
 | 
			
		||||
  return c == '.';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
is_identifier(const char* str) {
 | 
			
		||||
  if(!((*str >= 'A' && *str <= 'Z') || (*str >= 'a' && *str <= 'z') || *str == '$' || *str == '_'))
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
  while(*++str)
 | 
			
		||||
    if(!is_identifier_char(*str))
 | 
			
		||||
      return 0;
 | 
			
		||||
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
is_integer(const char* str) {
 | 
			
		||||
  if(*str == '-')
 | 
			
		||||
    ++str;
 | 
			
		||||
 | 
			
		||||
  if(!(*str >= '1' && *str <= '9') && !(*str == '0' && str[1] == '\0'))
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
  while(*++str)
 | 
			
		||||
    if(!is_digit_char(*str))
 | 
			
		||||
      return 0;
 | 
			
		||||
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline size_t
 | 
			
		||||
byte_count(const void* s, size_t n, char c) {
 | 
			
		||||
  const uint8_t* t;
 | 
			
		||||
  uint8_t ch = (uint8_t)c;
 | 
			
		||||
  size_t count;
 | 
			
		||||
 | 
			
		||||
  for(t = (uint8_t*)s, count = 0; n; ++t, --n)
 | 
			
		||||
    if(*t == ch)
 | 
			
		||||
      ++count;
 | 
			
		||||
 | 
			
		||||
  return count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline size_t
 | 
			
		||||
byte_chr(const void* str, size_t len, char c) {
 | 
			
		||||
  const char* s = memchr(str, c, len);
 | 
			
		||||
 | 
			
		||||
  if(s)
 | 
			
		||||
    return s - (const char*)str;
 | 
			
		||||
 | 
			
		||||
  return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline size_t
 | 
			
		||||
byte_rchr(const void* haystack, size_t len, char needle) {
 | 
			
		||||
  const char *s, *t;
 | 
			
		||||
 | 
			
		||||
  for(s = (const char*)haystack, t = s + len;;) {
 | 
			
		||||
    --t;
 | 
			
		||||
 | 
			
		||||
    if(s > t)
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    if(*t == needle)
 | 
			
		||||
      return (size_t)(t - s);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*size_t
 | 
			
		||||
byte_rchr(const void* str, size_t len, char c) {
 | 
			
		||||
  const char* s = memrchr(str, c, len);
 | 
			
		||||
  if(s)
 | 
			
		||||
    return s - (const char*)str;
 | 
			
		||||
  return len;
 | 
			
		||||
}*/
 | 
			
		||||
 | 
			
		||||
static inline size_t
 | 
			
		||||
byte_chrs(const void* str, size_t len, const char needle[], size_t nl) {
 | 
			
		||||
  const char *s, *t;
 | 
			
		||||
 | 
			
		||||
  for(s = str, t = s + len; s != t; s++)
 | 
			
		||||
    if(byte_chr(needle, nl, *s) < nl)
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
  return s - (const char*)str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
byte_diff(const void* a, size_t len, const void* b) {
 | 
			
		||||
  size_t i;
 | 
			
		||||
 | 
			
		||||
  for(i = 0; i < len; ++i) {
 | 
			
		||||
    int r = ((unsigned char*)a)[i] - ((unsigned char*)b)[i];
 | 
			
		||||
 | 
			
		||||
    if(r)
 | 
			
		||||
      return r;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
byte_diff2(const char* a, size_t alen, const char* b, size_t blen) {
 | 
			
		||||
 | 
			
		||||
  if(alen < blen)
 | 
			
		||||
    return -b[alen];
 | 
			
		||||
 | 
			
		||||
  if(blen < alen)
 | 
			
		||||
    return a[blen];
 | 
			
		||||
 | 
			
		||||
  return byte_diff(a, alen, b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline size_t
 | 
			
		||||
str_chr(const char* in, char needle) {
 | 
			
		||||
  const char *t, c = needle;
 | 
			
		||||
 | 
			
		||||
  for(t = in; *t; ++t)
 | 
			
		||||
    if(*t == c)
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
  return (size_t)(t - in);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline size_t
 | 
			
		||||
str_chrs(const char* in, const char needles[], size_t nn) {
 | 
			
		||||
  const char* t;
 | 
			
		||||
  size_t i;
 | 
			
		||||
 | 
			
		||||
  for(t = in; *t; ++t)
 | 
			
		||||
    for(i = 0; i < nn; i++)
 | 
			
		||||
      if(*t == needles[i])
 | 
			
		||||
        return (size_t)(t - in);
 | 
			
		||||
 | 
			
		||||
  return (size_t)(t - in);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline size_t
 | 
			
		||||
str_rchr(const char* s, char needle) {
 | 
			
		||||
  const char *in, *found = 0;
 | 
			
		||||
 | 
			
		||||
  for(in = s; *in; ++in)
 | 
			
		||||
    if(*in == needle)
 | 
			
		||||
      found = in;
 | 
			
		||||
 | 
			
		||||
  return (size_t)((found ? found : in) - s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline size_t
 | 
			
		||||
str_rchrs(const char* in, const char needles[], size_t nn) {
 | 
			
		||||
  const char *s, *found = 0;
 | 
			
		||||
  size_t i;
 | 
			
		||||
 | 
			
		||||
  for(s = in; *s; ++s)
 | 
			
		||||
    for(i = 0; i < nn; ++i)
 | 
			
		||||
      if(*s == needles[i])
 | 
			
		||||
        found = s;
 | 
			
		||||
 | 
			
		||||
  return (size_t)((found ? found : s) - in);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
str_endb(const char* a, const char* x, size_t n) {
 | 
			
		||||
  size_t alen = strlen(a);
 | 
			
		||||
  a += alen - n;
 | 
			
		||||
 | 
			
		||||
  return alen >= n && !memcmp(a, x, n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* str_ends returns 1 if the b is a suffix of a, 0 otherwise */
 | 
			
		||||
static inline int
 | 
			
		||||
str_ends(const char* a, const char* b) {
 | 
			
		||||
  return str_endb(a, b, strlen(b));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
str_startb(const char* a, const char* x, size_t len) {
 | 
			
		||||
  size_t i;
 | 
			
		||||
 | 
			
		||||
  for(i = 0;; i++) {
 | 
			
		||||
    if(i == len)
 | 
			
		||||
      return 1;
 | 
			
		||||
    if(a[i] != x[i])
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
str_start(const char* a, const char* b) {
 | 
			
		||||
  return str_startb(a, b, strlen(b));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define str_contains(s, needle) (!!strchr((s), (needle)))
 | 
			
		||||
 | 
			
		||||
char* str_escape(const char*);
 | 
			
		||||
 | 
			
		||||
static inline size_t
 | 
			
		||||
str_count(const char* s, char c) {
 | 
			
		||||
  size_t i, count = 0;
 | 
			
		||||
 | 
			
		||||
  for(i = 0; s[i]; i++)
 | 
			
		||||
    if(s[i] == c)
 | 
			
		||||
      ++count;
 | 
			
		||||
 | 
			
		||||
  return count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline size_t
 | 
			
		||||
str_copy(char* out, const char* in) {
 | 
			
		||||
  char* s;
 | 
			
		||||
 | 
			
		||||
  for(s = out; (*s = *in); ++s)
 | 
			
		||||
    ++in;
 | 
			
		||||
 | 
			
		||||
  return (size_t)(s - out);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline size_t
 | 
			
		||||
str_copyn(char* out, const char* in, size_t n) {
 | 
			
		||||
  char* s;
 | 
			
		||||
 | 
			
		||||
  for(s = out; n-- && (*s = *in); ++s)
 | 
			
		||||
    ++in;
 | 
			
		||||
 | 
			
		||||
  *s = '\0';
 | 
			
		||||
  return (size_t)(s - out);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline char*
 | 
			
		||||
str_ndup(const char* s, size_t n) {
 | 
			
		||||
  char* r = malloc(n + 1);
 | 
			
		||||
 | 
			
		||||
  if(r == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  memcpy(r, s, n);
 | 
			
		||||
  r[n] = '\0';
 | 
			
		||||
  return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t str_findb(const char*, const char*, size_t);
 | 
			
		||||
size_t str_find(const void*, const void*);
 | 
			
		||||
 | 
			
		||||
static inline size_t
 | 
			
		||||
predicate_find(const char* str, size_t len, int (*pred)(int32_t)) {
 | 
			
		||||
  size_t pos;
 | 
			
		||||
 | 
			
		||||
  for(pos = 0; pos < len; pos++)
 | 
			
		||||
    if(pred(str[pos]))
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
  return pos;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline size_t
 | 
			
		||||
lookup_find(const char* str, size_t len, const char table[256]) {
 | 
			
		||||
  size_t pos;
 | 
			
		||||
 | 
			
		||||
  for(pos = 0; pos < len; pos++)
 | 
			
		||||
    if(table[(unsigned char)str[pos]])
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
  return pos;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline char
 | 
			
		||||
escape_char_letter(char c) {
 | 
			
		||||
  switch(c) {
 | 
			
		||||
    case '\0': return '0';
 | 
			
		||||
    case '\a': return 'a';
 | 
			
		||||
    case '\b': return 'b';
 | 
			
		||||
    case '\t': return 't';
 | 
			
		||||
    case '\n': return 'n';
 | 
			
		||||
    case '\v': return 'v';
 | 
			
		||||
    case '\f': return 'f';
 | 
			
		||||
    case '\r': return 'r';
 | 
			
		||||
    case '\\': return '\\';
 | 
			
		||||
    case '\'': return '\'';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define FMT_LONG 41  /* enough space to hold -2^127 in decimal, plus \0 */
 | 
			
		||||
#define FMT_ULONG 40 /* enough space to hold 2^128 - 1 in decimal, plus \0 */
 | 
			
		||||
#define FMT_8LONG 44 /* enough space to hold 2^128 - 1 in octal, plus \0 */
 | 
			
		||||
#define FMT_XLONG 33 /* enough space to hold 2^128 - 1 in hexadecimal, plus \0 */
 | 
			
		||||
 | 
			
		||||
size_t token_length(const char*, size_t, char delim);
 | 
			
		||||
size_t fmt_ulong(char*, uint32_t);
 | 
			
		||||
size_t scan_ushort(const char*, uint16_t*);
 | 
			
		||||
size_t fmt_longlong(char*, int64_t);
 | 
			
		||||
size_t fmt_ulonglong(char*, uint64_t);
 | 
			
		||||
size_t fmt_xlonglong(char*, uint64_t);
 | 
			
		||||
size_t fmt_xlonglong0(char*, uint64_t, size_t);
 | 
			
		||||
size_t fmt_8long(char* dest, uint32_t i);
 | 
			
		||||
size_t fmt_xlong(char* dest, uint32_t num);
 | 
			
		||||
size_t fmt_xlong0(char* dest, uint32_t num, size_t n);
 | 
			
		||||
size_t scan_longlong(const char*, int64_t*);
 | 
			
		||||
size_t scan_int(const char*, int32_t*);
 | 
			
		||||
size_t scan_uint(const char*, uint32_t*);
 | 
			
		||||
size_t scan_ulonglong(const char*, uint64_t*);
 | 
			
		||||
size_t scan_xlonglong(const char*, uint64_t*);
 | 
			
		||||
size_t scan_8longn(const char*, size_t, uint32_t* dest);
 | 
			
		||||
size_t scan_whitenskip(const char*, size_t);
 | 
			
		||||
size_t scan_nonwhitenskip(const char*, size_t);
 | 
			
		||||
size_t scan_line(const char*, size_t);
 | 
			
		||||
size_t scan_lineskip(const char*, size_t);
 | 
			
		||||
size_t scan_lineskip_escaped(const char*, size_t);
 | 
			
		||||
size_t scan_eolskip(const char*, size_t);
 | 
			
		||||
size_t utf8_strlen(const void*, size_t);
 | 
			
		||||
wchar_t* utf8_towcs(const char*);
 | 
			
		||||
char* utf8_fromwcs(const wchar_t*);
 | 
			
		||||
BOOL utf16_multiword(const void*);
 | 
			
		||||
int case_lowerc(int);
 | 
			
		||||
int case_starts(const char*, const char*);
 | 
			
		||||
int case_diffb(const void*, size_t, const void* T);
 | 
			
		||||
size_t case_findb(const void*, size_t, const void* what, size_t wlen);
 | 
			
		||||
size_t case_finds(const void*, const char*);
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
scan_fromhex(unsigned char c) {
 | 
			
		||||
  c -= '0';
 | 
			
		||||
 | 
			
		||||
  if(c <= 9)
 | 
			
		||||
    return c;
 | 
			
		||||
 | 
			
		||||
  c &= ~0x20;
 | 
			
		||||
  c -= 'A' - '0';
 | 
			
		||||
 | 
			
		||||
  if(c < 6)
 | 
			
		||||
    return c + 10;
 | 
			
		||||
 | 
			
		||||
  return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline size_t
 | 
			
		||||
scan_8long(const char* src, uint32_t* dest) {
 | 
			
		||||
  return scan_8longn(src, (size_t)-1, dest);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline size_t
 | 
			
		||||
utf8_charlen(const char* in, size_t len) {
 | 
			
		||||
  const uint8_t* next = (const void*)in;
 | 
			
		||||
  int r = unicode_from_utf8((const uint8_t*)in, len, &next);
 | 
			
		||||
  return r == -1 ? 0 : next - (const uint8_t*)in;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
utf8_charcode(const char* in, size_t len) {
 | 
			
		||||
  const uint8_t* next = (const void*)in;
 | 
			
		||||
  int r = unicode_from_utf8((const uint8_t*)in, len, &next);
 | 
			
		||||
  return next > in ? r : -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BOOL utf16_multiword(const void*);
 | 
			
		||||
 | 
			
		||||
ssize_t write_file(const char* file, const void* buf, size_t len);
 | 
			
		||||
ssize_t puts_file(const char* file, const char* s);
 | 
			
		||||
 | 
			
		||||
size_t u64toa(char*, uint64_t num, int base);
 | 
			
		||||
size_t i64toa(char*, int64_t num, int base);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @}
 | 
			
		||||
 */
 | 
			
		||||
#endif /* defined(CHAR_UTILS_H) */
 | 
			
		||||
							
								
								
									
										631
									
								
								src/quickjs/cutils.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										631
									
								
								src/quickjs/cutils.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,631 @@
 | 
			
		||||
/*
 | 
			
		||||
 * C utilities
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2017 Fabrice Bellard
 | 
			
		||||
 * Copyright (c) 2018 Charlie Gordon
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 * of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
 * in the Software without restriction, including without limitation the rights
 | 
			
		||||
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
 * copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
 * THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "cutils.h"
 | 
			
		||||
 | 
			
		||||
void pstrcpy(char *buf, int buf_size, const char *str)
 | 
			
		||||
{
 | 
			
		||||
    int c;
 | 
			
		||||
    char *q = buf;
 | 
			
		||||
 | 
			
		||||
    if (buf_size <= 0)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    for(;;) {
 | 
			
		||||
        c = *str++;
 | 
			
		||||
        if (c == 0 || q >= buf + buf_size - 1)
 | 
			
		||||
            break;
 | 
			
		||||
        *q++ = c;
 | 
			
		||||
    }
 | 
			
		||||
    *q = '\0';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* strcat and truncate. */
 | 
			
		||||
char *pstrcat(char *buf, int buf_size, const char *s)
 | 
			
		||||
{
 | 
			
		||||
    int len;
 | 
			
		||||
    len = strlen(buf);
 | 
			
		||||
    if (len < buf_size)
 | 
			
		||||
        pstrcpy(buf + len, buf_size - len, s);
 | 
			
		||||
    return buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int strstart(const char *str, const char *val, const char **ptr)
 | 
			
		||||
{
 | 
			
		||||
    const char *p, *q;
 | 
			
		||||
    p = str;
 | 
			
		||||
    q = val;
 | 
			
		||||
    while (*q != '\0') {
 | 
			
		||||
        if (*p != *q)
 | 
			
		||||
            return 0;
 | 
			
		||||
        p++;
 | 
			
		||||
        q++;
 | 
			
		||||
    }
 | 
			
		||||
    if (ptr)
 | 
			
		||||
        *ptr = p;
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int has_suffix(const char *str, const char *suffix)
 | 
			
		||||
{
 | 
			
		||||
    size_t len = strlen(str);
 | 
			
		||||
    size_t slen = strlen(suffix);
 | 
			
		||||
    return (len >= slen && !memcmp(str + len - slen, suffix, slen));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Dynamic buffer package */
 | 
			
		||||
 | 
			
		||||
static void *dbuf_default_realloc(void *opaque, void *ptr, size_t size)
 | 
			
		||||
{
 | 
			
		||||
    return realloc(ptr, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dbuf_init2(DynBuf *s, void *opaque, DynBufReallocFunc *realloc_func)
 | 
			
		||||
{
 | 
			
		||||
    memset(s, 0, sizeof(*s));
 | 
			
		||||
    if (!realloc_func)
 | 
			
		||||
        realloc_func = dbuf_default_realloc;
 | 
			
		||||
    s->opaque = opaque;
 | 
			
		||||
    s->realloc_func = realloc_func;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dbuf_init(DynBuf *s)
 | 
			
		||||
{
 | 
			
		||||
    dbuf_init2(s, NULL, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* return < 0 if error */
 | 
			
		||||
int dbuf_realloc(DynBuf *s, size_t new_size)
 | 
			
		||||
{
 | 
			
		||||
    size_t size;
 | 
			
		||||
    uint8_t *new_buf;
 | 
			
		||||
    if (new_size > s->allocated_size) {
 | 
			
		||||
        if (s->error)
 | 
			
		||||
            return -1;
 | 
			
		||||
        size = s->allocated_size * 3 / 2;
 | 
			
		||||
        if (size > new_size)
 | 
			
		||||
            new_size = size;
 | 
			
		||||
        new_buf = s->realloc_func(s->opaque, s->buf, new_size);
 | 
			
		||||
        if (!new_buf) {
 | 
			
		||||
            s->error = TRUE;
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
        s->buf = new_buf;
 | 
			
		||||
        s->allocated_size = new_size;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dbuf_write(DynBuf *s, size_t offset, const uint8_t *data, size_t len)
 | 
			
		||||
{
 | 
			
		||||
    size_t end;
 | 
			
		||||
    end = offset + len;
 | 
			
		||||
    if (dbuf_realloc(s, end))
 | 
			
		||||
        return -1;
 | 
			
		||||
    memcpy(s->buf + offset, data, len);
 | 
			
		||||
    if (end > s->size)
 | 
			
		||||
        s->size = end;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dbuf_put(DynBuf *s, const uint8_t *data, size_t len)
 | 
			
		||||
{
 | 
			
		||||
    if (unlikely((s->size + len) > s->allocated_size)) {
 | 
			
		||||
        if (dbuf_realloc(s, s->size + len))
 | 
			
		||||
            return -1;
 | 
			
		||||
    }
 | 
			
		||||
    memcpy_no_ub(s->buf + s->size, data, len);
 | 
			
		||||
    s->size += len;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dbuf_put_self(DynBuf *s, size_t offset, size_t len)
 | 
			
		||||
{
 | 
			
		||||
    if (unlikely((s->size + len) > s->allocated_size)) {
 | 
			
		||||
        if (dbuf_realloc(s, s->size + len))
 | 
			
		||||
            return -1;
 | 
			
		||||
    }
 | 
			
		||||
    memcpy(s->buf + s->size, s->buf + offset, len);
 | 
			
		||||
    s->size += len;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dbuf_putc(DynBuf *s, uint8_t c)
 | 
			
		||||
{
 | 
			
		||||
    return dbuf_put(s, &c, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dbuf_putstr(DynBuf *s, const char *str)
 | 
			
		||||
{
 | 
			
		||||
    return dbuf_put(s, (const uint8_t *)str, strlen(str));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s,
 | 
			
		||||
                                                      const char *fmt, ...)
 | 
			
		||||
{
 | 
			
		||||
    va_list ap;
 | 
			
		||||
    char buf[128];
 | 
			
		||||
    int len;
 | 
			
		||||
 | 
			
		||||
    va_start(ap, fmt);
 | 
			
		||||
    len = vsnprintf(buf, sizeof(buf), fmt, ap);
 | 
			
		||||
    va_end(ap);
 | 
			
		||||
    if (len < sizeof(buf)) {
 | 
			
		||||
        /* fast case */
 | 
			
		||||
        return dbuf_put(s, (uint8_t *)buf, len);
 | 
			
		||||
    } else {
 | 
			
		||||
        if (dbuf_realloc(s, s->size + len + 1))
 | 
			
		||||
            return -1;
 | 
			
		||||
        va_start(ap, fmt);
 | 
			
		||||
        vsnprintf((char *)(s->buf + s->size), s->allocated_size - s->size,
 | 
			
		||||
                  fmt, ap);
 | 
			
		||||
        va_end(ap);
 | 
			
		||||
        s->size += len;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dbuf_free(DynBuf *s)
 | 
			
		||||
{
 | 
			
		||||
    /* we test s->buf as a fail safe to avoid crashing if dbuf_free()
 | 
			
		||||
       is called twice */
 | 
			
		||||
    if (s->buf) {
 | 
			
		||||
        s->realloc_func(s->opaque, s->buf, 0);
 | 
			
		||||
    }
 | 
			
		||||
    memset(s, 0, sizeof(*s));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Note: at most 31 bits are encoded. At most UTF8_CHAR_LEN_MAX bytes
 | 
			
		||||
   are output. */
 | 
			
		||||
int unicode_to_utf8(uint8_t *buf, unsigned int c)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t *q = buf;
 | 
			
		||||
 | 
			
		||||
    if (c < 0x80) {
 | 
			
		||||
        *q++ = c;
 | 
			
		||||
    } else {
 | 
			
		||||
        if (c < 0x800) {
 | 
			
		||||
            *q++ = (c >> 6) | 0xc0;
 | 
			
		||||
        } else {
 | 
			
		||||
            if (c < 0x10000) {
 | 
			
		||||
                *q++ = (c >> 12) | 0xe0;
 | 
			
		||||
            } else {
 | 
			
		||||
                if (c < 0x00200000) {
 | 
			
		||||
                    *q++ = (c >> 18) | 0xf0;
 | 
			
		||||
                } else {
 | 
			
		||||
                    if (c < 0x04000000) {
 | 
			
		||||
                        *q++ = (c >> 24) | 0xf8;
 | 
			
		||||
                    } else if (c < 0x80000000) {
 | 
			
		||||
                        *q++ = (c >> 30) | 0xfc;
 | 
			
		||||
                        *q++ = ((c >> 24) & 0x3f) | 0x80;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        return 0;
 | 
			
		||||
                    }
 | 
			
		||||
                    *q++ = ((c >> 18) & 0x3f) | 0x80;
 | 
			
		||||
                }
 | 
			
		||||
                *q++ = ((c >> 12) & 0x3f) | 0x80;
 | 
			
		||||
            }
 | 
			
		||||
            *q++ = ((c >> 6) & 0x3f) | 0x80;
 | 
			
		||||
        }
 | 
			
		||||
        *q++ = (c & 0x3f) | 0x80;
 | 
			
		||||
    }
 | 
			
		||||
    return q - buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const unsigned int utf8_min_code[5] = {
 | 
			
		||||
    0x80, 0x800, 0x10000, 0x00200000, 0x04000000,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const unsigned char utf8_first_code_mask[5] = {
 | 
			
		||||
    0x1f, 0xf, 0x7, 0x3, 0x1,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* return -1 if error. *pp is not updated in this case. max_len must
 | 
			
		||||
   be >= 1. The maximum length for a UTF8 byte sequence is 6 bytes. */
 | 
			
		||||
int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp)
 | 
			
		||||
{
 | 
			
		||||
    int l, c, b, i;
 | 
			
		||||
 | 
			
		||||
    c = *p++;
 | 
			
		||||
    if (c < 0x80) {
 | 
			
		||||
        *pp = p;
 | 
			
		||||
        return c;
 | 
			
		||||
    }
 | 
			
		||||
    switch(c) {
 | 
			
		||||
    case 0xc0: case 0xc1: case 0xc2: case 0xc3:
 | 
			
		||||
    case 0xc4: case 0xc5: case 0xc6: case 0xc7:
 | 
			
		||||
    case 0xc8: case 0xc9: case 0xca: case 0xcb:
 | 
			
		||||
    case 0xcc: case 0xcd: case 0xce: case 0xcf:
 | 
			
		||||
    case 0xd0: case 0xd1: case 0xd2: case 0xd3:
 | 
			
		||||
    case 0xd4: case 0xd5: case 0xd6: case 0xd7:
 | 
			
		||||
    case 0xd8: case 0xd9: case 0xda: case 0xdb:
 | 
			
		||||
    case 0xdc: case 0xdd: case 0xde: case 0xdf:
 | 
			
		||||
        l = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0xe0: case 0xe1: case 0xe2: case 0xe3:
 | 
			
		||||
    case 0xe4: case 0xe5: case 0xe6: case 0xe7:
 | 
			
		||||
    case 0xe8: case 0xe9: case 0xea: case 0xeb:
 | 
			
		||||
    case 0xec: case 0xed: case 0xee: case 0xef:
 | 
			
		||||
        l = 2;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0xf0: case 0xf1: case 0xf2: case 0xf3:
 | 
			
		||||
    case 0xf4: case 0xf5: case 0xf6: case 0xf7:
 | 
			
		||||
        l = 3;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0xf8: case 0xf9: case 0xfa: case 0xfb:
 | 
			
		||||
        l = 4;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0xfc: case 0xfd:
 | 
			
		||||
        l = 5;
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
    /* check that we have enough characters */
 | 
			
		||||
    if (l > (max_len - 1))
 | 
			
		||||
        return -1;
 | 
			
		||||
    c &= utf8_first_code_mask[l - 1];
 | 
			
		||||
    for(i = 0; i < l; i++) {
 | 
			
		||||
        b = *p++;
 | 
			
		||||
        if (b < 0x80 || b >= 0xc0)
 | 
			
		||||
            return -1;
 | 
			
		||||
        c = (c << 6) | (b & 0x3f);
 | 
			
		||||
    }
 | 
			
		||||
    if (c < utf8_min_code[l - 1])
 | 
			
		||||
        return -1;
 | 
			
		||||
    *pp = p;
 | 
			
		||||
    return c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
 | 
			
		||||
#if defined(EMSCRIPTEN) || defined(__ANDROID__)
 | 
			
		||||
 | 
			
		||||
static void *rqsort_arg;
 | 
			
		||||
static int (*rqsort_cmp)(const void *, const void *, void *);
 | 
			
		||||
 | 
			
		||||
static int rqsort_cmp2(const void *p1, const void *p2)
 | 
			
		||||
{
 | 
			
		||||
    return rqsort_cmp(p1, p2, rqsort_arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* not reentrant, but not needed with emscripten */
 | 
			
		||||
void rqsort(void *base, size_t nmemb, size_t size,
 | 
			
		||||
            int (*cmp)(const void *, const void *, void *),
 | 
			
		||||
            void *arg)
 | 
			
		||||
{
 | 
			
		||||
    rqsort_arg = arg;
 | 
			
		||||
    rqsort_cmp = cmp;
 | 
			
		||||
    qsort(base, nmemb, size, rqsort_cmp2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
typedef void (*exchange_f)(void *a, void *b, size_t size);
 | 
			
		||||
typedef int (*cmp_f)(const void *, const void *, void *opaque);
 | 
			
		||||
 | 
			
		||||
static void exchange_bytes(void *a, void *b, size_t size) {
 | 
			
		||||
    uint8_t *ap = (uint8_t *)a;
 | 
			
		||||
    uint8_t *bp = (uint8_t *)b;
 | 
			
		||||
 | 
			
		||||
    while (size-- != 0) {
 | 
			
		||||
        uint8_t t = *ap;
 | 
			
		||||
        *ap++ = *bp;
 | 
			
		||||
        *bp++ = t;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void exchange_one_byte(void *a, void *b, size_t size) {
 | 
			
		||||
    uint8_t *ap = (uint8_t *)a;
 | 
			
		||||
    uint8_t *bp = (uint8_t *)b;
 | 
			
		||||
    uint8_t t = *ap;
 | 
			
		||||
    *ap = *bp;
 | 
			
		||||
    *bp = t;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void exchange_int16s(void *a, void *b, size_t size) {
 | 
			
		||||
    uint16_t *ap = (uint16_t *)a;
 | 
			
		||||
    uint16_t *bp = (uint16_t *)b;
 | 
			
		||||
 | 
			
		||||
    for (size /= sizeof(uint16_t); size-- != 0;) {
 | 
			
		||||
        uint16_t t = *ap;
 | 
			
		||||
        *ap++ = *bp;
 | 
			
		||||
        *bp++ = t;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void exchange_one_int16(void *a, void *b, size_t size) {
 | 
			
		||||
    uint16_t *ap = (uint16_t *)a;
 | 
			
		||||
    uint16_t *bp = (uint16_t *)b;
 | 
			
		||||
    uint16_t t = *ap;
 | 
			
		||||
    *ap = *bp;
 | 
			
		||||
    *bp = t;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void exchange_int32s(void *a, void *b, size_t size) {
 | 
			
		||||
    uint32_t *ap = (uint32_t *)a;
 | 
			
		||||
    uint32_t *bp = (uint32_t *)b;
 | 
			
		||||
 | 
			
		||||
    for (size /= sizeof(uint32_t); size-- != 0;) {
 | 
			
		||||
        uint32_t t = *ap;
 | 
			
		||||
        *ap++ = *bp;
 | 
			
		||||
        *bp++ = t;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void exchange_one_int32(void *a, void *b, size_t size) {
 | 
			
		||||
    uint32_t *ap = (uint32_t *)a;
 | 
			
		||||
    uint32_t *bp = (uint32_t *)b;
 | 
			
		||||
    uint32_t t = *ap;
 | 
			
		||||
    *ap = *bp;
 | 
			
		||||
    *bp = t;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void exchange_int64s(void *a, void *b, size_t size) {
 | 
			
		||||
    uint64_t *ap = (uint64_t *)a;
 | 
			
		||||
    uint64_t *bp = (uint64_t *)b;
 | 
			
		||||
 | 
			
		||||
    for (size /= sizeof(uint64_t); size-- != 0;) {
 | 
			
		||||
        uint64_t t = *ap;
 | 
			
		||||
        *ap++ = *bp;
 | 
			
		||||
        *bp++ = t;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void exchange_one_int64(void *a, void *b, size_t size) {
 | 
			
		||||
    uint64_t *ap = (uint64_t *)a;
 | 
			
		||||
    uint64_t *bp = (uint64_t *)b;
 | 
			
		||||
    uint64_t t = *ap;
 | 
			
		||||
    *ap = *bp;
 | 
			
		||||
    *bp = t;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void exchange_int128s(void *a, void *b, size_t size) {
 | 
			
		||||
    uint64_t *ap = (uint64_t *)a;
 | 
			
		||||
    uint64_t *bp = (uint64_t *)b;
 | 
			
		||||
 | 
			
		||||
    for (size /= sizeof(uint64_t) * 2; size-- != 0; ap += 2, bp += 2) {
 | 
			
		||||
        uint64_t t = ap[0];
 | 
			
		||||
        uint64_t u = ap[1];
 | 
			
		||||
        ap[0] = bp[0];
 | 
			
		||||
        ap[1] = bp[1];
 | 
			
		||||
        bp[0] = t;
 | 
			
		||||
        bp[1] = u;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void exchange_one_int128(void *a, void *b, size_t size) {
 | 
			
		||||
    uint64_t *ap = (uint64_t *)a;
 | 
			
		||||
    uint64_t *bp = (uint64_t *)b;
 | 
			
		||||
    uint64_t t = ap[0];
 | 
			
		||||
    uint64_t u = ap[1];
 | 
			
		||||
    ap[0] = bp[0];
 | 
			
		||||
    ap[1] = bp[1];
 | 
			
		||||
    bp[0] = t;
 | 
			
		||||
    bp[1] = u;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline exchange_f exchange_func(const void *base, size_t size) {
 | 
			
		||||
    switch (((uintptr_t)base | (uintptr_t)size) & 15) {
 | 
			
		||||
    case 0:
 | 
			
		||||
        if (size == sizeof(uint64_t) * 2)
 | 
			
		||||
            return exchange_one_int128;
 | 
			
		||||
        else
 | 
			
		||||
            return exchange_int128s;
 | 
			
		||||
    case 8:
 | 
			
		||||
        if (size == sizeof(uint64_t))
 | 
			
		||||
            return exchange_one_int64;
 | 
			
		||||
        else
 | 
			
		||||
            return exchange_int64s;
 | 
			
		||||
    case 4:
 | 
			
		||||
    case 12:
 | 
			
		||||
        if (size == sizeof(uint32_t))
 | 
			
		||||
            return exchange_one_int32;
 | 
			
		||||
        else
 | 
			
		||||
            return exchange_int32s;
 | 
			
		||||
    case 2:
 | 
			
		||||
    case 6:
 | 
			
		||||
    case 10:
 | 
			
		||||
    case 14:
 | 
			
		||||
        if (size == sizeof(uint16_t))
 | 
			
		||||
            return exchange_one_int16;
 | 
			
		||||
        else
 | 
			
		||||
            return exchange_int16s;
 | 
			
		||||
    default:
 | 
			
		||||
        if (size == 1)
 | 
			
		||||
            return exchange_one_byte;
 | 
			
		||||
        else
 | 
			
		||||
            return exchange_bytes;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void heapsortx(void *base, size_t nmemb, size_t size, cmp_f cmp, void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t *basep = (uint8_t *)base;
 | 
			
		||||
    size_t i, n, c, r;
 | 
			
		||||
    exchange_f swap = exchange_func(base, size);
 | 
			
		||||
 | 
			
		||||
    if (nmemb > 1) {
 | 
			
		||||
        i = (nmemb / 2) * size;
 | 
			
		||||
        n = nmemb * size;
 | 
			
		||||
 | 
			
		||||
        while (i > 0) {
 | 
			
		||||
            i -= size;
 | 
			
		||||
            for (r = i; (c = r * 2 + size) < n; r = c) {
 | 
			
		||||
                if (c < n - size && cmp(basep + c, basep + c + size, opaque) <= 0)
 | 
			
		||||
                    c += size;
 | 
			
		||||
                if (cmp(basep + r, basep + c, opaque) > 0)
 | 
			
		||||
                    break;
 | 
			
		||||
                swap(basep + r, basep + c, size);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        for (i = n - size; i > 0; i -= size) {
 | 
			
		||||
            swap(basep, basep + i, size);
 | 
			
		||||
 | 
			
		||||
            for (r = 0; (c = r * 2 + size) < i; r = c) {
 | 
			
		||||
                if (c < i - size && cmp(basep + c, basep + c + size, opaque) <= 0)
 | 
			
		||||
                    c += size;
 | 
			
		||||
                if (cmp(basep + r, basep + c, opaque) > 0)
 | 
			
		||||
                    break;
 | 
			
		||||
                swap(basep + r, basep + c, size);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void *med3(void *a, void *b, void *c, cmp_f cmp, void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    return cmp(a, b, opaque) < 0 ?
 | 
			
		||||
        (cmp(b, c, opaque) < 0 ? b : (cmp(a, c, opaque) < 0 ? c : a )) :
 | 
			
		||||
        (cmp(b, c, opaque) > 0 ? b : (cmp(a, c, opaque) < 0 ? a : c ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* pointer based version with local stack and insertion sort threshhold */
 | 
			
		||||
void rqsort(void *base, size_t nmemb, size_t size, cmp_f cmp, void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    struct { uint8_t *base; size_t count; int depth; } stack[50], *sp = stack;
 | 
			
		||||
    uint8_t *ptr, *pi, *pj, *plt, *pgt, *top, *m;
 | 
			
		||||
    size_t m4, i, lt, gt, span, span2;
 | 
			
		||||
    int c, depth;
 | 
			
		||||
    exchange_f swap = exchange_func(base, size);
 | 
			
		||||
    exchange_f swap_block = exchange_func(base, size | 128);
 | 
			
		||||
 | 
			
		||||
    if (nmemb < 2 || size <= 0)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    sp->base = (uint8_t *)base;
 | 
			
		||||
    sp->count = nmemb;
 | 
			
		||||
    sp->depth = 0;
 | 
			
		||||
    sp++;
 | 
			
		||||
 | 
			
		||||
    while (sp > stack) {
 | 
			
		||||
        sp--;
 | 
			
		||||
        ptr = sp->base;
 | 
			
		||||
        nmemb = sp->count;
 | 
			
		||||
        depth = sp->depth;
 | 
			
		||||
 | 
			
		||||
        while (nmemb > 6) {
 | 
			
		||||
            if (++depth > 50) {
 | 
			
		||||
                /* depth check to ensure worst case logarithmic time */
 | 
			
		||||
                heapsortx(ptr, nmemb, size, cmp, opaque);
 | 
			
		||||
                nmemb = 0;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            /* select median of 3 from 1/4, 1/2, 3/4 positions */
 | 
			
		||||
            /* should use median of 5 or 9? */
 | 
			
		||||
            m4 = (nmemb >> 2) * size;
 | 
			
		||||
            m = med3(ptr + m4, ptr + 2 * m4, ptr + 3 * m4, cmp, opaque);
 | 
			
		||||
            swap(ptr, m, size);  /* move the pivot to the start or the array */
 | 
			
		||||
            i = lt = 1;
 | 
			
		||||
            pi = plt = ptr + size;
 | 
			
		||||
            gt = nmemb;
 | 
			
		||||
            pj = pgt = top = ptr + nmemb * size;
 | 
			
		||||
            for (;;) {
 | 
			
		||||
                while (pi < pj && (c = cmp(ptr, pi, opaque)) >= 0) {
 | 
			
		||||
                    if (c == 0) {
 | 
			
		||||
                        swap(plt, pi, size);
 | 
			
		||||
                        lt++;
 | 
			
		||||
                        plt += size;
 | 
			
		||||
                    }
 | 
			
		||||
                    i++;
 | 
			
		||||
                    pi += size;
 | 
			
		||||
                }
 | 
			
		||||
                while (pi < (pj -= size) && (c = cmp(ptr, pj, opaque)) <= 0) {
 | 
			
		||||
                    if (c == 0) {
 | 
			
		||||
                        gt--;
 | 
			
		||||
                        pgt -= size;
 | 
			
		||||
                        swap(pgt, pj, size);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (pi >= pj)
 | 
			
		||||
                    break;
 | 
			
		||||
                swap(pi, pj, size);
 | 
			
		||||
                i++;
 | 
			
		||||
                pi += size;
 | 
			
		||||
            }
 | 
			
		||||
            /* array has 4 parts:
 | 
			
		||||
             * from 0 to lt excluded: elements identical to pivot
 | 
			
		||||
             * from lt to pi excluded: elements smaller than pivot
 | 
			
		||||
             * from pi to gt excluded: elements greater than pivot
 | 
			
		||||
             * from gt to n excluded: elements identical to pivot
 | 
			
		||||
             */
 | 
			
		||||
            /* move elements identical to pivot in the middle of the array: */
 | 
			
		||||
            /* swap values in ranges [0..lt[ and [i-lt..i[
 | 
			
		||||
               swapping the smallest span between lt and i-lt is sufficient
 | 
			
		||||
             */
 | 
			
		||||
            span = plt - ptr;
 | 
			
		||||
            span2 = pi - plt;
 | 
			
		||||
            lt = i - lt;
 | 
			
		||||
            if (span > span2)
 | 
			
		||||
                span = span2;
 | 
			
		||||
            swap_block(ptr, pi - span, span);
 | 
			
		||||
            /* swap values in ranges [gt..top[ and [i..top-(top-gt)[
 | 
			
		||||
               swapping the smallest span between top-gt and gt-i is sufficient
 | 
			
		||||
             */
 | 
			
		||||
            span = top - pgt;
 | 
			
		||||
            span2 = pgt - pi;
 | 
			
		||||
            pgt = top - span2;
 | 
			
		||||
            gt = nmemb - (gt - i);
 | 
			
		||||
            if (span > span2)
 | 
			
		||||
                span = span2;
 | 
			
		||||
            swap_block(pi, top - span, span);
 | 
			
		||||
 | 
			
		||||
            /* now array has 3 parts:
 | 
			
		||||
             * from 0 to lt excluded: elements smaller than pivot
 | 
			
		||||
             * from lt to gt excluded: elements identical to pivot
 | 
			
		||||
             * from gt to n excluded: elements greater than pivot
 | 
			
		||||
             */
 | 
			
		||||
            /* stack the larger segment and keep processing the smaller one
 | 
			
		||||
               to minimize stack use for pathological distributions */
 | 
			
		||||
            if (lt > nmemb - gt) {
 | 
			
		||||
                sp->base = ptr;
 | 
			
		||||
                sp->count = lt;
 | 
			
		||||
                sp->depth = depth;
 | 
			
		||||
                sp++;
 | 
			
		||||
                ptr = pgt;
 | 
			
		||||
                nmemb -= gt;
 | 
			
		||||
            } else {
 | 
			
		||||
                sp->base = pgt;
 | 
			
		||||
                sp->count = nmemb - gt;
 | 
			
		||||
                sp->depth = depth;
 | 
			
		||||
                sp++;
 | 
			
		||||
                nmemb = lt;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        /* Use insertion sort for small fragments */
 | 
			
		||||
        for (pi = ptr + size, top = ptr + nmemb * size; pi < top; pi += size) {
 | 
			
		||||
            for (pj = pi; pj > ptr && cmp(pj - size, pj, opaque) > 0; pj -= size)
 | 
			
		||||
                swap(pj, pj - size, size);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										341
									
								
								src/quickjs/cutils.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										341
									
								
								src/quickjs/cutils.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,341 @@
 | 
			
		||||
/*
 | 
			
		||||
 * C utilities
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2017 Fabrice Bellard
 | 
			
		||||
 * Copyright (c) 2018 Charlie Gordon
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 * of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
 * in the Software without restriction, including without limitation the rights
 | 
			
		||||
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
 * copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
 * THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef CUTILS_H
 | 
			
		||||
#define CUTILS_H
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
 | 
			
		||||
#define likely(x)       __builtin_expect(!!(x), 1)
 | 
			
		||||
#define unlikely(x)     __builtin_expect(!!(x), 0)
 | 
			
		||||
#define force_inline inline __attribute__((always_inline))
 | 
			
		||||
#define no_inline __attribute__((noinline))
 | 
			
		||||
#define __maybe_unused __attribute__((unused))
 | 
			
		||||
 | 
			
		||||
#define xglue(x, y) x ## y
 | 
			
		||||
#define glue(x, y) xglue(x, y)
 | 
			
		||||
#define stringify(s)    tostring(s)
 | 
			
		||||
#define tostring(s)     #s
 | 
			
		||||
 | 
			
		||||
#ifndef offsetof
 | 
			
		||||
#define offsetof(type, field) ((size_t) &((type *)0)->field)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef countof
 | 
			
		||||
#define countof(x) (sizeof(x) / sizeof((x)[0]))
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef container_of
 | 
			
		||||
/* return the pointer of type 'type *' containing 'ptr' as field 'member' */
 | 
			
		||||
#define container_of(ptr, type, member) ((type *)((uint8_t *)(ptr) - offsetof(type, member)))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef int BOOL;
 | 
			
		||||
 | 
			
		||||
#ifndef FALSE
 | 
			
		||||
enum {
 | 
			
		||||
    FALSE = 0,
 | 
			
		||||
    TRUE = 1,
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void pstrcpy(char *buf, int buf_size, const char *str);
 | 
			
		||||
char *pstrcat(char *buf, int buf_size, const char *s);
 | 
			
		||||
int strstart(const char *str, const char *val, const char **ptr);
 | 
			
		||||
int has_suffix(const char *str, const char *suffix);
 | 
			
		||||
 | 
			
		||||
/* Prevent UB when n == 0 and (src == NULL or dest == NULL) */
 | 
			
		||||
static inline void memcpy_no_ub(void *dest, const void *src, size_t n) {
 | 
			
		||||
    if (n)
 | 
			
		||||
        memcpy(dest, src, n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int max_int(int a, int b)
 | 
			
		||||
{
 | 
			
		||||
    if (a > b)
 | 
			
		||||
        return a;
 | 
			
		||||
    else
 | 
			
		||||
        return b;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int min_int(int a, int b)
 | 
			
		||||
{
 | 
			
		||||
    if (a < b)
 | 
			
		||||
        return a;
 | 
			
		||||
    else
 | 
			
		||||
        return b;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline uint32_t max_uint32(uint32_t a, uint32_t b)
 | 
			
		||||
{
 | 
			
		||||
    if (a > b)
 | 
			
		||||
        return a;
 | 
			
		||||
    else
 | 
			
		||||
        return b;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline uint32_t min_uint32(uint32_t a, uint32_t b)
 | 
			
		||||
{
 | 
			
		||||
    if (a < b)
 | 
			
		||||
        return a;
 | 
			
		||||
    else
 | 
			
		||||
        return b;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int64_t max_int64(int64_t a, int64_t b)
 | 
			
		||||
{
 | 
			
		||||
    if (a > b)
 | 
			
		||||
        return a;
 | 
			
		||||
    else
 | 
			
		||||
        return b;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int64_t min_int64(int64_t a, int64_t b)
 | 
			
		||||
{
 | 
			
		||||
    if (a < b)
 | 
			
		||||
        return a;
 | 
			
		||||
    else
 | 
			
		||||
        return b;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* WARNING: undefined if a = 0 */
 | 
			
		||||
static inline int clz32(unsigned int a)
 | 
			
		||||
{
 | 
			
		||||
    return __builtin_clz(a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* WARNING: undefined if a = 0 */
 | 
			
		||||
static inline int clz64(uint64_t a)
 | 
			
		||||
{
 | 
			
		||||
    return __builtin_clzll(a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* WARNING: undefined if a = 0 */
 | 
			
		||||
static inline int ctz32(unsigned int a)
 | 
			
		||||
{
 | 
			
		||||
    return __builtin_ctz(a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* WARNING: undefined if a = 0 */
 | 
			
		||||
static inline int ctz64(uint64_t a)
 | 
			
		||||
{
 | 
			
		||||
    return __builtin_ctzll(a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct __attribute__((packed)) packed_u64 {
 | 
			
		||||
    uint64_t v;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct __attribute__((packed)) packed_u32 {
 | 
			
		||||
    uint32_t v;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct __attribute__((packed)) packed_u16 {
 | 
			
		||||
    uint16_t v;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static inline uint64_t get_u64(const uint8_t *tab)
 | 
			
		||||
{
 | 
			
		||||
    return ((const struct packed_u64 *)tab)->v;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int64_t get_i64(const uint8_t *tab)
 | 
			
		||||
{
 | 
			
		||||
    return (int64_t)((const struct packed_u64 *)tab)->v;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void put_u64(uint8_t *tab, uint64_t val)
 | 
			
		||||
{
 | 
			
		||||
    ((struct packed_u64 *)tab)->v = val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline uint32_t get_u32(const uint8_t *tab)
 | 
			
		||||
{
 | 
			
		||||
    return ((const struct packed_u32 *)tab)->v;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int32_t get_i32(const uint8_t *tab)
 | 
			
		||||
{
 | 
			
		||||
    return (int32_t)((const struct packed_u32 *)tab)->v;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void put_u32(uint8_t *tab, uint32_t val)
 | 
			
		||||
{
 | 
			
		||||
    ((struct packed_u32 *)tab)->v = val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline uint32_t get_u16(const uint8_t *tab)
 | 
			
		||||
{
 | 
			
		||||
    return ((const struct packed_u16 *)tab)->v;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int32_t get_i16(const uint8_t *tab)
 | 
			
		||||
{
 | 
			
		||||
    return (int16_t)((const struct packed_u16 *)tab)->v;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void put_u16(uint8_t *tab, uint16_t val)
 | 
			
		||||
{
 | 
			
		||||
    ((struct packed_u16 *)tab)->v = val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline uint32_t get_u8(const uint8_t *tab)
 | 
			
		||||
{
 | 
			
		||||
    return *tab;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int32_t get_i8(const uint8_t *tab)
 | 
			
		||||
{
 | 
			
		||||
    return (int8_t)*tab;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void put_u8(uint8_t *tab, uint8_t val)
 | 
			
		||||
{
 | 
			
		||||
    *tab = val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifndef bswap16
 | 
			
		||||
static inline uint16_t bswap16(uint16_t x)
 | 
			
		||||
{
 | 
			
		||||
    return (x >> 8) | (x << 8);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef bswap32
 | 
			
		||||
static inline uint32_t bswap32(uint32_t v)
 | 
			
		||||
{
 | 
			
		||||
    return ((v & 0xff000000) >> 24) | ((v & 0x00ff0000) >>  8) |
 | 
			
		||||
        ((v & 0x0000ff00) <<  8) | ((v & 0x000000ff) << 24);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef bswap64
 | 
			
		||||
static inline uint64_t bswap64(uint64_t v)
 | 
			
		||||
{
 | 
			
		||||
    return ((v & ((uint64_t)0xff << (7 * 8))) >> (7 * 8)) |
 | 
			
		||||
        ((v & ((uint64_t)0xff << (6 * 8))) >> (5 * 8)) |
 | 
			
		||||
        ((v & ((uint64_t)0xff << (5 * 8))) >> (3 * 8)) |
 | 
			
		||||
        ((v & ((uint64_t)0xff << (4 * 8))) >> (1 * 8)) |
 | 
			
		||||
        ((v & ((uint64_t)0xff << (3 * 8))) << (1 * 8)) |
 | 
			
		||||
        ((v & ((uint64_t)0xff << (2 * 8))) << (3 * 8)) |
 | 
			
		||||
        ((v & ((uint64_t)0xff << (1 * 8))) << (5 * 8)) |
 | 
			
		||||
        ((v & ((uint64_t)0xff << (0 * 8))) << (7 * 8));
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* XXX: should take an extra argument to pass slack information to the caller */
 | 
			
		||||
typedef void *DynBufReallocFunc(void *opaque, void *ptr, size_t size);
 | 
			
		||||
 | 
			
		||||
typedef struct DynBuf {
 | 
			
		||||
    uint8_t *buf;
 | 
			
		||||
    size_t size;
 | 
			
		||||
    size_t allocated_size;
 | 
			
		||||
    BOOL error; /* true if a memory allocation error occurred */
 | 
			
		||||
    DynBufReallocFunc *realloc_func;
 | 
			
		||||
    void *opaque; /* for realloc_func */
 | 
			
		||||
} DynBuf;
 | 
			
		||||
 | 
			
		||||
void dbuf_init(DynBuf *s);
 | 
			
		||||
void dbuf_init2(DynBuf *s, void *opaque, DynBufReallocFunc *realloc_func);
 | 
			
		||||
int dbuf_realloc(DynBuf *s, size_t new_size);
 | 
			
		||||
int dbuf_write(DynBuf *s, size_t offset, const uint8_t *data, size_t len);
 | 
			
		||||
int dbuf_put(DynBuf *s, const uint8_t *data, size_t len);
 | 
			
		||||
int dbuf_put_self(DynBuf *s, size_t offset, size_t len);
 | 
			
		||||
int dbuf_putc(DynBuf *s, uint8_t c);
 | 
			
		||||
int dbuf_putstr(DynBuf *s, const char *str);
 | 
			
		||||
static inline int dbuf_put_u16(DynBuf *s, uint16_t val)
 | 
			
		||||
{
 | 
			
		||||
    return dbuf_put(s, (uint8_t *)&val, 2);
 | 
			
		||||
}
 | 
			
		||||
static inline int dbuf_put_u32(DynBuf *s, uint32_t val)
 | 
			
		||||
{
 | 
			
		||||
    return dbuf_put(s, (uint8_t *)&val, 4);
 | 
			
		||||
}
 | 
			
		||||
static inline int dbuf_put_u64(DynBuf *s, uint64_t val)
 | 
			
		||||
{
 | 
			
		||||
    return dbuf_put(s, (uint8_t *)&val, 8);
 | 
			
		||||
}
 | 
			
		||||
int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s,
 | 
			
		||||
                                                      const char *fmt, ...);
 | 
			
		||||
void dbuf_free(DynBuf *s);
 | 
			
		||||
static inline BOOL dbuf_error(DynBuf *s) {
 | 
			
		||||
    return s->error;
 | 
			
		||||
}
 | 
			
		||||
static inline void dbuf_set_error(DynBuf *s)
 | 
			
		||||
{
 | 
			
		||||
    s->error = TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define UTF8_CHAR_LEN_MAX 6
 | 
			
		||||
 | 
			
		||||
int unicode_to_utf8(uint8_t *buf, unsigned int c);
 | 
			
		||||
int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp);
 | 
			
		||||
 | 
			
		||||
static inline BOOL is_surrogate(uint32_t c)
 | 
			
		||||
{
 | 
			
		||||
    return (c >> 11) == (0xD800 >> 11); // 0xD800-0xDFFF
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline BOOL is_hi_surrogate(uint32_t c)
 | 
			
		||||
{
 | 
			
		||||
    return (c >> 10) == (0xD800 >> 10); // 0xD800-0xDBFF
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline BOOL is_lo_surrogate(uint32_t c)
 | 
			
		||||
{
 | 
			
		||||
    return (c >> 10) == (0xDC00 >> 10); // 0xDC00-0xDFFF
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline uint32_t get_hi_surrogate(uint32_t c)
 | 
			
		||||
{
 | 
			
		||||
    return (c >> 10) - (0x10000 >> 10) + 0xD800;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline uint32_t get_lo_surrogate(uint32_t c)
 | 
			
		||||
{
 | 
			
		||||
    return (c & 0x3FF) | 0xDC00;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline uint32_t from_surrogate(uint32_t hi, uint32_t lo)
 | 
			
		||||
{
 | 
			
		||||
    return 0x10000 + 0x400 * (hi - 0xD800) + (lo - 0xDC00);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int from_hex(int c)
 | 
			
		||||
{
 | 
			
		||||
    if (c >= '0' && c <= '9')
 | 
			
		||||
        return c - '0';
 | 
			
		||||
    else if (c >= 'A' && c <= 'F')
 | 
			
		||||
        return c - 'A' + 10;
 | 
			
		||||
    else if (c >= 'a' && c <= 'f')
 | 
			
		||||
        return c - 'a' + 10;
 | 
			
		||||
    else
 | 
			
		||||
        return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void rqsort(void *base, size_t nmemb, size_t size,
 | 
			
		||||
            int (*cmp)(const void *, const void *, void *),
 | 
			
		||||
            void *arg);
 | 
			
		||||
 | 
			
		||||
#endif  /* CUTILS_H */
 | 
			
		||||
							
								
								
									
										483
									
								
								src/quickjs/debug.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										483
									
								
								src/quickjs/debug.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,483 @@
 | 
			
		||||
#define _IN_DEBUG_C 1
 | 
			
		||||
#include "debug.h"
 | 
			
		||||
#include <quickjs.h>
 | 
			
		||||
#include <list.h>
 | 
			
		||||
#include <cutils.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \addtogroup debug
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
struct alloc_block {
 | 
			
		||||
  struct list_head link;
 | 
			
		||||
  const char* file;
 | 
			
		||||
  int line;
 | 
			
		||||
  size_t size;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define ALLOC_BLOCK_SIZE sizeof(struct alloc_block)
 | 
			
		||||
#define ALLOC_BLOCK(p) (((struct alloc_block*)(p)) - 1)
 | 
			
		||||
#define ALLOC_PTR struct alloc_block*
 | 
			
		||||
 | 
			
		||||
#undef malloc
 | 
			
		||||
#undef calloc
 | 
			
		||||
#undef realloc
 | 
			
		||||
#undef strdup
 | 
			
		||||
#undef free
 | 
			
		||||
#undef js_malloc
 | 
			
		||||
#undef js_mallocz
 | 
			
		||||
#undef js_realloc
 | 
			
		||||
#undef js_strdup
 | 
			
		||||
#undef js_strndup
 | 
			
		||||
#undef js_free
 | 
			
		||||
#undef js_malloc_usable_size
 | 
			
		||||
#undef js_malloc_rt
 | 
			
		||||
#undef js_mallocz_rt
 | 
			
		||||
#undef js_realloc_rt
 | 
			
		||||
#undef js_free_rt
 | 
			
		||||
#undef js_malloc_usable_size_rt
 | 
			
		||||
 | 
			
		||||
thread_local struct list_head alloc_block_list = {0, 0};
 | 
			
		||||
 | 
			
		||||
static inline void
 | 
			
		||||
add_to_list(struct list_head* el, struct list_head* head) {
 | 
			
		||||
  if(alloc_block_list.prev == 0 && alloc_block_list.next == 0)
 | 
			
		||||
    init_list_head(&alloc_block_list);
 | 
			
		||||
 | 
			
		||||
  list_add_tail(el, head);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int64_t
 | 
			
		||||
check_pointer(void* p) {
 | 
			
		||||
  ALLOC_PTR ptr = ALLOC_BLOCK(p);
 | 
			
		||||
  struct list_head* link;
 | 
			
		||||
  int64_t ret = 0;
 | 
			
		||||
  list_for_each(link, &alloc_block_list) {
 | 
			
		||||
    if(link == &ptr->link)
 | 
			
		||||
      return ret;
 | 
			
		||||
    ret++;
 | 
			
		||||
  }
 | 
			
		||||
  // assert(0);
 | 
			
		||||
  return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
debug_malloc(size_t n, const char* file, int line) {
 | 
			
		||||
  ALLOC_PTR ptr;
 | 
			
		||||
 | 
			
		||||
  if((ptr = malloc(n + ALLOC_BLOCK_SIZE))) {
 | 
			
		||||
    ptr->file = file;
 | 
			
		||||
    ptr->line = line;
 | 
			
		||||
    ptr->size = n;
 | 
			
		||||
 | 
			
		||||
    add_to_list(&ptr->link, &alloc_block_list);
 | 
			
		||||
    return &ptr[1];
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
debug_calloc(size_t m, size_t n, const char* file, int line) {
 | 
			
		||||
  ALLOC_PTR ptr;
 | 
			
		||||
 | 
			
		||||
  m *= n;
 | 
			
		||||
  n = 1;
 | 
			
		||||
 | 
			
		||||
  if((ptr = calloc(m + ALLOC_BLOCK_SIZE, 1))) {
 | 
			
		||||
    ptr->file = file;
 | 
			
		||||
    ptr->line = line;
 | 
			
		||||
    ptr->size = n;
 | 
			
		||||
 | 
			
		||||
    add_to_list(&ptr->link, &alloc_block_list);
 | 
			
		||||
    return &ptr[1];
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
debug_realloc(void* p, size_t n, const char* file, int line) {
 | 
			
		||||
  ALLOC_PTR ptr;
 | 
			
		||||
 | 
			
		||||
  if(p) {
 | 
			
		||||
 | 
			
		||||
    check_pointer(p);
 | 
			
		||||
 | 
			
		||||
    ptr = ALLOC_BLOCK(p);
 | 
			
		||||
    list_del(&ptr->link);
 | 
			
		||||
 | 
			
		||||
    if(n == 0) {
 | 
			
		||||
      free(ptr);
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ptr = realloc(ptr, n + ALLOC_BLOCK_SIZE);
 | 
			
		||||
  } else {
 | 
			
		||||
    ptr = malloc(n + ALLOC_BLOCK_SIZE);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(ptr) {
 | 
			
		||||
    ptr->file = file;
 | 
			
		||||
    ptr->line = line;
 | 
			
		||||
    ptr->size = n;
 | 
			
		||||
 | 
			
		||||
    add_to_list(&ptr->link, &alloc_block_list);
 | 
			
		||||
    return &ptr[1];
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
debug_strdup(const char* s, const char* file, int line) {
 | 
			
		||||
  ALLOC_PTR ptr;
 | 
			
		||||
  size_t len = strlen(s);
 | 
			
		||||
 | 
			
		||||
  if((ptr = malloc(len + 1 + ALLOC_BLOCK_SIZE))) {
 | 
			
		||||
    ptr->file = file;
 | 
			
		||||
    ptr->line = line;
 | 
			
		||||
    ptr->size = len + 1;
 | 
			
		||||
 | 
			
		||||
    add_to_list(&ptr->link, &alloc_block_list);
 | 
			
		||||
 | 
			
		||||
    memcpy(&ptr[1], s, len + 1);
 | 
			
		||||
    return &ptr[1];
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
debug_free(void* p, const char* file, int line) {
 | 
			
		||||
  ALLOC_PTR ptr = ALLOC_BLOCK(p);
 | 
			
		||||
 | 
			
		||||
  list_del(&ptr->link);
 | 
			
		||||
 | 
			
		||||
  memset(ptr, 0xff, ALLOC_BLOCK_SIZE);
 | 
			
		||||
 | 
			
		||||
  free(ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
debug_js_malloc(JSContext* ctx, size_t n, const char* file, int line) {
 | 
			
		||||
  ALLOC_PTR ptr;
 | 
			
		||||
 | 
			
		||||
  if((ptr = js_malloc(ctx, n + ALLOC_BLOCK_SIZE))) {
 | 
			
		||||
    ptr->file = file;
 | 
			
		||||
    ptr->line = line;
 | 
			
		||||
    ptr->size = n;
 | 
			
		||||
 | 
			
		||||
    add_to_list(&ptr->link, &alloc_block_list);
 | 
			
		||||
    return &ptr[1];
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
debug_js_mallocz(JSContext* ctx, size_t n, const char* file, int line) {
 | 
			
		||||
  ALLOC_PTR ptr;
 | 
			
		||||
 | 
			
		||||
  if((ptr = js_mallocz(ctx, n + ALLOC_BLOCK_SIZE))) {
 | 
			
		||||
    ptr->file = file;
 | 
			
		||||
    ptr->line = line;
 | 
			
		||||
    ptr->size = n;
 | 
			
		||||
 | 
			
		||||
    add_to_list(&ptr->link, &alloc_block_list);
 | 
			
		||||
    return &ptr[1];
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
debug_js_realloc(JSContext* ctx, void* p, size_t n, const char* file, int line) {
 | 
			
		||||
  ALLOC_PTR ptr;
 | 
			
		||||
 | 
			
		||||
  if(p) {
 | 
			
		||||
 | 
			
		||||
    check_pointer(p);
 | 
			
		||||
 | 
			
		||||
    ptr = ALLOC_BLOCK(p);
 | 
			
		||||
    list_del(&ptr->link);
 | 
			
		||||
 | 
			
		||||
    if(n == 0) {
 | 
			
		||||
      js_free(ctx, ptr);
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ptr = js_realloc(ctx, ptr, n + ALLOC_BLOCK_SIZE);
 | 
			
		||||
  } else {
 | 
			
		||||
    ptr = js_malloc(ctx, n + ALLOC_BLOCK_SIZE);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(ptr) {
 | 
			
		||||
    ptr->file = file;
 | 
			
		||||
    ptr->line = line;
 | 
			
		||||
    ptr->size = n;
 | 
			
		||||
 | 
			
		||||
    add_to_list(&ptr->link, &alloc_block_list);
 | 
			
		||||
    return &ptr[1];
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
debug_js_realloc2(JSContext* ctx, void* p, size_t size, size_t* pslack, const char* file, int line) {
 | 
			
		||||
  void* ptr;
 | 
			
		||||
 | 
			
		||||
  if((ptr = debug_js_realloc(ctx, p, size, file, line))) {
 | 
			
		||||
    if(pslack) {
 | 
			
		||||
      size_t new_size = debug_js_malloc_usable_size(ctx, ptr, file, line);
 | 
			
		||||
      *pslack = (new_size > size) ? new_size - size : 0;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return ptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
debug_js_strdup(JSContext* ctx, const char* s, const char* file, int line) {
 | 
			
		||||
  ALLOC_PTR ptr;
 | 
			
		||||
  size_t len = strlen(s);
 | 
			
		||||
 | 
			
		||||
  if((ptr = js_malloc(ctx, len + 1 + ALLOC_BLOCK_SIZE))) {
 | 
			
		||||
    char* p = (char*)&ptr[1];
 | 
			
		||||
    ptr->file = file;
 | 
			
		||||
    ptr->line = line;
 | 
			
		||||
    ptr->size = len + 1;
 | 
			
		||||
 | 
			
		||||
    add_to_list(&ptr->link, &alloc_block_list);
 | 
			
		||||
 | 
			
		||||
    memcpy(p, s, len + 1);
 | 
			
		||||
    return p;
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
debug_js_strndup(JSContext* ctx, const char* s, size_t len, const char* file, int line) {
 | 
			
		||||
  ALLOC_PTR ptr;
 | 
			
		||||
 | 
			
		||||
  if((ptr = js_malloc(ctx, len + 1 + ALLOC_BLOCK_SIZE))) {
 | 
			
		||||
    char* p = (char*)&ptr[1];
 | 
			
		||||
    ptr->file = file;
 | 
			
		||||
    ptr->line = line;
 | 
			
		||||
    ptr->size = len + 1;
 | 
			
		||||
 | 
			
		||||
    add_to_list(&ptr->link, &alloc_block_list);
 | 
			
		||||
 | 
			
		||||
    memcpy(p, s, len);
 | 
			
		||||
    p[len] = '\0';
 | 
			
		||||
 | 
			
		||||
    return p;
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
debug_js_malloc_usable_size(JSContext* ctx, const void* p, const char* file, int line) {
 | 
			
		||||
  ALLOC_PTR ptr = ALLOC_BLOCK(p);
 | 
			
		||||
 | 
			
		||||
  return js_malloc_usable_size(ctx, ptr) - ALLOC_BLOCK_SIZE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
debug_js_free(JSContext* ctx, void* p, const char* file, int line) {
 | 
			
		||||
  ALLOC_PTR ptr;
 | 
			
		||||
 | 
			
		||||
  check_pointer(p);
 | 
			
		||||
  ptr = ALLOC_BLOCK(p);
 | 
			
		||||
  list_del(&ptr->link);
 | 
			
		||||
 | 
			
		||||
  memset(ptr, 0xff, ALLOC_BLOCK_SIZE);
 | 
			
		||||
 | 
			
		||||
  js_free(ctx, ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
debug_js_malloc_rt(JSRuntime* rt, size_t n, const char* file, int line) {
 | 
			
		||||
  ALLOC_PTR ptr;
 | 
			
		||||
 | 
			
		||||
  if((ptr = js_malloc_rt(rt, n + ALLOC_BLOCK_SIZE))) {
 | 
			
		||||
    ptr->file = file;
 | 
			
		||||
    ptr->line = line;
 | 
			
		||||
    ptr->size = n;
 | 
			
		||||
 | 
			
		||||
    add_to_list(&ptr->link, &alloc_block_list);
 | 
			
		||||
    return &ptr[1];
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
debug_js_mallocz_rt(JSRuntime* rt, size_t n, const char* file, int line) {
 | 
			
		||||
  ALLOC_PTR ptr;
 | 
			
		||||
 | 
			
		||||
  if((ptr = js_mallocz_rt(rt, n + ALLOC_BLOCK_SIZE))) {
 | 
			
		||||
    ptr->file = file;
 | 
			
		||||
    ptr->line = line;
 | 
			
		||||
    ptr->size = n;
 | 
			
		||||
 | 
			
		||||
    add_to_list(&ptr->link, &alloc_block_list);
 | 
			
		||||
    return &ptr[1];
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
debug_js_realloc_rt(JSRuntime* rt, void* p, size_t n, const char* file, int line) {
 | 
			
		||||
  ALLOC_PTR ptr;
 | 
			
		||||
 | 
			
		||||
  if(p) {
 | 
			
		||||
    check_pointer(p);
 | 
			
		||||
 | 
			
		||||
    ptr = ALLOC_BLOCK(p);
 | 
			
		||||
    list_del(&ptr->link);
 | 
			
		||||
    if(n == 0) {
 | 
			
		||||
      js_free_rt(rt, ptr);
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
    ptr = js_realloc_rt(rt, ptr, n + ALLOC_BLOCK_SIZE);
 | 
			
		||||
  } else {
 | 
			
		||||
    ptr = js_malloc_rt(rt, n + ALLOC_BLOCK_SIZE);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(ptr) {
 | 
			
		||||
    ptr->file = file;
 | 
			
		||||
    ptr->line = line;
 | 
			
		||||
    ptr->size = n;
 | 
			
		||||
 | 
			
		||||
    add_to_list(&ptr->link, &alloc_block_list);
 | 
			
		||||
    return &ptr[1];
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
debug_js_malloc_usable_size_rt(JSRuntime* rt, const void* p, const char* file, int line) {
 | 
			
		||||
  ALLOC_PTR ptr = ALLOC_BLOCK(p);
 | 
			
		||||
 | 
			
		||||
  return js_malloc_usable_size_rt(rt, ptr) - ALLOC_BLOCK_SIZE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
debug_js_free_rt(JSRuntime* rt, void* p, const char* file, int line) {
 | 
			
		||||
  ALLOC_PTR ptr;
 | 
			
		||||
  check_pointer(p);
 | 
			
		||||
 | 
			
		||||
  ptr = ALLOC_BLOCK(p);
 | 
			
		||||
 | 
			
		||||
  // printf("debug_js_free_rt %p\n", p);
 | 
			
		||||
 | 
			
		||||
  list_del(&ptr->link);
 | 
			
		||||
 | 
			
		||||
  memset(ptr, 0xff, ALLOC_BLOCK_SIZE);
 | 
			
		||||
 | 
			
		||||
  js_free_rt(rt, ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#undef malloc
 | 
			
		||||
#undef calloc
 | 
			
		||||
#undef realloc
 | 
			
		||||
#undef strdup
 | 
			
		||||
#undef free
 | 
			
		||||
#undef js_malloc
 | 
			
		||||
#undef js_mallocz
 | 
			
		||||
#undef js_realloc
 | 
			
		||||
#undef js_strdup
 | 
			
		||||
#undef js_strndup
 | 
			
		||||
#undef js_malloc_usable_size
 | 
			
		||||
#undef js_free
 | 
			
		||||
#undef js_malloc_rt
 | 
			
		||||
#undef js_mallocz_rt
 | 
			
		||||
#undef js_realloc_rt
 | 
			
		||||
#undef js_malloc_usable_size_rt
 | 
			
		||||
#undef js_free_rt
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
orig_malloc(size_t size) {
 | 
			
		||||
  return malloc(size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
orig_calloc(size_t nelem, size_t elemsz) {
 | 
			
		||||
  return calloc(nelem, elemsz);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
orig_realloc(void* ptr, size_t size) {
 | 
			
		||||
  return realloc(ptr, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
orig_strdup(const char* str) {
 | 
			
		||||
  return strdup(str);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
orig_free(void* ptr) {
 | 
			
		||||
  free(ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
orig_js_malloc(JSContext* ctx, size_t size) {
 | 
			
		||||
  return js_malloc(ctx, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
orig_js_mallocz(JSContext* ctx, size_t size) {
 | 
			
		||||
  return js_mallocz(ctx, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
orig_js_realloc(JSContext* ctx, void* p, size_t size) {
 | 
			
		||||
  return js_realloc(ctx, p, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
orig_js_strdup(JSContext* ctx, const char* str) {
 | 
			
		||||
  return js_strdup(ctx, str);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
orig_js_strndup(JSContext* ctx, const char* str, size_t size) {
 | 
			
		||||
  return js_strndup(ctx, str, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
orig_js_malloc_usable_size(JSContext* ctx, const void* p) {
 | 
			
		||||
  return js_malloc_usable_size(ctx, p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
orig_js_free(JSContext* ctx, void* p) {
 | 
			
		||||
  return js_free(ctx, p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
orig_js_malloc_rt(JSRuntime* rt, size_t size) {
 | 
			
		||||
  return js_malloc_rt(rt, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
orig_js_mallocz_rt(JSRuntime* rt, size_t size) {
 | 
			
		||||
  return js_mallocz_rt(rt, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
orig_js_realloc_rt(JSRuntime* rt, void* p, size_t size) {
 | 
			
		||||
  return js_realloc_rt(rt, p, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
orig_js_malloc_usable_size_rt(JSRuntime* rt, const void* p) {
 | 
			
		||||
  return js_malloc_usable_size_rt(rt, p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
orig_js_free_rt(JSRuntime* rt, void* p) {
 | 
			
		||||
  return js_free_rt(rt, p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @}
 | 
			
		||||
 */
 | 
			
		||||
							
								
								
									
										165
									
								
								src/quickjs/debug.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								src/quickjs/debug.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,165 @@
 | 
			
		||||
#ifndef DEBUG_H
 | 
			
		||||
#define DEBUG_H
 | 
			
		||||
 | 
			
		||||
#include <quickjs.h>
 | 
			
		||||
#include <cutils.h>
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
 | 
			
		||||
#ifndef QUICKJS_H
 | 
			
		||||
#error "quickjs.h not included"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \defgroup debug debug: Debugging helpers
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
extern thread_local struct list_head alloc_block_list;
 | 
			
		||||
 | 
			
		||||
int64_t check_pointer(void*);
 | 
			
		||||
void* debug_malloc(size_t, const char*, int);
 | 
			
		||||
void* debug_calloc(size_t, size_t, const char*, int line);
 | 
			
		||||
void* debug_realloc(void*, size_t, const char*, int line);
 | 
			
		||||
void* debug_strdup(const char*, const char*, int);
 | 
			
		||||
void debug_free(void*, const char*, int);
 | 
			
		||||
void* debug_js_malloc(JSContext*, size_t, const char*, int line);
 | 
			
		||||
void* debug_js_mallocz(JSContext*, size_t, const char*, int line);
 | 
			
		||||
void* debug_js_realloc(JSContext*, void*, size_t, const char* file, int line);
 | 
			
		||||
void* debug_js_realloc2(JSContext*, void*, size_t, size_t* pslack, const char* file, int line);
 | 
			
		||||
void* debug_js_strdup(JSContext*, const char*, const char*, int line);
 | 
			
		||||
void* debug_js_strndup(JSContext*, const char*, size_t, const char* file, int line);
 | 
			
		||||
size_t debug_js_malloc_usable_size(JSContext*, const void*, const char*, int line);
 | 
			
		||||
void debug_js_free(JSContext*, void*, const char*, int line);
 | 
			
		||||
void* debug_js_malloc_rt(JSRuntime*, size_t, const char*, int line);
 | 
			
		||||
void* debug_js_mallocz_rt(JSRuntime*, size_t, const char*, int line);
 | 
			
		||||
void* debug_js_realloc_rt(JSRuntime*, void*, size_t, const char* file, int line);
 | 
			
		||||
size_t debug_js_malloc_usable_size_rt(JSRuntime*, const void*, const char*, int line);
 | 
			
		||||
void debug_js_free_rt(JSRuntime*, void*, const char*, int line);
 | 
			
		||||
 | 
			
		||||
#if !defined(_IN_DEBUG_C)
 | 
			
		||||
 | 
			
		||||
#if defined(DEBUG_ALLOC)
 | 
			
		||||
#define malloc(size) debug_malloc(size, __FILE__, __LINE__)
 | 
			
		||||
#define calloc(nelem, size) debug_calloc(nelem, size, __FILE__, __LINE__)
 | 
			
		||||
#define realloc(ptr, size) debug_realloc(ptr, size, __FILE__, __LINE__)
 | 
			
		||||
#define strdup(str) debug_strdup(str, __FILE__, __LINE__)
 | 
			
		||||
#define free(ptr) debug_free(ptr, __FILE__, __LINE__)
 | 
			
		||||
#define js_malloc(ctx, size) debug_js_malloc(ctx, size, __FILE__, __LINE__)
 | 
			
		||||
#define js_mallocz(ctx, size) debug_js_mallocz(ctx, size, __FILE__, __LINE__)
 | 
			
		||||
#define js_realloc(ctx, ptr, size) debug_js_realloc(ctx, ptr, size, __FILE__, __LINE__)
 | 
			
		||||
#define js_strdup(ctx, str) debug_js_strdup(ctx, str, __FILE__, __LINE__)
 | 
			
		||||
#define js_strndup(ctx, str, len) debug_js_strndup(ctx, str, len, __FILE__, __LINE__)
 | 
			
		||||
#define js_free(ctx, ptr) debug_js_free(ctx, ptr, __FILE__, __LINE__)
 | 
			
		||||
#define js_malloc_usable_size(ctx, ptr) debug_js_malloc_usable_size(ctx, ptr, __FILE__, __LINE__)
 | 
			
		||||
#define js_malloc_rt(rt, size) debug_js_malloc_rt(rt, size, __FILE__, __LINE__)
 | 
			
		||||
#define js_mallocz_rt(rt, size) debug_js_mallocz_rt(rt, size, __FILE__, __LINE__)
 | 
			
		||||
#define js_realloc_rt(rt, ptr, size) debug_js_realloc_rt(rt, ptr, size, __FILE__, __LINE__)
 | 
			
		||||
#define js_malloc_usable_size_rt(rt, ptr) debug_js_malloc_usable_size_rt(rt, ptr, __FILE__, __LINE__)
 | 
			
		||||
#define js_free_rt(rt, ptr) debug_js_free_rt(rt, ptr, __FILE__, __LINE__)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_ALLOC
 | 
			
		||||
#define realloc_helper(name) \
 | 
			
		||||
  void* name(void* ptr, size_t size) { \
 | 
			
		||||
    if(ptr == 0) \
 | 
			
		||||
      return debug_malloc(size, __FILE__, __LINE__); \
 | 
			
		||||
    if(size == 0) \
 | 
			
		||||
      return debug_free(ptr, __FILE__, __LINE__); \
 | 
			
		||||
    return debug_realloc(ptr, size, __FILE__, __LINE__); \
 | 
			
		||||
  }
 | 
			
		||||
#define realloc2_helper(name) \
 | 
			
		||||
  void* name(void* opaque, void* ptr, size_t size) { \
 | 
			
		||||
    if(ptr == 0) \
 | 
			
		||||
      return debug_malloc(size, __FILE__, __LINE__); \
 | 
			
		||||
    if(size == 0) { \
 | 
			
		||||
      debug_free(ptr, __FILE__, __LINE__); \
 | 
			
		||||
      return 0; \
 | 
			
		||||
    } \
 | 
			
		||||
    return debug_realloc(ptr, size, __FILE__, __LINE__); \
 | 
			
		||||
  }
 | 
			
		||||
#define js_realloc_helper(name) \
 | 
			
		||||
  void* name(JSContext* ctx, void* ptr, size_t size) { \
 | 
			
		||||
    if(ptr == 0) \
 | 
			
		||||
      return debug_js_malloc(ctx, size, __FILE__, __LINE__); \
 | 
			
		||||
    if(size == 0) { \
 | 
			
		||||
      debug_js_free(ctx, ptr, __FILE__, __LINE__); \
 | 
			
		||||
      return 0; \
 | 
			
		||||
    } \
 | 
			
		||||
    return debug_js_realloc(ctx, ptr, size, __FILE__, __LINE__); \
 | 
			
		||||
  }
 | 
			
		||||
#define js_realloc_rt_helper(name) \
 | 
			
		||||
  void* name(JSRuntime* rt, void* ptr, size_t size) { \
 | 
			
		||||
    if(ptr == 0) \
 | 
			
		||||
      return debug_js_malloc_rt(rt, size, __FILE__, __LINE__); \
 | 
			
		||||
    if(size == 0) { \
 | 
			
		||||
      debug_js_free_rt(rt, ptr, __FILE__, __LINE__); \
 | 
			
		||||
      return 0; \
 | 
			
		||||
    } \
 | 
			
		||||
    return debug_js_realloc_rt(rt, ptr, size, __FILE__, __LINE__); \
 | 
			
		||||
  }
 | 
			
		||||
#else
 | 
			
		||||
#define realloc_helper(name) \
 | 
			
		||||
  void* name(void* ptr, size_t size) { \
 | 
			
		||||
    if(ptr == 0) \
 | 
			
		||||
      return malloc(size); \
 | 
			
		||||
    if(size == 0) { \
 | 
			
		||||
      free(ptr); \
 | 
			
		||||
      return 0; \
 | 
			
		||||
    } \
 | 
			
		||||
    return realloc(ptr, size); \
 | 
			
		||||
  }
 | 
			
		||||
#define realloc2_helper(name) \
 | 
			
		||||
  void* name(void* opaque, void* ptr, size_t size) { \
 | 
			
		||||
    if(ptr == 0) \
 | 
			
		||||
      return malloc(size); \
 | 
			
		||||
    if(size == 0) { \
 | 
			
		||||
      free(ptr); \
 | 
			
		||||
      return 0; \
 | 
			
		||||
    } \
 | 
			
		||||
    return realloc(ptr, size); \
 | 
			
		||||
  }
 | 
			
		||||
#define js_realloc_helper(name) \
 | 
			
		||||
  void* name(JSContext* ctx, void* ptr, size_t size) { \
 | 
			
		||||
    if(ptr == 0) \
 | 
			
		||||
      return orig_js_malloc(ctx, size); \
 | 
			
		||||
    if(size == 0) { \
 | 
			
		||||
      orig_js_free(ctx, ptr); \
 | 
			
		||||
      return 0; \
 | 
			
		||||
    } \
 | 
			
		||||
    return orig_js_realloc(ctx, ptr, size); \
 | 
			
		||||
  }
 | 
			
		||||
#define js_realloc_rt_helper(name) \
 | 
			
		||||
  void* name(JSRuntime* rt, void* ptr, size_t size) { \
 | 
			
		||||
    if(ptr == 0) \
 | 
			
		||||
      return orig_js_malloc_rt(rt, size); \
 | 
			
		||||
    if(size == 0) { \
 | 
			
		||||
      orig_js_free_rt(rt, ptr); \
 | 
			
		||||
      return 0; \
 | 
			
		||||
    } \
 | 
			
		||||
    return orig_js_realloc_rt(rt, ptr, size); \
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void* orig_malloc(size_t);
 | 
			
		||||
void* orig_calloc(size_t, size_t);
 | 
			
		||||
void* orig_realloc(void*, size_t);
 | 
			
		||||
void* orig_strdup(const char*);
 | 
			
		||||
void orig_free(void*);
 | 
			
		||||
void* orig_js_malloc(JSContext*, size_t);
 | 
			
		||||
void* orig_js_mallocz(JSContext*, size_t);
 | 
			
		||||
void* orig_js_realloc(JSContext*, void*, size_t);
 | 
			
		||||
void* orig_js_strdup(JSContext*, const char*);
 | 
			
		||||
void* orig_js_strndup(JSContext*, const char*, size_t);
 | 
			
		||||
size_t orig_js_malloc_usable_size(JSContext*, const void*);
 | 
			
		||||
void orig_js_free(JSContext*, void*);
 | 
			
		||||
void* orig_js_malloc_rt(JSRuntime*, size_t);
 | 
			
		||||
void* orig_js_mallocz_rt(JSRuntime*, size_t);
 | 
			
		||||
void* orig_js_realloc_rt(JSRuntime*, void*, size_t);
 | 
			
		||||
size_t orig_js_malloc_usable_size_rt(JSRuntime*, const void*);
 | 
			
		||||
void orig_js_free_rt(JSRuntime*, void*);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @}
 | 
			
		||||
 */
 | 
			
		||||
#endif /* defined(DEBUG_H) */
 | 
			
		||||
							
								
								
									
										181
									
								
								src/quickjs/defines.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								src/quickjs/defines.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,181 @@
 | 
			
		||||
#ifndef DEFINES_H
 | 
			
		||||
#define DEFINES_H
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \defgroup defines defines: Preprocessor definitions
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
#include <io.h>
 | 
			
		||||
#define FD_TO_SOCKET(fd) ((SOCKET)_get_osfhandle((fd)))
 | 
			
		||||
#define SOCKET_TO_FD(fh) (_open_osfhandle((intptr_t)(fh), O_RDWR | O_BINARY))
 | 
			
		||||
#else
 | 
			
		||||
#define FD_TO_SOCKET(fd) (fd)
 | 
			
		||||
#define SOCKET_TO_FD(fh) (fh)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef offsetof
 | 
			
		||||
#define offsetof(type, field) ((size_t) & ((type*)0)->field)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef inrange
 | 
			
		||||
#define inrange(value, min, max) ((value) >= (min) && (value) <= (max))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define trim_dotslash(str) (!strncmp((str), "./", 2) ? (str) + 2 : (str))
 | 
			
		||||
 | 
			
		||||
#ifndef thread_local
 | 
			
		||||
#ifdef _Thread_local
 | 
			
		||||
#define thread_local _Thread_local
 | 
			
		||||
#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
 | 
			
		||||
#define thread_local __thread
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
#define thread_local __declspec(thread)
 | 
			
		||||
#else
 | 
			
		||||
#error No TLS implementation found.
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(__GNUC__) || defined(__clang__)
 | 
			
		||||
#define PACK __attribute__((packed))
 | 
			
		||||
#define ENDPACK
 | 
			
		||||
#else
 | 
			
		||||
#define PACK #pragma pack(push, 1)
 | 
			
		||||
#define ENDPACK #pragma pack(pop)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define JS_CGETSET_ENUMERABLE_DEF(prop_name, fgetter, fsetter, magic_num) \
 | 
			
		||||
  { \
 | 
			
		||||
    .name = prop_name, .prop_flags = JS_PROP_ENUMERABLE | JS_PROP_CONFIGURABLE, .def_type = JS_DEF_CGETSET_MAGIC, .magic = magic_num, .u = { \
 | 
			
		||||
      .getset = {.get = {.getter_magic = fgetter}, .set = {.setter_magic = fsetter}} \
 | 
			
		||||
    } \
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#define JS_CGETSET_MAGIC_FLAGS_DEF(prop_name, fgetter, fsetter, magic_num, flags) \
 | 
			
		||||
  { \
 | 
			
		||||
    .name = prop_name, .prop_flags = flags, .def_type = JS_DEF_CGETSET_MAGIC, .magic = magic_num, .u = { \
 | 
			
		||||
      .getset = {.get = {.getter_magic = fgetter}, .set = {.setter_magic = fsetter}} \
 | 
			
		||||
    } \
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#define JS_CFUNC_DEF_FLAGS(prop_name, length, func1, flags) \
 | 
			
		||||
  { \
 | 
			
		||||
    .name = prop_name, .prop_flags = flags, .def_type = JS_DEF_CFUNC, .magic = 0, .u = {.func = {length, JS_CFUNC_generic, {.generic = func1}} } \
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#define JS_CONSTANT_FLAGS(name, flags) JS_PROP_INT32_DEF(#name, name, (flags))
 | 
			
		||||
#define JS_CONSTANT(name) JS_PROP_INT32_DEF(#name, name, JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE)
 | 
			
		||||
#define JS_CONSTANT_NONENUMERABLE(name) JS_PROP_INT32_DEF(#name, name, JS_PROP_CONFIGURABLE)
 | 
			
		||||
 | 
			
		||||
#ifdef JS_SHARED_LIBRARY
 | 
			
		||||
#if defined(_WIN32) || defined(__MINGW32__)
 | 
			
		||||
#define VISIBLE __declspec(dllexport)
 | 
			
		||||
#define HIDDEN
 | 
			
		||||
#else
 | 
			
		||||
#define VISIBLE __attribute__((visibility("default")))
 | 
			
		||||
#define HIDDEN __attribute__((visibility("hidden")))
 | 
			
		||||
#endif
 | 
			
		||||
#else
 | 
			
		||||
#define VISIBLE
 | 
			
		||||
#define HIDDEN
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef MAX_NUM
 | 
			
		||||
#define MAX_NUM(a, b) ((a) > (b) ? (a) : (b))
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef MIN_NUM
 | 
			
		||||
#define MIN_NUM(a, b) ((a) < (b) ? (a) : (b))
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ABS_NUM
 | 
			
		||||
#define ABS_NUM(n) ((n) < 0 ? -(n) : (n))
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef MOD_NUM
 | 
			
		||||
#define MOD_NUM(n, divisor) ((((n) % (divisor)) + (divisor)) % (divisor))
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef SIGN_NUM
 | 
			
		||||
#define SIGN_NUM(n) ((n) < 0)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define COLOR_BLACK "\x1b[0;30m"
 | 
			
		||||
#define COLOR_RED "\x1b[0;31m"
 | 
			
		||||
#define COLOR_GREEN "\x1b[0;32m"
 | 
			
		||||
#define COLOR_BROWN "\x1b[0;33m"
 | 
			
		||||
#define COLOR_BLUE "\x1b[0;34m"
 | 
			
		||||
#define COLOR_PURPLE "\x1b[0;35m"
 | 
			
		||||
#define COLOR_MARINE "\x1b[0;36m"
 | 
			
		||||
#define COLOR_LIGHTGRAY "\x1b[0;37m"
 | 
			
		||||
#define COLOR_GRAY "\x1b[1;30m"
 | 
			
		||||
#define COLOR_NONE "\x1b[0m"
 | 
			
		||||
 | 
			
		||||
#define COLOR_LIGHTRED "\x1b[1;31m"
 | 
			
		||||
 | 
			
		||||
#define COLOR_LIGHTGREEN "\x1b[1;32m"
 | 
			
		||||
#define COLOR_YELLOW "\x1b[1;33m"
 | 
			
		||||
#define COLOR_LIGHTBLUE "\x1b[1;34m"
 | 
			
		||||
#define COLOR_MAGENTA "\x1b[1;35m"
 | 
			
		||||
#define COLOR_CYAN "\x1b[1;36m"
 | 
			
		||||
#define COLOR_WHITE "\x1b[1;37m"
 | 
			
		||||
 | 
			
		||||
#define BGCOLOR_RED "\x1b[48;5;124m"
 | 
			
		||||
#define BGCOLOR_BLUE "\x1b[48;5;20m"
 | 
			
		||||
#define BGCOLOR_YELLOW "\x1b[48;5;214m"
 | 
			
		||||
#define BGCOLOR_GREEN "\x1b[48;5;28m"
 | 
			
		||||
#define BGCOLOR_PINK "\x1b[48;5;165m"
 | 
			
		||||
 | 
			
		||||
#define JS_VALUE_FREE(ctx, value) \
 | 
			
		||||
  do { \
 | 
			
		||||
    JS_FreeValue((ctx), (value)); \
 | 
			
		||||
    (value) = JS_UNDEFINED; \
 | 
			
		||||
  } while(0);
 | 
			
		||||
#define JS_VALUE_FREE_RT(ctx, value) \
 | 
			
		||||
  do { \
 | 
			
		||||
    JS_FreeValueRT((ctx), (value)); \
 | 
			
		||||
    (value) = JS_UNDEFINED; \
 | 
			
		||||
  } while(0);
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
#define js_object_tmpmark_set(value) \
 | 
			
		||||
  do { \
 | 
			
		||||
    ((uint8_t*)JS_VALUE_GET_OBJ((value)))[5] |= 0x40; \
 | 
			
		||||
  } while(0);
 | 
			
		||||
#define js_object_tmpmark_clear(value) \
 | 
			
		||||
  do { \
 | 
			
		||||
    ((uint8_t*)JS_VALUE_GET_OBJ((value)))[5] &= ~0x40; \
 | 
			
		||||
  } while(0);
 | 
			
		||||
#define js_object_tmpmark_isset(value) (((uint8_t*)JS_VALUE_GET_OBJ((value)))[5] & 0x40)
 | 
			
		||||
#else
 | 
			
		||||
#define js_object_tmpmark_set(value) \
 | 
			
		||||
  do { \
 | 
			
		||||
    JS_VALUE_GET_OBJ((value))->tmp_mark |= 0x40; \
 | 
			
		||||
  } while(0);
 | 
			
		||||
#define js_object_tmpmark_clear(value) \
 | 
			
		||||
  do { \
 | 
			
		||||
    JS_VALUE_GET_OBJ((value))->tmp_mark &= ~0x40; \
 | 
			
		||||
  } while(0);
 | 
			
		||||
#define js_object_tmpmark_isset(value) (JS_VALUE_GET_OBJ((value))->tmp_mark & 0x40)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define js_runtime_exception_set(rt, value) \
 | 
			
		||||
  do { \
 | 
			
		||||
    *(JSValue*)((uint8_t*)(rt) + 216) = value; \
 | 
			
		||||
  } while(0);
 | 
			
		||||
#define js_runtime_exception_get(rt) (*(JSValue*)((uint8_t*)(rt) + 216))
 | 
			
		||||
#define js_runtime_exception_clear(rt) \
 | 
			
		||||
  do { \
 | 
			
		||||
    if(!JS_IsNull(js_runtime_exception_get(rt))) \
 | 
			
		||||
      JS_FreeValueRT((rt), js_runtime_exception_get(rt)); \
 | 
			
		||||
    js_runtime_exception_set(rt, JS_NULL); \
 | 
			
		||||
  } while(0)
 | 
			
		||||
 | 
			
		||||
#define JS_ATOM_TAG_INT (1U << 31)
 | 
			
		||||
#define JS_ATOM_MAX_INT (JS_ATOM_TAG_INT - 1)
 | 
			
		||||
 | 
			
		||||
#define JS_ATOM_ISINT(i) ((JSAtom)((i)&JS_ATOM_TAG_INT))
 | 
			
		||||
#define JS_ATOM_FROMINT(i) ((JSAtom)((i)&JS_ATOM_MAX_INT) | JS_ATOM_TAG_INT)
 | 
			
		||||
#define JS_ATOM_TOINT(i) (unsigned int)(((JSAtom)(i) & (~(JS_ATOM_TAG_INT))))
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @}
 | 
			
		||||
 */
 | 
			
		||||
#endif /* defined(DEFINES_H) */
 | 
			
		||||
							
								
								
									
										45
									
								
								src/quickjs/hello.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/quickjs/hello.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
/* File generated automatically by the QuickJS compiler. */
 | 
			
		||||
 | 
			
		||||
#include "quickjs-libc.h"
 | 
			
		||||
 | 
			
		||||
const uint32_t qjsc_hello_size = 87;
 | 
			
		||||
 | 
			
		||||
const uint8_t qjsc_hello[87] = {
 | 
			
		||||
 0x43, 0x04, 0x0e, 0x63, 0x6f, 0x6e, 0x73, 0x6f,
 | 
			
		||||
 0x6c, 0x65, 0x06, 0x6c, 0x6f, 0x67, 0x16, 0x48,
 | 
			
		||||
 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72,
 | 
			
		||||
 0x6c, 0x64, 0x22, 0x65, 0x78, 0x61, 0x6d, 0x70,
 | 
			
		||||
 0x6c, 0x65, 0x73, 0x2f, 0x68, 0x65, 0x6c, 0x6c,
 | 
			
		||||
 0x6f, 0x2e, 0x6a, 0x73, 0x0c, 0x00, 0x06, 0x00,
 | 
			
		||||
 0xa2, 0x01, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00,
 | 
			
		||||
 0x14, 0x01, 0xa4, 0x01, 0x00, 0x00, 0x00, 0x38,
 | 
			
		||||
 0xe3, 0x00, 0x00, 0x00, 0x42, 0xe4, 0x00, 0x00,
 | 
			
		||||
 0x00, 0x04, 0xe5, 0x00, 0x00, 0x00, 0x24, 0x01,
 | 
			
		||||
 0x00, 0xcf, 0x28, 0xcc, 0x03, 0x01, 0x00,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static JSContext *JS_NewCustomContext(JSRuntime *rt)
 | 
			
		||||
{
 | 
			
		||||
  JSContext *ctx = JS_NewContextRaw(rt);
 | 
			
		||||
  if (!ctx)
 | 
			
		||||
    return NULL;
 | 
			
		||||
  JS_AddIntrinsicBaseObjects(ctx);
 | 
			
		||||
  return ctx;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
  JSRuntime *rt;
 | 
			
		||||
  JSContext *ctx;
 | 
			
		||||
  rt = JS_NewRuntime();
 | 
			
		||||
  js_std_set_worker_new_context_func(JS_NewCustomContext);
 | 
			
		||||
  js_std_init_handlers(rt);
 | 
			
		||||
  ctx = JS_NewCustomContext(rt);
 | 
			
		||||
  js_std_add_helpers(ctx, argc, argv);
 | 
			
		||||
  js_std_eval_binary(ctx, qjsc_hello, qjsc_hello_size, 0);
 | 
			
		||||
  js_std_loop(ctx);
 | 
			
		||||
  js_std_free_handlers(rt);
 | 
			
		||||
  JS_FreeContext(ctx);
 | 
			
		||||
  JS_FreeRuntime(rt);
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								src/quickjs/iso_8859_1.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/quickjs/iso_8859_1.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
 | 
			
		||||
#ifndef TUTF8E_ISO_8859_1_H
 | 
			
		||||
#define TUTF8E_ISO_8859_1_H
 | 
			
		||||
 | 
			
		||||
#include <tutf8e.h>
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_1_string_length(const char *input, size_t *input_length, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_length(tutf8e_encoder_iso_8859_1, input, input_length, invalid, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_1_string_encode(const char *input, char *output, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_encode(tutf8e_encoder_iso_8859_1, input, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_1_buffer_length(const char *i, size_t input_length, const char *invalid, size_t *length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_length(tutf8e_encoder_iso_8859_1, input, input_length, invalid, length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_1_buffer_encode(const char *i, size_t input_length, const char *invalid, char *output, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_encode(tutf8e_encoder_iso_8859_1, input, input_length, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										27
									
								
								src/quickjs/iso_8859_10.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/quickjs/iso_8859_10.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
 | 
			
		||||
#ifndef TUTF8E_ISO_8859_10_H
 | 
			
		||||
#define TUTF8E_ISO_8859_10_H
 | 
			
		||||
 | 
			
		||||
#include <tutf8e.h>
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_10_string_length(const char *input, size_t *input_length, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_length(tutf8e_encoder_iso_8859_10, input, input_length, invalid, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_10_string_encode(const char *input, char *output, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_encode(tutf8e_encoder_iso_8859_10, input, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_10_buffer_length(const char *i, size_t input_length, const char *invalid, size_t *length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_length(tutf8e_encoder_iso_8859_10, input, input_length, invalid, length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_10_buffer_encode(const char *i, size_t input_length, const char *invalid, char *output, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_encode(tutf8e_encoder_iso_8859_10, input, input_length, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										27
									
								
								src/quickjs/iso_8859_11.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/quickjs/iso_8859_11.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
 | 
			
		||||
#ifndef TUTF8E_ISO_8859_11_H
 | 
			
		||||
#define TUTF8E_ISO_8859_11_H
 | 
			
		||||
 | 
			
		||||
#include <tutf8e.h>
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_11_string_length(const char *input, size_t *input_length, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_length(tutf8e_encoder_iso_8859_11, input, input_length, invalid, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_11_string_encode(const char *input, char *output, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_encode(tutf8e_encoder_iso_8859_11, input, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_11_buffer_length(const char *i, size_t input_length, const char *invalid, size_t *length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_length(tutf8e_encoder_iso_8859_11, input, input_length, invalid, length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_11_buffer_encode(const char *i, size_t input_length, const char *invalid, char *output, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_encode(tutf8e_encoder_iso_8859_11, input, input_length, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										27
									
								
								src/quickjs/iso_8859_13.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/quickjs/iso_8859_13.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
 | 
			
		||||
#ifndef TUTF8E_ISO_8859_13_H
 | 
			
		||||
#define TUTF8E_ISO_8859_13_H
 | 
			
		||||
 | 
			
		||||
#include <tutf8e.h>
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_13_string_length(const char *input, size_t *input_length, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_length(tutf8e_encoder_iso_8859_13, input, input_length, invalid, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_13_string_encode(const char *input, char *output, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_encode(tutf8e_encoder_iso_8859_13, input, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_13_buffer_length(const char *i, size_t input_length, const char *invalid, size_t *length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_length(tutf8e_encoder_iso_8859_13, input, input_length, invalid, length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_13_buffer_encode(const char *i, size_t input_length, const char *invalid, char *output, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_encode(tutf8e_encoder_iso_8859_13, input, input_length, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										27
									
								
								src/quickjs/iso_8859_14.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/quickjs/iso_8859_14.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
 | 
			
		||||
#ifndef TUTF8E_ISO_8859_14_H
 | 
			
		||||
#define TUTF8E_ISO_8859_14_H
 | 
			
		||||
 | 
			
		||||
#include <tutf8e.h>
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_14_string_length(const char *input, size_t *input_length, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_length(tutf8e_encoder_iso_8859_14, input, input_length, invalid, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_14_string_encode(const char *input, char *output, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_encode(tutf8e_encoder_iso_8859_14, input, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_14_buffer_length(const char *i, size_t input_length, const char *invalid, size_t *length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_length(tutf8e_encoder_iso_8859_14, input, input_length, invalid, length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_14_buffer_encode(const char *i, size_t input_length, const char *invalid, char *output, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_encode(tutf8e_encoder_iso_8859_14, input, input_length, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										27
									
								
								src/quickjs/iso_8859_15.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/quickjs/iso_8859_15.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
 | 
			
		||||
#ifndef TUTF8E_ISO_8859_15_H
 | 
			
		||||
#define TUTF8E_ISO_8859_15_H
 | 
			
		||||
 | 
			
		||||
#include <tutf8e.h>
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_15_string_length(const char *input, size_t *input_length, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_length(tutf8e_encoder_iso_8859_15, input, input_length, invalid, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_15_string_encode(const char *input, char *output, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_encode(tutf8e_encoder_iso_8859_15, input, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_15_buffer_length(const char *i, size_t input_length, const char *invalid, size_t *length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_length(tutf8e_encoder_iso_8859_15, input, input_length, invalid, length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_15_buffer_encode(const char *i, size_t input_length, const char *invalid, char *output, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_encode(tutf8e_encoder_iso_8859_15, input, input_length, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										27
									
								
								src/quickjs/iso_8859_16.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/quickjs/iso_8859_16.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
 | 
			
		||||
#ifndef TUTF8E_ISO_8859_16_H
 | 
			
		||||
#define TUTF8E_ISO_8859_16_H
 | 
			
		||||
 | 
			
		||||
#include <tutf8e.h>
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_16_string_length(const char *input, size_t *input_length, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_length(tutf8e_encoder_iso_8859_16, input, input_length, invalid, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_16_string_encode(const char *input, char *output, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_encode(tutf8e_encoder_iso_8859_16, input, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_16_buffer_length(const char *i, size_t input_length, const char *invalid, size_t *length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_length(tutf8e_encoder_iso_8859_16, input, input_length, invalid, length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_16_buffer_encode(const char *i, size_t input_length, const char *invalid, char *output, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_encode(tutf8e_encoder_iso_8859_16, input, input_length, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										27
									
								
								src/quickjs/iso_8859_2.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/quickjs/iso_8859_2.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
 | 
			
		||||
#ifndef TUTF8E_ISO_8859_2_H
 | 
			
		||||
#define TUTF8E_ISO_8859_2_H
 | 
			
		||||
 | 
			
		||||
#include <tutf8e.h>
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_2_string_length(const char *input, size_t *input_length, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_length(tutf8e_encoder_iso_8859_2, input, input_length, invalid, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_2_string_encode(const char *input, char *output, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_encode(tutf8e_encoder_iso_8859_2, input, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_2_buffer_length(const char *i, size_t input_length, const char *invalid, size_t *length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_length(tutf8e_encoder_iso_8859_2, input, input_length, invalid, length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_2_buffer_encode(const char *i, size_t input_length, const char *invalid, char *output, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_encode(tutf8e_encoder_iso_8859_2, input, input_length, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										27
									
								
								src/quickjs/iso_8859_3.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/quickjs/iso_8859_3.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
 | 
			
		||||
#ifndef TUTF8E_ISO_8859_3_H
 | 
			
		||||
#define TUTF8E_ISO_8859_3_H
 | 
			
		||||
 | 
			
		||||
#include <tutf8e.h>
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_3_string_length(const char *input, size_t *input_length, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_length(tutf8e_encoder_iso_8859_3, input, input_length, invalid, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_3_string_encode(const char *input, char *output, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_encode(tutf8e_encoder_iso_8859_3, input, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_3_buffer_length(const char *i, size_t input_length, const char *invalid, size_t *length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_length(tutf8e_encoder_iso_8859_3, input, input_length, invalid, length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_3_buffer_encode(const char *i, size_t input_length, const char *invalid, char *output, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_encode(tutf8e_encoder_iso_8859_3, input, input_length, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										27
									
								
								src/quickjs/iso_8859_4.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/quickjs/iso_8859_4.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
 | 
			
		||||
#ifndef TUTF8E_ISO_8859_4_H
 | 
			
		||||
#define TUTF8E_ISO_8859_4_H
 | 
			
		||||
 | 
			
		||||
#include <tutf8e.h>
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_4_string_length(const char *input, size_t *input_length, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_length(tutf8e_encoder_iso_8859_4, input, input_length, invalid, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_4_string_encode(const char *input, char *output, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_encode(tutf8e_encoder_iso_8859_4, input, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_4_buffer_length(const char *i, size_t input_length, const char *invalid, size_t *length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_length(tutf8e_encoder_iso_8859_4, input, input_length, invalid, length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_4_buffer_encode(const char *i, size_t input_length, const char *invalid, char *output, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_encode(tutf8e_encoder_iso_8859_4, input, input_length, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										27
									
								
								src/quickjs/iso_8859_5.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/quickjs/iso_8859_5.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
 | 
			
		||||
#ifndef TUTF8E_ISO_8859_5_H
 | 
			
		||||
#define TUTF8E_ISO_8859_5_H
 | 
			
		||||
 | 
			
		||||
#include <tutf8e.h>
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_5_string_length(const char *input, size_t *input_length, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_length(tutf8e_encoder_iso_8859_5, input, input_length, invalid, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_5_string_encode(const char *input, char *output, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_encode(tutf8e_encoder_iso_8859_5, input, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_5_buffer_length(const char *i, size_t input_length, const char *invalid, size_t *length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_length(tutf8e_encoder_iso_8859_5, input, input_length, invalid, length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_5_buffer_encode(const char *i, size_t input_length, const char *invalid, char *output, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_encode(tutf8e_encoder_iso_8859_5, input, input_length, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										27
									
								
								src/quickjs/iso_8859_6.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/quickjs/iso_8859_6.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
 | 
			
		||||
#ifndef TUTF8E_ISO_8859_6_H
 | 
			
		||||
#define TUTF8E_ISO_8859_6_H
 | 
			
		||||
 | 
			
		||||
#include <tutf8e.h>
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_6_string_length(const char *input, size_t *input_length, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_length(tutf8e_encoder_iso_8859_6, input, input_length, invalid, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_6_string_encode(const char *input, char *output, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_encode(tutf8e_encoder_iso_8859_6, input, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_6_buffer_length(const char *i, size_t input_length, const char *invalid, size_t *length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_length(tutf8e_encoder_iso_8859_6, input, input_length, invalid, length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_6_buffer_encode(const char *i, size_t input_length, const char *invalid, char *output, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_encode(tutf8e_encoder_iso_8859_6, input, input_length, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										27
									
								
								src/quickjs/iso_8859_7.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/quickjs/iso_8859_7.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
 | 
			
		||||
#ifndef TUTF8E_ISO_8859_7_H
 | 
			
		||||
#define TUTF8E_ISO_8859_7_H
 | 
			
		||||
 | 
			
		||||
#include <tutf8e.h>
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_7_string_length(const char *input, size_t *input_length, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_length(tutf8e_encoder_iso_8859_7, input, input_length, invalid, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_7_string_encode(const char *input, char *output, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_encode(tutf8e_encoder_iso_8859_7, input, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_7_buffer_length(const char *i, size_t input_length, const char *invalid, size_t *length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_length(tutf8e_encoder_iso_8859_7, input, input_length, invalid, length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_7_buffer_encode(const char *i, size_t input_length, const char *invalid, char *output, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_encode(tutf8e_encoder_iso_8859_7, input, input_length, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										27
									
								
								src/quickjs/iso_8859_8.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/quickjs/iso_8859_8.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
 | 
			
		||||
#ifndef TUTF8E_ISO_8859_8_H
 | 
			
		||||
#define TUTF8E_ISO_8859_8_H
 | 
			
		||||
 | 
			
		||||
#include <tutf8e.h>
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_8_string_length(const char *input, size_t *input_length, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_length(tutf8e_encoder_iso_8859_8, input, input_length, invalid, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_8_string_encode(const char *input, char *output, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_encode(tutf8e_encoder_iso_8859_8, input, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_8_buffer_length(const char *i, size_t input_length, const char *invalid, size_t *length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_length(tutf8e_encoder_iso_8859_8, input, input_length, invalid, length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_8_buffer_encode(const char *i, size_t input_length, const char *invalid, char *output, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_encode(tutf8e_encoder_iso_8859_8, input, input_length, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										27
									
								
								src/quickjs/iso_8859_9.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/quickjs/iso_8859_9.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
 | 
			
		||||
#ifndef TUTF8E_ISO_8859_9_H
 | 
			
		||||
#define TUTF8E_ISO_8859_9_H
 | 
			
		||||
 | 
			
		||||
#include <tutf8e.h>
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_9_string_length(const char *input, size_t *input_length, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_length(tutf8e_encoder_iso_8859_9, input, input_length, invalid, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_9_string_encode(const char *input, char *output, const char *invalid, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_string_encode(tutf8e_encoder_iso_8859_9, input, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_9_buffer_length(const char *i, size_t input_length, const char *invalid, size_t *length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_length(tutf8e_encoder_iso_8859_9, input, input_length, invalid, length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int tutf8e_iso_8859_9_buffer_encode(const char *i, size_t input_length, const char *invalid, char *output, size_t *output_length)
 | 
			
		||||
{
 | 
			
		||||
  return tutf8e_encoder_buffer_encode(tutf8e_encoder_iso_8859_9, input, input_length, invalid, output, output_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										8473
									
								
								src/quickjs/libbf.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8473
									
								
								src/quickjs/libbf.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										535
									
								
								src/quickjs/libbf.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										535
									
								
								src/quickjs/libbf.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,535 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Tiny arbitrary precision floating point library
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2017-2021 Fabrice Bellard
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 * of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
 * in the Software without restriction, including without limitation the rights
 | 
			
		||||
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
 * copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
 * THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef LIBBF_H
 | 
			
		||||
#define LIBBF_H
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
#if defined(__SIZEOF_INT128__) && (INTPTR_MAX >= INT64_MAX)
 | 
			
		||||
#define LIMB_LOG2_BITS 6
 | 
			
		||||
#else
 | 
			
		||||
#define LIMB_LOG2_BITS 5
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define LIMB_BITS (1 << LIMB_LOG2_BITS)
 | 
			
		||||
 | 
			
		||||
#if LIMB_BITS == 64
 | 
			
		||||
typedef __int128 int128_t;
 | 
			
		||||
typedef unsigned __int128 uint128_t;
 | 
			
		||||
typedef int64_t slimb_t;
 | 
			
		||||
typedef uint64_t limb_t;
 | 
			
		||||
typedef uint128_t dlimb_t;
 | 
			
		||||
#define BF_RAW_EXP_MIN INT64_MIN
 | 
			
		||||
#define BF_RAW_EXP_MAX INT64_MAX
 | 
			
		||||
 | 
			
		||||
#define LIMB_DIGITS 19
 | 
			
		||||
#define BF_DEC_BASE UINT64_C(10000000000000000000)
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
typedef int32_t slimb_t;
 | 
			
		||||
typedef uint32_t limb_t;
 | 
			
		||||
typedef uint64_t dlimb_t;
 | 
			
		||||
#define BF_RAW_EXP_MIN INT32_MIN
 | 
			
		||||
#define BF_RAW_EXP_MAX INT32_MAX
 | 
			
		||||
 | 
			
		||||
#define LIMB_DIGITS 9
 | 
			
		||||
#define BF_DEC_BASE 1000000000U
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* in bits */
 | 
			
		||||
/* minimum number of bits for the exponent */
 | 
			
		||||
#define BF_EXP_BITS_MIN 3
 | 
			
		||||
/* maximum number of bits for the exponent */
 | 
			
		||||
#define BF_EXP_BITS_MAX (LIMB_BITS - 3)
 | 
			
		||||
/* extended range for exponent, used internally */
 | 
			
		||||
#define BF_EXT_EXP_BITS_MAX (BF_EXP_BITS_MAX + 1)
 | 
			
		||||
/* minimum possible precision */
 | 
			
		||||
#define BF_PREC_MIN 2
 | 
			
		||||
/* minimum possible precision */
 | 
			
		||||
#define BF_PREC_MAX (((limb_t)1 << (LIMB_BITS - 2)) - 2)
 | 
			
		||||
/* some operations support infinite precision */
 | 
			
		||||
#define BF_PREC_INF (BF_PREC_MAX + 1) /* infinite precision */
 | 
			
		||||
 | 
			
		||||
#if LIMB_BITS == 64
 | 
			
		||||
#define BF_CHKSUM_MOD (UINT64_C(975620677) * UINT64_C(9795002197))
 | 
			
		||||
#else
 | 
			
		||||
#define BF_CHKSUM_MOD 975620677U
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define BF_EXP_ZERO BF_RAW_EXP_MIN
 | 
			
		||||
#define BF_EXP_INF (BF_RAW_EXP_MAX - 1)
 | 
			
		||||
#define BF_EXP_NAN BF_RAW_EXP_MAX
 | 
			
		||||
 | 
			
		||||
/* +/-zero is represented with expn = BF_EXP_ZERO and len = 0,
 | 
			
		||||
   +/-infinity is represented with expn = BF_EXP_INF and len = 0,
 | 
			
		||||
   NaN is represented with expn = BF_EXP_NAN and len = 0 (sign is ignored)
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    struct bf_context_t *ctx;
 | 
			
		||||
    int sign;
 | 
			
		||||
    slimb_t expn;
 | 
			
		||||
    limb_t len;
 | 
			
		||||
    limb_t *tab;
 | 
			
		||||
} bf_t;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    /* must be kept identical to bf_t */
 | 
			
		||||
    struct bf_context_t *ctx;
 | 
			
		||||
    int sign;
 | 
			
		||||
    slimb_t expn;
 | 
			
		||||
    limb_t len;
 | 
			
		||||
    limb_t *tab;
 | 
			
		||||
} bfdec_t;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
    BF_RNDN, /* round to nearest, ties to even */
 | 
			
		||||
    BF_RNDZ, /* round to zero */
 | 
			
		||||
    BF_RNDD, /* round to -inf (the code relies on (BF_RNDD xor BF_RNDU) = 1) */
 | 
			
		||||
    BF_RNDU, /* round to +inf */
 | 
			
		||||
    BF_RNDNA, /* round to nearest, ties away from zero */
 | 
			
		||||
    BF_RNDA, /* round away from zero */
 | 
			
		||||
    BF_RNDF, /* faithful rounding (nondeterministic, either RNDD or RNDU,
 | 
			
		||||
                inexact flag is always set)  */
 | 
			
		||||
} bf_rnd_t;
 | 
			
		||||
 | 
			
		||||
/* allow subnormal numbers. Only available if the number of exponent
 | 
			
		||||
   bits is <= BF_EXP_BITS_USER_MAX and prec != BF_PREC_INF. */
 | 
			
		||||
#define BF_FLAG_SUBNORMAL (1 << 3)
 | 
			
		||||
/* 'prec' is the precision after the radix point instead of the whole
 | 
			
		||||
   mantissa. Can only be used with bf_round() and
 | 
			
		||||
   bfdec_[add|sub|mul|div|sqrt|round](). */
 | 
			
		||||
#define BF_FLAG_RADPNT_PREC (1 << 4)
 | 
			
		||||
 | 
			
		||||
#define BF_RND_MASK 0x7
 | 
			
		||||
#define BF_EXP_BITS_SHIFT 5
 | 
			
		||||
#define BF_EXP_BITS_MASK 0x3f
 | 
			
		||||
 | 
			
		||||
/* shortcut for bf_set_exp_bits(BF_EXT_EXP_BITS_MAX) */
 | 
			
		||||
#define BF_FLAG_EXT_EXP (BF_EXP_BITS_MASK << BF_EXP_BITS_SHIFT)
 | 
			
		||||
 | 
			
		||||
/* contains the rounding mode and number of exponents bits */
 | 
			
		||||
typedef uint32_t bf_flags_t;
 | 
			
		||||
 | 
			
		||||
typedef void *bf_realloc_func_t(void *opaque, void *ptr, size_t size);
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    bf_t val;
 | 
			
		||||
    limb_t prec;
 | 
			
		||||
} BFConstCache;
 | 
			
		||||
 | 
			
		||||
typedef struct bf_context_t {
 | 
			
		||||
    void *realloc_opaque;
 | 
			
		||||
    bf_realloc_func_t *realloc_func;
 | 
			
		||||
    BFConstCache log2_cache;
 | 
			
		||||
    BFConstCache pi_cache;
 | 
			
		||||
    struct BFNTTState *ntt_state;
 | 
			
		||||
} bf_context_t;
 | 
			
		||||
 | 
			
		||||
static inline int bf_get_exp_bits(bf_flags_t flags)
 | 
			
		||||
{
 | 
			
		||||
    int e;
 | 
			
		||||
    e = (flags >> BF_EXP_BITS_SHIFT) & BF_EXP_BITS_MASK;
 | 
			
		||||
    if (e == BF_EXP_BITS_MASK)
 | 
			
		||||
        return BF_EXP_BITS_MAX + 1;
 | 
			
		||||
    else
 | 
			
		||||
        return BF_EXP_BITS_MAX - e;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bf_flags_t bf_set_exp_bits(int n)
 | 
			
		||||
{
 | 
			
		||||
    return ((BF_EXP_BITS_MAX - n) & BF_EXP_BITS_MASK) << BF_EXP_BITS_SHIFT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* returned status */
 | 
			
		||||
#define BF_ST_INVALID_OP  (1 << 0)
 | 
			
		||||
#define BF_ST_DIVIDE_ZERO (1 << 1)
 | 
			
		||||
#define BF_ST_OVERFLOW    (1 << 2)
 | 
			
		||||
#define BF_ST_UNDERFLOW   (1 << 3)
 | 
			
		||||
#define BF_ST_INEXACT     (1 << 4)
 | 
			
		||||
/* indicate that a memory allocation error occured. NaN is returned */
 | 
			
		||||
#define BF_ST_MEM_ERROR   (1 << 5)
 | 
			
		||||
 | 
			
		||||
#define BF_RADIX_MAX 36 /* maximum radix for bf_atof() and bf_ftoa() */
 | 
			
		||||
 | 
			
		||||
static inline slimb_t bf_max(slimb_t a, slimb_t b)
 | 
			
		||||
{
 | 
			
		||||
    if (a > b)
 | 
			
		||||
        return a;
 | 
			
		||||
    else
 | 
			
		||||
        return b;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline slimb_t bf_min(slimb_t a, slimb_t b)
 | 
			
		||||
{
 | 
			
		||||
    if (a < b)
 | 
			
		||||
        return a;
 | 
			
		||||
    else
 | 
			
		||||
        return b;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void bf_context_init(bf_context_t *s, bf_realloc_func_t *realloc_func,
 | 
			
		||||
                     void *realloc_opaque);
 | 
			
		||||
void bf_context_end(bf_context_t *s);
 | 
			
		||||
/* free memory allocated for the bf cache data */
 | 
			
		||||
void bf_clear_cache(bf_context_t *s);
 | 
			
		||||
 | 
			
		||||
static inline void *bf_realloc(bf_context_t *s, void *ptr, size_t size)
 | 
			
		||||
{
 | 
			
		||||
    return s->realloc_func(s->realloc_opaque, ptr, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 'size' must be != 0 */
 | 
			
		||||
static inline void *bf_malloc(bf_context_t *s, size_t size)
 | 
			
		||||
{
 | 
			
		||||
    return bf_realloc(s, NULL, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void bf_free(bf_context_t *s, void *ptr)
 | 
			
		||||
{
 | 
			
		||||
    /* must test ptr otherwise equivalent to malloc(0) */
 | 
			
		||||
    if (ptr)
 | 
			
		||||
        bf_realloc(s, ptr, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void bf_init(bf_context_t *s, bf_t *r);
 | 
			
		||||
 | 
			
		||||
static inline void bf_delete(bf_t *r)
 | 
			
		||||
{
 | 
			
		||||
    bf_context_t *s = r->ctx;
 | 
			
		||||
    /* we accept to delete a zeroed bf_t structure */
 | 
			
		||||
    if (s && r->tab) {
 | 
			
		||||
        bf_realloc(s, r->tab, 0);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void bf_neg(bf_t *r)
 | 
			
		||||
{
 | 
			
		||||
    r->sign ^= 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int bf_is_finite(const bf_t *a)
 | 
			
		||||
{
 | 
			
		||||
    return (a->expn < BF_EXP_INF);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int bf_is_nan(const bf_t *a)
 | 
			
		||||
{
 | 
			
		||||
    return (a->expn == BF_EXP_NAN);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int bf_is_zero(const bf_t *a)
 | 
			
		||||
{
 | 
			
		||||
    return (a->expn == BF_EXP_ZERO);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void bf_memcpy(bf_t *r, const bf_t *a)
 | 
			
		||||
{
 | 
			
		||||
    *r = *a;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int bf_set_ui(bf_t *r, uint64_t a);
 | 
			
		||||
int bf_set_si(bf_t *r, int64_t a);
 | 
			
		||||
void bf_set_nan(bf_t *r);
 | 
			
		||||
void bf_set_zero(bf_t *r, int is_neg);
 | 
			
		||||
void bf_set_inf(bf_t *r, int is_neg);
 | 
			
		||||
int bf_set(bf_t *r, const bf_t *a);
 | 
			
		||||
void bf_move(bf_t *r, bf_t *a);
 | 
			
		||||
int bf_get_float64(const bf_t *a, double *pres, bf_rnd_t rnd_mode);
 | 
			
		||||
int bf_set_float64(bf_t *a, double d);
 | 
			
		||||
 | 
			
		||||
int bf_cmpu(const bf_t *a, const bf_t *b);
 | 
			
		||||
int bf_cmp_full(const bf_t *a, const bf_t *b);
 | 
			
		||||
int bf_cmp(const bf_t *a, const bf_t *b);
 | 
			
		||||
static inline int bf_cmp_eq(const bf_t *a, const bf_t *b)
 | 
			
		||||
{
 | 
			
		||||
    return bf_cmp(a, b) == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int bf_cmp_le(const bf_t *a, const bf_t *b)
 | 
			
		||||
{
 | 
			
		||||
    return bf_cmp(a, b) <= 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int bf_cmp_lt(const bf_t *a, const bf_t *b)
 | 
			
		||||
{
 | 
			
		||||
    return bf_cmp(a, b) < 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int bf_add(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags);
 | 
			
		||||
int bf_sub(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags);
 | 
			
		||||
int bf_add_si(bf_t *r, const bf_t *a, int64_t b1, limb_t prec, bf_flags_t flags);
 | 
			
		||||
int bf_mul(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags);
 | 
			
		||||
int bf_mul_ui(bf_t *r, const bf_t *a, uint64_t b1, limb_t prec, bf_flags_t flags);
 | 
			
		||||
int bf_mul_si(bf_t *r, const bf_t *a, int64_t b1, limb_t prec,
 | 
			
		||||
              bf_flags_t flags);
 | 
			
		||||
int bf_mul_2exp(bf_t *r, slimb_t e, limb_t prec, bf_flags_t flags);
 | 
			
		||||
int bf_div(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags);
 | 
			
		||||
#define BF_DIVREM_EUCLIDIAN BF_RNDF
 | 
			
		||||
int bf_divrem(bf_t *q, bf_t *r, const bf_t *a, const bf_t *b,
 | 
			
		||||
              limb_t prec, bf_flags_t flags, int rnd_mode);
 | 
			
		||||
int bf_rem(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec,
 | 
			
		||||
           bf_flags_t flags, int rnd_mode);
 | 
			
		||||
int bf_remquo(slimb_t *pq, bf_t *r, const bf_t *a, const bf_t *b, limb_t prec,
 | 
			
		||||
              bf_flags_t flags, int rnd_mode);
 | 
			
		||||
/* round to integer with infinite precision */
 | 
			
		||||
int bf_rint(bf_t *r, int rnd_mode);
 | 
			
		||||
int bf_round(bf_t *r, limb_t prec, bf_flags_t flags);
 | 
			
		||||
int bf_sqrtrem(bf_t *r, bf_t *rem1, const bf_t *a);
 | 
			
		||||
int bf_sqrt(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
 | 
			
		||||
slimb_t bf_get_exp_min(const bf_t *a);
 | 
			
		||||
int bf_logic_or(bf_t *r, const bf_t *a, const bf_t *b);
 | 
			
		||||
int bf_logic_xor(bf_t *r, const bf_t *a, const bf_t *b);
 | 
			
		||||
int bf_logic_and(bf_t *r, const bf_t *a, const bf_t *b);
 | 
			
		||||
 | 
			
		||||
/* additional flags for bf_atof */
 | 
			
		||||
/* do not accept hex radix prefix (0x or 0X) if radix = 0 or radix = 16 */
 | 
			
		||||
#define BF_ATOF_NO_HEX       (1 << 16)
 | 
			
		||||
/* accept binary (0b or 0B) or octal (0o or 0O) radix prefix if radix = 0 */
 | 
			
		||||
#define BF_ATOF_BIN_OCT      (1 << 17)
 | 
			
		||||
/* Do not parse NaN or Inf */
 | 
			
		||||
#define BF_ATOF_NO_NAN_INF   (1 << 18)
 | 
			
		||||
/* return the exponent separately */
 | 
			
		||||
#define BF_ATOF_EXPONENT       (1 << 19)
 | 
			
		||||
 | 
			
		||||
int bf_atof(bf_t *a, const char *str, const char **pnext, int radix,
 | 
			
		||||
            limb_t prec, bf_flags_t flags);
 | 
			
		||||
/* this version accepts prec = BF_PREC_INF and returns the radix
 | 
			
		||||
   exponent */
 | 
			
		||||
int bf_atof2(bf_t *r, slimb_t *pexponent,
 | 
			
		||||
             const char *str, const char **pnext, int radix,
 | 
			
		||||
             limb_t prec, bf_flags_t flags);
 | 
			
		||||
int bf_mul_pow_radix(bf_t *r, const bf_t *T, limb_t radix,
 | 
			
		||||
                     slimb_t expn, limb_t prec, bf_flags_t flags);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Conversion of floating point number to string. Return a null
 | 
			
		||||
   terminated string or NULL if memory error. *plen contains its
 | 
			
		||||
   length if plen != NULL.  The exponent letter is "e" for base 10,
 | 
			
		||||
   "p" for bases 2, 8, 16 with a binary exponent and "@" for the other
 | 
			
		||||
   bases. */
 | 
			
		||||
 | 
			
		||||
#define BF_FTOA_FORMAT_MASK (3 << 16)
 | 
			
		||||
 | 
			
		||||
/* fixed format: prec significant digits rounded with (flags &
 | 
			
		||||
   BF_RND_MASK). Exponential notation is used if too many zeros are
 | 
			
		||||
   needed.*/
 | 
			
		||||
#define BF_FTOA_FORMAT_FIXED (0 << 16)
 | 
			
		||||
/* fractional format: prec digits after the decimal point rounded with
 | 
			
		||||
   (flags & BF_RND_MASK) */
 | 
			
		||||
#define BF_FTOA_FORMAT_FRAC  (1 << 16)
 | 
			
		||||
/* free format:
 | 
			
		||||
 | 
			
		||||
   For binary radices with bf_ftoa() and for bfdec_ftoa(): use the minimum
 | 
			
		||||
   number of digits to represent 'a'. The precision and the rounding
 | 
			
		||||
   mode are ignored.
 | 
			
		||||
 | 
			
		||||
   For the non binary radices with bf_ftoa(): use as many digits as
 | 
			
		||||
   necessary so that bf_atof() return the same number when using
 | 
			
		||||
   precision 'prec', rounding to nearest and the subnormal
 | 
			
		||||
   configuration of 'flags'. The result is meaningful only if 'a' is
 | 
			
		||||
   already rounded to 'prec' bits. If the subnormal flag is set, the
 | 
			
		||||
   exponent in 'flags' must also be set to the desired exponent range.
 | 
			
		||||
*/
 | 
			
		||||
#define BF_FTOA_FORMAT_FREE  (2 << 16)
 | 
			
		||||
/* same as BF_FTOA_FORMAT_FREE but uses the minimum number of digits
 | 
			
		||||
   (takes more computation time). Identical to BF_FTOA_FORMAT_FREE for
 | 
			
		||||
   binary radices with bf_ftoa() and for bfdec_ftoa(). */
 | 
			
		||||
#define BF_FTOA_FORMAT_FREE_MIN (3 << 16)
 | 
			
		||||
 | 
			
		||||
/* force exponential notation for fixed or free format */
 | 
			
		||||
#define BF_FTOA_FORCE_EXP    (1 << 20)
 | 
			
		||||
/* add 0x prefix for base 16, 0o prefix for base 8 or 0b prefix for
 | 
			
		||||
   base 2 if non zero value */
 | 
			
		||||
#define BF_FTOA_ADD_PREFIX   (1 << 21)
 | 
			
		||||
/* return "Infinity" instead of "Inf" and add a "+" for positive
 | 
			
		||||
   exponents */
 | 
			
		||||
#define BF_FTOA_JS_QUIRKS    (1 << 22)
 | 
			
		||||
 | 
			
		||||
char *bf_ftoa(size_t *plen, const bf_t *a, int radix, limb_t prec,
 | 
			
		||||
              bf_flags_t flags);
 | 
			
		||||
 | 
			
		||||
/* modulo 2^n instead of saturation. NaN and infinity return 0 */
 | 
			
		||||
#define BF_GET_INT_MOD (1 << 0)
 | 
			
		||||
int bf_get_int32(int *pres, const bf_t *a, int flags);
 | 
			
		||||
int bf_get_int64(int64_t *pres, const bf_t *a, int flags);
 | 
			
		||||
int bf_get_uint64(uint64_t *pres, const bf_t *a);
 | 
			
		||||
 | 
			
		||||
/* the following functions are exported for testing only. */
 | 
			
		||||
void mp_print_str(const char *str, const limb_t *tab, limb_t n);
 | 
			
		||||
void bf_print_str(const char *str, const bf_t *a);
 | 
			
		||||
int bf_resize(bf_t *r, limb_t len);
 | 
			
		||||
int bf_get_fft_size(int *pdpl, int *pnb_mods, limb_t len);
 | 
			
		||||
int bf_normalize_and_round(bf_t *r, limb_t prec1, bf_flags_t flags);
 | 
			
		||||
int bf_can_round(const bf_t *a, slimb_t prec, bf_rnd_t rnd_mode, slimb_t k);
 | 
			
		||||
slimb_t bf_mul_log2_radix(slimb_t a1, unsigned int radix, int is_inv,
 | 
			
		||||
                          int is_ceil1);
 | 
			
		||||
int mp_mul(bf_context_t *s, limb_t *result,
 | 
			
		||||
           const limb_t *op1, limb_t op1_size,
 | 
			
		||||
           const limb_t *op2, limb_t op2_size);
 | 
			
		||||
limb_t mp_add(limb_t *res, const limb_t *op1, const limb_t *op2,
 | 
			
		||||
              limb_t n, limb_t carry);
 | 
			
		||||
limb_t mp_add_ui(limb_t *tab, limb_t b, size_t n);
 | 
			
		||||
int mp_sqrtrem(bf_context_t *s, limb_t *tabs, limb_t *taba, limb_t n);
 | 
			
		||||
int mp_recip(bf_context_t *s, limb_t *tabr, const limb_t *taba, limb_t n);
 | 
			
		||||
limb_t bf_isqrt(limb_t a);
 | 
			
		||||
 | 
			
		||||
/* transcendental functions */
 | 
			
		||||
int bf_const_log2(bf_t *T, limb_t prec, bf_flags_t flags);
 | 
			
		||||
int bf_const_pi(bf_t *T, limb_t prec, bf_flags_t flags);
 | 
			
		||||
int bf_exp(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
 | 
			
		||||
int bf_log(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
 | 
			
		||||
#define BF_POW_JS_QUIRKS (1 << 16) /* (+/-1)^(+/-Inf) = NaN, 1^NaN = NaN */
 | 
			
		||||
int bf_pow(bf_t *r, const bf_t *x, const bf_t *y, limb_t prec, bf_flags_t flags);
 | 
			
		||||
int bf_cos(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
 | 
			
		||||
int bf_sin(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
 | 
			
		||||
int bf_tan(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
 | 
			
		||||
int bf_atan(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
 | 
			
		||||
int bf_atan2(bf_t *r, const bf_t *y, const bf_t *x,
 | 
			
		||||
             limb_t prec, bf_flags_t flags);
 | 
			
		||||
int bf_asin(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
 | 
			
		||||
int bf_acos(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
 | 
			
		||||
 | 
			
		||||
/* decimal floating point */
 | 
			
		||||
 | 
			
		||||
static inline void bfdec_init(bf_context_t *s, bfdec_t *r)
 | 
			
		||||
{
 | 
			
		||||
    bf_init(s, (bf_t *)r);
 | 
			
		||||
}
 | 
			
		||||
static inline void bfdec_delete(bfdec_t *r)
 | 
			
		||||
{
 | 
			
		||||
    bf_delete((bf_t *)r);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void bfdec_neg(bfdec_t *r)
 | 
			
		||||
{
 | 
			
		||||
    r->sign ^= 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int bfdec_is_finite(const bfdec_t *a)
 | 
			
		||||
{
 | 
			
		||||
    return (a->expn < BF_EXP_INF);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int bfdec_is_nan(const bfdec_t *a)
 | 
			
		||||
{
 | 
			
		||||
    return (a->expn == BF_EXP_NAN);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int bfdec_is_zero(const bfdec_t *a)
 | 
			
		||||
{
 | 
			
		||||
    return (a->expn == BF_EXP_ZERO);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void bfdec_memcpy(bfdec_t *r, const bfdec_t *a)
 | 
			
		||||
{
 | 
			
		||||
    bf_memcpy((bf_t *)r, (const bf_t *)a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int bfdec_set_ui(bfdec_t *r, uint64_t a);
 | 
			
		||||
int bfdec_set_si(bfdec_t *r, int64_t a);
 | 
			
		||||
 | 
			
		||||
static inline void bfdec_set_nan(bfdec_t *r)
 | 
			
		||||
{
 | 
			
		||||
    bf_set_nan((bf_t *)r);
 | 
			
		||||
}
 | 
			
		||||
static inline void bfdec_set_zero(bfdec_t *r, int is_neg)
 | 
			
		||||
{
 | 
			
		||||
    bf_set_zero((bf_t *)r, is_neg);
 | 
			
		||||
}
 | 
			
		||||
static inline void bfdec_set_inf(bfdec_t *r, int is_neg)
 | 
			
		||||
{
 | 
			
		||||
    bf_set_inf((bf_t *)r, is_neg);
 | 
			
		||||
}
 | 
			
		||||
static inline int bfdec_set(bfdec_t *r, const bfdec_t *a)
 | 
			
		||||
{
 | 
			
		||||
    return bf_set((bf_t *)r, (bf_t *)a);
 | 
			
		||||
}
 | 
			
		||||
static inline void bfdec_move(bfdec_t *r, bfdec_t *a)
 | 
			
		||||
{
 | 
			
		||||
    bf_move((bf_t *)r, (bf_t *)a);
 | 
			
		||||
}
 | 
			
		||||
static inline int bfdec_cmpu(const bfdec_t *a, const bfdec_t *b)
 | 
			
		||||
{
 | 
			
		||||
    return bf_cmpu((const bf_t *)a, (const bf_t *)b);
 | 
			
		||||
}
 | 
			
		||||
static inline int bfdec_cmp_full(const bfdec_t *a, const bfdec_t *b)
 | 
			
		||||
{
 | 
			
		||||
    return bf_cmp_full((const bf_t *)a, (const bf_t *)b);
 | 
			
		||||
}
 | 
			
		||||
static inline int bfdec_cmp(const bfdec_t *a, const bfdec_t *b)
 | 
			
		||||
{
 | 
			
		||||
    return bf_cmp((const bf_t *)a, (const bf_t *)b);
 | 
			
		||||
}
 | 
			
		||||
static inline int bfdec_cmp_eq(const bfdec_t *a, const bfdec_t *b)
 | 
			
		||||
{
 | 
			
		||||
    return bfdec_cmp(a, b) == 0;
 | 
			
		||||
}
 | 
			
		||||
static inline int bfdec_cmp_le(const bfdec_t *a, const bfdec_t *b)
 | 
			
		||||
{
 | 
			
		||||
    return bfdec_cmp(a, b) <= 0;
 | 
			
		||||
}
 | 
			
		||||
static inline int bfdec_cmp_lt(const bfdec_t *a, const bfdec_t *b)
 | 
			
		||||
{
 | 
			
		||||
    return bfdec_cmp(a, b) < 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int bfdec_add(bfdec_t *r, const bfdec_t *a, const bfdec_t *b, limb_t prec,
 | 
			
		||||
              bf_flags_t flags);
 | 
			
		||||
int bfdec_sub(bfdec_t *r, const bfdec_t *a, const bfdec_t *b, limb_t prec,
 | 
			
		||||
              bf_flags_t flags);
 | 
			
		||||
int bfdec_add_si(bfdec_t *r, const bfdec_t *a, int64_t b1, limb_t prec,
 | 
			
		||||
                 bf_flags_t flags);
 | 
			
		||||
int bfdec_mul(bfdec_t *r, const bfdec_t *a, const bfdec_t *b, limb_t prec,
 | 
			
		||||
              bf_flags_t flags);
 | 
			
		||||
int bfdec_mul_si(bfdec_t *r, const bfdec_t *a, int64_t b1, limb_t prec,
 | 
			
		||||
                 bf_flags_t flags);
 | 
			
		||||
int bfdec_div(bfdec_t *r, const bfdec_t *a, const bfdec_t *b, limb_t prec,
 | 
			
		||||
              bf_flags_t flags);
 | 
			
		||||
int bfdec_divrem(bfdec_t *q, bfdec_t *r, const bfdec_t *a, const bfdec_t *b,
 | 
			
		||||
                 limb_t prec, bf_flags_t flags, int rnd_mode);
 | 
			
		||||
int bfdec_rem(bfdec_t *r, const bfdec_t *a, const bfdec_t *b, limb_t prec,
 | 
			
		||||
              bf_flags_t flags, int rnd_mode);
 | 
			
		||||
int bfdec_rint(bfdec_t *r, int rnd_mode);
 | 
			
		||||
int bfdec_sqrt(bfdec_t *r, const bfdec_t *a, limb_t prec, bf_flags_t flags);
 | 
			
		||||
int bfdec_round(bfdec_t *r, limb_t prec, bf_flags_t flags);
 | 
			
		||||
int bfdec_get_int32(int *pres, const bfdec_t *a);
 | 
			
		||||
int bfdec_pow_ui(bfdec_t *r, const bfdec_t *a, limb_t b);
 | 
			
		||||
 | 
			
		||||
char *bfdec_ftoa(size_t *plen, const bfdec_t *a, limb_t prec, bf_flags_t flags);
 | 
			
		||||
int bfdec_atof(bfdec_t *r, const char *str, const char **pnext,
 | 
			
		||||
               limb_t prec, bf_flags_t flags);
 | 
			
		||||
 | 
			
		||||
/* the following functions are exported for testing only. */
 | 
			
		||||
extern const limb_t mp_pow_dec[LIMB_DIGITS + 1];
 | 
			
		||||
void bfdec_print_str(const char *str, const bfdec_t *a);
 | 
			
		||||
static inline int bfdec_resize(bfdec_t *r, limb_t len)
 | 
			
		||||
{
 | 
			
		||||
    return bf_resize((bf_t *)r, len);
 | 
			
		||||
}
 | 
			
		||||
int bfdec_normalize_and_round(bfdec_t *r, limb_t prec1, bf_flags_t flags);
 | 
			
		||||
 | 
			
		||||
#endif /* LIBBF_H */
 | 
			
		||||
							
								
								
									
										57
									
								
								src/quickjs/libregexp-opcode.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/quickjs/libregexp-opcode.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Regular Expression Engine
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2017-2018 Fabrice Bellard
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 * of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
 * in the Software without restriction, including without limitation the rights
 | 
			
		||||
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
 * copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
 * THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef DEF
 | 
			
		||||
 | 
			
		||||
DEF(invalid, 1) /* never used */
 | 
			
		||||
DEF(char, 3)
 | 
			
		||||
DEF(char32, 5)
 | 
			
		||||
DEF(dot, 1)
 | 
			
		||||
DEF(any, 1) /* same as dot but match any character including line terminator */
 | 
			
		||||
DEF(line_start, 1)
 | 
			
		||||
DEF(line_end, 1)
 | 
			
		||||
DEF(goto, 5)
 | 
			
		||||
DEF(split_goto_first, 5)
 | 
			
		||||
DEF(split_next_first, 5)
 | 
			
		||||
DEF(match, 1)
 | 
			
		||||
DEF(save_start, 2) /* save start position */
 | 
			
		||||
DEF(save_end, 2) /* save end position, must come after saved_start */
 | 
			
		||||
DEF(save_reset, 3) /* reset save positions */
 | 
			
		||||
DEF(loop, 5) /* decrement the top the stack and goto if != 0 */
 | 
			
		||||
DEF(push_i32, 5) /* push integer on the stack */
 | 
			
		||||
DEF(drop, 1)
 | 
			
		||||
DEF(word_boundary, 1)
 | 
			
		||||
DEF(not_word_boundary, 1)
 | 
			
		||||
DEF(back_reference, 2)
 | 
			
		||||
DEF(backward_back_reference, 2) /* must come after back_reference */
 | 
			
		||||
DEF(range, 3) /* variable length */
 | 
			
		||||
DEF(range32, 3) /* variable length */
 | 
			
		||||
DEF(lookahead, 5)
 | 
			
		||||
DEF(negative_lookahead, 5)
 | 
			
		||||
DEF(push_char_pos, 1) /* push the character position on the stack */
 | 
			
		||||
DEF(check_advance, 1) /* pop one stack element and check that it is different from the character position */
 | 
			
		||||
DEF(prev, 1) /* go to the previous char */
 | 
			
		||||
DEF(simple_greedy_quant, 17)
 | 
			
		||||
 | 
			
		||||
#endif /* DEF */
 | 
			
		||||
							
								
								
									
										2528
									
								
								src/quickjs/libregexp.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2528
									
								
								src/quickjs/libregexp.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										92
									
								
								src/quickjs/libregexp.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								src/quickjs/libregexp.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Regular Expression Engine
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2017-2018 Fabrice Bellard
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 * of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
 * in the Software without restriction, including without limitation the rights
 | 
			
		||||
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
 * copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
 * THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef LIBREGEXP_H
 | 
			
		||||
#define LIBREGEXP_H
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
 | 
			
		||||
#include "libunicode.h"
 | 
			
		||||
 | 
			
		||||
#define LRE_BOOL  int       /* for documentation purposes */
 | 
			
		||||
 | 
			
		||||
#define LRE_FLAG_GLOBAL     (1 << 0)
 | 
			
		||||
#define LRE_FLAG_IGNORECASE (1 << 1)
 | 
			
		||||
#define LRE_FLAG_MULTILINE  (1 << 2)
 | 
			
		||||
#define LRE_FLAG_DOTALL     (1 << 3)
 | 
			
		||||
#define LRE_FLAG_UNICODE    (1 << 4)
 | 
			
		||||
#define LRE_FLAG_STICKY     (1 << 5)
 | 
			
		||||
#define LRE_FLAG_INDICES    (1 << 6) /* Unused by libregexp, just recorded. */
 | 
			
		||||
#define LRE_FLAG_NAMED_GROUPS (1 << 7) /* named groups are present in the regexp */
 | 
			
		||||
 | 
			
		||||
uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size,
 | 
			
		||||
                     const char *buf, size_t buf_len, int re_flags,
 | 
			
		||||
                     void *opaque);
 | 
			
		||||
int lre_get_capture_count(const uint8_t *bc_buf);
 | 
			
		||||
int lre_get_flags(const uint8_t *bc_buf);
 | 
			
		||||
const char *lre_get_groupnames(const uint8_t *bc_buf);
 | 
			
		||||
int lre_exec(uint8_t **capture,
 | 
			
		||||
             const uint8_t *bc_buf, const uint8_t *cbuf, int cindex, int clen,
 | 
			
		||||
             int cbuf_type, void *opaque);
 | 
			
		||||
 | 
			
		||||
int lre_parse_escape(const uint8_t **pp, int allow_utf16);
 | 
			
		||||
LRE_BOOL lre_is_space(int c);
 | 
			
		||||
 | 
			
		||||
/* must be provided by the user */
 | 
			
		||||
LRE_BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size);
 | 
			
		||||
void *lre_realloc(void *opaque, void *ptr, size_t size);
 | 
			
		||||
 | 
			
		||||
/* JS identifier test */
 | 
			
		||||
extern uint32_t const lre_id_start_table_ascii[4];
 | 
			
		||||
extern uint32_t const lre_id_continue_table_ascii[4];
 | 
			
		||||
 | 
			
		||||
static inline int lre_js_is_ident_first(int c)
 | 
			
		||||
{
 | 
			
		||||
    if ((uint32_t)c < 128) {
 | 
			
		||||
        return (lre_id_start_table_ascii[c >> 5] >> (c & 31)) & 1;
 | 
			
		||||
    } else {
 | 
			
		||||
#ifdef CONFIG_ALL_UNICODE
 | 
			
		||||
        return lre_is_id_start(c);
 | 
			
		||||
#else
 | 
			
		||||
        return !lre_is_space(c);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int lre_js_is_ident_next(int c)
 | 
			
		||||
{
 | 
			
		||||
    if ((uint32_t)c < 128) {
 | 
			
		||||
        return (lre_id_continue_table_ascii[c >> 5] >> (c & 31)) & 1;
 | 
			
		||||
    } else {
 | 
			
		||||
        /* ZWNJ and ZWJ are accepted in identifiers */
 | 
			
		||||
#ifdef CONFIG_ALL_UNICODE
 | 
			
		||||
        return lre_is_id_continue(c) || c == 0x200C || c == 0x200D;
 | 
			
		||||
#else
 | 
			
		||||
        return !lre_is_space(c) || c == 0x200C || c == 0x200D;
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#undef LRE_BOOL
 | 
			
		||||
 | 
			
		||||
#endif /* LIBREGEXP_H */
 | 
			
		||||
							
								
								
									
										4486
									
								
								src/quickjs/libunicode-table.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4486
									
								
								src/quickjs/libunicode-table.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1788
									
								
								src/quickjs/libunicode.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1788
									
								
								src/quickjs/libunicode.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										127
									
								
								src/quickjs/libunicode.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								src/quickjs/libunicode.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,127 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Unicode utilities
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2017-2018 Fabrice Bellard
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 * of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
 * in the Software without restriction, including without limitation the rights
 | 
			
		||||
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
 * copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
 * THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef LIBUNICODE_H
 | 
			
		||||
#define LIBUNICODE_H
 | 
			
		||||
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
 | 
			
		||||
#define LRE_BOOL  int       /* for documentation purposes */
 | 
			
		||||
 | 
			
		||||
/* define it to include all the unicode tables (40KB larger) */
 | 
			
		||||
#define CONFIG_ALL_UNICODE
 | 
			
		||||
 | 
			
		||||
#define LRE_CC_RES_LEN_MAX 3
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
    UNICODE_NFC,
 | 
			
		||||
    UNICODE_NFD,
 | 
			
		||||
    UNICODE_NFKC,
 | 
			
		||||
    UNICODE_NFKD,
 | 
			
		||||
} UnicodeNormalizationEnum;
 | 
			
		||||
 | 
			
		||||
int lre_case_conv(uint32_t *res, uint32_t c, int conv_type);
 | 
			
		||||
int lre_canonicalize(uint32_t c, LRE_BOOL is_unicode);
 | 
			
		||||
LRE_BOOL lre_is_cased(uint32_t c);
 | 
			
		||||
LRE_BOOL lre_is_case_ignorable(uint32_t c);
 | 
			
		||||
 | 
			
		||||
/* char ranges */
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    int len; /* in points, always even */
 | 
			
		||||
    int size;
 | 
			
		||||
    uint32_t *points; /* points sorted by increasing value */
 | 
			
		||||
    void *mem_opaque;
 | 
			
		||||
    void *(*realloc_func)(void *opaque, void *ptr, size_t size);
 | 
			
		||||
} CharRange;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
    CR_OP_UNION,
 | 
			
		||||
    CR_OP_INTER,
 | 
			
		||||
    CR_OP_XOR,
 | 
			
		||||
} CharRangeOpEnum;
 | 
			
		||||
 | 
			
		||||
void cr_init(CharRange *cr, void *mem_opaque, void *(*realloc_func)(void *opaque, void *ptr, size_t size));
 | 
			
		||||
void cr_free(CharRange *cr);
 | 
			
		||||
int cr_realloc(CharRange *cr, int size);
 | 
			
		||||
int cr_copy(CharRange *cr, const CharRange *cr1);
 | 
			
		||||
 | 
			
		||||
static inline int cr_add_point(CharRange *cr, uint32_t v)
 | 
			
		||||
{
 | 
			
		||||
    if (cr->len >= cr->size) {
 | 
			
		||||
        if (cr_realloc(cr, cr->len + 1))
 | 
			
		||||
            return -1;
 | 
			
		||||
    }
 | 
			
		||||
    cr->points[cr->len++] = v;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int cr_add_interval(CharRange *cr, uint32_t c1, uint32_t c2)
 | 
			
		||||
{
 | 
			
		||||
    if ((cr->len + 2) > cr->size) {
 | 
			
		||||
        if (cr_realloc(cr, cr->len + 2))
 | 
			
		||||
            return -1;
 | 
			
		||||
    }
 | 
			
		||||
    cr->points[cr->len++] = c1;
 | 
			
		||||
    cr->points[cr->len++] = c2;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cr_union1(CharRange *cr, const uint32_t *b_pt, int b_len);
 | 
			
		||||
 | 
			
		||||
static inline int cr_union_interval(CharRange *cr, uint32_t c1, uint32_t c2)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t b_pt[2];
 | 
			
		||||
    b_pt[0] = c1;
 | 
			
		||||
    b_pt[1] = c2 + 1;
 | 
			
		||||
    return cr_union1(cr, b_pt, 2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cr_op(CharRange *cr, const uint32_t *a_pt, int a_len,
 | 
			
		||||
          const uint32_t *b_pt, int b_len, int op);
 | 
			
		||||
 | 
			
		||||
int cr_invert(CharRange *cr);
 | 
			
		||||
 | 
			
		||||
int cr_regexp_canonicalize(CharRange *cr, LRE_BOOL is_unicode);
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_ALL_UNICODE
 | 
			
		||||
 | 
			
		||||
LRE_BOOL lre_is_id_start(uint32_t c);
 | 
			
		||||
LRE_BOOL lre_is_id_continue(uint32_t c);
 | 
			
		||||
 | 
			
		||||
int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len,
 | 
			
		||||
                      UnicodeNormalizationEnum n_type,
 | 
			
		||||
                      void *opaque, void *(*realloc_func)(void *opaque, void *ptr, size_t size));
 | 
			
		||||
 | 
			
		||||
/* Unicode character range functions */
 | 
			
		||||
 | 
			
		||||
int unicode_script(CharRange *cr,
 | 
			
		||||
                   const char *script_name, LRE_BOOL is_ext);
 | 
			
		||||
int unicode_general_category(CharRange *cr, const char *gc_name);
 | 
			
		||||
int unicode_prop(CharRange *cr, const char *prop_name);
 | 
			
		||||
 | 
			
		||||
#endif /* CONFIG_ALL_UNICODE */
 | 
			
		||||
 | 
			
		||||
#undef LRE_BOOL
 | 
			
		||||
 | 
			
		||||
#endif /* LIBUNICODE_H */
 | 
			
		||||
							
								
								
									
										153
									
								
								src/quickjs/libutf.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								src/quickjs/libutf.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,153 @@
 | 
			
		||||
#include <libutf.h>
 | 
			
		||||
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
LibutfC16Type libutf_c16_type(uint_least16_t c16) {
 | 
			
		||||
    if (0xD800 != (0xF800 & c16)) {
 | 
			
		||||
        return LIBUTF_UTF16_NOT_SURROGATE;
 | 
			
		||||
    }
 | 
			
		||||
    return (c16 & 0x0400) ? LIBUTF_UTF16_SURROGATE_LOW : LIBUTF_UTF16_SURROGATE_HIGH;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LibutfC8Type libutf_c8_type(char c) {
 | 
			
		||||
    static const LibutfC8Type lookup_table[256] = {
 | 
			
		||||
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 | 
			
		||||
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 | 
			
		||||
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 | 
			
		||||
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 | 
			
		||||
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 | 
			
		||||
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 | 
			
		||||
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 | 
			
		||||
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 | 
			
		||||
           -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
 | 
			
		||||
           -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
 | 
			
		||||
           -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
 | 
			
		||||
           -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
 | 
			
		||||
            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
 | 
			
		||||
            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
 | 
			
		||||
            3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
 | 
			
		||||
            4, 4, 4, 4, 4, 4, 4, 4,-2,-2,-2,-2,-2,-2,-2,-2,
 | 
			
		||||
    };
 | 
			
		||||
    return lookup_table[(unsigned char) c];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool libutf_c32_to_c8(uint_least32_t c32, int *length, char c8[4]) {
 | 
			
		||||
    if (!libutf_c32_is_valid(c32)) {
 | 
			
		||||
        *length = 3;
 | 
			
		||||
        c8[0] = (char) 0xEF;
 | 
			
		||||
        c8[1] = (char) 0xBF;
 | 
			
		||||
        c8[2] = (char) 0xBD;
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    if (c32 <= 0x007F) {
 | 
			
		||||
        c8[0] = c32;
 | 
			
		||||
        *length = 1;
 | 
			
		||||
        return true;
 | 
			
		||||
    } else if (c32 <= 0x07FF) {
 | 
			
		||||
        c8[0] = (char) (0xC0 | (c32 >> 6));
 | 
			
		||||
        c8[1] = (char) (0x80 | (c32 & 0x3F));
 | 
			
		||||
        *length = 2;
 | 
			
		||||
        return true;
 | 
			
		||||
    } else if (c32 <= 0xFFFF) {
 | 
			
		||||
        c8[0] = (char) (0xE0 | (c32 >> 12));
 | 
			
		||||
        c8[1] = (char) (0x80 | ((c32 >> 6) & 0x3F));
 | 
			
		||||
        c8[2] = (char) (0x80 | (c32 & 0x3F));
 | 
			
		||||
        *length = 3;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    assert(c32 <= 0x10FFFF);
 | 
			
		||||
    c8[0] = (char) (0xF0 | (c32 >> 18));
 | 
			
		||||
    c8[1] = (char) (0x80 | ((c32 >> 12) & 0x3F));
 | 
			
		||||
    c8[2] = (char) (0x80 | ((c32 >> 6) & 0x3F));
 | 
			
		||||
    c8[3] = (char) (0x80 | (c32 & 0x3F));
 | 
			
		||||
    *length = 4;
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool libutf_c8_to_c32(const char *c8, uint_least32_t *c32) {
 | 
			
		||||
    if (!c8 || !c32) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    unsigned char c = *c8;
 | 
			
		||||
    *c32 = 0xFFFD;
 | 
			
		||||
    LibutfC8Type type = libutf_c8_type(c);
 | 
			
		||||
    if (type < 0) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    int len = type;
 | 
			
		||||
    uint_least32_t result;
 | 
			
		||||
    switch (len) {
 | 
			
		||||
    case 1:
 | 
			
		||||
        *c32 = c;
 | 
			
		||||
        return true;
 | 
			
		||||
    case 2:
 | 
			
		||||
        result = c & 0x1F;
 | 
			
		||||
        break;
 | 
			
		||||
    case 3:
 | 
			
		||||
        result = c & 0x0F;
 | 
			
		||||
        break;
 | 
			
		||||
    case 4:
 | 
			
		||||
        result = c & 0x07;
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        abort();
 | 
			
		||||
    }
 | 
			
		||||
    for (int i = 1; i < len; ++i) {
 | 
			
		||||
        c = *++c8;
 | 
			
		||||
        if ((0xC0 & c) != 0x80) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        result = (result << 6) + (c & 0x3F);
 | 
			
		||||
    }
 | 
			
		||||
    if (!libutf_c32_is_valid(result)) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    char c8seq[4];
 | 
			
		||||
    int n;
 | 
			
		||||
    bool ok = libutf_c32_to_c8(result, &n, c8seq);
 | 
			
		||||
    assert(ok);
 | 
			
		||||
    if (n < (int) len) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    *c32 = result;
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool libutf_c32_to_c16(uint_least32_t c32, int *length, uint_least16_t c16[2]) {
 | 
			
		||||
    if (!libutf_c32_is_valid(c32)) {
 | 
			
		||||
        c16[0] = 0xFFFD;
 | 
			
		||||
        c16[1] = 0;
 | 
			
		||||
        *length = 1;
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    if (c32 < 0x10000) {
 | 
			
		||||
        c16[0] = c32;
 | 
			
		||||
        c16[1] = 0;
 | 
			
		||||
        *length = 1;
 | 
			
		||||
    } else {
 | 
			
		||||
        c32 -= 0x10000;
 | 
			
		||||
        c16[0] = 0xD800 | (c32 >> 10);
 | 
			
		||||
        c16[1] = 0xDC00 | (c32 & 0x3FF);
 | 
			
		||||
        *length = 2;
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool libutf_c16_to_c32(uint_least16_t c16[2], uint_least32_t *c32) {
 | 
			
		||||
    LibutfC16Type type = libutf_c16_type(c16[0]);
 | 
			
		||||
    if (LIBUTF_UTF16_NOT_SURROGATE == type) {
 | 
			
		||||
        *c32 = c16[0];
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    if (LIBUTF_UTF16_SURROGATE_HIGH != type || LIBUTF_UTF16_SURROGATE_LOW != libutf_c16_type(c16[1])) {
 | 
			
		||||
        *c32 = 0xFFFD;
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    *c32 = 0x10000 + ((c16[0] & 0x3FF) << 10) + (c16[1] & 0x3ff);
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool libutf_c32_is_valid(uint_least32_t c32) {
 | 
			
		||||
    return c32 < 0xD800 || (0xDFFF < c32 && c32 < 0x110000);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										109
									
								
								src/quickjs/libutf.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								src/quickjs/libutf.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,109 @@
 | 
			
		||||
/* LIBrary of UTF-(8,16,32) helper utility functions.
 | 
			
		||||
 *
 | 
			
		||||
 * Terminology:
 | 
			
		||||
 * code point = number of a Unicode character
 | 
			
		||||
 * code unit
 | 
			
		||||
 *   = 1 byte  for UTF-8
 | 
			
		||||
 *   = 2 bytes for UTF-16
 | 
			
		||||
 *   = 4 bytes for UTF-32
 | 
			
		||||
 * sequence = sequence of code units encoding SINGLE Unicode character
 | 
			
		||||
 *
 | 
			
		||||
 * Unicode has code points 0x000000..0x10FFFF except for the codes 0xD800..0xDFFF which are
 | 
			
		||||
 * reserved for UTF-16 surrogate pairs.
 | 
			
		||||
 *
 | 
			
		||||
 * UTF-32 is the simplest Unicode encoding. It encodes Unicode code points as is. Thus we may use
 | 
			
		||||
 * UTF-32 as a synonym for Unicode code point.
 | 
			
		||||
 * + O(1) indexing
 | 
			
		||||
 * - the text is 2-4 times bigger than in other encodings
 | 
			
		||||
 *
 | 
			
		||||
 * UTF-16 is variable width encoding. Each Unicode code point is represented as either single
 | 
			
		||||
 * code unit (two-byte number) or two code units which are called surrogate pairs.
 | 
			
		||||
 * - ASCII-only texts will be twice as big as in ASCII
 | 
			
		||||
 * - O(n) indexing
 | 
			
		||||
 *
 | 
			
		||||
 * UTF-8 is a variable width encoding. Each Unicode code point is represented as a sequence
 | 
			
		||||
 * of up to 4 bytes. The first byte determines the length of the sequence.
 | 
			
		||||
 * + is a superset of ASCII
 | 
			
		||||
 * + ASCII-only texts will have the same size
 | 
			
		||||
 * - O(n) indexing
 | 
			
		||||
 * - single Unicode code point can have different representations in
 | 
			
		||||
 *   UTF-8, only the shortest one is considered valid
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef LIBUTF_H
 | 
			
		||||
#define LIBUTF_H
 | 
			
		||||
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
// UTF-8 code unit type
 | 
			
		||||
typedef enum {
 | 
			
		||||
    LIBUTF_UTF8_OVERLONG   = -2,
 | 
			
		||||
    LIBUTF_UTF8_TRAILING   = -1,
 | 
			
		||||
    LIBUTF_UTF8_ONE_BYTE   = 1,
 | 
			
		||||
    LIBUTF_UTF8_TWO_BYTE   = 2,
 | 
			
		||||
    LIBUTF_UTF8_THREE_BYTE = 3,
 | 
			
		||||
    LIBUTF_UTF8_FOUR_BYTE  = 4,
 | 
			
		||||
} LibutfC8Type;
 | 
			
		||||
 | 
			
		||||
// UTF-16 code unit type
 | 
			
		||||
typedef enum {
 | 
			
		||||
    LIBUTF_UTF16_SURROGATE_LOW  = -1,
 | 
			
		||||
    LIBUTF_UTF16_NOT_SURROGATE  = 1,
 | 
			
		||||
    LIBUTF_UTF16_SURROGATE_HIGH = 2,
 | 
			
		||||
} LibutfC16Type;
 | 
			
		||||
 | 
			
		||||
/* Determine type of UTF-16 code unit. type = length of UTF-16 sequence starting with the specified code unit
 | 
			
		||||
 * or negative value if sequence cannot start with this code unit. */
 | 
			
		||||
LibutfC16Type libutf_c16_type(uint_least16_t c16);
 | 
			
		||||
 | 
			
		||||
/* Determine type of UTF-8 sequence based on the first byte. type = length of UTF-8 sequence starting
 | 
			
		||||
 * with this byte or negative value if the byte cannot be first. UTF-8 may be up to 4 bytes long.
 | 
			
		||||
 * Common idiom for using this function:
 | 
			
		||||
 * >>> LibutfC8Type type = libutf_c8_type(c);
 | 
			
		||||
 * >>> if (type < 0) {
 | 
			
		||||
 * >>>     return ERROR_CODE;
 | 
			
		||||
 * >>> }
 | 
			
		||||
 * >>> int length = type;
 | 
			
		||||
 * */
 | 
			
		||||
LibutfC8Type libutf_c8_type(char c);
 | 
			
		||||
 | 
			
		||||
/* Convert Unicode code point into UTF-8 sequence. If c32 is not a valid
 | 
			
		||||
 * Unicode code point c8 will be filled with UTF-8 representation of special
 | 
			
		||||
 * replacement character U+FFFD, *length will be set to its length and false will be returned.
 | 
			
		||||
 * c32    -- UTF-32 Unicode code point
 | 
			
		||||
 * length -- where to put length of the UTF-8 sequence.
 | 
			
		||||
 * c8     -- where to put UTF-8 sequence. Make sure string has enough space.
 | 
			
		||||
 * result -- true if c32 is a valid Unicode code point or false otherwise. */
 | 
			
		||||
bool libutf_c32_to_c8(uint_least32_t c32, int *length, char c8[4]);
 | 
			
		||||
 | 
			
		||||
/* Convert UTF-8 sequence into a UTF-32 Unicode code point. If c8 does not
 | 
			
		||||
 * point to a valid UTF-8 sequence c32 will be filled with special replacement
 | 
			
		||||
 * character U+FFFD and false will be returned.
 | 
			
		||||
 * c8     -- pointer to UTF-8 sequence.
 | 
			
		||||
 * c32    -- where to save UTF-32 Unicode code point.
 | 
			
		||||
 * result -- true if c8 points to a valid UTF-8 sequence or false otherwise. */
 | 
			
		||||
bool libutf_c8_to_c32(const char *c8, uint_least32_t *c32);
 | 
			
		||||
 | 
			
		||||
/* Convert UTF-32 Unicode code point into UTF-16 sequence. If c32 is not a valid
 | 
			
		||||
 * Unicode code point c16 will be filled with UTF-16 representation of special
 | 
			
		||||
 * replacement character U+FFFD and false will be returned.
 | 
			
		||||
 * c32    -- UTF-32 Unicode code point.
 | 
			
		||||
 * length -- were to put length of UTF-16 sequence.
 | 
			
		||||
 * c16    -- where to put UTF-16 sequence (c16[0] -- high surrogate, c16[1] -- low surrogate)
 | 
			
		||||
 * result -- true if c32 is a valid Unicode code point or false otherwise. */
 | 
			
		||||
bool libutf_c32_to_c16(uint_least32_t c32, int *length, uint_least16_t c16[2]);
 | 
			
		||||
 | 
			
		||||
/* Construct UTF-32 Unicode code point from UTF-16 surrogate pair. high
 | 
			
		||||
 * must be high surrogate and low must be low surrogate otherwise *c32 will
 | 
			
		||||
 * be filled with special replacement character U+FFFD and false will be returned.
 | 
			
		||||
 * c16    -- where to put UTF-16 sequence (c32[0] -- high surrogate, c32[1] -- low surrogate)
 | 
			
		||||
 * result -- true if c16 points to a valid UTF-16 sequence (single not surrogate
 | 
			
		||||
 * or valid surrogate pair) or false otherwise. */
 | 
			
		||||
bool libutf_c16_to_c32(uint_least16_t c16[2], uint_least32_t *c32);
 | 
			
		||||
 | 
			
		||||
/* Check whether given value is a valid Unicode code point i.e. below 0x110000 and is not
 | 
			
		||||
 * a UTF-16 surrogate. */
 | 
			
		||||
bool libutf_c32_is_valid(uint_least32_t c32);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										99
									
								
								src/quickjs/list.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								src/quickjs/list.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,99 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Linux klist like system
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2016-2017 Fabrice Bellard
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 * of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
 * in the Software without restriction, including without limitation the rights
 | 
			
		||||
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
 * copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
 * THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef LIST_H
 | 
			
		||||
#define LIST_H
 | 
			
		||||
 | 
			
		||||
#ifndef NULL
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
struct list_head {
 | 
			
		||||
    struct list_head *prev;
 | 
			
		||||
    struct list_head *next;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define LIST_HEAD_INIT(el) { &(el), &(el) }
 | 
			
		||||
 | 
			
		||||
/* return the pointer of type 'type *' containing 'el' as field 'member' */
 | 
			
		||||
#define list_entry(el, type, member) container_of(el, type, member)
 | 
			
		||||
 | 
			
		||||
static inline void init_list_head(struct list_head *head)
 | 
			
		||||
{
 | 
			
		||||
    head->prev = head;
 | 
			
		||||
    head->next = head;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* insert 'el' between 'prev' and 'next' */
 | 
			
		||||
static inline void __list_add(struct list_head *el,
 | 
			
		||||
                              struct list_head *prev, struct list_head *next)
 | 
			
		||||
{
 | 
			
		||||
    prev->next = el;
 | 
			
		||||
    el->prev = prev;
 | 
			
		||||
    el->next = next;
 | 
			
		||||
    next->prev = el;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* add 'el' at the head of the list 'head' (= after element head) */
 | 
			
		||||
static inline void list_add(struct list_head *el, struct list_head *head)
 | 
			
		||||
{
 | 
			
		||||
    __list_add(el, head, head->next);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* add 'el' at the end of the list 'head' (= before element head) */
 | 
			
		||||
static inline void list_add_tail(struct list_head *el, struct list_head *head)
 | 
			
		||||
{
 | 
			
		||||
    __list_add(el, head->prev, head);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void list_del(struct list_head *el)
 | 
			
		||||
{
 | 
			
		||||
    struct list_head *prev, *next;
 | 
			
		||||
    prev = el->prev;
 | 
			
		||||
    next = el->next;
 | 
			
		||||
    prev->next = next;
 | 
			
		||||
    next->prev = prev;
 | 
			
		||||
    el->prev = NULL; /* fail safe */
 | 
			
		||||
    el->next = NULL; /* fail safe */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int list_empty(struct list_head *el)
 | 
			
		||||
{
 | 
			
		||||
    return el->next == el;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define list_for_each(el, head) \
 | 
			
		||||
  for(el = (head)->next; el != (head); el = el->next)
 | 
			
		||||
 | 
			
		||||
#define list_for_each_safe(el, el1, head)                \
 | 
			
		||||
    for(el = (head)->next, el1 = el->next; el != (head); \
 | 
			
		||||
        el = el1, el1 = el->next)
 | 
			
		||||
 | 
			
		||||
#define list_for_each_prev(el, head) \
 | 
			
		||||
  for(el = (head)->prev; el != (head); el = el->prev)
 | 
			
		||||
 | 
			
		||||
#define list_for_each_prev_safe(el, el1, head)           \
 | 
			
		||||
    for(el = (head)->prev, el1 = el->prev; el != (head); \
 | 
			
		||||
        el = el1, el1 = el->prev)
 | 
			
		||||
 | 
			
		||||
#endif /* LIST_H */
 | 
			
		||||
							
								
								
									
										552
									
								
								src/quickjs/qjs.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										552
									
								
								src/quickjs/qjs.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,552 @@
 | 
			
		||||
/*
 | 
			
		||||
 * QuickJS stand alone interpreter
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2017-2021 Fabrice Bellard
 | 
			
		||||
 * Copyright (c) 2017-2021 Charlie Gordon
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 * of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
 * in the Software without restriction, including without limitation the rights
 | 
			
		||||
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
 * copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
 * THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#if defined(__APPLE__)
 | 
			
		||||
#include <malloc/malloc.h>
 | 
			
		||||
#elif defined(__linux__)
 | 
			
		||||
#include <malloc.h>
 | 
			
		||||
#elif defined(__FreeBSD__)
 | 
			
		||||
#include <malloc_np.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "cutils.h"
 | 
			
		||||
#include "quickjs-libc.h"
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_BIGNUM
 | 
			
		||||
static int bignum_ext;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static int eval_buf(JSContext *ctx, const void *buf, int buf_len,
 | 
			
		||||
                    const char *filename, int eval_flags)
 | 
			
		||||
{
 | 
			
		||||
    JSValue val;
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    if ((eval_flags & JS_EVAL_TYPE_MASK) == JS_EVAL_TYPE_MODULE) {
 | 
			
		||||
        /* for the modules, we compile then run to be able to set
 | 
			
		||||
           import.meta */
 | 
			
		||||
        val = JS_Eval(ctx, buf, buf_len, filename,
 | 
			
		||||
                      eval_flags | JS_EVAL_FLAG_COMPILE_ONLY);
 | 
			
		||||
        if (!JS_IsException(val)) {
 | 
			
		||||
            js_module_set_import_meta(ctx, val, TRUE, TRUE);
 | 
			
		||||
            val = JS_EvalFunction(ctx, val);
 | 
			
		||||
        }
 | 
			
		||||
        val = js_std_await(ctx, val);
 | 
			
		||||
    } else {
 | 
			
		||||
        val = JS_Eval(ctx, buf, buf_len, filename, eval_flags);
 | 
			
		||||
    }
 | 
			
		||||
    if (JS_IsException(val)) {
 | 
			
		||||
        js_std_dump_error(ctx);
 | 
			
		||||
        ret = -1;
 | 
			
		||||
    } else {
 | 
			
		||||
        ret = 0;
 | 
			
		||||
    }
 | 
			
		||||
    JS_FreeValue(ctx, val);
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int eval_file(JSContext *ctx, const char *filename, int module)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t *buf;
 | 
			
		||||
    int ret, eval_flags;
 | 
			
		||||
    size_t buf_len;
 | 
			
		||||
 | 
			
		||||
    buf = js_load_file(ctx, &buf_len, filename);
 | 
			
		||||
    if (!buf) {
 | 
			
		||||
        perror(filename);
 | 
			
		||||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (module < 0) {
 | 
			
		||||
        module = (has_suffix(filename, ".mjs") ||
 | 
			
		||||
                  JS_DetectModule((const char *)buf, buf_len));
 | 
			
		||||
    }
 | 
			
		||||
    if (module)
 | 
			
		||||
        eval_flags = JS_EVAL_TYPE_MODULE;
 | 
			
		||||
    else
 | 
			
		||||
        eval_flags = JS_EVAL_TYPE_GLOBAL;
 | 
			
		||||
    ret = eval_buf(ctx, buf, buf_len, filename, eval_flags);
 | 
			
		||||
    js_free(ctx, buf);
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* also used to initialize the worker context */
 | 
			
		||||
static JSContext *JS_NewCustomContext(JSRuntime *rt)
 | 
			
		||||
{
 | 
			
		||||
    JSContext *ctx;
 | 
			
		||||
    ctx = JS_NewContext(rt);
 | 
			
		||||
    if (!ctx)
 | 
			
		||||
        return NULL;
 | 
			
		||||
#ifdef CONFIG_BIGNUM
 | 
			
		||||
    if (bignum_ext) {
 | 
			
		||||
        JS_AddIntrinsicBigFloat(ctx);
 | 
			
		||||
        JS_AddIntrinsicBigDecimal(ctx);
 | 
			
		||||
        JS_AddIntrinsicOperators(ctx);
 | 
			
		||||
        JS_EnableBignumExt(ctx, TRUE);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    /* system modules */
 | 
			
		||||
    js_init_module_std(ctx, "std");
 | 
			
		||||
    js_init_module_os(ctx, "os");
 | 
			
		||||
    return ctx;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(__APPLE__)
 | 
			
		||||
#define MALLOC_OVERHEAD  0
 | 
			
		||||
#else
 | 
			
		||||
#define MALLOC_OVERHEAD  8
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
struct trace_malloc_data {
 | 
			
		||||
    uint8_t *base;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static inline unsigned long long js_trace_malloc_ptr_offset(uint8_t *ptr,
 | 
			
		||||
                                                struct trace_malloc_data *dp)
 | 
			
		||||
{
 | 
			
		||||
    return ptr - dp->base;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* default memory allocation functions with memory limitation */
 | 
			
		||||
static size_t js_trace_malloc_usable_size(const void *ptr)
 | 
			
		||||
{
 | 
			
		||||
#if defined(__APPLE__)
 | 
			
		||||
    return malloc_size(ptr);
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
    return _msize((void *)ptr);
 | 
			
		||||
#elif defined(EMSCRIPTEN)
 | 
			
		||||
    return 0;
 | 
			
		||||
#elif defined(__linux__)
 | 
			
		||||
    return malloc_usable_size((void *)ptr);
 | 
			
		||||
#else
 | 
			
		||||
    /* change this to `return 0;` if compilation fails */
 | 
			
		||||
    return malloc_usable_size((void *)ptr);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
/* mingw printf is used */
 | 
			
		||||
__attribute__((format(gnu_printf, 2, 3)))
 | 
			
		||||
#else
 | 
			
		||||
__attribute__((format(printf, 2, 3)))
 | 
			
		||||
#endif
 | 
			
		||||
    js_trace_malloc_printf(JSMallocState *s, const char *fmt, ...)
 | 
			
		||||
{
 | 
			
		||||
    va_list ap;
 | 
			
		||||
    int c;
 | 
			
		||||
 | 
			
		||||
    va_start(ap, fmt);
 | 
			
		||||
    while ((c = *fmt++) != '\0') {
 | 
			
		||||
        if (c == '%') {
 | 
			
		||||
            /* only handle %p and %zd */
 | 
			
		||||
            if (*fmt == 'p') {
 | 
			
		||||
                uint8_t *ptr = va_arg(ap, void *);
 | 
			
		||||
                if (ptr == NULL) {
 | 
			
		||||
                    printf("NULL");
 | 
			
		||||
                } else {
 | 
			
		||||
                    printf("H%+06lld.%zd",
 | 
			
		||||
                           js_trace_malloc_ptr_offset(ptr, s->opaque),
 | 
			
		||||
                           js_trace_malloc_usable_size(ptr));
 | 
			
		||||
                }
 | 
			
		||||
                fmt++;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (fmt[0] == 'z' && fmt[1] == 'd') {
 | 
			
		||||
                size_t sz = va_arg(ap, size_t);
 | 
			
		||||
                printf("%zd", sz);
 | 
			
		||||
                fmt += 2;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        putc(c, stdout);
 | 
			
		||||
    }
 | 
			
		||||
    va_end(ap);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void js_trace_malloc_init(struct trace_malloc_data *s)
 | 
			
		||||
{
 | 
			
		||||
    free(s->base = malloc(8));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void *js_trace_malloc(JSMallocState *s, size_t size)
 | 
			
		||||
{
 | 
			
		||||
    void *ptr;
 | 
			
		||||
 | 
			
		||||
    /* Do not allocate zero bytes: behavior is platform dependent */
 | 
			
		||||
    assert(size != 0);
 | 
			
		||||
 | 
			
		||||
    if (unlikely(s->malloc_size + size > s->malloc_limit))
 | 
			
		||||
        return NULL;
 | 
			
		||||
    ptr = malloc(size);
 | 
			
		||||
    js_trace_malloc_printf(s, "A %zd -> %p\n", size, ptr);
 | 
			
		||||
    if (ptr) {
 | 
			
		||||
        s->malloc_count++;
 | 
			
		||||
        s->malloc_size += js_trace_malloc_usable_size(ptr) + MALLOC_OVERHEAD;
 | 
			
		||||
    }
 | 
			
		||||
    return ptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void js_trace_free(JSMallocState *s, void *ptr)
 | 
			
		||||
{
 | 
			
		||||
    if (!ptr)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    js_trace_malloc_printf(s, "F %p\n", ptr);
 | 
			
		||||
    s->malloc_count--;
 | 
			
		||||
    s->malloc_size -= js_trace_malloc_usable_size(ptr) + MALLOC_OVERHEAD;
 | 
			
		||||
    free(ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void *js_trace_realloc(JSMallocState *s, void *ptr, size_t size)
 | 
			
		||||
{
 | 
			
		||||
    size_t old_size;
 | 
			
		||||
 | 
			
		||||
    if (!ptr) {
 | 
			
		||||
        if (size == 0)
 | 
			
		||||
            return NULL;
 | 
			
		||||
        return js_trace_malloc(s, size);
 | 
			
		||||
    }
 | 
			
		||||
    old_size = js_trace_malloc_usable_size(ptr);
 | 
			
		||||
    if (size == 0) {
 | 
			
		||||
        js_trace_malloc_printf(s, "R %zd %p\n", size, ptr);
 | 
			
		||||
        s->malloc_count--;
 | 
			
		||||
        s->malloc_size -= old_size + MALLOC_OVERHEAD;
 | 
			
		||||
        free(ptr);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
    if (s->malloc_size + size - old_size > s->malloc_limit)
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    js_trace_malloc_printf(s, "R %zd %p", size, ptr);
 | 
			
		||||
 | 
			
		||||
    ptr = realloc(ptr, size);
 | 
			
		||||
    js_trace_malloc_printf(s, " -> %p\n", ptr);
 | 
			
		||||
    if (ptr) {
 | 
			
		||||
        s->malloc_size += js_trace_malloc_usable_size(ptr) - old_size;
 | 
			
		||||
    }
 | 
			
		||||
    return ptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const JSMallocFunctions trace_mf = {
 | 
			
		||||
    js_trace_malloc,
 | 
			
		||||
    js_trace_free,
 | 
			
		||||
    js_trace_realloc,
 | 
			
		||||
    js_trace_malloc_usable_size,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define PROG_NAME "qjs"
 | 
			
		||||
 | 
			
		||||
void help(void)
 | 
			
		||||
{
 | 
			
		||||
    printf("QuickJS lite\n"
 | 
			
		||||
           "usage: " PROG_NAME " [options] [file [args]]\n"
 | 
			
		||||
           "-h  --help         list options\n"
 | 
			
		||||
           "-e  --eval EXPR    evaluate EXPR\n"
 | 
			
		||||
           "-i  --interactive  go to interactive mode\n"
 | 
			
		||||
           "-m  --module       load as ES6 module (default=autodetect)\n"
 | 
			
		||||
           "    --script       load as ES6 script (default=autodetect)\n"
 | 
			
		||||
           "-I  --include file include an additional file\n"
 | 
			
		||||
           "    --std          make 'std' and 'os' available to the loaded script\n"
 | 
			
		||||
#ifdef CONFIG_BIGNUM
 | 
			
		||||
           "    --bignum       enable the bignum extensions (BigFloat, BigDecimal)\n"
 | 
			
		||||
           "    --qjscalc      load the QJSCalc runtime (default if invoked as qjscalc)\n"
 | 
			
		||||
#endif
 | 
			
		||||
           "-T  --trace        trace memory allocation\n"
 | 
			
		||||
           "-d  --dump         dump the memory usage stats\n"
 | 
			
		||||
           "    --memory-limit n       limit the memory usage to 'n' bytes\n"
 | 
			
		||||
           "    --stack-size n         limit the stack size to 'n' bytes\n"
 | 
			
		||||
           "    --unhandled-rejection  dump unhandled promise rejections\n"
 | 
			
		||||
           "-q  --quit         just instantiate the interpreter and quit\n");
 | 
			
		||||
    exit(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
    JSRuntime *rt;
 | 
			
		||||
    JSContext *ctx;
 | 
			
		||||
    struct trace_malloc_data trace_data = { NULL };
 | 
			
		||||
    int optind;
 | 
			
		||||
    char *expr = NULL;
 | 
			
		||||
    int interactive = 0;
 | 
			
		||||
    int dump_memory = 0;
 | 
			
		||||
    int trace_memory = 0;
 | 
			
		||||
    int empty_run = 0;
 | 
			
		||||
    int module = -1;
 | 
			
		||||
    int load_std = 0;
 | 
			
		||||
    int dump_unhandled_promise_rejection = 0;
 | 
			
		||||
    size_t memory_limit = 0;
 | 
			
		||||
    char *include_list[32];
 | 
			
		||||
    int i, include_count = 0;
 | 
			
		||||
#ifdef CONFIG_BIGNUM
 | 
			
		||||
    int load_jscalc;
 | 
			
		||||
#endif
 | 
			
		||||
    size_t stack_size = 0;
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_BIGNUM
 | 
			
		||||
    /* load jscalc runtime if invoked as 'qjscalc' */
 | 
			
		||||
    {
 | 
			
		||||
        const char *p, *exename;
 | 
			
		||||
        exename = argv[0];
 | 
			
		||||
        p = strrchr(exename, '/');
 | 
			
		||||
        if (p)
 | 
			
		||||
            exename = p + 1;
 | 
			
		||||
        load_jscalc = !strcmp(exename, "qjscalc");
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /* cannot use getopt because we want to pass the command line to
 | 
			
		||||
       the script */
 | 
			
		||||
    optind = 1;
 | 
			
		||||
    while (optind < argc && *argv[optind] == '-') {
 | 
			
		||||
        char *arg = argv[optind] + 1;
 | 
			
		||||
        const char *longopt = "";
 | 
			
		||||
        /* a single - is not an option, it also stops argument scanning */
 | 
			
		||||
        if (!*arg)
 | 
			
		||||
            break;
 | 
			
		||||
        optind++;
 | 
			
		||||
        if (*arg == '-') {
 | 
			
		||||
            longopt = arg + 1;
 | 
			
		||||
            arg += strlen(arg);
 | 
			
		||||
            /* -- stops argument scanning */
 | 
			
		||||
            if (!*longopt)
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
        for (; *arg || *longopt; longopt = "") {
 | 
			
		||||
            char opt = *arg;
 | 
			
		||||
            if (opt)
 | 
			
		||||
                arg++;
 | 
			
		||||
            if (opt == 'h' || opt == '?' || !strcmp(longopt, "help")) {
 | 
			
		||||
                help();
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (opt == 'e' || !strcmp(longopt, "eval")) {
 | 
			
		||||
                if (*arg) {
 | 
			
		||||
                    expr = arg;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                if (optind < argc) {
 | 
			
		||||
                    expr = argv[optind++];
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                fprintf(stderr, "qjs: missing expression for -e\n");
 | 
			
		||||
                exit(2);
 | 
			
		||||
            }
 | 
			
		||||
            if (opt == 'I' || !strcmp(longopt, "include")) {
 | 
			
		||||
                if (optind >= argc) {
 | 
			
		||||
                    fprintf(stderr, "expecting filename");
 | 
			
		||||
                    exit(1);
 | 
			
		||||
                }
 | 
			
		||||
                if (include_count >= countof(include_list)) {
 | 
			
		||||
                    fprintf(stderr, "too many included files");
 | 
			
		||||
                    exit(1);
 | 
			
		||||
                }
 | 
			
		||||
                include_list[include_count++] = argv[optind++];
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (opt == 'i' || !strcmp(longopt, "interactive")) {
 | 
			
		||||
                interactive++;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (opt == 'm' || !strcmp(longopt, "module")) {
 | 
			
		||||
                module = 1;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (!strcmp(longopt, "script")) {
 | 
			
		||||
                module = 0;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (opt == 'd' || !strcmp(longopt, "dump")) {
 | 
			
		||||
                dump_memory++;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (opt == 'T' || !strcmp(longopt, "trace")) {
 | 
			
		||||
                trace_memory++;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (!strcmp(longopt, "std")) {
 | 
			
		||||
                load_std = 1;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (!strcmp(longopt, "unhandled-rejection")) {
 | 
			
		||||
                dump_unhandled_promise_rejection = 1;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
#ifdef CONFIG_BIGNUM
 | 
			
		||||
            if (!strcmp(longopt, "bignum")) {
 | 
			
		||||
                bignum_ext = 1;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (!strcmp(longopt, "qjscalc")) {
 | 
			
		||||
                load_jscalc = 1;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
#endif
 | 
			
		||||
            if (opt == 'q' || !strcmp(longopt, "quit")) {
 | 
			
		||||
                empty_run++;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (!strcmp(longopt, "memory-limit")) {
 | 
			
		||||
                if (optind >= argc) {
 | 
			
		||||
                    fprintf(stderr, "expecting memory limit");
 | 
			
		||||
                    exit(1);
 | 
			
		||||
                }
 | 
			
		||||
                memory_limit = (size_t)strtod(argv[optind++], NULL);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (!strcmp(longopt, "stack-size")) {
 | 
			
		||||
                if (optind >= argc) {
 | 
			
		||||
                    fprintf(stderr, "expecting stack size");
 | 
			
		||||
                    exit(1);
 | 
			
		||||
                }
 | 
			
		||||
                stack_size = (size_t)strtod(argv[optind++], NULL);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (opt) {
 | 
			
		||||
                fprintf(stderr, "qjs: unknown option '-%c'\n", opt);
 | 
			
		||||
            } else {
 | 
			
		||||
                fprintf(stderr, "qjs: unknown option '--%s'\n", longopt);
 | 
			
		||||
            }
 | 
			
		||||
            help();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_BIGNUM
 | 
			
		||||
    if (load_jscalc)
 | 
			
		||||
        bignum_ext = 1;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (trace_memory) {
 | 
			
		||||
        js_trace_malloc_init(&trace_data);
 | 
			
		||||
        rt = JS_NewRuntime2(&trace_mf, &trace_data);
 | 
			
		||||
    } else {
 | 
			
		||||
        rt = JS_NewRuntime();
 | 
			
		||||
    }
 | 
			
		||||
    if (!rt) {
 | 
			
		||||
        fprintf(stderr, "qjs: cannot allocate JS runtime\n");
 | 
			
		||||
        exit(2);
 | 
			
		||||
    }
 | 
			
		||||
    if (memory_limit != 0)
 | 
			
		||||
        JS_SetMemoryLimit(rt, memory_limit);
 | 
			
		||||
    if (stack_size != 0)
 | 
			
		||||
        JS_SetMaxStackSize(rt, stack_size);
 | 
			
		||||
    js_std_set_worker_new_context_func(JS_NewCustomContext);
 | 
			
		||||
    js_std_init_handlers(rt);
 | 
			
		||||
    ctx = JS_NewCustomContext(rt);
 | 
			
		||||
    if (!ctx) {
 | 
			
		||||
        fprintf(stderr, "qjs: cannot allocate JS context\n");
 | 
			
		||||
        exit(2);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* loader for ES6 modules */
 | 
			
		||||
    JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
 | 
			
		||||
 | 
			
		||||
    if (dump_unhandled_promise_rejection) {
 | 
			
		||||
        JS_SetHostPromiseRejectionTracker(rt, js_std_promise_rejection_tracker,
 | 
			
		||||
                                          NULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!empty_run) {
 | 
			
		||||
        js_std_add_helpers(ctx, argc - optind, argv + optind);
 | 
			
		||||
 | 
			
		||||
        /* make 'std' and 'os' visible to non module code */
 | 
			
		||||
        if (load_std) {
 | 
			
		||||
            const char *str = "import * as std from 'std';\n"
 | 
			
		||||
                "import * as os from 'os';\n"
 | 
			
		||||
                "globalThis.std = std;\n"
 | 
			
		||||
                "globalThis.os = os;\n";
 | 
			
		||||
            eval_buf(ctx, str, strlen(str), "<input>", JS_EVAL_TYPE_MODULE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for(i = 0; i < include_count; i++) {
 | 
			
		||||
            if (eval_file(ctx, include_list[i], module))
 | 
			
		||||
                goto fail;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (expr) {
 | 
			
		||||
            if (eval_buf(ctx, expr, strlen(expr), "<cmdline>", 0))
 | 
			
		||||
                goto fail;
 | 
			
		||||
        } else
 | 
			
		||||
        if (optind >= argc) {
 | 
			
		||||
            /* interactive mode */
 | 
			
		||||
            interactive = 1;
 | 
			
		||||
        } else {
 | 
			
		||||
            const char *filename;
 | 
			
		||||
            filename = argv[optind];
 | 
			
		||||
            if (eval_file(ctx, filename, module))
 | 
			
		||||
                goto fail;
 | 
			
		||||
        }
 | 
			
		||||
        js_std_loop(ctx);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (dump_memory) {
 | 
			
		||||
        JSMemoryUsage stats;
 | 
			
		||||
        JS_ComputeMemoryUsage(rt, &stats);
 | 
			
		||||
        JS_DumpMemoryUsage(stdout, &stats, rt);
 | 
			
		||||
    }
 | 
			
		||||
    js_std_free_handlers(rt);
 | 
			
		||||
    JS_FreeContext(ctx);
 | 
			
		||||
    JS_FreeRuntime(rt);
 | 
			
		||||
 | 
			
		||||
    if (empty_run && dump_memory) {
 | 
			
		||||
        clock_t t[5];
 | 
			
		||||
        double best[5];
 | 
			
		||||
        int i, j;
 | 
			
		||||
        for (i = 0; i < 100; i++) {
 | 
			
		||||
            t[0] = clock();
 | 
			
		||||
            rt = JS_NewRuntime();
 | 
			
		||||
            t[1] = clock();
 | 
			
		||||
            ctx = JS_NewContext(rt);
 | 
			
		||||
            t[2] = clock();
 | 
			
		||||
            JS_FreeContext(ctx);
 | 
			
		||||
            t[3] = clock();
 | 
			
		||||
            JS_FreeRuntime(rt);
 | 
			
		||||
            t[4] = clock();
 | 
			
		||||
            for (j = 4; j > 0; j--) {
 | 
			
		||||
                double ms = 1000.0 * (t[j] - t[j - 1]) / CLOCKS_PER_SEC;
 | 
			
		||||
                if (i == 0 || best[j] > ms)
 | 
			
		||||
                    best[j] = ms;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        printf("\nInstantiation times (ms): %.3f = %.3f+%.3f+%.3f+%.3f\n",
 | 
			
		||||
               best[1] + best[2] + best[3] + best[4],
 | 
			
		||||
               best[1], best[2], best[3], best[4]);
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
 fail:
 | 
			
		||||
    js_std_free_handlers(rt);
 | 
			
		||||
    JS_FreeContext(ctx);
 | 
			
		||||
    JS_FreeRuntime(rt);
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										761
									
								
								src/quickjs/qjsc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										761
									
								
								src/quickjs/qjsc.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,761 @@
 | 
			
		||||
/*
 | 
			
		||||
 * QuickJS command line compiler
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2018-2021 Fabrice Bellard
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 * of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
 * in the Software without restriction, including without limitation the rights
 | 
			
		||||
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
 * copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
 * THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#if !defined(_WIN32)
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "cutils.h"
 | 
			
		||||
#include "quickjs-libc.h"
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    char *name;
 | 
			
		||||
    char *short_name;
 | 
			
		||||
    int flags;
 | 
			
		||||
} namelist_entry_t;
 | 
			
		||||
 | 
			
		||||
typedef struct namelist_t {
 | 
			
		||||
    namelist_entry_t *array;
 | 
			
		||||
    int count;
 | 
			
		||||
    int size;
 | 
			
		||||
} namelist_t;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    const char *option_name;
 | 
			
		||||
    const char *init_name;
 | 
			
		||||
} FeatureEntry;
 | 
			
		||||
 | 
			
		||||
static namelist_t cname_list;
 | 
			
		||||
static namelist_t cmodule_list;
 | 
			
		||||
static namelist_t init_module_list;
 | 
			
		||||
static uint64_t feature_bitmap;
 | 
			
		||||
static FILE *outfile;
 | 
			
		||||
static BOOL byte_swap;
 | 
			
		||||
static BOOL dynamic_export;
 | 
			
		||||
static const char *c_ident_prefix = "qjsc_";
 | 
			
		||||
 | 
			
		||||
#define FE_ALL (-1)
 | 
			
		||||
 | 
			
		||||
static const FeatureEntry feature_list[] = {
 | 
			
		||||
    { "date", "Date" },
 | 
			
		||||
    { "eval", "Eval" },
 | 
			
		||||
    { "string-normalize", "StringNormalize" },
 | 
			
		||||
    { "regexp", "RegExp" },
 | 
			
		||||
    { "json", "JSON" },
 | 
			
		||||
    { "proxy", "Proxy" },
 | 
			
		||||
    { "map", "MapSet" },
 | 
			
		||||
    { "typedarray", "TypedArrays" },
 | 
			
		||||
    { "promise", "Promise" },
 | 
			
		||||
#define FE_MODULE_LOADER 9
 | 
			
		||||
    { "module-loader", NULL },
 | 
			
		||||
    { "bigint", "BigInt" },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void namelist_add(namelist_t *lp, const char *name, const char *short_name,
 | 
			
		||||
                  int flags)
 | 
			
		||||
{
 | 
			
		||||
    namelist_entry_t *e;
 | 
			
		||||
    if (lp->count == lp->size) {
 | 
			
		||||
        size_t newsize = lp->size + (lp->size >> 1) + 4;
 | 
			
		||||
        namelist_entry_t *a =
 | 
			
		||||
            realloc(lp->array, sizeof(lp->array[0]) * newsize);
 | 
			
		||||
        /* XXX: check for realloc failure */
 | 
			
		||||
        lp->array = a;
 | 
			
		||||
        lp->size = newsize;
 | 
			
		||||
    }
 | 
			
		||||
    e =  &lp->array[lp->count++];
 | 
			
		||||
    e->name = strdup(name);
 | 
			
		||||
    if (short_name)
 | 
			
		||||
        e->short_name = strdup(short_name);
 | 
			
		||||
    else
 | 
			
		||||
        e->short_name = NULL;
 | 
			
		||||
    e->flags = flags;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void namelist_free(namelist_t *lp)
 | 
			
		||||
{
 | 
			
		||||
    while (lp->count > 0) {
 | 
			
		||||
        namelist_entry_t *e = &lp->array[--lp->count];
 | 
			
		||||
        free(e->name);
 | 
			
		||||
        free(e->short_name);
 | 
			
		||||
    }
 | 
			
		||||
    free(lp->array);
 | 
			
		||||
    lp->array = NULL;
 | 
			
		||||
    lp->size = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namelist_entry_t *namelist_find(namelist_t *lp, const char *name)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    for(i = 0; i < lp->count; i++) {
 | 
			
		||||
        namelist_entry_t *e = &lp->array[i];
 | 
			
		||||
        if (!strcmp(e->name, name))
 | 
			
		||||
            return e;
 | 
			
		||||
    }
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void get_c_name(char *buf, size_t buf_size, const char *file)
 | 
			
		||||
{
 | 
			
		||||
    const char *p, *r;
 | 
			
		||||
    size_t len, i;
 | 
			
		||||
    int c;
 | 
			
		||||
    char *q;
 | 
			
		||||
 | 
			
		||||
    p = strrchr(file, '/');
 | 
			
		||||
    if (!p)
 | 
			
		||||
        p = file;
 | 
			
		||||
    else
 | 
			
		||||
        p++;
 | 
			
		||||
    r = strrchr(p, '.');
 | 
			
		||||
    if (!r)
 | 
			
		||||
        len = strlen(p);
 | 
			
		||||
    else
 | 
			
		||||
        len = r - p;
 | 
			
		||||
    pstrcpy(buf, buf_size, c_ident_prefix);
 | 
			
		||||
    q = buf + strlen(buf);
 | 
			
		||||
    for(i = 0; i < len; i++) {
 | 
			
		||||
        c = p[i];
 | 
			
		||||
        if (!((c >= '0' && c <= '9') ||
 | 
			
		||||
              (c >= 'A' && c <= 'Z') ||
 | 
			
		||||
              (c >= 'a' && c <= 'z'))) {
 | 
			
		||||
            c = '_';
 | 
			
		||||
        }
 | 
			
		||||
        if ((q - buf) < buf_size - 1)
 | 
			
		||||
            *q++ = c;
 | 
			
		||||
    }
 | 
			
		||||
    *q = '\0';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void dump_hex(FILE *f, const uint8_t *buf, size_t len)
 | 
			
		||||
{
 | 
			
		||||
    size_t i, col;
 | 
			
		||||
    col = 0;
 | 
			
		||||
    for(i = 0; i < len; i++) {
 | 
			
		||||
        fprintf(f, " 0x%02x,", buf[i]);
 | 
			
		||||
        if (++col == 8) {
 | 
			
		||||
            fprintf(f, "\n");
 | 
			
		||||
            col = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (col != 0)
 | 
			
		||||
        fprintf(f, "\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void output_object_code(JSContext *ctx,
 | 
			
		||||
                               FILE *fo, JSValueConst obj, const char *c_name,
 | 
			
		||||
                               BOOL load_only)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t *out_buf;
 | 
			
		||||
    size_t out_buf_len;
 | 
			
		||||
    int flags;
 | 
			
		||||
    flags = JS_WRITE_OBJ_BYTECODE;
 | 
			
		||||
    if (byte_swap)
 | 
			
		||||
        flags |= JS_WRITE_OBJ_BSWAP;
 | 
			
		||||
    out_buf = JS_WriteObject(ctx, &out_buf_len, obj, flags);
 | 
			
		||||
    if (!out_buf) {
 | 
			
		||||
        js_std_dump_error(ctx);
 | 
			
		||||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    namelist_add(&cname_list, c_name, NULL, load_only);
 | 
			
		||||
 | 
			
		||||
    fprintf(fo, "const uint32_t %s_size = %u;\n\n",
 | 
			
		||||
            c_name, (unsigned int)out_buf_len);
 | 
			
		||||
    fprintf(fo, "const uint8_t %s[%u] = {\n",
 | 
			
		||||
            c_name, (unsigned int)out_buf_len);
 | 
			
		||||
    dump_hex(fo, out_buf, out_buf_len);
 | 
			
		||||
    fprintf(fo, "};\n\n");
 | 
			
		||||
 | 
			
		||||
    js_free(ctx, out_buf);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int js_module_dummy_init(JSContext *ctx, JSModuleDef *m)
 | 
			
		||||
{
 | 
			
		||||
    /* should never be called when compiling JS code */
 | 
			
		||||
    abort();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void find_unique_cname(char *cname, size_t cname_size)
 | 
			
		||||
{
 | 
			
		||||
    char cname1[1024];
 | 
			
		||||
    int suffix_num;
 | 
			
		||||
    size_t len, max_len;
 | 
			
		||||
    assert(cname_size >= 32);
 | 
			
		||||
    /* find a C name not matching an existing module C name by
 | 
			
		||||
       adding a numeric suffix */
 | 
			
		||||
    len = strlen(cname);
 | 
			
		||||
    max_len = cname_size - 16;
 | 
			
		||||
    if (len > max_len)
 | 
			
		||||
        cname[max_len] = '\0';
 | 
			
		||||
    suffix_num = 1;
 | 
			
		||||
    for(;;) {
 | 
			
		||||
        snprintf(cname1, sizeof(cname1), "%s_%d", cname, suffix_num);
 | 
			
		||||
        if (!namelist_find(&cname_list, cname1))
 | 
			
		||||
            break;
 | 
			
		||||
        suffix_num++;
 | 
			
		||||
    }
 | 
			
		||||
    pstrcpy(cname, cname_size, cname1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSModuleDef *jsc_module_loader(JSContext *ctx,
 | 
			
		||||
                              const char *module_name, void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    JSModuleDef *m;
 | 
			
		||||
    namelist_entry_t *e;
 | 
			
		||||
 | 
			
		||||
    /* check if it is a declared C or system module */
 | 
			
		||||
    e = namelist_find(&cmodule_list, module_name);
 | 
			
		||||
    if (e) {
 | 
			
		||||
        /* add in the static init module list */
 | 
			
		||||
        namelist_add(&init_module_list, e->name, e->short_name, 0);
 | 
			
		||||
        /* create a dummy module */
 | 
			
		||||
        m = JS_NewCModule(ctx, module_name, js_module_dummy_init);
 | 
			
		||||
    } else if (has_suffix(module_name, ".so")) {
 | 
			
		||||
        fprintf(stderr, "Warning: binary module '%s' will be dynamically loaded\n", module_name);
 | 
			
		||||
        /* create a dummy module */
 | 
			
		||||
        m = JS_NewCModule(ctx, module_name, js_module_dummy_init);
 | 
			
		||||
        /* the resulting executable will export its symbols for the
 | 
			
		||||
           dynamic library */
 | 
			
		||||
        dynamic_export = TRUE;
 | 
			
		||||
    } else {
 | 
			
		||||
        size_t buf_len;
 | 
			
		||||
        uint8_t *buf;
 | 
			
		||||
        JSValue func_val;
 | 
			
		||||
        char cname[1024];
 | 
			
		||||
 | 
			
		||||
        buf = js_load_file(ctx, &buf_len, module_name);
 | 
			
		||||
        if (!buf) {
 | 
			
		||||
            JS_ThrowReferenceError(ctx, "could not load module filename '%s'",
 | 
			
		||||
                                   module_name);
 | 
			
		||||
            return NULL;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* compile the module */
 | 
			
		||||
        func_val = JS_Eval(ctx, (char *)buf, buf_len, module_name,
 | 
			
		||||
                           JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
 | 
			
		||||
        js_free(ctx, buf);
 | 
			
		||||
        if (JS_IsException(func_val))
 | 
			
		||||
            return NULL;
 | 
			
		||||
        get_c_name(cname, sizeof(cname), module_name);
 | 
			
		||||
        if (namelist_find(&cname_list, cname)) {
 | 
			
		||||
            find_unique_cname(cname, sizeof(cname));
 | 
			
		||||
        }
 | 
			
		||||
        output_object_code(ctx, outfile, func_val, cname, TRUE);
 | 
			
		||||
 | 
			
		||||
        /* the module is already referenced, so we must free it */
 | 
			
		||||
        m = JS_VALUE_GET_PTR(func_val);
 | 
			
		||||
        JS_FreeValue(ctx, func_val);
 | 
			
		||||
    }
 | 
			
		||||
    return m;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void compile_file(JSContext *ctx, FILE *fo,
 | 
			
		||||
                         const char *filename,
 | 
			
		||||
                         const char *c_name1,
 | 
			
		||||
                         int module)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t *buf;
 | 
			
		||||
    char c_name[1024];
 | 
			
		||||
    int eval_flags;
 | 
			
		||||
    JSValue obj;
 | 
			
		||||
    size_t buf_len;
 | 
			
		||||
 | 
			
		||||
    buf = js_load_file(ctx, &buf_len, filename);
 | 
			
		||||
    if (!buf) {
 | 
			
		||||
        fprintf(stderr, "Could not load '%s'\n", filename);
 | 
			
		||||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
    eval_flags = JS_EVAL_FLAG_COMPILE_ONLY;
 | 
			
		||||
    if (module < 0) {
 | 
			
		||||
        module = (has_suffix(filename, ".mjs") ||
 | 
			
		||||
                  JS_DetectModule((const char *)buf, buf_len));
 | 
			
		||||
    }
 | 
			
		||||
    if (module)
 | 
			
		||||
        eval_flags |= JS_EVAL_TYPE_MODULE;
 | 
			
		||||
    else
 | 
			
		||||
        eval_flags |= JS_EVAL_TYPE_GLOBAL;
 | 
			
		||||
    obj = JS_Eval(ctx, (const char *)buf, buf_len, filename, eval_flags);
 | 
			
		||||
    if (JS_IsException(obj)) {
 | 
			
		||||
        js_std_dump_error(ctx);
 | 
			
		||||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
    js_free(ctx, buf);
 | 
			
		||||
    if (c_name1) {
 | 
			
		||||
        pstrcpy(c_name, sizeof(c_name), c_name1);
 | 
			
		||||
    } else {
 | 
			
		||||
        get_c_name(c_name, sizeof(c_name), filename);
 | 
			
		||||
    }
 | 
			
		||||
    output_object_code(ctx, fo, obj, c_name, FALSE);
 | 
			
		||||
    JS_FreeValue(ctx, obj);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char main_c_template1[] =
 | 
			
		||||
    "int main(int argc, char **argv)\n"
 | 
			
		||||
    "{\n"
 | 
			
		||||
    "  JSRuntime *rt;\n"
 | 
			
		||||
    "  JSContext *ctx;\n"
 | 
			
		||||
    "  rt = JS_NewRuntime();\n"
 | 
			
		||||
    "  js_std_set_worker_new_context_func(JS_NewCustomContext);\n"
 | 
			
		||||
    "  js_std_init_handlers(rt);\n"
 | 
			
		||||
    ;
 | 
			
		||||
 | 
			
		||||
static const char main_c_template2[] =
 | 
			
		||||
    "  js_std_loop(ctx);\n"
 | 
			
		||||
    "  js_std_free_handlers(rt);\n"
 | 
			
		||||
    "  JS_FreeContext(ctx);\n"
 | 
			
		||||
    "  JS_FreeRuntime(rt);\n"
 | 
			
		||||
    "  return 0;\n"
 | 
			
		||||
    "}\n";
 | 
			
		||||
 | 
			
		||||
#define PROG_NAME "qjsc"
 | 
			
		||||
 | 
			
		||||
void help(void)
 | 
			
		||||
{
 | 
			
		||||
    printf("QuickJS Compiler version " CONFIG_VERSION "\n"
 | 
			
		||||
           "usage: " PROG_NAME " [options] [files]\n"
 | 
			
		||||
           "\n"
 | 
			
		||||
           "options are:\n"
 | 
			
		||||
           "-c          only output bytecode to a C file\n"
 | 
			
		||||
           "-e          output main() and bytecode to a C file (default = executable output)\n"
 | 
			
		||||
           "-o output   set the output filename\n"
 | 
			
		||||
           "-N cname    set the C name of the generated data\n"
 | 
			
		||||
           "-m          compile as Javascript module (default=autodetect)\n"
 | 
			
		||||
           "-D module_name         compile a dynamically loaded module or worker\n"
 | 
			
		||||
           "-M module_name[,cname] add initialization code for an external C module\n"
 | 
			
		||||
           "-x          byte swapped output\n"
 | 
			
		||||
           "-p prefix   set the prefix of the generated C names\n"
 | 
			
		||||
           "-S n        set the maximum stack size to 'n' bytes (default=%d)\n",
 | 
			
		||||
           JS_DEFAULT_STACK_SIZE);
 | 
			
		||||
#ifdef CONFIG_LTO
 | 
			
		||||
    {
 | 
			
		||||
        int i;
 | 
			
		||||
        printf("-flto       use link time optimization\n");
 | 
			
		||||
        printf("-fbignum    enable bignum extensions\n");
 | 
			
		||||
        printf("-fno-[");
 | 
			
		||||
        for(i = 0; i < countof(feature_list); i++) {
 | 
			
		||||
            if (i != 0)
 | 
			
		||||
                printf("|");
 | 
			
		||||
            printf("%s", feature_list[i].option_name);
 | 
			
		||||
        }
 | 
			
		||||
        printf("]\n"
 | 
			
		||||
               "            disable selected language features (smaller code size)\n");
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    exit(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(CONFIG_CC) && !defined(_WIN32)
 | 
			
		||||
 | 
			
		||||
int exec_cmd(char **argv)
 | 
			
		||||
{
 | 
			
		||||
    int pid, status, ret;
 | 
			
		||||
 | 
			
		||||
    pid = fork();
 | 
			
		||||
    if (pid == 0) {
 | 
			
		||||
        execvp(argv[0], argv);
 | 
			
		||||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for(;;) {
 | 
			
		||||
        ret = waitpid(pid, &status, 0);
 | 
			
		||||
        if (ret == pid && WIFEXITED(status))
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
    return WEXITSTATUS(status);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int output_executable(const char *out_filename, const char *cfilename,
 | 
			
		||||
                             BOOL use_lto, BOOL verbose, const char *exename)
 | 
			
		||||
{
 | 
			
		||||
    const char *argv[64];
 | 
			
		||||
    const char **arg, *bn_suffix, *lto_suffix;
 | 
			
		||||
    char libjsname[1024];
 | 
			
		||||
    char exe_dir[1024], inc_dir[1024], lib_dir[1024], buf[1024], *p;
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    /* get the directory of the executable */
 | 
			
		||||
    pstrcpy(exe_dir, sizeof(exe_dir), exename);
 | 
			
		||||
    p = strrchr(exe_dir, '/');
 | 
			
		||||
    if (p) {
 | 
			
		||||
        *p = '\0';
 | 
			
		||||
    } else {
 | 
			
		||||
        pstrcpy(exe_dir, sizeof(exe_dir), ".");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* if 'quickjs.h' is present at the same path as the executable, we
 | 
			
		||||
       use it as include and lib directory */
 | 
			
		||||
    snprintf(buf, sizeof(buf), "%s/quickjs.h", exe_dir);
 | 
			
		||||
    if (access(buf, R_OK) == 0) {
 | 
			
		||||
        pstrcpy(inc_dir, sizeof(inc_dir), exe_dir);
 | 
			
		||||
        pstrcpy(lib_dir, sizeof(lib_dir), exe_dir);
 | 
			
		||||
    } else {
 | 
			
		||||
        snprintf(inc_dir, sizeof(inc_dir), "%s/include/quickjs", CONFIG_PREFIX);
 | 
			
		||||
        snprintf(lib_dir, sizeof(lib_dir), "%s/lib/quickjs", CONFIG_PREFIX);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    lto_suffix = "";
 | 
			
		||||
    bn_suffix = "";
 | 
			
		||||
 | 
			
		||||
    arg = argv;
 | 
			
		||||
    *arg++ = CONFIG_CC;
 | 
			
		||||
    *arg++ = "-O2";
 | 
			
		||||
#ifdef CONFIG_LTO
 | 
			
		||||
    if (use_lto) {
 | 
			
		||||
        *arg++ = "-flto";
 | 
			
		||||
        lto_suffix = ".lto";
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    /* XXX: use the executable path to find the includes files and
 | 
			
		||||
       libraries */
 | 
			
		||||
    *arg++ = "-D";
 | 
			
		||||
    *arg++ = "_GNU_SOURCE";
 | 
			
		||||
    *arg++ = "-I";
 | 
			
		||||
    *arg++ = inc_dir;
 | 
			
		||||
    *arg++ = "-o";
 | 
			
		||||
    *arg++ = out_filename;
 | 
			
		||||
    if (dynamic_export)
 | 
			
		||||
        *arg++ = "-rdynamic";
 | 
			
		||||
    *arg++ = cfilename;
 | 
			
		||||
    snprintf(libjsname, sizeof(libjsname), "%s/libquickjs%s%s.a",
 | 
			
		||||
             lib_dir, bn_suffix, lto_suffix);
 | 
			
		||||
    *arg++ = libjsname;
 | 
			
		||||
    *arg++ = "-lm";
 | 
			
		||||
    *arg++ = "-ldl";
 | 
			
		||||
    *arg++ = "-lpthread";
 | 
			
		||||
    *arg = NULL;
 | 
			
		||||
 | 
			
		||||
    if (verbose) {
 | 
			
		||||
        for(arg = argv; *arg != NULL; arg++)
 | 
			
		||||
            printf("%s ", *arg);
 | 
			
		||||
        printf("\n");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ret = exec_cmd((char **)argv);
 | 
			
		||||
    unlink(cfilename);
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
static int output_executable(const char *out_filename, const char *cfilename,
 | 
			
		||||
                             BOOL use_lto, BOOL verbose, const char *exename)
 | 
			
		||||
{
 | 
			
		||||
    fprintf(stderr, "Executable output is not supported for this target\n");
 | 
			
		||||
    exit(1);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
    OUTPUT_C,
 | 
			
		||||
    OUTPUT_C_MAIN,
 | 
			
		||||
    OUTPUT_EXECUTABLE,
 | 
			
		||||
} OutputTypeEnum;
 | 
			
		||||
 | 
			
		||||
int main(int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
    int c, i, verbose;
 | 
			
		||||
    const char *out_filename, *cname;
 | 
			
		||||
    char cfilename[1024];
 | 
			
		||||
    FILE *fo;
 | 
			
		||||
    JSRuntime *rt;
 | 
			
		||||
    JSContext *ctx;
 | 
			
		||||
    BOOL use_lto;
 | 
			
		||||
    int module;
 | 
			
		||||
    OutputTypeEnum output_type;
 | 
			
		||||
    size_t stack_size;
 | 
			
		||||
#ifdef CONFIG_BIGNUM
 | 
			
		||||
    BOOL bignum_ext = FALSE;
 | 
			
		||||
#endif
 | 
			
		||||
    namelist_t dynamic_module_list;
 | 
			
		||||
 | 
			
		||||
    out_filename = NULL;
 | 
			
		||||
    output_type = OUTPUT_EXECUTABLE;
 | 
			
		||||
    cname = NULL;
 | 
			
		||||
    feature_bitmap = FE_ALL;
 | 
			
		||||
    module = -1;
 | 
			
		||||
    byte_swap = FALSE;
 | 
			
		||||
    verbose = 0;
 | 
			
		||||
    use_lto = FALSE;
 | 
			
		||||
    stack_size = 0;
 | 
			
		||||
    memset(&dynamic_module_list, 0, sizeof(dynamic_module_list));
 | 
			
		||||
 | 
			
		||||
    /* add system modules */
 | 
			
		||||
    namelist_add(&cmodule_list, "std", "std", 0);
 | 
			
		||||
    namelist_add(&cmodule_list, "os", "os", 0);
 | 
			
		||||
 | 
			
		||||
    for(;;) {
 | 
			
		||||
        c = getopt(argc, argv, "ho:cN:f:mxevM:p:S:D:");
 | 
			
		||||
        if (c == -1)
 | 
			
		||||
            break;
 | 
			
		||||
        switch(c) {
 | 
			
		||||
        case 'h':
 | 
			
		||||
            help();
 | 
			
		||||
        case 'o':
 | 
			
		||||
            out_filename = optarg;
 | 
			
		||||
            break;
 | 
			
		||||
        case 'c':
 | 
			
		||||
            output_type = OUTPUT_C;
 | 
			
		||||
            break;
 | 
			
		||||
        case 'e':
 | 
			
		||||
            output_type = OUTPUT_C_MAIN;
 | 
			
		||||
            break;
 | 
			
		||||
        case 'N':
 | 
			
		||||
            cname = optarg;
 | 
			
		||||
            break;
 | 
			
		||||
        case 'f':
 | 
			
		||||
            {
 | 
			
		||||
                const char *p;
 | 
			
		||||
                p = optarg;
 | 
			
		||||
                if (!strcmp(optarg, "lto")) {
 | 
			
		||||
                    use_lto = TRUE;
 | 
			
		||||
                } else if (strstart(p, "no-", &p)) {
 | 
			
		||||
                    use_lto = TRUE;
 | 
			
		||||
                    for(i = 0; i < countof(feature_list); i++) {
 | 
			
		||||
                        if (!strcmp(p, feature_list[i].option_name)) {
 | 
			
		||||
                            feature_bitmap &= ~((uint64_t)1 << i);
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    if (i == countof(feature_list))
 | 
			
		||||
                        goto bad_feature;
 | 
			
		||||
                } else
 | 
			
		||||
#ifdef CONFIG_BIGNUM
 | 
			
		||||
                if (!strcmp(optarg, "bignum")) {
 | 
			
		||||
                    bignum_ext = TRUE;
 | 
			
		||||
                } else
 | 
			
		||||
#endif
 | 
			
		||||
                {
 | 
			
		||||
                bad_feature:
 | 
			
		||||
                    fprintf(stderr, "unsupported feature: %s\n", optarg);
 | 
			
		||||
                    exit(1);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case 'm':
 | 
			
		||||
            module = 1;
 | 
			
		||||
            break;
 | 
			
		||||
        case 'M':
 | 
			
		||||
            {
 | 
			
		||||
                char *p;
 | 
			
		||||
                char path[1024];
 | 
			
		||||
                char cname[1024];
 | 
			
		||||
                pstrcpy(path, sizeof(path), optarg);
 | 
			
		||||
                p = strchr(path, ',');
 | 
			
		||||
                if (p) {
 | 
			
		||||
                    *p = '\0';
 | 
			
		||||
                    pstrcpy(cname, sizeof(cname), p + 1);
 | 
			
		||||
                } else {
 | 
			
		||||
                    get_c_name(cname, sizeof(cname), path);
 | 
			
		||||
                }
 | 
			
		||||
                namelist_add(&cmodule_list, path, cname, 0);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case 'D':
 | 
			
		||||
            namelist_add(&dynamic_module_list, optarg, NULL, 0);
 | 
			
		||||
            break;
 | 
			
		||||
        case 'x':
 | 
			
		||||
            byte_swap = TRUE;
 | 
			
		||||
            break;
 | 
			
		||||
        case 'v':
 | 
			
		||||
            verbose++;
 | 
			
		||||
            break;
 | 
			
		||||
        case 'p':
 | 
			
		||||
            c_ident_prefix = optarg;
 | 
			
		||||
            break;
 | 
			
		||||
        case 'S':
 | 
			
		||||
            stack_size = (size_t)strtod(optarg, NULL);
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (optind >= argc)
 | 
			
		||||
        help();
 | 
			
		||||
 | 
			
		||||
    if (!out_filename) {
 | 
			
		||||
        if (output_type == OUTPUT_EXECUTABLE) {
 | 
			
		||||
            out_filename = "a.out";
 | 
			
		||||
        } else {
 | 
			
		||||
            out_filename = "out.c";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (output_type == OUTPUT_EXECUTABLE) {
 | 
			
		||||
#if defined(_WIN32) || defined(__ANDROID__)
 | 
			
		||||
        /* XXX: find a /tmp directory ? */
 | 
			
		||||
        snprintf(cfilename, sizeof(cfilename), "out%d.c", getpid());
 | 
			
		||||
#else
 | 
			
		||||
        snprintf(cfilename, sizeof(cfilename), "/tmp/out%d.c", getpid());
 | 
			
		||||
#endif
 | 
			
		||||
    } else {
 | 
			
		||||
        pstrcpy(cfilename, sizeof(cfilename), out_filename);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fo = fopen(cfilename, "w");
 | 
			
		||||
    if (!fo) {
 | 
			
		||||
        perror(cfilename);
 | 
			
		||||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
    outfile = fo;
 | 
			
		||||
 | 
			
		||||
    rt = JS_NewRuntime();
 | 
			
		||||
    ctx = JS_NewContext(rt);
 | 
			
		||||
#ifdef CONFIG_BIGNUM
 | 
			
		||||
    if (bignum_ext) {
 | 
			
		||||
        JS_AddIntrinsicBigFloat(ctx);
 | 
			
		||||
        JS_AddIntrinsicBigDecimal(ctx);
 | 
			
		||||
        JS_AddIntrinsicOperators(ctx);
 | 
			
		||||
        JS_EnableBignumExt(ctx, TRUE);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /* loader for ES6 modules */
 | 
			
		||||
    JS_SetModuleLoaderFunc(rt, NULL, jsc_module_loader, NULL);
 | 
			
		||||
 | 
			
		||||
    fprintf(fo, "/* File generated automatically by the QuickJS compiler. */\n"
 | 
			
		||||
            "\n"
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
    if (output_type != OUTPUT_C) {
 | 
			
		||||
        fprintf(fo, "#include \"quickjs-libc.h\"\n"
 | 
			
		||||
                "\n"
 | 
			
		||||
                );
 | 
			
		||||
    } else {
 | 
			
		||||
        fprintf(fo, "#include <inttypes.h>\n"
 | 
			
		||||
                "\n"
 | 
			
		||||
                );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for(i = optind; i < argc; i++) {
 | 
			
		||||
        const char *filename = argv[i];
 | 
			
		||||
        compile_file(ctx, fo, filename, cname, module);
 | 
			
		||||
        cname = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for(i = 0; i < dynamic_module_list.count; i++) {
 | 
			
		||||
        if (!jsc_module_loader(ctx, dynamic_module_list.array[i].name, NULL)) {
 | 
			
		||||
            fprintf(stderr, "Could not load dynamic module '%s'\n",
 | 
			
		||||
                    dynamic_module_list.array[i].name);
 | 
			
		||||
            exit(1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (output_type != OUTPUT_C) {
 | 
			
		||||
        fprintf(fo,
 | 
			
		||||
                "static JSContext *JS_NewCustomContext(JSRuntime *rt)\n"
 | 
			
		||||
                "{\n"
 | 
			
		||||
                "  JSContext *ctx = JS_NewContextRaw(rt);\n"
 | 
			
		||||
                "  if (!ctx)\n"
 | 
			
		||||
                "    return NULL;\n");
 | 
			
		||||
        /* add the basic objects */
 | 
			
		||||
        fprintf(fo, "  JS_AddIntrinsicBaseObjects(ctx);\n");
 | 
			
		||||
        for(i = 0; i < countof(feature_list); i++) {
 | 
			
		||||
            if ((feature_bitmap & ((uint64_t)1 << i)) &&
 | 
			
		||||
                feature_list[i].init_name) {
 | 
			
		||||
                fprintf(fo, "  JS_AddIntrinsic%s(ctx);\n",
 | 
			
		||||
                        feature_list[i].init_name);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
#ifdef CONFIG_BIGNUM
 | 
			
		||||
        if (bignum_ext) {
 | 
			
		||||
            fprintf(fo,
 | 
			
		||||
                    "  JS_AddIntrinsicBigFloat(ctx);\n"
 | 
			
		||||
                    "  JS_AddIntrinsicBigDecimal(ctx);\n"
 | 
			
		||||
                    "  JS_AddIntrinsicOperators(ctx);\n"
 | 
			
		||||
                    "  JS_EnableBignumExt(ctx, 1);\n");
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
        /* add the precompiled modules (XXX: could modify the module
 | 
			
		||||
           loader instead) */
 | 
			
		||||
        for(i = 0; i < init_module_list.count; i++) {
 | 
			
		||||
            namelist_entry_t *e = &init_module_list.array[i];
 | 
			
		||||
            /* initialize the static C modules */
 | 
			
		||||
 | 
			
		||||
            fprintf(fo,
 | 
			
		||||
                    "  {\n"
 | 
			
		||||
                    "    extern JSModuleDef *js_init_module_%s(JSContext *ctx, const char *name);\n"
 | 
			
		||||
                    "    js_init_module_%s(ctx, \"%s\");\n"
 | 
			
		||||
                    "  }\n",
 | 
			
		||||
                    e->short_name, e->short_name, e->name);
 | 
			
		||||
        }
 | 
			
		||||
        for(i = 0; i < cname_list.count; i++) {
 | 
			
		||||
            namelist_entry_t *e = &cname_list.array[i];
 | 
			
		||||
            if (e->flags) {
 | 
			
		||||
                fprintf(fo, "  js_std_eval_binary(ctx, %s, %s_size, 1);\n",
 | 
			
		||||
                        e->name, e->name);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        fprintf(fo,
 | 
			
		||||
                "  return ctx;\n"
 | 
			
		||||
                "}\n\n");
 | 
			
		||||
 | 
			
		||||
        fputs(main_c_template1, fo);
 | 
			
		||||
 | 
			
		||||
        if (stack_size != 0) {
 | 
			
		||||
            fprintf(fo, "  JS_SetMaxStackSize(rt, %u);\n",
 | 
			
		||||
                    (unsigned int)stack_size);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* add the module loader if necessary */
 | 
			
		||||
        if (feature_bitmap & (1 << FE_MODULE_LOADER)) {
 | 
			
		||||
            fprintf(fo, "  JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);\n");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fprintf(fo,
 | 
			
		||||
                "  ctx = JS_NewCustomContext(rt);\n"
 | 
			
		||||
                "  js_std_add_helpers(ctx, argc, argv);\n");
 | 
			
		||||
 | 
			
		||||
        for(i = 0; i < cname_list.count; i++) {
 | 
			
		||||
            namelist_entry_t *e = &cname_list.array[i];
 | 
			
		||||
            if (!e->flags) {
 | 
			
		||||
                fprintf(fo, "  js_std_eval_binary(ctx, %s, %s_size, 0);\n",
 | 
			
		||||
                        e->name, e->name);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        fputs(main_c_template2, fo);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    JS_FreeContext(ctx);
 | 
			
		||||
    JS_FreeRuntime(rt);
 | 
			
		||||
 | 
			
		||||
    fclose(fo);
 | 
			
		||||
 | 
			
		||||
    if (output_type == OUTPUT_EXECUTABLE) {
 | 
			
		||||
        return output_executable(out_filename, cfilename, use_lto, verbose,
 | 
			
		||||
                                 argv[0]);
 | 
			
		||||
    }
 | 
			
		||||
    namelist_free(&cname_list);
 | 
			
		||||
    namelist_free(&cmodule_list);
 | 
			
		||||
    namelist_free(&init_module_list);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										87
									
								
								src/quickjs/qsort_r.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								src/quickjs/qsort_r.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
exch(char* base, size_t size, size_t a, size_t b) {
 | 
			
		||||
  char* x = base + a * size;
 | 
			
		||||
  char* y = base + b * size;
 | 
			
		||||
  while(size) {
 | 
			
		||||
    char z = *x;
 | 
			
		||||
    *x = *y;
 | 
			
		||||
    *y = z;
 | 
			
		||||
    --size;
 | 
			
		||||
    ++x;
 | 
			
		||||
    ++y;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define RAND
 | 
			
		||||
 | 
			
		||||
/* Quicksort with 3-way partitioning, ala Sedgewick */
 | 
			
		||||
/* Blame him for the scary variable names */
 | 
			
		||||
/* http://www.cs.princeton.edu/~rs/talks/QuicksortIsOptimal.pdf */
 | 
			
		||||
static void
 | 
			
		||||
quicksort(char* base, size_t size, ssize_t l, ssize_t r, int (*compar)(const void*, const void*, void*), void* ptr) {
 | 
			
		||||
  ssize_t i = l - 1, j = r, p = l - 1, q = r, k;
 | 
			
		||||
  char* v = base + r * size;
 | 
			
		||||
  if(r <= l)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
#ifdef RAND
 | 
			
		||||
  /*
 | 
			
		||||
     We chose the rightmost element in the array to be sorted as pivot,
 | 
			
		||||
     which is OK if the data is random, but which is horrible if the
 | 
			
		||||
     data is already sorted.  Try to improve by exchanging it with a
 | 
			
		||||
     random other pivot.
 | 
			
		||||
   */
 | 
			
		||||
  exch(base, size, l + (rand() % (r - l)), r);
 | 
			
		||||
#elif defined MID
 | 
			
		||||
  /*
 | 
			
		||||
     We chose the rightmost element in the array to be sorted as pivot,
 | 
			
		||||
     which is OK if the data is random, but which is horrible if the
 | 
			
		||||
     data is already sorted.  Try to improve by chosing the middle
 | 
			
		||||
     element instead.
 | 
			
		||||
   */
 | 
			
		||||
  exch(base, size, l + (r - l) / 2, r);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  for(;;) {
 | 
			
		||||
    while(++i != r && compar(base + i * size, v, ptr) < 0)
 | 
			
		||||
      ;
 | 
			
		||||
    while(compar(v, base + (--j) * size, ptr) < 0)
 | 
			
		||||
      if(j == l)
 | 
			
		||||
        break;
 | 
			
		||||
    if(i >= j)
 | 
			
		||||
      break;
 | 
			
		||||
    exch(base, size, i, j);
 | 
			
		||||
    if(compar(base + i * size, v, ptr) == 0)
 | 
			
		||||
      exch(base, size, ++p, i);
 | 
			
		||||
    if(compar(v, base + j * size, ptr) == 0)
 | 
			
		||||
      exch(base, size, j, --q);
 | 
			
		||||
  }
 | 
			
		||||
  exch(base, size, i, r);
 | 
			
		||||
  j = i - 1;
 | 
			
		||||
  ++i;
 | 
			
		||||
  for(k = l; k < p; k++, j--)
 | 
			
		||||
    exch(base, size, k, j);
 | 
			
		||||
  for(k = r - 1; k > q; k--, i++)
 | 
			
		||||
    exch(base, size, i, k);
 | 
			
		||||
  quicksort(base, size, l, j, compar, ptr);
 | 
			
		||||
  quicksort(base, size, i, r, compar, ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
quicksort_r(void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*, void*), void* ptr) {
 | 
			
		||||
  /* check for integer overflows */
 | 
			
		||||
  if(nmemb >= (((size_t)-1) >> 1) || size >= (((size_t)-1) >> 1))
 | 
			
		||||
    return;
 | 
			
		||||
#if 0
 | 
			
		||||
  if (sizeof(size_t) < sizeof(unsigned long long)) {
 | 
			
		||||
    if ((unsigned long long)size * nmemb > (size_t)-1) return;
 | 
			
		||||
  } else {
 | 
			
		||||
    if (size*nmemb/nmemb != size) return;
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
  if(nmemb > 1)
 | 
			
		||||
    quicksort(base, size, 0, nmemb - 1, compar, ptr);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										273
									
								
								src/quickjs/quickjs-atom.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										273
									
								
								src/quickjs/quickjs-atom.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,273 @@
 | 
			
		||||
/*
 | 
			
		||||
 * QuickJS atom definitions
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2017-2018 Fabrice Bellard
 | 
			
		||||
 * Copyright (c) 2017-2018 Charlie Gordon
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 * of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
 * in the Software without restriction, including without limitation the rights
 | 
			
		||||
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
 * copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
 * THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef DEF
 | 
			
		||||
 | 
			
		||||
/* Note: first atoms are considered as keywords in the parser */
 | 
			
		||||
DEF(null, "null") /* must be first */
 | 
			
		||||
DEF(false, "false")
 | 
			
		||||
DEF(true, "true")
 | 
			
		||||
DEF(if, "if")
 | 
			
		||||
DEF(else, "else")
 | 
			
		||||
DEF(return, "return")
 | 
			
		||||
DEF(var, "var")
 | 
			
		||||
DEF(this, "this")
 | 
			
		||||
DEF(delete, "delete")
 | 
			
		||||
DEF(void, "void")
 | 
			
		||||
DEF(typeof, "typeof")
 | 
			
		||||
DEF(new, "new")
 | 
			
		||||
DEF(in, "in")
 | 
			
		||||
DEF(instanceof, "instanceof")
 | 
			
		||||
DEF(do, "do")
 | 
			
		||||
DEF(while, "while")
 | 
			
		||||
DEF(for, "for")
 | 
			
		||||
DEF(break, "break")
 | 
			
		||||
DEF(continue, "continue")
 | 
			
		||||
DEF(switch, "switch")
 | 
			
		||||
DEF(case, "case")
 | 
			
		||||
DEF(default, "default")
 | 
			
		||||
DEF(throw, "throw")
 | 
			
		||||
DEF(try, "try")
 | 
			
		||||
DEF(catch, "catch")
 | 
			
		||||
DEF(finally, "finally")
 | 
			
		||||
DEF(function, "function")
 | 
			
		||||
DEF(debugger, "debugger")
 | 
			
		||||
DEF(with, "with")
 | 
			
		||||
/* FutureReservedWord */
 | 
			
		||||
DEF(class, "class")
 | 
			
		||||
DEF(const, "const")
 | 
			
		||||
DEF(enum, "enum")
 | 
			
		||||
DEF(export, "export")
 | 
			
		||||
DEF(extends, "extends")
 | 
			
		||||
DEF(import, "import")
 | 
			
		||||
DEF(super, "super")
 | 
			
		||||
/* FutureReservedWords when parsing strict mode code */
 | 
			
		||||
DEF(implements, "implements")
 | 
			
		||||
DEF(interface, "interface")
 | 
			
		||||
DEF(let, "let")
 | 
			
		||||
DEF(package, "package")
 | 
			
		||||
DEF(private, "private")
 | 
			
		||||
DEF(protected, "protected")
 | 
			
		||||
DEF(public, "public")
 | 
			
		||||
DEF(static, "static")
 | 
			
		||||
DEF(yield, "yield")
 | 
			
		||||
DEF(await, "await")
 | 
			
		||||
 | 
			
		||||
/* empty string */
 | 
			
		||||
DEF(empty_string, "")
 | 
			
		||||
/* identifiers */
 | 
			
		||||
DEF(length, "length")
 | 
			
		||||
DEF(fileName, "fileName")
 | 
			
		||||
DEF(lineNumber, "lineNumber")
 | 
			
		||||
DEF(message, "message")
 | 
			
		||||
DEF(cause, "cause")
 | 
			
		||||
DEF(errors, "errors")
 | 
			
		||||
DEF(stack, "stack")
 | 
			
		||||
DEF(name, "name")
 | 
			
		||||
DEF(toString, "toString")
 | 
			
		||||
DEF(toLocaleString, "toLocaleString")
 | 
			
		||||
DEF(valueOf, "valueOf")
 | 
			
		||||
DEF(eval, "eval")
 | 
			
		||||
DEF(prototype, "prototype")
 | 
			
		||||
DEF(constructor, "constructor")
 | 
			
		||||
DEF(configurable, "configurable")
 | 
			
		||||
DEF(writable, "writable")
 | 
			
		||||
DEF(enumerable, "enumerable")
 | 
			
		||||
DEF(value, "value")
 | 
			
		||||
DEF(get, "get")
 | 
			
		||||
DEF(set, "set")
 | 
			
		||||
DEF(of, "of")
 | 
			
		||||
DEF(__proto__, "__proto__")
 | 
			
		||||
DEF(undefined, "undefined")
 | 
			
		||||
DEF(number, "number")
 | 
			
		||||
DEF(boolean, "boolean")
 | 
			
		||||
DEF(string, "string")
 | 
			
		||||
DEF(object, "object")
 | 
			
		||||
DEF(symbol, "symbol")
 | 
			
		||||
DEF(integer, "integer")
 | 
			
		||||
DEF(unknown, "unknown")
 | 
			
		||||
DEF(arguments, "arguments")
 | 
			
		||||
DEF(callee, "callee")
 | 
			
		||||
DEF(caller, "caller")
 | 
			
		||||
DEF(_eval_, "<eval>")
 | 
			
		||||
DEF(_ret_, "<ret>")
 | 
			
		||||
DEF(_var_, "<var>")
 | 
			
		||||
DEF(_arg_var_, "<arg_var>")
 | 
			
		||||
DEF(_with_, "<with>")
 | 
			
		||||
DEF(lastIndex, "lastIndex")
 | 
			
		||||
DEF(target, "target")
 | 
			
		||||
DEF(index, "index")
 | 
			
		||||
DEF(input, "input")
 | 
			
		||||
DEF(defineProperties, "defineProperties")
 | 
			
		||||
DEF(apply, "apply")
 | 
			
		||||
DEF(join, "join")
 | 
			
		||||
DEF(concat, "concat")
 | 
			
		||||
DEF(split, "split")
 | 
			
		||||
DEF(construct, "construct")
 | 
			
		||||
DEF(getPrototypeOf, "getPrototypeOf")
 | 
			
		||||
DEF(setPrototypeOf, "setPrototypeOf")
 | 
			
		||||
DEF(isExtensible, "isExtensible")
 | 
			
		||||
DEF(preventExtensions, "preventExtensions")
 | 
			
		||||
DEF(has, "has")
 | 
			
		||||
DEF(deleteProperty, "deleteProperty")
 | 
			
		||||
DEF(defineProperty, "defineProperty")
 | 
			
		||||
DEF(getOwnPropertyDescriptor, "getOwnPropertyDescriptor")
 | 
			
		||||
DEF(ownKeys, "ownKeys")
 | 
			
		||||
DEF(add, "add")
 | 
			
		||||
DEF(done, "done")
 | 
			
		||||
DEF(next, "next")
 | 
			
		||||
DEF(values, "values")
 | 
			
		||||
DEF(source, "source")
 | 
			
		||||
DEF(flags, "flags")
 | 
			
		||||
DEF(global, "global")
 | 
			
		||||
DEF(unicode, "unicode")
 | 
			
		||||
DEF(raw, "raw")
 | 
			
		||||
DEF(new_target, "new.target")
 | 
			
		||||
DEF(this_active_func, "this.active_func")
 | 
			
		||||
DEF(home_object, "<home_object>")
 | 
			
		||||
DEF(computed_field, "<computed_field>")
 | 
			
		||||
DEF(static_computed_field, "<static_computed_field>") /* must come after computed_fields */
 | 
			
		||||
DEF(class_fields_init, "<class_fields_init>")
 | 
			
		||||
DEF(brand, "<brand>")
 | 
			
		||||
DEF(hash_constructor, "#constructor")
 | 
			
		||||
DEF(as, "as")
 | 
			
		||||
DEF(from, "from")
 | 
			
		||||
DEF(meta, "meta")
 | 
			
		||||
DEF(_default_, "*default*")
 | 
			
		||||
DEF(_star_, "*")
 | 
			
		||||
DEF(Module, "Module")
 | 
			
		||||
DEF(then, "then")
 | 
			
		||||
DEF(resolve, "resolve")
 | 
			
		||||
DEF(reject, "reject")
 | 
			
		||||
DEF(promise, "promise")
 | 
			
		||||
DEF(proxy, "proxy")
 | 
			
		||||
DEF(revoke, "revoke")
 | 
			
		||||
DEF(async, "async")
 | 
			
		||||
DEF(exec, "exec")
 | 
			
		||||
DEF(groups, "groups")
 | 
			
		||||
DEF(indices, "indices")
 | 
			
		||||
DEF(status, "status")
 | 
			
		||||
DEF(reason, "reason")
 | 
			
		||||
DEF(globalThis, "globalThis")
 | 
			
		||||
DEF(bigint, "bigint")
 | 
			
		||||
#ifdef CONFIG_BIGNUM
 | 
			
		||||
DEF(bigfloat, "bigfloat")
 | 
			
		||||
DEF(bigdecimal, "bigdecimal")
 | 
			
		||||
DEF(roundingMode, "roundingMode")
 | 
			
		||||
DEF(maximumSignificantDigits, "maximumSignificantDigits")
 | 
			
		||||
DEF(maximumFractionDigits, "maximumFractionDigits")
 | 
			
		||||
#endif
 | 
			
		||||
/* the following 3 atoms are only used with CONFIG_ATOMICS */
 | 
			
		||||
DEF(not_equal, "not-equal")
 | 
			
		||||
DEF(timed_out, "timed-out")
 | 
			
		||||
DEF(ok, "ok")
 | 
			
		||||
/* */
 | 
			
		||||
DEF(toJSON, "toJSON")
 | 
			
		||||
/* class names */
 | 
			
		||||
DEF(Object, "Object")
 | 
			
		||||
DEF(Array, "Array")
 | 
			
		||||
DEF(Error, "Error")
 | 
			
		||||
DEF(Number, "Number")
 | 
			
		||||
DEF(String, "String")
 | 
			
		||||
DEF(Boolean, "Boolean")
 | 
			
		||||
DEF(Symbol, "Symbol")
 | 
			
		||||
DEF(Arguments, "Arguments")
 | 
			
		||||
DEF(Math, "Math")
 | 
			
		||||
DEF(JSON, "JSON")
 | 
			
		||||
DEF(Date, "Date")
 | 
			
		||||
DEF(Function, "Function")
 | 
			
		||||
DEF(GeneratorFunction, "GeneratorFunction")
 | 
			
		||||
DEF(ForInIterator, "ForInIterator")
 | 
			
		||||
DEF(RegExp, "RegExp")
 | 
			
		||||
DEF(ArrayBuffer, "ArrayBuffer")
 | 
			
		||||
DEF(SharedArrayBuffer, "SharedArrayBuffer")
 | 
			
		||||
/* must keep same order as class IDs for typed arrays */
 | 
			
		||||
DEF(Uint8ClampedArray, "Uint8ClampedArray")
 | 
			
		||||
DEF(Int8Array, "Int8Array")
 | 
			
		||||
DEF(Uint8Array, "Uint8Array")
 | 
			
		||||
DEF(Int16Array, "Int16Array")
 | 
			
		||||
DEF(Uint16Array, "Uint16Array")
 | 
			
		||||
DEF(Int32Array, "Int32Array")
 | 
			
		||||
DEF(Uint32Array, "Uint32Array")
 | 
			
		||||
DEF(BigInt64Array, "BigInt64Array")
 | 
			
		||||
DEF(BigUint64Array, "BigUint64Array")
 | 
			
		||||
DEF(Float32Array, "Float32Array")
 | 
			
		||||
DEF(Float64Array, "Float64Array")
 | 
			
		||||
DEF(DataView, "DataView")
 | 
			
		||||
DEF(BigInt, "BigInt")
 | 
			
		||||
#ifdef CONFIG_BIGNUM
 | 
			
		||||
DEF(BigFloat, "BigFloat")
 | 
			
		||||
DEF(BigFloatEnv, "BigFloatEnv")
 | 
			
		||||
DEF(BigDecimal, "BigDecimal")
 | 
			
		||||
DEF(OperatorSet, "OperatorSet")
 | 
			
		||||
DEF(Operators, "Operators")
 | 
			
		||||
#endif
 | 
			
		||||
DEF(Map, "Map")
 | 
			
		||||
DEF(Set, "Set") /* Map + 1 */
 | 
			
		||||
DEF(WeakMap, "WeakMap") /* Map + 2 */
 | 
			
		||||
DEF(WeakSet, "WeakSet") /* Map + 3 */
 | 
			
		||||
DEF(Map_Iterator, "Map Iterator")
 | 
			
		||||
DEF(Set_Iterator, "Set Iterator")
 | 
			
		||||
DEF(Array_Iterator, "Array Iterator")
 | 
			
		||||
DEF(String_Iterator, "String Iterator")
 | 
			
		||||
DEF(RegExp_String_Iterator, "RegExp String Iterator")
 | 
			
		||||
DEF(Generator, "Generator")
 | 
			
		||||
DEF(Proxy, "Proxy")
 | 
			
		||||
DEF(Promise, "Promise")
 | 
			
		||||
DEF(PromiseResolveFunction, "PromiseResolveFunction")
 | 
			
		||||
DEF(PromiseRejectFunction, "PromiseRejectFunction")
 | 
			
		||||
DEF(AsyncFunction, "AsyncFunction")
 | 
			
		||||
DEF(AsyncFunctionResolve, "AsyncFunctionResolve")
 | 
			
		||||
DEF(AsyncFunctionReject, "AsyncFunctionReject")
 | 
			
		||||
DEF(AsyncGeneratorFunction, "AsyncGeneratorFunction")
 | 
			
		||||
DEF(AsyncGenerator, "AsyncGenerator")
 | 
			
		||||
DEF(EvalError, "EvalError")
 | 
			
		||||
DEF(RangeError, "RangeError")
 | 
			
		||||
DEF(ReferenceError, "ReferenceError")
 | 
			
		||||
DEF(SyntaxError, "SyntaxError")
 | 
			
		||||
DEF(TypeError, "TypeError")
 | 
			
		||||
DEF(URIError, "URIError")
 | 
			
		||||
DEF(InternalError, "InternalError")
 | 
			
		||||
/* private symbols */
 | 
			
		||||
DEF(Private_brand, "<brand>")
 | 
			
		||||
/* symbols */
 | 
			
		||||
DEF(Symbol_toPrimitive, "Symbol.toPrimitive")
 | 
			
		||||
DEF(Symbol_iterator, "Symbol.iterator")
 | 
			
		||||
DEF(Symbol_match, "Symbol.match")
 | 
			
		||||
DEF(Symbol_matchAll, "Symbol.matchAll")
 | 
			
		||||
DEF(Symbol_replace, "Symbol.replace")
 | 
			
		||||
DEF(Symbol_search, "Symbol.search")
 | 
			
		||||
DEF(Symbol_split, "Symbol.split")
 | 
			
		||||
DEF(Symbol_toStringTag, "Symbol.toStringTag")
 | 
			
		||||
DEF(Symbol_isConcatSpreadable, "Symbol.isConcatSpreadable")
 | 
			
		||||
DEF(Symbol_hasInstance, "Symbol.hasInstance")
 | 
			
		||||
DEF(Symbol_species, "Symbol.species")
 | 
			
		||||
DEF(Symbol_unscopables, "Symbol.unscopables")
 | 
			
		||||
DEF(Symbol_asyncIterator, "Symbol.asyncIterator")
 | 
			
		||||
#ifdef CONFIG_BIGNUM
 | 
			
		||||
DEF(Symbol_operatorSet, "Symbol.operatorSet")
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* DEF */
 | 
			
		||||
							
								
								
									
										8
									
								
								src/quickjs/quickjs-config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/quickjs/quickjs-config.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
#ifndef __QUICKJS_CONFIG_H
 | 
			
		||||
#define __QUICKJS_CONFIG_H
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
#define _WIN32_WINNT 0x0600
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif	// __QUICKJS_CONFIG_H
 | 
			
		||||
							
								
								
									
										645
									
								
								src/quickjs/quickjs-internal.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										645
									
								
								src/quickjs/quickjs-internal.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,645 @@
 | 
			
		||||
#include "utils.h"
 | 
			
		||||
#include "char-utils.h"
 | 
			
		||||
#include "vector.h"
 | 
			
		||||
#include "quickjs-internal.h"
 | 
			
		||||
 | 
			
		||||
JSValue
 | 
			
		||||
js_std_file(JSContext* ctx, FILE* f) {
 | 
			
		||||
  JSClassID class_id = js_class_find(ctx, "FILE");
 | 
			
		||||
  JSValue obj, proto = JS_GetClassProto(ctx, class_id);
 | 
			
		||||
  JSSTDFile* file;
 | 
			
		||||
 | 
			
		||||
  file = js_malloc(ctx, sizeof(JSSTDFile));
 | 
			
		||||
  *file = (JSSTDFile){0, TRUE, FALSE};
 | 
			
		||||
 | 
			
		||||
  file->f = f;
 | 
			
		||||
 | 
			
		||||
  obj = JS_NewObjectProtoClass(ctx, proto, class_id);
 | 
			
		||||
 | 
			
		||||
  JS_SetOpaque(obj, file);
 | 
			
		||||
 | 
			
		||||
  return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct list_head*
 | 
			
		||||
js_modules_list(JSContext* ctx) {
 | 
			
		||||
  return &ctx->loaded_modules;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSModuleDef**
 | 
			
		||||
js_modules_vector(JSContext* ctx) {
 | 
			
		||||
  struct list_head* el;
 | 
			
		||||
  Vector vec = VECTOR(ctx);
 | 
			
		||||
  JSModuleDef* m;
 | 
			
		||||
 | 
			
		||||
  list_for_each(el, js_modules_list(ctx)) {
 | 
			
		||||
    m = list_entry(el, JSModuleDef, link);
 | 
			
		||||
 | 
			
		||||
    vector_push(&vec, m);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  m = NULL;
 | 
			
		||||
  vector_push(&vec, m);
 | 
			
		||||
 | 
			
		||||
  return vector_begin(&vec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSValue
 | 
			
		||||
js_modules_entries(JSContext* ctx, JSValueConst this_val, int magic) {
 | 
			
		||||
  struct list_head* el;
 | 
			
		||||
  JSValue ret = JS_NewArray(ctx);
 | 
			
		||||
  uint32_t i = 0;
 | 
			
		||||
  list_for_each(el, &ctx->loaded_modules) {
 | 
			
		||||
    JSModuleDef* m = list_entry(el, JSModuleDef, link);
 | 
			
		||||
    // const char* name = module_namecstr(ctx, m);
 | 
			
		||||
    JSValue entry = JS_NewArray(ctx);
 | 
			
		||||
    JS_SetPropertyUint32(ctx, entry, 0, JS_AtomToValue(ctx, m->module_name));
 | 
			
		||||
    JS_SetPropertyUint32(ctx, entry, 1, magic ? module_entry(ctx, m) : module_value(ctx, m));
 | 
			
		||||
 | 
			
		||||
    if(1 /*str[0] != '<'*/)
 | 
			
		||||
      JS_SetPropertyUint32(ctx, ret, i++, entry);
 | 
			
		||||
    else
 | 
			
		||||
      JS_FreeValue(ctx, entry);
 | 
			
		||||
 | 
			
		||||
    // JS_FreeCString(ctx, name);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSValue
 | 
			
		||||
js_modules_object(JSContext* ctx, JSValueConst this_val, int magic) {
 | 
			
		||||
  struct list_head* it;
 | 
			
		||||
  JSValue obj = JS_NewObject(ctx);
 | 
			
		||||
 | 
			
		||||
  list_for_each(it, &ctx->loaded_modules) {
 | 
			
		||||
    JSModuleDef* m = list_entry(it, JSModuleDef, link);
 | 
			
		||||
    const char* name = module_namecstr(ctx, m);
 | 
			
		||||
    JSValue entry = magic ? module_entry(ctx, m) : module_value(ctx, m);
 | 
			
		||||
 | 
			
		||||
    if(1 /*str[0] != '<'*/)
 | 
			
		||||
      JS_SetPropertyStr(ctx, obj, basename(name), entry);
 | 
			
		||||
    else
 | 
			
		||||
      JS_FreeValue(ctx, entry);
 | 
			
		||||
 | 
			
		||||
    JS_FreeCString(ctx, name);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSModuleDef*
 | 
			
		||||
js_module_find_fwd(JSContext* ctx, const char* name, JSModuleDef* start) {
 | 
			
		||||
  struct list_head* el;
 | 
			
		||||
 | 
			
		||||
  for(el = start ? &start->link : ctx->loaded_modules.next; el != &ctx->loaded_modules; el = el->next)
 | 
			
		||||
  /*list_for_each(el, &ctx->loaded_modules)*/ {
 | 
			
		||||
    JSModuleDef* m = list_entry(el, JSModuleDef, link);
 | 
			
		||||
    const char* str = module_namecstr(ctx, m);
 | 
			
		||||
    BOOL match = !strcmp(str, name);
 | 
			
		||||
    JS_FreeCString(ctx, str);
 | 
			
		||||
 | 
			
		||||
    if(match)
 | 
			
		||||
      return m;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
js_module_index(JSContext* ctx, JSModuleDef* m) {
 | 
			
		||||
  struct list_head* el;
 | 
			
		||||
  int i = 0;
 | 
			
		||||
 | 
			
		||||
  list_for_each(el, &ctx->loaded_modules) {
 | 
			
		||||
 | 
			
		||||
    if(m == list_entry(el, JSModuleDef, link))
 | 
			
		||||
      return i;
 | 
			
		||||
    ++i;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSModuleDef*
 | 
			
		||||
js_module_find_rev(JSContext* ctx, const char* name, JSModuleDef* start) {
 | 
			
		||||
  struct list_head* el;
 | 
			
		||||
 | 
			
		||||
  for(el = start ? &start->link : ctx->loaded_modules.prev; el != &ctx->loaded_modules; el = el->prev) /*list_for_each_prev(el, &ctx->loaded_modules)*/ {
 | 
			
		||||
    JSModuleDef* m = list_entry(el, JSModuleDef, link);
 | 
			
		||||
    const char* str = module_namecstr(ctx, m);
 | 
			
		||||
    BOOL match = !strcmp(str, name);
 | 
			
		||||
    JS_FreeCString(ctx, str);
 | 
			
		||||
 | 
			
		||||
    if(match)
 | 
			
		||||
      return m;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
js_module_indexof(JSContext* ctx, JSModuleDef* def) {
 | 
			
		||||
  int i = 0;
 | 
			
		||||
  struct list_head* el;
 | 
			
		||||
 | 
			
		||||
  list_for_each(el, &ctx->loaded_modules) {
 | 
			
		||||
    JSModuleDef* m = list_entry(el, JSModuleDef, link);
 | 
			
		||||
 | 
			
		||||
    if(m == def)
 | 
			
		||||
      return i;
 | 
			
		||||
 | 
			
		||||
    ++i;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSModuleDef*
 | 
			
		||||
js_module_at(JSContext* ctx, int index) {
 | 
			
		||||
  int i = 0;
 | 
			
		||||
  struct list_head* el;
 | 
			
		||||
 | 
			
		||||
  if(index >= 0) {
 | 
			
		||||
    list_for_each(el, &ctx->loaded_modules) {
 | 
			
		||||
      JSModuleDef* m = list_entry(el, JSModuleDef, link);
 | 
			
		||||
 | 
			
		||||
      if(index == i)
 | 
			
		||||
        return m;
 | 
			
		||||
 | 
			
		||||
      ++i;
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    index = -(index + 1);
 | 
			
		||||
 | 
			
		||||
    list_for_each_prev(el, &ctx->loaded_modules) {
 | 
			
		||||
      JSModuleDef* m = list_entry(el, JSModuleDef, link);
 | 
			
		||||
 | 
			
		||||
      if(index == i)
 | 
			
		||||
        return m;
 | 
			
		||||
 | 
			
		||||
      ++i;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
module_make_object(JSContext* ctx, JSModuleDef* m, JSValueConst obj) {
 | 
			
		||||
  JSValue tmp;
 | 
			
		||||
  char buf[FMT_XLONG + 2];
 | 
			
		||||
  strcpy(buf, "0x");
 | 
			
		||||
 | 
			
		||||
  if(!js_has_propertystr(ctx, obj, "name"))
 | 
			
		||||
    JS_SetPropertyStr(ctx, obj, "name", module_name(ctx, m));
 | 
			
		||||
 | 
			
		||||
  JS_DefinePropertyValueStr(ctx, obj, "resolved", JS_NewBool(ctx, m->resolved), 0);
 | 
			
		||||
  JS_DefinePropertyValueStr(ctx, obj, "funcCreated", JS_NewBool(ctx, m->func_created), 0);
 | 
			
		||||
  JS_DefinePropertyValueStr(ctx, obj, "instantiated", JS_NewBool(ctx, m->instantiated), 0);
 | 
			
		||||
  JS_DefinePropertyValueStr(ctx, obj, "evaluated", JS_NewBool(ctx, m->evaluated), 0);
 | 
			
		||||
 | 
			
		||||
  if(!JS_IsUndefined((tmp = module_ns(ctx, m))))
 | 
			
		||||
    JS_DefinePropertyValueStr(ctx, obj, "ns", tmp, 0);
 | 
			
		||||
 | 
			
		||||
  if(!JS_IsUndefined((tmp = module_exports(ctx, m))))
 | 
			
		||||
    JS_DefinePropertyValueStr(ctx, obj, "exports", tmp, 0);
 | 
			
		||||
 | 
			
		||||
  if(!JS_IsUndefined((tmp = module_imports(ctx, m))))
 | 
			
		||||
    JS_DefinePropertyValueStr(ctx, obj, "imports", tmp, 0);
 | 
			
		||||
 | 
			
		||||
  if(!JS_IsUndefined((tmp = module_reqmodules(ctx, m))))
 | 
			
		||||
    JS_SetPropertyStr(ctx, obj, "reqModules", tmp);
 | 
			
		||||
 | 
			
		||||
  if(m->init_func) {
 | 
			
		||||
    JS_SetPropertyStr(ctx, obj, "native", JS_NewBool(ctx, m->init_func != NULL));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(!JS_IsUndefined((tmp = module_func(ctx, m)))) {
 | 
			
		||||
    if(m->init_func)
 | 
			
		||||
      JS_DefinePropertyValueStr(ctx, obj, "initFunc", tmp, 0);
 | 
			
		||||
    else
 | 
			
		||||
      JS_SetPropertyStr(ctx, obj, "func", tmp);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(!js_is_null_or_undefined((tmp = JS_DupValue(ctx, m->meta_obj))))
 | 
			
		||||
    JS_SetPropertyStr(ctx, obj, "metaObj", tmp);
 | 
			
		||||
 | 
			
		||||
  if(!js_is_null_or_undefined((tmp = JS_DupValue(ctx, m->eval_exception))))
 | 
			
		||||
    JS_SetPropertyStr(ctx, obj, "evalException", tmp);
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    JSAtom atom = js_symbol_static_atom(ctx, "toStringTag");
 | 
			
		||||
    JS_DefinePropertyValue(ctx, obj, atom, JS_NewString(ctx, "Module"), 0);
 | 
			
		||||
    JS_FreeAtom(ctx, atom);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
 | 
			
		||||
    buf[2 + fmt_xlonglong0(&buf[2], (long long)(uintptr_t)m, __SIZEOF_POINTER__ * 2)] = 0;
 | 
			
		||||
 | 
			
		||||
    JS_DefinePropertyValueStr(ctx, obj, "address", JS_NewString(ctx, buf), 0);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSValue
 | 
			
		||||
module_object(JSContext* ctx, JSModuleDef* m) {
 | 
			
		||||
  JSValue obj = JS_NewObject(ctx);
 | 
			
		||||
  module_make_object(ctx, m, obj);
 | 
			
		||||
  return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
module_exports_get(JSContext* ctx, JSModuleDef* m, BOOL rename_default, JSValueConst exports) {
 | 
			
		||||
  JSAtom def = JS_NewAtom(ctx, "default");
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  for(i = 0; i < m->export_entries_count; i++) {
 | 
			
		||||
    JSExportEntry* entry = &m->export_entries[i];
 | 
			
		||||
    JSVarRef* ref = entry->u.local.var_ref;
 | 
			
		||||
    JSValue val = JS_UNDEFINED;
 | 
			
		||||
    JSAtom name = entry->export_name;
 | 
			
		||||
 | 
			
		||||
    if(ref) {
 | 
			
		||||
      val = JS_DupValue(ctx, ref->pvalue ? *ref->pvalue : ref->value);
 | 
			
		||||
 | 
			
		||||
      if(rename_default && name == def)
 | 
			
		||||
        name = m->module_name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    JS_SetProperty(ctx, exports, name, val);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  JS_FreeAtom(ctx, def);
 | 
			
		||||
  return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSValue
 | 
			
		||||
module_imports(JSContext* ctx, JSModuleDef* m) {
 | 
			
		||||
  JSValue obj = m->import_entries_count > 0 ? JS_NewArray(ctx) : JS_UNDEFINED;
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  for(i = 0; i < m->import_entries_count; i++) {
 | 
			
		||||
    JSImportEntry* entry = &m->import_entries[i];
 | 
			
		||||
    JSAtom name = entry->import_name;
 | 
			
		||||
    /*JSReqModuleEntry* req_module = &m->req_module_entries[entry->req_module_idx];
 | 
			
		||||
    JSAtom module_name = req_module->module_name;*/
 | 
			
		||||
 | 
			
		||||
    JSValue import_value = JS_NewArray(ctx);
 | 
			
		||||
 | 
			
		||||
    JS_SetPropertyUint32(ctx, import_value, 0, JS_AtomToValue(ctx, name));
 | 
			
		||||
    JS_SetPropertyUint32(ctx, import_value, 1, JS_NewUint32(ctx, entry->req_module_idx));
 | 
			
		||||
    JS_SetPropertyUint32(ctx, obj, i, import_value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSValue
 | 
			
		||||
module_reqmodules(JSContext* ctx, JSModuleDef* m) {
 | 
			
		||||
  JSValue obj = m->req_module_entries_count > 0 ? JS_NewArray(ctx) : JS_UNDEFINED;
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  for(i = 0; i < m->req_module_entries_count; i++) {
 | 
			
		||||
    JSReqModuleEntry* req_module = &m->req_module_entries[i];
 | 
			
		||||
    JSAtom module_name = req_module->module_name;
 | 
			
		||||
    JSModuleDef* module = req_module->module;
 | 
			
		||||
 | 
			
		||||
    JSValue req_module_value = JS_NewArray(ctx);
 | 
			
		||||
 | 
			
		||||
    JS_SetPropertyUint32(ctx, req_module_value, 0, JS_AtomToValue(ctx, module_name));
 | 
			
		||||
    JS_SetPropertyUint32(ctx, req_module_value, 1, JS_NewInt32(ctx, js_module_index(ctx, module)));
 | 
			
		||||
    JS_SetPropertyUint32(ctx, obj, i, req_module_value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSValue
 | 
			
		||||
module_default_export(JSContext* ctx, JSModuleDef* m) {
 | 
			
		||||
  JSAtom def = JS_NewAtom(ctx, "default");
 | 
			
		||||
  JSValue ret = JS_UNDEFINED;
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  for(i = 0; i < m->export_entries_count; i++) {
 | 
			
		||||
    JSExportEntry* entry = &m->export_entries[i];
 | 
			
		||||
    JSVarRef* ref = entry->u.local.var_ref;
 | 
			
		||||
    JSAtom name = entry->export_name;
 | 
			
		||||
 | 
			
		||||
    if(ref) {
 | 
			
		||||
 | 
			
		||||
      if(name == def) {
 | 
			
		||||
        ret = JS_DupValue(ctx, ref->pvalue ? *ref->pvalue : ref->value);
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  JS_FreeAtom(ctx, def);
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSValue
 | 
			
		||||
module_ns(JSContext* ctx, JSModuleDef* m) {
 | 
			
		||||
  return JS_DupValue(ctx, m->module_ns);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSValue
 | 
			
		||||
module_exception(JSContext* ctx, JSModuleDef* m) {
 | 
			
		||||
  return m->eval_has_exception ? JS_DupValue(ctx, m->eval_exception) : JS_NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSValue
 | 
			
		||||
module_meta_obj(JSContext* ctx, JSModuleDef* m) {
 | 
			
		||||
  return JS_DupValue(ctx, m->meta_obj);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static JSValue
 | 
			
		||||
call_module_func(JSContext* ctx, JSValueConst this_val, int argc, JSValueConst* argv, int magic, JSValue* data) {
 | 
			
		||||
  union {
 | 
			
		||||
    JSModuleInitFunc* init_func;
 | 
			
		||||
    int32_t i[2];
 | 
			
		||||
  } u;
 | 
			
		||||
 | 
			
		||||
  u.i[0] = JS_VALUE_GET_INT(data[0]);
 | 
			
		||||
  u.i[1] = JS_VALUE_GET_INT(data[1]);
 | 
			
		||||
 | 
			
		||||
  if(argc >= 1) {
 | 
			
		||||
    JSModuleDef* m;
 | 
			
		||||
 | 
			
		||||
    if((m = js_module_def(ctx, argv[0])))
 | 
			
		||||
      return JS_NewInt32(ctx, u.init_func(ctx, m));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return JS_ThrowTypeError(ctx, "argument 1 module expected");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSValue
 | 
			
		||||
module_func(JSContext* ctx, JSModuleDef* m) {
 | 
			
		||||
  JSValue func = JS_UNDEFINED;
 | 
			
		||||
 | 
			
		||||
  if(JS_IsFunction(ctx, m->func_obj)) {
 | 
			
		||||
    func = JS_DupValue(ctx, m->func_obj);
 | 
			
		||||
  } else if(m->init_func) {
 | 
			
		||||
    union {
 | 
			
		||||
      JSModuleInitFunc* init_func;
 | 
			
		||||
      int32_t i[2];
 | 
			
		||||
    } u = {m->init_func};
 | 
			
		||||
 | 
			
		||||
    JSValueConst data[2] = {
 | 
			
		||||
        JS_MKVAL(JS_TAG_INT, u.i[0]),
 | 
			
		||||
        JS_MKVAL(JS_TAG_INT, u.i[1]),
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    func = JS_NewCFunctionData(ctx, call_module_func, 1, 0, 2, data);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return func;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSValue
 | 
			
		||||
module_name(JSContext* ctx, JSModuleDef* m) {
 | 
			
		||||
 | 
			
		||||
  if(m->module_name < (size_t)JS_GetRuntime(ctx)->atom_count)
 | 
			
		||||
    return JS_AtomToValue(ctx, m->module_name);
 | 
			
		||||
 | 
			
		||||
  return JS_UNDEFINED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char*
 | 
			
		||||
module_namecstr(JSContext* ctx, JSModuleDef* m) {
 | 
			
		||||
  return JS_AtomToCString(ctx, m->module_name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSValue
 | 
			
		||||
module_exports_find(JSContext* ctx, JSModuleDef* m, JSAtom atom) {
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  for(i = 0; i < m->export_entries_count; i++) {
 | 
			
		||||
    JSExportEntry* entry = &m->export_entries[i];
 | 
			
		||||
 | 
			
		||||
    if(entry->export_name == atom) {
 | 
			
		||||
      JSVarRef* ref = entry->u.local.var_ref;
 | 
			
		||||
      JSValue export = ref ? JS_DupValue(ctx, ref->pvalue ? *ref->pvalue : ref->value) : JS_UNDEFINED;
 | 
			
		||||
      return export;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return JS_UNDEFINED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSModuleDef*
 | 
			
		||||
module_next(JSContext* ctx, JSModuleDef* m) {
 | 
			
		||||
  return m->link.next != js_modules_list(ctx) ? list_entry(m->link.next, JSModuleDef, link) : 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSModuleDef*
 | 
			
		||||
module_prev(JSContext* ctx, JSModuleDef* m) {
 | 
			
		||||
  return m->link.prev != js_modules_list(ctx) ? list_entry(m->link.prev, JSModuleDef, link) : 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSModuleDef*
 | 
			
		||||
module_last(JSContext* ctx) {
 | 
			
		||||
  struct list_head* list = js_modules_list(ctx);
 | 
			
		||||
 | 
			
		||||
  return list_empty(list) ? 0 : list_entry(list->prev, JSModuleDef, link);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
module_rename(JSContext* ctx, JSModuleDef* m, JSAtom name) {
 | 
			
		||||
  JS_FreeAtom(ctx, m->module_name);
 | 
			
		||||
  m->module_name = name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
js_arraybuffer_freestring(JSRuntime* rt, void* opaque, void* ptr) {
 | 
			
		||||
  JSString* jstr = opaque;
 | 
			
		||||
  JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_STRING, jstr));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSValue
 | 
			
		||||
js_arraybuffer_fromstring(JSContext* ctx, JSValueConst str) {
 | 
			
		||||
  JSString* jstr;
 | 
			
		||||
 | 
			
		||||
  if(!JS_IsString(str))
 | 
			
		||||
    return JS_ThrowTypeError(ctx, "Not a string");
 | 
			
		||||
 | 
			
		||||
  JS_DupValue(ctx, str);
 | 
			
		||||
  jstr = JS_VALUE_GET_PTR(str);
 | 
			
		||||
 | 
			
		||||
  return JS_NewArrayBuffer(ctx, jstr->u.str8, jstr->len, js_arraybuffer_freestring, jstr, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
js_sab_alloc(void* opaque, size_t size) {
 | 
			
		||||
  JSSABHeader* sab;
 | 
			
		||||
 | 
			
		||||
  if(!(sab = malloc(sizeof(JSSABHeader) + size)))
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
  sab->ref_count = 1;
 | 
			
		||||
  return sab->buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
js_sab_free(void* opaque, void* ptr) {
 | 
			
		||||
  JSSABHeader* sab;
 | 
			
		||||
  int ref_count;
 | 
			
		||||
  sab = (JSSABHeader*)((uint8_t*)ptr - sizeof(JSSABHeader));
 | 
			
		||||
  ref_count = atomic_add_int(&sab->ref_count, -1);
 | 
			
		||||
  assert(ref_count >= 0);
 | 
			
		||||
 | 
			
		||||
  if(ref_count == 0)
 | 
			
		||||
    free(sab);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
js_sab_dup(void* opaque, void* ptr) {
 | 
			
		||||
  JSSABHeader* sab;
 | 
			
		||||
  sab = (JSSABHeader*)((uint8_t*)ptr - sizeof(JSSABHeader));
 | 
			
		||||
  atomic_add_int(&sab->ref_count, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSValueConst
 | 
			
		||||
js_cstring_value(const char* ptr) {
 | 
			
		||||
  return JS_MKPTR(JS_TAG_STRING, (JSString*)(void*)(ptr - offsetof(JSString, u)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char*
 | 
			
		||||
js_cstring_dup(JSContext* ctx, const char* str) {
 | 
			
		||||
  /* purposely removing constness */
 | 
			
		||||
  JSString* p = (JSString*)(void*)(str - offsetof(JSString, u));
 | 
			
		||||
  JS_DupValue(ctx, JS_MKPTR(JS_TAG_STRING, p));
 | 
			
		||||
  return (char*)str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
js_cstring_len(JSValueConst v) {
 | 
			
		||||
  JSString* p;
 | 
			
		||||
 | 
			
		||||
  if(JS_IsString(v)) {
 | 
			
		||||
    p = JS_VALUE_GET_PTR(v);
 | 
			
		||||
    return p->len;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char*
 | 
			
		||||
js_cstring_ptr(JSValueConst v) {
 | 
			
		||||
  JSString* p;
 | 
			
		||||
 | 
			
		||||
  if(JS_IsString(v)) {
 | 
			
		||||
    p = JS_VALUE_GET_PTR(v);
 | 
			
		||||
    return (char*)p->u.str8;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char*
 | 
			
		||||
js_class_name(JSContext* ctx, JSClassID id) {
 | 
			
		||||
  JSAtom atom = JS_GetRuntime(ctx)->class_array[id].class_name;
 | 
			
		||||
  return JS_AtomToCString(ctx, atom);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSAtom
 | 
			
		||||
js_class_atom(JSContext* ctx, JSClassID id) {
 | 
			
		||||
  JSAtom atom = 0;
 | 
			
		||||
 | 
			
		||||
  if(id > 0 && id < (JSClassID)JS_GetRuntime(ctx)->class_count)
 | 
			
		||||
    atom = JS_GetRuntime(ctx)->class_array[id].class_name;
 | 
			
		||||
  return atom;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSClassID
 | 
			
		||||
js_class_find(JSContext* ctx, const char* name) {
 | 
			
		||||
  JSAtom atom = JS_NewAtom(ctx, name);
 | 
			
		||||
  JSRuntime* rt = JS_GetRuntime(ctx);
 | 
			
		||||
  int i, n = rt->class_count;
 | 
			
		||||
 | 
			
		||||
  for(i = 0; i < n; i++)
 | 
			
		||||
 | 
			
		||||
    if(rt->class_array[i].class_name == atom)
 | 
			
		||||
      return i;
 | 
			
		||||
 | 
			
		||||
  return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSClassID
 | 
			
		||||
js_class_id(JSContext* ctx, int id) {
 | 
			
		||||
  return JS_GetRuntime(ctx)->class_array[id].class_id;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSValue
 | 
			
		||||
js_opcode_array(JSContext* ctx, const JSOpCode* opcode) {
 | 
			
		||||
  JSValue ret = JS_NewArray(ctx);
 | 
			
		||||
  JS_SetPropertyUint32(ctx, ret, 0, JS_NewUint32(ctx, opcode->size));
 | 
			
		||||
  JS_SetPropertyUint32(ctx, ret, 1, JS_NewUint32(ctx, opcode->n_pop));
 | 
			
		||||
  JS_SetPropertyUint32(ctx, ret, 2, JS_NewUint32(ctx, opcode->n_push));
 | 
			
		||||
  JS_SetPropertyUint32(ctx, ret, 3, JS_NewUint32(ctx, opcode->fmt));
 | 
			
		||||
  JS_SetPropertyUint32(ctx, ret, 4, JS_NewString(ctx, opcode->name));
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSValue
 | 
			
		||||
js_opcode_object(JSContext* ctx, const struct JSOpCode* opcode) {
 | 
			
		||||
  JSValue ret = JS_NewObject(ctx);
 | 
			
		||||
  JS_SetPropertyStr(ctx, ret, "size", JS_NewUint32(ctx, opcode->size));
 | 
			
		||||
  JS_SetPropertyStr(ctx, ret, "n_pop", JS_NewUint32(ctx, opcode->n_pop));
 | 
			
		||||
  JS_SetPropertyStr(ctx, ret, "n_push", JS_NewUint32(ctx, opcode->n_push));
 | 
			
		||||
  JS_SetPropertyStr(ctx, ret, "fmt", JS_NewUint32(ctx, opcode->fmt));
 | 
			
		||||
  JS_SetPropertyStr(ctx, ret, "name", JS_NewString(ctx, opcode->name));
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSValue
 | 
			
		||||
js_get_bytecode(JSContext* ctx, JSValueConst value) {
 | 
			
		||||
  JSValue ret = JS_UNDEFINED;
 | 
			
		||||
 | 
			
		||||
  if(JS_IsFunction(ctx, value)) {
 | 
			
		||||
    JSObject* obj = JS_VALUE_GET_OBJ(value);
 | 
			
		||||
    JSFunctionBytecode* fnbc;
 | 
			
		||||
 | 
			
		||||
    if((fnbc = obj->u.func.function_bytecode)) {
 | 
			
		||||
      ret = JS_NewArrayBufferCopy(ctx, fnbc->byte_code_buf, fnbc->byte_code_len);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSValue
 | 
			
		||||
js_opcode_list(JSContext* ctx, BOOL as_object) {
 | 
			
		||||
  JSValue ret = JS_NewArray(ctx);
 | 
			
		||||
  size_t i, j, len = countof(js_opcodes);
 | 
			
		||||
 | 
			
		||||
  for(i = 0, j = 0; i < len; i++) {
 | 
			
		||||
 | 
			
		||||
    if(i >= OP_TEMP_START && i < OP_TEMP_END)
 | 
			
		||||
      continue;
 | 
			
		||||
 | 
			
		||||
    JS_SetPropertyUint32(ctx, ret, j++, (as_object ? js_opcode_object : js_opcode_array)(ctx, &js_opcodes[i]));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_JS_DEBUGGER_BUILD_BACKTRACE
 | 
			
		||||
JSValue js_debugger_build_backtrace(JSContext* ctx, const uint8_t* cur_pc);
 | 
			
		||||
 | 
			
		||||
JSValue
 | 
			
		||||
js_stack_get(JSContext* ctx) {
 | 
			
		||||
  return js_debugger_build_backtrace(ctx, ctx->rt->current_stack_frame->cur_pc);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define SHORT_OPCODES 1
 | 
			
		||||
 | 
			
		||||
const JSOpCode js_opcodes[OP_COUNT + (OP_TEMP_END - OP_TEMP_START)] = {
 | 
			
		||||
#define FMT(f)
 | 
			
		||||
#define DEF(id, size, n_pop, n_push, f) {size, n_pop, n_push, OP_FMT_##f, #id},
 | 
			
		||||
#include <quickjs-opcode.h>
 | 
			
		||||
#undef DEF
 | 
			
		||||
#undef FMT
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										1213
									
								
								src/quickjs/quickjs-internal.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1213
									
								
								src/quickjs/quickjs-internal.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										4051
									
								
								src/quickjs/quickjs-libc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4051
									
								
								src/quickjs/quickjs-libc.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										62
									
								
								src/quickjs/quickjs-libc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								src/quickjs/quickjs-libc.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
/*
 | 
			
		||||
 * QuickJS C library
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2017-2018 Fabrice Bellard
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 * of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
 * in the Software without restriction, including without limitation the rights
 | 
			
		||||
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
 * copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
 * THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef QUICKJS_LIBC_H
 | 
			
		||||
#define QUICKJS_LIBC_H
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include "quickjs.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
JSModuleDef *js_init_module_std(JSContext *ctx, const char *module_name);
 | 
			
		||||
JSModuleDef *js_init_module_os(JSContext *ctx, const char *module_name);
 | 
			
		||||
void js_std_add_helpers(JSContext *ctx, int argc, char **argv);
 | 
			
		||||
void js_std_loop(JSContext *ctx);
 | 
			
		||||
JSValue js_std_await(JSContext *ctx, JSValue obj);
 | 
			
		||||
void js_std_init_handlers(JSRuntime *rt);
 | 
			
		||||
void js_std_free_handlers(JSRuntime *rt);
 | 
			
		||||
void js_std_dump_error(JSContext *ctx);
 | 
			
		||||
uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename);
 | 
			
		||||
int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val,
 | 
			
		||||
                              JS_BOOL use_realpath, JS_BOOL is_main);
 | 
			
		||||
JSModuleDef *js_module_loader(JSContext *ctx,
 | 
			
		||||
                              const char *module_name, void *opaque);
 | 
			
		||||
 | 
			
		||||
int js_std_eval_binary_bare(JSContext *ctx, const uint8_t *buf, size_t buf_len);
 | 
			
		||||
void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len,
 | 
			
		||||
                        int flags);
 | 
			
		||||
void js_std_promise_rejection_tracker(JSContext *ctx, JSValueConst promise,
 | 
			
		||||
                                      JSValueConst reason,
 | 
			
		||||
                                      JS_BOOL is_handled, void *opaque);
 | 
			
		||||
void js_std_set_worker_new_context_func(JSContext *(*func)(JSRuntime *rt));
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
} /* extern "C" { */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* QUICKJS_LIBC_H */
 | 
			
		||||
							
								
								
									
										372
									
								
								src/quickjs/quickjs-opcode.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										372
									
								
								src/quickjs/quickjs-opcode.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,372 @@
 | 
			
		||||
/*
 | 
			
		||||
 * QuickJS opcode definitions
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2017-2018 Fabrice Bellard
 | 
			
		||||
 * Copyright (c) 2017-2018 Charlie Gordon
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 * of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
 * in the Software without restriction, including without limitation the rights
 | 
			
		||||
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
 * copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
 * THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef FMT
 | 
			
		||||
FMT(none)
 | 
			
		||||
FMT(none_int)
 | 
			
		||||
FMT(none_loc)
 | 
			
		||||
FMT(none_arg)
 | 
			
		||||
FMT(none_var_ref)
 | 
			
		||||
FMT(u8)
 | 
			
		||||
FMT(i8)
 | 
			
		||||
FMT(loc8)
 | 
			
		||||
FMT(const8)
 | 
			
		||||
FMT(label8)
 | 
			
		||||
FMT(u16)
 | 
			
		||||
FMT(i16)
 | 
			
		||||
FMT(label16)
 | 
			
		||||
FMT(npop)
 | 
			
		||||
FMT(npopx)
 | 
			
		||||
FMT(npop_u16)
 | 
			
		||||
FMT(loc)
 | 
			
		||||
FMT(arg)
 | 
			
		||||
FMT(var_ref)
 | 
			
		||||
FMT(u32)
 | 
			
		||||
FMT(i32)
 | 
			
		||||
FMT(const)
 | 
			
		||||
FMT(label)
 | 
			
		||||
FMT(atom)
 | 
			
		||||
FMT(atom_u8)
 | 
			
		||||
FMT(atom_u16)
 | 
			
		||||
FMT(atom_label_u8)
 | 
			
		||||
FMT(atom_label_u16)
 | 
			
		||||
FMT(label_u16)
 | 
			
		||||
#undef FMT
 | 
			
		||||
#endif /* FMT */
 | 
			
		||||
 | 
			
		||||
#ifdef DEF
 | 
			
		||||
 | 
			
		||||
#ifndef def
 | 
			
		||||
#define def(id, size, n_pop, n_push, f) DEF(id, size, n_pop, n_push, f)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
DEF(invalid, 1, 0, 0, none) /* never emitted */
 | 
			
		||||
 | 
			
		||||
/* push values */
 | 
			
		||||
DEF(       push_i32, 5, 0, 1, i32)
 | 
			
		||||
DEF(     push_const, 5, 0, 1, const)
 | 
			
		||||
DEF(       fclosure, 5, 0, 1, const) /* must follow push_const */
 | 
			
		||||
DEF(push_atom_value, 5, 0, 1, atom)
 | 
			
		||||
DEF( private_symbol, 5, 0, 1, atom)
 | 
			
		||||
DEF(      undefined, 1, 0, 1, none)
 | 
			
		||||
DEF(           null, 1, 0, 1, none)
 | 
			
		||||
DEF(      push_this, 1, 0, 1, none) /* only used at the start of a function */
 | 
			
		||||
DEF(     push_false, 1, 0, 1, none)
 | 
			
		||||
DEF(      push_true, 1, 0, 1, none)
 | 
			
		||||
DEF(         object, 1, 0, 1, none)
 | 
			
		||||
DEF( special_object, 2, 0, 1, u8) /* only used at the start of a function */
 | 
			
		||||
DEF(           rest, 3, 0, 1, u16) /* only used at the start of a function */
 | 
			
		||||
 | 
			
		||||
DEF(           drop, 1, 1, 0, none) /* a -> */
 | 
			
		||||
DEF(            nip, 1, 2, 1, none) /* a b -> b */
 | 
			
		||||
DEF(           nip1, 1, 3, 2, none) /* a b c -> b c */
 | 
			
		||||
DEF(            dup, 1, 1, 2, none) /* a -> a a */
 | 
			
		||||
DEF(           dup1, 1, 2, 3, none) /* a b -> a a b */
 | 
			
		||||
DEF(           dup2, 1, 2, 4, none) /* a b -> a b a b */
 | 
			
		||||
DEF(           dup3, 1, 3, 6, none) /* a b c -> a b c a b c */
 | 
			
		||||
DEF(        insert2, 1, 2, 3, none) /* obj a -> a obj a (dup_x1) */
 | 
			
		||||
DEF(        insert3, 1, 3, 4, none) /* obj prop a -> a obj prop a (dup_x2) */
 | 
			
		||||
DEF(        insert4, 1, 4, 5, none) /* this obj prop a -> a this obj prop a */
 | 
			
		||||
DEF(          perm3, 1, 3, 3, none) /* obj a b -> a obj b */
 | 
			
		||||
DEF(          perm4, 1, 4, 4, none) /* obj prop a b -> a obj prop b */
 | 
			
		||||
DEF(          perm5, 1, 5, 5, none) /* this obj prop a b -> a this obj prop b */
 | 
			
		||||
DEF(           swap, 1, 2, 2, none) /* a b -> b a */
 | 
			
		||||
DEF(          swap2, 1, 4, 4, none) /* a b c d -> c d a b */
 | 
			
		||||
DEF(          rot3l, 1, 3, 3, none) /* x a b -> a b x */
 | 
			
		||||
DEF(          rot3r, 1, 3, 3, none) /* a b x -> x a b */
 | 
			
		||||
DEF(          rot4l, 1, 4, 4, none) /* x a b c -> a b c x */
 | 
			
		||||
DEF(          rot5l, 1, 5, 5, none) /* x a b c d -> a b c d x */
 | 
			
		||||
 | 
			
		||||
DEF(call_constructor, 3, 2, 1, npop) /* func new.target args -> ret. arguments are not counted in n_pop */
 | 
			
		||||
DEF(           call, 3, 1, 1, npop) /* arguments are not counted in n_pop */
 | 
			
		||||
DEF(      tail_call, 3, 1, 0, npop) /* arguments are not counted in n_pop */
 | 
			
		||||
DEF(    call_method, 3, 2, 1, npop) /* arguments are not counted in n_pop */
 | 
			
		||||
DEF(tail_call_method, 3, 2, 0, npop) /* arguments are not counted in n_pop */
 | 
			
		||||
DEF(     array_from, 3, 0, 1, npop) /* arguments are not counted in n_pop */
 | 
			
		||||
DEF(          apply, 3, 3, 1, u16)
 | 
			
		||||
DEF(         return, 1, 1, 0, none)
 | 
			
		||||
DEF(   return_undef, 1, 0, 0, none)
 | 
			
		||||
DEF(check_ctor_return, 1, 1, 2, none)
 | 
			
		||||
DEF(     check_ctor, 1, 0, 0, none)
 | 
			
		||||
DEF(    check_brand, 1, 2, 2, none) /* this_obj func -> this_obj func */
 | 
			
		||||
DEF(      add_brand, 1, 2, 0, none) /* this_obj home_obj -> */
 | 
			
		||||
DEF(   return_async, 1, 1, 0, none)
 | 
			
		||||
DEF(          throw, 1, 1, 0, none)
 | 
			
		||||
DEF(    throw_error, 6, 0, 0, atom_u8)
 | 
			
		||||
DEF(           eval, 5, 1, 1, npop_u16) /* func args... -> ret_val */
 | 
			
		||||
DEF(     apply_eval, 3, 2, 1, u16) /* func array -> ret_eval */
 | 
			
		||||
DEF(         regexp, 1, 2, 1, none) /* create a RegExp object from the pattern and a
 | 
			
		||||
                                       bytecode string */
 | 
			
		||||
DEF(      get_super, 1, 1, 1, none)
 | 
			
		||||
DEF(         import, 1, 1, 1, none) /* dynamic module import */
 | 
			
		||||
 | 
			
		||||
DEF(      check_var, 5, 0, 1, atom) /* check if a variable exists */
 | 
			
		||||
DEF(  get_var_undef, 5, 0, 1, atom) /* push undefined if the variable does not exist */
 | 
			
		||||
DEF(        get_var, 5, 0, 1, atom) /* throw an exception if the variable does not exist */
 | 
			
		||||
DEF(        put_var, 5, 1, 0, atom) /* must come after get_var */
 | 
			
		||||
DEF(   put_var_init, 5, 1, 0, atom) /* must come after put_var. Used to initialize a global lexical variable */
 | 
			
		||||
DEF( put_var_strict, 5, 2, 0, atom) /* for strict mode variable write */
 | 
			
		||||
 | 
			
		||||
DEF(  get_ref_value, 1, 2, 3, none)
 | 
			
		||||
DEF(  put_ref_value, 1, 3, 0, none)
 | 
			
		||||
 | 
			
		||||
DEF(     define_var, 6, 0, 0, atom_u8)
 | 
			
		||||
DEF(check_define_var, 6, 0, 0, atom_u8)
 | 
			
		||||
DEF(    define_func, 6, 1, 0, atom_u8)
 | 
			
		||||
DEF(      get_field, 5, 1, 1, atom)
 | 
			
		||||
DEF(     get_field2, 5, 1, 2, atom)
 | 
			
		||||
DEF(      put_field, 5, 2, 0, atom)
 | 
			
		||||
DEF( get_private_field, 1, 2, 1, none) /* obj prop -> value */
 | 
			
		||||
DEF( put_private_field, 1, 3, 0, none) /* obj value prop -> */
 | 
			
		||||
DEF(define_private_field, 1, 3, 1, none) /* obj prop value -> obj */
 | 
			
		||||
DEF(   get_array_el, 1, 2, 1, none)
 | 
			
		||||
DEF(  get_array_el2, 1, 2, 2, none) /* obj prop -> obj value */
 | 
			
		||||
DEF(   put_array_el, 1, 3, 0, none)
 | 
			
		||||
DEF(get_super_value, 1, 3, 1, none) /* this obj prop -> value */
 | 
			
		||||
DEF(put_super_value, 1, 4, 0, none) /* this obj prop value -> */
 | 
			
		||||
DEF(   define_field, 5, 2, 1, atom)
 | 
			
		||||
DEF(       set_name, 5, 1, 1, atom)
 | 
			
		||||
DEF(set_name_computed, 1, 2, 2, none)
 | 
			
		||||
DEF(      set_proto, 1, 2, 1, none)
 | 
			
		||||
DEF(set_home_object, 1, 2, 2, none)
 | 
			
		||||
DEF(define_array_el, 1, 3, 2, none)
 | 
			
		||||
DEF(         append, 1, 3, 2, none) /* append enumerated object, update length */
 | 
			
		||||
DEF(copy_data_properties, 2, 3, 3, u8)
 | 
			
		||||
DEF(  define_method, 6, 2, 1, atom_u8)
 | 
			
		||||
DEF(define_method_computed, 2, 3, 1, u8) /* must come after define_method */
 | 
			
		||||
DEF(   define_class, 6, 2, 2, atom_u8) /* parent ctor -> ctor proto */
 | 
			
		||||
DEF(   define_class_computed, 6, 3, 3, atom_u8) /* field_name parent ctor -> field_name ctor proto (class with computed name) */
 | 
			
		||||
 | 
			
		||||
DEF(        get_loc, 3, 0, 1, loc)
 | 
			
		||||
DEF(        put_loc, 3, 1, 0, loc) /* must come after get_loc */
 | 
			
		||||
DEF(        set_loc, 3, 1, 1, loc) /* must come after put_loc */
 | 
			
		||||
DEF(        get_arg, 3, 0, 1, arg)
 | 
			
		||||
DEF(        put_arg, 3, 1, 0, arg) /* must come after get_arg */
 | 
			
		||||
DEF(        set_arg, 3, 1, 1, arg) /* must come after put_arg */
 | 
			
		||||
DEF(    get_var_ref, 3, 0, 1, var_ref)
 | 
			
		||||
DEF(    put_var_ref, 3, 1, 0, var_ref) /* must come after get_var_ref */
 | 
			
		||||
DEF(    set_var_ref, 3, 1, 1, var_ref) /* must come after put_var_ref */
 | 
			
		||||
DEF(set_loc_uninitialized, 3, 0, 0, loc)
 | 
			
		||||
DEF(  get_loc_check, 3, 0, 1, loc)
 | 
			
		||||
DEF(  put_loc_check, 3, 1, 0, loc) /* must come after get_loc_check */
 | 
			
		||||
DEF(  put_loc_check_init, 3, 1, 0, loc)
 | 
			
		||||
DEF(get_loc_checkthis, 3, 0, 1, loc)
 | 
			
		||||
DEF(get_var_ref_check, 3, 0, 1, var_ref)
 | 
			
		||||
DEF(put_var_ref_check, 3, 1, 0, var_ref) /* must come after get_var_ref_check */
 | 
			
		||||
DEF(put_var_ref_check_init, 3, 1, 0, var_ref)
 | 
			
		||||
DEF(      close_loc, 3, 0, 0, loc)
 | 
			
		||||
DEF(       if_false, 5, 1, 0, label)
 | 
			
		||||
DEF(        if_true, 5, 1, 0, label) /* must come after if_false */
 | 
			
		||||
DEF(           goto, 5, 0, 0, label) /* must come after if_true */
 | 
			
		||||
DEF(          catch, 5, 0, 1, label)
 | 
			
		||||
DEF(          gosub, 5, 0, 0, label) /* used to execute the finally block */
 | 
			
		||||
DEF(            ret, 1, 1, 0, none) /* used to return from the finally block */
 | 
			
		||||
DEF(      nip_catch, 1, 2, 1, none) /* catch ... a -> a */
 | 
			
		||||
 | 
			
		||||
DEF(      to_object, 1, 1, 1, none)
 | 
			
		||||
//DEF(      to_string, 1, 1, 1, none)
 | 
			
		||||
DEF(     to_propkey, 1, 1, 1, none)
 | 
			
		||||
DEF(    to_propkey2, 1, 2, 2, none)
 | 
			
		||||
 | 
			
		||||
DEF(   with_get_var, 10, 1, 0, atom_label_u8)     /* must be in the same order as scope_xxx */
 | 
			
		||||
DEF(   with_put_var, 10, 2, 1, atom_label_u8)     /* must be in the same order as scope_xxx */
 | 
			
		||||
DEF(with_delete_var, 10, 1, 0, atom_label_u8)     /* must be in the same order as scope_xxx */
 | 
			
		||||
DEF(  with_make_ref, 10, 1, 0, atom_label_u8)     /* must be in the same order as scope_xxx */
 | 
			
		||||
DEF(   with_get_ref, 10, 1, 0, atom_label_u8)     /* must be in the same order as scope_xxx */
 | 
			
		||||
DEF(with_get_ref_undef, 10, 1, 0, atom_label_u8)
 | 
			
		||||
 | 
			
		||||
DEF(   make_loc_ref, 7, 0, 2, atom_u16)
 | 
			
		||||
DEF(   make_arg_ref, 7, 0, 2, atom_u16)
 | 
			
		||||
DEF(make_var_ref_ref, 7, 0, 2, atom_u16)
 | 
			
		||||
DEF(   make_var_ref, 5, 0, 2, atom)
 | 
			
		||||
 | 
			
		||||
DEF(   for_in_start, 1, 1, 1, none)
 | 
			
		||||
DEF(   for_of_start, 1, 1, 3, none)
 | 
			
		||||
DEF(for_await_of_start, 1, 1, 3, none)
 | 
			
		||||
DEF(    for_in_next, 1, 1, 3, none)
 | 
			
		||||
DEF(    for_of_next, 2, 3, 5, u8)
 | 
			
		||||
DEF(iterator_check_object, 1, 1, 1, none)
 | 
			
		||||
DEF(iterator_get_value_done, 1, 1, 2, none)
 | 
			
		||||
DEF( iterator_close, 1, 3, 0, none)
 | 
			
		||||
DEF(  iterator_next, 1, 4, 4, none)
 | 
			
		||||
DEF(  iterator_call, 2, 4, 5, u8)
 | 
			
		||||
DEF(  initial_yield, 1, 0, 0, none)
 | 
			
		||||
DEF(          yield, 1, 1, 2, none)
 | 
			
		||||
DEF(     yield_star, 1, 1, 2, none)
 | 
			
		||||
DEF(async_yield_star, 1, 1, 2, none)
 | 
			
		||||
DEF(          await, 1, 1, 1, none)
 | 
			
		||||
 | 
			
		||||
/* arithmetic/logic operations */
 | 
			
		||||
DEF(            neg, 1, 1, 1, none)
 | 
			
		||||
DEF(           plus, 1, 1, 1, none)
 | 
			
		||||
DEF(            dec, 1, 1, 1, none)
 | 
			
		||||
DEF(            inc, 1, 1, 1, none)
 | 
			
		||||
DEF(       post_dec, 1, 1, 2, none)
 | 
			
		||||
DEF(       post_inc, 1, 1, 2, none)
 | 
			
		||||
DEF(        dec_loc, 2, 0, 0, loc8)
 | 
			
		||||
DEF(        inc_loc, 2, 0, 0, loc8)
 | 
			
		||||
DEF(        add_loc, 2, 1, 0, loc8)
 | 
			
		||||
DEF(            not, 1, 1, 1, none)
 | 
			
		||||
DEF(           lnot, 1, 1, 1, none)
 | 
			
		||||
DEF(         typeof, 1, 1, 1, none)
 | 
			
		||||
DEF(         delete, 1, 2, 1, none)
 | 
			
		||||
DEF(     delete_var, 5, 0, 1, atom)
 | 
			
		||||
 | 
			
		||||
DEF(            mul, 1, 2, 1, none)
 | 
			
		||||
DEF(            div, 1, 2, 1, none)
 | 
			
		||||
DEF(            mod, 1, 2, 1, none)
 | 
			
		||||
DEF(            add, 1, 2, 1, none)
 | 
			
		||||
DEF(            sub, 1, 2, 1, none)
 | 
			
		||||
DEF(            pow, 1, 2, 1, none)
 | 
			
		||||
DEF(            shl, 1, 2, 1, none)
 | 
			
		||||
DEF(            sar, 1, 2, 1, none)
 | 
			
		||||
DEF(            shr, 1, 2, 1, none)
 | 
			
		||||
DEF(             lt, 1, 2, 1, none)
 | 
			
		||||
DEF(            lte, 1, 2, 1, none)
 | 
			
		||||
DEF(             gt, 1, 2, 1, none)
 | 
			
		||||
DEF(            gte, 1, 2, 1, none)
 | 
			
		||||
DEF(     instanceof, 1, 2, 1, none)
 | 
			
		||||
DEF(             in, 1, 2, 1, none)
 | 
			
		||||
DEF(             eq, 1, 2, 1, none)
 | 
			
		||||
DEF(            neq, 1, 2, 1, none)
 | 
			
		||||
DEF(      strict_eq, 1, 2, 1, none)
 | 
			
		||||
DEF(     strict_neq, 1, 2, 1, none)
 | 
			
		||||
DEF(            and, 1, 2, 1, none)
 | 
			
		||||
DEF(            xor, 1, 2, 1, none)
 | 
			
		||||
DEF(             or, 1, 2, 1, none)
 | 
			
		||||
DEF(is_undefined_or_null, 1, 1, 1, none)
 | 
			
		||||
DEF(     private_in, 1, 2, 1, none)
 | 
			
		||||
#ifdef CONFIG_BIGNUM
 | 
			
		||||
DEF(      mul_pow10, 1, 2, 1, none)
 | 
			
		||||
DEF(       math_mod, 1, 2, 1, none)
 | 
			
		||||
#endif
 | 
			
		||||
/* must be the last non short and non temporary opcode */
 | 
			
		||||
DEF(            nop, 1, 0, 0, none)
 | 
			
		||||
 | 
			
		||||
/* temporary opcodes: never emitted in the final bytecode */
 | 
			
		||||
 | 
			
		||||
def(    enter_scope, 3, 0, 0, u16)  /* emitted in phase 1, removed in phase 2 */
 | 
			
		||||
def(    leave_scope, 3, 0, 0, u16)  /* emitted in phase 1, removed in phase 2 */
 | 
			
		||||
 | 
			
		||||
def(          label, 5, 0, 0, label) /* emitted in phase 1, removed in phase 3 */
 | 
			
		||||
 | 
			
		||||
/* the following opcodes must be in the same order as the 'with_x' and
 | 
			
		||||
   get_var_undef, get_var and put_var opcodes */
 | 
			
		||||
def(scope_get_var_undef, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */
 | 
			
		||||
def(  scope_get_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */
 | 
			
		||||
def(  scope_put_var, 7, 1, 0, atom_u16) /* emitted in phase 1, removed in phase 2 */
 | 
			
		||||
def(scope_delete_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */
 | 
			
		||||
def( scope_make_ref, 11, 0, 2, atom_label_u16) /* emitted in phase 1, removed in phase 2 */
 | 
			
		||||
def(  scope_get_ref, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */
 | 
			
		||||
def(scope_put_var_init, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */
 | 
			
		||||
def(scope_get_var_checkthis, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2, only used to return 'this' in derived class constructors */
 | 
			
		||||
def(scope_get_private_field, 7, 1, 1, atom_u16) /* obj -> value, emitted in phase 1, removed in phase 2 */
 | 
			
		||||
def(scope_get_private_field2, 7, 1, 2, atom_u16) /* obj -> obj value, emitted in phase 1, removed in phase 2 */
 | 
			
		||||
def(scope_put_private_field, 7, 2, 0, atom_u16) /* obj value ->, emitted in phase 1, removed in phase 2 */
 | 
			
		||||
def(scope_in_private_field, 7, 1, 1, atom_u16) /* obj -> res emitted in phase 1, removed in phase 2 */
 | 
			
		||||
def(get_field_opt_chain, 5, 1, 1, atom) /* emitted in phase 1, removed in phase 2 */
 | 
			
		||||
def(get_array_el_opt_chain, 1, 2, 1, none) /* emitted in phase 1, removed in phase 2 */
 | 
			
		||||
def( set_class_name, 5, 1, 1, u32) /* emitted in phase 1, removed in phase 2 */
 | 
			
		||||
 | 
			
		||||
def(       line_num, 5, 0, 0, u32) /* emitted in phase 1, removed in phase 3 */
 | 
			
		||||
 | 
			
		||||
#if SHORT_OPCODES
 | 
			
		||||
DEF(    push_minus1, 1, 0, 1, none_int)
 | 
			
		||||
DEF(         push_0, 1, 0, 1, none_int)
 | 
			
		||||
DEF(         push_1, 1, 0, 1, none_int)
 | 
			
		||||
DEF(         push_2, 1, 0, 1, none_int)
 | 
			
		||||
DEF(         push_3, 1, 0, 1, none_int)
 | 
			
		||||
DEF(         push_4, 1, 0, 1, none_int)
 | 
			
		||||
DEF(         push_5, 1, 0, 1, none_int)
 | 
			
		||||
DEF(         push_6, 1, 0, 1, none_int)
 | 
			
		||||
DEF(         push_7, 1, 0, 1, none_int)
 | 
			
		||||
DEF(        push_i8, 2, 0, 1, i8)
 | 
			
		||||
DEF(       push_i16, 3, 0, 1, i16)
 | 
			
		||||
DEF(    push_const8, 2, 0, 1, const8)
 | 
			
		||||
DEF(      fclosure8, 2, 0, 1, const8) /* must follow push_const8 */
 | 
			
		||||
DEF(push_empty_string, 1, 0, 1, none)
 | 
			
		||||
 | 
			
		||||
DEF(       get_loc8, 2, 0, 1, loc8)
 | 
			
		||||
DEF(       put_loc8, 2, 1, 0, loc8)
 | 
			
		||||
DEF(       set_loc8, 2, 1, 1, loc8)
 | 
			
		||||
 | 
			
		||||
DEF(       get_loc0, 1, 0, 1, none_loc)
 | 
			
		||||
DEF(       get_loc1, 1, 0, 1, none_loc)
 | 
			
		||||
DEF(       get_loc2, 1, 0, 1, none_loc)
 | 
			
		||||
DEF(       get_loc3, 1, 0, 1, none_loc)
 | 
			
		||||
DEF(       put_loc0, 1, 1, 0, none_loc)
 | 
			
		||||
DEF(       put_loc1, 1, 1, 0, none_loc)
 | 
			
		||||
DEF(       put_loc2, 1, 1, 0, none_loc)
 | 
			
		||||
DEF(       put_loc3, 1, 1, 0, none_loc)
 | 
			
		||||
DEF(       set_loc0, 1, 1, 1, none_loc)
 | 
			
		||||
DEF(       set_loc1, 1, 1, 1, none_loc)
 | 
			
		||||
DEF(       set_loc2, 1, 1, 1, none_loc)
 | 
			
		||||
DEF(       set_loc3, 1, 1, 1, none_loc)
 | 
			
		||||
DEF(       get_arg0, 1, 0, 1, none_arg)
 | 
			
		||||
DEF(       get_arg1, 1, 0, 1, none_arg)
 | 
			
		||||
DEF(       get_arg2, 1, 0, 1, none_arg)
 | 
			
		||||
DEF(       get_arg3, 1, 0, 1, none_arg)
 | 
			
		||||
DEF(       put_arg0, 1, 1, 0, none_arg)
 | 
			
		||||
DEF(       put_arg1, 1, 1, 0, none_arg)
 | 
			
		||||
DEF(       put_arg2, 1, 1, 0, none_arg)
 | 
			
		||||
DEF(       put_arg3, 1, 1, 0, none_arg)
 | 
			
		||||
DEF(       set_arg0, 1, 1, 1, none_arg)
 | 
			
		||||
DEF(       set_arg1, 1, 1, 1, none_arg)
 | 
			
		||||
DEF(       set_arg2, 1, 1, 1, none_arg)
 | 
			
		||||
DEF(       set_arg3, 1, 1, 1, none_arg)
 | 
			
		||||
DEF(   get_var_ref0, 1, 0, 1, none_var_ref)
 | 
			
		||||
DEF(   get_var_ref1, 1, 0, 1, none_var_ref)
 | 
			
		||||
DEF(   get_var_ref2, 1, 0, 1, none_var_ref)
 | 
			
		||||
DEF(   get_var_ref3, 1, 0, 1, none_var_ref)
 | 
			
		||||
DEF(   put_var_ref0, 1, 1, 0, none_var_ref)
 | 
			
		||||
DEF(   put_var_ref1, 1, 1, 0, none_var_ref)
 | 
			
		||||
DEF(   put_var_ref2, 1, 1, 0, none_var_ref)
 | 
			
		||||
DEF(   put_var_ref3, 1, 1, 0, none_var_ref)
 | 
			
		||||
DEF(   set_var_ref0, 1, 1, 1, none_var_ref)
 | 
			
		||||
DEF(   set_var_ref1, 1, 1, 1, none_var_ref)
 | 
			
		||||
DEF(   set_var_ref2, 1, 1, 1, none_var_ref)
 | 
			
		||||
DEF(   set_var_ref3, 1, 1, 1, none_var_ref)
 | 
			
		||||
 | 
			
		||||
DEF(     get_length, 1, 1, 1, none)
 | 
			
		||||
 | 
			
		||||
DEF(      if_false8, 2, 1, 0, label8)
 | 
			
		||||
DEF(       if_true8, 2, 1, 0, label8) /* must come after if_false8 */
 | 
			
		||||
DEF(          goto8, 2, 0, 0, label8) /* must come after if_true8 */
 | 
			
		||||
DEF(         goto16, 3, 0, 0, label16)
 | 
			
		||||
 | 
			
		||||
DEF(          call0, 1, 1, 1, npopx)
 | 
			
		||||
DEF(          call1, 1, 1, 1, npopx)
 | 
			
		||||
DEF(          call2, 1, 1, 1, npopx)
 | 
			
		||||
DEF(          call3, 1, 1, 1, npopx)
 | 
			
		||||
 | 
			
		||||
DEF(   is_undefined, 1, 1, 1, none)
 | 
			
		||||
DEF(        is_null, 1, 1, 1, none)
 | 
			
		||||
DEF(typeof_is_undefined, 1, 1, 1, none)
 | 
			
		||||
DEF( typeof_is_function, 1, 1, 1, none)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#undef DEF
 | 
			
		||||
#undef def
 | 
			
		||||
#endif  /* DEF */
 | 
			
		||||
							
								
								
									
										689
									
								
								src/quickjs/quickjs-textcode.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										689
									
								
								src/quickjs/quickjs-textcode.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,689 @@
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "quickjs-textcode.h"
 | 
			
		||||
#include "utils.h"
 | 
			
		||||
#include "buffer-utils.h"
 | 
			
		||||
#include "debug.h"
 | 
			
		||||
#include <libutf.h>
 | 
			
		||||
#include <libutf.h>
 | 
			
		||||
#include "tutf8e.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \addtogroup quickjs-textdecoder
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
VISIBLE JSClassID js_decoder_class_id = 0, js_encoder_class_id = 0;
 | 
			
		||||
VISIBLE JSValue textdecoder_proto = {{0}, JS_TAG_UNDEFINED}, textdecoder_ctor = {{0}, JS_TAG_UNDEFINED}, textencoder_proto = {{0}, JS_TAG_UNDEFINED},
 | 
			
		||||
                textencoder_ctor = {{0}, JS_TAG_UNDEFINED};
 | 
			
		||||
 | 
			
		||||
const TUTF8encoder* tutf8e_coders[] = {
 | 
			
		||||
    /* 0, 0, 0, 0, 0, 0, 0, 0, */
 | 
			
		||||
    &tutf8e_encoder_iso_8859_1,   &tutf8e_encoder_iso_8859_2,   &tutf8e_encoder_iso_8859_3,   &tutf8e_encoder_iso_8859_4,   &tutf8e_encoder_iso_8859_5,
 | 
			
		||||
    &tutf8e_encoder_iso_8859_6,   &tutf8e_encoder_iso_8859_7,   &tutf8e_encoder_iso_8859_8,   &tutf8e_encoder_iso_8859_9,   &tutf8e_encoder_iso_8859_10,
 | 
			
		||||
    &tutf8e_encoder_iso_8859_11,  &tutf8e_encoder_iso_8859_13,  &tutf8e_encoder_iso_8859_14,  &tutf8e_encoder_iso_8859_15,  &tutf8e_encoder_iso_8859_16,
 | 
			
		||||
    &tutf8e_encoder_windows_1250, &tutf8e_encoder_windows_1251, &tutf8e_encoder_windows_1252, &tutf8e_encoder_windows_1253, &tutf8e_encoder_windows_1254,
 | 
			
		||||
    &tutf8e_encoder_windows_1255, &tutf8e_encoder_windows_1256, &tutf8e_encoder_windows_1257, &tutf8e_encoder_windows_1258,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const char* const textcode_encodings[] = {
 | 
			
		||||
    "unknown",      "UTF-8",        "UTF-16",       "UTF-32",       "unknown",      "UTF-8",        "UTF-16BE",     "UTF-32BE",
 | 
			
		||||
    "ISO-8859-1",   "ISO-8859-2",   "ISO-8859-3",   "ISO-8859-4",   "ISO-8859-5",   "ISO-8859-6",   "ISO-8859-7",   "ISO-8859-8",
 | 
			
		||||
    "ISO-8859-9",   "ISO-8859-10",  "ISO-8859-11",  "ISO-8859-13",  "ISO-8859-14",  "ISO-8859-15",  "ISO-8859-16",  "WINDOWS-1250",
 | 
			
		||||
    "WINDOWS-1251", "WINDOWS-1252", "WINDOWS-1253", "WINDOWS-1254", "WINDOWS-1255", "WINDOWS-1256", "WINDOWS-1257", "WINDOWS-1258",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
  DECODER_DECODE,
 | 
			
		||||
  DECODER_END,
 | 
			
		||||
};
 | 
			
		||||
enum {
 | 
			
		||||
  DECODER_ENCODING,
 | 
			
		||||
  DECODER_ENDIANNESS,
 | 
			
		||||
  DECODER_BUFFERED,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static size_t
 | 
			
		||||
textdecoder_try(const void* in, size_t len) {
 | 
			
		||||
  const uint8_t *x, *y, *end;
 | 
			
		||||
  size_t r = 0;
 | 
			
		||||
  int ch;
 | 
			
		||||
 | 
			
		||||
  x = in;
 | 
			
		||||
  end = x + len;
 | 
			
		||||
 | 
			
		||||
  while(x < end) {
 | 
			
		||||
    y = x;
 | 
			
		||||
 | 
			
		||||
    if((ch = unicode_from_utf8(x, end - x, &x)) == -1)
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    r += x - y;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
textdecoder_length(TextDecoder* td) {
 | 
			
		||||
  size_t len = 0, r;
 | 
			
		||||
 | 
			
		||||
  r = textdecoder_try(ringbuffer_begin(&td->buffer), ringbuffer_continuous(&td->buffer));
 | 
			
		||||
  len += r;
 | 
			
		||||
 | 
			
		||||
  if(len == ringbuffer_continuous(&td->buffer))
 | 
			
		||||
    if(td->buffer.head < td->buffer.tail) {
 | 
			
		||||
      r = textdecoder_try(td->buffer.data, ringbuffer_head(&td->buffer));
 | 
			
		||||
      len += r;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSValue
 | 
			
		||||
textdecoder_decode(TextDecoder* dec, JSContext* ctx) {
 | 
			
		||||
  JSValue ret = JS_UNDEFINED;
 | 
			
		||||
  DynBuf dbuf;
 | 
			
		||||
  size_t i = 0, blen;
 | 
			
		||||
  uint_least32_t cp;
 | 
			
		||||
  char tmp[UTF8_CHAR_LEN_MAX];
 | 
			
		||||
  int len = 0;
 | 
			
		||||
  js_dbuf_init(ctx, &dbuf);
 | 
			
		||||
  blen = ringbuffer_length(&dec->buffer);
 | 
			
		||||
 | 
			
		||||
  if(blen)
 | 
			
		||||
    switch(dec->encoding) {
 | 
			
		||||
      case UTF8: {
 | 
			
		||||
        size_t blen, rlen = ringbuffer_length(&dec->buffer);
 | 
			
		||||
 | 
			
		||||
        if((blen = textdecoder_length(dec)) < rlen) {
 | 
			
		||||
          ringbuffer_normalize(&dec->buffer);
 | 
			
		||||
          blen = textdecoder_length(dec);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ret = JS_NewStringLen(ctx, (const char*)ringbuffer_begin(&dec->buffer), blen);
 | 
			
		||||
        ringbuffer_skip(&dec->buffer, blen);
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      case UTF16: {
 | 
			
		||||
        uint_least16_t* ptr = ringbuffer_begin(&dec->buffer);
 | 
			
		||||
        size_t n = blen & ~(0x1);
 | 
			
		||||
 | 
			
		||||
        for(i = 0; i < n; ptr = ringbuffer_next(&dec->buffer, ptr), i += 2) {
 | 
			
		||||
          uint_least16_t u16[2] = {uint16_get_endian(ptr, dec->endian), 0};
 | 
			
		||||
          size_t ns = 2;
 | 
			
		||||
 | 
			
		||||
          if(utf16_multiword(u16)) {
 | 
			
		||||
            if(i + 2 >= n)
 | 
			
		||||
              break;
 | 
			
		||||
            u16[1] = uint16_get_endian(ptr + 1, dec->endian == BIG);
 | 
			
		||||
            ns += 2;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          if(!libutf_c16_to_c32(u16, &cp)) {
 | 
			
		||||
            ret = JS_ThrowInternalError(ctx,
 | 
			
		||||
                                        "%s: TextDecoder: not a valid utf-16 code at (%llu: 0x%04x, 0x%04x): %lu",
 | 
			
		||||
                                        __func__,
 | 
			
		||||
                                        (long long unsigned int)i,
 | 
			
		||||
                                        (unsigned int)ptr[0],
 | 
			
		||||
                                        (unsigned int)ptr[1],
 | 
			
		||||
                                        (unsigned long)cp);
 | 
			
		||||
            break;
 | 
			
		||||
          }
 | 
			
		||||
          len = unicode_to_utf8((void*)tmp, cp);
 | 
			
		||||
 | 
			
		||||
          if(dbuf_put(&dbuf, (const void*)tmp, len))
 | 
			
		||||
            return JS_EXCEPTION;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      case UTF32: {
 | 
			
		||||
        const uint_least32_t* ptr = ringbuffer_begin(&dec->buffer);
 | 
			
		||||
        size_t n = blen & ~(0x3);
 | 
			
		||||
 | 
			
		||||
        for(i = 0; i < n; ptr = ringbuffer_next(&dec->buffer, ptr), i += 4) {
 | 
			
		||||
          cp = uint32_get_endian(ptr, dec->endian);
 | 
			
		||||
          if(!libutf_c32_to_c8(cp, &len, tmp)) {
 | 
			
		||||
            ret = JS_ThrowInternalError(ctx,
 | 
			
		||||
                                        "%s: TextDecoder: not a valid utf-32 code at (%llu: 0x%04x, 0x%04x): %lu",
 | 
			
		||||
                                        __func__,
 | 
			
		||||
                                        (long long unsigned int)i,
 | 
			
		||||
                                        (unsigned int)ptr[0],
 | 
			
		||||
                                        (unsigned int)ptr[1],
 | 
			
		||||
                                        (unsigned long)cp);
 | 
			
		||||
            break;
 | 
			
		||||
          }
 | 
			
		||||
          if(dbuf_put(&dbuf, (const void*)tmp, len))
 | 
			
		||||
            return JS_EXCEPTION;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      default: {
 | 
			
		||||
        TUTF8encoder encoder;
 | 
			
		||||
 | 
			
		||||
        if((encoder = *tutf8e_coders[dec->encoding - 8])) {
 | 
			
		||||
 | 
			
		||||
          const char* ptr = ringbuffer_begin(&dec->buffer);
 | 
			
		||||
          size_t n = 0;
 | 
			
		||||
 | 
			
		||||
          if(TUTF8E_OK == tutf8e_encoder_buffer_length(encoder, ptr, 0, blen, &n)) {
 | 
			
		||||
 | 
			
		||||
            uint8_t* dst = dbuf_reserve(&dbuf, n);
 | 
			
		||||
 | 
			
		||||
            if(TUTF8E_OK == tutf8e_encoder_buffer_encode(encoder, ptr, blen, 0, (char*)dst, &n)) {
 | 
			
		||||
              dbuf.size += n;
 | 
			
		||||
              i = blen;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
          ret = JS_ThrowInternalError(ctx, "%s: TextDecoder: unknown encoding: %s", __func__, textcode_encodings[dec->encoding]);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  ringbuffer_skip(&dec->buffer, i);
 | 
			
		||||
 | 
			
		||||
  if(JS_IsUndefined(ret) && dbuf.size > 0)
 | 
			
		||||
    ret = JS_NewStringLen(ctx, (const char*)dbuf.buf, dbuf.size);
 | 
			
		||||
 | 
			
		||||
  dbuf_free(&dbuf);
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static JSValue
 | 
			
		||||
js_decoder_get(JSContext* ctx, JSValueConst this_val, int magic) {
 | 
			
		||||
  TextDecoder* dec;
 | 
			
		||||
  JSValue ret = JS_UNDEFINED;
 | 
			
		||||
  if(!(dec = js_decoder_data(ctx, this_val)))
 | 
			
		||||
    return ret;
 | 
			
		||||
  switch(magic) {
 | 
			
		||||
    case DECODER_ENCODING: {
 | 
			
		||||
      ret = JS_NewString(ctx, textcode_encodings[dec->type_code]);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    case DECODER_ENDIANNESS: {
 | 
			
		||||
      ret = JS_NewBool(ctx, dec->endian == BIG);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    case DECODER_BUFFERED: {
 | 
			
		||||
      ret = JS_NewUint32(ctx, ringbuffer_length(&dec->buffer));
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static JSValue
 | 
			
		||||
js_decoder_constructor(JSContext* ctx, JSValueConst new_target, int argc, JSValueConst argv[]) {
 | 
			
		||||
  JSValue obj = JS_UNDEFINED;
 | 
			
		||||
  JSValue proto;
 | 
			
		||||
  TextDecoder* dec;
 | 
			
		||||
 | 
			
		||||
  if(!(dec = js_mallocz(ctx, sizeof(TextDecoder))))
 | 
			
		||||
    return JS_EXCEPTION;
 | 
			
		||||
 | 
			
		||||
  /* using new_target to get the prototype is necessary when the class is extended. */
 | 
			
		||||
  proto = JS_GetPropertyStr(ctx, new_target, "prototype");
 | 
			
		||||
  if(JS_IsException(proto))
 | 
			
		||||
    goto fail;
 | 
			
		||||
  if(!JS_IsObject(proto))
 | 
			
		||||
    proto = textdecoder_proto;
 | 
			
		||||
 | 
			
		||||
  /* using new_target to get the prototype is necessary when the class is extended. */
 | 
			
		||||
  obj = JS_NewObjectProtoClass(ctx, proto, js_decoder_class_id);
 | 
			
		||||
  JS_FreeValue(ctx, proto);
 | 
			
		||||
  if(JS_IsException(obj))
 | 
			
		||||
    goto fail;
 | 
			
		||||
 | 
			
		||||
  ringbuffer_init(&dec->buffer, ctx);
 | 
			
		||||
 | 
			
		||||
  if(argc >= 1) {
 | 
			
		||||
    const char* s = JS_ToCString(ctx, argv[0]);
 | 
			
		||||
 | 
			
		||||
    if(s[case_finds(s, "utf32")] || s[case_finds(s, "utf-32")])
 | 
			
		||||
      dec->encoding = UTF32;
 | 
			
		||||
    else if(s[case_finds(s, "utf16")] || s[case_finds(s, "utf-16")])
 | 
			
		||||
      dec->encoding = UTF16;
 | 
			
		||||
    else if(s[case_finds(s, "utf8")] || s[case_finds(s, "utf-8")])
 | 
			
		||||
      dec->encoding = UTF8;
 | 
			
		||||
    else {
 | 
			
		||||
      return JS_ThrowInternalError(ctx, "%s: TextDecoder: '%s' is invalid s", __func__, s);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(s[case_finds(s, "be")] || s[case_finds(s, "be")])
 | 
			
		||||
      dec->endian = BIG;
 | 
			
		||||
 | 
			
		||||
    JS_FreeCString(ctx, s);
 | 
			
		||||
  } else {
 | 
			
		||||
    dec->encoding = UTF8;
 | 
			
		||||
  }
 | 
			
		||||
  JS_SetOpaque(obj, dec);
 | 
			
		||||
 | 
			
		||||
  return obj;
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
  js_free(ctx, dec);
 | 
			
		||||
  JS_FreeValue(ctx, obj);
 | 
			
		||||
  return JS_EXCEPTION;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static JSValue
 | 
			
		||||
js_decoder_decode(JSContext* ctx, JSValueConst this_val, int argc, JSValueConst argv[], int magic) {
 | 
			
		||||
  TextDecoder* dec;
 | 
			
		||||
  JSValue ret = JS_UNDEFINED;
 | 
			
		||||
 | 
			
		||||
  if(!(dec = js_decoder_data(ctx, this_val)))
 | 
			
		||||
    return JS_EXCEPTION;
 | 
			
		||||
 | 
			
		||||
  switch(magic) {
 | 
			
		||||
    case DECODER_END:
 | 
			
		||||
    case DECODER_DECODE: {
 | 
			
		||||
      InputBuffer in = js_input_chars(ctx, argv[0]);
 | 
			
		||||
 | 
			
		||||
      // printf("js_decoder_decode (1) %s length=%zu in.size=%zu\n", magic == DECODER_DECODE ? "decode" :
 | 
			
		||||
      // "end", ringbuffer_length(&dec->buffer), in.size);
 | 
			
		||||
      if(ringbuffer_write(&dec->buffer, in.data, in.size) < 0)
 | 
			
		||||
        return JS_ThrowInternalError(ctx, "%s: TextDecoder: ringbuffer %s failed", __func__, magic == DECODER_DECODE ? "decode" : "end");
 | 
			
		||||
 | 
			
		||||
      if(ringbuffer_length(&dec->buffer) == 0)
 | 
			
		||||
        ret = JS_NULL;
 | 
			
		||||
      else
 | 
			
		||||
        ret = textdecoder_decode(dec, ctx);
 | 
			
		||||
 | 
			
		||||
      if(magic == DECODER_END)
 | 
			
		||||
        ringbuffer_reset(&dec->buffer);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static JSValue
 | 
			
		||||
js_decoder_inspect(JSContext* ctx, JSValueConst this_val, int argc, JSValueConst argv[]) {
 | 
			
		||||
  TextDecoder* dec;
 | 
			
		||||
 | 
			
		||||
  if(!(dec = js_decoder_data(ctx, this_val)))
 | 
			
		||||
    return JS_EXCEPTION;
 | 
			
		||||
 | 
			
		||||
  JSValue obj = JS_NewObjectClass(ctx, js_decoder_class_id);
 | 
			
		||||
 | 
			
		||||
  JS_DefinePropertyValueStr(ctx, obj, "encoding", JS_NewString(ctx, textcode_encodings[dec->type_code]), JS_PROP_ENUMERABLE);
 | 
			
		||||
  JS_DefinePropertyValueStr(ctx, obj, "buffered", JS_NewUint32(ctx, ringbuffer_length(&dec->buffer)), JS_PROP_ENUMERABLE);
 | 
			
		||||
  return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
js_decoder_finalizer(JSRuntime* rt, JSValue val) {
 | 
			
		||||
  TextDecoder* dec = JS_GetOpaque(val, js_decoder_class_id);
 | 
			
		||||
  if(dec) {
 | 
			
		||||
    ringbuffer_free(&dec->buffer);
 | 
			
		||||
    js_free_rt(rt, dec);
 | 
			
		||||
  }
 | 
			
		||||
  // JS_FreeValueRT(rt, val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static JSClassDef js_decoder_class = {
 | 
			
		||||
    .class_name = "TextDecoder",
 | 
			
		||||
    .finalizer = js_decoder_finalizer,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const JSCFunctionListEntry js_decoder_funcs[] = {
 | 
			
		||||
    JS_CFUNC_MAGIC_DEF("decode", 1, js_decoder_decode, DECODER_DECODE),
 | 
			
		||||
    JS_CFUNC_MAGIC_DEF("end", 1, js_decoder_decode, DECODER_END),
 | 
			
		||||
    JS_CGETSET_ENUMERABLE_DEF("encoding", js_decoder_get, 0, DECODER_ENCODING),
 | 
			
		||||
    JS_CGETSET_MAGIC_DEF("endian", js_decoder_get, 0, DECODER_ENDIANNESS),
 | 
			
		||||
    JS_CGETSET_MAGIC_DEF("buffered", js_decoder_get, 0, DECODER_BUFFERED),
 | 
			
		||||
    JS_PROP_STRING_DEF("[Symbol.toStringTag]", "TextDecoder", JS_PROP_CONFIGURABLE),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
  ENCODER_ENCODE,
 | 
			
		||||
  ENCODER_END,
 | 
			
		||||
};
 | 
			
		||||
enum {
 | 
			
		||||
  ENCODER_ENCODING,
 | 
			
		||||
  ENCODER_ENDIANNESS,
 | 
			
		||||
  ENCODER_BUFFERED,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*static size_t
 | 
			
		||||
textencoder_try(const void* in, size_t len) {
 | 
			
		||||
  const uint8_t *x, *y, *end;
 | 
			
		||||
  size_t r = 0;
 | 
			
		||||
  int ch;
 | 
			
		||||
  for(x = in, end=x+len; x < end; ) {
 | 
			
		||||
    y = x;
 | 
			
		||||
    if((ch = unicode_from_utf8(x, end - x, &x)) == -1)
 | 
			
		||||
      break;
 | 
			
		||||
    r += x - y;
 | 
			
		||||
  }
 | 
			
		||||
  return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
textencoder_length(TextEncoder* td) {
 | 
			
		||||
  size_t r = 0;
 | 
			
		||||
 | 
			
		||||
  r += textencoder_try(ringbuffer_begin(&td->buffer), ringbuffer_continuous(&td->buffer));
 | 
			
		||||
 | 
			
		||||
  if(td->buffer.head < td->buffer.tail)
 | 
			
		||||
    r += textencoder_try(td->buffer.data, ringbuffer_head(&td->buffer));
 | 
			
		||||
 | 
			
		||||
  return r;
 | 
			
		||||
}*/
 | 
			
		||||
 | 
			
		||||
JSValue
 | 
			
		||||
textencoder_read(TextEncoder* te, JSContext* ctx) {
 | 
			
		||||
  JSValue ret, buf;
 | 
			
		||||
  int bits;
 | 
			
		||||
  size_t len = ringbuffer_length(&te->buffer);
 | 
			
		||||
 | 
			
		||||
  if(len > ringbuffer_continuous(&te->buffer))
 | 
			
		||||
    ringbuffer_normalize(&te->buffer);
 | 
			
		||||
 | 
			
		||||
  switch(te->encoding) {
 | 
			
		||||
    case UTF8: bits = 8; break;
 | 
			
		||||
    case UTF16: bits = 16; break;
 | 
			
		||||
    case UTF32: bits = 32; break;
 | 
			
		||||
    default: return JS_ThrowInternalError(ctx, "%s: TextEncoder: invalid encoding: %d", __func__, te->encoding);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  buf = JS_NewArrayBufferCopy(ctx, ringbuffer_begin(&te->buffer), len);
 | 
			
		||||
  ret = js_typedarray_new(ctx, bits, FALSE, FALSE, buf);
 | 
			
		||||
  JS_FreeValue(ctx, buf);
 | 
			
		||||
 | 
			
		||||
  te->buffer.tail += len;
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
JSValue
 | 
			
		||||
textencoder_encode(TextEncoder* enc, InputBuffer in, JSContext* ctx) {
 | 
			
		||||
  JSValue ret = JS_UNDEFINED;
 | 
			
		||||
  size_t i;
 | 
			
		||||
  uint32_t cp;
 | 
			
		||||
  uint8_t u8[UTF8_CHAR_LEN_MAX];
 | 
			
		||||
  const uint8_t *ptr, *end, *next;
 | 
			
		||||
 | 
			
		||||
  switch(enc->encoding) {
 | 
			
		||||
    case UTF8: {
 | 
			
		||||
      if(ringbuffer_write(&enc->buffer, in.data, in.size) < 0)
 | 
			
		||||
        return JS_ThrowInternalError(ctx, "%s: TextEncoder: ringbuffer write failed", __func__);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    case UTF16: {
 | 
			
		||||
      ptr = block_begin(&in.block);
 | 
			
		||||
      end = block_end(&in.block);
 | 
			
		||||
 | 
			
		||||
      for(i = 0; ptr < end; ptr = next, i++) {
 | 
			
		||||
        cp = unicode_from_utf8(ptr, end - ptr, &next);
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
          uint_least16_t u16[2];
 | 
			
		||||
          int len;
 | 
			
		||||
 | 
			
		||||
          if(!libutf_c32_to_c16(cp, &len, u16))
 | 
			
		||||
            return JS_ThrowInternalError(ctx,
 | 
			
		||||
                                         "%s: TextEncoder: not a valid code point at (%llu) [%llu]: %lu",
 | 
			
		||||
                                         __func__,
 | 
			
		||||
                                         (long long unsigned int)i,
 | 
			
		||||
                                         (long long unsigned int)(end - ptr),
 | 
			
		||||
                                         (unsigned long)cp);
 | 
			
		||||
 | 
			
		||||
          for(int j = 0; j < len; j++)
 | 
			
		||||
            uint16_put_endian(u8 + j * 2, u16[j], enc->endian);
 | 
			
		||||
 | 
			
		||||
          if(ringbuffer_append(&enc->buffer, u8, len * sizeof(uint16_t), ctx) < 0)
 | 
			
		||||
            return JS_ThrowInternalError(ctx, "TextEncoder: ringbuffer write failed");
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    case UTF32: {
 | 
			
		||||
      ptr = block_begin(&in.block);
 | 
			
		||||
      end = block_end(&in.block);
 | 
			
		||||
 | 
			
		||||
      for(i = 0; ptr < end; ptr = next, i++) {
 | 
			
		||||
        cp = unicode_from_utf8(ptr, end - ptr, &next);
 | 
			
		||||
        if(cp == 0xffffffff)
 | 
			
		||||
          return JS_ThrowInternalError(
 | 
			
		||||
              ctx, "%s: TextEncoder: not a valid code point at (%llu): %lu", __func__, (long long unsigned int)(ptr - in.block.base), (long unsigned int)cp);
 | 
			
		||||
        /*cp = 0;
 | 
			
		||||
        if(!libutf_c8_to_c32(ptr, &cp))
 | 
			
		||||
          return JS_ThrowInternalError(ctx, "No a valid code point at (%zu) [%zu]: %" PRIu32, i, end - ptr,
 | 
			
		||||
        cp); next = ptr + libutf_c8_type(ptr); if(next == ptr) break;*/
 | 
			
		||||
 | 
			
		||||
        uint32_put_endian(u8, cp, enc->endian);
 | 
			
		||||
 | 
			
		||||
        if(ringbuffer_append(&enc->buffer, u8, sizeof(cp), ctx) < 0)
 | 
			
		||||
          return JS_ThrowInternalError(ctx, "%s: TextEncoder: ringbuffer write failed", __func__);
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    default: {
 | 
			
		||||
      ret = JS_ThrowInternalError(ctx, "%s: TextEncoder: unknown encoding", __func__);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static JSValue
 | 
			
		||||
js_encoder_get(JSContext* ctx, JSValueConst this_val, int magic) {
 | 
			
		||||
  TextEncoder* enc;
 | 
			
		||||
  JSValue ret = JS_UNDEFINED;
 | 
			
		||||
  if(!(enc = js_encoder_data(ctx, this_val)))
 | 
			
		||||
    return ret;
 | 
			
		||||
  switch(magic) {
 | 
			
		||||
    case ENCODER_ENCODING: {
 | 
			
		||||
      ret = JS_NewString(ctx, textcode_encodings[enc->type_code]);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    case ENCODER_ENDIANNESS: {
 | 
			
		||||
      ret = JS_NewBool(ctx, enc->endian == BIG);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    case ENCODER_BUFFERED: {
 | 
			
		||||
      ret = JS_NewUint32(ctx, ringbuffer_length(&enc->buffer));
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static JSValue
 | 
			
		||||
js_encoder_constructor(JSContext* ctx, JSValueConst new_target, int argc, JSValueConst argv[]) {
 | 
			
		||||
  JSValue obj = JS_UNDEFINED;
 | 
			
		||||
  JSValue proto;
 | 
			
		||||
  TextEncoder* enc;
 | 
			
		||||
 | 
			
		||||
  if(!(enc = js_mallocz(ctx, sizeof(TextEncoder))))
 | 
			
		||||
    return JS_EXCEPTION;
 | 
			
		||||
 | 
			
		||||
  /* using new_target to get the prototype is necessary when the class is extended. */
 | 
			
		||||
  proto = JS_GetPropertyStr(ctx, new_target, "prototype");
 | 
			
		||||
  if(JS_IsException(proto))
 | 
			
		||||
    goto fail;
 | 
			
		||||
  if(!JS_IsObject(proto))
 | 
			
		||||
    proto = textencoder_proto;
 | 
			
		||||
 | 
			
		||||
  /* using new_target to get the prototype is necessary when the class is extended. */
 | 
			
		||||
  obj = JS_NewObjectProtoClass(ctx, proto, js_encoder_class_id);
 | 
			
		||||
  JS_FreeValue(ctx, proto);
 | 
			
		||||
  if(JS_IsException(obj))
 | 
			
		||||
    goto fail;
 | 
			
		||||
 | 
			
		||||
  ringbuffer_init(&enc->buffer, ctx);
 | 
			
		||||
 | 
			
		||||
  if(argc >= 1) {
 | 
			
		||||
    const char* s = JS_ToCString(ctx, argv[0]);
 | 
			
		||||
 | 
			
		||||
    if(s[case_finds(s, "utf32")] || s[case_finds(s, "utf-32")])
 | 
			
		||||
      enc->encoding = UTF32;
 | 
			
		||||
    else if(s[case_finds(s, "utf16")] || s[case_finds(s, "utf-16")])
 | 
			
		||||
      enc->encoding = UTF16;
 | 
			
		||||
    else if(s[case_finds(s, "utf8")] || s[case_finds(s, "utf-8")])
 | 
			
		||||
      enc->encoding = UTF8;
 | 
			
		||||
    else {
 | 
			
		||||
      return JS_ThrowInternalError(ctx, "TextEncoder '%s' is invalid s", s);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(enc->encoding > UTF8)
 | 
			
		||||
      if(s[case_finds(s, "be")] || s[case_finds(s, "be")])
 | 
			
		||||
        enc->endian = BIG;
 | 
			
		||||
 | 
			
		||||
    JS_FreeCString(ctx, s);
 | 
			
		||||
  } else {
 | 
			
		||||
    enc->encoding = UTF8;
 | 
			
		||||
  }
 | 
			
		||||
  JS_SetOpaque(obj, enc);
 | 
			
		||||
 | 
			
		||||
  return obj;
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
  js_free(ctx, enc);
 | 
			
		||||
  JS_FreeValue(ctx, obj);
 | 
			
		||||
  return JS_EXCEPTION;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static JSValue
 | 
			
		||||
js_encoder_encode(JSContext* ctx, JSValueConst this_val, int argc, JSValueConst argv[], int magic) {
 | 
			
		||||
  TextEncoder* enc;
 | 
			
		||||
  JSValue ret = JS_UNDEFINED;
 | 
			
		||||
 | 
			
		||||
  if(!(enc = js_encoder_data(ctx, this_val)))
 | 
			
		||||
    return JS_EXCEPTION;
 | 
			
		||||
 | 
			
		||||
  switch(magic) {
 | 
			
		||||
    case ENCODER_END:
 | 
			
		||||
    case ENCODER_ENCODE: {
 | 
			
		||||
      InputBuffer in = js_input_chars(ctx, argv[0]);
 | 
			
		||||
 | 
			
		||||
      ret = textencoder_encode(enc, in, ctx);
 | 
			
		||||
 | 
			
		||||
      if(JS_IsException(ret))
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      if(ringbuffer_length(&enc->buffer) == 0)
 | 
			
		||||
        ret = JS_NULL;
 | 
			
		||||
      else
 | 
			
		||||
        ret = textencoder_read(enc, ctx);
 | 
			
		||||
 | 
			
		||||
      if(magic == ENCODER_END)
 | 
			
		||||
        ringbuffer_reset(&enc->buffer);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static JSValue
 | 
			
		||||
js_encoder_inspect(JSContext* ctx, JSValueConst this_val, int argc, JSValueConst argv[]) {
 | 
			
		||||
  TextEncoder* enc;
 | 
			
		||||
 | 
			
		||||
  if(!(enc = js_encoder_data(ctx, this_val)))
 | 
			
		||||
    return JS_EXCEPTION;
 | 
			
		||||
 | 
			
		||||
  JSValue obj = JS_NewObjectClass(ctx, js_encoder_class_id);
 | 
			
		||||
 | 
			
		||||
  JS_DefinePropertyValueStr(ctx, obj, "encoding", JS_NewString(ctx, textcode_encodings[enc->type_code]), JS_PROP_ENUMERABLE);
 | 
			
		||||
  JS_DefinePropertyValueStr(ctx, obj, "buffered", JS_NewUint32(ctx, ringbuffer_length(&enc->buffer)), JS_PROP_ENUMERABLE);
 | 
			
		||||
  return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
js_encoder_finalizer(JSRuntime* rt, JSValue val) {
 | 
			
		||||
  TextEncoder* enc = JS_GetOpaque(val, js_encoder_class_id);
 | 
			
		||||
  if(enc) {
 | 
			
		||||
    ringbuffer_free(&enc->buffer);
 | 
			
		||||
    js_free_rt(rt, enc);
 | 
			
		||||
  }
 | 
			
		||||
  // JS_FreeValueRT(rt, val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static JSClassDef js_encoder_class = {
 | 
			
		||||
    .class_name = "TextEncoder",
 | 
			
		||||
    .finalizer = js_encoder_finalizer,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const JSCFunctionListEntry js_encoder_funcs[] = {
 | 
			
		||||
    JS_CFUNC_MAGIC_DEF("encode", 1, js_encoder_encode, ENCODER_ENCODE),
 | 
			
		||||
    JS_CFUNC_MAGIC_DEF("end", 1, js_encoder_encode, ENCODER_END),
 | 
			
		||||
    JS_CGETSET_ENUMERABLE_DEF("encoding", js_encoder_get, 0, ENCODER_ENCODING),
 | 
			
		||||
    JS_CGETSET_MAGIC_DEF("endian", js_encoder_get, 0, ENCODER_ENDIANNESS),
 | 
			
		||||
    JS_CGETSET_MAGIC_DEF("buffered", js_encoder_get, 0, ENCODER_BUFFERED),
 | 
			
		||||
    JS_PROP_STRING_DEF("[Symbol.toStringTag]", "TextEncoder", JS_PROP_CONFIGURABLE),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern
 | 
			
		||||
void JS_NewGlobalCConstructor2(JSContext *ctx,
 | 
			
		||||
                                      JSValue func_obj,
 | 
			
		||||
                                      const char *name,
 | 
			
		||||
                                      JSValueConst proto);
 | 
			
		||||
int
 | 
			
		||||
js_code_init_textdecoder(JSContext* ctx, JSModuleDef* m)
 | 
			
		||||
{
 | 
			
		||||
    // RH TODO: check if this (possibly being called twice or for some other reason) produces a mem leak
 | 
			
		||||
    JS_NewClassID(&js_encoder_class_id);
 | 
			
		||||
    JS_NewClass(JS_GetRuntime(ctx), js_encoder_class_id, &js_encoder_class);
 | 
			
		||||
 | 
			
		||||
    textencoder_ctor = JS_NewCFunction2(ctx, js_encoder_constructor, "TextEncoder", 1, JS_CFUNC_constructor, 0);
 | 
			
		||||
    textencoder_proto = JS_NewObject(ctx);
 | 
			
		||||
 | 
			
		||||
    JS_SetPropertyFunctionList(ctx, textencoder_proto, js_encoder_funcs, countof(js_encoder_funcs));
 | 
			
		||||
    JS_SetClassProto(ctx, js_encoder_class_id, textencoder_proto);
 | 
			
		||||
    JS_SetConstructor(ctx, textencoder_ctor, textencoder_proto);
 | 
			
		||||
 | 
			
		||||
    JS_NewGlobalCConstructor2(ctx, textencoder_ctor, "TextEncoder", textencoder_proto);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    JS_NewClassID(&js_decoder_class_id);
 | 
			
		||||
    JS_NewClass(JS_GetRuntime(ctx), js_decoder_class_id, &js_decoder_class);
 | 
			
		||||
 | 
			
		||||
    textdecoder_ctor = JS_NewCFunction2(ctx, js_decoder_constructor, "TextDecoder", 1, JS_CFUNC_constructor, 0);
 | 
			
		||||
    textdecoder_proto = JS_NewObject(ctx);
 | 
			
		||||
 | 
			
		||||
    JS_SetPropertyFunctionList(ctx, textdecoder_proto, js_decoder_funcs, countof(js_decoder_funcs));
 | 
			
		||||
    JS_SetClassProto(ctx, js_decoder_class_id, textdecoder_proto);
 | 
			
		||||
 | 
			
		||||
    JS_SetConstructor(ctx, textdecoder_ctor, textdecoder_proto);
 | 
			
		||||
    
 | 
			
		||||
    JS_NewGlobalCConstructor2(ctx, textdecoder_ctor, "TextDecoder", textdecoder_proto);
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef JS_TEXTCODE_MODULE
 | 
			
		||||
#define JS_INIT_MODULE js_init_module
 | 
			
		||||
#else
 | 
			
		||||
#define JS_INIT_MODULE js_init_module_textdecoder
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
VISIBLE JSModuleDef*
 | 
			
		||||
JS_INIT_MODULE(JSContext* ctx, const char* module_name) {
 | 
			
		||||
  JSModuleDef* m;
 | 
			
		||||
 | 
			
		||||
  /*if((m = JS_NewCModule(ctx, module_name, js_code_init)))
 | 
			
		||||
  {
 | 
			
		||||
    JS_AddModuleExport(ctx, m, "TextDecoder");
 | 
			
		||||
    JS_AddModuleExport(ctx, m, "TextEncoder");
 | 
			
		||||
    //if(!strcmp(module_name, "textdecoder"))
 | 
			
		||||
    //  JS_AddModuleExport(ctx, m, "default");
 | 
			
		||||
  }*/
 | 
			
		||||
 | 
			
		||||
  return m;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @}
 | 
			
		||||
 */
 | 
			
		||||
							
								
								
									
										86
									
								
								src/quickjs/quickjs-textcode.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								src/quickjs/quickjs-textcode.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
#ifndef QUICKJS_TEXTCODE_H
 | 
			
		||||
#define QUICKJS_TEXTCODE_H
 | 
			
		||||
 | 
			
		||||
#include "utils.h"
 | 
			
		||||
#include "ringbuffer.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \defgroup quickjs-textdecoder quickjs-textdecoder: String Decoder
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
typedef enum utf_encoding { UNKNOWN = 0, UTF8, UTF16, UTF32 } UTFCharset;
 | 
			
		||||
typedef enum text_encoding {
 | 
			
		||||
  UTF16LE = 2,
 | 
			
		||||
  UTF32LE = 3,
 | 
			
		||||
  UTF16BE = 6,
 | 
			
		||||
  UTF32BE = 7,
 | 
			
		||||
  ISO_8859_1,
 | 
			
		||||
  ISO_8859_2,
 | 
			
		||||
  ISO_8859_3,
 | 
			
		||||
  ISO_8859_4,
 | 
			
		||||
  ISO_8859_5,
 | 
			
		||||
  ISO_8859_6,
 | 
			
		||||
  ISO_8859_7,
 | 
			
		||||
  ISO_8859_8,
 | 
			
		||||
  ISO_8859_9,
 | 
			
		||||
  ISO_8859_10,
 | 
			
		||||
  ISO_8859_11,
 | 
			
		||||
  ISO_8859_13,
 | 
			
		||||
  ISO_8859_14,
 | 
			
		||||
  ISO_8859_15,
 | 
			
		||||
  ISO_8859_16,
 | 
			
		||||
  WINDOWS_1250,
 | 
			
		||||
  WINDOWS_1251,
 | 
			
		||||
  WINDOWS_1252,
 | 
			
		||||
  WINDOWS_1253,
 | 
			
		||||
  WINDOWS_1254,
 | 
			
		||||
  WINDOWS_1255,
 | 
			
		||||
  WINDOWS_1256,
 | 
			
		||||
  WINDOWS_1257,
 | 
			
		||||
  WINDOWS_1258,
 | 
			
		||||
} TextEncoding;
 | 
			
		||||
 | 
			
		||||
#define TextcodeType \
 | 
			
		||||
  PACK union { \
 | 
			
		||||
    struct { \
 | 
			
		||||
      UTFCharset encoding : 2; \
 | 
			
		||||
      Endian endian : 1; \
 | 
			
		||||
    }; \
 | 
			
		||||
    TextEncoding type_code; \
 | 
			
		||||
  }; \
 | 
			
		||||
  ENDPACK
 | 
			
		||||
 | 
			
		||||
struct text_coder {
 | 
			
		||||
  RingBuffer buffer;
 | 
			
		||||
  TextcodeType
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct text_coder TextEncoder;
 | 
			
		||||
typedef struct text_coder TextDecoder;
 | 
			
		||||
 | 
			
		||||
extern VISIBLE JSClassID js_decoder_class_id, js_encoder_class_id;
 | 
			
		||||
extern VISIBLE JSValue textdecoder_proto, textdecoder_ctor, textencoder_proto, textencoder_ctor;
 | 
			
		||||
extern const char* const textcode_encodings[];
 | 
			
		||||
 | 
			
		||||
size_t textdecoder_length(TextDecoder*);
 | 
			
		||||
JSValue textdecoder_read(TextDecoder*, JSContext* ctx);
 | 
			
		||||
int js_code_init_textdecoder(JSContext*, JSModuleDef* m);
 | 
			
		||||
size_t textencoder_length(TextEncoder*);
 | 
			
		||||
JSValue textencoder_read(TextEncoder*, JSContext* ctx);
 | 
			
		||||
int js_encoder_init(JSContext*, JSModuleDef* m);
 | 
			
		||||
 | 
			
		||||
static inline TextDecoder*
 | 
			
		||||
js_decoder_data(JSContext* ctx, JSValueConst value) {
 | 
			
		||||
  return JS_GetOpaque(value, js_decoder_class_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline TextEncoder*
 | 
			
		||||
js_encoder_data(JSContext* ctx, JSValueConst value) {
 | 
			
		||||
  return JS_GetOpaque(value, js_encoder_class_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @}
 | 
			
		||||
 */
 | 
			
		||||
#endif /* defined(QUICKJS_TEXTCODE_H) */
 | 
			
		||||
							
								
								
									
										55942
									
								
								src/quickjs/quickjs.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55942
									
								
								src/quickjs/quickjs.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1070
									
								
								src/quickjs/quickjs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1070
									
								
								src/quickjs/quickjs.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										136
									
								
								src/quickjs/ringbuffer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								src/quickjs/ringbuffer.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,136 @@
 | 
			
		||||
#include "ringbuffer.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \addtogroup ringbuffer
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
ringbuffer_reset(RingBuffer* r) {
 | 
			
		||||
  r->head = r->tail = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ringbuffer_queue(RingBuffer* r, uint8_t data) {
 | 
			
		||||
  /* overwrite the oldest byte if the r is full */
 | 
			
		||||
  if(ringbuffer_full(r)) {
 | 
			
		||||
    r->tail = ((r->tail + 1) % r->size);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  r->data[r->head] = data;
 | 
			
		||||
  r->head = ((r->head + 1) % r->size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BOOL
 | 
			
		||||
ringbuffer_dequeue(RingBuffer* r, uint8_t* data) {
 | 
			
		||||
  if(ringbuffer_empty(r))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  *data = r->data[r->tail];
 | 
			
		||||
  r->tail = ((r->tail + 1) % r->size);
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ssize_t
 | 
			
		||||
ringbuffer_write(RingBuffer* r, const void* x, size_t len) {
 | 
			
		||||
  const uint8_t* p = x;
 | 
			
		||||
  size_t i;
 | 
			
		||||
 | 
			
		||||
  if(ringbuffer_avail(r) < len)
 | 
			
		||||
    return -1;
 | 
			
		||||
  //    ringbuffer_realloc(r, ringbuffer_length(r) + len);
 | 
			
		||||
 | 
			
		||||
  for(i = 0; i < len; i++) {
 | 
			
		||||
    assert(!ringbuffer_full(r));
 | 
			
		||||
    ringbuffer_queue(r, p[i]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ssize_t
 | 
			
		||||
ringbuffer_append(RingBuffer* r, const void* x, size_t len, JSContext* ctx) {
 | 
			
		||||
 | 
			
		||||
  if(!ringbuffer_reserve(r, ringbuffer_length(r) + len))
 | 
			
		||||
    return -1;
 | 
			
		||||
 | 
			
		||||
  return ringbuffer_write(r, x, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ssize_t
 | 
			
		||||
ringbuffer_read(RingBuffer* r, void* x, size_t len) {
 | 
			
		||||
  uint8_t* p = x;
 | 
			
		||||
  size_t i;
 | 
			
		||||
 | 
			
		||||
  if(ringbuffer_empty(r))
 | 
			
		||||
    return -1;
 | 
			
		||||
 | 
			
		||||
  for(i = 0; i < len; i++)
 | 
			
		||||
    ringbuffer_dequeue(r, &p[i]);
 | 
			
		||||
 | 
			
		||||
  return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t*
 | 
			
		||||
ringbuffer_peek(RingBuffer* r, size_t index) {
 | 
			
		||||
  if(index >= ringbuffer_length(r))
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
  return &r->data[(r->tail + index) % r->size];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ringbuffer_normalize(RingBuffer* r) {
 | 
			
		||||
  if(r->head < r->tail) {
 | 
			
		||||
    size_t n = r->size - r->tail;
 | 
			
		||||
    void* x = alloca(r->head);
 | 
			
		||||
    memcpy(x, r->data, r->head);
 | 
			
		||||
    memmove(r->data, &r->data[r->tail], n);
 | 
			
		||||
    memcpy(&r->data[n], x, r->head);
 | 
			
		||||
    r->tail = 0;
 | 
			
		||||
    r->head += n;
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  memcpy(r->data, &r->data[r->tail], ringbuffer_length(r));
 | 
			
		||||
  r->head -= r->tail;
 | 
			
		||||
  r->tail = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BOOL
 | 
			
		||||
ringbuffer_resize(RingBuffer* r, size_t newsize) {
 | 
			
		||||
  ringbuffer_normalize(r);
 | 
			
		||||
  if(newsize > r->size)
 | 
			
		||||
    return vector_grow(&r->vec, 1, newsize);
 | 
			
		||||
  else if(newsize < r->size)
 | 
			
		||||
    return vector_shrink(&r->vec, 1, newsize);
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BOOL
 | 
			
		||||
ringbuffer_allocate(RingBuffer* r, size_t size) {
 | 
			
		||||
  ssize_t n = ringbuffer_length(r);
 | 
			
		||||
 | 
			
		||||
  if((r->size - n) < size)
 | 
			
		||||
    return ringbuffer_resize(r, ringbuffer_length(r) + size);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t*
 | 
			
		||||
ringbuffer_reserve(RingBuffer* rb, size_t min_bytes) {
 | 
			
		||||
  ssize_t grow;
 | 
			
		||||
  if((grow = min_bytes - ringbuffer_avail(rb)) > 0)
 | 
			
		||||
    if(!ringbuffer_resize(rb, vector_size(&rb->vec, 1) + grow))
 | 
			
		||||
      return 0;
 | 
			
		||||
 | 
			
		||||
  if(ringbuffer_headroom(rb) < min_bytes)
 | 
			
		||||
    ringbuffer_normalize(rb);
 | 
			
		||||
 | 
			
		||||
  assert(ringbuffer_headroom(rb) >= min_bytes);
 | 
			
		||||
 | 
			
		||||
  return ringbuffer_end(rb);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @}
 | 
			
		||||
 */
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user