diff --git a/love/build.gradle b/love/build.gradle index 2a9e4adf..7b708cf6 100644 --- a/love/build.gradle +++ b/love/build.gradle @@ -21,7 +21,7 @@ android { ndk { // Specifies the ABI configurations of your native // libraries Gradle should build and package with your APK. - abiFilters 'armeabi-v7a', 'armeabi' + abiFilters 'armeabi-v7a' } } buildTypes { diff --git a/love/src/jni/Application.mk b/love/src/jni/Application.mk index 4b0278dd..adbddcb4 100644 --- a/love/src/jni/Application.mk +++ b/love/src/jni/Application.mk @@ -1,12 +1,12 @@ # Uncomment this if you're using STL in your project # See CPLUSPLUS-SUPPORT.html in the NDK documentation for more information # APP_STL := stlport_static -APP_STL := gnustl_shared -APP_ABI := armeabi armeabi-v7a +APP_STL := c++_shared +APP_ABI := armeabi-v7a APP_CPPFLAGS := -frtti APP_LDFLAGS := -llog -landroid -lz APP_PLATFORM := 10 -NDK_TOOLCHAIN_VERSION := 4.9 +NDK_TOOLCHAIN_VERSION := clang # Fix for building on Windows # http://stackoverflow.com/questions/12598933/ndk-build-createprocess-make-e-87-the-parameter-is-incorrect diff --git a/love/src/jni/love/.hg_archival.txt b/love/src/jni/love/.hg_archival.txt index 5470a59b..e93dc2ca 100644 --- a/love/src/jni/love/.hg_archival.txt +++ b/love/src/jni/love/.hg_archival.txt @@ -1,5 +1,6 @@ repo: d362ae6ab7f5005b8dbc7cba9ce592637de60f99 -node: 228a26ab99bbb41e47d7ff792c670dba220fca88 -branch: android -latesttag: 0.9.1 -latesttagdistance: 105 +node: a2e84c9fdb8ca18d073d0e782d68205b9aa9ec96 +branch: default +latesttag: 0.10.2 +latesttagdistance: 381 +changessincelatesttag: 550 diff --git a/love/src/jni/love/.hgignore b/love/src/jni/love/.hgignore index 0d04fc2a..6ee27a2f 100644 --- a/love/src/jni/love/.hgignore +++ b/love/src/jni/love/.hgignore @@ -1,45 +1,57 @@ -relre:platform/msvc2008/include/ -glob:platform/msvc2008/lib/ -relre:platform/msvc2008/(.*)txt -relre:platform/msvc2008/(.*)suo -glob:extra/reshax/Release/ -glob:extra/reshax/Debug/ -glob:extra/reshax/resources.h -glob:extra/reshax/resources.cpp -glob:*.obj -glob:*.o -glob:*.dirstamp -glob:*.m4 -glob:*.Po -glob:*.lo -glob:*.Plo -glob:*.dll -glob:*.user -glob:*.suo -glob:*/Release* -glob:*/Debug* -glob:*.lib -glob:*.ncb -glob:*.exe -glob:*.bat -glob:platform/macosx/build -glob:platform/macosx/Build -glob:platform/macosx/DerivedData -glob:platform/macosx/*.xcodeproj/bill* -glob:platform/macosx/*.xcodeproj/xcuserdata -glob:platform/macosx/*.xcodeproj/project.xcworkspace -glob:*.DS_Store -glob:*.dylib -glob:*.dmg* -glob:demos -glob:*.orig -relre:platform/msvc2010/include/ -glob:platform/msvc2010/lib/ -relre:platform/msvc2010/(.*)txt -relre:platform/msvc2010/(.*)suo -relre:platform/msvc2010/(.*)sdf -relre:platform/msvc2010/(.*)ipch -glob:.*.swp -glob:autom4te.cache/ -glob:src/.libs/ -glob:*~ +glob:extra/reshax/Release/ +glob:extra/reshax/Debug/ +glob:extra/reshax/resources.h +glob:extra/reshax/resources.cpp +glob:*.obj +glob:*.o +glob:*.dirstamp +glob:*.m4 +glob:*.Po +glob:*.lo +glob:*.Plo +glob:*.dll +glob:*.user +glob:*.suo +glob:*/Release* +glob:*/Debug* +glob:*.lib +glob:*.ncb +glob:*.exe +glob:*.bat +glob:platform/xcode/Build +glob:platform/xcode/DerivedData +glob:platform/xcode/ios/include +glob:platform/xcode/ios/libraries +glob:*xcuserdata* +glob:*.DS_Store +glob:*.dylib +glob:*.dmg* +glob:demos +glob:*.orig +glob:.*.swp +glob:autom4te.cache/ +glob:src/.libs/ +glob:*~ +glob:Makefile* +glob:config* +glob:libtool +glob:platform/unix/ar-lib +glob:platform/unix/compile +glob:platform/unix/config.guess +glob:platform/unix/config.sub +glob:platform/unix/debian/changelog +glob:platform/unix/debian/control +glob:platform/unix/debian/rules +glob:platform/unix/depcomp +glob:platform/unix/install-sh +glob:platform/unix/love.desktop +glob:platform/unix/ltmain.sh +glob:platform/unix/missing +glob:.lineno +glob:*.la +glob:*.Tpo +glob:*.rej +glob:*/.deps +glob:stamp-h1 +glob:src/love +glob:src/tags diff --git a/love/src/jni/love/.hgtags b/love/src/jni/love/.hgtags index e12439c6..69c60352 100644 --- a/love/src/jni/love/.hgtags +++ b/love/src/jni/love/.hgtags @@ -7,3 +7,7 @@ bcca82b60d0f5cd724edbe4ed65db18ab95d4691 0.7.2 e0f98d53debb62347c6433ca0534a0f77f15f76f 0.8.0 38c00c788bcb03bda2ad40efebcdfe7a6be85b4a 0.9.0 8b113c345e97e7bb7e963e5d67451abdfb05cfde 0.9.1 +a5e405cdf14d030b71d09a105086797942ae91a9 0.9.2 +14717f0fb5d96d380c10fe6f41b74b7652c7d836 0.10.0 +3cb3559eebb89803c0b7fa83d51d8e48a2b20b7a 0.10.1 +afc69c4f714534c64e6f8c8660b724b5b736d7f3 0.10.2 diff --git a/love/src/jni/love/Android.mk b/love/src/jni/love/Android.mk index f44bcbc4..47474c28 100644 --- a/love/src/jni/love/Android.mk +++ b/love/src/jni/love/Android.mk @@ -16,6 +16,8 @@ LOCAL_C_INCLUDES := \ ${LOCAL_PATH}/src/modules \ ${LOCAL_PATH}/src/libraries/ \ ${LOCAL_PATH}/src/libraries/enet/libenet/include \ + ${LOCAL_PATH}/src/libraries/physfs \ + ${LOCAL_PATH}/src/libraries/glslang/glslang/Include \ ${LOCAL_PATH}/../SDL2-2.0.7/include \ ${LOCAL_PATH}/../jasper-1.900.1/src/libjasper/include \ ${LOCAL_PATH}/../libmng-1.0.10/ \ @@ -25,7 +27,6 @@ LOCAL_C_INCLUDES := \ ${LOCAL_PATH}/../openal-soft-1.18.2/OpenAL32/Include \ ${LOCAL_PATH}/../freetype2-android/include \ ${LOCAL_PATH}/../freetype2-android/src \ - ${LOCAL_PATH}/../physfs-3.0.1/src \ ${LOCAL_PATH}/../mpg123-1.17.0/src/libmpg123 \ ${LOCAL_PATH}/../libmodplug-0.8.8.4/src \ ${LOCAL_PATH}/../libvorbis-1.3.5/include \ @@ -43,6 +44,7 @@ LOCAL_SRC_FILES := \ $(wildcard ${LOCAL_PATH}/src/modules/audio/*.cpp) \ $(wildcard ${LOCAL_PATH}/src/modules/audio/null/*.cpp) \ $(wildcard ${LOCAL_PATH}/src/modules/audio/openal/*.cpp) \ + $(wildcard ${LOCAL_PATH}/src/modules/data/*.cpp) \ $(wildcard ${LOCAL_PATH}/src/modules/event/*.cpp) \ $(wildcard ${LOCAL_PATH}/src/modules/event/sdl/*.cpp) \ $(wildcard ${LOCAL_PATH}/src/modules/filesystem/*.cpp) \ @@ -87,22 +89,31 @@ LOCAL_SRC_FILES := \ $(wildcard ${LOCAL_PATH}/src/libraries/Box2D/Dynamics/Joints/*.cpp) \ $(wildcard ${LOCAL_PATH}/src/libraries/Box2D/Rope/*.cpp) \ $(wildcard ${LOCAL_PATH}/src/libraries/glad/*.cpp) \ + $(wildcard ${LOCAL_PATH}/src/libraries/glslang/glslang/GenericCodeGen/*.cpp) \ + $(wildcard ${LOCAL_PATH}/src/libraries/glslang/glslang/MachineIndependent/*.cpp) \ + $(wildcard ${LOCAL_PATH}/src/libraries/glslang/glslang/MachineIndependent/preprocessor/*.cpp) \ + $(wildcard ${LOCAL_PATH}/src/libraries/glslang/glslang/OSDependent/Unix/*.cpp) \ + $(wildcard ${LOCAL_PATH}/src/libraries/glslang/OGLCompilersDLL/*.cpp) \ + $(wildcard ${LOCAL_PATH}/src/libraries/glslang/glslang//*.cpp) \ $(wildcard ${LOCAL_PATH}/src/libraries/enet/*.cpp) \ $(wildcard ${LOCAL_PATH}/src/libraries/enet/libenet/*.c) \ + $(wildcard ${LOCAL_PATH}/src/libraries/lua53/*.c) \ $(wildcard ${LOCAL_PATH}/src/libraries/luasocket/*.cpp) \ $(wildcard ${LOCAL_PATH}/src/libraries/luautf8/*.c) \ $(wildcard ${LOCAL_PATH}/src/libraries/luasocket/libluasocket/*.c) \ - $(wildcard ${LOCAL_PATH}/src/libraries/noise1234/*.cpp) \ - $(wildcard ${LOCAL_PATH}/src/libraries/Wuff/*.c) \ $(wildcard ${LOCAL_PATH}/src/libraries/lodepng/*.cpp) \ $(wildcard ${LOCAL_PATH}/src/libraries/lz4/*.c) \ + $(wildcard ${LOCAL_PATH}/src/libraries/noise1234/*.cpp) \ + $(wildcard ${LOCAL_PATH}/src/libraries/physfs/*.c) \ + $(wildcard ${LOCAL_PATH}/src/libraries/Wuff/*.c) \ + $(wildcard ${LOCAL_PATH}/src/libraries/xxHash/*.c) \ )) LOCAL_CXXFLAGS := -std=c++0x LOCAL_SHARED_LIBRARIES := libopenal libmpg123 -LOCAL_STATIC_LIBRARIES := libphysfs libvorbis libogg libtheora libmodplug libfreetype libluajit SDL2_static +LOCAL_STATIC_LIBRARIES := libvorbis libogg libtheora libmodplug libfreetype libluajit SDL2_static # $(info liblove: include dirs $(LOCAL_C_INCLUDES)) # $(info liblove: src files $(LOCAL_SRC_FILES)) diff --git a/love/src/jni/love/CMakeLists.txt b/love/src/jni/love/CMakeLists.txt index 38d2e718..9ab59cfd 100755 --- a/love/src/jni/love/CMakeLists.txt +++ b/love/src/jni/love/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2006-2016 LOVE Development Team +# Copyright (c) 2006-2018 LOVE Development Team # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages @@ -97,7 +97,6 @@ if(MEGA) ${MEGA_LIBTHEORA} ${MEGA_MODPLUG} ${MEGA_OPENAL} - ${MEGA_PHYSFS} ${MEGA_SDL2MAIN} ${MEGA_SDL2} ${MEGA_ZLIB} @@ -172,7 +171,6 @@ Please see http://bitbucket.org/rude/megasource find_package(ModPlug REQUIRED) find_package(OpenAL REQUIRED) find_package(OpenGL REQUIRED) - find_package(PhysFS REQUIRED) find_package(SDL2 REQUIRED) find_package(Theora REQUIRED) find_package(Vorbis REQUIRED) @@ -182,7 +180,6 @@ Please see http://bitbucket.org/rude/megasource set(LOVE_INCLUDE_DIRS ${SDL2_INCLUDE_DIR} - ${PHYSFS_INCLUDE_DIR} ${FREETYPE_INCLUDE_DIRS} ${VORBIS_INCLUDE_DIR} ) @@ -193,7 +190,6 @@ Please see http://bitbucket.org/rude/megasource ${FREETYPE_LIBRARY} ${OPENAL_LIBRARY} ${MODPLUG_LIBRARY} - ${PHYSFS_LIBRARY} ${THEORA_LIBRARY} ${THEORADEC_LIBRARY} ${VORBISFILE_LIBRARY} @@ -255,27 +251,41 @@ endfunction() set(LOVE_SRC_COMMON src/common/b64.cpp src/common/b64.h + src/common/Color.h src/common/config.h + src/common/Data.cpp src/common/Data.h src/common/delay.cpp src/common/delay.h + src/common/deprecation.cpp + src/common/deprecation.h src/common/EnumMap.h src/common/Exception.cpp src/common/Exception.h + src/common/halffloat.cpp + src/common/halffloat.h src/common/int.h src/common/math.h src/common/Matrix.cpp src/common/Matrix.h src/common/Memoizer.cpp src/common/Memoizer.h + src/common/memory.cpp + src/common/memory.h src/common/Module.cpp src/common/Module.h src/common/Object.cpp src/common/Object.h + src/common/Optional.h + src/common/pixelformat.cpp + src/common/pixelformat.h src/common/Reference.cpp src/common/Reference.h src/common/runtime.cpp src/common/runtime.h + src/common/Stream.cpp + src/common/Stream.h + src/common/StringMap.cpp src/common/StringMap.h src/common/types.cpp src/common/types.h @@ -286,8 +296,6 @@ set(LOVE_SRC_COMMON #src/common/Vector.cpp # Vector.cpp is empty. src/common/Vector.h src/common/version.h - src/common/wrap_Data.cpp - src/common/wrap_Data.h ) if (APPLE) @@ -307,10 +315,18 @@ set(LOVE_SRC_MODULE_AUDIO_ROOT src/modules/audio/Audio.h src/modules/audio/Source.cpp src/modules/audio/Source.h + src/modules/audio/RecordingDevice.cpp + src/modules/audio/RecordingDevice.h + src/modules/audio/Filter.cpp + src/modules/audio/Filter.h + src/modules/audio/Effect.cpp + src/modules/audio/Effect.h src/modules/audio/wrap_Audio.cpp src/modules/audio/wrap_Audio.h src/modules/audio/wrap_Source.cpp src/modules/audio/wrap_Source.h + src/modules/audio/wrap_RecordingDevice.cpp + src/modules/audio/wrap_RecordingDevice.h ) set(LOVE_SRC_MODULE_AUDIO_NULL @@ -318,6 +334,8 @@ set(LOVE_SRC_MODULE_AUDIO_NULL src/modules/audio/null/Audio.h src/modules/audio/null/Source.cpp src/modules/audio/null/Source.h + src/modules/audio/null/RecordingDevice.cpp + src/modules/audio/null/RecordingDevice.h ) set(LOVE_SRC_MODULE_AUDIO_OPENAL @@ -327,6 +345,12 @@ set(LOVE_SRC_MODULE_AUDIO_OPENAL src/modules/audio/openal/Pool.h src/modules/audio/openal/Source.cpp src/modules/audio/openal/Source.h + src/modules/audio/openal/RecordingDevice.cpp + src/modules/audio/openal/RecordingDevice.h + src/modules/audio/openal/Filter.cpp + src/modules/audio/openal/Filter.h + src/modules/audio/openal/Effect.cpp + src/modules/audio/openal/Effect.h ) set(LOVE_SRC_MODULE_AUDIO @@ -339,6 +363,37 @@ source_group("modules\\audio" FILES ${LOVE_SRC_MODULE_AUDIO_ROOT}) source_group("modules\\audio\\null" FILES ${LOVE_SRC_MODULE_AUDIO_NULL}) source_group("modules\\audio\\openal" FILES ${LOVE_SRC_MODULE_AUDIO_OPENAL}) +# +# love.data +# + +set(LOVE_SRC_MODULE_DATA + src/modules/data/ByteData.cpp + src/modules/data/ByteData.h + src/modules/data/CompressedData.cpp + src/modules/data/CompressedData.h + src/modules/data/Compressor.cpp + src/modules/data/Compressor.h + src/modules/data/DataModule.cpp + src/modules/data/DataModule.h + src/modules/data/DataView.cpp + src/modules/data/DataView.h + src/modules/data/HashFunction.cpp + src/modules/data/HashFunction.h + src/modules/data/wrap_ByteData.cpp + src/modules/data/wrap_ByteData.h + src/modules/data/wrap_CompressedData.cpp + src/modules/data/wrap_CompressedData.h + src/modules/data/wrap_Data.cpp + src/modules/data/wrap_Data.h + src/modules/data/wrap_DataModule.cpp + src/modules/data/wrap_DataModule.h + src/modules/data/wrap_DataView.cpp + src/modules/data/wrap_DataView.h +) + +source_group("modules\\data" FILES ${LOVE_SRC_MODULE_DATA}) + # # love.event # @@ -446,71 +501,94 @@ source_group("modules\\font\\freetype" FILES ${LOVE_SRC_MODULE_FONT_FREETYPE}) # set(LOVE_SRC_MODULE_GRAPHICS_ROOT - src/modules/graphics/Color.h + src/modules/graphics/Buffer.cpp + src/modules/graphics/Buffer.h + src/modules/graphics/Canvas.cpp + src/modules/graphics/Canvas.h + src/modules/graphics/depthstencil.cpp + src/modules/graphics/depthstencil.h + src/modules/graphics/Deprecations.cpp + src/modules/graphics/Deprecations.h + src/modules/graphics/Drawable.cpp src/modules/graphics/Drawable.h + src/modules/graphics/Font.cpp + src/modules/graphics/Font.h src/modules/graphics/Graphics.cpp src/modules/graphics/Graphics.h + src/modules/graphics/Image.cpp + src/modules/graphics/Image.h + src/modules/graphics/Mesh.cpp + src/modules/graphics/Mesh.h src/modules/graphics/ParticleSystem.cpp src/modules/graphics/ParticleSystem.h + src/modules/graphics/Polyline.cpp + src/modules/graphics/Polyline.h src/modules/graphics/Quad.cpp src/modules/graphics/Quad.h + src/modules/graphics/Resource.h + src/modules/graphics/Shader.cpp + src/modules/graphics/Shader.h + src/modules/graphics/ShaderStage.cpp + src/modules/graphics/ShaderStage.h + src/modules/graphics/SpriteBatch.cpp + src/modules/graphics/SpriteBatch.h + src/modules/graphics/StreamBuffer.cpp + src/modules/graphics/StreamBuffer.h + src/modules/graphics/Text.cpp + src/modules/graphics/Text.h src/modules/graphics/Texture.cpp src/modules/graphics/Texture.h + src/modules/graphics/vertex.cpp + src/modules/graphics/vertex.h + src/modules/graphics/Video.cpp + src/modules/graphics/Video.h src/modules/graphics/Volatile.cpp src/modules/graphics/Volatile.h + src/modules/graphics/wrap_Canvas.cpp + src/modules/graphics/wrap_Canvas.h + src/modules/graphics/wrap_Font.cpp + src/modules/graphics/wrap_Font.h + src/modules/graphics/wrap_Graphics.cpp + src/modules/graphics/wrap_Graphics.h + src/modules/graphics/wrap_Image.cpp + src/modules/graphics/wrap_Image.h + src/modules/graphics/wrap_Mesh.cpp + src/modules/graphics/wrap_Mesh.h + src/modules/graphics/wrap_ParticleSystem.cpp + src/modules/graphics/wrap_ParticleSystem.h src/modules/graphics/wrap_Quad.cpp src/modules/graphics/wrap_Quad.h + src/modules/graphics/wrap_Shader.cpp + src/modules/graphics/wrap_Shader.h + src/modules/graphics/wrap_SpriteBatch.cpp + src/modules/graphics/wrap_SpriteBatch.h src/modules/graphics/wrap_Texture.cpp src/modules/graphics/wrap_Texture.h + src/modules/graphics/wrap_Text.cpp + src/modules/graphics/wrap_Text.h + src/modules/graphics/wrap_Video.cpp + src/modules/graphics/wrap_Video.h ) set(LOVE_SRC_MODULE_GRAPHICS_OPENGL + src/modules/graphics/opengl/Buffer.cpp + src/modules/graphics/opengl/Buffer.h src/modules/graphics/opengl/Canvas.cpp src/modules/graphics/opengl/Canvas.h - src/modules/graphics/opengl/Font.cpp - src/modules/graphics/opengl/Font.h - src/modules/graphics/opengl/GLBuffer.cpp - src/modules/graphics/opengl/GLBuffer.h + src/modules/graphics/opengl/FenceSync.cpp + src/modules/graphics/opengl/FenceSync.h src/modules/graphics/opengl/Graphics.cpp src/modules/graphics/opengl/Graphics.h src/modules/graphics/opengl/Image.cpp src/modules/graphics/opengl/Image.h - src/modules/graphics/opengl/Mesh.cpp - src/modules/graphics/opengl/Mesh.h src/modules/graphics/opengl/OpenGL.cpp src/modules/graphics/opengl/OpenGL.h - src/modules/graphics/opengl/ParticleSystem.cpp - src/modules/graphics/opengl/ParticleSystem.h - src/modules/graphics/opengl/Polyline.cpp - src/modules/graphics/opengl/Polyline.h src/modules/graphics/opengl/Shader.cpp src/modules/graphics/opengl/Shader.h - src/modules/graphics/opengl/SpriteBatch.cpp - src/modules/graphics/opengl/SpriteBatch.h - src/modules/graphics/opengl/Text.cpp - src/modules/graphics/opengl/Text.h - src/modules/graphics/opengl/Video.cpp - src/modules/graphics/opengl/Video.h - src/modules/graphics/opengl/wrap_Canvas.cpp - src/modules/graphics/opengl/wrap_Canvas.h - src/modules/graphics/opengl/wrap_Font.cpp - src/modules/graphics/opengl/wrap_Font.h - src/modules/graphics/opengl/wrap_Graphics.cpp - src/modules/graphics/opengl/wrap_Graphics.h - src/modules/graphics/opengl/wrap_Image.cpp - src/modules/graphics/opengl/wrap_Image.h - src/modules/graphics/opengl/wrap_Mesh.cpp - src/modules/graphics/opengl/wrap_Mesh.h - src/modules/graphics/opengl/wrap_ParticleSystem.cpp - src/modules/graphics/opengl/wrap_ParticleSystem.h - src/modules/graphics/opengl/wrap_Shader.cpp - src/modules/graphics/opengl/wrap_Shader.h - src/modules/graphics/opengl/wrap_SpriteBatch.cpp - src/modules/graphics/opengl/wrap_SpriteBatch.h - src/modules/graphics/opengl/wrap_Text.cpp - src/modules/graphics/opengl/wrap_Text.h - src/modules/graphics/opengl/wrap_Video.cpp - src/modules/graphics/opengl/wrap_Video.h + src/modules/graphics/opengl/ShaderStage.cpp + src/modules/graphics/opengl/ShaderStage.h + src/modules/graphics/opengl/StreamBuffer.cpp + src/modules/graphics/opengl/StreamBuffer.h ) set(LOVE_SRC_MODULE_GRAPHICS @@ -528,9 +606,16 @@ source_group("modules\\graphics\\opengl" FILES ${LOVE_SRC_MODULE_GRAPHICS_OPENGL set(LOVE_SRC_MODULE_IMAGE_ROOT src/modules/image/CompressedImageData.cpp src/modules/image/CompressedImageData.h + src/modules/image/CompressedSlice.cpp + src/modules/image/CompressedSlice.h + src/modules/image/FormatHandler.cpp + src/modules/image/FormatHandler.h + src/modules/image/Image.cpp src/modules/image/Image.h src/modules/image/ImageData.cpp src/modules/image/ImageData.h + src/modules/image/ImageDataBase.cpp + src/modules/image/ImageDataBase.h src/modules/image/wrap_CompressedImageData.cpp src/modules/image/wrap_CompressedImageData.h src/modules/image/wrap_Image.cpp @@ -542,17 +627,10 @@ set(LOVE_SRC_MODULE_IMAGE_ROOT set(LOVE_SRC_MODULE_IMAGE_MAGPIE src/modules/image/magpie/ASTCHandler.cpp src/modules/image/magpie/ASTCHandler.h - src/modules/image/magpie/CompressedImageData.cpp - src/modules/image/magpie/CompressedImageData.h - src/modules/image/magpie/CompressedFormatHandler.h src/modules/image/magpie/ddsHandler.cpp src/modules/image/magpie/ddsHandler.h - src/modules/image/magpie/FormatHandler.cpp - src/modules/image/magpie/FormatHandler.h - src/modules/image/magpie/Image.cpp - src/modules/image/magpie/Image.h - src/modules/image/magpie/ImageData.cpp - src/modules/image/magpie/ImageData.h + src/modules/image/magpie/EXRHandler.cpp + src/modules/image/magpie/EXRHandler.h src/modules/image/magpie/KTXHandler.cpp src/modules/image/magpie/KTXHandler.h src/modules/image/magpie/PKMHandler.cpp @@ -633,22 +711,20 @@ source_group("modules\\keyboard\\sdl" FILES ${LOVE_SRC_MODULE_KEYBOARD_SDL}) set(LOVE_SRC_MODULE_MATH src/modules/math/BezierCurve.cpp src/modules/math/BezierCurve.h - src/modules/math/CompressedData.cpp - src/modules/math/CompressedData.h - src/modules/math/Compressor.cpp - src/modules/math/Compressor.h src/modules/math/MathModule.cpp src/modules/math/MathModule.h src/modules/math/RandomGenerator.cpp src/modules/math/RandomGenerator.h + src/modules/math/Transform.cpp + src/modules/math/Transform.h src/modules/math/wrap_BezierCurve.cpp src/modules/math/wrap_BezierCurve.h - src/modules/math/wrap_CompressedData.cpp - src/modules/math/wrap_CompressedData.h src/modules/math/wrap_Math.cpp src/modules/math/wrap_Math.h src/modules/math/wrap_RandomGenerator.cpp src/modules/math/wrap_RandomGenerator.h + src/modules/math/wrap_Transform.cpp + src/modules/math/wrap_Transform.h ) source_group("modules\\math" FILES ${LOVE_SRC_MODULE_MATH}) @@ -809,6 +885,7 @@ source_group("modules\\physics\\box2d" FILES ${LOVE_SRC_MODULE_PHYSICS_BOX2D}) # set(LOVE_SRC_MODULE_SOUND_ROOT + src/modules/sound/Decoder.cpp src/modules/sound/Decoder.h src/modules/sound/Sound.cpp src/modules/sound/Sound.h @@ -823,8 +900,6 @@ set(LOVE_SRC_MODULE_SOUND_ROOT ) set(LOVE_SRC_MODULE_SOUND_LULLABY - src/modules/sound/lullaby/Decoder.cpp - src/modules/sound/lullaby/Decoder.h src/modules/sound/lullaby/FLACDecoder.cpp src/modules/sound/lullaby/FLACDecoder.h src/modules/sound/lullaby/GmeDecoder.cpp @@ -920,25 +995,14 @@ source_group("modules\\thread\\sdl" FILES ${LOVE_SRC_MODULE_THREAD_SDL}) # love.timer # -set(LOVE_SRC_MODULE_TIMER_ROOT +set(LOVE_SRC_MODULE_TIMER src/modules/timer/Timer.cpp src/modules/timer/Timer.h src/modules/timer/wrap_Timer.cpp src/modules/timer/wrap_Timer.h ) -set(LOVE_SRC_MODULE_TIMER_SDL - src/modules/timer/sdl/Timer.cpp - src/modules/timer/sdl/Timer.h -) - -set(LOVE_SRC_MODULE_TIMER - ${LOVE_SRC_MODULE_TIMER_ROOT} - ${LOVE_SRC_MODULE_TIMER_SDL} -) - -source_group("modules\\timer" FILES ${LOVE_SRC_MODULE_TIMER_ROOT}) -source_group("modules\\timer\\sdl" FILES ${LOVE_SRC_MODULE_TIMER_SDL}) +source_group("modules\\timer" FILES ${LOVE_SRC_MODULE_TIMER}) # # love.touch @@ -980,8 +1044,10 @@ set(LOVE_SRC_MODULE_VIDEO_ROOT set(LOVE_SRC_MODULE_VIDEO_THEORA src/modules/video/theora/Video.cpp src/modules/video/theora/Video.h - src/modules/video/theora/VideoStream.cpp - src/modules/video/theora/VideoStream.h + src/modules/video/theora/OggDemuxer.cpp + src/modules/video/theora/OggDemuxer.h + src/modules/video/theora/TheoraVideoStream.cpp + src/modules/video/theora/TheoraVideoStream.h ) set(LOVE_SRC_MODULE_VIDEO @@ -1220,6 +1286,121 @@ set(LOVE_SRC_3P_GLAD add_library(love_3p_glad ${LOVE_SRC_3P_GLAD}) +# +# glslang +# + +set(LOVE_SRC_3P_GLSLANG_GLSLANG_GENERICCODEGEN + src/libraries/glslang/glslang/GenericCodeGen/CodeGen.cpp + src/libraries/glslang/glslang/GenericCodeGen/Link.cpp +) + +set(LOVE_SRC_3P_GLSLANG_GLSLANG_INCLUDE + src/libraries/glslang/glslang/Include/arrays.h + src/libraries/glslang/glslang/Include/BaseTypes.h + src/libraries/glslang/glslang/Include/Common.h + src/libraries/glslang/glslang/Include/ConstantUnion.h + src/libraries/glslang/glslang/Include/InfoSink.h + src/libraries/glslang/glslang/Include/InitializeGlobals.h + src/libraries/glslang/glslang/Include/intermediate.h + src/libraries/glslang/glslang/Include/PoolAlloc.h + src/libraries/glslang/glslang/Include/ResourceLimits.h + src/libraries/glslang/glslang/Include/revision.h + src/libraries/glslang/glslang/Include/ShHandle.h + src/libraries/glslang/glslang/Include/Types.h +) + +set(LOVE_SRC_3P_GLSLANG_GLSLANG_MACHINEINDEPENDENT_PREPROCESSOR + src/libraries/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp + src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpAtom.cpp + src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp + src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.h + src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp + src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp + src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.h +) + +set(LOVE_SRC_3P_GLSLANG_GLSLANG_MACHINEINDEPENDENT + ${LOVE_SRC_3P_GLSLANG_GLSLANG_MACHINEINDEPENDENT_PREPROCESSOR} + src/libraries/glslang/glslang/MachineIndependent/Constant.cpp + src/libraries/glslang/glslang/MachineIndependent/gl_types.h + src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp + src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp.h + src/libraries/glslang/glslang/MachineIndependent/InfoSink.cpp + src/libraries/glslang/glslang/MachineIndependent/Initialize.cpp + src/libraries/glslang/glslang/MachineIndependent/Initialize.h + src/libraries/glslang/glslang/MachineIndependent/Intermediate.cpp + src/libraries/glslang/glslang/MachineIndependent/intermOut.cpp + src/libraries/glslang/glslang/MachineIndependent/IntermTraverse.cpp + src/libraries/glslang/glslang/MachineIndependent/iomapper.cpp + src/libraries/glslang/glslang/MachineIndependent/iomapper.h + src/libraries/glslang/glslang/MachineIndependent/limits.cpp + src/libraries/glslang/glslang/MachineIndependent/linkValidate.cpp + src/libraries/glslang/glslang/MachineIndependent/LiveTraverser.h + src/libraries/glslang/glslang/MachineIndependent/localintermediate.h + src/libraries/glslang/glslang/MachineIndependent/parseConst.cpp + src/libraries/glslang/glslang/MachineIndependent/ParseContextBase.cpp + src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp + src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h + src/libraries/glslang/glslang/MachineIndependent/parseVersions.h + src/libraries/glslang/glslang/MachineIndependent/PoolAlloc.cpp + src/libraries/glslang/glslang/MachineIndependent/propagateNoContraction.cpp + src/libraries/glslang/glslang/MachineIndependent/propagateNoContraction.h + src/libraries/glslang/glslang/MachineIndependent/reflection.cpp + src/libraries/glslang/glslang/MachineIndependent/reflection.h + src/libraries/glslang/glslang/MachineIndependent/RemoveTree.cpp + src/libraries/glslang/glslang/MachineIndependent/RemoveTree.h + src/libraries/glslang/glslang/MachineIndependent/Scan.cpp + src/libraries/glslang/glslang/MachineIndependent/Scan.h + src/libraries/glslang/glslang/MachineIndependent/ScanContext.h + src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp + src/libraries/glslang/glslang/MachineIndependent/SymbolTable.cpp + src/libraries/glslang/glslang/MachineIndependent/SymbolTable.h + src/libraries/glslang/glslang/MachineIndependent/Versions.cpp + src/libraries/glslang/glslang/MachineIndependent/Versions.h +) + +set(LOVE_SRC_3P_GLSLANG_GLSLANG_OSDEPENDENT + src/libraries/glslang/glslang/OSDependent/osinclude.h +) + +if(MSVC) + set(LOVE_SRC_3P_GLSLANG_GLSLANG_OSDEPENDENT + ${LOVE_SRC_3P_GLSLANG_GLSLANG_OSDEPENDENT} + src/libraries/glslang/glslang/OSDependent/Windows/main.cpp + src/libraries/glslang/glslang/OSDependent/Windows/ossource.cpp + ) +else() + set(LOVE_SRC_3P_GLSLANG_GLSLANG_OSDEPENDENT + ${LOVE_SRC_3P_GLSLANG_GLSLANG_OSDEPENDENT} + src/libraries/glslang/glslang/OSDependent/Unix/ossource.cpp + ) +endif() + +set(LOVE_SRC_3P_GLSLANG_GLSLANG_PUBLIC + src/libraries/glslang/glslang/Public/ShaderLang.h +) + +set(LOVE_SRC_3P_GLSLANG_GLSLANG + ${LOVE_SRC_3P_GLSLANG_GLSLANG_GENERICCODEGEN} + ${LOVE_SRC_3P_GLSLANG_GLSLANG_INCLUDE} + ${LOVE_SRC_3P_GLSLANG_GLSLANG_MACHINEINDEPENDENT} + ${LOVE_SRC_3P_GLSLANG_GLSLANG_OSDEPENDENT} + ${LOVE_SRC_3P_GLSLANG_GLSLANG_PUBLIC} +) + +set(LOVE_SRC_3P_GLSLANG_OGLCOMPILERSDLL + src/libraries/glslang/OGLCompilersDLL/InitializeDll.cpp + src/libraries/glslang/OGLCompilersDLL/InitializeDll.h +) + +set(LOVE_SRC_3P_GLSLANG + ${LOVE_SRC_3P_GLSLANG_GLSLANG} + ${LOVE_SRC_3P_GLSLANG_OGLCOMPILERSDLL} +) + +add_library(love_3p_glslang ${LOVE_SRC_3P_GLSLANG}) + # # LodePNG # @@ -1245,23 +1426,27 @@ set(LOVE_SRC_3P_LUASOCKET_LIBLUASOCKET src/libraries/luasocket/libluasocket/auxiliar.h src/libraries/luasocket/libluasocket/buffer.c src/libraries/luasocket/libluasocket/buffer.h + src/libraries/luasocket/libluasocket/compat.c + src/libraries/luasocket/libluasocket/compat.h src/libraries/luasocket/libluasocket/except.c src/libraries/luasocket/libluasocket/except.h src/libraries/luasocket/libluasocket/ftp.lua.h + src/libraries/luasocket/libluasocket/headers.lua.h src/libraries/luasocket/libluasocket/http.lua.h src/libraries/luasocket/libluasocket/inet.c src/libraries/luasocket/libluasocket/inet.h src/libraries/luasocket/libluasocket/io.c src/libraries/luasocket/libluasocket/io.h src/libraries/luasocket/libluasocket/ltn12.lua.h - src/libraries/luasocket/libluasocket/lua.h src/libraries/luasocket/libluasocket/luasocket.c src/libraries/luasocket/libluasocket/luasocket.h + src/libraries/luasocket/libluasocket/mbox.lua.h src/libraries/luasocket/libluasocket/mime.c src/libraries/luasocket/libluasocket/mime.h src/libraries/luasocket/libluasocket/mime.lua.h src/libraries/luasocket/libluasocket/options.c src/libraries/luasocket/libluasocket/options.h + src/libraries/luasocket/libluasocket/pierror.h src/libraries/luasocket/libluasocket/select.c src/libraries/luasocket/libluasocket/select.h src/libraries/luasocket/libluasocket/smtp.lua.h @@ -1277,15 +1462,29 @@ set(LOVE_SRC_3P_LUASOCKET_LIBLUASOCKET src/libraries/luasocket/libluasocket/url.lua.h ) +set(LOVE_LINK_L3P_LUASOCKET_LIBLUASOCKET) + if(MSVC) set(LOVE_SRC_3P_LUASOCKET_LIBLUASOCKET ${LOVE_SRC_3P_LUASOCKET_LIBLUASOCKET} src/libraries/luasocket/libluasocket/wsocket.c src/libraries/luasocket/libluasocket/wsocket.h ) + + set(LOVE_LINK_L3P_LUASOCKET_LIBLUASOCKET + ${LOVE_LINK_L3P_LUASOCKET_LIBLUASOCKET} + ws2_32.lib + ) else() set(LOVE_SRC_3P_LUASOCKET_LIBLUASOCKET ${LOVE_SRC_3P_LUASOCKET_LIBLUASOCKET} + src/libraries/luasocket/libluasocket/serial.c + src/libraries/luasocket/libluasocket/unix.c + src/libraries/luasocket/libluasocket/unix.h + src/libraries/luasocket/libluasocket/unixtcp.c + src/libraries/luasocket/libluasocket/unixtcp.h + src/libraries/luasocket/libluasocket/unixudp.c + src/libraries/luasocket/libluasocket/unixudp.h src/libraries/luasocket/libluasocket/usocket.c src/libraries/luasocket/libluasocket/usocket.h ) @@ -1297,20 +1496,22 @@ set(LOVE_SRC_3P_LUASOCKET ) add_library(love_3p_luasocket ${LOVE_SRC_3P_LUASOCKET}) -target_link_libraries(love_3p_luasocket ${LOVE_LUA_LIBRARY}) +target_link_libraries(love_3p_luasocket ${LOVE_LUA_LIBRARY} ${LOVE_LINK_L3P_LUASOCKET_LIBLUASOCKET}) # -# Lua 5.3's UTF-8 library +# APIs from Lua 5.3 # -set(LOVE_SRC_3P_LUAUTF8 - src/libraries/luautf8/lprefix.h - src/libraries/luautf8/lutf8lib.c - src/libraries/luautf8/lutf8lib.h +set(LOVE_SRC_3P_LUA53 + src/libraries/lua53/lprefix.h + src/libraries/lua53/lstrlib.c + src/libraries/lua53/lstrlib.h + src/libraries/lua53/lutf8lib.c + src/libraries/lua53/lutf8lib.h ) -add_library(love_3p_luautf8 ${LOVE_SRC_3P_LUAUTF8}) -target_link_libraries(love_3p_luautf8 ${LOVE_LUA_LIBRARY}) +add_library(love_3p_lua53 ${LOVE_SRC_3P_LUA53}) +target_link_libraries(love_3p_lua53 ${LOVE_LUA_LIBRARY}) # # lz4 @@ -1321,6 +1522,7 @@ set(LOVE_SRC_3P_LZ4 src/libraries/lz4/lz4.h src/libraries/lz4/lz4hc.c src/libraries/lz4/lz4hc.h + src/libraries/lz4/lz4opt.h ) add_library(love_3p_lz4 ${LOVE_SRC_3P_LZ4}) @@ -1338,6 +1540,49 @@ set(LOVE_SRC_3P_NOISE1234 add_library(love_3p_noise1234 ${LOVE_SRC_3P_NOISE1234}) +# +# physfs +# + +set(LOVE_SRC_3P_PHYSFS + src/libraries/physfs/physfs_archiver_7z.c + src/libraries/physfs/physfs_archiver_dir.c + src/libraries/physfs/physfs_archiver_grp.c + src/libraries/physfs/physfs_archiver_hog.c + src/libraries/physfs/physfs_archiver_iso9660.c + src/libraries/physfs/physfs_archiver_mvl.c + src/libraries/physfs/physfs_archiver_qpak.c + src/libraries/physfs/physfs_archiver_slb.c + src/libraries/physfs/physfs_archiver_unpacked.c + src/libraries/physfs/physfs_archiver_vdf.c + src/libraries/physfs/physfs_archiver_wad.c + src/libraries/physfs/physfs_archiver_zip.c + src/libraries/physfs/physfs_byteorder.c + src/libraries/physfs/physfs_casefolding.h + src/libraries/physfs/physfs_internal.h + src/libraries/physfs/physfs_lzmasdk.h + src/libraries/physfs/physfs_miniz.h + src/libraries/physfs/physfs_platform_haiku.cpp + src/libraries/physfs/physfs_platform_os2.c + src/libraries/physfs/physfs_platform_posix.c + src/libraries/physfs/physfs_platform_qnx.c + src/libraries/physfs/physfs_platform_unix.c + src/libraries/physfs/physfs_platform_windows.c + src/libraries/physfs/physfs_platform_winrt.cpp + src/libraries/physfs/physfs_platforms.h + src/libraries/physfs/physfs_unicode.c + src/libraries/physfs/physfs.c + src/libraries/physfs/physfs.h +) + +if(APPLE) + set(LOVE_SRC_3P_PHYSFS ${LOVE_SRC_3P_PHYSFS} + src/libraries/physfs/physfs_platform_apple.m + ) +endif() + +add_library(love_3p_physfs ${LOVE_SRC_3P_PHYSFS}) + # # stb_image # @@ -1348,6 +1593,16 @@ set(LOVE_SRC_3P_STB # stb_image has no implementation files of its own. +# +# tiny exr +# + +set(LOVE_SRC_3P_TINYEXR + src/libraries/tinyexr/tinyexr.h +) + +# tinyexr has no implementation files of its own. + # # utf8 # @@ -1385,20 +1640,34 @@ set(LOVE_SRC_3P_WUFF add_library(love_3p_wuff ${LOVE_SRC_3P_WUFF}) +# +# xxHash +# + +set(LOVE_SRC_3P_XXHASH + src/libraries/xxHash/xxhash.c + src/libraries/xxHash/xxhash.h +) + +add_library(love_3p_xxhash ${LOVE_SRC_3P_XXHASH}) + set(LOVE_3P love_3p_box2d love_3p_ddsparse love_3p_enet love_3p_glad + love_3p_glslang love_3p_lodepng love_3p_luasocket - love_3p_luautf8 + love_3p_lua53 love_3p_lz4 love_3p_noise1234 + love_3p_physfs love_3p_wuff + love_3p_xxhash ) -love_disable_warnings(love_3p_box2d love_3p_enet love_3p_luasocket) +love_disable_warnings(love_3p_box2d love_3p_enet love_3p_luasocket love_3p_physfs) # # liblove @@ -1407,6 +1676,7 @@ set(LOVE_LIB_SRC ${LOVE_SRC_COMMON} # Modules ${LOVE_SRC_MODULE_AUDIO} + ${LOVE_SRC_MODULE_DATA} ${LOVE_SRC_MODULE_EVENT} ${LOVE_SRC_MODULE_FILESYSTEM} ${LOVE_SRC_MODULE_FONT} diff --git a/love/src/jni/love/changes.txt b/love/src/jni/love/changes.txt index 5b50368c..135f2cf6 100644 --- a/love/src/jni/love/changes.txt +++ b/love/src/jni/love/changes.txt @@ -1,3 +1,170 @@ +LOVE 0.11.0 [] +-------------- + +Released: N/A + + * Added Object:release. + * Added Data:clone. + * Added queueable audio sources. + * Added audio input support. + * Added Source filters: low gain, high gain and band pass. + * Added audio effect APIs (reverb, echo, etc.) + * Added variants of SoundData:getSample/setSample which take a channel parameter. + * Added variants of all table-with-fields-returning get* functions, the new variants take an existing table to fill in. + * Added a variant to World:update, which accepts the number of iterations to run. The defaults are now 8 and 3. + * Added Body:isTouching. + * Added RopeJoint:setMaxLength. + * Added a click count argument to love.mousepressed and love.mousereleased. + * Added variants of love.filesystem.mount which accept a Data or FileData object containing zipped data. + * Added love.filesystem.get/setCRequirePath, and use that to find c libraries for require. + * Added variants of File:read and love.filesystem.read which take an enum to determine whether they return a FileData or a string. + * Added love.data module. It includes hex/base64 encoding functions, MD5 and SHA hashing, string packing, compression APIs, and more. + * Added Channel:hasRead, which checks if a message has been read. Takes an id, which Channel:push will now return. + * Added variants of Channel:demand and Channel:supply which take a timeout argument. + * Added Transform objects to love.math. + * Added support for different ImageData formats, including RGBA8 (the default), RGBA16, RGBA16F, and RGBA32F. + * Added the ability to load Radiance HDR, OpenEXR, and 16 bit PNG images. + * Added love.graphics.getImageFormats (replaces love.graphics.getCompressedImageFormats). + * Added the ability to specify a per-object pixel density scale factor when creating Images, Canvases, Fonts, and Videos. Affects drawing. + * Added Texture:getPixelWidth/Height and love.graphics.getPixelWidth/Height. + * Added Texture:getPixelDensity, love.graphics.getPixelDensity, and Font:getPixelDensity. + * Added Texture:getMipmapCount, getFormat, getLayerCount, getDepth, and getTextureType. + * Added Array, Cubemap, and Volume texture types and corresponding Image and Canvas APIs. + * Added love.graphics.getTextureTypes, returns a table with fields indicating support for each texture type. + * Added mipmapping support to Canvases, including both auto-generated mipmaps and manually rendering to a specific mipmap level. + * Added 'stencil8', 'depth24stencil8', 'depth32fstencil8', 'depth16', 'depth24', and 'depth32f' pixel formats for Canvases. + * Added variant of love.graphics.newCanvas which accepts a table of settings. + * Added optional 'readable' boolean field to the table passed into love.graphics.newCanvas. + * Added optional 'depthstencil' field to the table passed into love.graphics.setCanvas, for using a depth/stencil Canvas. + * Added optional 'depth' and 'stencil' boolean fields to the table passed into setCanvas, for enabling depth and stencil buffers if 'depthstencil' isn't used. + * Added shadow sampler support for Canvases. + * Added love.graphics.setDepthMode for using the depth buffer for depth testing/writes. Depth values of rendered objects can only be set via shaders. + * Added love.graphics.setMeshCullMode, for culling back- or front-facing triangles when drawing a Mesh. + * Added love.graphics.setFrontFaceWinding. + * Added variant of love.graphics.getCanvasFormats which takes a 'readable' boolean. + * Added love.graphics.drawLayer and SpriteBatch:add/setLayer for easily drawing layers of Array Textures. + * Added variants of love.graphics.print and printf which take a Font argument. + * Added variants of love.graphics.clear to control how the active depth and stencil buffers are cleared. + * Added love.graphics.applyTransform and love.graphics.replaceTransform. + * Added love.graphics.transformPoint and love.graphics.inverseTransformPoint. + * Added love.graphics.getStackDepth. + * Added love.graphics.flushBatch for manually flushing automatically batched draws. + * Added SpriteBatch:setDrawRange. + * Added per-shader opt in support for the GLSL 3.30 and GLSL ES 3.00 shading languages. + * Added 'void effect()' pixel shader entry point. + * Added love.graphics.validateShader. + * Added Shader:hasUniform. + * Added support for non-square shader uniform matrices on desktop platforms and on mobile GLSL 3. + * Added Shader:send(matrixname, is_column_major, matrix, ...) which specifies how to interpret the matrix table arguments. + * Added Shader:send variants which accept a Data object. + * Added 'borderellipse' and 'borderrectangle' ParticleSystem distributions. + * Added variant of ParticleSystem:setEmissionArea which accepts an area angle and a flag for whether particle directions are relative to the center of the area. + * Added ParticleSystem:set/getAreaSpreadAngle and set/getAreaSpreadIsRelativeDirection. + * Added love.graphics.captureScreenshot (replaces love.graphics.newScreenshot). + * Added 'glsl3', 'instancing', 'fullnpot','pixelshaderhighp', and 'shaderderivatives' graphics features. + * Added 'anisotropy' graphics limit. + * Added Mesh instancing support via love.graphics.drawInstanced and Mesh:attachAttribute. + * Added a Mesh:attachAttribute variant that takes a different target attribute name. + * Added Mesh:detachAttribute. + * Added a variant of Mesh:setVertexMap which accepts a Data object. + * Added love.window.updateMode. + * Added love.window.isMinimized. + * Added love.window.restore. + * Added the ability to prevent love from creating a stencil buffer for the window. + * Added cycle detection to Variant's table serialization, cycles now cause an error, rather than a stack overflow. + * Added love.graphics.newShader File and FileData variants. + * Added a default love.threaderror callback, which raises the error in the main thread. + * Added checks for invalid constants passed to love.keyboard.isDown/isScancodeDown. + * Added deprecation warnings, on by default for non-fused games. + * Added love.filesystem.getInfo. + * Added 'drawcallsbatched' to love.graphics.getStats. + + * Deprecated love.filesystem.exists / isFile / isDirectory / isSymlink / getLastModified / getSize (use getInfo instead). + * Deprecated love.math.compress / decompress (use love.data.compress / decompress instead). + + * - All renamed APIs are formally deprecated rather than completely removed. + * Renamed love.window.getPixelScale to love.window.getDPIScale. + * Renamed love.mouse.hasCursor to love.mouse.isCursorSupported. + * Renamed ParticleSystem:setAreaSpread to ParticleSystem:setEmissionArea. + * Renamed love.errhand to love.errorhandler. + * Renamed Source/SoundData/Decoder:getChannels to getChannelCount. + * Renamed PrismaticJoint/RevoluteJoint:hasLimitsEnabled to areLimitsEnabled. + * Renamed love.audio.getSourceCount to love.audio.getActiveSourceCount. + * Renamed all get[Object]List functions to get[Object]s. + + * Removed the default source type for love.audio.newSource. + * Removed variant of love.filesystem.newFileData which takes base64 data, use love.math.decode instead. + * Removed the no-argument variant of Text:set, use Text:clear instead. + * Removed love.graphics.getCompressedImageFormats, use love.graphics.getImageFormats instead. + * Removed the 'void effects(...)' pixel shader entry point. Use the new 'void effect()' instead. + * Removed Shader:getExternVariable, use Shader:hasUniform instead. + * Removed love.graphics.newScreenshot, use love.graphics.captureScreenshot instead. + * Removed deprecated enet function host:socket_get_address. + * Removed functions deprecated in LÖVE 0.10.2: + * Removed Shader:sendInt, Shader:sendBoolean, Shader:sentFloat, Shader:sendMatrix, and Shader:sendTexture (use Shader:send instead). + * Removed love.window.isCreated (use love.window.isOpen instead). + + * Improved performance when drawing textures, shapes, lines, and points by automatically batching their draw calls together when possible. + * Improved performance of Shader:send when the Shader is not active. + * Improved performance of love.math.randomNormal when LuaJIT's JIT compiler is enabled. + * Improved performance of love.filesystem.lines and File:lines, especially when reading from a file inside a zip/.love. + + * Changed all color values to be in the range 0-1, rather than 0-255. + * Changed high-dpi functionality to require much less code (often none at all) for graphics to appear at the correct sizes and positions. + * Changed love.graphics.print and friends to ignore carriage returns. + * Changed the 'multiply' blend mode to error if not used with the 'premultiplied' blend alpha mode, since the formula only works with that anyway. + * Changed some love.graphics, love.window, and love.event APIs to cause an error if a Canvas is active. + * Changed stenciling functionality with a Canvas active to require stencil=true (or a custom stencil-formatted Canvas) to be set in setCanvas. + * Changed Mesh:setDrawRange to take 'start' and 'count' parameters instead of 'min' and 'max'. + * Changed the 'vsync' field of love.window.setMode and t.window in love.conf. It's now an integer with 0 disabling vsync. + * Changed the audio playback APIs drastically. + * Changed enet to no longer set the 'enet' global, again matching luasocket. + * Changed Source seeking behaviour, all kinds of Sources now behave similarly when seeking past the boundaries. + * Changed love.timer.step, it now returns dt. + * Changed love.run and love.errhand to return a function for their main loop, which gets called until love quits. + + * Updated and improved command line argument handling. + * Updated the boot sequence to show an error instead of the no-game screen, if a nonexistant folder is passed in as the source game directory. + * Updated 'love.exe --version' on Windows to print to the parent console. + * Updated Android print rerouting and JIT compilation disabling to apply inside threads. + * Updated invalid enum value error messages to show a list of the valid enum values. + * Updated Source:seek to work if the Source isn't playing. + * Updated love.event.poll to stop allocating memory unnecessarily. + * Updated love.math.random to have improved numeric distribution. + * Updated love.graphics to support Core Profile OpenGL 3.3+ when available. + * Updated shaders to always expose derivative functions (dFdx, dFdy, fwidth) when available in OpenGL ES. + * Updated shaders to allow using VERTEX and PIXEL in shader code. + * Updated love.graphics.circle/ellipse/arc/rectangle to take transformation scale into account when determining the number of segments to use. + * Updated Font glyph generation to improve antialiasing. + * Updated Canvas:newImageData to return an ImageData with a format that matches the Canvas' as closely as possible. + * Updated love.graphics.newImage to treat file names ending with "@2x", "@3x", etc. as a pixel density scale factor if none is explicitly supplied. + * Updated the error message when bad values are given to love.graphics.line. + * Updated the maximum love.graphics transformation/state stack depth from 64 to 128. + * Updated the default error handler to allow copying the error to the clipboard when the user decides to do so. + * Updated love.filesystem.setRequirePath to support multiple template '?' characters in each path. + * Updated luasocket to version 3.0rc1. + + * Fixed error in default error handler when the error message contains non UTF-8 bytes. + * Fixed a memory leak when sending love objects to threads which never load that object's module. + * Fixed a memory leak in enet when peer:send fails. + * Fixed os.execute always returning -1 in Linux. + * Fixed the default reference angle for WeldJoint, PrismaticJoint, and RevoluteJoint. + * Fixed Fixture:getShape to reuse the existing internal Fixture-owned shape. + * Fixed MouseJoint:setFrequency to error instead of crashing if a frequency of 0 is set. + * Fixed love.system.set/getClipboardText to error instead of crashing, when a window hasn't been created. + * Fixed Joystick:getGamepadMapping to work with xinput controllers. + * Fixed love.joystick.setGamepadMapping's replacement code. + * Fixed baseline calculation when rendering text. + * Fixed VaryingTexCoords and love_ScreenSize in shaders to be 'highp' in OpenGL ES, when supported. + * Fixed ParticleSystem:setParticleLifetime to error if a negative value is given. + * Fixed Shader:send and Shader:sendColor ignoring the last argument for an array. + * Fixed a crash when love.graphics.pop is called after a love.window.setMode while the transformation stack was not empty. + * Fixed love.window.isMaximized. + * Fixed video playback to work with a wider range of Ogg Theora files. + * Fixed video seeking to be faster. + * Fixed BezierCurves to error instead of hanging in some situations. + * Fixed compilation of luasocket with newer luajit 2.1.0 beta versions. + LOVE 0.10.2 [Super Toast] ------------------------- diff --git a/love/src/jni/love/extra/appveyor/appveyor.yml b/love/src/jni/love/extra/appveyor/appveyor.yml index e827408f..6849f338 100644 --- a/love/src/jni/love/extra/appveyor/appveyor.yml +++ b/love/src/jni/love/extra/appveyor/appveyor.yml @@ -1,12 +1,21 @@ -version: 0.10.2.{build} +version: 0.11.0.{build} image: Visual Studio 2013 shallow_clone: true +environment: + matrix: + - PLATFORM: x86 + VCVARSALL_PLATFORM: x86 + GENERATOR: "Visual Studio 12" + - PLATFORM: x64 + VCVARSALL_PLATFORM: x86_amd64 + GENERATOR: "Visual Studio 12 Win64" + init: # Make VS 2013 command line tools available -- call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" %platform% +- call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" %VCVARSALL_PLATFORM% install: # We need to install NSIS to create the packaged installer executable. @@ -26,7 +35,7 @@ install: - move love libs\love before_build: -- cmake -G "Visual Studio 12" -H. -Bbuild +- cmake -G "%GENERATOR%" -H. -Bbuild build_script: - cmake --build build --target PACKAGE --config Release diff --git a/love/src/jni/love/extra/windows/love.rc b/love/src/jni/love/extra/windows/love.rc index 72ed2661..3ab8535e 100644 Binary files a/love/src/jni/love/extra/windows/love.rc and b/love/src/jni/love/extra/windows/love.rc differ diff --git a/love/src/jni/love/license.txt b/love/src/jni/love/license.txt index 2e935e9f..b85de9cb 100644 --- a/love/src/jni/love/license.txt +++ b/love/src/jni/love/license.txt @@ -1,6 +1,6 @@ This software uses LOVE: -LOVE is Copyright (c) 2006-2016 LOVE Development Team +LOVE is Copyright (c) 2006-2018 LOVE Development Team This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,9 +23,9 @@ distribution. --------- -This software uses LuaJIT: +This software uses ENet: -LuaJIT is Copyright (c) 2005-2015 Mike Pall +Copyright (c) 2002-2016 Lee Salzman Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -47,27 +47,91 @@ THE SOFTWARE. --------- -This software uses ENet: +This software uses GLAD: -Copyright (c) 2002-2014 Lee Salzman + The MIT License (MIT) + + Copyright (c) 2013 David Herberth, modified by Alex Szpakowski + + 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. -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. +This software uses glslang: + +Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +Copyright (C) 2013-2016 LunarG, Inc. + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + Neither the name of 3Dlabs Inc. Ltd. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +--------- + +This software uses portions of Kepler Project's lua-compat-5.3: + +The MIT License (MIT) + +Copyright (c) 2015 Kepler Project. + +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. +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. --------- @@ -95,6 +159,145 @@ THE SOFTWARE. --------- +This software uses LuaJIT: + +LuaJIT is Copyright (c) 2005-2016 Mike Pall + +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. + +--------- + +This software uses Lua's UTF-8 module: + +Copyright (C) 1994-2015 Lua.org, PUC-Rio, 2015 LOVE Development Team. + +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. + +--------- + +This software uses luasocket: + +LuaSocket 3.0 license +Copyright (C) 2004-2013 Diego Nehab + +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. + +--------- + +This software uses LZ4: + +LZ4 - Fast LZ compression algorithm +Copyright (C) 2011-2015, Yann Collet. + +BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +You can contact the author at : +- LZ4 source repository : https://github.com/Cyan4973/lz4 +- LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c + +--------- + +This software uses TinyEXR: + +Copyright (c) 2014 - 2016, Syoyo Fujita +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--------- + This software uses UTF8-CPP: Copyright 2006 Nemanja Trifunovic @@ -123,12 +326,48 @@ DEALINGS IN THE SOFTWARE. --------- +This software uses xxHash: + +xxHash - Extremely Fast Hash algorithm +Copyright (C) 2012-2016, Yann Collet. + +BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +You can contact the author at : +- xxHash source repository : https://github.com/Cyan4973/xxHash + +--------- + This software uses the following LGPL libraries on Windows, Mac OS X, Linux, and Android: - libmpg123 Website: http://www.mpg123.de/ Source download: http://sourceforge.net/projects/mpg123/files/latest/download + - OpenAL Soft Website: http://kcat.strangesoft.net/openal.html Source download: http://kcat.strangesoft.net/openal.html#download diff --git a/love/src/jni/love/platform/macosx/Info-Framework.plist b/love/src/jni/love/platform/macosx/Info-Framework.plist deleted file mode 100644 index d2104642..00000000 --- a/love/src/jni/love/platform/macosx/Info-Framework.plist +++ /dev/null @@ -1,28 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIconFile - - CFBundleIdentifier - love2d.${PRODUCT_NAME:rfc1034identifier} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - LÖVE - CFBundlePackageType - FMWK - CFBundleShortVersionString - 0.9.2 - CFBundleSignature - LoVe - CFBundleVersion - 0.9.2 - NSPrincipalClass - - - diff --git a/love/src/jni/love/platform/macosx/OSX.mm b/love/src/jni/love/platform/macosx/OSX.mm deleted file mode 100644 index 418de494..00000000 --- a/love/src/jni/love/platform/macosx/OSX.mm +++ /dev/null @@ -1,75 +0,0 @@ -/** - * Copyright (c) 2006-2014 LOVE Development Team - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - **/ - -#import "OSX.h" -#import - -#include - -namespace love -{ -namespace osx -{ - -std::string getLoveInResources() -{ - std::string path; - - @autoreleasepool - { - // check to see if there are any .love files in Resources - props to stevejohnson/diordna - NSArray *lovePaths = [[NSBundle mainBundle] pathsForResourcesOfType:@"love" inDirectory:nil]; - if ([lovePaths count] > 0) - { - NSString *firstLovePath = [lovePaths objectAtIndex:0]; - path = std::string([firstLovePath UTF8String]); - } - } - - return path; -} - -std::string checkDropEvents() -{ - std::string dropstr; - SDL_Event event; - - bool initvideo = SDL_WasInit(SDL_INIT_VIDEO) != 0; - if (!initvideo) - SDL_InitSubSystem(SDL_INIT_VIDEO); - - SDL_PumpEvents(); - if (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_DROPFILE, SDL_DROPFILE) > 0) - { - if (event.type == SDL_DROPFILE) - { - dropstr = std::string(event.drop.file); - SDL_free(event.drop.file); - } - } - - if (!initvideo) - SDL_QuitSubSystem(SDL_INIT_VIDEO); - - return dropstr; -} - -} // osx -} // love diff --git a/love/src/jni/love/platform/macosx/dmg/DS_Store b/love/src/jni/love/platform/macosx/dmg/DS_Store deleted file mode 100644 index e9df1d6f..00000000 Binary files a/love/src/jni/love/platform/macosx/dmg/DS_Store and /dev/null differ diff --git a/love/src/jni/love/platform/macosx/dmg/VolumeIcon.icns b/love/src/jni/love/platform/macosx/dmg/VolumeIcon.icns deleted file mode 100644 index 7303779b..00000000 Binary files a/love/src/jni/love/platform/macosx/dmg/VolumeIcon.icns and /dev/null differ diff --git a/love/src/jni/love/platform/macosx/dmg/backgroundImage.tiff b/love/src/jni/love/platform/macosx/dmg/backgroundImage.tiff deleted file mode 100644 index 66c84377..00000000 Binary files a/love/src/jni/love/platform/macosx/dmg/backgroundImage.tiff and /dev/null differ diff --git a/love/src/jni/love/platform/macosx/icons/Love.icns b/love/src/jni/love/platform/macosx/icons/Love.icns deleted file mode 100644 index 483712ea..00000000 Binary files a/love/src/jni/love/platform/macosx/icons/Love.icns and /dev/null differ diff --git a/love/src/jni/love/platform/macosx/icons/LoveDocument.icns b/love/src/jni/love/platform/macosx/icons/LoveDocument.icns deleted file mode 100644 index 1dede26b..00000000 Binary files a/love/src/jni/love/platform/macosx/icons/LoveDocument.icns and /dev/null differ diff --git a/love/src/jni/love/platform/macosx/love-Info.plist b/love/src/jni/love/platform/macosx/love-Info.plist deleted file mode 100644 index 3dbad5b8..00000000 --- a/love/src/jni/love/platform/macosx/love-Info.plist +++ /dev/null @@ -1,87 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleDocumentTypes - - - CFBundleTypeIconFile - LoveDocument.icns - CFBundleTypeName - LÖVE Project - CFBundleTypeRole - Viewer - LSHandlerRank - Owner - LSItemContentTypes - - org.love2d.love-game - - - - CFBundleTypeName - Folder - CFBundleTypeOSTypes - - fold - - CFBundleTypeRole - Viewer - LSHandlerRank - None - - - CFBundleExecutable - love - CFBundleIconFile - Love.icns - CFBundleIdentifier - org.love2d.love - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - LÖVE - CFBundlePackageType - APPL - CFBundleShortVersionString - 0.9.2 - CFBundleSignature - LoVe - LSApplicationCategoryType - public.app-category.games - NSHumanReadableCopyright - © 2006-2014 LÖVE Development Team - NSPrincipalClass - NSApplication - UTExportedTypeDeclarations - - - UTTypeConformsTo - - com.pkware.zip-archive - - UTTypeDescription - LÖVE Project - UTTypeIconFile - LoveDocument.icns - UTTypeIdentifier - org.love2d.love-game - UTTypeReferenceURL - http://love2d.org/wiki/Game_Distribution - UTTypeTagSpecification - - com.apple.ostype - LOVE - public.filename-extension - - love - - public.mime-type - application/x-love-game - - - - - diff --git a/love/src/jni/love/platform/macosx/love-framework.xcodeproj/project.pbxproj b/love/src/jni/love/platform/macosx/love-framework.xcodeproj/project.pbxproj deleted file mode 100644 index f7ddf110..00000000 --- a/love/src/jni/love/platform/macosx/love-framework.xcodeproj/project.pbxproj +++ /dev/null @@ -1,2702 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - FA01BE1E1878E35B00640047 /* wrap_Texture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA01BE1C1878E35B00640047 /* wrap_Texture.cpp */; }; - FA01BE1F1878E35B00640047 /* wrap_Texture.h in Headers */ = {isa = PBXBuildFile; fileRef = FA01BE1D1878E35B00640047 /* wrap_Texture.h */; }; - FA03546C1731F3A700284828 /* simplexnoise1234.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA03546A1731F3A700284828 /* simplexnoise1234.cpp */; }; - FA03546D1731F3A700284828 /* simplexnoise1234.h in Headers */ = {isa = PBXBuildFile; fileRef = FA03546B1731F3A700284828 /* simplexnoise1234.h */; }; - FA08F5B016C752F900F007B5 /* Source.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2FB732687B1669402408356D /* Source.cpp */; }; - FA08F5B116C752F900F007B5 /* wrap_Audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02CA1BE908D91B104EB9590F /* wrap_Audio.cpp */; }; - FA08F5B216C752F900F007B5 /* wrap_Source.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02662CBC29B954295A634A39 /* wrap_Source.cpp */; }; - FA08F5B316C752FC00F007B5 /* Audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1839744763625B5D64EC70AC /* Audio.cpp */; }; - FA08F5B416C7530100F007B5 /* Audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CC5707C79175FA6427B3D62 /* Audio.cpp */; }; - FA08F5B516C7530100F007B5 /* Source.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A304E384AF2119905C01504 /* Source.cpp */; }; - FA08F5B616C7530A00F007B5 /* Audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6CB1193233FA78EE646A17A1 /* Audio.cpp */; }; - FA08F5B716C7530A00F007B5 /* Pool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 601E6A56345412E87E1D396B /* Pool.cpp */; }; - FA08F5B816C7530A00F007B5 /* Source.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28024635525B077E08A73D9B /* Source.cpp */; }; - FA08F5B916C7532A00F007B5 /* b64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5D383DA1468545C30E7B5805 /* b64.cpp */; }; - FA08F5BA16C7532A00F007B5 /* delay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36437CE95936736320710513 /* delay.cpp */; }; - FA08F5BB16C7532A00F007B5 /* Exception.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3746164716797CF80D6B0CEE /* Exception.cpp */; }; - FA08F5BD16C7532A00F007B5 /* Matrix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0CB6025618505B055A4E75DD /* Matrix.cpp */; }; - FA08F5BE16C7532A00F007B5 /* Memoizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 40A0593B616A223A4CEF07C9 /* Memoizer.cpp */; }; - FA08F5BF16C7532A00F007B5 /* Module.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 30E466F441EE727658716873 /* Module.cpp */; }; - FA08F5C016C7532A00F007B5 /* Object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 411B061C49172C971C622125 /* Object.cpp */; }; - FA08F5C116C7532A00F007B5 /* Reference.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35B31EBC4DDB6F994BCA46B6 /* Reference.cpp */; }; - FA08F5C216C7532A00F007B5 /* runtime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45E761A0072E0EF92BD66EA9 /* runtime.cpp */; }; - FA08F5C316C7532A00F007B5 /* utf8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7D9B03C2438B748D0DE93DD5 /* utf8.cpp */; }; - FA08F5C416C7532A00F007B5 /* Variant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C56375F752B7A9779DD37EC /* Variant.cpp */; }; - FA08F5C516C7532A00F007B5 /* Vector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2A61843B753E3F5B330703 /* Vector.cpp */; }; - FA08F5C616C7532A00F007B5 /* wrap_Data.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5ED732200E1B2E5F79831DDA /* wrap_Data.cpp */; }; - FA08F5C716C7533C00F007B5 /* b2BroadPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5F4DF8110020A96B5D3EAB /* b2BroadPhase.cpp */; }; - FA08F5C816C7533C00F007B5 /* b2CollideCircle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7E7A068041FD553876712F05 /* b2CollideCircle.cpp */; }; - FA08F5C916C7533C00F007B5 /* b2CollideEdge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1B036C7C5A8832AE53BB1C06 /* b2CollideEdge.cpp */; }; - FA08F5CA16C7533C00F007B5 /* b2CollidePolygon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 427B4B2517C0516844370E3D /* b2CollidePolygon.cpp */; }; - FA08F5CB16C7533C00F007B5 /* b2Collision.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32CC11481CD9164455455D72 /* b2Collision.cpp */; }; - FA08F5CC16C7533C00F007B5 /* b2Distance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 175A1B8D733B2D4803F64AC1 /* b2Distance.cpp */; }; - FA08F5CD16C7533C00F007B5 /* b2DynamicTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59D27EA33E8E62E15C185948 /* b2DynamicTree.cpp */; }; - FA08F5CE16C7533C00F007B5 /* b2TimeOfImpact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1F0D375C38A245E403E53DB5 /* b2TimeOfImpact.cpp */; }; - FA08F5CF16C7534400F007B5 /* b2ChainShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4E6705C154C34FBD143F465E /* b2ChainShape.cpp */; }; - FA08F5D016C7534400F007B5 /* b2CircleShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08AA5965073A1C520A7A6833 /* b2CircleShape.cpp */; }; - FA08F5D116C7534400F007B5 /* b2EdgeShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 633E37194CB535AE41A00092 /* b2EdgeShape.cpp */; }; - FA08F5D216C7534400F007B5 /* b2PolygonShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08983C025D0655270DF81A5B /* b2PolygonShape.cpp */; }; - FA08F5D316C7535000F007B5 /* b2BlockAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 55A759CE711E157339930E58 /* b2BlockAllocator.cpp */; }; - FA08F5D416C7535000F007B5 /* b2Draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12390CBC115B00D06EF951DD /* b2Draw.cpp */; }; - FA08F5D516C7535000F007B5 /* b2Math.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2C78323D7D5C628A53EC6931 /* b2Math.cpp */; }; - FA08F5D616C7535000F007B5 /* b2Settings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6FF15DF4423F6426224024C9 /* b2Settings.cpp */; }; - FA08F5D716C7535000F007B5 /* b2StackAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 780D5B6358096BEB1F1336EE /* b2StackAllocator.cpp */; }; - FA08F5D816C7535000F007B5 /* b2Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 239054AE7475433E39747DA9 /* b2Timer.cpp */; }; - FA08F5D916C7536C00F007B5 /* b2Body.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 120B391518206E964493126C /* b2Body.cpp */; }; - FA08F5DA16C7536C00F007B5 /* b2ContactManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A6150F7479D21346EC54B68 /* b2ContactManager.cpp */; }; - FA08F5DB16C7536C00F007B5 /* b2Fixture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 059C04C13F3A7C05570F2987 /* b2Fixture.cpp */; }; - FA08F5DC16C7536C00F007B5 /* b2Island.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59BE634A2ACE722F14B86F89 /* b2Island.cpp */; }; - FA08F5DD16C7536C00F007B5 /* b2World.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0D6F00D95C4407BB26E71E02 /* b2World.cpp */; }; - FA08F5DE16C7536C00F007B5 /* b2WorldCallbacks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8D03F1544476B57CA97B01 /* b2WorldCallbacks.cpp */; }; - FA08F5DF16C7537B00F007B5 /* b2ChainAndCircleContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 468F7A0A484820DE79CE76D2 /* b2ChainAndCircleContact.cpp */; }; - FA08F5E016C7537B00F007B5 /* b2ChainAndPolygonContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 60C95C7F507A381D0A483B3F /* b2ChainAndPolygonContact.cpp */; }; - FA08F5E116C7537B00F007B5 /* b2CircleContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 58792BC1126C2917432D706B /* b2CircleContact.cpp */; }; - FA08F5E216C7537B00F007B5 /* b2Contact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 71F878E2440A021B68D93ABC /* b2Contact.cpp */; }; - FA08F5E316C7537B00F007B5 /* b2ContactSolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E9E4F657DEC2772493B79CC /* b2ContactSolver.cpp */; }; - FA08F5E416C7537B00F007B5 /* b2EdgeAndCircleContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1108594E361A22D90D6022E8 /* b2EdgeAndCircleContact.cpp */; }; - FA08F5E516C7537B00F007B5 /* b2EdgeAndPolygonContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 243E18977E2A37CC6FDD55A5 /* b2EdgeAndPolygonContact.cpp */; }; - FA08F5E616C7537B00F007B5 /* b2PolygonAndCircleContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 31871B8B7E1A697A73576040 /* b2PolygonAndCircleContact.cpp */; }; - FA08F5E716C7537B00F007B5 /* b2PolygonContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1F4E747212DE41716BC245C9 /* b2PolygonContact.cpp */; }; - FA08F5E816C7538F00F007B5 /* b2DistanceJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33627AE97E66147E76804EF9 /* b2DistanceJoint.cpp */; }; - FA08F5E916C7538F00F007B5 /* b2FrictionJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 13093ADC78426C5009DF3B13 /* b2FrictionJoint.cpp */; }; - FA08F5EA16C7538F00F007B5 /* b2GearJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 69A01D71103275D451F965B2 /* b2GearJoint.cpp */; }; - FA08F5EB16C7538F00F007B5 /* b2Joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6F1B61350B6B36AF216C57D7 /* b2Joint.cpp */; }; - FA08F5EC16C7538F00F007B5 /* b2MouseJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A47384208BE218F688C4EFA /* b2MouseJoint.cpp */; }; - FA08F5ED16C7538F00F007B5 /* b2PrismaticJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E27263847302FCA1F843B47 /* b2PrismaticJoint.cpp */; }; - FA08F5EE16C7538F00F007B5 /* b2PulleyJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66EC3C0463A703A97445193B /* b2PulleyJoint.cpp */; }; - FA08F5EF16C7538F00F007B5 /* b2RevoluteJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 11D62E873092729B497B447F /* b2RevoluteJoint.cpp */; }; - FA08F5F016C7538F00F007B5 /* b2RopeJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 38AF72D4790619BB022E2AEF /* b2RopeJoint.cpp */; }; - FA08F5F116C7538F00F007B5 /* b2WeldJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BCC49F529F726385CD41FA6 /* b2WeldJoint.cpp */; }; - FA08F5F216C7538F00F007B5 /* b2WheelJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0602250B7E4664E43CA113DC /* b2WheelJoint.cpp */; }; - FA08F5F316C7539B00F007B5 /* b2Rope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4832527C02C105776536438A /* b2Rope.cpp */; }; - FA08F5F416C753A400F007B5 /* luasocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2DC90F3C6160198256795C75 /* luasocket.cpp */; }; - FA08F5F516C753B800F007B5 /* auxiliar.c in Sources */ = {isa = PBXBuildFile; fileRef = 1CD02D1975803957282F28AB /* auxiliar.c */; }; - FA08F5F616C753B800F007B5 /* buffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 21B25A7E333315172B754D4F /* buffer.c */; }; - FA08F5F716C753B800F007B5 /* except.c in Sources */ = {isa = PBXBuildFile; fileRef = 49496EAF3305281B19223C22 /* except.c */; }; - FA08F5F816C753B800F007B5 /* inet.c in Sources */ = {isa = PBXBuildFile; fileRef = 610B475400DE0F7213352BC3 /* inet.c */; }; - FA08F5F916C753B800F007B5 /* io.c in Sources */ = {isa = PBXBuildFile; fileRef = 135801A6483528800C676492 /* io.c */; }; - FA08F5FA16C753B800F007B5 /* luasocket.c in Sources */ = {isa = PBXBuildFile; fileRef = 5FAE2A9679C97F2C2792182D /* luasocket.c */; }; - FA08F5FB16C753B800F007B5 /* mime.c in Sources */ = {isa = PBXBuildFile; fileRef = 00393E4930202C2B6E381F68 /* mime.c */; }; - FA08F5FC16C753B800F007B5 /* options.c in Sources */ = {isa = PBXBuildFile; fileRef = 5F846B49240D52C10F6F76E5 /* options.c */; }; - FA08F5FD16C753B800F007B5 /* select.c in Sources */ = {isa = PBXBuildFile; fileRef = 415E1438178736BE0EA908D5 /* select.c */; }; - FA08F5FE16C753B800F007B5 /* tcp.c in Sources */ = {isa = PBXBuildFile; fileRef = 22256CC12B7C7D0D1B430D46 /* tcp.c */; }; - FA08F5FF16C753B800F007B5 /* timeout.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B41232F7AF7793540F46C58 /* timeout.c */; }; - FA08F60016C753B800F007B5 /* udp.c in Sources */ = {isa = PBXBuildFile; fileRef = 2E2675AF3DAA24CE0728042C /* udp.c */; }; - FA08F60116C753B800F007B5 /* unix.c in Sources */ = {isa = PBXBuildFile; fileRef = 734947AA28AF36E436D242FD /* unix.c */; }; - FA08F60216C753B800F007B5 /* usocket.c in Sources */ = {isa = PBXBuildFile; fileRef = 041672ED2CF51FC62F532FDB /* usocket.c */; }; - FA08F60316C753CE00F007B5 /* Event.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 24265680279E30A40DF81946 /* Event.cpp */; }; - FA08F60416C753CE00F007B5 /* Event.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3BA712260D725FEB72EB3CDE /* Event.cpp */; }; - FA08F60516C753CE00F007B5 /* wrap_Event.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 691C5C5828550E2F60754EF2 /* wrap_Event.cpp */; }; - FA08F60616C753DB00F007B5 /* File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 11D141087979064B441B787D /* File.cpp */; }; - FA08F60716C753DB00F007B5 /* FileData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 62370A494F9D6E2D570065EB /* FileData.cpp */; }; - FA08F60816C753DB00F007B5 /* File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4E0F565B03D05C3722496F27 /* File.cpp */; }; - FA08F60916C753DB00F007B5 /* Filesystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6DE3129F3A0B2D9C178118F3 /* Filesystem.cpp */; }; - FA08F60A16C753DB00F007B5 /* wrap_File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6C367AE309C453C412D91363 /* wrap_File.cpp */; }; - FA08F60B16C753DB00F007B5 /* wrap_FileData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 597478A255B82B56488B4717 /* wrap_FileData.cpp */; }; - FA08F60C16C753DB00F007B5 /* wrap_Filesystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E827AE8548C52493ED95629 /* wrap_Filesystem.cpp */; }; - FA08F60D16C753E700F007B5 /* Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 714251EE742346DC17103357 /* Font.cpp */; }; - FA08F60E16C753E700F007B5 /* TrueTypeRasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0C30420F7FD3038C721223A5 /* TrueTypeRasterizer.cpp */; }; - FA08F60F16C753E700F007B5 /* wrap_Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 232D67C67BEE54B776420682 /* wrap_Font.cpp */; }; - FA08F61016C753E700F007B5 /* GlyphData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 74003CB27FA762A021183AD5 /* GlyphData.cpp */; }; - FA08F61116C753E700F007B5 /* ImageRasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5D016F4C27EF506C13FE3058 /* ImageRasterizer.cpp */; }; - FA08F61216C753E700F007B5 /* Rasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1B1C4E4D288A1D2F29E57B1B /* Rasterizer.cpp */; }; - FA08F61316C753E700F007B5 /* wrap_GlyphData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1B4E22F1388E2B2E76E3377B /* wrap_GlyphData.cpp */; }; - FA08F61416C753E700F007B5 /* wrap_Rasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 11745DE315E859F71E881D76 /* wrap_Rasterizer.cpp */; }; - FA08F61716C753F600F007B5 /* Graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 03F17FF546D637744E263961 /* Graphics.cpp */; }; - FA08F61816C753F600F007B5 /* Texture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 58CC50E70A375FDF53EF01B6 /* Texture.cpp */; }; - FA08F61A16C753F600F007B5 /* Volatile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B731754147B27AF73AC5358 /* Volatile.cpp */; }; - FA08F61B16C7541400F007B5 /* Canvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4AD52074367950B735707CE1 /* Canvas.cpp */; }; - FA08F61C16C7541400F007B5 /* Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 583037E9238A6EF00DD20B1A /* Font.cpp */; }; - FA08F61E16C7541400F007B5 /* Graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 11773415762F3A38421C6DB3 /* Graphics.cpp */; }; - FA08F61F16C7541400F007B5 /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 56D6030A0B8F7397715062B9 /* Image.cpp */; }; - FA08F62016C7541400F007B5 /* OpenGL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2E406F8328543EC63EB922C6 /* OpenGL.cpp */; }; - FA08F62116C7541400F007B5 /* ParticleSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 48A206C9004150640C432100 /* ParticleSystem.cpp */; }; - FA08F62316C7541400F007B5 /* Shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA577A8516C71CF000860150 /* Shader.cpp */; }; - FA08F62416C7541400F007B5 /* SpriteBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D700D182EAA46273D1E2CC4 /* SpriteBatch.cpp */; }; - FA08F62516C7541400F007B5 /* VertexBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 426B1C4475DC54505B824B7F /* VertexBuffer.cpp */; }; - FA08F62616C7541400F007B5 /* wrap_Canvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4E3251027026699A1D4D310D /* wrap_Canvas.cpp */; }; - FA08F62716C7541400F007B5 /* wrap_Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A3B52AF1FBE73FC36AD50C8 /* wrap_Font.cpp */; }; - FA08F62816C7541400F007B5 /* wrap_Graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A9810F758AC1D1E4B6431FD /* wrap_Graphics.cpp */; }; - FA08F62916C7541400F007B5 /* wrap_Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14AE68E14C2C74526A612FA0 /* wrap_Image.cpp */; }; - FA08F62A16C7541400F007B5 /* wrap_ParticleSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5F42052D7C8271A1105541DE /* wrap_ParticleSystem.cpp */; }; - FA08F62C16C7541400F007B5 /* wrap_Shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA577A8716C71CF000860150 /* wrap_Shader.cpp */; }; - FA08F62D16C7541400F007B5 /* wrap_SpriteBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02C16FDB537A702F4D42534E /* wrap_SpriteBatch.cpp */; }; - FA08F62E16C7542600F007B5 /* ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 78115E763B723C0C40AD47CF /* ImageData.cpp */; }; - FA08F62F16C7542600F007B5 /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 505F23A73BFE250833D650E4 /* Image.cpp */; }; - FA08F63016C7542600F007B5 /* DevilHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AA7781A230065F346E2313A /* DevilHandler.cpp */; }; - FA08F63116C7542600F007B5 /* wrap_Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0B0728FA73B107B37A956A09 /* wrap_Image.cpp */; }; - FA08F63216C7542600F007B5 /* wrap_ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 076840774B0B6E721D0C18D0 /* wrap_ImageData.cpp */; }; - FA08F63416C7542D00F007B5 /* JoystickModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 55B425307C0C1C4B3EFC3A5F /* JoystickModule.cpp */; }; - FA08F63516C7542D00F007B5 /* wrap_JoystickModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 139411436818381E493F00F5 /* wrap_JoystickModule.cpp */; }; - FA08F63616C7543400F007B5 /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 524741891BB93848039F4174 /* Keyboard.cpp */; }; - FA08F63716C7543400F007B5 /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43BC2B1C505E5EFF650C31E3 /* Keyboard.cpp */; }; - FA08F63816C7543400F007B5 /* wrap_Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 19F40DF6507028212FEB1D77 /* wrap_Keyboard.cpp */; }; - FA08F63916C7543A00F007B5 /* love.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 19ED419874B46EC16F927524 /* love.cpp */; }; - FA08F63A16C7544300F007B5 /* Mouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 31E0110E5797041465FF5F95 /* Mouse.cpp */; }; - FA08F63B16C7544300F007B5 /* Mouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 584E16AE09E12536206C46FE /* Mouse.cpp */; }; - FA08F63C16C7544300F007B5 /* wrap_Mouse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 22EF17981EBD442773FE41B6 /* wrap_Mouse.cpp */; }; - FA08F63D16C7544B00F007B5 /* Body.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2DCE45C868A0091B762C7377 /* Body.cpp */; }; - FA08F63E16C7544B00F007B5 /* Joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 69DB4423147C7E3362941E75 /* Joint.cpp */; }; - FA08F63F16C7544B00F007B5 /* Shape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 70F425B5336E1CD652827FD0 /* Shape.cpp */; }; - FA08F64016C7546400F007B5 /* Body.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 089B1AC1248B21D336594457 /* Body.cpp */; }; - FA08F64116C7546400F007B5 /* ChainShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0959542C4B54320B1DDD5911 /* ChainShape.cpp */; }; - FA08F64216C7546400F007B5 /* CircleShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DAB28A9235E2CBE75F56848 /* CircleShape.cpp */; }; - FA08F64316C7546400F007B5 /* Contact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02CD63315FF902E336AB4657 /* Contact.cpp */; }; - FA08F64416C7546400F007B5 /* DistanceJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 34A36BB617BC5CCA5B870EA6 /* DistanceJoint.cpp */; }; - FA08F64516C7546400F007B5 /* EdgeShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 755C2B980C106EA7423E7E5E /* EdgeShape.cpp */; }; - FA08F64616C7546400F007B5 /* Fixture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 47C77F6032FA77E046AA6810 /* Fixture.cpp */; }; - FA08F64716C7546400F007B5 /* FrictionJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E22646A710E5EFC27FE3932 /* FrictionJoint.cpp */; }; - FA08F64816C7546400F007B5 /* GearJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6F4D478A52A0408765095920 /* GearJoint.cpp */; }; - FA08F64916C7546400F007B5 /* Joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3EA80A4E0CE0014052076037 /* Joint.cpp */; }; - FA08F64A16C7546400F007B5 /* MouseJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C0B06AF6B5326C840477B18 /* MouseJoint.cpp */; }; - FA08F64B16C7546400F007B5 /* Physics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 370D76DC224F2EB300CB4E2F /* Physics.cpp */; }; - FA08F64C16C7546400F007B5 /* PolygonShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 54E85987318206E93DC8189F /* PolygonShape.cpp */; }; - FA08F64D16C7546400F007B5 /* PrismaticJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0AE5755936E84C247FB56C65 /* PrismaticJoint.cpp */; }; - FA08F64E16C7546400F007B5 /* PulleyJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5CB720BA493D7D995E0E20DD /* PulleyJoint.cpp */; }; - FA08F64F16C7546400F007B5 /* RevoluteJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36DD053F754B2D29719B1F80 /* RevoluteJoint.cpp */; }; - FA08F65016C7546400F007B5 /* RopeJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53C4064801456193163E4631 /* RopeJoint.cpp */; }; - FA08F65116C7546400F007B5 /* Shape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61E64F07028039774F502D69 /* Shape.cpp */; }; - FA08F65216C7547300F007B5 /* WeldJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 78E50525407567F863476E27 /* WeldJoint.cpp */; }; - FA08F65316C7547300F007B5 /* WheelJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 44DE79C879CC0074510A2403 /* WheelJoint.cpp */; }; - FA08F65416C7547300F007B5 /* World.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 644D0C953C3439FC57C03FC6 /* World.cpp */; }; - FA08F65516C7547300F007B5 /* wrap_Body.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 64694F91593478085859666F /* wrap_Body.cpp */; }; - FA08F65616C7547300F007B5 /* wrap_ChainShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1CAA69E00D0808BA2108238B /* wrap_ChainShape.cpp */; }; - FA08F65716C7547300F007B5 /* wrap_CircleShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6EF321185C2B1F1E1AF54F64 /* wrap_CircleShape.cpp */; }; - FA08F65816C7547300F007B5 /* wrap_Contact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3BB22A142670197B0DBD0BED /* wrap_Contact.cpp */; }; - FA08F65916C7547300F007B5 /* wrap_DistanceJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 69967D2323404E1F0ED21F11 /* wrap_DistanceJoint.cpp */; }; - FA08F65A16C7547300F007B5 /* wrap_EdgeShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 40F412FF29F65F5A3D511B98 /* wrap_EdgeShape.cpp */; }; - FA08F65B16C7547300F007B5 /* wrap_Fixture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7F796B7A3362196075C62E61 /* wrap_Fixture.cpp */; }; - FA08F65C16C7547300F007B5 /* wrap_FrictionJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 340345481F165F8945C716AE /* wrap_FrictionJoint.cpp */; }; - FA08F65D16C7548200F007B5 /* wrap_GearJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50B67F2D0CC511706810302E /* wrap_GearJoint.cpp */; }; - FA08F65E16C7548200F007B5 /* wrap_Joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 71810207414B52F8340D7797 /* wrap_Joint.cpp */; }; - FA08F65F16C7548200F007B5 /* wrap_MouseJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D81102E7ABD1C282BE42CE3 /* wrap_MouseJoint.cpp */; }; - FA08F66016C7548200F007B5 /* wrap_Physics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6CEB48E969FC42C53F9432B1 /* wrap_Physics.cpp */; }; - FA08F66116C7548200F007B5 /* wrap_PolygonShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3AD03C7A77C546ED07BE4C06 /* wrap_PolygonShape.cpp */; }; - FA08F66216C7548200F007B5 /* wrap_PrismaticJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0B4020CD058D70F569DF6129 /* wrap_PrismaticJoint.cpp */; }; - FA08F66316C7548200F007B5 /* wrap_PulleyJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E840AF84AB61C6410E26634 /* wrap_PulleyJoint.cpp */; }; - FA08F66416C7548200F007B5 /* wrap_RevoluteJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1F3A277A44141DBF7BCF146A /* wrap_RevoluteJoint.cpp */; }; - FA08F66516C7548200F007B5 /* wrap_RopeJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E3E13BC3E3A7C0C7DBE7DF8 /* wrap_RopeJoint.cpp */; }; - FA08F66616C7548200F007B5 /* wrap_Shape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 124E716E0BCA055534A60AD2 /* wrap_Shape.cpp */; }; - FA08F66716C7548200F007B5 /* wrap_WeldJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3DFF31EE26405E554C610C8F /* wrap_WeldJoint.cpp */; }; - FA08F66816C7548200F007B5 /* wrap_WheelJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 73473B3C698B538002540A5D /* wrap_WheelJoint.cpp */; }; - FA08F66916C7548200F007B5 /* wrap_World.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36324E12371E518E6E9C61B5 /* wrap_World.cpp */; }; - FA08F66A16C7549200F007B5 /* Sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 30ED4BB03C5F11254AF12E98 /* Sound.cpp */; }; - FA08F66B16C7549200F007B5 /* SoundData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0C5C6C6E47851D1308411DE6 /* SoundData.cpp */; }; - FA08F66C16C7549200F007B5 /* wrap_Decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5CF629B94C7802D446D61C45 /* wrap_Decoder.cpp */; }; - FA08F66D16C7549200F007B5 /* wrap_Sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 385902BD584E7D73154E4EBB /* wrap_Sound.cpp */; }; - FA08F66E16C7549200F007B5 /* wrap_SoundData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DC3617831763D2760335D87 /* wrap_SoundData.cpp */; }; - FA08F66F16C754A100F007B5 /* Decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4E15567759041CC379292BE6 /* Decoder.cpp */; }; - FA08F67016C754A100F007B5 /* FLACDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A774BC26B7235E410D40C8E /* FLACDecoder.cpp */; }; - FA08F67116C754A100F007B5 /* GmeDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02F0197227150E1B28D9425B /* GmeDecoder.cpp */; }; - FA08F67216C754A100F007B5 /* ModPlugDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 407422E8589417B6683D1042 /* ModPlugDecoder.cpp */; }; - FA08F67316C754A100F007B5 /* Mpg123Decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1F875B224C4E1B9E35854766 /* Mpg123Decoder.cpp */; }; - FA08F67416C754A100F007B5 /* Sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A5F7DCB40652F9B7D61073A /* Sound.cpp */; }; - FA08F67516C754A100F007B5 /* VorbisDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 727648E06CD863A2582F798F /* VorbisDecoder.cpp */; }; - FA08F67716C754A900F007B5 /* threads.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6B3565203A1778431F8A5409 /* threads.cpp */; }; - FA08F67916C754B100F007B5 /* Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 113269E55FCF208D2D6754BC /* Timer.cpp */; }; - FA08F67A16C754B100F007B5 /* wrap_Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 695E4ED13AA0689E64280573 /* wrap_Timer.cpp */; }; - FA08F67B16C754BA00F007B5 /* Window.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 351B09E51FDC338622F44624 /* Window.cpp */; }; - FA08F67C16C754BA00F007B5 /* Window.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6CDD4F3320303D222C180CD0 /* Window.cpp */; }; - FA0A4BF0182E0C2800E1E4D2 /* b2MotorJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0A4BEE182E0C2800E1E4D2 /* b2MotorJoint.cpp */; }; - FA0A4BF1182E0C2800E1E4D2 /* b2MotorJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0A4BEF182E0C2800E1E4D2 /* b2MotorJoint.h */; }; - FA0A4BF4182E1AD600E1E4D2 /* MotorJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0A4BF2182E1AD600E1E4D2 /* MotorJoint.cpp */; }; - FA0A4BF5182E1AD600E1E4D2 /* MotorJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0A4BF3182E1AD600E1E4D2 /* MotorJoint.h */; }; - FA0A4BF9182E260200E1E4D2 /* wrap_MotorJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0A4BF7182E260200E1E4D2 /* wrap_MotorJoint.h */; }; - FA0A4BFA182E26F500E1E4D2 /* wrap_MotorJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0A4BF6182E260200E1E4D2 /* wrap_MotorJoint.cpp */; }; - FA0CDE3D1710F9A50056E8D7 /* FormatHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0CDE3B1710F9A50056E8D7 /* FormatHandler.h */; }; - FA1EF7C41799FEAC00FF380C /* wrap_System.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA34E7D4174B55AF00E04D3F /* wrap_System.cpp */; }; - FA1EF7C51799FEB200FF380C /* wrap_System.h in Headers */ = {isa = PBXBuildFile; fileRef = FA34E7D5174B55AF00E04D3F /* wrap_System.h */; }; - FA34E7CD174B513F00E04D3F /* System.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA34E7CB174B513F00E04D3F /* System.cpp */; }; - FA34E7CE174B513F00E04D3F /* System.h in Headers */ = {isa = PBXBuildFile; fileRef = FA34E7CC174B513F00E04D3F /* System.h */; }; - FA34E7D2174B515D00E04D3F /* System.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA34E7D0174B515D00E04D3F /* System.cpp */; }; - FA34E7D3174B515D00E04D3F /* System.h in Headers */ = {isa = PBXBuildFile; fileRef = FA34E7D1174B515D00E04D3F /* System.h */; }; - FA3D9E0D16E68DE600CA6630 /* Cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA3D9E0B16E68DE600CA6630 /* Cursor.cpp */; }; - FA3D9E0E16E68DE600CA6630 /* Cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = FA3D9E0C16E68DE600CA6630 /* Cursor.h */; }; - FA3D9E1116E68EAE00CA6630 /* Cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA3D9E0F16E68EAE00CA6630 /* Cursor.cpp */; }; - FA3D9E1216E68EAE00CA6630 /* Cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = FA3D9E1016E68EAE00CA6630 /* Cursor.h */; }; - FA3D9E1516E6D41100CA6630 /* wrap_Cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA3D9E1316E6D41000CA6630 /* wrap_Cursor.cpp */; }; - FA3D9E1616E6D41100CA6630 /* wrap_Cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = FA3D9E1416E6D41000CA6630 /* wrap_Cursor.h */; }; - FA435EA317B36E9C004C3F22 /* Polyline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA435EA117B36E9C004C3F22 /* Polyline.cpp */; }; - FA435EA417B36E9C004C3F22 /* Polyline.h in Headers */ = {isa = PBXBuildFile; fileRef = FA435EA217B36E9C004C3F22 /* Polyline.h */; }; - FA45F775187A0F3600D99ED8 /* Touch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA45F770187A0F3600D99ED8 /* Touch.cpp */; }; - FA45F776187A0F3600D99ED8 /* Touch.h in Headers */ = {isa = PBXBuildFile; fileRef = FA45F771187A0F3600D99ED8 /* Touch.h */; }; - FA45F777187A0F3600D99ED8 /* Touch.h in Headers */ = {isa = PBXBuildFile; fileRef = FA45F772187A0F3600D99ED8 /* Touch.h */; }; - FA45F778187A0F3600D99ED8 /* wrap_Touch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA45F773187A0F3600D99ED8 /* wrap_Touch.cpp */; }; - FA45F779187A0F3600D99ED8 /* wrap_Touch.h in Headers */ = {isa = PBXBuildFile; fileRef = FA45F774187A0F3600D99ED8 /* wrap_Touch.h */; }; - FA4DAE691941410D009F0A3E /* PNGHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA4DAE651941410D009F0A3E /* PNGHandler.cpp */; }; - FA4DAE6A1941410D009F0A3E /* PNGHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4DAE661941410D009F0A3E /* PNGHandler.h */; }; - FA4DAE6B1941410D009F0A3E /* STBHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA4DAE671941410D009F0A3E /* STBHandler.cpp */; }; - FA4DAE6C1941410D009F0A3E /* STBHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4DAE681941410D009F0A3E /* STBHandler.h */; }; - FA4DAE731941411D009F0A3E /* lodepng.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA4DAE6E1941411D009F0A3E /* lodepng.cpp */; }; - FA4DAE741941411D009F0A3E /* lodepng.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4DAE6F1941411D009F0A3E /* lodepng.h */; }; - FA4DAE761941411D009F0A3E /* stb_image.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4DAE721941411D009F0A3E /* stb_image.h */; }; - FA4DAE791941419A009F0A3E /* JPEGHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA4DAE771941419A009F0A3E /* JPEGHandler.cpp */; }; - FA4DAE7A1941419A009F0A3E /* JPEGHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4DAE781941419A009F0A3E /* JPEGHandler.h */; }; - FA4DAE7C19414281009F0A3E /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA4DAE7B19414281009F0A3E /* libz.dylib */; }; - FA52E446192AAADE0064D2FF /* PKMHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA52E444192AAADE0064D2FF /* PKMHandler.cpp */; }; - FA52E447192AAADE0064D2FF /* PKMHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA52E445192AAADE0064D2FF /* PKMHandler.h */; }; - FA5454C216F1310000D30303 /* MathModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA5454C016F1310000D30303 /* MathModule.cpp */; }; - FA5454C316F1310000D30303 /* MathModule.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5454C116F1310000D30303 /* MathModule.h */; }; - FA577AB016C7507900860150 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7916C71A1700860150 /* Cocoa.framework */; }; - FA577AC216C7512D00860150 /* FreeType.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A6716C719D900860150 /* FreeType.framework */; }; - FA577AC416C7513200860150 /* IL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A6916C719DE00860150 /* IL.framework */; }; - FA577AC516C7513400860150 /* libmodplug.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A8216C71A5300860150 /* libmodplug.framework */; }; - FA577AC716C7513A00860150 /* mpg123.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A6F16C719F000860150 /* mpg123.framework */; }; - FA577AC816C7513C00860150 /* Ogg.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7116C719F400860150 /* Ogg.framework */; }; - FA577ACA16C7514100860150 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7C16C71A2600860150 /* OpenGL.framework */; }; - FA577ACB16C7514400860150 /* physfs.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7316C719F900860150 /* physfs.framework */; }; - FA577ACD16C7514C00860150 /* Vorbis.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7716C71A0800860150 /* Vorbis.framework */; }; - FA5FDC791788D548002F0ED2 /* enet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC5F1788D548002F0ED2 /* enet.cpp */; }; - FA5FDC7A1788D548002F0ED2 /* callbacks.c in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC611788D548002F0ED2 /* callbacks.c */; }; - FA5FDC7C1788D548002F0ED2 /* compress.c in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC631788D548002F0ED2 /* compress.c */; }; - FA5FDC7D1788D548002F0ED2 /* host.c in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC641788D548002F0ED2 /* host.c */; }; - FA5FDC7E1788D548002F0ED2 /* callbacks.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5FDC671788D548002F0ED2 /* callbacks.h */; }; - FA5FDC7F1788D548002F0ED2 /* enet.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5FDC681788D548002F0ED2 /* enet.h */; }; - FA5FDC801788D548002F0ED2 /* list.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5FDC691788D548002F0ED2 /* list.h */; }; - FA5FDC811788D548002F0ED2 /* protocol.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5FDC6A1788D548002F0ED2 /* protocol.h */; }; - FA5FDC821788D548002F0ED2 /* time.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5FDC6B1788D548002F0ED2 /* time.h */; }; - FA5FDC831788D548002F0ED2 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5FDC6C1788D548002F0ED2 /* types.h */; }; - FA5FDC841788D548002F0ED2 /* unix.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5FDC6D1788D548002F0ED2 /* unix.h */; }; - FA5FDC851788D548002F0ED2 /* utility.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5FDC6E1788D548002F0ED2 /* utility.h */; }; - FA5FDC861788D548002F0ED2 /* win32.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5FDC6F1788D548002F0ED2 /* win32.h */; }; - FA5FDC881788D548002F0ED2 /* list.c in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC711788D548002F0ED2 /* list.c */; }; - FA5FDC891788D548002F0ED2 /* packet.c in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC721788D548002F0ED2 /* packet.c */; }; - FA5FDC8A1788D548002F0ED2 /* peer.c in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC731788D548002F0ED2 /* peer.c */; }; - FA5FDC8B1788D548002F0ED2 /* protocol.c in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC741788D548002F0ED2 /* protocol.c */; }; - FA5FDC8D1788D548002F0ED2 /* unix.c in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC761788D548002F0ED2 /* unix.c */; }; - FA5FDC8E1788D548002F0ED2 /* win32.c in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC771788D548002F0ED2 /* win32.c */; }; - FA5FDC8F1788D548002F0ED2 /* lua-enet.h in Headers */ = {isa = PBXBuildFile; fileRef = FA5FDC781788D548002F0ED2 /* lua-enet.h */; }; - FA61FD5E1926CFCE003AE9FB /* CompressedFormatHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA61FD5B1926CFCE003AE9FB /* CompressedFormatHandler.h */; }; - FA61FD5F1926CFCE003AE9FB /* PVRHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA61FD5C1926CFCE003AE9FB /* PVRHandler.cpp */; }; - FA61FD601926CFCE003AE9FB /* PVRHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA61FD5D1926CFCE003AE9FB /* PVRHandler.h */; }; - FA636D8A171B70920065623F /* RandomGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA636D88171B70920065623F /* RandomGenerator.cpp */; }; - FA636D8B171B70920065623F /* RandomGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FA636D89171B70920065623F /* RandomGenerator.h */; }; - FA636D8E171B72A70065623F /* wrap_RandomGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA636D8C171B72A70065623F /* wrap_RandomGenerator.cpp */; }; - FA636D8F171B72A70065623F /* wrap_RandomGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FA636D8D171B72A70065623F /* wrap_RandomGenerator.h */; }; - FA7175AA178E8418001FE7FE /* lua.h in Headers */ = {isa = PBXBuildFile; fileRef = FA7175A9178E8418001FE7FE /* lua.h */; }; - FA7AA59217F6AC1F00704BE2 /* wrap_Mesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA7AA59017F6AC1F00704BE2 /* wrap_Mesh.cpp */; }; - FA7AA59317F6AC1F00704BE2 /* wrap_Mesh.h in Headers */ = {isa = PBXBuildFile; fileRef = FA7AA59117F6AC1F00704BE2 /* wrap_Mesh.h */; }; - FA7C937A16DCC6C2006F2BEE /* wrap_Math.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA7C937516DCC6C2006F2BEE /* wrap_Math.cpp */; }; - FA7C937B16DCC6C2006F2BEE /* wrap_Math.h in Headers */ = {isa = PBXBuildFile; fileRef = FA7C937616DCC6C2006F2BEE /* wrap_Math.h */; }; - FA9A100C182A0D5200106F9F /* glad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA9A1009182A0D5200106F9F /* glad.cpp */; }; - FA9A100D182A0D5200106F9F /* glad.hpp in Headers */ = {isa = PBXBuildFile; fileRef = FA9A100A182A0D5200106F9F /* glad.hpp */; }; - FA9A100E182A0D5200106F9F /* gladfuncs.hpp in Headers */ = {isa = PBXBuildFile; fileRef = FA9A100B182A0D5200106F9F /* gladfuncs.hpp */; }; - FA9B492A1875EFB900201DA9 /* Texture.h in Headers */ = {isa = PBXBuildFile; fileRef = FA9B49281875EFB900201DA9 /* Texture.h */; }; - FA9B4A0816E1578300074F42 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA9B4A0716E1578300074F42 /* SDL2.framework */; }; - FA9FC0B0173D6E3E005027FF /* wrap_Window.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA9FC0AE173D6E3E005027FF /* wrap_Window.cpp */; }; - FA9FC0B1173D6E3E005027FF /* wrap_Window.h in Headers */ = {isa = PBXBuildFile; fileRef = FA9FC0AF173D6E3E005027FF /* wrap_Window.h */; }; - FAA627CE18E7E1560080752D /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAA627CD18E7E1560080752D /* CoreServices.framework */; }; - FAAC6B02170A373B008A61C5 /* CompressedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAAC6B00170A373A008A61C5 /* CompressedData.cpp */; }; - FAAC6B03170A373B008A61C5 /* CompressedData.h in Headers */ = {isa = PBXBuildFile; fileRef = FAAC6B01170A373A008A61C5 /* CompressedData.h */; }; - FAAFF04416CB11C700CCDE45 /* OpenAL-Soft.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAAFF04316CB11C700CCDE45 /* OpenAL-Soft.framework */; }; - FAB0078F1740C12D00A9664D /* Joystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB0078D1740C12D00A9664D /* Joystick.cpp */; }; - FAB007901740C12D00A9664D /* Joystick.h in Headers */ = {isa = PBXBuildFile; fileRef = FAB0078E1740C12D00A9664D /* Joystick.h */; }; - FAB007931740C28900A9664D /* Joystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB007911740C28900A9664D /* Joystick.cpp */; }; - FAB007941740C28900A9664D /* Joystick.h in Headers */ = {isa = PBXBuildFile; fileRef = FAB007921740C28900A9664D /* Joystick.h */; }; - FAB007971740C87D00A9664D /* wrap_Joystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB007951740C87D00A9664D /* wrap_Joystick.cpp */; }; - FAB007981740C87D00A9664D /* wrap_Joystick.h in Headers */ = {isa = PBXBuildFile; fileRef = FAB007961740C87D00A9664D /* wrap_Joystick.h */; }; - FAC5710017402D1100D147E4 /* BezierCurve.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC570FC17402D1100D147E4 /* BezierCurve.cpp */; }; - FAC5710117402D1100D147E4 /* BezierCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC570FD17402D1100D147E4 /* BezierCurve.h */; }; - FAC5710217402D1100D147E4 /* wrap_BezierCurve.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC570FE17402D1100D147E4 /* wrap_BezierCurve.cpp */; }; - FAC5710317402D1100D147E4 /* wrap_BezierCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC570FF17402D1100D147E4 /* wrap_BezierCurve.h */; }; - FAC86E631724552C00EED715 /* wrap_Quad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC86E611724552C00EED715 /* wrap_Quad.cpp */; }; - FAC86E641724552C00EED715 /* wrap_Quad.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC86E621724552C00EED715 /* wrap_Quad.h */; }; - FAC86E6B1724555D00EED715 /* Quad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC86E671724555D00EED715 /* Quad.cpp */; }; - FAC86E6C1724555D00EED715 /* Quad.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC86E681724555D00EED715 /* Quad.h */; }; - FADD58DD18C30367005FC3BF /* FormatHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADD58DC18C30367005FC3BF /* FormatHandler.cpp */; }; - FAE010DB170DDE99006F29D0 /* ddsinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE010D8170DDE99006F29D0 /* ddsinfo.h */; }; - FAE010DC170DDE99006F29D0 /* ddsparse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAE010D9170DDE99006F29D0 /* ddsparse.cpp */; }; - FAE010DD170DDE99006F29D0 /* ddsparse.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE010DA170DDE99006F29D0 /* ddsparse.h */; }; - FAE010E0170DE25E006F29D0 /* ddsHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAE010DE170DE25E006F29D0 /* ddsHandler.cpp */; }; - FAE010E1170DE25E006F29D0 /* ddsHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE010DF170DE25E006F29D0 /* ddsHandler.h */; }; - FAE010E4170DF75C006F29D0 /* wrap_CompressedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAE010E2170DF75B006F29D0 /* wrap_CompressedData.cpp */; }; - FAE010E5170DF75C006F29D0 /* wrap_CompressedData.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE010E3170DF75C006F29D0 /* wrap_CompressedData.h */; }; - FAE404401927F22C00814481 /* KTXHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAE4043E1927F22C00814481 /* KTXHandler.cpp */; }; - FAE404411927F22C00814481 /* KTXHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE4043F1927F22C00814481 /* KTXHandler.h */; }; - FAEC808A1710FEA60057279A /* ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAEC80881710FEA60057279A /* ImageData.cpp */; }; - FAEC808B1710FEA60057279A /* ImageData.h in Headers */ = {isa = PBXBuildFile; fileRef = FAEC80891710FEA60057279A /* ImageData.h */; }; - FAEC808E1711E76C0057279A /* CompressedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAEC808C1711E76C0057279A /* CompressedData.cpp */; }; - FAEC808F1711E76C0057279A /* CompressedData.h in Headers */ = {isa = PBXBuildFile; fileRef = FAEC808D1711E76C0057279A /* CompressedData.h */; }; - FAF272A416E3D44400CC193A /* Channel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF2729816E3D44400CC193A /* Channel.cpp */; }; - FAF272A516E3D44400CC193A /* Channel.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF2729916E3D44400CC193A /* Channel.h */; }; - FAF272A616E3D44400CC193A /* LuaThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF2729A16E3D44400CC193A /* LuaThread.cpp */; }; - FAF272A716E3D44400CC193A /* LuaThread.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF2729B16E3D44400CC193A /* LuaThread.h */; }; - FAF272A816E3D44400CC193A /* ThreadModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF2729C16E3D44400CC193A /* ThreadModule.cpp */; }; - FAF272A916E3D44400CC193A /* ThreadModule.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF2729D16E3D44400CC193A /* ThreadModule.h */; }; - FAF272AA16E3D44400CC193A /* wrap_Channel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF2729E16E3D44400CC193A /* wrap_Channel.cpp */; }; - FAF272AB16E3D44400CC193A /* wrap_Channel.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF2729F16E3D44400CC193A /* wrap_Channel.h */; }; - FAF272AC16E3D44400CC193A /* wrap_LuaThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF272A016E3D44400CC193A /* wrap_LuaThread.cpp */; }; - FAF272AD16E3D44400CC193A /* wrap_LuaThread.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF272A116E3D44400CC193A /* wrap_LuaThread.h */; }; - FAF272AE16E3D44400CC193A /* wrap_ThreadModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF272A216E3D44400CC193A /* wrap_ThreadModule.cpp */; }; - FAF272AF16E3D44400CC193A /* wrap_ThreadModule.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF272A316E3D44400CC193A /* wrap_ThreadModule.h */; }; - FAF272B516E3D46400CC193A /* Thread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF272B116E3D46400CC193A /* Thread.cpp */; }; - FAF272B616E3D46400CC193A /* Thread.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF272B216E3D46400CC193A /* Thread.h */; }; - FAF272B716E3D46400CC193A /* threads.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF272B316E3D46400CC193A /* threads.cpp */; }; - FAF272B816E3D46400CC193A /* threads.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF272B416E3D46400CC193A /* threads.h */; }; - FAF4376F17F4AC530074F9E2 /* Mesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF4376D17F4AC530074F9E2 /* Mesh.cpp */; }; - FAF4377017F4AC530074F9E2 /* Mesh.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF4376E17F4AC530074F9E2 /* Mesh.h */; }; - FAF6704C18184FF800DBDEEA /* wuff.c in Sources */ = {isa = PBXBuildFile; fileRef = FAF6704418184FF800DBDEEA /* wuff.c */; }; - FAF6704D18184FF800DBDEEA /* wuff.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF6704518184FF800DBDEEA /* wuff.h */; }; - FAF6704E18184FF800DBDEEA /* wuff_config.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF6704618184FF800DBDEEA /* wuff_config.h */; }; - FAF6704F18184FF800DBDEEA /* wuff_convert.c in Sources */ = {isa = PBXBuildFile; fileRef = FAF6704718184FF800DBDEEA /* wuff_convert.c */; }; - FAF6705018184FF800DBDEEA /* wuff_convert.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF6704818184FF800DBDEEA /* wuff_convert.h */; }; - FAF6705118184FF800DBDEEA /* wuff_internal.c in Sources */ = {isa = PBXBuildFile; fileRef = FAF6704918184FF800DBDEEA /* wuff_internal.c */; }; - FAF6705218184FF800DBDEEA /* wuff_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF6704A18184FF800DBDEEA /* wuff_internal.h */; }; - FAF6705318184FF800DBDEEA /* wuff_memory.c in Sources */ = {isa = PBXBuildFile; fileRef = FAF6704B18184FF800DBDEEA /* wuff_memory.c */; }; - FAF670561818501300DBDEEA /* WaveDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF670541818501300DBDEEA /* WaveDecoder.cpp */; }; - FAF670571818501300DBDEEA /* WaveDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF670551818501300DBDEEA /* WaveDecoder.h */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 001F02BC119E349012652C17 /* wrap_Data.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Data.h; sourceTree = ""; }; - 003142374F3D40A518716024 /* wrap_Keyboard.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Keyboard.h; sourceTree = ""; }; - 00393E4930202C2B6E381F68 /* mime.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mime.c; sourceTree = ""; }; - 006B015320155B4D42B43B61 /* wrap_Image.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Image.h; sourceTree = ""; }; - 00744BD73BFE3F591537728F /* Shape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Shape.h; sourceTree = ""; }; - 00D329851B1E7F6A3AF9614E /* tcp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = tcp.h; sourceTree = ""; }; - 02662CBC29B954295A634A39 /* wrap_Source.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Source.cpp; sourceTree = ""; }; - 02C16FDB537A702F4D42534E /* wrap_SpriteBatch.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_SpriteBatch.cpp; sourceTree = ""; }; - 02CA1BE908D91B104EB9590F /* wrap_Audio.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Audio.cpp; sourceTree = ""; }; - 02CD63315FF902E336AB4657 /* Contact.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Contact.cpp; sourceTree = ""; }; - 02F0197227150E1B28D9425B /* GmeDecoder.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GmeDecoder.cpp; sourceTree = ""; }; - 02F064F5202E34F5718352B8 /* wrap_Shape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Shape.h; sourceTree = ""; }; - 034144EE6C33421377674516 /* b2Distance.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2Distance.h; sourceTree = ""; }; - 03F17FF546D637744E263961 /* Graphics.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Graphics.cpp; sourceTree = ""; }; - 041672ED2CF51FC62F532FDB /* usocket.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = usocket.c; sourceTree = ""; }; - 047815B73C1C5373551442A6 /* wrap_Joint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Joint.h; sourceTree = ""; }; - 048C39D14DA05F5843FE08CA /* ftp.lua.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ftp.lua.h; sourceTree = ""; }; - 057A3770539D25AE6C8F20D3 /* Keyboard.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Keyboard.h; sourceTree = ""; }; - 059C04C13F3A7C05570F2987 /* b2Fixture.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2Fixture.cpp; sourceTree = ""; }; - 05DF237B657042515F3B4E52 /* wrap_Graphics.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Graphics.h; sourceTree = ""; }; - 0602250B7E4664E43CA113DC /* b2WheelJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2WheelJoint.cpp; sourceTree = ""; }; - 065364DB7A29396C777213D0 /* Joint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Joint.h; sourceTree = ""; }; - 076840774B0B6E721D0C18D0 /* wrap_ImageData.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_ImageData.cpp; sourceTree = ""; }; - 079504CB332E415D4B27797B /* b2Body.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2Body.h; sourceTree = ""; }; - 07B301984BE42246402F7D27 /* ImageData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImageData.h; sourceTree = ""; }; - 085B376E3FBB254F0FD37958 /* Matrix.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Matrix.h; sourceTree = ""; }; - 086B4A4E025B4B5F606747A2 /* b2DistanceJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2DistanceJoint.h; sourceTree = ""; }; - 08983C025D0655270DF81A5B /* b2PolygonShape.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2PolygonShape.cpp; sourceTree = ""; }; - 089B1AC1248B21D336594457 /* Body.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Body.cpp; sourceTree = ""; }; - 08AA5965073A1C520A7A6833 /* b2CircleShape.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2CircleShape.cpp; sourceTree = ""; }; - 08D24B70441A2496160C0849 /* Rasterizer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Rasterizer.h; sourceTree = ""; }; - 090F537B70DA06EA0B29593F /* b2Settings.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2Settings.h; sourceTree = ""; }; - 0959542C4B54320B1DDD5911 /* ChainShape.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ChainShape.cpp; sourceTree = ""; }; - 09C71F9D7DC45F5765B2462B /* socket.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = socket.h; sourceTree = ""; }; - 0A063D006D52330E67FF4B3A /* b2PolygonContact.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2PolygonContact.h; sourceTree = ""; }; - 0A0A2DA4094130187F655E52 /* b2Math.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2Math.h; sourceTree = ""; }; - 0A420541704C1C2D718A4D20 /* b2EdgeAndCircleContact.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2EdgeAndCircleContact.h; sourceTree = ""; }; - 0A936C83344E2CF84E703059 /* PulleyJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PulleyJoint.h; sourceTree = ""; }; - 0AA1539E66B2641B66130709 /* b2MouseJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2MouseJoint.h; sourceTree = ""; }; - 0AE5755936E84C247FB56C65 /* PrismaticJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = PrismaticJoint.cpp; sourceTree = ""; }; - 0AFB7DA45B2D6913110A5AAB /* wrap_WheelJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_WheelJoint.h; sourceTree = ""; }; - 0B0728FA73B107B37A956A09 /* wrap_Image.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Image.cpp; sourceTree = ""; }; - 0B4020CD058D70F569DF6129 /* wrap_PrismaticJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_PrismaticJoint.cpp; sourceTree = ""; }; - 0B727D416262392743091BC3 /* TrueTypeRasterizer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TrueTypeRasterizer.h; sourceTree = ""; }; - 0BEB72033ACA25550ADA76C4 /* b64.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b64.h; sourceTree = ""; }; - 0C30420F7FD3038C721223A5 /* TrueTypeRasterizer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TrueTypeRasterizer.cpp; sourceTree = ""; }; - 0C5C6C6E47851D1308411DE6 /* SoundData.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SoundData.cpp; sourceTree = ""; }; - 0CB6025618505B055A4E75DD /* Matrix.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Matrix.cpp; sourceTree = ""; }; - 0CFF64090F0F4F481BB80CF0 /* Volatile.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Volatile.h; sourceTree = ""; }; - 0D6F00D95C4407BB26E71E02 /* b2World.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2World.cpp; sourceTree = ""; }; - 0E3E13BC3E3A7C0C7DBE7DF8 /* wrap_RopeJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_RopeJoint.cpp; sourceTree = ""; }; - 0E755DCF691828CE11444877 /* b2PolygonShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2PolygonShape.h; sourceTree = ""; }; - 0EA87794395D3B287C5949AA /* wrap_FrictionJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_FrictionJoint.h; sourceTree = ""; }; - 0EB870A1180261FD424A41B3 /* Shape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Shape.h; sourceTree = ""; }; - 0F0E666B7C790BB870477994 /* b2BlockAllocator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2BlockAllocator.h; sourceTree = ""; }; - 0F8D03F1544476B57CA97B01 /* b2WorldCallbacks.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2WorldCallbacks.cpp; sourceTree = ""; }; - 104144AB73A974BC04A03131 /* graphics.lua.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = graphics.lua.h; sourceTree = ""; }; - 104D5534669B772556942891 /* PrismaticJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PrismaticJoint.h; sourceTree = ""; }; - 104D567660003ADE696D341A /* Source.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Source.h; sourceTree = ""; }; - 10A608C96F067F972C962EFB /* love.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = love.h; sourceTree = ""; }; - 10F83B5848B77A937C250FEB /* b2Joint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2Joint.h; sourceTree = ""; }; - 1108594E361A22D90D6022E8 /* b2EdgeAndCircleContact.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2EdgeAndCircleContact.cpp; sourceTree = ""; }; - 112814480BBF2ED06EED15BF /* GlyphData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GlyphData.h; sourceTree = ""; }; - 113269E55FCF208D2D6754BC /* Timer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Timer.cpp; sourceTree = ""; }; - 11745DE315E859F71E881D76 /* wrap_Rasterizer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Rasterizer.cpp; sourceTree = ""; }; - 11773415762F3A38421C6DB3 /* Graphics.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = Graphics.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; - 11CF30E73CEA2D8D0A1B17D3 /* b2DynamicTree.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2DynamicTree.h; sourceTree = ""; }; - 11D141087979064B441B787D /* File.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = File.cpp; sourceTree = ""; }; - 11D62E873092729B497B447F /* b2RevoluteJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2RevoluteJoint.cpp; sourceTree = ""; }; - 120B391518206E964493126C /* b2Body.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2Body.cpp; sourceTree = ""; }; - 12390CBC115B00D06EF951DD /* b2Draw.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2Draw.cpp; sourceTree = ""; }; - 124E716E0BCA055534A60AD2 /* wrap_Shape.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Shape.cpp; sourceTree = ""; }; - 13093ADC78426C5009DF3B13 /* b2FrictionJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2FrictionJoint.cpp; sourceTree = ""; }; - 131F69C3368C4B8A55EE0DAD /* wrap_WeldJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_WeldJoint.h; sourceTree = ""; }; - 135801A6483528800C676492 /* io.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = io.c; sourceTree = ""; }; - 138913BE5126483748FA43D0 /* Joint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Joint.h; sourceTree = ""; }; - 139411436818381E493F00F5 /* wrap_JoystickModule.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_JoystickModule.cpp; sourceTree = ""; }; - 14AE68E14C2C74526A612FA0 /* wrap_Image.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Image.cpp; sourceTree = ""; }; - 15093E1B1A14176374C81299 /* wrap_CircleShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_CircleShape.h; sourceTree = ""; }; - 153957EB332E1269671E7F4A /* b2CircleShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2CircleShape.h; sourceTree = ""; }; - 16C36B3C59A10CDC7ACE0DD4 /* http.lua.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = http.lua.h; sourceTree = ""; }; - 174D472C1AFE594D77A0322B /* b2ChainAndCircleContact.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2ChainAndCircleContact.h; sourceTree = ""; }; - 175A1B8D733B2D4803F64AC1 /* b2Distance.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2Distance.cpp; sourceTree = ""; }; - 17C730CB1DA01B8F0A11217C /* except.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = except.h; sourceTree = ""; }; - 17E9544103AE376210ED5BAA /* select.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = select.h; sourceTree = ""; }; - 182A781C7A2D3D2B6B8904A8 /* Data.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Data.h; sourceTree = ""; }; - 1839744763625B5D64EC70AC /* Audio.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Audio.cpp; sourceTree = ""; }; - 18E0492204644DE929B96486 /* wrap_DistanceJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_DistanceJoint.h; sourceTree = ""; }; - 1916112F57AF56A173727464 /* Audio.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Audio.h; sourceTree = ""; }; - 198A44BD71BB61EE517C2A39 /* Mouse.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Mouse.h; sourceTree = ""; }; - 19ED419874B46EC16F927524 /* love.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = love.cpp; sourceTree = ""; }; - 19F40DF6507028212FEB1D77 /* wrap_Keyboard.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Keyboard.cpp; sourceTree = ""; }; - 1A2A61843B753E3F5B330703 /* Vector.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Vector.cpp; sourceTree = ""; }; - 1A304E384AF2119905C01504 /* Source.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Source.cpp; sourceTree = ""; }; - 1A311FC16B9C0F8D7A41580E /* wrap_Body.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Body.h; sourceTree = ""; }; - 1A95437F513E662113AC154A /* b2Rope.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2Rope.h; sourceTree = ""; }; - 1A9810F758AC1D1E4B6431FD /* wrap_Graphics.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Graphics.cpp; sourceTree = ""; }; - 1AA213FC158815FA77C40330 /* ChainShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ChainShape.h; sourceTree = ""; }; - 1AA7781A230065F346E2313A /* DevilHandler.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DevilHandler.cpp; sourceTree = ""; }; - 1B036C7C5A8832AE53BB1C06 /* b2CollideEdge.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2CollideEdge.cpp; sourceTree = ""; }; - 1B1C4E4D288A1D2F29E57B1B /* Rasterizer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Rasterizer.cpp; sourceTree = ""; }; - 1B4E22F1388E2B2E76E3377B /* wrap_GlyphData.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_GlyphData.cpp; sourceTree = ""; }; - 1BCD6EE50EB8791E5A870135 /* utf8.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = utf8.h; sourceTree = ""; }; - 1C5B57F87B315E39005B119F /* b2TimeOfImpact.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2TimeOfImpact.h; sourceTree = ""; }; - 1CAA69E00D0808BA2108238B /* wrap_ChainShape.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_ChainShape.cpp; sourceTree = ""; }; - 1CD02D1975803957282F28AB /* auxiliar.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = auxiliar.c; sourceTree = ""; }; - 1CE84F1F19BC2AA412C638B1 /* timeout.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = timeout.h; sourceTree = ""; }; - 1DA41DFF0869489411A71AFC /* Texture.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Texture.h; sourceTree = ""; }; - 1E22646A710E5EFC27FE3932 /* FrictionJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FrictionJoint.cpp; sourceTree = ""; }; - 1E27263847302FCA1F843B47 /* b2PrismaticJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2PrismaticJoint.cpp; sourceTree = ""; }; - 1E827AE8548C52493ED95629 /* wrap_Filesystem.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Filesystem.cpp; sourceTree = ""; }; - 1E840AF84AB61C6410E26634 /* wrap_PulleyJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_PulleyJoint.cpp; sourceTree = ""; }; - 1E9E4F657DEC2772493B79CC /* b2ContactSolver.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2ContactSolver.cpp; sourceTree = ""; }; - 1F0D375C38A245E403E53DB5 /* b2TimeOfImpact.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2TimeOfImpact.cpp; sourceTree = ""; }; - 1F3A277A44141DBF7BCF146A /* wrap_RevoluteJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_RevoluteJoint.cpp; sourceTree = ""; }; - 1F4E747212DE41716BC245C9 /* b2PolygonContact.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2PolygonContact.cpp; sourceTree = ""; }; - 1F6F652A57F8098E5CCA6F9A /* auxiliar.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = auxiliar.h; sourceTree = ""; }; - 1F875B224C4E1B9E35854766 /* Mpg123Decoder.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Mpg123Decoder.cpp; sourceTree = ""; }; - 202650DE4F267CD3082A1B30 /* wrap_Font.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Font.h; sourceTree = ""; }; - 208275724C9421035EA145A4 /* MouseJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MouseJoint.h; sourceTree = ""; }; - 21124F915912499179A42115 /* b2CircleContact.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2CircleContact.h; sourceTree = ""; }; - 219636CF6780074F7871463D /* Filesystem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Filesystem.h; sourceTree = ""; }; - 21B25A7E333315172B754D4F /* buffer.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = buffer.c; sourceTree = ""; }; - 21E975B81E8D701F2147658C /* wrap_Contact.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Contact.h; sourceTree = ""; }; - 22256CC12B7C7D0D1B430D46 /* tcp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = tcp.c; sourceTree = ""; }; - 22EF17981EBD442773FE41B6 /* wrap_Mouse.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Mouse.cpp; sourceTree = ""; }; - 232D67C67BEE54B776420682 /* wrap_Font.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Font.cpp; sourceTree = ""; }; - 23573F2F4F7D56312E663E24 /* Canvas.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Canvas.h; sourceTree = ""; }; - 239054AE7475433E39747DA9 /* b2Timer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2Timer.cpp; sourceTree = ""; }; - 23985AB32E7B463A2CB87E2C /* Sound.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Sound.h; sourceTree = ""; }; - 23A266CD4FC729355E23606E /* b2WheelJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2WheelJoint.h; sourceTree = ""; }; - 24265680279E30A40DF81946 /* Event.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Event.cpp; sourceTree = ""; }; - 243E18977E2A37CC6FDD55A5 /* b2EdgeAndPolygonContact.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2EdgeAndPolygonContact.cpp; sourceTree = ""; }; - 249015D170563D85709D7B6D /* options.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = options.h; sourceTree = ""; }; - 24D758D262EA18DC15187A12 /* delay.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = delay.h; sourceTree = ""; }; - 24EE059E03D8155F4BFF64D6 /* Audio.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Audio.h; sourceTree = ""; }; - 25C325DC2128769F6C6A54C3 /* Image.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = ""; }; - 25CE236F66F70EB3444A7CC8 /* GearJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GearJoint.h; sourceTree = ""; }; - 276C3474657D0A246F64221C /* wrap_EdgeShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_EdgeShape.h; sourceTree = ""; }; - 27F777AB188D674F30BC1829 /* wrap_World.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_World.h; sourceTree = ""; }; - 28016C9B51FE1A893DC35B66 /* Variant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Variant.h; sourceTree = ""; }; - 28024635525B077E08A73D9B /* Source.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Source.cpp; sourceTree = ""; }; - 283342E174613897621A43F1 /* DevilHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DevilHandler.h; sourceTree = ""; }; - 286660042F9654F61AB90D7A /* Body.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Body.h; sourceTree = ""; }; - 2912092853050AF9785F39BE /* wrap_RevoluteJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_RevoluteJoint.h; sourceTree = ""; }; - 295C665B1E0B6B2D03CC4937 /* wrap_Event.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Event.h; sourceTree = ""; }; - 2A5F7DCB40652F9B7D61073A /* Sound.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Sound.cpp; sourceTree = ""; }; - 2A6150F7479D21346EC54B68 /* b2ContactManager.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2ContactManager.cpp; sourceTree = ""; }; - 2B8C245A21A515E86636725A /* wrap_PrismaticJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_PrismaticJoint.h; sourceTree = ""; }; - 2BE75A693BE206B22DAE1B2E /* wrap_SpriteBatch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_SpriteBatch.h; sourceTree = ""; }; - 2C78323D7D5C628A53EC6931 /* b2Math.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2Math.cpp; sourceTree = ""; }; - 2C87695707B046B536F347D8 /* OpenGL.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OpenGL.h; sourceTree = ""; }; - 2C970EA7229F20934C72581D /* b2RopeJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2RopeJoint.h; sourceTree = ""; }; - 2CAE75B079B828FE6892684A /* udp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = udp.h; sourceTree = ""; }; - 2CEC5ED5211174C7583849AD /* Reference.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Reference.h; sourceTree = ""; }; - 2D290E902C451D6849051FEF /* b2WeldJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2WeldJoint.h; sourceTree = ""; }; - 2D7B7DEC4FC87878332E41B3 /* wrap_JoystickModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_JoystickModule.h; sourceTree = ""; }; - 2D8E6FAE2A100B5866E96BFF /* runtime.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = runtime.h; sourceTree = ""; }; - 2D9475890CDA3D3776435622 /* Timer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Timer.h; sourceTree = ""; }; - 2DC90F3C6160198256795C75 /* luasocket.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = luasocket.cpp; sourceTree = ""; }; - 2DCE45C868A0091B762C7377 /* Body.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Body.cpp; sourceTree = ""; }; - 2E2675AF3DAA24CE0728042C /* udp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = udp.c; sourceTree = ""; }; - 2E406F8328543EC63EB922C6 /* OpenGL.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = OpenGL.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; - 2E5C2A2F05417B294ED655E8 /* Audio.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Audio.h; sourceTree = ""; }; - 2E9B5D9926034F9172215D5E /* Font.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Font.h; sourceTree = ""; }; - 2FB732687B1669402408356D /* Source.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Source.cpp; sourceTree = ""; }; - 2FD366F113387BC95125133D /* b2Shape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2Shape.h; sourceTree = ""; }; - 2FF26CC52C28773750B812D9 /* PolygonShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PolygonShape.h; sourceTree = ""; }; - 30E466F441EE727658716873 /* Module.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Module.cpp; sourceTree = ""; }; - 30ED4BB03C5F11254AF12E98 /* Sound.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Sound.cpp; sourceTree = ""; }; - 31871B8B7E1A697A73576040 /* b2PolygonAndCircleContact.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2PolygonAndCircleContact.cpp; sourceTree = ""; }; - 31A444CF0B4E6DA450120730 /* File.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = File.h; sourceTree = ""; }; - 31B85B507F466FE158A3718E /* wrap_ImageData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_ImageData.h; sourceTree = ""; }; - 31C84D0129AE5F6044A94AC2 /* ModPlugDecoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ModPlugDecoder.h; sourceTree = ""; }; - 31E0110E5797041465FF5F95 /* Mouse.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Mouse.cpp; sourceTree = ""; }; - 325E60A57F2624766A524423 /* b2World.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2World.h; sourceTree = ""; }; - 329915E84B0B6D025DDC34A9 /* luasocket.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = luasocket.h; sourceTree = ""; }; - 32CC11481CD9164455455D72 /* b2Collision.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2Collision.cpp; sourceTree = ""; }; - 32FD3FEE52FD1911405B3C59 /* b2BroadPhase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2BroadPhase.h; sourceTree = ""; }; - 330F59B11A5B5D1B44DC07BF /* wrap_Source.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Source.h; sourceTree = ""; }; - 33627AE97E66147E76804EF9 /* b2DistanceJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2DistanceJoint.cpp; sourceTree = ""; }; - 33FD508B0754314530A35EF3 /* StringMap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StringMap.h; sourceTree = ""; }; - 340345481F165F8945C716AE /* wrap_FrictionJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_FrictionJoint.cpp; sourceTree = ""; }; - 343E66751EBA75264C3400FA /* b2Draw.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2Draw.h; sourceTree = ""; }; - 34A36BB617BC5CCA5B870EA6 /* DistanceJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DistanceJoint.cpp; sourceTree = ""; }; - 350C47C774835EA552130431 /* Object.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Object.h; sourceTree = ""; }; - 3512460642B046876D687B22 /* wrap_FileData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_FileData.h; sourceTree = ""; }; - 351B09E51FDC338622F44624 /* Window.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Window.cpp; sourceTree = ""; }; - 3547706F2E7D43212CB40D04 /* wrap_GlyphData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_GlyphData.h; sourceTree = ""; }; - 35B31EBC4DDB6F994BCA46B6 /* Reference.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Reference.cpp; sourceTree = ""; }; - 36324E12371E518E6E9C61B5 /* wrap_World.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_World.cpp; sourceTree = ""; }; - 36437CE95936736320710513 /* delay.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = delay.cpp; sourceTree = ""; }; - 36465ABA28FB06F4333C3F07 /* ImageRasterizer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImageRasterizer.h; sourceTree = ""; }; - 36DD053F754B2D29719B1F80 /* RevoluteJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RevoluteJoint.cpp; sourceTree = ""; }; - 370D76DC224F2EB300CB4E2F /* Physics.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Physics.cpp; sourceTree = ""; }; - 37224F6B30CA5D800B1F41F1 /* wrap_Rasterizer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Rasterizer.h; sourceTree = ""; }; - 3746164716797CF80D6B0CEE /* Exception.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Exception.cpp; sourceTree = ""; }; - 385902BD584E7D73154E4EBB /* wrap_Sound.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Sound.cpp; sourceTree = ""; }; - 386430B43A081E2A617B05F1 /* EnumMap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EnumMap.h; sourceTree = ""; }; - 389E3CEC356050A27784290E /* Graphics.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Graphics.h; sourceTree = ""; }; - 38AF72D4790619BB022E2AEF /* b2RopeJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2RopeJoint.cpp; sourceTree = ""; }; - 3960064616E26C0213E323E2 /* wrap_Sound.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Sound.h; sourceTree = ""; }; - 3A430C846C642DBC14975C7C /* utf8.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = utf8.h; sourceTree = ""; }; - 3AC7627D7E1458AA0D8E0522 /* b2GrowableStack.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2GrowableStack.h; sourceTree = ""; }; - 3AD03C7A77C546ED07BE4C06 /* wrap_PolygonShape.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_PolygonShape.cpp; sourceTree = ""; }; - 3AFB3A18384A2D22352262B1 /* wrap_Canvas.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Canvas.h; sourceTree = ""; }; - 3BA712260D725FEB72EB3CDE /* Event.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Event.cpp; sourceTree = ""; }; - 3BB22A142670197B0DBD0BED /* wrap_Contact.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Contact.cpp; sourceTree = ""; }; - 3C0B06AF6B5326C840477B18 /* MouseJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MouseJoint.cpp; sourceTree = ""; }; - 3C4D70E82FC12A9A15EC39BA /* checked.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = checked.h; sourceTree = ""; }; - 3C56375F752B7A9779DD37EC /* Variant.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Variant.cpp; sourceTree = ""; }; - 3C9253C8152355E1274814B7 /* FLACDecoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FLACDecoder.h; sourceTree = ""; }; - 3C965422252F672D3FF6598C /* CircleShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CircleShape.h; sourceTree = ""; }; - 3CDA3E9B364F17A902384AAC /* wrap_Font.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Font.h; sourceTree = ""; }; - 3CFE5C4A12D5675E7C9C7BF9 /* Image.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = ""; }; - 3D8460B2486A372825213933 /* Vector.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Vector.h; sourceTree = ""; }; - 3DFF31EE26405E554C610C8F /* wrap_WeldJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_WeldJoint.cpp; sourceTree = ""; }; - 3EA80A4E0CE0014052076037 /* Joint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Joint.cpp; sourceTree = ""; }; - 407422E8589417B6683D1042 /* ModPlugDecoder.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ModPlugDecoder.cpp; sourceTree = ""; }; - 40A0593B616A223A4CEF07C9 /* Memoizer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Memoizer.cpp; sourceTree = ""; }; - 40BC14C607396F8B1B084012 /* int.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = int.h; sourceTree = ""; }; - 40F412FF29F65F5A3D511B98 /* wrap_EdgeShape.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_EdgeShape.cpp; sourceTree = ""; }; - 411B061C49172C971C622125 /* Object.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Object.cpp; sourceTree = ""; }; - 415E1438178736BE0EA908D5 /* select.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = select.c; sourceTree = ""; }; - 426B1C4475DC54505B824B7F /* VertexBuffer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = VertexBuffer.cpp; sourceTree = ""; }; - 427B4B2517C0516844370E3D /* b2CollidePolygon.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2CollidePolygon.cpp; sourceTree = ""; }; - 439E46D768A266780E894800 /* JoystickModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JoystickModule.h; sourceTree = ""; }; - 43A258C229C75C15238E520C /* Decoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Decoder.h; sourceTree = ""; }; - 43BC2B1C505E5EFF650C31E3 /* Keyboard.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Keyboard.cpp; sourceTree = ""; }; - 448C492C7AEB7840504F1C9D /* b2EdgeShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2EdgeShape.h; sourceTree = ""; }; - 44DE79C879CC0074510A2403 /* WheelJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WheelJoint.cpp; sourceTree = ""; }; - 44E85D982F01082F5E1346B6 /* b2ChainAndPolygonContact.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2ChainAndPolygonContact.h; sourceTree = ""; }; - 457674E43FF71E974D990C00 /* DistanceJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DistanceJoint.h; sourceTree = ""; }; - 459946CA7F4406B026E80501 /* inet.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = inet.h; sourceTree = ""; }; - 45DC20A760FC42341E5762F7 /* FrictionJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FrictionJoint.h; sourceTree = ""; }; - 45E761A0072E0EF92BD66EA9 /* runtime.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = runtime.cpp; sourceTree = ""; }; - 465D0438379342C4589E2B1C /* WeldJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WeldJoint.h; sourceTree = ""; }; - 468F7A0A484820DE79CE76D2 /* b2ChainAndCircleContact.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2ChainAndCircleContact.cpp; sourceTree = ""; }; - 46CA2B6B17C32BBE55772268 /* Source.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Source.h; sourceTree = ""; }; - 473D2247745F4901155A75DB /* config.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = ""; }; - 47C77F6032FA77E046AA6810 /* Fixture.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Fixture.cpp; sourceTree = ""; }; - 47D46915001F342A3CD23E86 /* File.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = File.h; sourceTree = ""; }; - 4832527C02C105776536438A /* b2Rope.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2Rope.cpp; sourceTree = ""; }; - 485645C663D372A96DFD33F7 /* mime.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mime.h; sourceTree = ""; }; - 48A206C9004150640C432100 /* ParticleSystem.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ParticleSystem.cpp; sourceTree = ""; }; - 4941079838020ECA049B5C21 /* Color.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Color.h; sourceTree = ""; }; - 49496EAF3305281B19223C22 /* except.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = except.c; sourceTree = ""; }; - 4A1D6DAE45E627BD12903B52 /* b2PolygonAndCircleContact.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2PolygonAndCircleContact.h; sourceTree = ""; }; - 4A47384208BE218F688C4EFA /* b2MouseJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2MouseJoint.cpp; sourceTree = ""; }; - 4A774BC26B7235E410D40C8E /* FLACDecoder.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FLACDecoder.cpp; sourceTree = ""; }; - 4A80315175C5625804AA4A56 /* VorbisDecoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VorbisDecoder.h; sourceTree = ""; }; - 4ABD4A7B5CB6678E39490982 /* io.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = io.h; sourceTree = ""; }; - 4AD52074367950B735707CE1 /* Canvas.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = Canvas.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; - 4B002CBD52493ED9347C6EBA /* url.lua.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = url.lua.h; sourceTree = ""; }; - 4B41232F7AF7793540F46C58 /* timeout.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = timeout.c; sourceTree = ""; }; - 4B5F4DF8110020A96B5D3EAB /* b2BroadPhase.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2BroadPhase.cpp; sourceTree = ""; }; - 4B731754147B27AF73AC5358 /* Volatile.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Volatile.cpp; sourceTree = ""; }; - 4C606AEC342457600C3F0741 /* JoystickModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JoystickModule.h; sourceTree = ""; }; - 4D700D182EAA46273D1E2CC4 /* SpriteBatch.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SpriteBatch.cpp; sourceTree = ""; }; - 4D81102E7ABD1C282BE42CE3 /* wrap_MouseJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_MouseJoint.cpp; sourceTree = ""; }; - 4DAB28A9235E2CBE75F56848 /* CircleShape.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CircleShape.cpp; sourceTree = ""; }; - 4DC3617831763D2760335D87 /* wrap_SoundData.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_SoundData.cpp; sourceTree = ""; }; - 4E0F565B03D05C3722496F27 /* File.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = File.cpp; sourceTree = ""; }; - 4E15567759041CC379292BE6 /* Decoder.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Decoder.cpp; sourceTree = ""; }; - 4E3251027026699A1D4D310D /* wrap_Canvas.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Canvas.cpp; sourceTree = ""; }; - 4E6705C154C34FBD143F465E /* b2ChainShape.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2ChainShape.cpp; sourceTree = ""; }; - 4E972C114A6C25A63B5B6EF2 /* wrap_Mouse.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Mouse.h; sourceTree = ""; }; - 4F1862D324C9429157A27A2E /* Event.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Event.h; sourceTree = ""; }; - 4F34010A575C02E66D400CE2 /* RopeJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RopeJoint.h; sourceTree = ""; }; - 4F3E12BD4A646D0366792FC9 /* b2WorldCallbacks.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2WorldCallbacks.h; sourceTree = ""; }; - 503971A86B7167A91B670FBA /* boot.lua.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = boot.lua.h; sourceTree = ""; }; - 505F23A73BFE250833D650E4 /* Image.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Image.cpp; sourceTree = ""; }; - 50B67F2D0CC511706810302E /* wrap_GearJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_GearJoint.cpp; sourceTree = ""; }; - 50EC67CE3ED71F5D13304FD4 /* b2Contact.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2Contact.h; sourceTree = ""; }; - 50F0575E16561864699E41F5 /* b2Fixture.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2Fixture.h; sourceTree = ""; }; - 5100177E5D8A14366C5B0BC5 /* b2Island.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2Island.h; sourceTree = ""; }; - 524741891BB93848039F4174 /* Keyboard.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Keyboard.cpp; sourceTree = ""; }; - 525A4D633D9B0D8B225936D4 /* b2Timer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2Timer.h; sourceTree = ""; }; - 52D130DF3DC82D9D4C867B61 /* math.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = math.h; sourceTree = ""; }; - 52E15B702C40593D3BF431DF /* wrap_File.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_File.h; sourceTree = ""; }; - 53C4064801456193163E4631 /* RopeJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RopeJoint.cpp; sourceTree = ""; }; - 53C6151E07FB1E3471590CB9 /* ltn12.lua.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ltn12.lua.h; sourceTree = ""; }; - 53EE57FF4DBD52BB22701160 /* ParticleSystem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ParticleSystem.h; sourceTree = ""; }; - 54A13C2209F945671BC27974 /* FileData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FileData.h; sourceTree = ""; }; - 54E653E84E8873D467C750FC /* mime.lua.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mime.lua.h; sourceTree = ""; }; - 54E85987318206E93DC8189F /* PolygonShape.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = PolygonShape.cpp; sourceTree = ""; }; - 55A759CE711E157339930E58 /* b2BlockAllocator.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2BlockAllocator.cpp; sourceTree = ""; }; - 55AE226405CC1A55462E1D89 /* threads.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = threads.h; sourceTree = ""; }; - 55B425307C0C1C4B3EFC3A5F /* JoystickModule.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JoystickModule.cpp; sourceTree = ""; }; - 561D4A4722E36BAA16D17CC8 /* EdgeShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EdgeShape.h; sourceTree = ""; }; - 567C0A0C58931DE54733011B /* b2StackAllocator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2StackAllocator.h; sourceTree = ""; }; - 56D6030A0B8F7397715062B9 /* Image.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = Image.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; - 577B66502A5360AE60733B10 /* VertexBuffer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VertexBuffer.h; sourceTree = ""; }; - 57E6429235C547BE26B73C6C /* version.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = ""; }; - 583037E9238A6EF00DD20B1A /* Font.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Font.cpp; sourceTree = ""; }; - 584E16AE09E12536206C46FE /* Mouse.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Mouse.cpp; sourceTree = ""; }; - 58792BC1126C2917432D706B /* b2CircleContact.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2CircleContact.cpp; sourceTree = ""; }; - 58CC50E70A375FDF53EF01B6 /* Texture.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Texture.cpp; sourceTree = ""; }; - 58CD093F254501E37CA47CA8 /* types.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = types.h; sourceTree = ""; }; - 597478A255B82B56488B4717 /* wrap_FileData.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_FileData.cpp; sourceTree = ""; }; - 59BE634A2ACE722F14B86F89 /* b2Island.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2Island.cpp; sourceTree = ""; }; - 59D27EA33E8E62E15C185948 /* b2DynamicTree.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2DynamicTree.cpp; sourceTree = ""; }; - 5A1C77401B1B32CE326332A1 /* b2ContactSolver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2ContactSolver.h; sourceTree = ""; }; - 5B3306B5587A708557EE4D4F /* Source.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Source.h; sourceTree = ""; }; - 5B5A0BEC36BE007E6E491396 /* wrap_SoundData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_SoundData.h; sourceTree = ""; }; - 5BCC49F529F726385CD41FA6 /* b2WeldJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2WeldJoint.cpp; sourceTree = ""; }; - 5CB720BA493D7D995E0E20DD /* PulleyJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = PulleyJoint.cpp; sourceTree = ""; }; - 5CE0167703887B376F2368FD /* RevoluteJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RevoluteJoint.h; sourceTree = ""; }; - 5CE370672B1234B10F9532FA /* Physics.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Physics.h; sourceTree = ""; }; - 5CF629B94C7802D446D61C45 /* wrap_Decoder.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Decoder.cpp; sourceTree = ""; }; - 5D016F4C27EF506C13FE3058 /* ImageRasterizer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ImageRasterizer.cpp; sourceTree = ""; }; - 5D383DA1468545C30E7B5805 /* b64.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b64.cpp; sourceTree = ""; }; - 5D590ACE5E237B7D5B556AD0 /* Contact.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Contact.h; sourceTree = ""; }; - 5D93601669875EE06721689E /* Drawable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Drawable.h; sourceTree = ""; }; - 5DA322AC59AD7E43183577CB /* b2EdgeAndPolygonContact.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2EdgeAndPolygonContact.h; sourceTree = ""; }; - 5DC271240F0119AE16FA1B8E /* wrap_Filesystem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Filesystem.h; sourceTree = ""; }; - 5ED732200E1B2E5F79831DDA /* wrap_Data.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Data.cpp; sourceTree = ""; }; - 5F1F169C7FC633EF292E26DF /* wrap_Fixture.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Fixture.h; sourceTree = ""; }; - 5F42052D7C8271A1105541DE /* wrap_ParticleSystem.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_ParticleSystem.cpp; sourceTree = ""; }; - 5F846B49240D52C10F6F76E5 /* options.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = options.c; sourceTree = ""; }; - 5FAE2A9679C97F2C2792182D /* luasocket.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = luasocket.c; sourceTree = ""; }; - 5FF97D522B8872947DED611C /* wrap_Audio.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Audio.h; sourceTree = ""; }; - 601E6A56345412E87E1D396B /* Pool.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Pool.cpp; sourceTree = ""; }; - 60840050412A459D5D21518F /* Fixture.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Fixture.h; sourceTree = ""; }; - 60C95C7F507A381D0A483B3F /* b2ChainAndPolygonContact.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2ChainAndPolygonContact.cpp; sourceTree = ""; }; - 610B475400DE0F7213352BC3 /* inet.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = inet.c; sourceTree = ""; }; - 615E0F450F2B7BA25EE679A6 /* Font.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Font.h; sourceTree = ""; }; - 61E64F07028039774F502D69 /* Shape.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Shape.cpp; sourceTree = ""; }; - 62370A494F9D6E2D570065EB /* FileData.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FileData.cpp; sourceTree = ""; }; - 62E121F35BEB622029324F25 /* Pool.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Pool.h; sourceTree = ""; }; - 63024AF52EE3658260BE116B /* Module.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Module.h; sourceTree = ""; }; - 633E37194CB535AE41A00092 /* b2EdgeShape.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2EdgeShape.cpp; sourceTree = ""; }; - 63936FF81D4E14F6534A43BB /* usocket.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = usocket.h; sourceTree = ""; }; - 63A63DFB339266AC401B545A /* Mouse.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Mouse.h; sourceTree = ""; }; - 64491E98483728D601110EF0 /* b2PrismaticJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2PrismaticJoint.h; sourceTree = ""; }; - 644D0C953C3439FC57C03FC6 /* World.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = World.cpp; sourceTree = ""; }; - 64694F91593478085859666F /* wrap_Body.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Body.cpp; sourceTree = ""; }; - 64AC15B600F2473651823D40 /* GmeDecoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GmeDecoder.h; sourceTree = ""; }; - 64BA1CE328FF17144B475111 /* wrap_MouseJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_MouseJoint.h; sourceTree = ""; }; - 6590063A6E4B3AEF4550443C /* b2GearJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2GearJoint.h; sourceTree = ""; }; - 66EC3C0463A703A97445193B /* b2PulleyJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2PulleyJoint.cpp; sourceTree = ""; }; - 66F8479E6D2D587A592F2024 /* socket.lua.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = socket.lua.h; sourceTree = ""; }; - 678E42771C9B415628A3234D /* wrap_ParticleSystem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_ParticleSystem.h; sourceTree = ""; }; - 68616BD516DB124312B47EB3 /* Image.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = ""; }; - 691C5C5828550E2F60754EF2 /* wrap_Event.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Event.cpp; sourceTree = ""; }; - 695E4ED13AA0689E64280573 /* wrap_Timer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Timer.cpp; sourceTree = ""; }; - 69967D2323404E1F0ED21F11 /* wrap_DistanceJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_DistanceJoint.cpp; sourceTree = ""; }; - 69A01D71103275D451F965B2 /* b2GearJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2GearJoint.cpp; sourceTree = ""; }; - 69DB4423147C7E3362941E75 /* Joint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Joint.cpp; sourceTree = ""; }; - 6AA03CE31B942DC660045FE9 /* WheelJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WheelJoint.h; sourceTree = ""; }; - 6B255FFC4A2C404E50512CB5 /* Mpg123Decoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Mpg123Decoder.h; sourceTree = ""; }; - 6B2E52E6185E6980660F1374 /* luasocket.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = luasocket.h; sourceTree = ""; }; - 6B3565203A1778431F8A5409 /* threads.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = threads.cpp; sourceTree = ""; }; - 6BEE6511475F641A70A0591E /* Timer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Timer.h; sourceTree = ""; }; - 6C367AE309C453C412D91363 /* wrap_File.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_File.cpp; sourceTree = ""; }; - 6C7E6C3F1CCA1CF6164123F6 /* b2ChainShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2ChainShape.h; sourceTree = ""; }; - 6C981DA13E3D42DA06891046 /* Keyboard.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Keyboard.h; sourceTree = ""; }; - 6CB1193233FA78EE646A17A1 /* Audio.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Audio.cpp; sourceTree = ""; }; - 6CDD4F3320303D222C180CD0 /* Window.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Window.cpp; sourceTree = ""; }; - 6CEB48E969FC42C53F9432B1 /* wrap_Physics.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Physics.cpp; sourceTree = ""; }; - 6D822D830EF049417D184372 /* b2TimeStep.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2TimeStep.h; sourceTree = ""; }; - 6DE3129F3A0B2D9C178118F3 /* Filesystem.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Filesystem.cpp; sourceTree = ""; }; - 6E682862758051BF7C0A10AA /* tp.lua.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = tp.lua.h; sourceTree = ""; }; - 6E6D5AB27B71488D405526C3 /* Body.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Body.h; sourceTree = ""; }; - 6EF321185C2B1F1E1AF54F64 /* wrap_CircleShape.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_CircleShape.cpp; sourceTree = ""; }; - 6F1B61350B6B36AF216C57D7 /* b2Joint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2Joint.cpp; sourceTree = ""; }; - 6F4D478A52A0408765095920 /* GearJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GearJoint.cpp; sourceTree = ""; }; - 6FF15DF4423F6426224024C9 /* b2Settings.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2Settings.cpp; sourceTree = ""; }; - 70564CC32DEC209F2A615F44 /* wrap_ChainShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_ChainShape.h; sourceTree = ""; }; - 70F425B5336E1CD652827FD0 /* Shape.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Shape.cpp; sourceTree = ""; }; - 714251EE742346DC17103357 /* Font.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Font.cpp; sourceTree = ""; }; - 71810207414B52F8340D7797 /* wrap_Joint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Joint.cpp; sourceTree = ""; }; - 71C579A557640A3E2A696518 /* wrap_Physics.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Physics.h; sourceTree = ""; }; - 71F878E2440A021B68D93ABC /* b2Contact.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2Contact.cpp; sourceTree = ""; }; - 727648E06CD863A2582F798F /* VorbisDecoder.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = VorbisDecoder.cpp; sourceTree = ""; }; - 727D23FA1CC755B902471A45 /* SpriteBatch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SpriteBatch.h; sourceTree = ""; }; - 733758E8028B20BB799A7BE6 /* Decoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Decoder.h; sourceTree = ""; }; - 73473B3C698B538002540A5D /* wrap_WheelJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_WheelJoint.cpp; sourceTree = ""; }; - 734947AA28AF36E436D242FD /* unix.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = unix.c; sourceTree = ""; }; - 74003CB27FA762A021183AD5 /* GlyphData.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GlyphData.cpp; sourceTree = ""; }; - 74215662418726B35C581E55 /* Thread.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Thread.h; sourceTree = ""; }; - 7423362764CF57574BB16CDA /* Window.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Window.h; sourceTree = ""; }; - 74EE403977734BA53DDF16F0 /* core.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = core.h; sourceTree = ""; }; - 753F0B42534106D6545926C8 /* Memoizer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Memoizer.h; sourceTree = ""; }; - 755C2B980C106EA7423E7E5E /* EdgeShape.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = EdgeShape.cpp; sourceTree = ""; }; - 75C0197971FE16926CDA624A /* wrap_RopeJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_RopeJoint.h; sourceTree = ""; }; - 762E57DE65A626FA1F6D4305 /* wrap_PulleyJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_PulleyJoint.h; sourceTree = ""; }; - 77234CEE2EFE633537975850 /* Sound.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Sound.h; sourceTree = ""; }; - 774434E1581A23EC1B0F1E6F /* b2RevoluteJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2RevoluteJoint.h; sourceTree = ""; }; - 777352284E262F48543E6E7F /* Graphics.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Graphics.h; sourceTree = ""; }; - 78073FEB0F54031B1A3A56FD /* wrap_PolygonShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_PolygonShape.h; sourceTree = ""; }; - 780D5B6358096BEB1F1336EE /* b2StackAllocator.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2StackAllocator.cpp; sourceTree = ""; }; - 78115E763B723C0C40AD47CF /* ImageData.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ImageData.cpp; sourceTree = ""; }; - 782A153A1E6314CB583250E0 /* wrap_Decoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Decoder.h; sourceTree = ""; }; - 785D31764A1D6CDE21BC6404 /* SoundData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SoundData.h; sourceTree = ""; }; - 78A2127828793F7A778D7932 /* wrap_Image.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Image.h; sourceTree = ""; }; - 78C0420E2548523B241E3D61 /* b2FrictionJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2FrictionJoint.h; sourceTree = ""; }; - 78E50525407567F863476E27 /* WeldJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WeldJoint.cpp; sourceTree = ""; }; - 79A9038A15A324B450010E8B /* unix.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = unix.h; sourceTree = ""; }; - 7A0A2BB707F44CAD12694679 /* buffer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = buffer.h; sourceTree = ""; }; - 7A3B52AF1FBE73FC36AD50C8 /* wrap_Font.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Font.cpp; sourceTree = ""; }; - 7A5C32955F016AB85EB55519 /* Exception.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Exception.h; sourceTree = ""; }; - 7A707F7A60B47A091107144B /* World.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = World.h; sourceTree = ""; }; - 7A840CB020803B7C6C097CD1 /* b2PulleyJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2PulleyJoint.h; sourceTree = ""; }; - 7B7A47F267D77A570D995658 /* Box2D.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Box2D.h; sourceTree = ""; }; - 7BAB25936D207169591A666A /* wrap_GearJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_GearJoint.h; sourceTree = ""; }; - 7CA02BF51EBA65C263E15250 /* unchecked.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = unchecked.h; sourceTree = ""; }; - 7CC5707C79175FA6427B3D62 /* Audio.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Audio.cpp; sourceTree = ""; }; - 7D48236B78EA06D346A86E3F /* smtp.lua.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = smtp.lua.h; sourceTree = ""; }; - 7D9B03C2438B748D0DE93DD5 /* utf8.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = utf8.cpp; sourceTree = ""; }; - 7E4B280637927B532B456D5E /* Event.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Event.h; sourceTree = ""; }; - 7E7A068041FD553876712F05 /* b2CollideCircle.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2CollideCircle.cpp; sourceTree = ""; }; - 7EC570BC74C369747ED0183A /* Window.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Window.h; sourceTree = ""; }; - 7EFA04373ADC5CC24DCB5824 /* Font.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Font.h; sourceTree = ""; }; - 7F4B2A3860273D89294A44F4 /* b2ContactManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2ContactManager.h; sourceTree = ""; }; - 7F575BE9573C654B5ED44CC1 /* wrap_Timer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Timer.h; sourceTree = ""; }; - 7F796B7A3362196075C62E61 /* wrap_Fixture.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Fixture.cpp; sourceTree = ""; }; - 7F911CF2107B22F44C5B2542 /* b2Collision.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2Collision.h; sourceTree = ""; }; - FA01BE1C1878E35B00640047 /* wrap_Texture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Texture.cpp; sourceTree = ""; }; - FA01BE1D1878E35B00640047 /* wrap_Texture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Texture.h; sourceTree = ""; }; - FA03546A1731F3A700284828 /* simplexnoise1234.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = simplexnoise1234.cpp; sourceTree = ""; }; - FA03546B1731F3A700284828 /* simplexnoise1234.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = simplexnoise1234.h; sourceTree = ""; }; - FA08F5AE16C7525600F007B5 /* Info-Framework.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-Framework.plist"; sourceTree = ""; }; - FA0A4BEE182E0C2800E1E4D2 /* b2MotorJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2MotorJoint.cpp; sourceTree = ""; }; - FA0A4BEF182E0C2800E1E4D2 /* b2MotorJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2MotorJoint.h; sourceTree = ""; }; - FA0A4BF2182E1AD600E1E4D2 /* MotorJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MotorJoint.cpp; sourceTree = ""; }; - FA0A4BF3182E1AD600E1E4D2 /* MotorJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MotorJoint.h; sourceTree = ""; }; - FA0A4BF6182E260200E1E4D2 /* wrap_MotorJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_MotorJoint.cpp; sourceTree = ""; }; - FA0A4BF7182E260200E1E4D2 /* wrap_MotorJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_MotorJoint.h; sourceTree = ""; }; - FA0CDE3B1710F9A50056E8D7 /* FormatHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormatHandler.h; sourceTree = ""; }; - FA34E7CB174B513F00E04D3F /* System.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = System.cpp; sourceTree = ""; }; - FA34E7CC174B513F00E04D3F /* System.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = System.h; sourceTree = ""; }; - FA34E7D0174B515D00E04D3F /* System.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = System.cpp; sourceTree = ""; }; - FA34E7D1174B515D00E04D3F /* System.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = System.h; sourceTree = ""; }; - FA34E7D4174B55AF00E04D3F /* wrap_System.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_System.cpp; sourceTree = ""; }; - FA34E7D5174B55AF00E04D3F /* wrap_System.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_System.h; sourceTree = ""; }; - FA3D9E0B16E68DE600CA6630 /* Cursor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Cursor.cpp; sourceTree = ""; }; - FA3D9E0C16E68DE600CA6630 /* Cursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cursor.h; sourceTree = ""; }; - FA3D9E0F16E68EAE00CA6630 /* Cursor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Cursor.cpp; sourceTree = ""; }; - FA3D9E1016E68EAE00CA6630 /* Cursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cursor.h; sourceTree = ""; }; - FA3D9E1316E6D41000CA6630 /* wrap_Cursor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Cursor.cpp; sourceTree = ""; }; - FA3D9E1416E6D41000CA6630 /* wrap_Cursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Cursor.h; sourceTree = ""; }; - FA435EA117B36E9C004C3F22 /* Polyline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Polyline.cpp; sourceTree = ""; }; - FA435EA217B36E9C004C3F22 /* Polyline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Polyline.h; sourceTree = ""; }; - FA45F770187A0F3600D99ED8 /* Touch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Touch.cpp; sourceTree = ""; }; - FA45F771187A0F3600D99ED8 /* Touch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Touch.h; sourceTree = ""; }; - FA45F772187A0F3600D99ED8 /* Touch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Touch.h; sourceTree = ""; }; - FA45F773187A0F3600D99ED8 /* wrap_Touch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Touch.cpp; sourceTree = ""; }; - FA45F774187A0F3600D99ED8 /* wrap_Touch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Touch.h; sourceTree = ""; }; - FA4DAE651941410D009F0A3E /* PNGHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PNGHandler.cpp; sourceTree = ""; }; - FA4DAE661941410D009F0A3E /* PNGHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PNGHandler.h; sourceTree = ""; }; - FA4DAE671941410D009F0A3E /* STBHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = STBHandler.cpp; sourceTree = ""; }; - FA4DAE681941410D009F0A3E /* STBHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STBHandler.h; sourceTree = ""; }; - FA4DAE6E1941411D009F0A3E /* lodepng.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lodepng.cpp; sourceTree = ""; }; - FA4DAE6F1941411D009F0A3E /* lodepng.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lodepng.h; sourceTree = ""; }; - FA4DAE721941411D009F0A3E /* stb_image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stb_image.h; sourceTree = ""; }; - FA4DAE771941419A009F0A3E /* JPEGHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JPEGHandler.cpp; sourceTree = ""; }; - FA4DAE781941419A009F0A3E /* JPEGHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JPEGHandler.h; sourceTree = ""; }; - FA4DAE7B19414281009F0A3E /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; - FA52E444192AAADE0064D2FF /* PKMHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PKMHandler.cpp; sourceTree = ""; }; - FA52E445192AAADE0064D2FF /* PKMHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PKMHandler.h; sourceTree = ""; }; - FA5454C016F1310000D30303 /* MathModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathModule.cpp; sourceTree = ""; }; - FA5454C116F1310000D30303 /* MathModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathModule.h; sourceTree = ""; }; - FA577A6716C719D900860150 /* FreeType.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FreeType.framework; path = /Library/Frameworks/FreeType.framework; sourceTree = ""; }; - FA577A6916C719DE00860150 /* IL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IL.framework; path = /Library/Frameworks/IL.framework; sourceTree = ""; }; - FA577A6D16C719EA00860150 /* Lua.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Lua.framework; path = /Library/Frameworks/Lua.framework; sourceTree = ""; }; - FA577A6F16C719F000860150 /* mpg123.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mpg123.framework; path = /Library/Frameworks/mpg123.framework; sourceTree = ""; }; - FA577A7116C719F400860150 /* Ogg.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Ogg.framework; path = /Library/Frameworks/Ogg.framework; sourceTree = ""; }; - FA577A7316C719F900860150 /* physfs.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = physfs.framework; path = /Library/Frameworks/physfs.framework; sourceTree = ""; }; - FA577A7716C71A0800860150 /* Vorbis.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Vorbis.framework; path = /Library/Frameworks/Vorbis.framework; sourceTree = ""; }; - FA577A7916C71A1700860150 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; - FA577A7C16C71A2600860150 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = ""; }; - FA577A8216C71A5300860150 /* libmodplug.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = libmodplug.framework; path = /Library/Frameworks/libmodplug.framework; sourceTree = ""; }; - FA577A8516C71CF000860150 /* Shader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Shader.cpp; sourceTree = ""; }; - FA577A8616C71CF000860150 /* Shader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Shader.h; sourceTree = ""; }; - FA577A8716C71CF000860150 /* wrap_Shader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Shader.cpp; sourceTree = ""; }; - FA577A8816C71CF000860150 /* wrap_Shader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Shader.h; sourceTree = ""; }; - FA577A8C16C71D3600860150 /* auto.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = auto.lua; sourceTree = ""; }; - FA577A8D16C71D3600860150 /* boot.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = boot.lua; sourceTree = ""; }; - FA577A8E16C71D3600860150 /* graphics.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = graphics.lua; sourceTree = ""; }; - FA577AAF16C7507900860150 /* love.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = love.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - FA5FDC5F1788D548002F0ED2 /* enet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = enet.cpp; sourceTree = ""; }; - FA5FDC611788D548002F0ED2 /* callbacks.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = callbacks.c; sourceTree = ""; }; - FA5FDC631788D548002F0ED2 /* compress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = compress.c; sourceTree = ""; }; - FA5FDC641788D548002F0ED2 /* host.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = host.c; sourceTree = ""; }; - FA5FDC671788D548002F0ED2 /* callbacks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = callbacks.h; sourceTree = ""; }; - FA5FDC681788D548002F0ED2 /* enet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = enet.h; sourceTree = ""; }; - FA5FDC691788D548002F0ED2 /* list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = list.h; sourceTree = ""; }; - FA5FDC6A1788D548002F0ED2 /* protocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = protocol.h; sourceTree = ""; }; - FA5FDC6B1788D548002F0ED2 /* time.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = time.h; sourceTree = ""; }; - FA5FDC6C1788D548002F0ED2 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = types.h; sourceTree = ""; }; - FA5FDC6D1788D548002F0ED2 /* unix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unix.h; sourceTree = ""; }; - FA5FDC6E1788D548002F0ED2 /* utility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utility.h; sourceTree = ""; }; - FA5FDC6F1788D548002F0ED2 /* win32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = win32.h; sourceTree = ""; }; - FA5FDC711788D548002F0ED2 /* list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = list.c; sourceTree = ""; }; - FA5FDC721788D548002F0ED2 /* packet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = packet.c; sourceTree = ""; }; - FA5FDC731788D548002F0ED2 /* peer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = peer.c; sourceTree = ""; }; - FA5FDC741788D548002F0ED2 /* protocol.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = protocol.c; sourceTree = ""; }; - FA5FDC761788D548002F0ED2 /* unix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = unix.c; sourceTree = ""; }; - FA5FDC771788D548002F0ED2 /* win32.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = win32.c; sourceTree = ""; }; - FA5FDC781788D548002F0ED2 /* lua-enet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "lua-enet.h"; sourceTree = ""; }; - FA61FD5B1926CFCE003AE9FB /* CompressedFormatHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompressedFormatHandler.h; sourceTree = ""; }; - FA61FD5C1926CFCE003AE9FB /* PVRHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PVRHandler.cpp; sourceTree = ""; }; - FA61FD5D1926CFCE003AE9FB /* PVRHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PVRHandler.h; sourceTree = ""; }; - FA636D88171B70920065623F /* RandomGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RandomGenerator.cpp; sourceTree = ""; }; - FA636D89171B70920065623F /* RandomGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RandomGenerator.h; sourceTree = ""; }; - FA636D8C171B72A70065623F /* wrap_RandomGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_RandomGenerator.cpp; sourceTree = ""; }; - FA636D8D171B72A70065623F /* wrap_RandomGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_RandomGenerator.h; sourceTree = ""; }; - FA7175A9178E8418001FE7FE /* lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua.h; sourceTree = ""; }; - FA7AA59017F6AC1F00704BE2 /* wrap_Mesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Mesh.cpp; sourceTree = ""; }; - FA7AA59117F6AC1F00704BE2 /* wrap_Mesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Mesh.h; sourceTree = ""; }; - FA7C937516DCC6C2006F2BEE /* wrap_Math.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Math.cpp; sourceTree = ""; }; - FA7C937616DCC6C2006F2BEE /* wrap_Math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Math.h; sourceTree = ""; }; - FA9A1009182A0D5200106F9F /* glad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = glad.cpp; sourceTree = ""; }; - FA9A100A182A0D5200106F9F /* glad.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = glad.hpp; sourceTree = ""; }; - FA9A100B182A0D5200106F9F /* gladfuncs.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = gladfuncs.hpp; sourceTree = ""; }; - FA9B49281875EFB900201DA9 /* Texture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Texture.h; sourceTree = ""; }; - FA9B4A0716E1578300074F42 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = /Library/Frameworks/SDL2.framework; sourceTree = ""; }; - FA9FC0AE173D6E3E005027FF /* wrap_Window.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Window.cpp; sourceTree = ""; }; - FA9FC0AF173D6E3E005027FF /* wrap_Window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Window.h; sourceTree = ""; }; - FAA627CD18E7E1560080752D /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; }; - FAAC6B00170A373A008A61C5 /* CompressedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CompressedData.cpp; sourceTree = ""; }; - FAAC6B01170A373A008A61C5 /* CompressedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompressedData.h; sourceTree = ""; }; - FAAFF04316CB11C700CCDE45 /* OpenAL-Soft.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "OpenAL-Soft.framework"; path = "/Library/Frameworks/OpenAL-Soft.framework"; sourceTree = ""; }; - FAB0078D1740C12D00A9664D /* Joystick.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Joystick.cpp; sourceTree = ""; }; - FAB0078E1740C12D00A9664D /* Joystick.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Joystick.h; sourceTree = ""; }; - FAB007911740C28900A9664D /* Joystick.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Joystick.cpp; sourceTree = ""; }; - FAB007921740C28900A9664D /* Joystick.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Joystick.h; sourceTree = ""; }; - FAB007951740C87D00A9664D /* wrap_Joystick.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Joystick.cpp; sourceTree = ""; }; - FAB007961740C87D00A9664D /* wrap_Joystick.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Joystick.h; sourceTree = ""; }; - FAC570FC17402D1100D147E4 /* BezierCurve.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BezierCurve.cpp; sourceTree = ""; }; - FAC570FD17402D1100D147E4 /* BezierCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BezierCurve.h; sourceTree = ""; }; - FAC570FE17402D1100D147E4 /* wrap_BezierCurve.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_BezierCurve.cpp; sourceTree = ""; }; - FAC570FF17402D1100D147E4 /* wrap_BezierCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_BezierCurve.h; sourceTree = ""; }; - FAC86E611724552C00EED715 /* wrap_Quad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Quad.cpp; sourceTree = ""; }; - FAC86E621724552C00EED715 /* wrap_Quad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Quad.h; sourceTree = ""; }; - FAC86E671724555D00EED715 /* Quad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Quad.cpp; sourceTree = ""; }; - FAC86E681724555D00EED715 /* Quad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Quad.h; sourceTree = ""; }; - FADD58DC18C30367005FC3BF /* FormatHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FormatHandler.cpp; sourceTree = ""; }; - FAE010D8170DDE99006F29D0 /* ddsinfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ddsinfo.h; sourceTree = ""; }; - FAE010D9170DDE99006F29D0 /* ddsparse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ddsparse.cpp; sourceTree = ""; }; - FAE010DA170DDE99006F29D0 /* ddsparse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ddsparse.h; sourceTree = ""; }; - FAE010DE170DE25E006F29D0 /* ddsHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ddsHandler.cpp; sourceTree = ""; }; - FAE010DF170DE25E006F29D0 /* ddsHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ddsHandler.h; sourceTree = ""; }; - FAE010E2170DF75B006F29D0 /* wrap_CompressedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_CompressedData.cpp; sourceTree = ""; }; - FAE010E3170DF75C006F29D0 /* wrap_CompressedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_CompressedData.h; sourceTree = ""; }; - FAE4043E1927F22C00814481 /* KTXHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KTXHandler.cpp; sourceTree = ""; }; - FAE4043F1927F22C00814481 /* KTXHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KTXHandler.h; sourceTree = ""; }; - FAEC80881710FEA60057279A /* ImageData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageData.cpp; sourceTree = ""; }; - FAEC80891710FEA60057279A /* ImageData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageData.h; sourceTree = ""; }; - FAEC808C1711E76C0057279A /* CompressedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CompressedData.cpp; sourceTree = ""; }; - FAEC808D1711E76C0057279A /* CompressedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompressedData.h; sourceTree = ""; }; - FAF2729816E3D44400CC193A /* Channel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Channel.cpp; sourceTree = ""; }; - FAF2729916E3D44400CC193A /* Channel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Channel.h; sourceTree = ""; }; - FAF2729A16E3D44400CC193A /* LuaThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LuaThread.cpp; sourceTree = ""; }; - FAF2729B16E3D44400CC193A /* LuaThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LuaThread.h; sourceTree = ""; }; - FAF2729C16E3D44400CC193A /* ThreadModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadModule.cpp; sourceTree = ""; }; - FAF2729D16E3D44400CC193A /* ThreadModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadModule.h; sourceTree = ""; }; - FAF2729E16E3D44400CC193A /* wrap_Channel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Channel.cpp; sourceTree = ""; }; - FAF2729F16E3D44400CC193A /* wrap_Channel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Channel.h; sourceTree = ""; }; - FAF272A016E3D44400CC193A /* wrap_LuaThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_LuaThread.cpp; sourceTree = ""; }; - FAF272A116E3D44400CC193A /* wrap_LuaThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_LuaThread.h; sourceTree = ""; }; - FAF272A216E3D44400CC193A /* wrap_ThreadModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_ThreadModule.cpp; sourceTree = ""; }; - FAF272A316E3D44400CC193A /* wrap_ThreadModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_ThreadModule.h; sourceTree = ""; }; - FAF272B116E3D46400CC193A /* Thread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Thread.cpp; sourceTree = ""; }; - FAF272B216E3D46400CC193A /* Thread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Thread.h; sourceTree = ""; }; - FAF272B316E3D46400CC193A /* threads.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = threads.cpp; sourceTree = ""; }; - FAF272B416E3D46400CC193A /* threads.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = threads.h; sourceTree = ""; }; - FAF4376D17F4AC530074F9E2 /* Mesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Mesh.cpp; sourceTree = ""; }; - FAF4376E17F4AC530074F9E2 /* Mesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Mesh.h; sourceTree = ""; }; - FAF6704418184FF800DBDEEA /* wuff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wuff.c; sourceTree = ""; }; - FAF6704518184FF800DBDEEA /* wuff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wuff.h; sourceTree = ""; }; - FAF6704618184FF800DBDEEA /* wuff_config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wuff_config.h; sourceTree = ""; }; - FAF6704718184FF800DBDEEA /* wuff_convert.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wuff_convert.c; sourceTree = ""; }; - FAF6704818184FF800DBDEEA /* wuff_convert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wuff_convert.h; sourceTree = ""; }; - FAF6704918184FF800DBDEEA /* wuff_internal.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wuff_internal.c; sourceTree = ""; }; - FAF6704A18184FF800DBDEEA /* wuff_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wuff_internal.h; sourceTree = ""; }; - FAF6704B18184FF800DBDEEA /* wuff_memory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wuff_memory.c; sourceTree = ""; }; - FAF670541818501300DBDEEA /* WaveDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WaveDecoder.cpp; sourceTree = ""; }; - FAF670551818501300DBDEEA /* WaveDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WaveDecoder.h; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - FA577AAB16C7507900860150 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - FA4DAE7C19414281009F0A3E /* libz.dylib in Frameworks */, - FAA627CE18E7E1560080752D /* CoreServices.framework in Frameworks */, - FA9B4A0816E1578300074F42 /* SDL2.framework in Frameworks */, - FAAFF04416CB11C700CCDE45 /* OpenAL-Soft.framework in Frameworks */, - FA577AB016C7507900860150 /* Cocoa.framework in Frameworks */, - FA577AC216C7512D00860150 /* FreeType.framework in Frameworks */, - FA577AC416C7513200860150 /* IL.framework in Frameworks */, - FA577AC516C7513400860150 /* libmodplug.framework in Frameworks */, - FA577AC716C7513A00860150 /* mpg123.framework in Frameworks */, - FA577AC816C7513C00860150 /* Ogg.framework in Frameworks */, - FA577ACA16C7514100860150 /* OpenGL.framework in Frameworks */, - FA577ACB16C7514400860150 /* physfs.framework in Frameworks */, - FA577ACD16C7514C00860150 /* Vorbis.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 003F4BA82B6046BC133B3F0F /* image */ = { - isa = PBXGroup; - children = ( - FAAC6B00170A373A008A61C5 /* CompressedData.cpp */, - FAAC6B01170A373A008A61C5 /* CompressedData.h */, - 25C325DC2128769F6C6A54C3 /* Image.h */, - 78115E763B723C0C40AD47CF /* ImageData.cpp */, - 07B301984BE42246402F7D27 /* ImageData.h */, - 13730AB030E309FF6E2961F1 /* magpie */, - FAE010E2170DF75B006F29D0 /* wrap_CompressedData.cpp */, - FAE010E3170DF75C006F29D0 /* wrap_CompressedData.h */, - 0B0728FA73B107B37A956A09 /* wrap_Image.cpp */, - 006B015320155B4D42B43B61 /* wrap_Image.h */, - 076840774B0B6E721D0C18D0 /* wrap_ImageData.cpp */, - 31B85B507F466FE158A3718E /* wrap_ImageData.h */, - ); - path = image; - sourceTree = ""; - }; - 02E0744773D13AD65E7C49DC /* thread */ = { - isa = PBXGroup; - children = ( - FAF2729816E3D44400CC193A /* Channel.cpp */, - FAF2729916E3D44400CC193A /* Channel.h */, - FAF2729A16E3D44400CC193A /* LuaThread.cpp */, - FAF2729B16E3D44400CC193A /* LuaThread.h */, - FAF272B016E3D46400CC193A /* sdl */, - 74215662418726B35C581E55 /* Thread.h */, - FAF2729C16E3D44400CC193A /* ThreadModule.cpp */, - FAF2729D16E3D44400CC193A /* ThreadModule.h */, - 6B3565203A1778431F8A5409 /* threads.cpp */, - 55AE226405CC1A55462E1D89 /* threads.h */, - FAF2729E16E3D44400CC193A /* wrap_Channel.cpp */, - FAF2729F16E3D44400CC193A /* wrap_Channel.h */, - FAF272A016E3D44400CC193A /* wrap_LuaThread.cpp */, - FAF272A116E3D44400CC193A /* wrap_LuaThread.h */, - FAF272A216E3D44400CC193A /* wrap_ThreadModule.cpp */, - FAF272A316E3D44400CC193A /* wrap_ThreadModule.h */, - ); - path = thread; - sourceTree = ""; - }; - 07571BBD29A9184E2F465E28 /* common */ = { - isa = PBXGroup; - children = ( - 5D383DA1468545C30E7B5805 /* b64.cpp */, - 0BEB72033ACA25550ADA76C4 /* b64.h */, - 473D2247745F4901155A75DB /* config.h */, - 182A781C7A2D3D2B6B8904A8 /* Data.h */, - 36437CE95936736320710513 /* delay.cpp */, - 24D758D262EA18DC15187A12 /* delay.h */, - 386430B43A081E2A617B05F1 /* EnumMap.h */, - 3746164716797CF80D6B0CEE /* Exception.cpp */, - 7A5C32955F016AB85EB55519 /* Exception.h */, - 40BC14C607396F8B1B084012 /* int.h */, - 52D130DF3DC82D9D4C867B61 /* math.h */, - 0CB6025618505B055A4E75DD /* Matrix.cpp */, - 085B376E3FBB254F0FD37958 /* Matrix.h */, - 40A0593B616A223A4CEF07C9 /* Memoizer.cpp */, - 753F0B42534106D6545926C8 /* Memoizer.h */, - 30E466F441EE727658716873 /* Module.cpp */, - 63024AF52EE3658260BE116B /* Module.h */, - 411B061C49172C971C622125 /* Object.cpp */, - 350C47C774835EA552130431 /* Object.h */, - 35B31EBC4DDB6F994BCA46B6 /* Reference.cpp */, - 2CEC5ED5211174C7583849AD /* Reference.h */, - 45E761A0072E0EF92BD66EA9 /* runtime.cpp */, - 2D8E6FAE2A100B5866E96BFF /* runtime.h */, - 33FD508B0754314530A35EF3 /* StringMap.h */, - 58CD093F254501E37CA47CA8 /* types.h */, - 7D9B03C2438B748D0DE93DD5 /* utf8.cpp */, - 3A430C846C642DBC14975C7C /* utf8.h */, - 3C56375F752B7A9779DD37EC /* Variant.cpp */, - 28016C9B51FE1A893DC35B66 /* Variant.h */, - 1A2A61843B753E3F5B330703 /* Vector.cpp */, - 3D8460B2486A372825213933 /* Vector.h */, - 57E6429235C547BE26B73C6C /* version.h */, - 5ED732200E1B2E5F79831DDA /* wrap_Data.cpp */, - 001F02BC119E349012652C17 /* wrap_Data.h */, - ); - name = common; - path = ../../src/common; - sourceTree = ""; - }; - 09000F404D44660029EF38F0 /* sdl */ = { - isa = PBXGroup; - children = ( - 3BA712260D725FEB72EB3CDE /* Event.cpp */, - 7E4B280637927B532B456D5E /* Event.h */, - 691C5C5828550E2F60754EF2 /* wrap_Event.cpp */, - 295C665B1E0B6B2D03CC4937 /* wrap_Event.h */, - ); - path = sdl; - sourceTree = ""; - }; - 12BB56F127170B3709670896 /* freetype */ = { - isa = PBXGroup; - children = ( - 714251EE742346DC17103357 /* Font.cpp */, - 615E0F450F2B7BA25EE679A6 /* Font.h */, - 0C30420F7FD3038C721223A5 /* TrueTypeRasterizer.cpp */, - 0B727D416262392743091BC3 /* TrueTypeRasterizer.h */, - 232D67C67BEE54B776420682 /* wrap_Font.cpp */, - 202650DE4F267CD3082A1B30 /* wrap_Font.h */, - ); - path = freetype; - sourceTree = ""; - }; - 130737AF4BD12D0356A65C87 /* mouse */ = { - isa = PBXGroup; - children = ( - FA3D9E0B16E68DE600CA6630 /* Cursor.cpp */, - FA3D9E0C16E68DE600CA6630 /* Cursor.h */, - 31E0110E5797041465FF5F95 /* Mouse.cpp */, - 63A63DFB339266AC401B545A /* Mouse.h */, - 1E017A8673D531394B5A3B16 /* sdl */, - FA3D9E1316E6D41000CA6630 /* wrap_Cursor.cpp */, - FA3D9E1416E6D41000CA6630 /* wrap_Cursor.h */, - 22EF17981EBD442773FE41B6 /* wrap_Mouse.cpp */, - 4E972C114A6C25A63B5B6EF2 /* wrap_Mouse.h */, - ); - path = mouse; - sourceTree = ""; - }; - 1350109F709C227D4AFD423C /* libluasocket */ = { - isa = PBXGroup; - children = ( - FA7175A9178E8418001FE7FE /* lua.h */, - 1CD02D1975803957282F28AB /* auxiliar.c */, - 1F6F652A57F8098E5CCA6F9A /* auxiliar.h */, - 21B25A7E333315172B754D4F /* buffer.c */, - 7A0A2BB707F44CAD12694679 /* buffer.h */, - 49496EAF3305281B19223C22 /* except.c */, - 17C730CB1DA01B8F0A11217C /* except.h */, - 048C39D14DA05F5843FE08CA /* ftp.lua.h */, - 16C36B3C59A10CDC7ACE0DD4 /* http.lua.h */, - 610B475400DE0F7213352BC3 /* inet.c */, - 459946CA7F4406B026E80501 /* inet.h */, - 135801A6483528800C676492 /* io.c */, - 4ABD4A7B5CB6678E39490982 /* io.h */, - 53C6151E07FB1E3471590CB9 /* ltn12.lua.h */, - 5FAE2A9679C97F2C2792182D /* luasocket.c */, - 329915E84B0B6D025DDC34A9 /* luasocket.h */, - 00393E4930202C2B6E381F68 /* mime.c */, - 485645C663D372A96DFD33F7 /* mime.h */, - 54E653E84E8873D467C750FC /* mime.lua.h */, - 5F846B49240D52C10F6F76E5 /* options.c */, - 249015D170563D85709D7B6D /* options.h */, - 415E1438178736BE0EA908D5 /* select.c */, - 17E9544103AE376210ED5BAA /* select.h */, - 7D48236B78EA06D346A86E3F /* smtp.lua.h */, - 09C71F9D7DC45F5765B2462B /* socket.h */, - 66F8479E6D2D587A592F2024 /* socket.lua.h */, - 22256CC12B7C7D0D1B430D46 /* tcp.c */, - 00D329851B1E7F6A3AF9614E /* tcp.h */, - 4B41232F7AF7793540F46C58 /* timeout.c */, - 1CE84F1F19BC2AA412C638B1 /* timeout.h */, - 6E682862758051BF7C0A10AA /* tp.lua.h */, - 2E2675AF3DAA24CE0728042C /* udp.c */, - 2CAE75B079B828FE6892684A /* udp.h */, - 734947AA28AF36E436D242FD /* unix.c */, - 79A9038A15A324B450010E8B /* unix.h */, - 4B002CBD52493ED9347C6EBA /* url.lua.h */, - 041672ED2CF51FC62F532FDB /* usocket.c */, - 63936FF81D4E14F6534A43BB /* usocket.h */, - ); - path = libluasocket; - sourceTree = ""; - }; - 13730AB030E309FF6E2961F1 /* magpie */ = { - isa = PBXGroup; - children = ( - FAEC808C1711E76C0057279A /* CompressedData.cpp */, - FAEC808D1711E76C0057279A /* CompressedData.h */, - FA61FD5B1926CFCE003AE9FB /* CompressedFormatHandler.h */, - FAE010DE170DE25E006F29D0 /* ddsHandler.cpp */, - FAE010DF170DE25E006F29D0 /* ddsHandler.h */, - 1AA7781A230065F346E2313A /* DevilHandler.cpp */, - 283342E174613897621A43F1 /* DevilHandler.h */, - FADD58DC18C30367005FC3BF /* FormatHandler.cpp */, - FA0CDE3B1710F9A50056E8D7 /* FormatHandler.h */, - 505F23A73BFE250833D650E4 /* Image.cpp */, - 68616BD516DB124312B47EB3 /* Image.h */, - FAEC80881710FEA60057279A /* ImageData.cpp */, - FAEC80891710FEA60057279A /* ImageData.h */, - FA4DAE771941419A009F0A3E /* JPEGHandler.cpp */, - FA4DAE781941419A009F0A3E /* JPEGHandler.h */, - FAE4043E1927F22C00814481 /* KTXHandler.cpp */, - FAE4043F1927F22C00814481 /* KTXHandler.h */, - FA52E444192AAADE0064D2FF /* PKMHandler.cpp */, - FA52E445192AAADE0064D2FF /* PKMHandler.h */, - FA4DAE651941410D009F0A3E /* PNGHandler.cpp */, - FA4DAE661941410D009F0A3E /* PNGHandler.h */, - FA61FD5C1926CFCE003AE9FB /* PVRHandler.cpp */, - FA61FD5D1926CFCE003AE9FB /* PVRHandler.h */, - FA4DAE671941410D009F0A3E /* STBHandler.cpp */, - FA4DAE681941410D009F0A3E /* STBHandler.h */, - ); - path = magpie; - sourceTree = ""; - }; - 153D76205F7A4ACD12FB4C0E /* window */ = { - isa = PBXGroup; - children = ( - 63082CBA23A6046C60DA1C6F /* sdl */, - 351B09E51FDC338622F44624 /* Window.cpp */, - 7423362764CF57574BB16CDA /* Window.h */, - FA9FC0AE173D6E3E005027FF /* wrap_Window.cpp */, - FA9FC0AF173D6E3E005027FF /* wrap_Window.h */, - ); - path = window; - sourceTree = ""; - }; - 18AF317B298302545C386404 /* Dynamics */ = { - isa = PBXGroup; - children = ( - 7DE032B3334E559969264529 /* Contacts */, - 68027AB25AAF234679615C14 /* Joints */, - 120B391518206E964493126C /* b2Body.cpp */, - 079504CB332E415D4B27797B /* b2Body.h */, - 2A6150F7479D21346EC54B68 /* b2ContactManager.cpp */, - 7F4B2A3860273D89294A44F4 /* b2ContactManager.h */, - 059C04C13F3A7C05570F2987 /* b2Fixture.cpp */, - 50F0575E16561864699E41F5 /* b2Fixture.h */, - 59BE634A2ACE722F14B86F89 /* b2Island.cpp */, - 5100177E5D8A14366C5B0BC5 /* b2Island.h */, - 6D822D830EF049417D184372 /* b2TimeStep.h */, - 0D6F00D95C4407BB26E71E02 /* b2World.cpp */, - 325E60A57F2624766A524423 /* b2World.h */, - 0F8D03F1544476B57CA97B01 /* b2WorldCallbacks.cpp */, - 4F3E12BD4A646D0366792FC9 /* b2WorldCallbacks.h */, - ); - path = Dynamics; - sourceTree = ""; - }; - 196B6B2E1BC81F47771E6467 /* font */ = { - isa = PBXGroup; - children = ( - 2E9B5D9926034F9172215D5E /* Font.h */, - 12BB56F127170B3709670896 /* freetype */, - 74003CB27FA762A021183AD5 /* GlyphData.cpp */, - 112814480BBF2ED06EED15BF /* GlyphData.h */, - 5D016F4C27EF506C13FE3058 /* ImageRasterizer.cpp */, - 36465ABA28FB06F4333C3F07 /* ImageRasterizer.h */, - 1B1C4E4D288A1D2F29E57B1B /* Rasterizer.cpp */, - 08D24B70441A2496160C0849 /* Rasterizer.h */, - 1B4E22F1388E2B2E76E3377B /* wrap_GlyphData.cpp */, - 3547706F2E7D43212CB40D04 /* wrap_GlyphData.h */, - 11745DE315E859F71E881D76 /* wrap_Rasterizer.cpp */, - 37224F6B30CA5D800B1F41F1 /* wrap_Rasterizer.h */, - ); - path = font; - sourceTree = ""; - }; - 1E017A8673D531394B5A3B16 /* sdl */ = { - isa = PBXGroup; - children = ( - FA3D9E0F16E68EAE00CA6630 /* Cursor.cpp */, - FA3D9E1016E68EAE00CA6630 /* Cursor.h */, - 584E16AE09E12536206C46FE /* Mouse.cpp */, - 198A44BD71BB61EE517C2A39 /* Mouse.h */, - ); - path = sdl; - sourceTree = ""; - }; - 20A8288624E9654322DC388D /* sdl */ = { - isa = PBXGroup; - children = ( - 43BC2B1C505E5EFF650C31E3 /* Keyboard.cpp */, - 057A3770539D25AE6C8F20D3 /* Keyboard.h */, - ); - path = sdl; - sourceTree = ""; - }; - 264B1FF46F2C68D26B7B158D /* openal */ = { - isa = PBXGroup; - children = ( - 6CB1193233FA78EE646A17A1 /* Audio.cpp */, - 1916112F57AF56A173727464 /* Audio.h */, - 601E6A56345412E87E1D396B /* Pool.cpp */, - 62E121F35BEB622029324F25 /* Pool.h */, - 28024635525B077E08A73D9B /* Source.cpp */, - 5B3306B5587A708557EE4D4F /* Source.h */, - ); - path = openal; - sourceTree = ""; - }; - 2F654C0235EB60C744A22507 /* Products */ = { - isa = PBXGroup; - children = ( - FA577AAF16C7507900860150 /* love.framework */, - ); - name = Products; - sourceTree = ""; - }; - 34067FA94AEA4D7C3E103A64 /* box2d */ = { - isa = PBXGroup; - children = ( - 089B1AC1248B21D336594457 /* Body.cpp */, - 6E6D5AB27B71488D405526C3 /* Body.h */, - 0959542C4B54320B1DDD5911 /* ChainShape.cpp */, - 1AA213FC158815FA77C40330 /* ChainShape.h */, - 4DAB28A9235E2CBE75F56848 /* CircleShape.cpp */, - 3C965422252F672D3FF6598C /* CircleShape.h */, - 02CD63315FF902E336AB4657 /* Contact.cpp */, - 5D590ACE5E237B7D5B556AD0 /* Contact.h */, - 34A36BB617BC5CCA5B870EA6 /* DistanceJoint.cpp */, - 457674E43FF71E974D990C00 /* DistanceJoint.h */, - 755C2B980C106EA7423E7E5E /* EdgeShape.cpp */, - 561D4A4722E36BAA16D17CC8 /* EdgeShape.h */, - 47C77F6032FA77E046AA6810 /* Fixture.cpp */, - 60840050412A459D5D21518F /* Fixture.h */, - 1E22646A710E5EFC27FE3932 /* FrictionJoint.cpp */, - 45DC20A760FC42341E5762F7 /* FrictionJoint.h */, - 6F4D478A52A0408765095920 /* GearJoint.cpp */, - 25CE236F66F70EB3444A7CC8 /* GearJoint.h */, - 3EA80A4E0CE0014052076037 /* Joint.cpp */, - 138913BE5126483748FA43D0 /* Joint.h */, - FA0A4BF2182E1AD600E1E4D2 /* MotorJoint.cpp */, - FA0A4BF3182E1AD600E1E4D2 /* MotorJoint.h */, - 3C0B06AF6B5326C840477B18 /* MouseJoint.cpp */, - 208275724C9421035EA145A4 /* MouseJoint.h */, - 370D76DC224F2EB300CB4E2F /* Physics.cpp */, - 5CE370672B1234B10F9532FA /* Physics.h */, - 54E85987318206E93DC8189F /* PolygonShape.cpp */, - 2FF26CC52C28773750B812D9 /* PolygonShape.h */, - 0AE5755936E84C247FB56C65 /* PrismaticJoint.cpp */, - 104D5534669B772556942891 /* PrismaticJoint.h */, - 5CB720BA493D7D995E0E20DD /* PulleyJoint.cpp */, - 0A936C83344E2CF84E703059 /* PulleyJoint.h */, - 36DD053F754B2D29719B1F80 /* RevoluteJoint.cpp */, - 5CE0167703887B376F2368FD /* RevoluteJoint.h */, - 53C4064801456193163E4631 /* RopeJoint.cpp */, - 4F34010A575C02E66D400CE2 /* RopeJoint.h */, - 61E64F07028039774F502D69 /* Shape.cpp */, - 0EB870A1180261FD424A41B3 /* Shape.h */, - 78E50525407567F863476E27 /* WeldJoint.cpp */, - 465D0438379342C4589E2B1C /* WeldJoint.h */, - 44DE79C879CC0074510A2403 /* WheelJoint.cpp */, - 6AA03CE31B942DC660045FE9 /* WheelJoint.h */, - 644D0C953C3439FC57C03FC6 /* World.cpp */, - 7A707F7A60B47A091107144B /* World.h */, - 64694F91593478085859666F /* wrap_Body.cpp */, - 1A311FC16B9C0F8D7A41580E /* wrap_Body.h */, - 1CAA69E00D0808BA2108238B /* wrap_ChainShape.cpp */, - 70564CC32DEC209F2A615F44 /* wrap_ChainShape.h */, - 6EF321185C2B1F1E1AF54F64 /* wrap_CircleShape.cpp */, - 15093E1B1A14176374C81299 /* wrap_CircleShape.h */, - 3BB22A142670197B0DBD0BED /* wrap_Contact.cpp */, - 21E975B81E8D701F2147658C /* wrap_Contact.h */, - 69967D2323404E1F0ED21F11 /* wrap_DistanceJoint.cpp */, - 18E0492204644DE929B96486 /* wrap_DistanceJoint.h */, - 40F412FF29F65F5A3D511B98 /* wrap_EdgeShape.cpp */, - 276C3474657D0A246F64221C /* wrap_EdgeShape.h */, - 7F796B7A3362196075C62E61 /* wrap_Fixture.cpp */, - 5F1F169C7FC633EF292E26DF /* wrap_Fixture.h */, - 340345481F165F8945C716AE /* wrap_FrictionJoint.cpp */, - 0EA87794395D3B287C5949AA /* wrap_FrictionJoint.h */, - 50B67F2D0CC511706810302E /* wrap_GearJoint.cpp */, - 7BAB25936D207169591A666A /* wrap_GearJoint.h */, - 71810207414B52F8340D7797 /* wrap_Joint.cpp */, - 047815B73C1C5373551442A6 /* wrap_Joint.h */, - FA0A4BF6182E260200E1E4D2 /* wrap_MotorJoint.cpp */, - FA0A4BF7182E260200E1E4D2 /* wrap_MotorJoint.h */, - 4D81102E7ABD1C282BE42CE3 /* wrap_MouseJoint.cpp */, - 64BA1CE328FF17144B475111 /* wrap_MouseJoint.h */, - 6CEB48E969FC42C53F9432B1 /* wrap_Physics.cpp */, - 71C579A557640A3E2A696518 /* wrap_Physics.h */, - 3AD03C7A77C546ED07BE4C06 /* wrap_PolygonShape.cpp */, - 78073FEB0F54031B1A3A56FD /* wrap_PolygonShape.h */, - 0B4020CD058D70F569DF6129 /* wrap_PrismaticJoint.cpp */, - 2B8C245A21A515E86636725A /* wrap_PrismaticJoint.h */, - 1E840AF84AB61C6410E26634 /* wrap_PulleyJoint.cpp */, - 762E57DE65A626FA1F6D4305 /* wrap_PulleyJoint.h */, - 1F3A277A44141DBF7BCF146A /* wrap_RevoluteJoint.cpp */, - 2912092853050AF9785F39BE /* wrap_RevoluteJoint.h */, - 0E3E13BC3E3A7C0C7DBE7DF8 /* wrap_RopeJoint.cpp */, - 75C0197971FE16926CDA624A /* wrap_RopeJoint.h */, - 124E716E0BCA055534A60AD2 /* wrap_Shape.cpp */, - 02F064F5202E34F5718352B8 /* wrap_Shape.h */, - 3DFF31EE26405E554C610C8F /* wrap_WeldJoint.cpp */, - 131F69C3368C4B8A55EE0DAD /* wrap_WeldJoint.h */, - 73473B3C698B538002540A5D /* wrap_WheelJoint.cpp */, - 0AFB7DA45B2D6913110A5AAB /* wrap_WheelJoint.h */, - 36324E12371E518E6E9C61B5 /* wrap_World.cpp */, - 27F777AB188D674F30BC1829 /* wrap_World.h */, - ); - path = box2d; - sourceTree = ""; - }; - 352E6C5F6F8A681766EB5299 /* scripts */ = { - isa = PBXGroup; - children = ( - FA577A8C16C71D3600860150 /* auto.lua */, - FA577A8D16C71D3600860150 /* boot.lua */, - 503971A86B7167A91B670FBA /* boot.lua.h */, - FA577A8E16C71D3600860150 /* graphics.lua */, - 104144AB73A974BC04A03131 /* graphics.lua.h */, - ); - name = scripts; - path = ../../src/scripts; - sourceTree = ""; - }; - 36C14C81334735EC54E33637 /* utf8 */ = { - isa = PBXGroup; - children = ( - 5CB1063C6DF04E2E409F2DB0 /* utf8 */, - 1BCD6EE50EB8791E5A870135 /* utf8.h */, - ); - path = utf8; - sourceTree = ""; - }; - 36DA23075AF92B22676D34C9 /* audio */ = { - isa = PBXGroup; - children = ( - 1839744763625B5D64EC70AC /* Audio.cpp */, - 24EE059E03D8155F4BFF64D6 /* Audio.h */, - 7DB6750C1F01062849171B8B /* null */, - 264B1FF46F2C68D26B7B158D /* openal */, - 2FB732687B1669402408356D /* Source.cpp */, - 46CA2B6B17C32BBE55772268 /* Source.h */, - 02CA1BE908D91B104EB9590F /* wrap_Audio.cpp */, - 5FF97D522B8872947DED611C /* wrap_Audio.h */, - 02662CBC29B954295A634A39 /* wrap_Source.cpp */, - 330F59B11A5B5D1B44DC07BF /* wrap_Source.h */, - ); - path = audio; - sourceTree = ""; - }; - 3AED1DE005A53DDB07902760 /* luasocket */ = { - isa = PBXGroup; - children = ( - 1350109F709C227D4AFD423C /* libluasocket */, - 2DC90F3C6160198256795C75 /* luasocket.cpp */, - 6B2E52E6185E6980660F1374 /* luasocket.h */, - ); - path = luasocket; - sourceTree = ""; - }; - 3D490B3A36B935BD14B05986 /* Collision */ = { - isa = PBXGroup; - children = ( - 7BC957592F43649453A57B23 /* Shapes */, - 4B5F4DF8110020A96B5D3EAB /* b2BroadPhase.cpp */, - 32FD3FEE52FD1911405B3C59 /* b2BroadPhase.h */, - 7E7A068041FD553876712F05 /* b2CollideCircle.cpp */, - 1B036C7C5A8832AE53BB1C06 /* b2CollideEdge.cpp */, - 427B4B2517C0516844370E3D /* b2CollidePolygon.cpp */, - 32CC11481CD9164455455D72 /* b2Collision.cpp */, - 7F911CF2107B22F44C5B2542 /* b2Collision.h */, - 175A1B8D733B2D4803F64AC1 /* b2Distance.cpp */, - 034144EE6C33421377674516 /* b2Distance.h */, - 59D27EA33E8E62E15C185948 /* b2DynamicTree.cpp */, - 11CF30E73CEA2D8D0A1B17D3 /* b2DynamicTree.h */, - 1F0D375C38A245E403E53DB5 /* b2TimeOfImpact.cpp */, - 1C5B57F87B315E39005B119F /* b2TimeOfImpact.h */, - ); - path = Collision; - sourceTree = ""; - }; - 47217E6729AC72E74FF651E3 /* lullaby */ = { - isa = PBXGroup; - children = ( - 4E15567759041CC379292BE6 /* Decoder.cpp */, - 733758E8028B20BB799A7BE6 /* Decoder.h */, - 4A774BC26B7235E410D40C8E /* FLACDecoder.cpp */, - 3C9253C8152355E1274814B7 /* FLACDecoder.h */, - 02F0197227150E1B28D9425B /* GmeDecoder.cpp */, - 64AC15B600F2473651823D40 /* GmeDecoder.h */, - 407422E8589417B6683D1042 /* ModPlugDecoder.cpp */, - 31C84D0129AE5F6044A94AC2 /* ModPlugDecoder.h */, - 1F875B224C4E1B9E35854766 /* Mpg123Decoder.cpp */, - 6B255FFC4A2C404E50512CB5 /* Mpg123Decoder.h */, - 2A5F7DCB40652F9B7D61073A /* Sound.cpp */, - 77234CEE2EFE633537975850 /* Sound.h */, - 727648E06CD863A2582F798F /* VorbisDecoder.cpp */, - 4A80315175C5625804AA4A56 /* VorbisDecoder.h */, - FAF670541818501300DBDEEA /* WaveDecoder.cpp */, - FAF670551818501300DBDEEA /* WaveDecoder.h */, - ); - path = lullaby; - sourceTree = ""; - }; - 48DE0A5A52042D0361883E40 /* libraries */ = { - isa = PBXGroup; - children = ( - 63287ED84D0F2EEB65D249A3 /* Box2D */, - FAE010D7170DDE99006F29D0 /* ddsparse */, - FA5FDC5E1788D548002F0ED2 /* enet */, - FA9A1008182A0D5200106F9F /* glad */, - FA4DAE6D1941411D009F0A3E /* lodepng */, - 3AED1DE005A53DDB07902760 /* luasocket */, - FA0354691731F3A700284828 /* noise1234 */, - FA4DAE701941411D009F0A3E /* stb */, - 36C14C81334735EC54E33637 /* utf8 */, - FAF6704318184FF800DBDEEA /* Wuff */, - ); - name = libraries; - path = ../../src/libraries; - sourceTree = ""; - }; - 4BAB08EE4A6B4A1A01DA50A4 /* sound */ = { - isa = PBXGroup; - children = ( - 43A258C229C75C15238E520C /* Decoder.h */, - 47217E6729AC72E74FF651E3 /* lullaby */, - 30ED4BB03C5F11254AF12E98 /* Sound.cpp */, - 23985AB32E7B463A2CB87E2C /* Sound.h */, - 0C5C6C6E47851D1308411DE6 /* SoundData.cpp */, - 785D31764A1D6CDE21BC6404 /* SoundData.h */, - 5CF629B94C7802D446D61C45 /* wrap_Decoder.cpp */, - 782A153A1E6314CB583250E0 /* wrap_Decoder.h */, - 385902BD584E7D73154E4EBB /* wrap_Sound.cpp */, - 3960064616E26C0213E323E2 /* wrap_Sound.h */, - 4DC3617831763D2760335D87 /* wrap_SoundData.cpp */, - 5B5A0BEC36BE007E6E491396 /* wrap_SoundData.h */, - ); - path = sound; - sourceTree = ""; - }; - 4E2517690E6C64EB07D164F7 /* event */ = { - isa = PBXGroup; - children = ( - 24265680279E30A40DF81946 /* Event.cpp */, - 4F1862D324C9429157A27A2E /* Event.h */, - 09000F404D44660029EF38F0 /* sdl */, - ); - path = event; - sourceTree = ""; - }; - 501126AD67DC2A4B527654EA /* joystick */ = { - isa = PBXGroup; - children = ( - FAB0078D1740C12D00A9664D /* Joystick.cpp */, - FAB0078E1740C12D00A9664D /* Joystick.h */, - 4C606AEC342457600C3F0741 /* JoystickModule.h */, - 687216AD6FA406C838284B91 /* sdl */, - FAB007951740C87D00A9664D /* wrap_Joystick.cpp */, - FAB007961740C87D00A9664D /* wrap_Joystick.h */, - 139411436818381E493F00F5 /* wrap_JoystickModule.cpp */, - 2D7B7DEC4FC87878332E41B3 /* wrap_JoystickModule.h */, - ); - path = joystick; - sourceTree = ""; - }; - 54067CFB7D564E5764FA17DC /* love */ = { - isa = PBXGroup; - children = ( - 07571BBD29A9184E2F465E28 /* common */, - 48DE0A5A52042D0361883E40 /* libraries */, - 548A533617C45319431D3ECF /* modules */, - 352E6C5F6F8A681766EB5299 /* scripts */, - FA577A6616C7199700860150 /* Frameworks */, - FA08F5AC16C751BA00F007B5 /* Resources */, - 2F654C0235EB60C744A22507 /* Products */, - ); - name = love; - sourceTree = ""; - usesTabs = 1; - }; - 548A533617C45319431D3ECF /* modules */ = { - isa = PBXGroup; - children = ( - 36DA23075AF92B22676D34C9 /* audio */, - 4E2517690E6C64EB07D164F7 /* event */, - 7B0734182055607468261A5E /* filesystem */, - 196B6B2E1BC81F47771E6467 /* font */, - 586900D11BD011D949F45D7D /* graphics */, - 003F4BA82B6046BC133B3F0F /* image */, - 501126AD67DC2A4B527654EA /* joystick */, - 752A4B4672B6166A2CA30E85 /* keyboard */, - 70C250C41ADF59C0697925C2 /* love */, - FA7C937116DCC6C2006F2BEE /* math */, - 130737AF4BD12D0356A65C87 /* mouse */, - 67F10C1D58A96C1C53563B5C /* physics */, - 4BAB08EE4A6B4A1A01DA50A4 /* sound */, - FA34E7CA174B512200E04D3F /* system */, - 02E0744773D13AD65E7C49DC /* thread */, - 6D590DDD41E72A60262E4A4F /* timer */, - FA45F76E187A0F3600D99ED8 /* touch */, - 153D76205F7A4ACD12FB4C0E /* window */, - ); - name = modules; - path = ../../src/modules; - sourceTree = ""; - }; - 586900D11BD011D949F45D7D /* graphics */ = { - isa = PBXGroup; - children = ( - 4941079838020ECA049B5C21 /* Color.h */, - 5D93601669875EE06721689E /* Drawable.h */, - 03F17FF546D637744E263961 /* Graphics.cpp */, - 777352284E262F48543E6E7F /* Graphics.h */, - 75093EE94918576801F50993 /* opengl */, - FAC86E671724555D00EED715 /* Quad.cpp */, - FAC86E681724555D00EED715 /* Quad.h */, - 58CC50E70A375FDF53EF01B6 /* Texture.cpp */, - 1DA41DFF0869489411A71AFC /* Texture.h */, - 4B731754147B27AF73AC5358 /* Volatile.cpp */, - 0CFF64090F0F4F481BB80CF0 /* Volatile.h */, - ); - path = graphics; - sourceTree = ""; - }; - 59207AEF0DE97A632CE30FE6 /* Rope */ = { - isa = PBXGroup; - children = ( - 4832527C02C105776536438A /* b2Rope.cpp */, - 1A95437F513E662113AC154A /* b2Rope.h */, - ); - path = Rope; - sourceTree = ""; - }; - 5CB1063C6DF04E2E409F2DB0 /* utf8 */ = { - isa = PBXGroup; - children = ( - 3C4D70E82FC12A9A15EC39BA /* checked.h */, - 74EE403977734BA53DDF16F0 /* core.h */, - 7CA02BF51EBA65C263E15250 /* unchecked.h */, - ); - path = utf8; - sourceTree = ""; - }; - 5CFF12567FFB5C5166631693 /* sdl */ = { - isa = PBXGroup; - children = ( - 113269E55FCF208D2D6754BC /* Timer.cpp */, - 6BEE6511475F641A70A0591E /* Timer.h */, - ); - path = sdl; - sourceTree = ""; - }; - 63082CBA23A6046C60DA1C6F /* sdl */ = { - isa = PBXGroup; - children = ( - 6CDD4F3320303D222C180CD0 /* Window.cpp */, - 7EC570BC74C369747ED0183A /* Window.h */, - ); - path = sdl; - sourceTree = ""; - }; - 63287ED84D0F2EEB65D249A3 /* Box2D */ = { - isa = PBXGroup; - children = ( - 7B7A47F267D77A570D995658 /* Box2D.h */, - 3D490B3A36B935BD14B05986 /* Collision */, - 71F67B4A51CC637C6D113715 /* Common */, - 18AF317B298302545C386404 /* Dynamics */, - 59207AEF0DE97A632CE30FE6 /* Rope */, - ); - path = Box2D; - sourceTree = ""; - }; - 64DD03B45BF6265723662DAF /* physfs */ = { - isa = PBXGroup; - children = ( - 4E0F565B03D05C3722496F27 /* File.cpp */, - 47D46915001F342A3CD23E86 /* File.h */, - 6DE3129F3A0B2D9C178118F3 /* Filesystem.cpp */, - 219636CF6780074F7871463D /* Filesystem.h */, - ); - path = physfs; - sourceTree = ""; - }; - 67F10C1D58A96C1C53563B5C /* physics */ = { - isa = PBXGroup; - children = ( - 2DCE45C868A0091B762C7377 /* Body.cpp */, - 286660042F9654F61AB90D7A /* Body.h */, - 69DB4423147C7E3362941E75 /* Joint.cpp */, - 065364DB7A29396C777213D0 /* Joint.h */, - 70F425B5336E1CD652827FD0 /* Shape.cpp */, - 00744BD73BFE3F591537728F /* Shape.h */, - 34067FA94AEA4D7C3E103A64 /* box2d */, - ); - path = physics; - sourceTree = ""; - }; - 68027AB25AAF234679615C14 /* Joints */ = { - isa = PBXGroup; - children = ( - 33627AE97E66147E76804EF9 /* b2DistanceJoint.cpp */, - 086B4A4E025B4B5F606747A2 /* b2DistanceJoint.h */, - 13093ADC78426C5009DF3B13 /* b2FrictionJoint.cpp */, - 78C0420E2548523B241E3D61 /* b2FrictionJoint.h */, - 69A01D71103275D451F965B2 /* b2GearJoint.cpp */, - 6590063A6E4B3AEF4550443C /* b2GearJoint.h */, - 6F1B61350B6B36AF216C57D7 /* b2Joint.cpp */, - 10F83B5848B77A937C250FEB /* b2Joint.h */, - FA0A4BEE182E0C2800E1E4D2 /* b2MotorJoint.cpp */, - FA0A4BEF182E0C2800E1E4D2 /* b2MotorJoint.h */, - 4A47384208BE218F688C4EFA /* b2MouseJoint.cpp */, - 0AA1539E66B2641B66130709 /* b2MouseJoint.h */, - 1E27263847302FCA1F843B47 /* b2PrismaticJoint.cpp */, - 64491E98483728D601110EF0 /* b2PrismaticJoint.h */, - 66EC3C0463A703A97445193B /* b2PulleyJoint.cpp */, - 7A840CB020803B7C6C097CD1 /* b2PulleyJoint.h */, - 11D62E873092729B497B447F /* b2RevoluteJoint.cpp */, - 774434E1581A23EC1B0F1E6F /* b2RevoluteJoint.h */, - 38AF72D4790619BB022E2AEF /* b2RopeJoint.cpp */, - 2C970EA7229F20934C72581D /* b2RopeJoint.h */, - 5BCC49F529F726385CD41FA6 /* b2WeldJoint.cpp */, - 2D290E902C451D6849051FEF /* b2WeldJoint.h */, - 0602250B7E4664E43CA113DC /* b2WheelJoint.cpp */, - 23A266CD4FC729355E23606E /* b2WheelJoint.h */, - ); - path = Joints; - sourceTree = ""; - }; - 687216AD6FA406C838284B91 /* sdl */ = { - isa = PBXGroup; - children = ( - FAB007911740C28900A9664D /* Joystick.cpp */, - FAB007921740C28900A9664D /* Joystick.h */, - 55B425307C0C1C4B3EFC3A5F /* JoystickModule.cpp */, - 439E46D768A266780E894800 /* JoystickModule.h */, - ); - path = sdl; - sourceTree = ""; - }; - 6D590DDD41E72A60262E4A4F /* timer */ = { - isa = PBXGroup; - children = ( - 5CFF12567FFB5C5166631693 /* sdl */, - 2D9475890CDA3D3776435622 /* Timer.h */, - 695E4ED13AA0689E64280573 /* wrap_Timer.cpp */, - 7F575BE9573C654B5ED44CC1 /* wrap_Timer.h */, - ); - path = timer; - sourceTree = ""; - }; - 70C250C41ADF59C0697925C2 /* love */ = { - isa = PBXGroup; - children = ( - 19ED419874B46EC16F927524 /* love.cpp */, - 10A608C96F067F972C962EFB /* love.h */, - ); - path = love; - sourceTree = ""; - }; - 71F67B4A51CC637C6D113715 /* Common */ = { - isa = PBXGroup; - children = ( - 55A759CE711E157339930E58 /* b2BlockAllocator.cpp */, - 0F0E666B7C790BB870477994 /* b2BlockAllocator.h */, - 12390CBC115B00D06EF951DD /* b2Draw.cpp */, - 343E66751EBA75264C3400FA /* b2Draw.h */, - 3AC7627D7E1458AA0D8E0522 /* b2GrowableStack.h */, - 2C78323D7D5C628A53EC6931 /* b2Math.cpp */, - 0A0A2DA4094130187F655E52 /* b2Math.h */, - 6FF15DF4423F6426224024C9 /* b2Settings.cpp */, - 090F537B70DA06EA0B29593F /* b2Settings.h */, - 780D5B6358096BEB1F1336EE /* b2StackAllocator.cpp */, - 567C0A0C58931DE54733011B /* b2StackAllocator.h */, - 239054AE7475433E39747DA9 /* b2Timer.cpp */, - 525A4D633D9B0D8B225936D4 /* b2Timer.h */, - ); - path = Common; - sourceTree = ""; - }; - 75093EE94918576801F50993 /* opengl */ = { - isa = PBXGroup; - children = ( - 4AD52074367950B735707CE1 /* Canvas.cpp */, - 23573F2F4F7D56312E663E24 /* Canvas.h */, - 583037E9238A6EF00DD20B1A /* Font.cpp */, - 7EFA04373ADC5CC24DCB5824 /* Font.h */, - 11773415762F3A38421C6DB3 /* Graphics.cpp */, - 389E3CEC356050A27784290E /* Graphics.h */, - 56D6030A0B8F7397715062B9 /* Image.cpp */, - 3CFE5C4A12D5675E7C9C7BF9 /* Image.h */, - FAF4376D17F4AC530074F9E2 /* Mesh.cpp */, - FAF4376E17F4AC530074F9E2 /* Mesh.h */, - 2E406F8328543EC63EB922C6 /* OpenGL.cpp */, - 2C87695707B046B536F347D8 /* OpenGL.h */, - 48A206C9004150640C432100 /* ParticleSystem.cpp */, - 53EE57FF4DBD52BB22701160 /* ParticleSystem.h */, - FA435EA117B36E9C004C3F22 /* Polyline.cpp */, - FA435EA217B36E9C004C3F22 /* Polyline.h */, - FA577A8516C71CF000860150 /* Shader.cpp */, - FA577A8616C71CF000860150 /* Shader.h */, - 4D700D182EAA46273D1E2CC4 /* SpriteBatch.cpp */, - 727D23FA1CC755B902471A45 /* SpriteBatch.h */, - FA9B49281875EFB900201DA9 /* Texture.h */, - 426B1C4475DC54505B824B7F /* VertexBuffer.cpp */, - 577B66502A5360AE60733B10 /* VertexBuffer.h */, - 4E3251027026699A1D4D310D /* wrap_Canvas.cpp */, - 3AFB3A18384A2D22352262B1 /* wrap_Canvas.h */, - 7A3B52AF1FBE73FC36AD50C8 /* wrap_Font.cpp */, - 3CDA3E9B364F17A902384AAC /* wrap_Font.h */, - 1A9810F758AC1D1E4B6431FD /* wrap_Graphics.cpp */, - 05DF237B657042515F3B4E52 /* wrap_Graphics.h */, - 14AE68E14C2C74526A612FA0 /* wrap_Image.cpp */, - 78A2127828793F7A778D7932 /* wrap_Image.h */, - FA7AA59017F6AC1F00704BE2 /* wrap_Mesh.cpp */, - FA7AA59117F6AC1F00704BE2 /* wrap_Mesh.h */, - 5F42052D7C8271A1105541DE /* wrap_ParticleSystem.cpp */, - 678E42771C9B415628A3234D /* wrap_ParticleSystem.h */, - FAC86E611724552C00EED715 /* wrap_Quad.cpp */, - FAC86E621724552C00EED715 /* wrap_Quad.h */, - FA577A8716C71CF000860150 /* wrap_Shader.cpp */, - FA577A8816C71CF000860150 /* wrap_Shader.h */, - 02C16FDB537A702F4D42534E /* wrap_SpriteBatch.cpp */, - 2BE75A693BE206B22DAE1B2E /* wrap_SpriteBatch.h */, - FA01BE1C1878E35B00640047 /* wrap_Texture.cpp */, - FA01BE1D1878E35B00640047 /* wrap_Texture.h */, - ); - path = opengl; - sourceTree = ""; - }; - 752A4B4672B6166A2CA30E85 /* keyboard */ = { - isa = PBXGroup; - children = ( - 524741891BB93848039F4174 /* Keyboard.cpp */, - 6C981DA13E3D42DA06891046 /* Keyboard.h */, - 20A8288624E9654322DC388D /* sdl */, - 19F40DF6507028212FEB1D77 /* wrap_Keyboard.cpp */, - 003142374F3D40A518716024 /* wrap_Keyboard.h */, - ); - path = keyboard; - sourceTree = ""; - }; - 7B0734182055607468261A5E /* filesystem */ = { - isa = PBXGroup; - children = ( - 11D141087979064B441B787D /* File.cpp */, - 31A444CF0B4E6DA450120730 /* File.h */, - 62370A494F9D6E2D570065EB /* FileData.cpp */, - 54A13C2209F945671BC27974 /* FileData.h */, - 64DD03B45BF6265723662DAF /* physfs */, - 6C367AE309C453C412D91363 /* wrap_File.cpp */, - 52E15B702C40593D3BF431DF /* wrap_File.h */, - 597478A255B82B56488B4717 /* wrap_FileData.cpp */, - 3512460642B046876D687B22 /* wrap_FileData.h */, - 1E827AE8548C52493ED95629 /* wrap_Filesystem.cpp */, - 5DC271240F0119AE16FA1B8E /* wrap_Filesystem.h */, - ); - path = filesystem; - sourceTree = ""; - }; - 7BC957592F43649453A57B23 /* Shapes */ = { - isa = PBXGroup; - children = ( - 4E6705C154C34FBD143F465E /* b2ChainShape.cpp */, - 6C7E6C3F1CCA1CF6164123F6 /* b2ChainShape.h */, - 08AA5965073A1C520A7A6833 /* b2CircleShape.cpp */, - 153957EB332E1269671E7F4A /* b2CircleShape.h */, - 633E37194CB535AE41A00092 /* b2EdgeShape.cpp */, - 448C492C7AEB7840504F1C9D /* b2EdgeShape.h */, - 08983C025D0655270DF81A5B /* b2PolygonShape.cpp */, - 0E755DCF691828CE11444877 /* b2PolygonShape.h */, - 2FD366F113387BC95125133D /* b2Shape.h */, - ); - path = Shapes; - sourceTree = ""; - }; - 7DB6750C1F01062849171B8B /* null */ = { - isa = PBXGroup; - children = ( - 7CC5707C79175FA6427B3D62 /* Audio.cpp */, - 2E5C2A2F05417B294ED655E8 /* Audio.h */, - 1A304E384AF2119905C01504 /* Source.cpp */, - 104D567660003ADE696D341A /* Source.h */, - ); - path = null; - sourceTree = ""; - }; - 7DE032B3334E559969264529 /* Contacts */ = { - isa = PBXGroup; - children = ( - 468F7A0A484820DE79CE76D2 /* b2ChainAndCircleContact.cpp */, - 174D472C1AFE594D77A0322B /* b2ChainAndCircleContact.h */, - 60C95C7F507A381D0A483B3F /* b2ChainAndPolygonContact.cpp */, - 44E85D982F01082F5E1346B6 /* b2ChainAndPolygonContact.h */, - 58792BC1126C2917432D706B /* b2CircleContact.cpp */, - 21124F915912499179A42115 /* b2CircleContact.h */, - 71F878E2440A021B68D93ABC /* b2Contact.cpp */, - 50EC67CE3ED71F5D13304FD4 /* b2Contact.h */, - 1E9E4F657DEC2772493B79CC /* b2ContactSolver.cpp */, - 5A1C77401B1B32CE326332A1 /* b2ContactSolver.h */, - 1108594E361A22D90D6022E8 /* b2EdgeAndCircleContact.cpp */, - 0A420541704C1C2D718A4D20 /* b2EdgeAndCircleContact.h */, - 243E18977E2A37CC6FDD55A5 /* b2EdgeAndPolygonContact.cpp */, - 5DA322AC59AD7E43183577CB /* b2EdgeAndPolygonContact.h */, - 31871B8B7E1A697A73576040 /* b2PolygonAndCircleContact.cpp */, - 4A1D6DAE45E627BD12903B52 /* b2PolygonAndCircleContact.h */, - 1F4E747212DE41716BC245C9 /* b2PolygonContact.cpp */, - 0A063D006D52330E67FF4B3A /* b2PolygonContact.h */, - ); - path = Contacts; - sourceTree = ""; - }; - FA0354691731F3A700284828 /* noise1234 */ = { - isa = PBXGroup; - children = ( - FA03546A1731F3A700284828 /* simplexnoise1234.cpp */, - FA03546B1731F3A700284828 /* simplexnoise1234.h */, - ); - path = noise1234; - sourceTree = ""; - }; - FA08F5AC16C751BA00F007B5 /* Resources */ = { - isa = PBXGroup; - children = ( - FA08F5AE16C7525600F007B5 /* Info-Framework.plist */, - ); - name = Resources; - sourceTree = ""; - }; - FA34E7CA174B512200E04D3F /* system */ = { - isa = PBXGroup; - children = ( - FA34E7CF174B514F00E04D3F /* sdl */, - FA34E7CB174B513F00E04D3F /* System.cpp */, - FA34E7CC174B513F00E04D3F /* System.h */, - FA34E7D4174B55AF00E04D3F /* wrap_System.cpp */, - FA34E7D5174B55AF00E04D3F /* wrap_System.h */, - ); - path = system; - sourceTree = ""; - }; - FA34E7CF174B514F00E04D3F /* sdl */ = { - isa = PBXGroup; - children = ( - FA34E7D0174B515D00E04D3F /* System.cpp */, - FA34E7D1174B515D00E04D3F /* System.h */, - ); - path = sdl; - sourceTree = ""; - }; - FA45F76E187A0F3600D99ED8 /* touch */ = { - isa = PBXGroup; - children = ( - FA45F76F187A0F3600D99ED8 /* sdl */, - FA45F772187A0F3600D99ED8 /* Touch.h */, - FA45F773187A0F3600D99ED8 /* wrap_Touch.cpp */, - FA45F774187A0F3600D99ED8 /* wrap_Touch.h */, - ); - path = touch; - sourceTree = ""; - }; - FA45F76F187A0F3600D99ED8 /* sdl */ = { - isa = PBXGroup; - children = ( - FA45F770187A0F3600D99ED8 /* Touch.cpp */, - FA45F771187A0F3600D99ED8 /* Touch.h */, - ); - path = sdl; - sourceTree = ""; - }; - FA4DAE6D1941411D009F0A3E /* lodepng */ = { - isa = PBXGroup; - children = ( - FA4DAE6E1941411D009F0A3E /* lodepng.cpp */, - FA4DAE6F1941411D009F0A3E /* lodepng.h */, - ); - path = lodepng; - sourceTree = ""; - }; - FA4DAE701941411D009F0A3E /* stb */ = { - isa = PBXGroup; - children = ( - FA4DAE721941411D009F0A3E /* stb_image.h */, - ); - path = stb; - sourceTree = ""; - }; - FA577A6616C7199700860150 /* Frameworks */ = { - isa = PBXGroup; - children = ( - FA4DAE7B19414281009F0A3E /* libz.dylib */, - FA577A7916C71A1700860150 /* Cocoa.framework */, - FAA627CD18E7E1560080752D /* CoreServices.framework */, - FA577A6716C719D900860150 /* FreeType.framework */, - FA577A6916C719DE00860150 /* IL.framework */, - FA577A8216C71A5300860150 /* libmodplug.framework */, - FA577A6D16C719EA00860150 /* Lua.framework */, - FA577A6F16C719F000860150 /* mpg123.framework */, - FA577A7116C719F400860150 /* Ogg.framework */, - FAAFF04316CB11C700CCDE45 /* OpenAL-Soft.framework */, - FA577A7C16C71A2600860150 /* OpenGL.framework */, - FA577A7316C719F900860150 /* physfs.framework */, - FA9B4A0716E1578300074F42 /* SDL2.framework */, - FA577A7716C71A0800860150 /* Vorbis.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - FA5FDC5E1788D548002F0ED2 /* enet */ = { - isa = PBXGroup; - children = ( - FA5FDC5F1788D548002F0ED2 /* enet.cpp */, - FA5FDC601788D548002F0ED2 /* libenet */, - FA5FDC781788D548002F0ED2 /* lua-enet.h */, - ); - path = enet; - sourceTree = ""; - }; - FA5FDC601788D548002F0ED2 /* libenet */ = { - isa = PBXGroup; - children = ( - FA5FDC611788D548002F0ED2 /* callbacks.c */, - FA5FDC631788D548002F0ED2 /* compress.c */, - FA5FDC641788D548002F0ED2 /* host.c */, - FA5FDC651788D548002F0ED2 /* include */, - FA5FDC711788D548002F0ED2 /* list.c */, - FA5FDC721788D548002F0ED2 /* packet.c */, - FA5FDC731788D548002F0ED2 /* peer.c */, - FA5FDC741788D548002F0ED2 /* protocol.c */, - FA5FDC761788D548002F0ED2 /* unix.c */, - FA5FDC771788D548002F0ED2 /* win32.c */, - ); - path = libenet; - sourceTree = ""; - }; - FA5FDC651788D548002F0ED2 /* include */ = { - isa = PBXGroup; - children = ( - FA5FDC661788D548002F0ED2 /* enet */, - ); - path = include; - sourceTree = ""; - }; - FA5FDC661788D548002F0ED2 /* enet */ = { - isa = PBXGroup; - children = ( - FA5FDC671788D548002F0ED2 /* callbacks.h */, - FA5FDC681788D548002F0ED2 /* enet.h */, - FA5FDC691788D548002F0ED2 /* list.h */, - FA5FDC6A1788D548002F0ED2 /* protocol.h */, - FA5FDC6B1788D548002F0ED2 /* time.h */, - FA5FDC6C1788D548002F0ED2 /* types.h */, - FA5FDC6D1788D548002F0ED2 /* unix.h */, - FA5FDC6E1788D548002F0ED2 /* utility.h */, - FA5FDC6F1788D548002F0ED2 /* win32.h */, - ); - path = enet; - sourceTree = ""; - }; - FA7C937116DCC6C2006F2BEE /* math */ = { - isa = PBXGroup; - children = ( - FAC570FC17402D1100D147E4 /* BezierCurve.cpp */, - FAC570FD17402D1100D147E4 /* BezierCurve.h */, - FA5454C016F1310000D30303 /* MathModule.cpp */, - FA5454C116F1310000D30303 /* MathModule.h */, - FA636D88171B70920065623F /* RandomGenerator.cpp */, - FA636D89171B70920065623F /* RandomGenerator.h */, - FAC570FE17402D1100D147E4 /* wrap_BezierCurve.cpp */, - FAC570FF17402D1100D147E4 /* wrap_BezierCurve.h */, - FA7C937516DCC6C2006F2BEE /* wrap_Math.cpp */, - FA7C937616DCC6C2006F2BEE /* wrap_Math.h */, - FA636D8C171B72A70065623F /* wrap_RandomGenerator.cpp */, - FA636D8D171B72A70065623F /* wrap_RandomGenerator.h */, - ); - path = math; - sourceTree = ""; - }; - FA9A1008182A0D5200106F9F /* glad */ = { - isa = PBXGroup; - children = ( - FA9A1009182A0D5200106F9F /* glad.cpp */, - FA9A100A182A0D5200106F9F /* glad.hpp */, - FA9A100B182A0D5200106F9F /* gladfuncs.hpp */, - ); - path = glad; - sourceTree = ""; - }; - FAE010D7170DDE99006F29D0 /* ddsparse */ = { - isa = PBXGroup; - children = ( - FAE010D8170DDE99006F29D0 /* ddsinfo.h */, - FAE010D9170DDE99006F29D0 /* ddsparse.cpp */, - FAE010DA170DDE99006F29D0 /* ddsparse.h */, - ); - path = ddsparse; - sourceTree = ""; - }; - FAF272B016E3D46400CC193A /* sdl */ = { - isa = PBXGroup; - children = ( - FAF272B116E3D46400CC193A /* Thread.cpp */, - FAF272B216E3D46400CC193A /* Thread.h */, - FAF272B316E3D46400CC193A /* threads.cpp */, - FAF272B416E3D46400CC193A /* threads.h */, - ); - path = sdl; - sourceTree = ""; - }; - FAF6704318184FF800DBDEEA /* Wuff */ = { - isa = PBXGroup; - children = ( - FAF6704418184FF800DBDEEA /* wuff.c */, - FAF6704518184FF800DBDEEA /* wuff.h */, - FAF6704618184FF800DBDEEA /* wuff_config.h */, - FAF6704718184FF800DBDEEA /* wuff_convert.c */, - FAF6704818184FF800DBDEEA /* wuff_convert.h */, - FAF6704918184FF800DBDEEA /* wuff_internal.c */, - FAF6704A18184FF800DBDEEA /* wuff_internal.h */, - FAF6704B18184FF800DBDEEA /* wuff_memory.c */, - ); - path = Wuff; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - FA577AAC16C7507900860150 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - FA7C937B16DCC6C2006F2BEE /* wrap_Math.h in Headers */, - FAF272A516E3D44400CC193A /* Channel.h in Headers */, - FAF272A716E3D44400CC193A /* LuaThread.h in Headers */, - FAF4377017F4AC530074F9E2 /* Mesh.h in Headers */, - FAF272A916E3D44400CC193A /* ThreadModule.h in Headers */, - FA4DAE6C1941410D009F0A3E /* STBHandler.h in Headers */, - FAF6705018184FF800DBDEEA /* wuff_convert.h in Headers */, - FA9A100D182A0D5200106F9F /* glad.hpp in Headers */, - FAF272AB16E3D44400CC193A /* wrap_Channel.h in Headers */, - FA0A4BF9182E260200E1E4D2 /* wrap_MotorJoint.h in Headers */, - FAF272AD16E3D44400CC193A /* wrap_LuaThread.h in Headers */, - FAF272AF16E3D44400CC193A /* wrap_ThreadModule.h in Headers */, - FAF272B616E3D46400CC193A /* Thread.h in Headers */, - FAF272B816E3D46400CC193A /* threads.h in Headers */, - FA5454C316F1310000D30303 /* MathModule.h in Headers */, - FA4DAE7A1941419A009F0A3E /* JPEGHandler.h in Headers */, - FAAC6B03170A373B008A61C5 /* CompressedData.h in Headers */, - FAE010DB170DDE99006F29D0 /* ddsinfo.h in Headers */, - FAE010DD170DDE99006F29D0 /* ddsparse.h in Headers */, - FAE010E1170DE25E006F29D0 /* ddsHandler.h in Headers */, - FAE010E5170DF75C006F29D0 /* wrap_CompressedData.h in Headers */, - FA4DAE761941411D009F0A3E /* stb_image.h in Headers */, - FAF6704E18184FF800DBDEEA /* wuff_config.h in Headers */, - FA0CDE3D1710F9A50056E8D7 /* FormatHandler.h in Headers */, - FA7AA59317F6AC1F00704BE2 /* wrap_Mesh.h in Headers */, - FA45F777187A0F3600D99ED8 /* Touch.h in Headers */, - FA45F779187A0F3600D99ED8 /* wrap_Touch.h in Headers */, - FA01BE1F1878E35B00640047 /* wrap_Texture.h in Headers */, - FAE404411927F22C00814481 /* KTXHandler.h in Headers */, - FAEC808B1710FEA60057279A /* ImageData.h in Headers */, - FAEC808F1711E76C0057279A /* CompressedData.h in Headers */, - FA636D8B171B70920065623F /* RandomGenerator.h in Headers */, - FA636D8F171B72A70065623F /* wrap_RandomGenerator.h in Headers */, - FAC86E641724552C00EED715 /* wrap_Quad.h in Headers */, - FAC86E6C1724555D00EED715 /* Quad.h in Headers */, - FA03546D1731F3A700284828 /* simplexnoise1234.h in Headers */, - FA3D9E0E16E68DE600CA6630 /* Cursor.h in Headers */, - FA3D9E1216E68EAE00CA6630 /* Cursor.h in Headers */, - FA3D9E1616E6D41100CA6630 /* wrap_Cursor.h in Headers */, - FA9A100E182A0D5200106F9F /* gladfuncs.hpp in Headers */, - FA9FC0B1173D6E3E005027FF /* wrap_Window.h in Headers */, - FA61FD5E1926CFCE003AE9FB /* CompressedFormatHandler.h in Headers */, - FAB007901740C12D00A9664D /* Joystick.h in Headers */, - FAF6705218184FF800DBDEEA /* wuff_internal.h in Headers */, - FAB007941740C28900A9664D /* Joystick.h in Headers */, - FA45F776187A0F3600D99ED8 /* Touch.h in Headers */, - FAB007981740C87D00A9664D /* wrap_Joystick.h in Headers */, - FA52E447192AAADE0064D2FF /* PKMHandler.h in Headers */, - FA9B492A1875EFB900201DA9 /* Texture.h in Headers */, - FAC5710117402D1100D147E4 /* BezierCurve.h in Headers */, - FAC5710317402D1100D147E4 /* wrap_BezierCurve.h in Headers */, - FA5FDC7E1788D548002F0ED2 /* callbacks.h in Headers */, - FA5FDC7F1788D548002F0ED2 /* enet.h in Headers */, - FA5FDC801788D548002F0ED2 /* list.h in Headers */, - FA5FDC811788D548002F0ED2 /* protocol.h in Headers */, - FA5FDC821788D548002F0ED2 /* time.h in Headers */, - FA5FDC831788D548002F0ED2 /* types.h in Headers */, - FA0A4BF5182E1AD600E1E4D2 /* MotorJoint.h in Headers */, - FA5FDC841788D548002F0ED2 /* unix.h in Headers */, - FA0A4BF1182E0C2800E1E4D2 /* b2MotorJoint.h in Headers */, - FA5FDC851788D548002F0ED2 /* utility.h in Headers */, - FAF6704D18184FF800DBDEEA /* wuff.h in Headers */, - FA4DAE6A1941410D009F0A3E /* PNGHandler.h in Headers */, - FA5FDC861788D548002F0ED2 /* win32.h in Headers */, - FA5FDC8F1788D548002F0ED2 /* lua-enet.h in Headers */, - FA4DAE741941411D009F0A3E /* lodepng.h in Headers */, - FA7175AA178E8418001FE7FE /* lua.h in Headers */, - FA34E7CE174B513F00E04D3F /* System.h in Headers */, - FA34E7D3174B515D00E04D3F /* System.h in Headers */, - FAF670571818501300DBDEEA /* WaveDecoder.h in Headers */, - FA1EF7C51799FEB200FF380C /* wrap_System.h in Headers */, - FA61FD601926CFCE003AE9FB /* PVRHandler.h in Headers */, - FA435EA417B36E9C004C3F22 /* Polyline.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - FA577AAE16C7507900860150 /* Framework */ = { - isa = PBXNativeTarget; - buildConfigurationList = FA577ABF16C7507900860150 /* Build configuration list for PBXNativeTarget "Framework" */; - buildPhases = ( - FA577AAA16C7507900860150 /* Sources */, - FA577AAB16C7507900860150 /* Frameworks */, - FA577AAC16C7507900860150 /* Headers */, - FA577AAD16C7507900860150 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Framework; - productName = love; - productReference = FA577AAF16C7507900860150 /* love.framework */; - productType = "com.apple.product-type.framework"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 08FB7793FE84155DC02AAC07 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0510; - }; - buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "love-framework" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 1; - knownRegions = ( - en, - ); - mainGroup = 54067CFB7D564E5764FA17DC /* love */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - FA577AAE16C7507900860150 /* Framework */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - FA577AAD16C7507900860150 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - FA577AAA16C7507900860150 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - FA08F5B016C752F900F007B5 /* Source.cpp in Sources */, - FA08F5B116C752F900F007B5 /* wrap_Audio.cpp in Sources */, - FA08F5B216C752F900F007B5 /* wrap_Source.cpp in Sources */, - FA08F5B316C752FC00F007B5 /* Audio.cpp in Sources */, - FA08F5B416C7530100F007B5 /* Audio.cpp in Sources */, - FA08F5B516C7530100F007B5 /* Source.cpp in Sources */, - FAF6705118184FF800DBDEEA /* wuff_internal.c in Sources */, - FA08F5B616C7530A00F007B5 /* Audio.cpp in Sources */, - FA4DAE791941419A009F0A3E /* JPEGHandler.cpp in Sources */, - FA08F5B716C7530A00F007B5 /* Pool.cpp in Sources */, - FA08F5B816C7530A00F007B5 /* Source.cpp in Sources */, - FA08F5B916C7532A00F007B5 /* b64.cpp in Sources */, - FA08F5BA16C7532A00F007B5 /* delay.cpp in Sources */, - FA08F5BB16C7532A00F007B5 /* Exception.cpp in Sources */, - FA08F5BD16C7532A00F007B5 /* Matrix.cpp in Sources */, - FA08F5BE16C7532A00F007B5 /* Memoizer.cpp in Sources */, - FA08F5BF16C7532A00F007B5 /* Module.cpp in Sources */, - FA08F5C016C7532A00F007B5 /* Object.cpp in Sources */, - FAF670561818501300DBDEEA /* WaveDecoder.cpp in Sources */, - FA08F5C116C7532A00F007B5 /* Reference.cpp in Sources */, - FA08F5C216C7532A00F007B5 /* runtime.cpp in Sources */, - FA08F5C316C7532A00F007B5 /* utf8.cpp in Sources */, - FA08F5C416C7532A00F007B5 /* Variant.cpp in Sources */, - FA08F5C516C7532A00F007B5 /* Vector.cpp in Sources */, - FA08F5C616C7532A00F007B5 /* wrap_Data.cpp in Sources */, - FA08F5C716C7533C00F007B5 /* b2BroadPhase.cpp in Sources */, - FA08F5C816C7533C00F007B5 /* b2CollideCircle.cpp in Sources */, - FA08F5C916C7533C00F007B5 /* b2CollideEdge.cpp in Sources */, - FA08F5CA16C7533C00F007B5 /* b2CollidePolygon.cpp in Sources */, - FA08F5CB16C7533C00F007B5 /* b2Collision.cpp in Sources */, - FA08F5CC16C7533C00F007B5 /* b2Distance.cpp in Sources */, - FA08F5CD16C7533C00F007B5 /* b2DynamicTree.cpp in Sources */, - FA08F5CE16C7533C00F007B5 /* b2TimeOfImpact.cpp in Sources */, - FA61FD5F1926CFCE003AE9FB /* PVRHandler.cpp in Sources */, - FA08F5CF16C7534400F007B5 /* b2ChainShape.cpp in Sources */, - FA08F5D016C7534400F007B5 /* b2CircleShape.cpp in Sources */, - FA08F5D116C7534400F007B5 /* b2EdgeShape.cpp in Sources */, - FA08F5D216C7534400F007B5 /* b2PolygonShape.cpp in Sources */, - FA08F5D316C7535000F007B5 /* b2BlockAllocator.cpp in Sources */, - FA08F5D416C7535000F007B5 /* b2Draw.cpp in Sources */, - FA0A4BF4182E1AD600E1E4D2 /* MotorJoint.cpp in Sources */, - FA08F5D516C7535000F007B5 /* b2Math.cpp in Sources */, - FA08F5D616C7535000F007B5 /* b2Settings.cpp in Sources */, - FA08F5D716C7535000F007B5 /* b2StackAllocator.cpp in Sources */, - FA08F5D816C7535000F007B5 /* b2Timer.cpp in Sources */, - FA08F5D916C7536C00F007B5 /* b2Body.cpp in Sources */, - FA08F5DA16C7536C00F007B5 /* b2ContactManager.cpp in Sources */, - FA08F5DB16C7536C00F007B5 /* b2Fixture.cpp in Sources */, - FA08F5DC16C7536C00F007B5 /* b2Island.cpp in Sources */, - FA08F5DD16C7536C00F007B5 /* b2World.cpp in Sources */, - FA08F5DE16C7536C00F007B5 /* b2WorldCallbacks.cpp in Sources */, - FA08F5DF16C7537B00F007B5 /* b2ChainAndCircleContact.cpp in Sources */, - FA08F5E016C7537B00F007B5 /* b2ChainAndPolygonContact.cpp in Sources */, - FA08F5E116C7537B00F007B5 /* b2CircleContact.cpp in Sources */, - FA08F5E216C7537B00F007B5 /* b2Contact.cpp in Sources */, - FA08F5E316C7537B00F007B5 /* b2ContactSolver.cpp in Sources */, - FA08F5E416C7537B00F007B5 /* b2EdgeAndCircleContact.cpp in Sources */, - FA08F5E516C7537B00F007B5 /* b2EdgeAndPolygonContact.cpp in Sources */, - FA08F5E616C7537B00F007B5 /* b2PolygonAndCircleContact.cpp in Sources */, - FA08F5E716C7537B00F007B5 /* b2PolygonContact.cpp in Sources */, - FA08F5E816C7538F00F007B5 /* b2DistanceJoint.cpp in Sources */, - FA08F5E916C7538F00F007B5 /* b2FrictionJoint.cpp in Sources */, - FA08F5EA16C7538F00F007B5 /* b2GearJoint.cpp in Sources */, - FA08F5EB16C7538F00F007B5 /* b2Joint.cpp in Sources */, - FA08F5EC16C7538F00F007B5 /* b2MouseJoint.cpp in Sources */, - FA08F5ED16C7538F00F007B5 /* b2PrismaticJoint.cpp in Sources */, - FAF6705318184FF800DBDEEA /* wuff_memory.c in Sources */, - FA08F5EE16C7538F00F007B5 /* b2PulleyJoint.cpp in Sources */, - FA08F5EF16C7538F00F007B5 /* b2RevoluteJoint.cpp in Sources */, - FA08F5F016C7538F00F007B5 /* b2RopeJoint.cpp in Sources */, - FA08F5F116C7538F00F007B5 /* b2WeldJoint.cpp in Sources */, - FA45F775187A0F3600D99ED8 /* Touch.cpp in Sources */, - FA08F5F216C7538F00F007B5 /* b2WheelJoint.cpp in Sources */, - FA08F5F316C7539B00F007B5 /* b2Rope.cpp in Sources */, - FA08F5F416C753A400F007B5 /* luasocket.cpp in Sources */, - FA08F5F516C753B800F007B5 /* auxiliar.c in Sources */, - FA08F5F616C753B800F007B5 /* buffer.c in Sources */, - FAF6704F18184FF800DBDEEA /* wuff_convert.c in Sources */, - FA08F5F716C753B800F007B5 /* except.c in Sources */, - FA08F5F816C753B800F007B5 /* inet.c in Sources */, - FA08F5F916C753B800F007B5 /* io.c in Sources */, - FA08F5FA16C753B800F007B5 /* luasocket.c in Sources */, - FA08F5FB16C753B800F007B5 /* mime.c in Sources */, - FA08F5FC16C753B800F007B5 /* options.c in Sources */, - FA08F5FD16C753B800F007B5 /* select.c in Sources */, - FA08F5FE16C753B800F007B5 /* tcp.c in Sources */, - FA08F5FF16C753B800F007B5 /* timeout.c in Sources */, - FA08F60016C753B800F007B5 /* udp.c in Sources */, - FA08F60116C753B800F007B5 /* unix.c in Sources */, - FA08F60216C753B800F007B5 /* usocket.c in Sources */, - FA08F60316C753CE00F007B5 /* Event.cpp in Sources */, - FA08F60416C753CE00F007B5 /* Event.cpp in Sources */, - FA08F60516C753CE00F007B5 /* wrap_Event.cpp in Sources */, - FA08F60616C753DB00F007B5 /* File.cpp in Sources */, - FA08F60716C753DB00F007B5 /* FileData.cpp in Sources */, - FA08F60816C753DB00F007B5 /* File.cpp in Sources */, - FA08F60916C753DB00F007B5 /* Filesystem.cpp in Sources */, - FA08F60A16C753DB00F007B5 /* wrap_File.cpp in Sources */, - FA08F60B16C753DB00F007B5 /* wrap_FileData.cpp in Sources */, - FA08F60C16C753DB00F007B5 /* wrap_Filesystem.cpp in Sources */, - FA08F60D16C753E700F007B5 /* Font.cpp in Sources */, - FA08F60E16C753E700F007B5 /* TrueTypeRasterizer.cpp in Sources */, - FA08F60F16C753E700F007B5 /* wrap_Font.cpp in Sources */, - FA08F61016C753E700F007B5 /* GlyphData.cpp in Sources */, - FA08F61116C753E700F007B5 /* ImageRasterizer.cpp in Sources */, - FA08F61216C753E700F007B5 /* Rasterizer.cpp in Sources */, - FA08F61316C753E700F007B5 /* wrap_GlyphData.cpp in Sources */, - FA08F61416C753E700F007B5 /* wrap_Rasterizer.cpp in Sources */, - FA08F61716C753F600F007B5 /* Graphics.cpp in Sources */, - FA45F778187A0F3600D99ED8 /* wrap_Touch.cpp in Sources */, - FA08F61816C753F600F007B5 /* Texture.cpp in Sources */, - FA08F61A16C753F600F007B5 /* Volatile.cpp in Sources */, - FA08F61B16C7541400F007B5 /* Canvas.cpp in Sources */, - FA08F61C16C7541400F007B5 /* Font.cpp in Sources */, - FA08F61E16C7541400F007B5 /* Graphics.cpp in Sources */, - FAF4376F17F4AC530074F9E2 /* Mesh.cpp in Sources */, - FA08F61F16C7541400F007B5 /* Image.cpp in Sources */, - FA08F62016C7541400F007B5 /* OpenGL.cpp in Sources */, - FA08F62116C7541400F007B5 /* ParticleSystem.cpp in Sources */, - FA08F62316C7541400F007B5 /* Shader.cpp in Sources */, - FA08F62416C7541400F007B5 /* SpriteBatch.cpp in Sources */, - FA08F62516C7541400F007B5 /* VertexBuffer.cpp in Sources */, - FA08F62616C7541400F007B5 /* wrap_Canvas.cpp in Sources */, - FAE404401927F22C00814481 /* KTXHandler.cpp in Sources */, - FA08F62716C7541400F007B5 /* wrap_Font.cpp in Sources */, - FA08F62816C7541400F007B5 /* wrap_Graphics.cpp in Sources */, - FA08F62916C7541400F007B5 /* wrap_Image.cpp in Sources */, - FA08F62A16C7541400F007B5 /* wrap_ParticleSystem.cpp in Sources */, - FA08F62C16C7541400F007B5 /* wrap_Shader.cpp in Sources */, - FA0A4BFA182E26F500E1E4D2 /* wrap_MotorJoint.cpp in Sources */, - FA08F62D16C7541400F007B5 /* wrap_SpriteBatch.cpp in Sources */, - FA08F62E16C7542600F007B5 /* ImageData.cpp in Sources */, - FA08F62F16C7542600F007B5 /* Image.cpp in Sources */, - FA08F63016C7542600F007B5 /* DevilHandler.cpp in Sources */, - FA08F63116C7542600F007B5 /* wrap_Image.cpp in Sources */, - FA08F63216C7542600F007B5 /* wrap_ImageData.cpp in Sources */, - FA08F63416C7542D00F007B5 /* JoystickModule.cpp in Sources */, - FA7AA59217F6AC1F00704BE2 /* wrap_Mesh.cpp in Sources */, - FA08F63516C7542D00F007B5 /* wrap_JoystickModule.cpp in Sources */, - FA08F63616C7543400F007B5 /* Keyboard.cpp in Sources */, - FA08F63716C7543400F007B5 /* Keyboard.cpp in Sources */, - FA08F63816C7543400F007B5 /* wrap_Keyboard.cpp in Sources */, - FA08F63916C7543A00F007B5 /* love.cpp in Sources */, - FA08F63A16C7544300F007B5 /* Mouse.cpp in Sources */, - FA08F63B16C7544300F007B5 /* Mouse.cpp in Sources */, - FA08F63C16C7544300F007B5 /* wrap_Mouse.cpp in Sources */, - FA08F63D16C7544B00F007B5 /* Body.cpp in Sources */, - FA08F63E16C7544B00F007B5 /* Joint.cpp in Sources */, - FA08F63F16C7544B00F007B5 /* Shape.cpp in Sources */, - FA08F64016C7546400F007B5 /* Body.cpp in Sources */, - FA08F64116C7546400F007B5 /* ChainShape.cpp in Sources */, - FA08F64216C7546400F007B5 /* CircleShape.cpp in Sources */, - FA08F64316C7546400F007B5 /* Contact.cpp in Sources */, - FA08F64416C7546400F007B5 /* DistanceJoint.cpp in Sources */, - FA08F64516C7546400F007B5 /* EdgeShape.cpp in Sources */, - FA08F64616C7546400F007B5 /* Fixture.cpp in Sources */, - FA08F64716C7546400F007B5 /* FrictionJoint.cpp in Sources */, - FA08F64816C7546400F007B5 /* GearJoint.cpp in Sources */, - FA08F64916C7546400F007B5 /* Joint.cpp in Sources */, - FA08F64A16C7546400F007B5 /* MouseJoint.cpp in Sources */, - FA08F64B16C7546400F007B5 /* Physics.cpp in Sources */, - FA08F64C16C7546400F007B5 /* PolygonShape.cpp in Sources */, - FA08F64D16C7546400F007B5 /* PrismaticJoint.cpp in Sources */, - FA08F64E16C7546400F007B5 /* PulleyJoint.cpp in Sources */, - FA08F64F16C7546400F007B5 /* RevoluteJoint.cpp in Sources */, - FA08F65016C7546400F007B5 /* RopeJoint.cpp in Sources */, - FA08F65116C7546400F007B5 /* Shape.cpp in Sources */, - FA08F65216C7547300F007B5 /* WeldJoint.cpp in Sources */, - FAF6704C18184FF800DBDEEA /* wuff.c in Sources */, - FA08F65316C7547300F007B5 /* WheelJoint.cpp in Sources */, - FA08F65416C7547300F007B5 /* World.cpp in Sources */, - FA08F65516C7547300F007B5 /* wrap_Body.cpp in Sources */, - FA08F65616C7547300F007B5 /* wrap_ChainShape.cpp in Sources */, - FA08F65716C7547300F007B5 /* wrap_CircleShape.cpp in Sources */, - FA08F65816C7547300F007B5 /* wrap_Contact.cpp in Sources */, - FA08F65916C7547300F007B5 /* wrap_DistanceJoint.cpp in Sources */, - FA08F65A16C7547300F007B5 /* wrap_EdgeShape.cpp in Sources */, - FA08F65B16C7547300F007B5 /* wrap_Fixture.cpp in Sources */, - FA08F65C16C7547300F007B5 /* wrap_FrictionJoint.cpp in Sources */, - FA08F65D16C7548200F007B5 /* wrap_GearJoint.cpp in Sources */, - FA08F65E16C7548200F007B5 /* wrap_Joint.cpp in Sources */, - FA08F65F16C7548200F007B5 /* wrap_MouseJoint.cpp in Sources */, - FA08F66016C7548200F007B5 /* wrap_Physics.cpp in Sources */, - FA08F66116C7548200F007B5 /* wrap_PolygonShape.cpp in Sources */, - FA08F66216C7548200F007B5 /* wrap_PrismaticJoint.cpp in Sources */, - FA08F66316C7548200F007B5 /* wrap_PulleyJoint.cpp in Sources */, - FA08F66416C7548200F007B5 /* wrap_RevoluteJoint.cpp in Sources */, - FA08F66516C7548200F007B5 /* wrap_RopeJoint.cpp in Sources */, - FA08F66616C7548200F007B5 /* wrap_Shape.cpp in Sources */, - FA08F66716C7548200F007B5 /* wrap_WeldJoint.cpp in Sources */, - FA08F66816C7548200F007B5 /* wrap_WheelJoint.cpp in Sources */, - FA08F66916C7548200F007B5 /* wrap_World.cpp in Sources */, - FA08F66A16C7549200F007B5 /* Sound.cpp in Sources */, - FADD58DD18C30367005FC3BF /* FormatHandler.cpp in Sources */, - FA08F66B16C7549200F007B5 /* SoundData.cpp in Sources */, - FA08F66C16C7549200F007B5 /* wrap_Decoder.cpp in Sources */, - FA08F66D16C7549200F007B5 /* wrap_Sound.cpp in Sources */, - FA08F66E16C7549200F007B5 /* wrap_SoundData.cpp in Sources */, - FA08F66F16C754A100F007B5 /* Decoder.cpp in Sources */, - FA08F67016C754A100F007B5 /* FLACDecoder.cpp in Sources */, - FA08F67116C754A100F007B5 /* GmeDecoder.cpp in Sources */, - FA08F67216C754A100F007B5 /* ModPlugDecoder.cpp in Sources */, - FA08F67316C754A100F007B5 /* Mpg123Decoder.cpp in Sources */, - FA08F67416C754A100F007B5 /* Sound.cpp in Sources */, - FA08F67516C754A100F007B5 /* VorbisDecoder.cpp in Sources */, - FA4DAE691941410D009F0A3E /* PNGHandler.cpp in Sources */, - FA08F67716C754A900F007B5 /* threads.cpp in Sources */, - FA08F67916C754B100F007B5 /* Timer.cpp in Sources */, - FA08F67A16C754B100F007B5 /* wrap_Timer.cpp in Sources */, - FA08F67B16C754BA00F007B5 /* Window.cpp in Sources */, - FA08F67C16C754BA00F007B5 /* Window.cpp in Sources */, - FA7C937A16DCC6C2006F2BEE /* wrap_Math.cpp in Sources */, - FAF272A416E3D44400CC193A /* Channel.cpp in Sources */, - FAF272A616E3D44400CC193A /* LuaThread.cpp in Sources */, - FA0A4BF0182E0C2800E1E4D2 /* b2MotorJoint.cpp in Sources */, - FA4DAE6B1941410D009F0A3E /* STBHandler.cpp in Sources */, - FAF272A816E3D44400CC193A /* ThreadModule.cpp in Sources */, - FA52E446192AAADE0064D2FF /* PKMHandler.cpp in Sources */, - FA4DAE731941411D009F0A3E /* lodepng.cpp in Sources */, - FA01BE1E1878E35B00640047 /* wrap_Texture.cpp in Sources */, - FAF272AA16E3D44400CC193A /* wrap_Channel.cpp in Sources */, - FAF272AC16E3D44400CC193A /* wrap_LuaThread.cpp in Sources */, - FAF272AE16E3D44400CC193A /* wrap_ThreadModule.cpp in Sources */, - FAF272B516E3D46400CC193A /* Thread.cpp in Sources */, - FAF272B716E3D46400CC193A /* threads.cpp in Sources */, - FA5454C216F1310000D30303 /* MathModule.cpp in Sources */, - FAAC6B02170A373B008A61C5 /* CompressedData.cpp in Sources */, - FAE010DC170DDE99006F29D0 /* ddsparse.cpp in Sources */, - FAE010E0170DE25E006F29D0 /* ddsHandler.cpp in Sources */, - FAE010E4170DF75C006F29D0 /* wrap_CompressedData.cpp in Sources */, - FAEC808A1710FEA60057279A /* ImageData.cpp in Sources */, - FAEC808E1711E76C0057279A /* CompressedData.cpp in Sources */, - FA636D8A171B70920065623F /* RandomGenerator.cpp in Sources */, - FA636D8E171B72A70065623F /* wrap_RandomGenerator.cpp in Sources */, - FAC86E631724552C00EED715 /* wrap_Quad.cpp in Sources */, - FAC86E6B1724555D00EED715 /* Quad.cpp in Sources */, - FA03546C1731F3A700284828 /* simplexnoise1234.cpp in Sources */, - FA3D9E0D16E68DE600CA6630 /* Cursor.cpp in Sources */, - FA3D9E1116E68EAE00CA6630 /* Cursor.cpp in Sources */, - FA3D9E1516E6D41100CA6630 /* wrap_Cursor.cpp in Sources */, - FA9FC0B0173D6E3E005027FF /* wrap_Window.cpp in Sources */, - FAB0078F1740C12D00A9664D /* Joystick.cpp in Sources */, - FAB007931740C28900A9664D /* Joystick.cpp in Sources */, - FAB007971740C87D00A9664D /* wrap_Joystick.cpp in Sources */, - FAC5710017402D1100D147E4 /* BezierCurve.cpp in Sources */, - FAC5710217402D1100D147E4 /* wrap_BezierCurve.cpp in Sources */, - FA5FDC791788D548002F0ED2 /* enet.cpp in Sources */, - FA5FDC7A1788D548002F0ED2 /* callbacks.c in Sources */, - FA5FDC7C1788D548002F0ED2 /* compress.c in Sources */, - FA5FDC7D1788D548002F0ED2 /* host.c in Sources */, - FA5FDC881788D548002F0ED2 /* list.c in Sources */, - FA5FDC891788D548002F0ED2 /* packet.c in Sources */, - FA5FDC8A1788D548002F0ED2 /* peer.c in Sources */, - FA5FDC8B1788D548002F0ED2 /* protocol.c in Sources */, - FA5FDC8D1788D548002F0ED2 /* unix.c in Sources */, - FA5FDC8E1788D548002F0ED2 /* win32.c in Sources */, - FA34E7CD174B513F00E04D3F /* System.cpp in Sources */, - FA34E7D2174B515D00E04D3F /* System.cpp in Sources */, - FA1EF7C41799FEAC00FF380C /* wrap_System.cpp in Sources */, - FA435EA317B36E9C004C3F22 /* Polyline.cpp in Sources */, - FA9A100C182A0D5200106F9F /* glad.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 10D5479E63C26BB35EB5482E /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; - CLANG_ENABLE_MODULES = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - DEAD_CODE_STRIPPING = YES; - FRAMEWORK_SEARCH_PATHS = /Library/Frameworks; - GCC_OPTIMIZATION_LEVEL = 3; - GCC_PREPROCESSOR_DEFINITIONS = LOVE_MACOSX_USE_FRAMEWORKS; - GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; - GCC_WARN_ABOUT_MISSING_NEWLINE = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; - GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; - GCC_WARN_SIGN_COMPARE = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_PARAMETER = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ( - "\"$(SRCROOT)/../../src\"", - "\"$(SRCROOT)/../../src/libraries\"", - "\"$(SRCROOT)/../../src/modules\"", - "\"$(SRCROOT)/../../src/libraries/enet/libenet/include\"", - /Library/Frameworks/FreeType.framework/Headers, - /Library/Frameworks/Lua.framework/Headers, - /Library/Frameworks/SDL2.framework/Headers, - ); - LD_RUNPATH_SEARCH_PATHS = "@rpath"; - LIBRARY_SEARCH_PATHS = ""; - MACOSX_DEPLOYMENT_TARGET = 10.6; - ONLY_ACTIVE_ARCH = NO; - USE_HEADERMAP = NO; - WARNING_CFLAGS = "-Wall"; - }; - name = Release; - }; - 64274E785071353E1A1D0D4B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; - CLANG_ENABLE_MODULES = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - COPY_PHASE_STRIP = NO; - FRAMEWORK_SEARCH_PATHS = /Library/Frameworks; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = LOVE_MACOSX_USE_FRAMEWORKS; - GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; - GCC_WARN_ABOUT_MISSING_NEWLINE = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; - GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; - GCC_WARN_SIGN_COMPARE = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_PARAMETER = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ( - "\"$(SRCROOT)/../../src\"", - "\"$(SRCROOT)/../../src/libraries\"", - "\"$(SRCROOT)/../../src/modules\"", - "\"$(SRCROOT)/../../src/libraries/enet/libenet/include\"", - /Library/Frameworks/FreeType.framework/Headers, - /Library/Frameworks/Lua.framework/Headers, - /Library/Frameworks/SDL2.framework/Headers, - ); - LD_RUNPATH_SEARCH_PATHS = "@rpath"; - LIBRARY_SEARCH_PATHS = ""; - MACOSX_DEPLOYMENT_TARGET = 10.6; - ONLY_ACTIVE_ARCH = YES; - USE_HEADERMAP = NO; - WARNING_CFLAGS = "-Wall"; - }; - name = Debug; - }; - FA5326C4189719C700F7BBF4 /* Distribution */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; - CLANG_ENABLE_MODULES = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - DEAD_CODE_STRIPPING = YES; - FRAMEWORK_SEARCH_PATHS = /Library/Frameworks; - GCC_OPTIMIZATION_LEVEL = 3; - GCC_PREPROCESSOR_DEFINITIONS = LOVE_MACOSX_USE_FRAMEWORKS; - GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; - GCC_WARN_ABOUT_MISSING_NEWLINE = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; - GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; - GCC_WARN_SIGN_COMPARE = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_PARAMETER = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ( - "\"$(SRCROOT)/../../src\"", - "\"$(SRCROOT)/../../src/libraries\"", - "\"$(SRCROOT)/../../src/modules\"", - "\"$(SRCROOT)/../../src/libraries/enet/libenet/include\"", - /Library/Frameworks/FreeType.framework/Headers, - /Library/Frameworks/Lua.framework/Headers, - /Library/Frameworks/SDL2.framework/Headers, - ); - LD_RUNPATH_SEARCH_PATHS = "@rpath"; - LIBRARY_SEARCH_PATHS = ""; - LLVM_LTO = YES; - MACOSX_DEPLOYMENT_TARGET = 10.6; - ONLY_ACTIVE_ARCH = NO; - USE_HEADERMAP = NO; - WARNING_CFLAGS = "-Wall"; - }; - name = Distribution; - }; - FA5326C5189719C700F7BBF4 /* Distribution */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ENABLE_MODULES = NO; - COMBINE_HIDPI_IMAGES = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DYLIB_COMPATIBILITY_VERSION = 9.0; - DYLIB_CURRENT_VERSION = 9.0; - FRAMEWORK_VERSION = A; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - INFOPLIST_FILE = "Info-Framework.plist"; - LD_DYLIB_INSTALL_NAME = "@rpath/$(EXECUTABLE_PATH)"; - OTHER_LDFLAGS = ( - "-undefined", - dynamic_lookup, - ); - PRODUCT_NAME = love; - SKIP_INSTALL = YES; - WRAPPER_EXTENSION = framework; - }; - name = Distribution; - }; - FA577AC016C7507900860150 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ENABLE_MODULES = NO; - COMBINE_HIDPI_IMAGES = YES; - DYLIB_COMPATIBILITY_VERSION = 9.0; - DYLIB_CURRENT_VERSION = 9.0; - FRAMEWORK_VERSION = A; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - INFOPLIST_FILE = "Info-Framework.plist"; - LD_DYLIB_INSTALL_NAME = "@rpath/$(EXECUTABLE_PATH)"; - OTHER_LDFLAGS = ( - "-undefined", - dynamic_lookup, - ); - PRODUCT_NAME = love; - SKIP_INSTALL = YES; - WRAPPER_EXTENSION = framework; - }; - name = Debug; - }; - FA577AC116C7507900860150 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ENABLE_MODULES = NO; - COMBINE_HIDPI_IMAGES = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DYLIB_COMPATIBILITY_VERSION = 9.0; - DYLIB_CURRENT_VERSION = 9.0; - FRAMEWORK_VERSION = A; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - INFOPLIST_FILE = "Info-Framework.plist"; - LD_DYLIB_INSTALL_NAME = "@rpath/$(EXECUTABLE_PATH)"; - OTHER_LDFLAGS = ( - "-undefined", - dynamic_lookup, - ); - PRODUCT_NAME = love; - SKIP_INSTALL = YES; - WRAPPER_EXTENSION = framework; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "love-framework" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 64274E785071353E1A1D0D4B /* Debug */, - 10D5479E63C26BB35EB5482E /* Release */, - FA5326C4189719C700F7BBF4 /* Distribution */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; - FA577ABF16C7507900860150 /* Build configuration list for PBXNativeTarget "Framework" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - FA577AC016C7507900860150 /* Debug */, - FA577AC116C7507900860150 /* Release */, - FA5326C5189719C700F7BBF4 /* Distribution */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; -/* End XCConfigurationList section */ - }; - rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; -} diff --git a/love/src/jni/love/platform/macosx/love.xcodeproj/TemplateIcon.icns b/love/src/jni/love/platform/macosx/love.xcodeproj/TemplateIcon.icns deleted file mode 100644 index 62cb7015..00000000 Binary files a/love/src/jni/love/platform/macosx/love.xcodeproj/TemplateIcon.icns and /dev/null differ diff --git a/love/src/jni/love/platform/macosx/love.xcodeproj/default.pbxuser b/love/src/jni/love/platform/macosx/love.xcodeproj/default.pbxuser deleted file mode 100644 index 347c8dc8..00000000 --- a/love/src/jni/love/platform/macosx/love.xcodeproj/default.pbxuser +++ /dev/null @@ -1,1052 +0,0 @@ -// !$*UTF8*$! -{ - 29B97313FDCFA39411CA2CEA /* Project object */ = { - activeArchitecturePreference = ppc; - activeBuildConfigurationName = Release; - activeExecutable = A93E69C010420A88007D418B /* love */; - activeSDKPreference = macosx10.5; - activeTarget = 8D1107260486CEB800E47090 /* love */; - addToTargets = ( - 8D1107260486CEB800E47090 /* love */, - ); - breakpoints = ( - ); - codeSenseManager = A93E69C410420AA6007D418B /* Code sense */; - executables = ( - A93E69C010420A88007D418B /* love */, - ); - perUserDictionary = { - PBXConfiguration.PBXFileTableDataSource3.PBXBookmarksDataSource = { - PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; - PBXFileTableDataSourceColumnSortingKey = PBXBookmarksDataSource_NameID; - PBXFileTableDataSourceColumnWidthsKey = ( - 200, - 200, - 150.58349609375, - ); - PBXFileTableDataSourceColumnsKey = ( - PBXBookmarksDataSource_LocationID, - PBXBookmarksDataSource_NameID, - PBXBookmarksDataSource_CommentsID, - ); - }; - PBXConfiguration.PBXFileTableDataSource3.PBXErrorsWarningsDataSource = { - PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; - PBXFileTableDataSourceColumnSortingKey = PBXErrorsWarningsDataSource_LocationID; - PBXFileTableDataSourceColumnWidthsKey = ( - 20, - 300, - 193.20849609375, - ); - PBXFileTableDataSourceColumnsKey = ( - PBXErrorsWarningsDataSource_TypeID, - PBXErrorsWarningsDataSource_MessageID, - PBXErrorsWarningsDataSource_LocationID, - ); - }; - PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = { - PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; - PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID; - PBXFileTableDataSourceColumnWidthsKey = ( - 22, - 300, - 191, - ); - PBXFileTableDataSourceColumnsKey = ( - PBXExecutablesDataSource_ActiveFlagID, - PBXExecutablesDataSource_NameID, - PBXExecutablesDataSource_CommentsID, - ); - }; - PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { - PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; - PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_FiletypeID; - PBXFileTableDataSourceColumnWidthsKey = ( - 20, - 341, - 20, - 48, - 43, - 43, - 20, - ); - PBXFileTableDataSourceColumnsKey = ( - PBXFileDataSource_FiletypeID, - PBXFileDataSource_Filename_ColumnID, - PBXFileDataSource_Built_ColumnID, - PBXFileDataSource_ObjectSize_ColumnID, - PBXFileDataSource_Errors_ColumnID, - PBXFileDataSource_Warnings_ColumnID, - PBXFileDataSource_Target_ColumnID, - ); - }; - PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = { - PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; - PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; - PBXFileTableDataSourceColumnWidthsKey = ( - 20, - 301, - 60, - 20, - 48, - 43, - 43, - ); - PBXFileTableDataSourceColumnsKey = ( - PBXFileDataSource_FiletypeID, - PBXFileDataSource_Filename_ColumnID, - PBXTargetDataSource_PrimaryAttribute, - PBXFileDataSource_Built_ColumnID, - PBXFileDataSource_ObjectSize_ColumnID, - PBXFileDataSource_Errors_ColumnID, - PBXFileDataSource_Warnings_ColumnID, - ); - }; - PBXPerProjectTemplateStateSaveDate = 272885036; - PBXWorkspaceStateSaveDate = 272885036; - }; - perUserProjectItems = { - A9D8FBD21043E5320063561F /* PBXTextBookmark */ = A9D8FBD21043E5320063561F /* PBXTextBookmark */; - A9D8FBE01043E5AE0063561F /* PBXTextBookmark */ = A9D8FBE01043E5AE0063561F /* PBXTextBookmark */; - A9D8FBE21043E5AE0063561F /* PBXTextBookmark */ = A9D8FBE21043E5AE0063561F /* PBXTextBookmark */; - A9D8FBE71043E5C10063561F /* PBXTextBookmark */ = A9D8FBE71043E5C10063561F /* PBXTextBookmark */; - A9D8FBE81043E5C10063561F /* PBXTextBookmark */ = A9D8FBE81043E5C10063561F /* PBXTextBookmark */; - A9D8FBE91043E5C10063561F /* PBXTextBookmark */ = A9D8FBE91043E5C10063561F /* PBXTextBookmark */; - A9D8FBEA1043E5C10063561F /* PBXTextBookmark */ = A9D8FBEA1043E5C10063561F /* PBXTextBookmark */; - A9D8FBEB1043E5C10063561F /* PBXTextBookmark */ = A9D8FBEB1043E5C10063561F /* PBXTextBookmark */; - A9D8FBEC1043E5C10063561F /* PBXTextBookmark */ = A9D8FBEC1043E5C10063561F /* PBXTextBookmark */; - A9D8FBED1043E5C10063561F /* PBXTextBookmark */ = A9D8FBED1043E5C10063561F /* PBXTextBookmark */; - A9D8FBFC1043E7C20063561F /* PBXTextBookmark */ = A9D8FBFC1043E7C20063561F /* PBXTextBookmark */; - A9D8FC011043E8770063561F /* PBXTextBookmark */ = A9D8FC011043E8770063561F /* PBXTextBookmark */; - A9D8FC031043E94F0063561F /* PBXTextBookmark */ = A9D8FC031043E94F0063561F /* PBXTextBookmark */; - A9D8FC041043E94F0063561F /* PBXTextBookmark */ = A9D8FC041043E94F0063561F /* PBXTextBookmark */; - A9D8FC051043E94F0063561F /* PBXTextBookmark */ = A9D8FC051043E94F0063561F /* PBXTextBookmark */; - A9D8FC061043E94F0063561F /* PBXTextBookmark */ = A9D8FC061043E94F0063561F /* PBXTextBookmark */; - A9D8FC0D1043EBD30063561F /* PBXTextBookmark */ = A9D8FC0D1043EBD30063561F /* PBXTextBookmark */; - A9D8FC131043EC200063561F /* PBXTextBookmark */ = A9D8FC131043EC200063561F /* PBXTextBookmark */; - A9D8FC1E1043EFA00063561F /* PBXTextBookmark */ = A9D8FC1E1043EFA00063561F /* PBXTextBookmark */; - A9D8FC2010441C030063561F /* PBXTextBookmark */ = A9D8FC2010441C030063561F /* PBXTextBookmark */; - A9D8FC2110441C0F0063561F /* PBXTextBookmark */ = A9D8FC2110441C0F0063561F /* PBXTextBookmark */; - A9D8FC2410441DF10063561F /* PBXTextBookmark */ = A9D8FC2410441DF10063561F /* PBXTextBookmark */; - A9D8FC2510441E590063561F /* PBXTextBookmark */ = A9D8FC2510441E590063561F /* PBXTextBookmark */; - A9D8FC2610441E700063561F /* PBXTextBookmark */ = A9D8FC2610441E700063561F /* PBXTextBookmark */; - A9D8FC2710441E890063561F /* PBXTextBookmark */ = A9D8FC2710441E890063561F /* PBXTextBookmark */; - A9D8FC2910441E9B0063561F /* PBXTextBookmark */ = A9D8FC2910441E9B0063561F /* PBXTextBookmark */; - A9D8FC2F104423D80063561F /* PBXTextBookmark */ = A9D8FC2F104423D80063561F /* PBXTextBookmark */; - A9D8FC30104423D80063561F /* PBXTextBookmark */ = A9D8FC30104423D80063561F /* PBXTextBookmark */; - A9D8FC31104423D80063561F /* PBXTextBookmark */ = A9D8FC31104423D80063561F /* PBXTextBookmark */; - A9D8FC32104423D80063561F /* PBXTextBookmark */ = A9D8FC32104423D80063561F /* PBXTextBookmark */; - A9D8FC36104423F90063561F /* PBXTextBookmark */ = A9D8FC36104423F90063561F /* PBXTextBookmark */; - A9D8FC3D104427770063561F /* PBXTextBookmark */ = A9D8FC3D104427770063561F /* PBXTextBookmark */; - A9D8FC3F104427A10063561F /* PBXTextBookmark */ = A9D8FC3F104427A10063561F /* PBXTextBookmark */; - A9D8FC40104427AE0063561F /* PBXTextBookmark */ = A9D8FC40104427AE0063561F /* PBXTextBookmark */; - A9D8FC421044283D0063561F /* PBXTextBookmark */ = A9D8FC421044283D0063561F /* PBXTextBookmark */; - A9DE83571043CE2800567BA4 = A9DE83571043CE2800567BA4 /* PBXTextBookmark */; - A9DE835A1043CE2800567BA4 = A9DE835A1043CE2800567BA4 /* PBXTextBookmark */; - A9DE83781043CFEF00567BA4 = A9DE83781043CFEF00567BA4 /* PBXTextBookmark */; - A9DE83791043CFEF00567BA4 = A9DE83791043CFEF00567BA4 /* PBXTextBookmark */; - A9DE837A1043CFEF00567BA4 = A9DE837A1043CFEF00567BA4 /* PBXBookmark */; - A9DE837B1043CFEF00567BA4 = A9DE837B1043CFEF00567BA4 /* PBXTextBookmark */; - A9DE837C1043CFEF00567BA4 = A9DE837C1043CFEF00567BA4 /* PBXTextBookmark */; - A9DE85AA1043E49900567BA4 = A9DE85AA1043E49900567BA4 /* PBXTextBookmark */; - }; - sourceControlManager = A93E69C310420AA6007D418B /* Source Control */; - userBuildSettings = { - }; - }; - 8D1107260486CEB800E47090 /* love */ = { - activeExec = 0; - executables = ( - A93E69C010420A88007D418B /* love */, - ); - }; - A9255DEA1043188D00BA1496 /* SDLMain.m */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {762, 5586}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{561, 596}"; - }; - }; - A93E69C010420A88007D418B /* love */ = { - isa = PBXExecutable; - activeArgIndices = ( - ); - argumentStrings = ( - ); - autoAttachOnCrash = 1; - breakpointsEnabled = 0; - configStateDict = { - }; - customDataFormattersEnabled = 1; - debuggerPlugin = GDBDebugging; - disassemblyDisplayState = 0; - dylibVariantSuffix = ""; - enableDebugStr = 1; - environmentEntries = ( - ); - executableSystemSymbolLevel = 0; - executableUserSymbolLevel = 0; - libgmallocEnabled = 0; - name = love; - sourceDirectories = ( - ); - }; - A93E69C310420AA6007D418B /* Source Control */ = { - isa = PBXSourceControlManager; - fallbackIsa = XCSourceControlManager; - isSCMEnabled = 0; - scmConfiguration = { - }; - }; - A93E69C410420AA6007D418B /* Code sense */ = { - isa = PBXCodeSenseManager; - indexTemplatePath = ""; - }; - A93E69DE10420ABF007D418B /* config.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {481, 812}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{922, 334}"; - }; - }; - A93E69E110420ABF007D418B /* Exception.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {481, 770}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 844}"; - }; - }; - A93E69E610420ABF007D418B /* MemoryData.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {481, 910}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{987, 353}"; - }; - }; - A93E69E710420ABF007D418B /* Module.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {481, 798}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{1168, 298}"; - }; - }; - A93E69EA10420ABF007D418B /* Reference.cpp */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 742}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 927}"; - }; - }; - A93E69ED10420ABF007D418B /* runtime.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {798, 3990}}"; - sepNavSelRange = "{1030, 18}"; - sepNavVisRange = "{9125, 493}"; - }; - }; - A93E69F110420ABF007D418B /* version.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {481, 532}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 844}"; - }; - }; - A93E69F710420ABF007D418B /* keeper.lch */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 3094}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 1141}"; - }; - }; - A93E6A0410420ABF007D418B /* auxiliar.c */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 2156}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 765}"; - }; - }; - A93E6A2C10420AC0007D418B /* unix.c */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 5054}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 534}"; - }; - }; - A93E6A3010420AC0007D418B /* usocket.c */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 5250}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 728}"; - }; - }; - A93E6A3110420AC0007D418B /* usocket.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {1206, 641}}"; - sepNavSelRange = "{601, 0}"; - sepNavVisRange = "{0, 1146}"; - sepNavWindowFrame = "{{15, 4}, {1265, 769}}"; - }; - }; - A93E6A3410420AC0007D418B /* love.cpp */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {606, 2576}}"; - sepNavSelRange = "{4804, 0}"; - sepNavVisRange = "{3953, 397}"; - }; - }; - A93E6A4410420AC0007D418B /* Audio.cpp */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {468, 2590}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 674}"; - }; - }; - A93E6A4510420AC0007D418B /* Audio.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {481, 1624}}"; - sepNavSelRange = "{1170, 127}"; - sepNavVisRange = "{1062, 295}"; - }; - }; - A93E6A4710420AC0007D418B /* Music.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {481, 1064}}"; - sepNavSelRange = "{1084, 127}"; - sepNavVisRange = "{1065, 229}"; - }; - }; - A93E6A4910420AC0007D418B /* Pool.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {481, 1806}}"; - sepNavSelRange = "{1297, 0}"; - sepNavVisRange = "{1139, 229}"; - }; - }; - A93E6A4A10420AC0007D418B /* Sound.cpp */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 1008}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 926}"; - }; - }; - A93E6A4B10420AC0007D418B /* Sound.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {481, 980}}"; - sepNavSelRange = "{1242, 0}"; - sepNavVisRange = "{1066, 274}"; - }; - }; - A93E6A4D10420AC0007D418B /* Source.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {481, 1190}}"; - sepNavSelRange = "{1243, 0}"; - sepNavVisRange = "{1095, 229}"; - }; - }; - A93E6A5210420AC0007D418B /* wrap_Audio.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 798}}"; - sepNavSelRange = "{1721, 64}"; - sepNavVisRange = "{1247, 565}"; - }; - }; - A93E6A5E10420AC1007D418B /* wrap_Event.cpp */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 1260}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 927}"; - }; - }; - A93E6A6B10420AC1007D418B /* wrap_FileData.cpp */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 798}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 908}"; - }; - }; - A93E6A7510420AC2007D418B /* wrap_Font.cpp */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 1064}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 927}"; - }; - }; - A93E6A8910420AC2007D418B /* GLee.c */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 182112}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 847}"; - }; - }; - A93E6A8D10420AC2007D418B /* Graphics.cpp */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {696, 17220}}"; - sepNavSelRange = "{2543, 0}"; - sepNavVisRange = "{2152, 690}"; - }; - }; - A93E6A8E10420AC2007D418B /* Graphics.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {481, 7588}}"; - sepNavSelRange = "{2168, 0}"; - sepNavVisRange = "{1975, 342}"; - }; - }; - A93E6A9010420AC2007D418B /* Image.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 2002}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{1597, 394}"; - }; - }; - A93E6AB210420AC3007D418B /* wrap_ImageData.cpp */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 1932}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 927}"; - }; - }; - A93E6AB710420AC3007D418B /* Joystick.cpp */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 2968}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 926}"; - }; - }; - A93E6AB910420AC3007D418B /* wrap_Joystick.cpp */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 2366}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 927}"; - }; - }; - A93E6ABE10420AC3007D418B /* Keyboard.cpp */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 812}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 926}"; - }; - }; - A93E6AC510420AC3007D418B /* Mouse.cpp */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 980}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 926}"; - }; - }; - A93E6AC710420AC3007D418B /* wrap_Mouse.cpp */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 1694}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 927}"; - }; - }; - A93E6ACB10420AC3007D418B /* api.c */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {481, 1680}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{1254, 265}"; - }; - }; - A93E6AD710420AC5007D418B /* libtcc.c */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {444, 31906}}"; - sepNavSelRange = "{39418, 40}"; - sepNavVisRange = "{39238, 339}"; - sepNavWindowFrame = "{{15, 4}, {1265, 769}}"; - }; - }; - A93E6AD810420AC5007D418B /* libtcc.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 1526}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 299}"; - }; - }; - A93E6AD910420AC5007D418B /* stab.def */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 3332}}"; - sepNavSelRange = "{8422, 0}"; - sepNavVisRange = "{8041, 701}"; - }; - }; - A93E6ADB10420AC5007D418B /* tcc.c */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {498, 7854}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{16939, 512}"; - sepNavWindowFrame = "{{15, 4}, {1265, 769}}"; - }; - }; - A93E6ADC10420AC5007D418B /* tcc.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {481, 10990}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{2051, 632}"; - sepNavWindowFrame = "{{15, 4}, {1265, 769}}"; - }; - }; - A93E6ADF10420AC6007D418B /* tccelf.c */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 38388}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 822}"; - }; - }; - A93E6AE210420AC7007D418B /* tccpp.c */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {481, 40502}}"; - sepNavSelRange = "{5078, 31}"; - sepNavVisRange = "{4906, 460}"; - }; - }; - A93E6AE510420AC7007D418B /* Native.cpp */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 2282}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{598, 493}"; - }; - }; - A93E6AE610420AC7007D418B /* Native.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 1162}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{844, 283}"; - }; - }; - A93E6AE710420AC7007D418B /* wrap_Native.cpp */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 1792}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 927}"; - }; - }; - A93E6AF010420AC7007D418B /* Contact.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {468, 1526}}"; - sepNavSelRange = "{1359, 0}"; - sepNavVisRange = "{1199, 238}"; - }; - }; - A93E6B0810420AC8007D418B /* Shape.cpp */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 2660}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 927}"; - }; - }; - A93E6B1710420AC8007D418B /* b2CircleShape.cpp */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 1568}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 947}"; - }; - }; - A93E6B5810420ACA007D418B /* wrap_GearJoint.cpp */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 854}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 927}"; - }; - }; - A93E6B7010420ACB007D418B /* Signal.cpp */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 896}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 908}"; - }; - }; - A93E6B7110420ACB007D418B /* Signal.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 812}}"; - sepNavSelRange = "{1377, 23}"; - sepNavVisRange = "{4, 905}"; - }; - }; - A93E6B7210420ACB007D418B /* wrap_Signal.cpp */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 1106}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 908}"; - }; - }; - A93E6B7910420ACB007D418B /* FLACDecoder.cpp */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 2296}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 908}"; - }; - }; - A93E6B7F10420ACB007D418B /* Sound.cpp */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {618, 1050}}"; - sepNavSelRange = "{1940, 0}"; - sepNavVisRange = "{0, 926}"; - }; - }; - A93E6B9710420ACC007D418B /* boot.lua */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {481, 9702}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 391}"; - }; - }; - A93E6B9810420ACC007D418B /* boot.lua.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 9926}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 1228}"; - }; - }; - A9D8FBD21043E5320063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A93E6A8910420AC2007D418B /* GLee.c */; - name = "GLee.c: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 847; - vrLoc = 0; - }; - A9D8FBE01043E5AE0063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - comments = "warning: 'OV_CALLBACKS_DEFAULT' defined but not used"; - fRef = A9D8FBE11043E5AE0063561F /* vorbisfile.h */; - rLen = 1; - rLoc = 55; - rType = 1; - }; - A9D8FBE11043E5AE0063561F /* vorbisfile.h */ = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = vorbisfile.h; - path = /opt/local/include/vorbis/vorbisfile.h; - sourceTree = ""; - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 2464}}"; - sepNavSelRange = "{2279, 45}"; - sepNavVisRange = "{1931, 733}"; - }; - }; - A9D8FBE21043E5AE0063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9D8FBE31043E5AE0063561F /* vorbisfile.h */; - name = "vorbisfile.h: 56"; - rLen = 45; - rLoc = 2279; - rType = 0; - vrLen = 629; - vrLoc = 1931; - }; - A9D8FBE31043E5AE0063561F /* vorbisfile.h */ = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.c.h; - name = vorbisfile.h; - path = /opt/local/include/vorbis/vorbisfile.h; - sourceTree = ""; - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {492, 2618}}"; - sepNavSelRange = "{2279, 45}"; - sepNavVisRange = "{1931, 629}"; - }; - }; - A9D8FBE71043E5C10063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A93E6A8910420AC2007D418B /* GLee.c */; - name = "GLee.c: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 847; - vrLoc = 0; - }; - A9D8FBE81043E5C10063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A93E6B7910420ACB007D418B /* FLACDecoder.cpp */; - name = "FLACDecoder.cpp: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 908; - vrLoc = 0; - }; - A9D8FBE91043E5C10063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A93E6B7F10420ACB007D418B /* Sound.cpp */; - name = "Sound.cpp: 63"; - rLen = 0; - rLoc = 1940; - rType = 0; - vrLen = 926; - vrLoc = 0; - }; - A9D8FBEA1043E5C10063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A93E6A8910420AC2007D418B /* GLee.c */; - name = "GLee.c: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 847; - vrLoc = 0; - }; - A9D8FBEB1043E5C10063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A93E6B7910420ACB007D418B /* FLACDecoder.cpp */; - name = "FLACDecoder.cpp: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 908; - vrLoc = 0; - }; - A9D8FBEC1043E5C10063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A93E6B7F10420ACB007D418B /* Sound.cpp */; - name = "Sound.cpp: 63"; - rLen = 0; - rLoc = 1940; - rType = 0; - vrLen = 926; - vrLoc = 0; - }; - A9D8FBED1043E5C10063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9D8FBE11043E5AE0063561F /* vorbisfile.h */; - name = "vorbisfile.h: 56"; - rLen = 45; - rLoc = 2279; - rType = 0; - vrLen = 733; - vrLoc = 1931; - }; - A9D8FBFC1043E7C20063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9D8FBE11043E5AE0063561F /* vorbisfile.h */; - name = "vorbisfile.h: 56"; - rLen = 45; - rLoc = 2279; - rType = 0; - vrLen = 733; - vrLoc = 1931; - }; - A9D8FC011043E8770063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9D8FBE11043E5AE0063561F /* vorbisfile.h */; - name = "vorbisfile.h: 56"; - rLen = 45; - rLoc = 2279; - rType = 0; - vrLen = 733; - vrLoc = 1931; - }; - A9D8FC031043E94F0063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9D8FBE11043E5AE0063561F /* vorbisfile.h */; - name = "vorbisfile.h: 56"; - rLen = 45; - rLoc = 2279; - rType = 0; - vrLen = 733; - vrLoc = 1931; - }; - A9D8FC041043E94F0063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9255DEA1043188D00BA1496 /* SDLMain.m */; - name = "SDLMain.m: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 604; - vrLoc = 0; - }; - A9D8FC051043E94F0063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9D8FBE11043E5AE0063561F /* vorbisfile.h */; - name = "vorbisfile.h: 56"; - rLen = 45; - rLoc = 2279; - rType = 0; - vrLen = 733; - vrLoc = 1931; - }; - A9D8FC061043E94F0063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9255DEA1043188D00BA1496 /* SDLMain.m */; - name = "SDLMain.m: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 549; - vrLoc = 347; - }; - A9D8FC0D1043EBD30063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9255DEA1043188D00BA1496 /* SDLMain.m */; - name = "SDLMain.m: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 596; - vrLoc = 561; - }; - A9D8FC131043EC200063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9255DEA1043188D00BA1496 /* SDLMain.m */; - name = "SDLMain.m: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 596; - vrLoc = 561; - }; - A9D8FC1E1043EFA00063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9255DEA1043188D00BA1496 /* SDLMain.m */; - name = "SDLMain.m: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 596; - vrLoc = 561; - }; - A9D8FC2010441C030063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9255DEA1043188D00BA1496 /* SDLMain.m */; - name = "SDLMain.m: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 596; - vrLoc = 561; - }; - A9D8FC2110441C0F0063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9255DEA1043188D00BA1496 /* SDLMain.m */; - name = "SDLMain.m: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 596; - vrLoc = 561; - }; - A9D8FC2410441DF10063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9255DEA1043188D00BA1496 /* SDLMain.m */; - name = "SDLMain.m: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 596; - vrLoc = 561; - }; - A9D8FC2510441E590063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9255DEA1043188D00BA1496 /* SDLMain.m */; - name = "SDLMain.m: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 596; - vrLoc = 561; - }; - A9D8FC2610441E700063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9255DEA1043188D00BA1496 /* SDLMain.m */; - name = "SDLMain.m: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 596; - vrLoc = 561; - }; - A9D8FC2710441E890063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9255DEA1043188D00BA1496 /* SDLMain.m */; - name = "SDLMain.m: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 596; - vrLoc = 561; - }; - A9D8FC2910441E9B0063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9255DEA1043188D00BA1496 /* SDLMain.m */; - name = "SDLMain.m: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 596; - vrLoc = 561; - }; - A9D8FC2F104423D80063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9D8FBE31043E5AE0063561F /* vorbisfile.h */; - name = "vorbisfile.h: 56"; - rLen = 45; - rLoc = 2279; - rType = 0; - vrLen = 629; - vrLoc = 1931; - }; - A9D8FC30104423D80063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - comments = "error: 'struct mcontext' has no member named '__ss'"; - fRef = A93E6AD710420AC5007D418B /* libtcc.c */; - rLen = 1; - rLoc = 1480; - rType = 1; - }; - A9D8FC31104423D80063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9D8FBE31043E5AE0063561F /* vorbisfile.h */; - name = "vorbisfile.h: 56"; - rLen = 45; - rLoc = 2279; - rType = 0; - vrLen = 629; - vrLoc = 1931; - }; - A9D8FC32104423D80063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A93E6AD710420AC5007D418B /* libtcc.c */; - name = "libtcc.c: 1481"; - rLen = 40; - rLoc = 39418; - rType = 0; - vrLen = 300; - vrLoc = 39238; - }; - A9D8FC36104423F90063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9255DEA1043188D00BA1496 /* SDLMain.m */; - name = "SDLMain.m: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 596; - vrLoc = 561; - }; - A9D8FC3D104427770063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9255DEA1043188D00BA1496 /* SDLMain.m */; - name = "SDLMain.m: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 596; - vrLoc = 561; - }; - A9D8FC3F104427A10063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9255DEA1043188D00BA1496 /* SDLMain.m */; - name = "SDLMain.m: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 596; - vrLoc = 561; - }; - A9D8FC40104427AE0063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9255DEA1043188D00BA1496 /* SDLMain.m */; - name = "SDLMain.m: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 596; - vrLoc = 561; - }; - A9D8FC421044283D0063561F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9255DEA1043188D00BA1496 /* SDLMain.m */; - name = "SDLMain.m: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 596; - vrLoc = 561; - }; - A9DE83571043CE2800567BA4 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A93E6B7110420ACB007D418B /* Signal.h */; - name = "Signal.h: 52"; - rLen = 23; - rLoc = 1377; - rType = 0; - vrLen = 905; - vrLoc = 4; - }; - A9DE83591043CE2800567BA4 /* Makefile */ = { - isa = PBXFileReference; - lastKnownFileType = sourcecode.make; - name = Makefile; - path = "/Users/bill/Downloads/flac-1.2.1/src/libFLAC++/Makefile"; - sourceTree = ""; - }; - A9DE835A1043CE2800567BA4 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A93E6B7110420ACB007D418B /* Signal.h */; - name = "Signal.h: 52"; - rLen = 23; - rLoc = 1377; - rType = 0; - vrLen = 905; - vrLoc = 4; - }; - A9DE83781043CFEF00567BA4 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9DE83591043CE2800567BA4 /* Makefile */; - name = "Makefile: 608"; - rLen = 0; - rLoc = 18653; - rType = 0; - vrLen = 753; - vrLoc = 233; - }; - A9DE83791043CFEF00567BA4 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A93E6ADF10420AC6007D418B /* tccelf.c */; - name = "tccelf.c: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 822; - vrLoc = 0; - }; - A9DE837A1043CFEF00567BA4 /* PBXBookmark */ = { - isa = PBXBookmark; - fRef = A93E6A8910420AC2007D418B /* GLee.c */; - }; - A9DE837B1043CFEF00567BA4 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A9DE83591043CE2800567BA4 /* Makefile */; - name = "Makefile: 608"; - rLen = 0; - rLoc = 18653; - rType = 0; - vrLen = 753; - vrLoc = 233; - }; - A9DE837C1043CFEF00567BA4 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A93E6ADF10420AC6007D418B /* tccelf.c */; - name = "tccelf.c: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 822; - vrLoc = 0; - }; - A9DE85AA1043E49900567BA4 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = A93E6A8910420AC2007D418B /* GLee.c */; - name = "GLee.c: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 847; - vrLoc = 0; - }; -} diff --git a/love/src/jni/love/platform/macosx/love.xcodeproj/project.pbxproj b/love/src/jni/love/platform/macosx/love.xcodeproj/project.pbxproj deleted file mode 100644 index c1e0dad5..00000000 --- a/love/src/jni/love/platform/macosx/love.xcodeproj/project.pbxproj +++ /dev/null @@ -1,508 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; - A9255DD11043183600BA1496 /* FreeType.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E4810420B4A007D418B /* FreeType.framework */; }; - A9255DD31043183600BA1496 /* Lua.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E5310420B57007D418B /* Lua.framework */; }; - A9255E031043195A00BA1496 /* Vorbis.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9255E021043195A00BA1496 /* Vorbis.framework */; }; - A9255F431043240F00BA1496 /* IL.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9255F421043240F00BA1496 /* IL.framework */; }; - A9255F58104324E100BA1496 /* Ogg.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9255F51104324D700BA1496 /* Ogg.framework */; }; - A93E6E5510420B57007D418B /* Lua.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E5310420B57007D418B /* Lua.framework */; }; - A93E6EED10420BA8007D418B /* love.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6A3410420AC0007D418B /* love.cpp */; }; - A9D307F2106635D3004FEDF8 /* physfs.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9D307E9106635C3004FEDF8 /* physfs.framework */; }; - A9DEC1C11046EFA70049C70C /* Love.icns in Resources */ = {isa = PBXBuildFile; fileRef = A9DEC1BF1046EFA60049C70C /* Love.icns */; }; - A9DEC1C21046EFA70049C70C /* LoveDocument.icns in Resources */ = {isa = PBXBuildFile; fileRef = A9DEC1C01046EFA70049C70C /* LoveDocument.icns */; }; - A9F169AC109E825000FC83D1 /* mpg123.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9F169A6109E824900FC83D1 /* mpg123.framework */; }; - A9F169AD109E825000FC83D1 /* libmodplug.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9F16926109E7BAD00FC83D1 /* libmodplug.framework */; }; - FA08F69616C766E000F007B5 /* love.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA08F69116C765A200F007B5 /* love.framework */; }; - FA08F69716C766E700F007B5 /* love.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FA08F69116C765A200F007B5 /* love.framework */; }; - FA9B4A0A16E1579F00074F42 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA9B4A0916E1579F00074F42 /* SDL2.framework */; }; - FA9B4A0B16E157B500074F42 /* SDL2.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FA9B4A0916E1579F00074F42 /* SDL2.framework */; }; - FAAFF04716CB120000CCDE45 /* OpenAL-Soft.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FAAFF04616CB120000CCDE45 /* OpenAL-Soft.framework */; }; - FAC1A449196F5DC600125284 /* license.txt in Resources */ = {isa = PBXBuildFile; fileRef = FAC1A448196F5DC600125284 /* license.txt */; }; - FAC8E8D416F3C468004DADF3 /* OSX.mm in Sources */ = {isa = PBXBuildFile; fileRef = FAC8E8D316F3C468004DADF3 /* OSX.mm */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - FA08F6A616C77A4300F007B5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = FA577A9316C7217800860150 /* love-framework.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = FA577AAF16C7507900860150; - remoteInfo = "love framework"; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - A9255DDE1043185300BA1496 /* Copy Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - FA08F69716C766E700F007B5 /* love.framework in Copy Frameworks */, - FA9B4A0B16E157B500074F42 /* SDL2.framework in Copy Frameworks */, - FAAFF04716CB120000CCDE45 /* OpenAL-Soft.framework in Copy Frameworks */, - A9F169AC109E825000FC83D1 /* mpg123.framework in Copy Frameworks */, - A9F169AD109E825000FC83D1 /* libmodplug.framework in Copy Frameworks */, - A9D307F2106635D3004FEDF8 /* physfs.framework in Copy Frameworks */, - A9255F58104324E100BA1496 /* Ogg.framework in Copy Frameworks */, - A9255F431043240F00BA1496 /* IL.framework in Copy Frameworks */, - A9255E031043195A00BA1496 /* Vorbis.framework in Copy Frameworks */, - A9255DD11043183600BA1496 /* FreeType.framework in Copy Frameworks */, - A9255DD31043183600BA1496 /* Lua.framework in Copy Frameworks */, - ); - name = "Copy Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; - 8D1107320486CEB800E47090 /* love.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = love.app; sourceTree = BUILT_PRODUCTS_DIR; }; - A9255E021043195A00BA1496 /* Vorbis.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Vorbis.framework; path = /Library/Frameworks/Vorbis.framework; sourceTree = ""; }; - A9255F421043240F00BA1496 /* IL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IL.framework; path = /Library/Frameworks/IL.framework; sourceTree = ""; }; - A9255F51104324D700BA1496 /* Ogg.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Ogg.framework; path = /Library/Frameworks/Ogg.framework; sourceTree = ""; }; - A93E6A3410420AC0007D418B /* love.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = love.cpp; path = ../../src/love.cpp; sourceTree = ""; }; - A93E6E4710420B4A007D418B /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = ""; }; - A93E6E4810420B4A007D418B /* FreeType.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FreeType.framework; path = /Library/Frameworks/FreeType.framework; sourceTree = ""; }; - A93E6E5310420B57007D418B /* Lua.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Lua.framework; path = /Library/Frameworks/Lua.framework; sourceTree = ""; }; - A97E3842132A9EDE00198A2F /* love-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "love-Info.plist"; sourceTree = ""; }; - A9D307E9106635C3004FEDF8 /* physfs.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = physfs.framework; path = /Library/Frameworks/physfs.framework; sourceTree = ""; }; - A9DEC1BF1046EFA60049C70C /* Love.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = Love.icns; path = icons/Love.icns; sourceTree = ""; }; - A9DEC1C01046EFA70049C70C /* LoveDocument.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = LoveDocument.icns; path = icons/LoveDocument.icns; sourceTree = ""; }; - A9F16926109E7BAD00FC83D1 /* libmodplug.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = libmodplug.framework; path = /Library/Frameworks/libmodplug.framework; sourceTree = ""; }; - A9F169A6109E824900FC83D1 /* mpg123.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mpg123.framework; path = /Library/Frameworks/mpg123.framework; sourceTree = ""; }; - FA08F69116C765A200F007B5 /* love.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = love.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - FA577A9316C7217800860150 /* love-framework.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = "love-framework.xcodeproj"; sourceTree = ""; }; - FA9B4A0916E1579F00074F42 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = /Library/Frameworks/SDL2.framework; sourceTree = ""; }; - FAAFF04616CB120000CCDE45 /* OpenAL-Soft.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "OpenAL-Soft.framework"; path = "/Library/Frameworks/OpenAL-Soft.framework"; sourceTree = ""; }; - FAC1A448196F5DC600125284 /* license.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = license.txt; path = ../../license.txt; sourceTree = ""; }; - FAC8E8D316F3C468004DADF3 /* OSX.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OSX.mm; sourceTree = ""; }; - FAC8E8D616F3C46E004DADF3 /* OSX.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSX.h; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 8D11072E0486CEB800E47090 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - FA08F69616C766E000F007B5 /* love.framework in Frameworks */, - 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, - A93E6E5510420B57007D418B /* Lua.framework in Frameworks */, - FA9B4A0A16E1579F00074F42 /* SDL2.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 1058C7A0FEA54F0111CA2CBB /* Frameworks */ = { - isa = PBXGroup; - children = ( - FA9B4A0916E1579F00074F42 /* SDL2.framework */, - 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, - A93E6E4810420B4A007D418B /* FreeType.framework */, - A9255F421043240F00BA1496 /* IL.framework */, - A9F16926109E7BAD00FC83D1 /* libmodplug.framework */, - FA08F69116C765A200F007B5 /* love.framework */, - A93E6E5310420B57007D418B /* Lua.framework */, - A9F169A6109E824900FC83D1 /* mpg123.framework */, - A9255F51104324D700BA1496 /* Ogg.framework */, - FAAFF04616CB120000CCDE45 /* OpenAL-Soft.framework */, - A93E6E4710420B4A007D418B /* OpenGL.framework */, - A9D307E9106635C3004FEDF8 /* physfs.framework */, - A9255E021043195A00BA1496 /* Vorbis.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 19C28FACFE9D520D11CA2CBB /* Products */ = { - isa = PBXGroup; - children = ( - 8D1107320486CEB800E47090 /* love.app */, - ); - name = Products; - sourceTree = ""; - }; - 29B97314FDCFA39411CA2CEA /* love */ = { - isa = PBXGroup; - children = ( - FA577A9D16C7262E00860150 /* Source */, - 1058C7A0FEA54F0111CA2CBB /* Frameworks */, - 29B97317FDCFA39411CA2CEA /* Resources */, - 19C28FACFE9D520D11CA2CBB /* Products */, - FA577A9316C7217800860150 /* love-framework.xcodeproj */, - ); - name = love; - sourceTree = ""; - usesTabs = 1; - }; - 29B97317FDCFA39411CA2CEA /* Resources */ = { - isa = PBXGroup; - children = ( - FAC1A448196F5DC600125284 /* license.txt */, - A97E3842132A9EDE00198A2F /* love-Info.plist */, - A9DEC1BF1046EFA60049C70C /* Love.icns */, - A9DEC1C01046EFA70049C70C /* LoveDocument.icns */, - ); - name = Resources; - sourceTree = ""; - }; - FA08F6A316C77A4300F007B5 /* Products */ = { - isa = PBXGroup; - children = ( - FA08F6A716C77A4300F007B5 /* love.framework */, - ); - name = Products; - sourceTree = ""; - }; - FA577A9D16C7262E00860150 /* Source */ = { - isa = PBXGroup; - children = ( - A93E6A3410420AC0007D418B /* love.cpp */, - FAC8E8D616F3C46E004DADF3 /* OSX.h */, - FAC8E8D316F3C468004DADF3 /* OSX.mm */, - ); - name = Source; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 8D1107260486CEB800E47090 /* love */ = { - isa = PBXNativeTarget; - buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "love" */; - buildPhases = ( - 8D1107290486CEB800E47090 /* Resources */, - 8D11072C0486CEB800E47090 /* Sources */, - A9255DDE1043185300BA1496 /* Copy Frameworks */, - 8D11072E0486CEB800E47090 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = love; - productInstallPath = "$(HOME)/Applications"; - productName = love; - productReference = 8D1107320486CEB800E47090 /* love.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 29B97313FDCFA39411CA2CEA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0510; - }; - buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "love" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 1; - knownRegions = ( - English, - Japanese, - French, - German, - ); - mainGroup = 29B97314FDCFA39411CA2CEA /* love */; - projectDirPath = ""; - projectReferences = ( - { - ProductGroup = FA08F6A316C77A4300F007B5 /* Products */; - ProjectRef = FA577A9316C7217800860150 /* love-framework.xcodeproj */; - }, - ); - projectRoot = ""; - targets = ( - 8D1107260486CEB800E47090 /* love */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXReferenceProxy section */ - FA08F6A716C77A4300F007B5 /* love.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = love.framework; - remoteRef = FA08F6A616C77A4300F007B5 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; -/* End PBXReferenceProxy section */ - -/* Begin PBXResourcesBuildPhase section */ - 8D1107290486CEB800E47090 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - FAC1A449196F5DC600125284 /* license.txt in Resources */, - A9DEC1C11046EFA70049C70C /* Love.icns in Resources */, - A9DEC1C21046EFA70049C70C /* LoveDocument.icns in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 8D11072C0486CEB800E47090 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - A93E6EED10420BA8007D418B /* love.cpp in Sources */, - FAC8E8D416F3C468004DADF3 /* OSX.mm in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - C01FCF4B08A954540054247B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/build/Release\"", - "\"$(SRCROOT)/build/Debug\"", - ); - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - INSTALL_PATH = /Applications; - PRODUCT_NAME = love; - }; - name = Debug; - }; - C01FCF4C08A954540054247B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - COMBINE_HIDPI_IMAGES = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/build/Release\"", - "\"$(SRCROOT)/build/Debug\"", - ); - INSTALL_PATH = /Applications; - PRODUCT_NAME = love; - }; - name = Release; - }; - C01FCF4F08A954540054247B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; - CLANG_ENABLE_MODULES = YES; - FRAMEWORK_SEARCH_PATHS = /Library/Frameworks; - GCC_INCREASE_PRECOMPILED_HEADER_SHARING = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = LOVE_MACOSX_USE_FRAMEWORKS; - GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = NO; - GCC_WARN_ABOUT_MISSING_NEWLINE = NO; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; - GCC_WARN_ABOUT_POINTER_SIGNEDNESS = YES; - GCC_WARN_ABOUT_RETURN_TYPE = NO; - GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; - GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; - GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = NO; - GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = NO; - GCC_WARN_MISSING_PARENTHESES = NO; - GCC_WARN_NON_VIRTUAL_DESTRUCTOR = NO; - GCC_WARN_PEDANTIC = NO; - GCC_WARN_SHADOW = NO; - GCC_WARN_SIGN_COMPARE = YES; - GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ( - "\"$(SRCROOT)/../../src\"", - "\"$(SRCROOT)/../../src/libraries\"", - "\"$(SRCROOT)/../../src/modules\"", - /Library/Frameworks/Lua.framework/Headers, - /Library/Frameworks/SDL2.framework/Headers, - ); - INFOPLIST_FILE = "love-Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.6; - ONLY_ACTIVE_ARCH = YES; - OTHER_LDFLAGS = ""; - "OTHER_LDFLAGS[arch=x86_64]" = ( - "-pagezero_size", - 10000, - "-image_base", - 100000000, - ); - PRODUCT_NAME = love; - WARNING_CFLAGS = ( - "-Wall", - "-W", - ); - }; - name = Debug; - }; - C01FCF5008A954540054247B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; - CLANG_ENABLE_MODULES = YES; - DEPLOYMENT_POSTPROCESSING = NO; - FRAMEWORK_SEARCH_PATHS = /Library/Frameworks; - GCC_INPUT_FILETYPE = automatic; - GCC_OPTIMIZATION_LEVEL = 3; - GCC_PREPROCESSOR_DEFINITIONS = LOVE_MACOSX_USE_FRAMEWORKS; - GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = NO; - GCC_WARN_ABOUT_MISSING_NEWLINE = NO; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; - GCC_WARN_ABOUT_POINTER_SIGNEDNESS = YES; - GCC_WARN_ABOUT_RETURN_TYPE = NO; - GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; - GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; - GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = NO; - GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = NO; - GCC_WARN_MISSING_PARENTHESES = NO; - GCC_WARN_NON_VIRTUAL_DESTRUCTOR = NO; - GCC_WARN_PEDANTIC = NO; - GCC_WARN_SHADOW = NO; - GCC_WARN_SIGN_COMPARE = YES; - GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO; - GCC_WARN_UNUSED_PARAMETER = NO; - GCC_WARN_UNUSED_VALUE = NO; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ( - "\"$(SRCROOT)/../../src\"", - "\"$(SRCROOT)/../../src/libraries\"", - "\"$(SRCROOT)/../../src/modules\"", - /Library/Frameworks/Lua.framework/Headers, - /Library/Frameworks/SDL2.framework/Headers, - ); - INFOPLIST_FILE = "love-Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks"; - LLVM_LTO = YES; - MACOSX_DEPLOYMENT_TARGET = 10.6; - ONLY_ACTIVE_ARCH = NO; - OTHER_LDFLAGS = ""; - "OTHER_LDFLAGS[arch=x86_64]" = ( - "-pagezero_size", - 10000, - "-image_base", - 100000000, - ); - PRODUCT_NAME = love; - SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = YES; - WARNING_CFLAGS = ( - "-Wall", - "-W", - ); - }; - name = Release; - }; - FA5326C618971A0900F7BBF4 /* Distribution */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; - CLANG_ENABLE_MODULES = YES; - DEPLOYMENT_POSTPROCESSING = NO; - FRAMEWORK_SEARCH_PATHS = /Library/Frameworks; - GCC_INPUT_FILETYPE = automatic; - GCC_OPTIMIZATION_LEVEL = 3; - GCC_PREPROCESSOR_DEFINITIONS = LOVE_MACOSX_USE_FRAMEWORKS; - GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = NO; - GCC_WARN_ABOUT_MISSING_NEWLINE = NO; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; - GCC_WARN_ABOUT_POINTER_SIGNEDNESS = YES; - GCC_WARN_ABOUT_RETURN_TYPE = NO; - GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; - GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; - GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = NO; - GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = NO; - GCC_WARN_MISSING_PARENTHESES = NO; - GCC_WARN_NON_VIRTUAL_DESTRUCTOR = NO; - GCC_WARN_PEDANTIC = NO; - GCC_WARN_SHADOW = NO; - GCC_WARN_SIGN_COMPARE = YES; - GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO; - GCC_WARN_UNUSED_PARAMETER = NO; - GCC_WARN_UNUSED_VALUE = NO; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ( - "\"$(SRCROOT)/../../src\"", - "\"$(SRCROOT)/../../src/libraries\"", - "\"$(SRCROOT)/../../src/modules\"", - /Library/Frameworks/Lua.framework/Headers, - /Library/Frameworks/SDL2.framework/Headers, - ); - INFOPLIST_FILE = "love-Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks"; - LLVM_LTO = YES; - MACOSX_DEPLOYMENT_TARGET = 10.6; - ONLY_ACTIVE_ARCH = NO; - OTHER_LDFLAGS = ""; - "OTHER_LDFLAGS[arch=x86_64]" = ( - "-pagezero_size", - 10000, - "-image_base", - 100000000, - ); - PRODUCT_NAME = love; - SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = YES; - WARNING_CFLAGS = ( - "-Wall", - "-W", - ); - }; - name = Distribution; - }; - FA5326C718971A0900F7BBF4 /* Distribution */ = { - isa = XCBuildConfiguration; - buildSettings = { - COMBINE_HIDPI_IMAGES = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/build/Release\"", - "\"$(SRCROOT)/build/Debug\"", - ); - INSTALL_PATH = /Applications; - PRODUCT_NAME = love; - }; - name = Distribution; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "love" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C01FCF4B08A954540054247B /* Debug */, - C01FCF4C08A954540054247B /* Release */, - FA5326C718971A0900F7BBF4 /* Distribution */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - C01FCF4E08A954540054247B /* Build configuration list for PBXProject "love" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C01FCF4F08A954540054247B /* Debug */, - C01FCF5008A954540054247B /* Release */, - FA5326C618971A0900F7BBF4 /* Distribution */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; -} diff --git a/love/src/jni/love/platform/msvc2010/liblove.vcxproj b/love/src/jni/love/platform/msvc2010/liblove.vcxproj deleted file mode 100644 index 8bbf1d65..00000000 --- a/love/src/jni/love/platform/msvc2010/liblove.vcxproj +++ /dev/null @@ -1,847 +0,0 @@ - - - - - Debug Dynamic - Win32 - - - Debug Dynamic - x64 - - - Release Dynamic - Win32 - - - Release Dynamic - x64 - - - Release Static - Win32 - - - Release Static - x64 - - - - {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8} - liblove - - - - DynamicLibrary - true - Unicode - - - DynamicLibrary - true - Unicode - - - StaticLibrary - false - true - Unicode - - - StaticLibrary - false - true - Unicode - - - DynamicLibrary - false - true - Unicode - - - DynamicLibrary - false - true - Unicode - Windows7.1SDK - - - StaticLibrary - Unicode - - - StaticLibrary - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - $(SolutionDir)\$(PlatformShortName)\$(Configuration) - - - $(SolutionDir)\$(PlatformShortName)\$(Configuration) - - - $(ProjectName)\$(Configuration)\ - - - $(ProjectName)\$(Configuration)\ - - - $(SolutionDir)\bin\$(PlatformShortName)\Debug\MD\ - $(ProjectName)\$(PlatformShortName)\Debug\ - false - love - - - $(SolutionDir)\bin\$(PlatformShortName)\Debug\MD\ - $(ProjectName)\$(PlatformShortName)\Debug\ - false - love - - - $(SolutionDir)\bin\$(PlatformShortName)\Release\MT\ - $(ProjectName)\$(PlatformShortName)\Release\ - - - $(SolutionDir)\bin\$(PlatformShortName)\Release\MT\ - $(ProjectName)\$(PlatformShortName)\Release\ - - - $(SolutionDir)\bin\$(PlatformShortName)\Release\MD\ - $(ProjectName)\$(PlatformShortName)\Release\ - false - love - - - $(SolutionDir)\bin\$(PlatformShortName)\Release\MD\ - $(ProjectName)\$(PlatformShortName)\Release\ - false - love - - - - Level3 - Disabled - include;include\SDL;include\AL;..\..\src;..\..\src\libraries;..\..\src\modules;..\..\src\libraries\enet\libenet\include;%(AdditionalIncludeDirectories) - true - _DEBUG;DEBUG;%(PreprocessorDefinitions) - false - MultiThreadedDebugDLL - $(IntDir)obj\obj\obj\%(RelativeDir) - ProgramDatabase - - - true - msvcrtd.lib;msvcprtd.lib;kernel32.lib;user32.lib;shell32.lib;uuid.lib;advapi32.lib;ws2_32.lib;winmm.lib;opengl32.lib;oldnames.lib;DevIL.lib;freetype.lib;libmodplug.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua51.lib;mpg123.lib;physfs.lib;OpenAL.lib;zlib.lib;SDL2.lib;%(AdditionalDependencies) - true - lib\$(PlatformShortName)\Debug\MD\ - $(TargetDir)lib$(TargetName).pdb - $(TargetDir)lib$(TargetName).pgd - - - LOVE_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - - - - - Level3 - Disabled - include;include\SDL;include\AL;..\..\src;..\..\src\libraries;..\..\src\modules;..\..\src\libraries\enet\libenet\include;%(AdditionalIncludeDirectories) - true - _DEBUG;DEBUG;%(PreprocessorDefinitions) - false - MultiThreadedDebugDLL - $(IntDir)obj\obj\obj\%(RelativeDir) - ProgramDatabase - - - true - msvcrtd.lib;msvcprtd.lib;kernel32.lib;user32.lib;shell32.lib;uuid.lib;advapi32.lib;ws2_32.lib;winmm.lib;opengl32.lib;oldnames.lib;DevIL.lib;freetype.lib;libmodplug.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua51.lib;mpg123.lib;physfs.lib;OpenAL.lib;zlib.lib;SDL2.lib;%(AdditionalDependencies) - true - lib\$(PlatformShortName)\Debug\MD\ - $(TargetDir)lib$(TargetName).pdb - $(TargetDir)lib$(TargetName).pgd - - - LOVE_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - - - - - Level3 - MaxSpeed - true - true - include;include\SDL;include\AL;..\..\src;..\..\src\libraries;..\..\src\modules;..\..\src\libraries\enet\libenet\include;%(AdditionalIncludeDirectories) - true - true - NDEBUG;%(PreprocessorDefinitions) - MultiThreaded - false - $(IntDir)obj\obj\obj\%(RelativeDir) - true - - - true - true - true - - - LOVE_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - - - MachineX86 - - - - - true - true - - - - - Level3 - MaxSpeed - true - true - include;include\SDL;include\AL;..\..\src;..\..\src\libraries;..\..\src\modules;..\..\src\libraries\enet\libenet\include;%(AdditionalIncludeDirectories) - true - true - NDEBUG;%(PreprocessorDefinitions) - MultiThreaded - false - $(IntDir)obj\obj\obj\%(RelativeDir) - true - - - true - true - true - - - LOVE_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - - - MachineX64 - - - - - true - true - - - - - Level3 - MaxSpeed - true - true - include;include\SDL;include\AL;..\..\src;..\..\src\libraries;..\..\src\modules;..\..\src\libraries\enet\libenet\include;%(AdditionalIncludeDirectories) - true - true - NDEBUG;%(PreprocessorDefinitions) - MultiThreadedDLL - false - $(IntDir)obj\obj\obj\%(RelativeDir) - true - - - true - true - true - msvcrt.lib;msvcprt.lib;kernel32.lib;user32.lib;shell32.lib;uuid.lib;advapi32.lib;ws2_32.lib;winmm.lib;opengl32.lib;oldnames.lib;DevIL.lib;freetype.lib;libmodplug.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua51.lib;mpg123.lib;physfs.lib;OpenAL.lib;zlib.lib;SDL2.lib;%(AdditionalDependencies) - true - lib\$(PlatformShortName)\Release\MD\ - $(TargetDir)lib$(TargetName).pdb - $(TargetDir)lib$(TargetName).pgd - - - LOVE_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - - - - - Level3 - MaxSpeed - true - true - include;include\SDL;include\AL;..\..\src;..\..\src\libraries;..\..\src\modules;..\..\src\libraries\enet\libenet\include;%(AdditionalIncludeDirectories) - true - true - NDEBUG;%(PreprocessorDefinitions) - MultiThreadedDLL - false - $(IntDir)obj\obj\obj\%(RelativeDir) - true - - - true - true - true - msvcrt.lib;msvcprt.lib;kernel32.lib;user32.lib;shell32.lib;uuid.lib;advapi32.lib;ws2_32.lib;winmm.lib;opengl32.lib;oldnames.lib;DevIL.lib;freetype.lib;libmodplug.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua51.lib;mpg123.lib;physfs.lib;OpenAL.lib;zlib.lib;SDL2.lib;%(AdditionalDependencies) - true - lib\$(PlatformShortName)\Release\MD\ - $(TargetDir)lib$(TargetName).pdb - $(TargetDir)lib$(TargetName).pgd - - - LOVE_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/love/src/jni/love/platform/msvc2010/liblove.vcxproj.filters b/love/src/jni/love/platform/msvc2010/liblove.vcxproj.filters deleted file mode 100644 index b8b83546..00000000 --- a/love/src/jni/love/platform/msvc2010/liblove.vcxproj.filters +++ /dev/null @@ -1,1796 +0,0 @@ - - - - - {9204b296-06f7-44d4-a739-c7bd2f1b6a10} - - - {8db39aa0-6dd9-454e-83e3-337a250a26a7} - - - {c33f8514-328c-435a-83cf-592b907efdf6} - - - {15622628-c450-48d5-af6d-11a81d9b3453} - - - {648d76dd-df9d-458d-beb3-de53e780d07e} - - - {67d48dd8-574e-4bdd-bdb1-71af5801e234} - - - {b00f9fc5-a6a6-44e7-a52d-84c134de265d} - - - {4ed69d3b-2b3e-4bb1-b756-620816c86916} - - - {3c66e3d3-c2fd-409b-88d9-fd6d67df2edd} - - - {7eb57e83-24c3-4b47-a9bb-f73adac7c4c2} - - - {90878f00-844f-453d-a521-76366e3031b2} - - - {7ae21d0a-2dbd-4d89-8ed3-74a0af8e1901} - - - {809e6999-08d1-41b5-9536-bcfe7cc09588} - - - {9c1b1395-34b7-4158-b778-56b622c81e37} - - - {5dcd8aac-7614-4d4e-b507-7df82969cb68} - - - {6f277a7f-c3b8-4eff-bffe-1635d2819c01} - - - {0ceac368-959f-47da-8881-66e22383e2c3} - - - {822de099-663f-46e9-8c22-e2563903b2d1} - - - {374bede6-77d8-4dd9-922c-65ebc1094df4} - - - {83e8ce99-8a0f-4e64-b5be-3c184026aa52} - - - {d9e2d64e-5fd3-4f49-be70-50d5ae85ee26} - - - {679a49ca-08fc-400a-b0ae-30ac2a072b6b} - - - {cc6c06ce-6fa1-46fe-9308-f0844d198123} - - - {e4a78077-53fd-4f65-bc7b-9357fca59d37} - - - {44378345-7eb7-45d5-8f32-fe7e3375ca7b} - - - {03c38556-a58d-4a16-bd8a-26da917b73aa} - - - {a9c040aa-4e09-4a43-b7d4-62ab7e9cde4b} - - - {8ca0aa01-6595-4e00-9257-6668218bfaad} - - - {d0e97654-3e56-4ce0-aa0a-a5b660ade090} - - - {018b53e4-51ff-41ef-8752-530f7ca83f5f} - - - {e3bb8877-dc46-45db-999d-97a3b3482227} - - - {9a56922c-6ee8-4e4a-af76-c310a3052de6} - - - {6c504e35-8799-4ce8-89e7-b4904095efe5} - - - {d78871c7-7ca9-4dff-9163-f2a6a97462d7} - - - {72f85e75-dd35-4a93-9c39-258c8aee813b} - - - {806ac1d0-ed5c-47d5-8cdc-60e3fdbfe412} - - - {1266e902-11b4-4f0d-afb5-66df65b0429c} - - - {7715d905-5dc6-41ce-9aa1-6f94c707ced5} - - - {ad88c2dc-e31c-4362-bd7a-4d76c79d5783} - - - {fe7cb272-ea46-4f31-873a-a8a42e4efd3a} - - - {ea198321-c3fb-4444-bd1e-608461f7af20} - - - {d46cbbf1-a76f-4401-83d4-1f20492f9889} - - - {5fb201c1-9b39-48ca-8334-6862da260b43} - - - {5d2c2149-93bf-42a6-b8b5-6ddbac9485a3} - - - {5673936a-786e-40ee-96d2-1830e89c1532} - - - {dd0ef317-7117-4ddc-b8ef-aaf58130c7bd} - - - {d39bd4fd-3bea-428a-813f-4b1c55aedac8} - - - {d5e565d0-da66-4412-9144-dff8c7d82b2e} - - - {4bf8a9b0-db1a-4a6e-a157-a9eab128f5ca} - - - {ab75aa3d-8e32-45e0-b91b-ed3cb31f472e} - - - {86f5346b-8859-4c03-8c1f-3bd8d200b658} - - - {a9a12c5a-ff54-43c1-b0c6-ba1597af7b03} - - - {731671fa-d695-42c3-9d1c-9e227d9ebab4} - - - {2241f4ca-a51c-4d8d-be82-2b7dfd267b7b} - - - {731671fa-d695-42c3-9d1c-9e227d9ebab4} - - - {2241f4ca-a51c-4d8d-be82-2b7dfd267b7b} - - - {4127f9be-b9c3-45bf-968f-888df9d5bc35} - - - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - libraries\Box2D\Collision - - - libraries\Box2D\Collision - - - libraries\Box2D\Collision - - - libraries\Box2D\Collision - - - libraries\Box2D\Collision - - - libraries\Box2D\Collision - - - libraries\Box2D\Collision - - - libraries\Box2D\Collision - - - libraries\Box2D\Collision\Shapes - - - libraries\Box2D\Collision\Shapes - - - libraries\Box2D\Collision\Shapes - - - libraries\Box2D\Collision\Shapes - - - libraries\Box2D\Common - - - libraries\Box2D\Common - - - libraries\Box2D\Common - - - libraries\Box2D\Common - - - libraries\Box2D\Common - - - libraries\Box2D\Common - - - libraries\Box2D\Dynamcis - - - libraries\Box2D\Dynamcis - - - libraries\Box2D\Dynamcis - - - libraries\Box2D\Dynamcis - - - libraries\Box2D\Dynamcis - - - libraries\Box2D\Dynamcis - - - libraries\Box2D\Dynamcis\Contacts - - - libraries\Box2D\Dynamcis\Contacts - - - libraries\Box2D\Dynamcis\Contacts - - - libraries\Box2D\Dynamcis\Contacts - - - libraries\Box2D\Dynamcis\Contacts - - - libraries\Box2D\Dynamcis\Contacts - - - libraries\Box2D\Dynamcis\Contacts - - - libraries\Box2D\Dynamcis\Contacts - - - libraries\Box2D\Dynamcis\Contacts - - - libraries\Box2D\Dynamcis\Joints - - - libraries\Box2D\Dynamcis\Joints - - - libraries\Box2D\Dynamcis\Joints - - - libraries\Box2D\Dynamcis\Joints - - - libraries\Box2D\Dynamcis\Joints - - - libraries\Box2D\Dynamcis\Joints - - - libraries\Box2D\Dynamcis\Joints - - - libraries\Box2D\Dynamcis\Joints - - - libraries\Box2D\Dynamcis\Joints - - - libraries\Box2D\Dynamcis\Joints - - - libraries\Box2D\Dynamcis\Joints - - - libraries\Box2D\Rope - - - libraries\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - modules\audio - - - modules\audio - - - modules\audio - - - modules\audio - - - modules\audio\null - - - modules\audio\null - - - modules\audio\openal - - - modules\audio\openal - - - modules\audio\openal - - - modules\event - - - modules\event\sdl - - - modules\event\sdl - - - modules\filesystem - - - modules\filesystem - - - modules\filesystem\physfs - - - modules\filesystem\physfs - - - modules\filesystem\physfs - - - modules\filesystem\physfs - - - modules\filesystem\physfs - - - modules\font - - - modules\font - - - modules\font - - - modules\font - - - modules\font - - - modules\font\freetype - - - modules\font\freetype - - - modules\font\freetype - - - modules\graphics - - - modules\graphics - - - modules\graphics - - - modules\graphics - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\image - - - modules\image - - - modules\image - - - modules\joystick - - - modules\joystick\sdl - - - modules\joystick\sdl - - - modules\keyboard - - - modules\keyboard - - - modules\keyboard\sdl - - - modules\mouse - - - modules\mouse - - - modules\mouse\sdl - - - modules\physics - - - modules\physics - - - modules\physics - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\sound - - - modules\sound - - - modules\sound - - - modules\sound - - - modules\sound - - - modules\sound\lullaby - - - modules\sound\lullaby - - - modules\sound\lullaby - - - modules\sound\lullaby - - - modules\sound\lullaby - - - modules\sound\lullaby - - - modules\timer - - - modules\timer\sdl - - - modules\window - - - modules\window\sdl - - - modules\love - - - common - - - modules\math - - - modules\thread - - - modules\thread - - - modules\thread - - - modules\thread - - - modules\thread - - - modules\thread - - - modules\thread - - - modules\thread\sdl - - - modules\thread\sdl - - - modules\math - - - libraries\ddsparse - - - modules\image\magpie - - - modules\image\magpie - - - modules\image\magpie - - - modules\image\magpie - - - modules\image\magpie - - - modules\image - - - modules\image - - - modules\math - - - modules\math - - - libraries\noise1234 - - - modules\math - - - modules\math - - - modules\window - - - libraries\enet\libenet - - - libraries\enet\libenet - - - libraries\enet\libenet - - - libraries\enet\libenet - - - libraries\enet\libenet - - - libraries\enet\libenet - - - libraries\enet\libenet - - - libraries\enet\libenet - - - libraries\enet - - - modules\graphics\opengl - - - modules\joystick\sdl - - - modules\joystick\sdl - - - modules\mouse - - - modules\mouse - - - modules\mouse\sdl - - - modules\system - - - modules\system - - - modules\system\sdl - - - modules\joystick\sdl - - - modules\joystick\sdl - - - modules\mouse - - - modules\mouse - - - modules\mouse\sdl - - - modules\system - - - modules\system - - - modules\system\sdl - - - modules\graphics - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - libraries\Wuff - - - libraries\Wuff - - - libraries\Wuff - - - libraries\Wuff - - - modules\sound\lullaby - - - - - scripts - - - scripts - - - scripts - - - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - common - - - libraries\Box2D - - - libraries\Box2D\Collision - - - libraries\Box2D\Collision - - - libraries\Box2D\Collision - - - libraries\Box2D\Collision - - - libraries\Box2D\Collision - - - libraries\Box2D\Collision\Shapes - - - libraries\Box2D\Collision\Shapes - - - libraries\Box2D\Collision\Shapes - - - libraries\Box2D\Collision\Shapes - - - libraries\Box2D\Collision\Shapes - - - libraries\Box2D\Common - - - libraries\Box2D\Common - - - libraries\Box2D\Common - - - libraries\Box2D\Common - - - libraries\Box2D\Common - - - libraries\Box2D\Common - - - libraries\Box2D\Common - - - libraries\Box2D\Dynamcis - - - libraries\Box2D\Dynamcis - - - libraries\Box2D\Dynamcis - - - libraries\Box2D\Dynamcis - - - libraries\Box2D\Dynamcis - - - libraries\Box2D\Dynamcis - - - libraries\Box2D\Dynamcis - - - libraries\Box2D\Dynamcis\Contacts - - - libraries\Box2D\Dynamcis\Contacts - - - libraries\Box2D\Dynamcis\Contacts - - - libraries\Box2D\Dynamcis\Contacts - - - libraries\Box2D\Dynamcis\Contacts - - - libraries\Box2D\Dynamcis\Contacts - - - libraries\Box2D\Dynamcis\Contacts - - - libraries\Box2D\Dynamcis\Contacts - - - libraries\Box2D\Dynamcis\Contacts - - - libraries\Box2D\Dynamcis\Joints - - - libraries\Box2D\Dynamcis\Joints - - - libraries\Box2D\Dynamcis\Joints - - - libraries\Box2D\Dynamcis\Joints - - - libraries\Box2D\Dynamcis\Joints - - - libraries\Box2D\Dynamcis\Joints - - - libraries\Box2D\Dynamcis\Joints - - - libraries\Box2D\Dynamcis\Joints - - - libraries\Box2D\Dynamcis\Joints - - - libraries\Box2D\Dynamcis\Joints - - - libraries\Box2D\Dynamcis\Joints - - - libraries\Box2D\Rope - - - libraries\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\luasocket\luasocket - - - libraries\utf8 - - - libraries\utf8 - - - libraries\utf8 - - - libraries\utf8 - - - modules\audio - - - modules\audio - - - modules\audio - - - modules\audio - - - modules\audio\null - - - modules\audio\null - - - modules\audio\openal - - - modules\audio\openal - - - modules\audio\openal - - - modules\event - - - modules\event\sdl - - - modules\event\sdl - - - modules\filesystem - - - modules\filesystem - - - modules\filesystem\physfs - - - modules\filesystem\physfs - - - modules\filesystem\physfs - - - modules\filesystem\physfs - - - modules\filesystem\physfs - - - modules\font - - - modules\font - - - modules\font - - - modules\font - - - modules\font - - - modules\font - - - modules\font\freetype - - - modules\font\freetype - - - modules\font\freetype - - - modules\graphics - - - modules\graphics - - - modules\graphics - - - modules\graphics - - - modules\graphics - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\image - - - modules\image - - - modules\image - - - modules\image - - - modules\joystick - - - modules\joystick\sdl - - - modules\joystick\sdl - - - modules\keyboard - - - modules\keyboard - - - modules\keyboard\sdl - - - modules\mouse - - - modules\mouse - - - modules\mouse\sdl - - - modules\physics - - - modules\physics - - - modules\physics - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\physics\box2d - - - modules\sound - - - modules\sound - - - modules\sound - - - modules\sound - - - modules\sound - - - modules\sound - - - modules\sound\lullaby - - - modules\sound\lullaby - - - modules\sound\lullaby - - - modules\sound\lullaby - - - modules\sound\lullaby - - - modules\sound\lullaby - - - modules\timer - - - modules\timer - - - modules\timer\sdl - - - modules\window - - - modules\window\sdl - - - modules\love - - - modules\math - - - modules\thread - - - modules\thread - - - modules\thread - - - modules\thread - - - modules\thread - - - modules\thread - - - modules\thread - - - modules\thread - - - modules\thread\sdl - - - modules\thread\sdl - - - modules\math - - - libraries\ddsparse - - - libraries\ddsparse - - - modules\image\magpie - - - modules\image\magpie - - - modules\image\magpie - - - modules\image\magpie - - - modules\image\magpie - - - modules\image\magpie - - - modules\image - - - modules\image - - - modules\math - - - modules\math - - - libraries\noise1234 - - - modules\math - - - modules\math - - - modules\window - - - libraries\enet - - - libraries\enet\libenet\include\enet - - - libraries\enet\libenet\include\enet - - - libraries\enet\libenet\include\enet - - - libraries\enet\libenet\include\enet - - - libraries\enet\libenet\include\enet - - - libraries\enet\libenet\include\enet - - - libraries\enet\libenet\include\enet - - - libraries\enet\libenet\include\enet - - - libraries\enet\libenet\include\enet - - - modules\graphics\opengl - - - modules\joystick - - - modules\joystick\sdl - - - modules\joystick\sdl - - - modules\mouse - - - modules\mouse - - - modules\mouse\sdl - - - modules\system - - - modules\system - - - modules\system\sdl - - - modules\joystick - - - modules\joystick\sdl - - - modules\joystick\sdl - - - modules\mouse - - - modules\mouse - - - modules\mouse\sdl - - - modules\system - - - modules\system - - - modules\system\sdl - - - modules\graphics - - - modules\graphics - - - modules\graphics\opengl - - - modules\graphics\opengl - - - modules\graphics\opengl - - - libraries\Wuff - - - libraries\Wuff - - - libraries\Wuff - - - libraries\Wuff - - - modules\sound\lullaby - - - - - - \ No newline at end of file diff --git a/love/src/jni/love/platform/msvc2010/love.ico b/love/src/jni/love/platform/msvc2010/love.ico deleted file mode 100644 index 73403aed..00000000 Binary files a/love/src/jni/love/platform/msvc2010/love.ico and /dev/null differ diff --git a/love/src/jni/love/platform/msvc2010/love.rc b/love/src/jni/love/platform/msvc2010/love.rc deleted file mode 100644 index bb620fa1..00000000 Binary files a/love/src/jni/love/platform/msvc2010/love.rc and /dev/null differ diff --git a/love/src/jni/love/platform/msvc2010/love.sln b/love/src/jni/love/platform/msvc2010/love.sln deleted file mode 100644 index 0bb8e317..00000000 --- a/love/src/jni/love/platform/msvc2010/love.sln +++ /dev/null @@ -1,47 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual C++ Express 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "love", "love.vcxproj", "{B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}" - ProjectSection(ProjectDependencies) = postProject - {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8} = {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblove", "liblove.vcxproj", "{A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug MD|Win32 = Debug MD|Win32 - Debug MD|x64 = Debug MD|x64 - Release MD|Win32 = Release MD|Win32 - Release MD|x64 = Release MD|x64 - Release MT|Win32 = Release MT|Win32 - Release MT|x64 = Release MT|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Debug MD|Win32.ActiveCfg = Debug Dynamic|Win32 - {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Debug MD|Win32.Build.0 = Debug Dynamic|Win32 - {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Debug MD|x64.ActiveCfg = Debug Dynamic|x64 - {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release MD|Win32.ActiveCfg = Release Dynamic|Win32 - {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release MD|Win32.Build.0 = Release Dynamic|Win32 - {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release MD|x64.ActiveCfg = Release Dynamic|x64 - {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release MD|x64.Build.0 = Release Dynamic|x64 - {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release MT|Win32.ActiveCfg = Release Static|Win32 - {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release MT|Win32.Build.0 = Release Static|Win32 - {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release MT|x64.ActiveCfg = Release Static|x64 - {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release MT|x64.Build.0 = Release Static|x64 - {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Debug MD|Win32.ActiveCfg = Debug Dynamic|Win32 - {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Debug MD|Win32.Build.0 = Debug Dynamic|Win32 - {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Debug MD|x64.ActiveCfg = Debug Dynamic|x64 - {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Release MD|Win32.ActiveCfg = Release Dynamic|Win32 - {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Release MD|Win32.Build.0 = Release Dynamic|Win32 - {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Release MD|x64.ActiveCfg = Release Dynamic|x64 - {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Release MD|x64.Build.0 = Release Dynamic|x64 - {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Release MT|Win32.ActiveCfg = Release Static|Win32 - {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Release MT|Win32.Build.0 = Release Static|Win32 - {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Release MT|x64.ActiveCfg = Release Static|x64 - {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Release MT|x64.Build.0 = Release Static|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/love/src/jni/love/platform/msvc2010/love.vcxproj b/love/src/jni/love/platform/msvc2010/love.vcxproj deleted file mode 100644 index 1d956c3a..00000000 --- a/love/src/jni/love/platform/msvc2010/love.vcxproj +++ /dev/null @@ -1,273 +0,0 @@ - - - - - Debug Dynamic - Win32 - - - Debug Dynamic - x64 - - - Release Dynamic - Win32 - - - Release Dynamic - x64 - - - Release Static - Win32 - - - Release Static - x64 - - - - Win32Proj - - - - Application - true - Unicode - - - Application - true - Unicode - - - Application - false - Unicode - true - - - Application - false - Unicode - true - Windows7.1SDK - - - Unicode - - - Unicode - - - true - - - true - Windows7.1SDK - - - - - - - - - - - - - - - - - - - false - false - $(SolutionDir)\bin\$(PlatformShortName)\Debug\MD\ - $(ProjectName)\$(PlatformShortName)\Debug\ - - - false - false - $(SolutionDir)\bin\$(PlatformShortName)\Debug\MD\ - $(ProjectName)\$(PlatformShortName)\Debug\ - - - false - $(SolutionDir)\bin\$(PlatformShortName)\Release\MD\ - $(ProjectName)\$(PlatformShortName)\Release\ - false - - - false - $(SolutionDir)\bin\$(PlatformShortName)\Release\MD\ - $(ProjectName)\$(PlatformShortName)\Release\ - false - - - $(SolutionDir)\bin\$(PlatformShortName)\Release\MT\ - $(ProjectName)\$(PlatformShortName)\Release\ - false - false - - - $(SolutionDir)\bin\$(PlatformShortName)\Release\MT\ - $(ProjectName)\$(PlatformShortName)\Release\ - false - false - - - - DEBUG;_DEBUG%(PreprocessorDefinitions) - MultiThreadedDebugDLL - Level3 - ProgramDatabase - Disabled - include;include\SDL;..\..\src;%(AdditionalIncludeDirectories) - - - false - - - MachineX86 - true - Windows - lib\$(PlatformShortName)\Debug\MD\ - msvcrtd.lib;msvcprtd.lib;kernel32.lib;lua51.lib;SDL2main.lib;SDL2.lib;%(AdditionalDependencies) - true - $(TargetDir)$(TargetName).pdb - $(TargetDir)$(TargetName).pgd - - - - - DEBUG;_DEBUG%(PreprocessorDefinitions) - MultiThreadedDebugDLL - Level3 - ProgramDatabase - Disabled - include;include\SDL;..\..\src;%(AdditionalIncludeDirectories) - - - false - false - - - true - Windows - lib\$(PlatformShortName)\Debug\MD\ - msvcrtd.lib;msvcprtd.lib;kernel32.lib;lua51.lib;SDL2main.lib;SDL2.lib;%(AdditionalDependencies) - true - $(TargetDir)$(TargetName).pgd - $(TargetDir)$(TargetName).pdb - - - - - NDEBUG;%(PreprocessorDefinitions) - MultiThreadedDLL - Level1 - ProgramDatabase - include;include\SDL;..\..\src;%(AdditionalIncludeDirectories) - true - true - false - true - - - MachineX86 - true - Windows - true - true - lib\$(PlatformShortName)\Release\MD\ - msvcrt.lib;msvcprt.lib;kernel32.lib;lua51.lib;SDL2main.lib;SDL2.lib;%(AdditionalDependencies) - true - - - - - NDEBUG;%(PreprocessorDefinitions) - MultiThreadedDLL - Level1 - ProgramDatabase - include;include\SDL;..\..\src;%(AdditionalIncludeDirectories) - true - true - false - true - - - true - Windows - true - true - lib\$(PlatformShortName)\Release\MD\ - msvcrt.lib;msvcprt.lib;kernel32.lib;lua51.lib;SDL2main.lib;SDL2.lib;%(AdditionalDependencies) - true - - - - - include;include\SDL;..\..\src;%(AdditionalIncludeDirectories) - true - NDEBUG;%(PreprocessorDefinitions) - true - MultiThreaded - false - true - - - Windows - true - true - libcmt.lib;libcpmt.lib;kernel32.lib;user32.lib;shell32.lib;uuid.lib;advapi32.lib;ws2_32.lib;winmm.lib;opengl32.lib;oldnames.lib;DevIL.lib;freetype.lib;libmodplug.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua51.lib;mpg123.lib;physfs.lib;OpenAL.lib;zlib.lib;SDL2main.lib;SDL2.lib;%(AdditionalDependencies) - lib\$(PlatformShortName)\Release\MT\ - true - NotSet - true - true - - - - - include;include\SDL;..\..\src;%(AdditionalIncludeDirectories) - true - NDEBUG;%(PreprocessorDefinitions) - true - MultiThreaded - false - true - - - Windows - true - true - libcmt.lib;libcpmt.lib;kernel32.lib;user32.lib;shell32.lib;uuid.lib;advapi32.lib;ws2_32.lib;winmm.lib;opengl32.lib;oldnames.lib;DevIL.lib;freetype.lib;libmodplug.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua51.lib;mpg123.lib;physfs.lib;OpenAL.lib;zlib.lib;SDL2main.lib;SDL2.lib;%(AdditionalDependencies) - lib\$(PlatformShortName)\Release\MT\ - true - true - - - - - - - - {a3fcc735-3e18-4d6b-9da9-01d9e910b7f8} - false - false - false - true - false - - - - - - - - - \ No newline at end of file diff --git a/love/src/jni/love/platform/msvc2010/love.vcxproj.filters b/love/src/jni/love/platform/msvc2010/love.vcxproj.filters deleted file mode 100644 index 8c1f9cea..00000000 --- a/love/src/jni/love/platform/msvc2010/love.vcxproj.filters +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/love/src/jni/love/platform/unix/automagic b/love/src/jni/love/platform/unix/automagic index 6e5c68bb..23acf626 100755 --- a/love/src/jni/love/platform/unix/automagic +++ b/love/src/jni/love/platform/unix/automagic @@ -26,42 +26,44 @@ AUTOMAKE=${AUTOMAKE:-$(which automake)} [[ -x ${ACLOCAL} ]] || die "Could not find aclocal. Install automake." [[ -x ${AUTOMAKE} ]] || die "Could not find automake." +print_errors() { + local output + output="$("$@" 2>&1)" && return 0 + printf "%s\n" "$output" + return 1 +} + automagic() { - log "Copying files..." >&2 + log "Copying files..." cp platform/unix/configure.ac . cp platform/unix/Makefile.am . - log "Running genmodules..." >&2 - if ! bash platform/unix/genmodules "$1"; then + log "Running genmodules..." + if ! print_errors bash platform/unix/genmodules "$1"; then echo "You should be doing this from the root directory of the project." exit 1 fi - log "Running autoheader..." >&2 - ${AUTOHEADER} 2>&1 || return 1 # Gimmie config.h.in + log "Running autoheader..." + print_errors ${AUTOHEADER} || return 1 # Gimmie config.h.in - log "Running libtoolize..." >&2 - ${LIBTOOLIZE} --force 2>&1 || return 1 + log "Running libtoolize..." + print_errors ${LIBTOOLIZE} --force || return 1 - log "Running aclocal..." >&2 - ${ACLOCAL} 2>&1 || return 1 + log "Running aclocal..." + print_errors ${ACLOCAL} || return 1 - log "Running autoconf..." >&2 - ${AUTOCONF} 2>&1 || return 1 + log "Running autoconf..." + print_errors ${AUTOCONF} || return 1 - log "Running automake..." >&2 - ${AUTOMAKE} -a 2>&1 || return 1 + log "Running automake..." + print_errors ${AUTOMAKE} -a || return 1 } -if [[ $1 == "-d" ]]; then - shift 1 - automagic "$@" 2>&1 -else - (automagic "$@" > /dev/null) 2>&1 -fi +automagic "$@" + if [[ $? -eq 1 ]]; then log "Failed, sadface." - log "You can make this script more verbose running it in debug mode (-d)" log "This is generally a configuration error (I'm looking at you aclocal)" exit 1 else diff --git a/love/src/jni/love/platform/unix/configure.ac b/love/src/jni/love/platform/unix/configure.ac index ddfa8345..9f730981 100644 --- a/love/src/jni/love/platform/unix/configure.ac +++ b/love/src/jni/love/platform/unix/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([love], [HEAD]) +AC_INIT([love], [0.11.0]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_AUX_DIR([platform/unix]) AC_CONFIG_MACRO_DIR([platform/unix/m4]) @@ -19,6 +19,7 @@ AC_LANG([C++]) dnl Workaround for old aclocal versions m4_include([platform/unix/cpp11.m4]) +m4_include([platform/unix/deps.m4]) includes= @@ -44,70 +45,68 @@ AS_VAR_IF([enable_stbi_sse2_override], [no], [], #else # --with-lua and --with-luaversion AC_ARG_WITH([lua], [AS_HELP_STRING([--with-lua], [Select the lua implementation])], - [], [with_lua=luajit]) + [], [with_lua=luajit]) AC_ARG_WITH([luaversion], [AS_HELP_STRING([--with-luaversion], [Select the lua version])], - [], [with_luaversion=5.1]) + [], [with_luaversion=5.1]) -# pkg-config libraries -AM_PATH_SDL2([], [], [LOVE_MSG_ERROR([SDL 2])]) with_clean_luaversion=`printf ${with_luaversion} | sed 's/\.//g'` -PKG_CHECK_MODULES([lua], [${with_lua}${with_luaversion}], [lua_found=yes], - [PKG_CHECK_MODULES([lua], [${with_lua}${with_clean_luaversion}], [lua_found=yes], - [PKG_CHECK_MODULES([lua], [${with_lua}], [lua_found=yes], [lua_found=no])])]) -PKG_CHECK_MODULES([freetype2], [freetype2], [], [LOVE_MSG_ERROR([FreeType2])]) -PKG_CHECK_MODULES([openal], [openal], [], [LOVE_MSG_ERROR([OpenAL])]) -PKG_CHECK_MODULES([libmodplug], [libmodplug], [], [LOVE_MSG_ERROR([libmodplug])]) -PKG_CHECK_MODULES([vorbisfile], [vorbisfile], [], [LOVE_MSG_ERROR([libvorbis and libvorbisfile])]) -PKG_CHECK_MODULES([zlib], [zlib], [], [LOVE_MSG_ERROR([zlib])]) -PKG_CHECK_MODULES([theora], [theoradec], [], [LOVE_MSG_ERROR([libtheora])]) -# Other libraries -AC_SEARCH_LIBS([sqrt], [m], [], [LOVE_MSG_ERROR([the C math library])]) -AC_SEARCH_LIBS([PHYSFS_init], [physfs], [], [LOVE_MSG_ERROR([PhysicsFS])]) +# Generated sources for enabling/disabling modules +m4_include([configure-modules-pre.ac]) -# Lua, treated seperately because of --with-lua -AS_VAR_IF([lua_found], [yes], - #if - [ - luaheaders_found=yes - AC_MSG_CHECKING([for library containing lua_call]) - AC_MSG_RESULT([${lua_LIBS}])], - #else - [ - AC_MSG_WARN([Could not find pkg-config definition for ${with_lua}${with_luaversion} or ${with_lua}${with_clean_luaversion}${with_lua}, falling back to manual detection]) - AC_SEARCH_LIBS([lua_call], ["${with_lua}${with_luaversion}" "${with_lua}"], [], - [LOVE_MSG_ERROR([$with_lua])]) - luaheaders_found=no - AC_CHECK_HEADER(["${with_lua}${with_luaversion}/lua.h"], [luaheaders_found=yes includes="$includes -I/usr/include/${with_lua}${with_luaversion}"], []) - AC_CHECK_HEADER(["${with_lua}/lua.h"], [luaheaders_found=yes includes="$includes -I/usr/include/${with_lua}"], [])]) -AS_VAR_IF([luaheaders_found], [yes], [], #else - [ - AC_MSG_WARN([Could not locate lua headers for ${with_lua}${with_luaversion} or ${with_lua}, you probably need to specify them with CPPFLAGS])]) - -# mpg123, treated seperately because it can be disabled (default on) -# also not pkg-config because of the FILE_OFFSET_BITS.. bit +# Other features that can be enabled/disabled AC_ARG_ENABLE([mpg123], AC_HELP_STRING([--disable-mpg123], [Disable mp3 support, for patent-free builds]), [], [enable_mpg123=yes]) +AC_ARG_ENABLE([gme], AC_HELP_STRING([--enable-gme], [Enable GME support, for more chiptuney goodness]), [], [enable_gme=no]) + +# Dependencies we always use +ACLOVE_DEP_LUA +ACLOVE_DEP_SDL2 +ACLOVE_DEP_LIBM +ACLOVE_DEP_ZLIB + +# Conditional dependencies +AS_VAR_IF([enable_module_audio], [yes], [ACLOVE_DEP_OPENAL], []) +AS_VAR_IF([enable_module_font], [yes], [ACLOVE_DEP_FREETYPE2], []) +AS_VAR_IF([enable_module_sound], [yes], [ + ACLOVE_DEP_LIBMODPLUG + ACLOVE_DEP_VORBISFILE +], [enable_mpg123=no]) +AS_VAR_IF([enable_module_video], [yes], [ACLOVE_DEP_THEORA], []) +AS_VAR_IF([enable_gme], [yes], [ACLOVE_DEP_GME], []) AS_VAR_IF([enable_mpg123], [no], AC_DEFINE([LOVE_NOMPG123], [], [Build without mpg123]), - # else - AC_SEARCH_LIBS([mpg123_open_feed], [mpg123], [], - [LOVE_MSG_ERROR([libmpg123])]) - AC_SEARCH_LIBS([mpg123_seek_64], [mpg123], - AC_SUBST([FILE_OFFSET],[-D_FILE_OFFSET_BITS=64]), - AC_SUBST([FILE_OFFSET],[]))) + [ACLOVE_DEP_MPG123]) -# GME, treated seperately because it can be enabled (default off) -AC_ARG_ENABLE([gme], AC_HELP_STRING([--enable-gme], [Enable GME support, for more chiptuney goodness]), [], [enable_gme=no]) -AS_VAR_IF([enable_gme], [yes], - AC_SEARCH_LIBS([gme_open_data], [gme], [], [LOVE_MSG_ERROR([gme])]) - AC_DEFINE([LOVE_SUPPORT_GME], [], [Enable gme]) - AC_CHECK_HEADER([gme/gme.h], [includes="$includes -I/usr/include/gme"], [])) +# Add flags for optional libraries +AC_ARG_ENABLE([library-enet], [ --disable-library-enet Turn off library enet], [], [enable_library_enet=yes]) +AC_ARG_ENABLE([library-luasocket], [ --disable-library-luasocket Turn off library luasocket], [], [enable_library_luasocket=yes]) +AC_ARG_ENABLE([library-lua53], [ --disable-library-lua53 Turn off library lua53 (lua 5.3 backports, required by love.data)], [], [enable_library_lua53=yes]) + +# Select the libraries we need to build, based on the selected modules +AS_VAR_IF([enable_module_filesystem], [yes], [enable_library_physfs=yes], [enable_library_physfs=no]) +AS_VAR_IF([enable_module_physics], [yes], [enable_library_Box2D=yes], [enable_library_Box2D=no]) +AS_VAR_IF([enable_module_image], [yes], [enable_library_ddsparse=yes], [enable_library_ddsparse=no]) +AS_VAR_IF([enable_module_graphics], [yes], [enable_library_glad=yes], [enable_library_glad=no]) +AS_VAR_IF([enable_module_graphics], [yes], [enable_library_glslang=yes], [enable_library_glslang=no]) +AS_VAR_IF([enable_module_image], [yes], [enable_library_lodepng=yes], [enable_library_lodepng=no]) +AS_VAR_IF([enable_module_data], [yes], [enable_library_lua53=yes], []) +AS_VAR_IF([enable_module_math], [yes], [enable_library_lz4=yes], [enable_library_lz4=no]) +AS_VAR_IF([enable_module_math], [yes], [enable_library_noise1234=yes], [enable_library_noise1234=no]) +AS_VAR_IF([enable_module_image], [yes], [enable_library_stb=yes], [enable_library_stb=no]) +AS_VAR_IF([enable_module_image], [yes], [enable_library_tinyexr=yes], [enable_library_tinyexr=no]) +AS_VAR_IF([enable_module_sound], [yes], [enable_library_Wuff=yes], [enable_library_Wuff=no]) +AS_VAR_IF([enable_module_graphics], [yes], [enable_library_xxHash=yes], [enable_library_xxHash=no]) + +# Utf8 is required by both graphics and font, so enable if either is enabled +enable_library_utf8=no +AS_VAR_IF([enable_module_graphics], [yes], [enable_library_utf8=yes], []) +AS_VAR_IF([enable_module_font], [yes], [enable_library_utf8=yes], []) # libenet check for socklen_t -AC_CHECK_TYPE([socklen_t], [AC_DEFINE([HAS_SOCKLEN_T], [1], [Define if socklen_t exists.] )], , - #include - #include -) +ACLOVE_SOCKLEN_T + +# Generated sources for enabling/disabling modules +m4_include([configure-modules-post.ac]) # Optionally build the executable (default on) AC_ARG_ENABLE([exe], @@ -128,8 +127,6 @@ AS_VAR_IF([LUA_EXECUTABLE], [:], # Set our includes as automake variable AC_SUBST([LOVE_INCLUDES], ["$includes"]) -m4_include([configure-modules.ac]) - AC_CONFIG_FILES([ Makefile src/Makefile diff --git a/love/src/jni/love/platform/unix/debian/changelog b/love/src/jni/love/platform/unix/debian/changelog deleted file mode 100644 index c9b52249..00000000 --- a/love/src/jni/love/platform/unix/debian/changelog +++ /dev/null @@ -1,5 +0,0 @@ -love (0.9.0~ppatest5) precise; urgency=medium - - * Upstream testing release - - -- Bart van Strien Sat, 2 Nov 2013 16:23:40 +0100 diff --git a/love/src/jni/love/platform/unix/debian/control b/love/src/jni/love/platform/unix/debian/control deleted file mode 100644 index d8bbc182..00000000 --- a/love/src/jni/love/platform/unix/debian/control +++ /dev/null @@ -1,58 +0,0 @@ -Source: love -Section: games -Priority: extra -Maintainer: Bart van Strien -Build-Depends: debhelper (>= 9), - autotools-dev, - libdevil-dev, - libfreetype6-dev, - libluajit-5.1-dev, - libphysfs-dev, - libsdl2-dev (>= 2.0.1), - libopenal-dev, - libogg-dev, - libvorbis-dev, - libflac-dev, - libflac++-dev, - libmodplug-dev, - libmpg123-dev, - libmng-dev -Standards-Version: 3.9.3 -Homepage: http://love2d.org - -Package: liblove -Architecture: any -Multi-Arch: same -Pre-Depends: ${misc:Pre-Depends} -Depends: ${misc:Depends}, - ${shlibs:Depends}, - libdevil1c2, - libmng1, - libfreetype6, - libgl1-mesa-glx, - libluajit-5.1-2, - libphysfs-1.0-0, - libsdl2 (>= 2.0.1), - libopenal1, - libogg0, - libvorbis0a, - libvorbisfile3, - libmodplug1, - libmpg123-0 -Description: LOVE is a free 2D game engine which enables easy game creation in Lua. - -Package: love -Architecture: any -Multi-Arch: same -Depends: ${misc:Depends}, - liblove (= ${binary:Version}) -Description: LOVE is a free 2D game engine which enables easy game creation in Lua. - -Package: love-dbg -Priority: extra -Section: debug -Architecture: any -Multi-Arch: same -Depends: ${misc:Depends}, - love (= ${binary:Version}), -Description: LOVE is a free 2D game engine which enables easy game creation in Lua. diff --git a/love/src/jni/love/platform/unix/debian/copyright b/love/src/jni/love/platform/unix/debian/copyright index 6683e79c..d41eca42 100644 --- a/love/src/jni/love/platform/unix/debian/copyright +++ b/love/src/jni/love/platform/unix/debian/copyright @@ -4,7 +4,7 @@ Upstream-Contact: Bart van Strien Source: http://www.love2d.org/ Files: * -Copyright: 2006-2015 LOVE Development Team +Copyright: 2006-2018 LOVE Development Team License: zlib This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/love/src/jni/love/platform/unix/debian/rules b/love/src/jni/love/platform/unix/debian/rules deleted file mode 100755 index 93c8611e..00000000 --- a/love/src/jni/love/platform/unix/debian/rules +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/make -f - -DEB_HOST_ARCH_CPU ?= $(shell dpkg-architecture -qDEB_HOST_ARCH_CPU) -DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) - -override_dh_auto_configure: - dh_auto_configure -- CPPFLAGS=-I/usr/include/luajit-2.0 --with-lua=luajit-5.1 - -override_dh_link: - dh_link -plove-dev usr/lib/$(DEB_HOST_MULTIARCH)/liblove.so.0.0.0 usr/lib/$(DEB_HOST_MULTIARCH)/liblove.so - -override_dh_strip: - dh_strip --dbg-package=love-dbg - -%: - dh $@ --parallel diff --git a/love/src/jni/love/platform/unix/deps.m4 b/love/src/jni/love/platform/unix/deps.m4 new file mode 100644 index 00000000..0a108bc6 --- /dev/null +++ b/love/src/jni/love/platform/unix/deps.m4 @@ -0,0 +1,74 @@ +AC_DEFUN([ACLOVE_DEP_FREETYPE2], [ + PKG_CHECK_MODULES([freetype2], [freetype2], [], [LOVE_MSG_ERROR([FreeType2])])]) + +AC_DEFUN([ACLOVE_DEP_OPENAL], [ + PKG_CHECK_MODULES([openal], [openal], [], [LOVE_MSG_ERROR([OpenAL])])]) + +AC_DEFUN([ACLOVE_DEP_LIBMODPLUG], [ + PKG_CHECK_MODULES([libmodplug], [libmodplug], [], [LOVE_MSG_ERROR([libmodplug])])]) + +AC_DEFUN([ACLOVE_DEP_VORBISFILE], [ + PKG_CHECK_MODULES([vorbisfile], [vorbisfile], [], [LOVE_MSG_ERROR([libvorbis and libvorbisfile])])]) + +AC_DEFUN([ACLOVE_DEP_ZLIB], [ + PKG_CHECK_MODULES([zlib], [zlib], [], [LOVE_MSG_ERROR([zlib])])]) + +AC_DEFUN([ACLOVE_DEP_THEORA], [ + PKG_CHECK_MODULES([theora], [theoradec], [], [LOVE_MSG_ERROR([libtheora])])]) + +AC_DEFUN([ACLOVE_DEP_LIBM], [ + AC_SEARCH_LIBS([sqrt], [m], [], [LOVE_MSG_ERROR([the C math library])])]) + +AC_DEFUN([ACLOVE_DEP_SDL2], [ + AM_PATH_SDL2([], [], [LOVE_MSG_ERROR([SDL 2])])]) + +# does not use pkg-config because of the FILE_OFFSET_BITS.. bit +AC_DEFUN([ACLOVE_DEP_MPG123], [ + AC_SEARCH_LIBS([mpg123_open_feed], [mpg123], [], + [LOVE_MSG_ERROR([libmpg123])]) + AC_SEARCH_LIBS([mpg123_seek_64], [mpg123], + AC_SUBST([FILE_OFFSET],[-D_FILE_OFFSET_BITS=64]), + AC_SUBST([FILE_OFFSET],[]))]) + +AC_DEFUN([ACLOVE_DEP_GME], [ + AC_SEARCH_LIBS([gme_open_data], [gme], [], [LOVE_MSG_ERROR([gme])]) + AC_DEFINE([LOVE_SUPPORT_GME], [], [Enable gme]) + AC_CHECK_HEADER([gme/gme.h], [includes="$includes -I/usr/include/gme"], [])]) + +# For enet +AC_DEFUN([ACLOVE_SOCKLEN_T], [ + AC_CHECK_TYPE([socklen_t], [AC_DEFINE([HAS_SOCKLEN_T], [1], [Define if socklen_t exists.] )], , + #include + #include + )]) + +# The lua detection is quite annoying because of distro differences and our version selection code +AC_DEFUN([ACLOVE_DEP_LUA_PKGCONFIG], [ + PKG_CHECK_MODULES([lua], [${with_lua}${with_luaversion}], [aclove_lua_found=yes], + [PKG_CHECK_MODULES([lua], [${with_lua}${with_clean_luaversion}], [aclove_lua_found=yes], + [PKG_CHECK_MODULES([lua], [${with_lua}], [aclove_lua_found=yes], [])])]) + + AS_VAR_IF([aclove_lua_found], [yes], + [ + aclove_luaheaders_found=yes + AC_MSG_CHECKING([for library containing lua_call]) + AC_MSG_RESULT([${lua_LIBS}]) + ], [])]) + +AC_DEFUN([ACLOVE_DEP_LUA_FALLBACK], [ + AC_MSG_WARN([Could not find pkg-config definition for ${with_lua}${with_luaversion} or ${with_lua}${with_clean_luaversion}${with_lua}, falling back to manual detection]) + AC_SEARCH_LIBS([lua_call], ["${with_lua}${with_luaversion}" "${with_lua}"], [aclove_lua_found=yes], + [LOVE_MSG_ERROR([$with_lua])]) + + AC_CHECK_HEADER(["${with_lua}${with_luaversion}/lua.h"], [aclove_luaheaders_found=yes includes="$includes -I/usr/include/${with_lua}${with_luaversion}"], []) + AC_CHECK_HEADER(["${with_lua}/lua.h"], [aclove_luaheaders_found=yes includes="$includes -I/usr/include/${with_lua}"], [])]) + +# First, try pkg-config, then fall back to manual detection if not available. +AC_DEFUN([ACLOVE_DEP_LUA], [ dnl Requires with-lua and with-luaversion + aclove_lua_found=no + aclove_luaheaders_found=no + + ACLOVE_DEP_LUA_PKGCONFIG + AS_VAR_IF([aclove_lua_found], [no], [ACLOVE_DEP_LUA_FALLBACK], []) + AS_VAR_IF([aclove_luaheaders_found], [no], + [AC_MSG_WARN([Could not locate lua headers for ${with_lua}${with_luaversion} or ${with_lua}, you probably need to specify them with CPPFLAGS])], [])]) diff --git a/love/src/jni/love/platform/unix/exclude b/love/src/jni/love/platform/unix/exclude index b233a4d1..a221cf61 100644 --- a/love/src/jni/love/platform/unix/exclude +++ b/love/src/jni/love/platform/unix/exclude @@ -1,5 +1,6 @@ -\./libraries/luasocket/libluasocket/wsocket\.* -\./modules/sound/lullaby/FLACDecoder\.* +\./libraries/luasocket/libluasocket/wsocket.* +\./modules/sound/lullaby/FLACDecoder\..* \./love\.cpp \./modules/sound/lullaby/Mpg123Decoder\.cpp \./modules/sound/lullaby/Mpg123Decoder\.h +\./libraries/glslang/glslang/OSDependent/Windows diff --git a/love/src/jni/love/platform/unix/gen-makefile b/love/src/jni/love/platform/unix/gen-makefile deleted file mode 100644 index 757653e2..00000000 --- a/love/src/jni/love/platform/unix/gen-makefile +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -echo Generating src/Makefile.am ... -inc_current='$(srcdir)' -inc_modules="$inc_current/modules" -inc_libraries="$inc_current/libraries" - -cat > src/Makefile.am << EOF -AM_CPPFLAGS = -I$inc_current -I$inc_modules -I$inc_libraries -I$inc_libraries/enet/libenet/include \$(LOVE_INCLUDES) \$(FILE_OFFSET) -AM_CXXFLAGS = \$(SDL_CFLAGS) -AUTOMAKE_OPTIONS = subdir-objects -SUBDIRS = - -if LOVE_BUILD_EXE -# LÖVE executable -bin_PROGRAMS = love -#love_LDFLAGS = -love_LDADD = liblove.la -love_SOURCES = love.cpp -endif - -# Compile scripts -#scripts/%.lua.h: scripts/%.lua -# cd scripts; \ -# lua auto.lua \$* -#TODO: Figure out how to only do this on gnu make, and detect which lua -# executable to run - -# libLÖVE -lib_LTLIBRARIES = liblove.la -liblove_la_LDFLAGS = -module -export-dynamic \$(LDFLAGS) \$(SDL_LIBS) -EOF - -platform/unix/genmodules >> src/Makefile.am - -printf "\n" >> src/Makefile.am - -cd .. -echo "src/Makefile.am is updated! ^.^" diff --git a/love/src/jni/love/platform/unix/genmodules b/love/src/jni/love/platform/unix/genmodules index ccfb69b3..b757554b 100644 --- a/love/src/jni/love/platform/unix/genmodules +++ b/love/src/jni/love/platform/unix/genmodules @@ -3,20 +3,15 @@ love_suffix="$1" love_amsuffix="$(echo "$love_suffix" | sed 's/\-/_/g' | sed 's/\./_/g')" -flags="" +flags=() upper() { echo "$@" | tr '[:lower:]' '[:upper:]' } -implfind() -{ - find "$1" -maxdepth 1 -type d -exec basename '{}' \; | grep -v "^\." | tail -n +2 -} - sourcefind() { - find "$1" $2 -type f \( -iname "*.c" -o -iname "*.cpp" -o -iname "*.h" -o -iname "*.hpp" -o -iname "*.lch" \) | awk "{print \"./$prefix\"\$0\" \\\\\"}" | grep -v -f"$LOVEROOT/platform/unix/exclude" + find "$1" $2 -type f \( -iname "*.c" -o -iname "*.cpp" -o -iname "*.h" -o -iname "*.hpp" -o -iname "*.lch" -o -iname "*.lua" \) | awk "{print \"./$prefix\"\$0\" \\\\\"}" | grep -v -f"$LOVEROOT/platform/unix/exclude" | sort } handlemodule() @@ -26,82 +21,90 @@ handlemodule() printf "$DEFINENAME" } -handleimpl() -{ - module="$1" - implementation="$2" - name="$3" - - printf "if $name\n" - FILES="$(sourcefind "$module/$implementation" | sed "s/^/ /")" - if [[ "x$FILES" != "x" ]]; then - printf "liblove${love_amsuffix}_la_SOURCES += \\\\\n" - printf "${FILES:0:${#FILES}-2}\n" - fi - printf "endif\n\n" -} - genmodules() { LOVEROOT="$(pwd)" - cd src + cd ./src printf "liblove${love_amsuffix}_la_SOURCES = \\\\\n" sourcefind "common" | sed "s/^/ /" FILES="$(sourcefind "scripts" | sed "s/^/ /")" printf "${FILES:0:${#FILES}-2}\n\n" - cd modules + local -a modulelist=() + local -a liblist=() + + cd ./modules prefix="modules/" for module in *; do - NAME=$(handlemodule "$module") - flags="$flags module-$module" + flags+=("module-$module") - printf "if $NAME\n" - - for implementation in $(implfind "$module"); do - flags="$flags implementation-$module-$implementation" - handleimpl "$module" "$implementation" "LOVE_IMPLEMENTATION_$(upper "$module")_$(upper "$implementation")" - done - - FILES="$(sourcefind "$module" "-maxdepth 1" | sed "s/^/ /")" + FILES="$(sourcefind "$module" | sed "s/^/ /")" if [[ "x$FILES" != "x" ]]; then - printf "liblove${love_amsuffix}_la_SOURCES += \\\\\n" - printf "${FILES:0:${#FILES}-2}\n" + printf "liblove_module_$module = \\\\\n" + printf "${FILES:0:${#FILES}-2}\n\n" + modulelist+=("$module") fi - printf "endif\n\n" + if [[ "$module" = "sound" ]]; then + printf "if !LOVE_NOMPG123\n" + printf "liblove_module_$module += \\\\\n" + printf "\t./modules/sound/lullaby/Mpg123Decoder.cpp \\\\\n" + printf "\t./modules/sound/lullaby/Mpg123Decoder.h\n" + printf "endif\n\n" + fi done cd ../libraries prefix="libraries/" for library in *; do - NAME="LOVE_LIBRARY_$(upper "$library")" - flags="$flags library-$library" + flags+=("library-$library") FILES="$(sourcefind "$library" | sed "s/^/ /")" if [[ ${#FILES} -gt 2 ]]; then - printf "if $NAME\n" - printf "liblove${love_amsuffix}_la_SOURCES += \\\\\n" - printf "${FILES:0:${#FILES}-2}\nendif\n\n" + printf "liblove_library_$library = \\\\\n" + printf "${FILES:0:${#FILES}-2}\n\n" + liblist+=("$library") fi done + + for module in "${modulelist[@]}"; do + NAME=$(handlemodule "$module") + printf "if $NAME\n" + printf "liblove${love_amsuffix}_la_SOURCES += \$(liblove_module_$module)\n" + printf "endif\n\n" + done + + for library in "${liblist[@]}"; do + NAME="LOVE_LIBRARY_$(upper "$library")" + printf "if $NAME\n" + printf "liblove${love_amsuffix}_la_SOURCES += \$(liblove_library_$library)\n" + printf "endif\n\n" + done + cd ../.. } genflags() { - for flag in $flags; do - prettyflag="$(echo "$flag" | sed 's/-/ love./' | sed 's/-/./g')" - varflag="enable_$(echo "$flag" | sed 's/^[^-]*-//' | sed 's/[^a-zA-Z0-9]/_/')" - defineflag="LOVE_ENABLE_$(upper $(echo $flag | sed 's/^[^-]*-//' | sed 's/-/_/g'))" + printf > configure-modules-pre.ac + printf > configure-modules-post.ac + for flag in "${flags[@]}"; do + prettyflag="$(echo "$flag" | sed -e 's/-/ love./' -e 's/-/./g')" + varflag="enable_$(echo "$flag" | sed -e 's/[^a-zA-Z0-9]/_/')" + defineflag="LOVE_ENABLE_$(upper $(echo $flag | sed -e 's/^[^-]*-//' -e 's/-/_/g'))" amflag="$(upper $(echo love-$flag | sed 's/-/_/g'))" - printf "AC_ARG_ENABLE([$flag], [ --disable-$flag Turn off $prettyflag], [], [$varflag=true])\n" - printf "AH_TEMPLATE([$defineflag], [])\n" - printf "if test x\"\$$varflag\" = xtrue; then\n" - printf " AC_DEFINE([$defineflag], [])\n" - printf "fi\n" - printf "AM_CONDITIONAL([$amflag], [test x\$$varflag = xtrue])\n\n" + + # Don't generate an --enable rule for libraries + if [[ "$(echo $flag | sed -e '/^library-/d')" != "" ]]; then + printf "AC_ARG_ENABLE([$flag], [ --disable-$flag Turn off $prettyflag], [], [$varflag=yes])\n" >> configure-modules-pre.ac + fi + + printf "AH_TEMPLATE([$defineflag], [])\n" >> configure-modules-post.ac + printf "if test x\"\$$varflag\" = xyes; then\n" >> configure-modules-post.ac + printf " AC_DEFINE([$defineflag], [])\n" >> configure-modules-post.ac + printf "fi\n" >> configure-modules-post.ac + printf "AM_CONDITIONAL([$amflag], [test x\$$varflag = xyes])\n\n" >> configure-modules-post.ac done } @@ -137,33 +140,26 @@ endif # Compile scripts .lua.lua.h: - cd scripts; \ + cd ./scripts; \ \$(LUA_EXECUTABLE) auto.lua \$< # libLÖVE lib_LTLIBRARIES = liblove${love_suffix}.la -liblove${love_amsuffix}_la_LDFLAGS = -module -export-dynamic \$(LDFLAGS) +liblove${love_amsuffix}_la_LDFLAGS = -module -export-dynamic \$(LDFLAGS) -release \$(PACKAGE_VERSION) liblove${love_amsuffix}_la_LIBADD = \ \$(SDL_LIBS) \$(freetype2_LIBS) \$(lua_LIBS)\ \$(openal_LIBS) \$(zlib_LIBS) \$(libmodplug_LIBS)\ \$(vorbisfile_LIBS) \$(theora_LIBS) + EOF genmodules >> src/Makefile.am -cat >> src/Makefile.am << EOF -if !LOVE_NOMPG123 -liblove${love_amsuffix}_la_SOURCES += \\ - ./modules/sound/lullaby/Mpg123Decoder.cpp \\ - ./modules/sound/lullaby/Mpg123Decoder.h -endif -EOF - echo "src/Makefile.am is updated! ^.^" echo "Generating configure-modules.ac" -genflags > configure-modules.ac -cat >> configure-modules.ac << EOF +genflags +cat >> configure-modules-post.ac << EOF AC_SUBST([LOVE_SUFFIX], [${love_suffix}]) EOF echo "configure-modules.ac is updated! ^.^" diff --git a/love/src/jni/love/platform/unix/love.1 b/love/src/jni/love/platform/unix/love.1 deleted file mode 100644 index 539cf9a9..00000000 --- a/love/src/jni/love/platform/unix/love.1 +++ /dev/null @@ -1,36 +0,0 @@ -.\" (c) 2008-2011 Miriam Ruiz -.\" (c) 2013 Bart van Strien -.\" -.\" This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damagesarising from the use of this software. -.\" -.\" Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: -.\" -.\" 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. -.\" -.\" 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. -.\" -.\" 3. This notice may not be removed or altered from any source distribution. -.\" -.\" Modifications: -.\" - Update version to 0.9 and remove reference to doc dir -.\" - Add fused and version flags - -.TH "LÖVE" "1" "0.9" "" "" -.SH "NAME" -love \- 2D game development framework - -.SH "SYNOPSIS" -.B love -[--fused] <\fIgame.love\fR> -.PP -.B love ---version -.PP - -.SH "DESCRIPTION" -LÖVE was created to be a user\-friendly engine in which simple (or complicated) games could be made without having extensive knowledge of system or graphics functions and without having to dedicate time towards developing the same engine features time and time again. -.P -Developed with cross\-platform implementation in mind, it utilizes the latest open source libraries to deliver a similar game experience, independent of operating system. By relying on the Lua scripting language for game\-specific programming, it allows even the novice game creator to quickly and efficiently develop an idea into a fully working game. - -.SH "SEE ALSO" -You can find more information at \fIhttp://love2d.org/\fR diff --git a/love/src/jni/love/platform/unix/postinst b/love/src/jni/love/platform/unix/postinst deleted file mode 100755 index 68e87b81..00000000 --- a/love/src/jni/love/platform/unix/postinst +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -update-mime-database /usr/share/mime -gtk-update-icon-cache --force /usr/share/icons/gnome -xdg-mime default love.desktop application/x-love-game diff --git a/love/src/jni/love/platform/unix/postrm b/love/src/jni/love/platform/unix/postrm deleted file mode 100755 index 7cb24e4b..00000000 --- a/love/src/jni/love/platform/unix/postrm +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -update-mime-database /usr/share/mime -gtk-update-icon-cache --force /usr/share/icons/gnome diff --git a/love/src/jni/love/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/Contents.json b/love/src/jni/love/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/Contents.json index f1a9e097..3c6f2798 100644 --- a/love/src/jni/love/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/Contents.json +++ b/love/src/jni/love/platform/xcode/Images.xcassets/iOS AppIcon.appiconset/Contents.json @@ -1,5 +1,15 @@ { "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, { "size" : "29x29", "idiom" : "iphone", @@ -54,6 +64,16 @@ "filename" : "icon-60pt@3x.png", "scale" : "3x" }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, { "size" : "29x29", "idiom" : "ipad", @@ -119,10 +139,15 @@ "idiom" : "ipad", "filename" : "icon-83.5pt@2x.png", "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" } ], "info" : { "version" : 1, "author" : "xcode" } -} +} \ No newline at end of file diff --git a/love/src/jni/love/platform/xcode/ios/love-ios.plist b/love/src/jni/love/platform/xcode/ios/love-ios.plist index 1fc317e5..ea43d5e9 100644 --- a/love/src/jni/love/platform/xcode/ios/love-ios.plist +++ b/love/src/jni/love/platform/xcode/ios/love-ios.plist @@ -40,7 +40,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.10.2 + 0.11.0 CFBundleSignature ???? CFBundleVersion diff --git a/love/src/jni/love/platform/xcode/liblove.xcodeproj/project.pbxproj b/love/src/jni/love/platform/xcode/liblove.xcodeproj/project.pbxproj index d21bd683..45c4f8b0 100644 --- a/love/src/jni/love/platform/xcode/liblove.xcodeproj/project.pbxproj +++ b/love/src/jni/love/platform/xcode/liblove.xcodeproj/project.pbxproj @@ -7,6 +7,63 @@ objects = { /* Begin PBXBuildFile section */ + 217DFBD91D9F6D490055D849 /* auxiliar.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFB9D1D9F6D490055D849 /* auxiliar.c */; }; + 217DFBDA1D9F6D490055D849 /* auxiliar.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFB9E1D9F6D490055D849 /* auxiliar.h */; }; + 217DFBDB1D9F6D490055D849 /* buffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFB9F1D9F6D490055D849 /* buffer.c */; }; + 217DFBDC1D9F6D490055D849 /* buffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBA01D9F6D490055D849 /* buffer.h */; }; + 217DFBDD1D9F6D490055D849 /* compat.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBA11D9F6D490055D849 /* compat.c */; }; + 217DFBDE1D9F6D490055D849 /* compat.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBA21D9F6D490055D849 /* compat.h */; }; + 217DFBDF1D9F6D490055D849 /* except.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBA31D9F6D490055D849 /* except.c */; }; + 217DFBE01D9F6D490055D849 /* except.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBA41D9F6D490055D849 /* except.h */; }; + 217DFBE11D9F6D490055D849 /* ftp.lua in Resources */ = {isa = PBXBuildFile; fileRef = 217DFBA51D9F6D490055D849 /* ftp.lua */; }; + 217DFBE21D9F6D490055D849 /* ftp.lua.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBA61D9F6D490055D849 /* ftp.lua.h */; }; + 217DFBE31D9F6D490055D849 /* headers.lua in Resources */ = {isa = PBXBuildFile; fileRef = 217DFBA71D9F6D490055D849 /* headers.lua */; }; + 217DFBE41D9F6D490055D849 /* headers.lua.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBA81D9F6D490055D849 /* headers.lua.h */; }; + 217DFBE51D9F6D490055D849 /* http.lua in Resources */ = {isa = PBXBuildFile; fileRef = 217DFBA91D9F6D490055D849 /* http.lua */; }; + 217DFBE61D9F6D490055D849 /* http.lua.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBAA1D9F6D490055D849 /* http.lua.h */; }; + 217DFBE71D9F6D490055D849 /* inet.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBAB1D9F6D490055D849 /* inet.c */; }; + 217DFBE81D9F6D490055D849 /* inet.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBAC1D9F6D490055D849 /* inet.h */; }; + 217DFBE91D9F6D490055D849 /* io.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBAD1D9F6D490055D849 /* io.c */; }; + 217DFBEA1D9F6D490055D849 /* io.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBAE1D9F6D490055D849 /* io.h */; }; + 217DFBEB1D9F6D490055D849 /* ltn12.lua in Resources */ = {isa = PBXBuildFile; fileRef = 217DFBAF1D9F6D490055D849 /* ltn12.lua */; }; + 217DFBEC1D9F6D490055D849 /* ltn12.lua.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBB01D9F6D490055D849 /* ltn12.lua.h */; }; + 217DFBED1D9F6D490055D849 /* luasocket.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBB11D9F6D490055D849 /* luasocket.c */; }; + 217DFBEE1D9F6D490055D849 /* luasocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBB21D9F6D490055D849 /* luasocket.h */; }; + 217DFBF01D9F6D490055D849 /* mbox.lua in Resources */ = {isa = PBXBuildFile; fileRef = 217DFBB41D9F6D490055D849 /* mbox.lua */; }; + 217DFBF11D9F6D490055D849 /* mbox.lua.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBB51D9F6D490055D849 /* mbox.lua.h */; }; + 217DFBF21D9F6D490055D849 /* mime.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBB61D9F6D490055D849 /* mime.c */; }; + 217DFBF31D9F6D490055D849 /* mime.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBB71D9F6D490055D849 /* mime.h */; }; + 217DFBF41D9F6D490055D849 /* mime.lua in Resources */ = {isa = PBXBuildFile; fileRef = 217DFBB81D9F6D490055D849 /* mime.lua */; }; + 217DFBF51D9F6D490055D849 /* mime.lua.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBB91D9F6D490055D849 /* mime.lua.h */; }; + 217DFBF61D9F6D490055D849 /* options.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBBA1D9F6D490055D849 /* options.c */; }; + 217DFBF71D9F6D490055D849 /* options.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBBB1D9F6D490055D849 /* options.h */; }; + 217DFBF81D9F6D490055D849 /* pierror.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBBC1D9F6D490055D849 /* pierror.h */; }; + 217DFBF91D9F6D490055D849 /* select.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBBD1D9F6D490055D849 /* select.c */; }; + 217DFBFA1D9F6D490055D849 /* select.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBBE1D9F6D490055D849 /* select.h */; }; + 217DFBFB1D9F6D490055D849 /* serial.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBBF1D9F6D490055D849 /* serial.c */; }; + 217DFBFC1D9F6D490055D849 /* smtp.lua in Resources */ = {isa = PBXBuildFile; fileRef = 217DFBC01D9F6D490055D849 /* smtp.lua */; }; + 217DFBFD1D9F6D490055D849 /* smtp.lua.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBC11D9F6D490055D849 /* smtp.lua.h */; }; + 217DFBFE1D9F6D490055D849 /* socket.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBC21D9F6D490055D849 /* socket.h */; }; + 217DFBFF1D9F6D490055D849 /* socket.lua in Resources */ = {isa = PBXBuildFile; fileRef = 217DFBC31D9F6D490055D849 /* socket.lua */; }; + 217DFC001D9F6D490055D849 /* socket.lua.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBC41D9F6D490055D849 /* socket.lua.h */; }; + 217DFC011D9F6D490055D849 /* tcp.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBC51D9F6D490055D849 /* tcp.c */; }; + 217DFC021D9F6D490055D849 /* tcp.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBC61D9F6D490055D849 /* tcp.h */; }; + 217DFC031D9F6D490055D849 /* timeout.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBC71D9F6D490055D849 /* timeout.c */; }; + 217DFC041D9F6D490055D849 /* timeout.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBC81D9F6D490055D849 /* timeout.h */; }; + 217DFC051D9F6D490055D849 /* tp.lua in Resources */ = {isa = PBXBuildFile; fileRef = 217DFBC91D9F6D490055D849 /* tp.lua */; }; + 217DFC061D9F6D490055D849 /* tp.lua.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBCA1D9F6D490055D849 /* tp.lua.h */; }; + 217DFC071D9F6D490055D849 /* udp.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBCB1D9F6D490055D849 /* udp.c */; }; + 217DFC081D9F6D490055D849 /* udp.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBCC1D9F6D490055D849 /* udp.h */; }; + 217DFC091D9F6D490055D849 /* unix.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBCD1D9F6D490055D849 /* unix.c */; }; + 217DFC0A1D9F6D490055D849 /* unix.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBCE1D9F6D490055D849 /* unix.h */; }; + 217DFC0B1D9F6D490055D849 /* unixtcp.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBCF1D9F6D490055D849 /* unixtcp.c */; }; + 217DFC0C1D9F6D490055D849 /* unixtcp.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBD01D9F6D490055D849 /* unixtcp.h */; }; + 217DFC0D1D9F6D490055D849 /* unixudp.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBD11D9F6D490055D849 /* unixudp.c */; }; + 217DFC0E1D9F6D490055D849 /* unixudp.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBD21D9F6D490055D849 /* unixudp.h */; }; + 217DFC0F1D9F6D490055D849 /* url.lua in Resources */ = {isa = PBXBuildFile; fileRef = 217DFBD31D9F6D490055D849 /* url.lua */; }; + 217DFC101D9F6D490055D849 /* url.lua.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBD41D9F6D490055D849 /* url.lua.h */; }; + 217DFC111D9F6D490055D849 /* usocket.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBD51D9F6D490055D849 /* usocket.c */; }; + 217DFC121D9F6D490055D849 /* usocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBD61D9F6D490055D849 /* usocket.h */; }; FA0B791B1A958E3B000E1D17 /* b64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B78F71A958E3B000E1D17 /* b64.cpp */; }; FA0B791C1A958E3B000E1D17 /* b64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B78F71A958E3B000E1D17 /* b64.cpp */; }; FA0B791D1A958E3B000E1D17 /* b64.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B78F81A958E3B000E1D17 /* b64.h */; }; @@ -54,9 +111,6 @@ FA0B79471A958E3B000E1D17 /* Vector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79161A958E3B000E1D17 /* Vector.cpp */; }; FA0B79481A958E3B000E1D17 /* Vector.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79171A958E3B000E1D17 /* Vector.h */; }; FA0B79491A958E3B000E1D17 /* version.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79181A958E3B000E1D17 /* version.h */; }; - FA0B794A1A958E3B000E1D17 /* wrap_Data.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79191A958E3B000E1D17 /* wrap_Data.cpp */; }; - FA0B794B1A958E3B000E1D17 /* wrap_Data.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79191A958E3B000E1D17 /* wrap_Data.cpp */; }; - FA0B794C1A958E3B000E1D17 /* wrap_Data.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B791A1A958E3B000E1D17 /* wrap_Data.h */; }; FA0B7A281A958EA3000E1D17 /* Box2D.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B794F1A958EA3000E1D17 /* Box2D.h */; }; FA0B7A291A958EA3000E1D17 /* b2BroadPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79511A958EA3000E1D17 /* b2BroadPhase.cpp */; }; FA0B7A2A1A958EA3000E1D17 /* b2BroadPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79511A958EA3000E1D17 /* b2BroadPhase.cpp */; }; @@ -237,41 +291,9 @@ FA0B7ADE1A958EA3000E1D17 /* lodepng.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79D91A958EA3000E1D17 /* lodepng.cpp */; }; FA0B7ADF1A958EA3000E1D17 /* lodepng.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79D91A958EA3000E1D17 /* lodepng.cpp */; }; FA0B7AE01A958EA3000E1D17 /* lodepng.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79DA1A958EA3000E1D17 /* lodepng.h */; }; - FA0B7AE11A958EA3000E1D17 /* auxiliar.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79DD1A958EA3000E1D17 /* auxiliar.c */; }; - FA0B7AE21A958EA3000E1D17 /* auxiliar.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79DD1A958EA3000E1D17 /* auxiliar.c */; }; - FA0B7AE41A958EA3000E1D17 /* buffer.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79DF1A958EA3000E1D17 /* buffer.c */; }; - FA0B7AE51A958EA3000E1D17 /* buffer.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79DF1A958EA3000E1D17 /* buffer.c */; }; - FA0B7AE71A958EA3000E1D17 /* except.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79E11A958EA3000E1D17 /* except.c */; }; - FA0B7AE81A958EA3000E1D17 /* except.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79E11A958EA3000E1D17 /* except.c */; }; - FA0B7AEE1A958EA3000E1D17 /* inet.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79E71A958EA3000E1D17 /* inet.c */; }; - FA0B7AEF1A958EA3000E1D17 /* inet.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79E71A958EA3000E1D17 /* inet.c */; }; - FA0B7AF11A958EA3000E1D17 /* io.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79E91A958EA3000E1D17 /* io.c */; }; - FA0B7AF21A958EA3000E1D17 /* io.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79E91A958EA3000E1D17 /* io.c */; }; - FA0B7AF71A958EA3000E1D17 /* luasocket.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79EE1A958EA3000E1D17 /* luasocket.c */; }; - FA0B7AF81A958EA3000E1D17 /* luasocket.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79EE1A958EA3000E1D17 /* luasocket.c */; }; - FA0B7AFA1A958EA3000E1D17 /* mime.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79F01A958EA3000E1D17 /* mime.c */; }; - FA0B7AFB1A958EA3000E1D17 /* mime.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79F01A958EA3000E1D17 /* mime.c */; }; - FA0B7AFF1A958EA3000E1D17 /* options.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79F41A958EA3000E1D17 /* options.c */; }; - FA0B7B001A958EA3000E1D17 /* options.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79F41A958EA3000E1D17 /* options.c */; }; - FA0B7B031A958EA3000E1D17 /* select.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79F71A958EA3000E1D17 /* select.c */; }; - FA0B7B041A958EA3000E1D17 /* select.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79F71A958EA3000E1D17 /* select.c */; }; - FA0B7B0B1A958EA3000E1D17 /* tcp.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79FE1A958EA3000E1D17 /* tcp.c */; }; - FA0B7B0C1A958EA3000E1D17 /* tcp.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79FE1A958EA3000E1D17 /* tcp.c */; }; - FA0B7B0E1A958EA3000E1D17 /* timeout.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7A001A958EA3000E1D17 /* timeout.c */; }; - FA0B7B0F1A958EA3000E1D17 /* timeout.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7A001A958EA3000E1D17 /* timeout.c */; }; - FA0B7B131A958EA3000E1D17 /* udp.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7A041A958EA3000E1D17 /* udp.c */; }; - FA0B7B141A958EA3000E1D17 /* udp.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7A041A958EA3000E1D17 /* udp.c */; }; - FA0B7B161A958EA3000E1D17 /* unix.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7A061A958EA3000E1D17 /* unix.c */; }; - FA0B7B171A958EA3000E1D17 /* unix.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7A061A958EA3000E1D17 /* unix.c */; }; - FA0B7B1B1A958EA3000E1D17 /* usocket.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7A0A1A958EA3000E1D17 /* usocket.c */; }; - FA0B7B1C1A958EA3000E1D17 /* usocket.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7A0A1A958EA3000E1D17 /* usocket.c */; }; FA0B7B211A958EA3000E1D17 /* luasocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7A0E1A958EA3000E1D17 /* luasocket.cpp */; }; FA0B7B221A958EA3000E1D17 /* luasocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7A0E1A958EA3000E1D17 /* luasocket.cpp */; }; FA0B7B231A958EA3000E1D17 /* luasocket.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7A0F1A958EA3000E1D17 /* luasocket.h */; }; - FA0B7B241A958EA3000E1D17 /* lprefix.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7A111A958EA3000E1D17 /* lprefix.h */; }; - FA0B7B251A958EA3000E1D17 /* lutf8lib.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7A121A958EA3000E1D17 /* lutf8lib.c */; }; - FA0B7B261A958EA3000E1D17 /* lutf8lib.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7A121A958EA3000E1D17 /* lutf8lib.c */; }; - FA0B7B271A958EA3000E1D17 /* lutf8lib.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7A131A958EA3000E1D17 /* lutf8lib.h */; }; FA0B7B281A958EA3000E1D17 /* simplexnoise1234.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7A151A958EA3000E1D17 /* simplexnoise1234.cpp */; }; FA0B7B291A958EA3000E1D17 /* simplexnoise1234.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7A151A958EA3000E1D17 /* simplexnoise1234.cpp */; }; FA0B7B2A1A958EA3000E1D17 /* simplexnoise1234.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7A161A958EA3000E1D17 /* simplexnoise1234.h */; }; @@ -386,7 +408,6 @@ FA0B7D2B1A95902C000E1D17 /* wrap_Rasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B851A95902C000E1D17 /* wrap_Rasterizer.cpp */; }; FA0B7D2C1A95902C000E1D17 /* wrap_Rasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B851A95902C000E1D17 /* wrap_Rasterizer.cpp */; }; FA0B7D2D1A95902C000E1D17 /* wrap_Rasterizer.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7B861A95902C000E1D17 /* wrap_Rasterizer.h */; }; - FA0B7D2E1A95902C000E1D17 /* Color.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7B881A95902C000E1D17 /* Color.h */; }; FA0B7D2F1A95902C000E1D17 /* Drawable.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7B891A95902C000E1D17 /* Drawable.h */; }; FA0B7D301A95902C000E1D17 /* Graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B8A1A95902C000E1D17 /* Graphics.cpp */; }; FA0B7D311A95902C000E1D17 /* Graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B8A1A95902C000E1D17 /* Graphics.cpp */; }; @@ -394,66 +415,24 @@ FA0B7D331A95902C000E1D17 /* Canvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B8D1A95902C000E1D17 /* Canvas.cpp */; }; FA0B7D341A95902C000E1D17 /* Canvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B8D1A95902C000E1D17 /* Canvas.cpp */; }; FA0B7D351A95902C000E1D17 /* Canvas.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7B8E1A95902C000E1D17 /* Canvas.h */; }; - FA0B7D361A95902C000E1D17 /* Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B8F1A95902C000E1D17 /* Font.cpp */; }; - FA0B7D371A95902C000E1D17 /* Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B8F1A95902C000E1D17 /* Font.cpp */; }; - FA0B7D381A95902C000E1D17 /* Font.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7B901A95902C000E1D17 /* Font.h */; }; FA0B7D391A95902C000E1D17 /* Graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B911A95902C000E1D17 /* Graphics.cpp */; }; FA0B7D3A1A95902C000E1D17 /* Graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B911A95902C000E1D17 /* Graphics.cpp */; }; FA0B7D3B1A95902C000E1D17 /* Graphics.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7B921A95902C000E1D17 /* Graphics.h */; }; FA0B7D3C1A95902C000E1D17 /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B931A95902C000E1D17 /* Image.cpp */; }; FA0B7D3D1A95902C000E1D17 /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B931A95902C000E1D17 /* Image.cpp */; }; FA0B7D3E1A95902C000E1D17 /* Image.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7B941A95902C000E1D17 /* Image.h */; }; - FA0B7D3F1A95902C000E1D17 /* Mesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B951A95902C000E1D17 /* Mesh.cpp */; }; - FA0B7D401A95902C000E1D17 /* Mesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B951A95902C000E1D17 /* Mesh.cpp */; }; - FA0B7D411A95902C000E1D17 /* Mesh.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7B961A95902C000E1D17 /* Mesh.h */; }; FA0B7D421A95902C000E1D17 /* OpenGL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B971A95902C000E1D17 /* OpenGL.cpp */; }; FA0B7D431A95902C000E1D17 /* OpenGL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B971A95902C000E1D17 /* OpenGL.cpp */; }; FA0B7D441A95902C000E1D17 /* OpenGL.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7B981A95902C000E1D17 /* OpenGL.h */; }; - FA0B7D451A95902C000E1D17 /* ParticleSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B991A95902C000E1D17 /* ParticleSystem.cpp */; }; - FA0B7D461A95902C000E1D17 /* ParticleSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B991A95902C000E1D17 /* ParticleSystem.cpp */; }; - FA0B7D471A95902C000E1D17 /* ParticleSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7B9A1A95902C000E1D17 /* ParticleSystem.h */; }; FA0B7D481A95902C000E1D17 /* Polyline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B9B1A95902C000E1D17 /* Polyline.cpp */; }; FA0B7D491A95902C000E1D17 /* Polyline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B9B1A95902C000E1D17 /* Polyline.cpp */; }; FA0B7D4A1A95902C000E1D17 /* Polyline.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7B9C1A95902C000E1D17 /* Polyline.h */; }; FA0B7D4B1A95902C000E1D17 /* Shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B9D1A95902C000E1D17 /* Shader.cpp */; }; FA0B7D4C1A95902C000E1D17 /* Shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B9D1A95902C000E1D17 /* Shader.cpp */; }; FA0B7D4D1A95902C000E1D17 /* Shader.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7B9E1A95902C000E1D17 /* Shader.h */; }; - FA0B7D4E1A95902C000E1D17 /* SpriteBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B9F1A95902C000E1D17 /* SpriteBatch.cpp */; }; - FA0B7D4F1A95902C000E1D17 /* SpriteBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B9F1A95902C000E1D17 /* SpriteBatch.cpp */; }; - FA0B7D501A95902C000E1D17 /* SpriteBatch.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BA01A95902C000E1D17 /* SpriteBatch.h */; }; - FA0B7D511A95902C000E1D17 /* Text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BA11A95902C000E1D17 /* Text.cpp */; }; - FA0B7D521A95902C000E1D17 /* Text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BA11A95902C000E1D17 /* Text.cpp */; }; - FA0B7D531A95902C000E1D17 /* Text.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BA21A95902C000E1D17 /* Text.h */; }; - FA0B7D551A95902C000E1D17 /* GLBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BA41A95902C000E1D17 /* GLBuffer.cpp */; }; - FA0B7D561A95902C000E1D17 /* GLBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BA41A95902C000E1D17 /* GLBuffer.cpp */; }; - FA0B7D571A95902C000E1D17 /* GLBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BA51A95902C000E1D17 /* GLBuffer.h */; }; - FA0B7D581A95902C000E1D17 /* wrap_Canvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BA61A95902C000E1D17 /* wrap_Canvas.cpp */; }; - FA0B7D591A95902C000E1D17 /* wrap_Canvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BA61A95902C000E1D17 /* wrap_Canvas.cpp */; }; - FA0B7D5A1A95902C000E1D17 /* wrap_Canvas.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BA71A95902C000E1D17 /* wrap_Canvas.h */; }; - FA0B7D5B1A95902C000E1D17 /* wrap_Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BA81A95902C000E1D17 /* wrap_Font.cpp */; }; - FA0B7D5C1A95902C000E1D17 /* wrap_Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BA81A95902C000E1D17 /* wrap_Font.cpp */; }; - FA0B7D5D1A95902C000E1D17 /* wrap_Font.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BA91A95902C000E1D17 /* wrap_Font.h */; }; - FA0B7D5E1A95902C000E1D17 /* wrap_Graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BAA1A95902C000E1D17 /* wrap_Graphics.cpp */; }; - FA0B7D5F1A95902C000E1D17 /* wrap_Graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BAA1A95902C000E1D17 /* wrap_Graphics.cpp */; }; - FA0B7D601A95902C000E1D17 /* wrap_Graphics.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BAB1A95902C000E1D17 /* wrap_Graphics.h */; }; - FA0B7D611A95902C000E1D17 /* wrap_Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BAC1A95902C000E1D17 /* wrap_Image.cpp */; }; - FA0B7D621A95902C000E1D17 /* wrap_Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BAC1A95902C000E1D17 /* wrap_Image.cpp */; }; - FA0B7D631A95902C000E1D17 /* wrap_Image.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BAD1A95902C000E1D17 /* wrap_Image.h */; }; - FA0B7D641A95902C000E1D17 /* wrap_Mesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BAE1A95902C000E1D17 /* wrap_Mesh.cpp */; }; - FA0B7D651A95902C000E1D17 /* wrap_Mesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BAE1A95902C000E1D17 /* wrap_Mesh.cpp */; }; - FA0B7D661A95902C000E1D17 /* wrap_Mesh.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BAF1A95902C000E1D17 /* wrap_Mesh.h */; }; - FA0B7D671A95902C000E1D17 /* wrap_ParticleSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BB01A95902C000E1D17 /* wrap_ParticleSystem.cpp */; }; - FA0B7D681A95902C000E1D17 /* wrap_ParticleSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BB01A95902C000E1D17 /* wrap_ParticleSystem.cpp */; }; - FA0B7D691A95902C000E1D17 /* wrap_ParticleSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BB11A95902C000E1D17 /* wrap_ParticleSystem.h */; }; - FA0B7D6D1A95902C000E1D17 /* wrap_Shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BB41A95902C000E1D17 /* wrap_Shader.cpp */; }; - FA0B7D6E1A95902C000E1D17 /* wrap_Shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BB41A95902C000E1D17 /* wrap_Shader.cpp */; }; - FA0B7D6F1A95902C000E1D17 /* wrap_Shader.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BB51A95902C000E1D17 /* wrap_Shader.h */; }; - FA0B7D701A95902C000E1D17 /* wrap_SpriteBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BB61A95902C000E1D17 /* wrap_SpriteBatch.cpp */; }; - FA0B7D711A95902C000E1D17 /* wrap_SpriteBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BB61A95902C000E1D17 /* wrap_SpriteBatch.cpp */; }; - FA0B7D721A95902C000E1D17 /* wrap_SpriteBatch.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BB71A95902C000E1D17 /* wrap_SpriteBatch.h */; }; - FA0B7D731A95902C000E1D17 /* wrap_Text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BB81A95902C000E1D17 /* wrap_Text.cpp */; }; - FA0B7D741A95902C000E1D17 /* wrap_Text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BB81A95902C000E1D17 /* wrap_Text.cpp */; }; - FA0B7D751A95902C000E1D17 /* wrap_Text.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BB91A95902C000E1D17 /* wrap_Text.h */; }; + FA0B7D551A95902C000E1D17 /* Buffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BA41A95902C000E1D17 /* Buffer.cpp */; }; + FA0B7D561A95902C000E1D17 /* Buffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BA41A95902C000E1D17 /* Buffer.cpp */; }; + FA0B7D571A95902C000E1D17 /* Buffer.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BA51A95902C000E1D17 /* Buffer.h */; }; FA0B7D791A95902C000E1D17 /* Quad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BBC1A95902C000E1D17 /* Quad.cpp */; }; FA0B7D7A1A95902C000E1D17 /* Quad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BBC1A95902C000E1D17 /* Quad.cpp */; }; FA0B7D7B1A95902C000E1D17 /* Quad.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BBD1A95902C000E1D17 /* Quad.h */; }; @@ -470,22 +449,9 @@ FA0B7D861A95902C000E1D17 /* ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BC61A95902C000E1D17 /* ImageData.cpp */; }; FA0B7D871A95902C000E1D17 /* ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BC61A95902C000E1D17 /* ImageData.cpp */; }; FA0B7D881A95902C000E1D17 /* ImageData.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BC71A95902C000E1D17 /* ImageData.h */; }; - FA0B7D891A95902C000E1D17 /* CompressedImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BC91A95902C000E1D17 /* CompressedImageData.cpp */; }; - FA0B7D8A1A95902C000E1D17 /* CompressedImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BC91A95902C000E1D17 /* CompressedImageData.cpp */; }; - FA0B7D8B1A95902C000E1D17 /* CompressedImageData.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BCA1A95902C000E1D17 /* CompressedImageData.h */; }; - FA0B7D8C1A95902C000E1D17 /* CompressedFormatHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BCB1A95902C000E1D17 /* CompressedFormatHandler.h */; }; FA0B7D8D1A95902C000E1D17 /* ddsHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BCC1A95902C000E1D17 /* ddsHandler.cpp */; }; FA0B7D8E1A95902C000E1D17 /* ddsHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BCC1A95902C000E1D17 /* ddsHandler.cpp */; }; FA0B7D8F1A95902C000E1D17 /* ddsHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BCD1A95902C000E1D17 /* ddsHandler.h */; }; - FA0B7D901A95902C000E1D17 /* FormatHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BCE1A95902C000E1D17 /* FormatHandler.cpp */; }; - FA0B7D911A95902C000E1D17 /* FormatHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BCE1A95902C000E1D17 /* FormatHandler.cpp */; }; - FA0B7D921A95902C000E1D17 /* FormatHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BCF1A95902C000E1D17 /* FormatHandler.h */; }; - FA0B7D931A95902C000E1D17 /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BD01A95902C000E1D17 /* Image.cpp */; }; - FA0B7D941A95902C000E1D17 /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BD01A95902C000E1D17 /* Image.cpp */; }; - FA0B7D951A95902C000E1D17 /* Image.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BD11A95902C000E1D17 /* Image.h */; }; - FA0B7D961A95902C000E1D17 /* ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BD21A95902C000E1D17 /* ImageData.cpp */; }; - FA0B7D971A95902C000E1D17 /* ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BD21A95902C000E1D17 /* ImageData.cpp */; }; - FA0B7D981A95902C000E1D17 /* ImageData.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BD31A95902C000E1D17 /* ImageData.h */; }; FA0B7D9F1A95902C000E1D17 /* KTXHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BD81A95902C000E1D17 /* KTXHandler.cpp */; }; FA0B7DA01A95902C000E1D17 /* KTXHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BD81A95902C000E1D17 /* KTXHandler.cpp */; }; FA0B7DA11A95902C000E1D17 /* KTXHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BD91A95902C000E1D17 /* KTXHandler.h */; }; @@ -719,7 +685,6 @@ FA0B7E871A95902C000E1D17 /* CoreAudioDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7C7F1A95902C000E1D17 /* CoreAudioDecoder.h */; }; FA0B7E881A95902C000E1D17 /* Decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7C801A95902C000E1D17 /* Decoder.cpp */; }; FA0B7E891A95902C000E1D17 /* Decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7C801A95902C000E1D17 /* Decoder.cpp */; }; - FA0B7E8A1A95902C000E1D17 /* Decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7C811A95902C000E1D17 /* Decoder.h */; }; FA0B7E8B1A95902C000E1D17 /* FLACDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7C821A95902C000E1D17 /* FLACDecoder.cpp */; }; FA0B7E8C1A95902C000E1D17 /* FLACDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7C821A95902C000E1D17 /* FLACDecoder.cpp */; }; FA0B7E8D1A95902C000E1D17 /* FLACDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7C831A95902C000E1D17 /* FLACDecoder.h */; }; @@ -792,9 +757,6 @@ FA0B7ED11A95902C000E1D17 /* wrap_ThreadModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7CB51A95902C000E1D17 /* wrap_ThreadModule.cpp */; }; FA0B7ED21A95902C000E1D17 /* wrap_ThreadModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7CB51A95902C000E1D17 /* wrap_ThreadModule.cpp */; }; FA0B7ED31A95902C000E1D17 /* wrap_ThreadModule.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7CB61A95902C000E1D17 /* wrap_ThreadModule.h */; }; - FA0B7ED41A95902D000E1D17 /* Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7CB91A95902C000E1D17 /* Timer.cpp */; }; - FA0B7ED51A95902D000E1D17 /* Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7CB91A95902C000E1D17 /* Timer.cpp */; }; - FA0B7ED61A95902D000E1D17 /* Timer.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7CBA1A95902C000E1D17 /* Timer.h */; }; FA0B7ED71A95902D000E1D17 /* Timer.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7CBB1A95902C000E1D17 /* Timer.h */; }; FA0B7ED81A95902D000E1D17 /* wrap_Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7CBC1A95902C000E1D17 /* wrap_Timer.cpp */; }; FA0B7ED91A95902D000E1D17 /* wrap_Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7CBC1A95902C000E1D17 /* wrap_Timer.cpp */; }; @@ -816,15 +778,44 @@ FA0B7EE91A95902D000E1D17 /* wrap_Window.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7CCB1A95902C000E1D17 /* wrap_Window.cpp */; }; FA0B7EEA1A95902D000E1D17 /* wrap_Window.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7CCC1A95902C000E1D17 /* wrap_Window.h */; }; FA0B7EF21A959D2C000E1D17 /* ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7EF11A959D2C000E1D17 /* ios.mm */; }; - FA19C4C51B4B0BD50059B0B3 /* wrap_Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA19C4C21B4B0BD50059B0B3 /* wrap_Video.cpp */; }; - FA19C4C61B4B0BD50059B0B3 /* wrap_Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA19C4C21B4B0BD50059B0B3 /* wrap_Video.cpp */; }; - FA19C4C71B4B0BD50059B0B3 /* wrap_Video.h in Headers */ = {isa = PBXBuildFile; fileRef = FA19C4C31B4B0BD50059B0B3 /* wrap_Video.h */; }; + FA1557C01CE90A2C00AFF582 /* tinyexr.h in Headers */ = {isa = PBXBuildFile; fileRef = FA1557BF1CE90A2C00AFF582 /* tinyexr.h */; }; + FA1557C31CE90BD200AFF582 /* EXRHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1557C11CE90BD200AFF582 /* EXRHandler.cpp */; }; + FA1557C41CE90BD200AFF582 /* EXRHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA1557C21CE90BD200AFF582 /* EXRHandler.h */; }; + FA1557C51CE90BD900AFF582 /* EXRHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1557C11CE90BD200AFF582 /* EXRHandler.cpp */; }; + FA1583E21E196180005E603B /* wrap_Shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1BA0B51E17043400AA2803 /* wrap_Shader.cpp */; }; + FA15DFAC1F9B8C850042AB22 /* StringMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA15DFAB1F9B8C850042AB22 /* StringMap.cpp */; }; + FA15DFAD1F9B8CBA0042AB22 /* StringMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA15DFAB1F9B8C850042AB22 /* StringMap.cpp */; }; + FA15DFAE1F9B8D360042AB22 /* lutf8lib.c in Sources */ = {isa = PBXBuildFile; fileRef = FAAA3FD61F64B3AD00F89E99 /* lutf8lib.c */; }; + FA15DFAF1F9B8D390042AB22 /* lstrlib.c in Sources */ = {isa = PBXBuildFile; fileRef = FAAA3FD41F64B3AD00F89E99 /* lstrlib.c */; }; + FA15DFB01F9B8D6A0042AB22 /* wrap_Data.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA6A2B651F5F7B6B0074C308 /* wrap_Data.cpp */; }; + FA15DFB11F9B8D820042AB22 /* OggDemuxer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAA54AC91F91660400A8FA7B /* OggDemuxer.cpp */; }; + FA15DFB21F9B8D840042AB22 /* TheoraVideoStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAA54AC81F91660400A8FA7B /* TheoraVideoStream.cpp */; }; + FA1BA09D1E16CFCE00AA2803 /* Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1BA09B1E16CFCE00AA2803 /* Font.cpp */; }; + FA1BA09E1E16CFCE00AA2803 /* Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1BA09B1E16CFCE00AA2803 /* Font.cpp */; }; + FA1BA09F1E16CFCE00AA2803 /* Font.h in Headers */ = {isa = PBXBuildFile; fileRef = FA1BA09C1E16CFCE00AA2803 /* Font.h */; }; + FA1BA0A21E16D97500AA2803 /* wrap_Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1BA0A01E16D97500AA2803 /* wrap_Font.cpp */; }; + FA1BA0A31E16D97500AA2803 /* wrap_Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1BA0A01E16D97500AA2803 /* wrap_Font.cpp */; }; + FA1BA0A41E16D97500AA2803 /* wrap_Font.h in Headers */ = {isa = PBXBuildFile; fileRef = FA1BA0A11E16D97500AA2803 /* wrap_Font.h */; }; + FA1BA0A71E16F20600AA2803 /* Canvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1BA0A51E16F20600AA2803 /* Canvas.cpp */; }; + FA1BA0A81E16F20600AA2803 /* Canvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1BA0A51E16F20600AA2803 /* Canvas.cpp */; }; + FA1BA0A91E16F20600AA2803 /* Canvas.h in Headers */ = {isa = PBXBuildFile; fileRef = FA1BA0A61E16F20600AA2803 /* Canvas.h */; }; + FA1BA0AC1E16F9EE00AA2803 /* wrap_Canvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1BA0AA1E16F9EE00AA2803 /* wrap_Canvas.cpp */; }; + FA1BA0AD1E16F9EE00AA2803 /* wrap_Canvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1BA0AA1E16F9EE00AA2803 /* wrap_Canvas.cpp */; }; + FA1BA0AE1E16F9EE00AA2803 /* wrap_Canvas.h in Headers */ = {isa = PBXBuildFile; fileRef = FA1BA0AB1E16F9EE00AA2803 /* wrap_Canvas.h */; }; + FA1BA0B11E16FD0800AA2803 /* Shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1BA0AF1E16FD0800AA2803 /* Shader.cpp */; }; + FA1BA0B21E16FD0800AA2803 /* Shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1BA0AF1E16FD0800AA2803 /* Shader.cpp */; }; + FA1BA0B31E16FD0800AA2803 /* Shader.h in Headers */ = {isa = PBXBuildFile; fileRef = FA1BA0B01E16FD0800AA2803 /* Shader.h */; }; + FA1BA0B71E17043400AA2803 /* wrap_Shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1BA0B51E17043400AA2803 /* wrap_Shader.cpp */; }; + FA1BA0B81E17043400AA2803 /* wrap_Shader.h in Headers */ = {isa = PBXBuildFile; fileRef = FA1BA0B61E17043400AA2803 /* wrap_Shader.h */; }; + FA1E887E1DF363CD00E808AA /* Filter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1E887C1DF363CD00E808AA /* Filter.cpp */; }; + FA1E887F1DF363CD00E808AA /* Filter.h in Headers */ = {isa = PBXBuildFile; fileRef = FA1E887D1DF363CD00E808AA /* Filter.h */; }; + FA1E88801DF363D400E808AA /* Filter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1E887C1DF363CD00E808AA /* Filter.cpp */; }; + FA1E88831DF363DB00E808AA /* Filter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1E88811DF363DB00E808AA /* Filter.cpp */; }; + FA1E88841DF363DB00E808AA /* Filter.h in Headers */ = {isa = PBXBuildFile; fileRef = FA1E88821DF363DB00E808AA /* Filter.h */; }; + FA1E88851DF363E100E808AA /* Filter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1E88811DF363DB00E808AA /* Filter.cpp */; }; FA27B39D1B498151008A9DCE /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA27B38A1B498151008A9DCE /* Video.cpp */; }; FA27B39E1B498151008A9DCE /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA27B38A1B498151008A9DCE /* Video.cpp */; }; FA27B39F1B498151008A9DCE /* Video.h in Headers */ = {isa = PBXBuildFile; fileRef = FA27B38B1B498151008A9DCE /* Video.h */; }; - FA27B3A01B498151008A9DCE /* VideoStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA27B38C1B498151008A9DCE /* VideoStream.cpp */; }; - FA27B3A11B498151008A9DCE /* VideoStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA27B38C1B498151008A9DCE /* VideoStream.cpp */; }; - FA27B3A21B498151008A9DCE /* VideoStream.h in Headers */ = {isa = PBXBuildFile; fileRef = FA27B38D1B498151008A9DCE /* VideoStream.h */; }; FA27B3A91B498151008A9DCE /* Video.h in Headers */ = {isa = PBXBuildFile; fileRef = FA27B3931B498151008A9DCE /* Video.h */; }; FA27B3AA1B498151008A9DCE /* VideoStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA27B3941B498151008A9DCE /* VideoStream.cpp */; }; FA27B3AB1B498151008A9DCE /* VideoStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA27B3941B498151008A9DCE /* VideoStream.cpp */; }; @@ -835,25 +826,75 @@ FA27B3C01B4985BF008A9DCE /* wrap_VideoStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA27B3B91B4985BF008A9DCE /* wrap_VideoStream.cpp */; }; FA27B3C11B4985BF008A9DCE /* wrap_VideoStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA27B3B91B4985BF008A9DCE /* wrap_VideoStream.cpp */; }; FA27B3C21B4985BF008A9DCE /* wrap_VideoStream.h in Headers */ = {isa = PBXBuildFile; fileRef = FA27B3BA1B4985BF008A9DCE /* wrap_VideoStream.h */; }; - FA27B3C51B4985D8008A9DCE /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA27B3C31B4985D8008A9DCE /* Video.cpp */; }; - FA27B3C61B4985D8008A9DCE /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA27B3C31B4985D8008A9DCE /* Video.cpp */; }; - FA27B3C71B4985D8008A9DCE /* Video.h in Headers */ = {isa = PBXBuildFile; fileRef = FA27B3C41B4985D8008A9DCE /* Video.h */; }; - FA27B3C91B498623008A9DCE /* Theora.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA27B3C81B498623008A9DCE /* Theora.framework */; }; + FA27B3C91B498623008A9DCE /* theora.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA27B3C81B498623008A9DCE /* theora.framework */; }; + FA28EBD51E352DB5003446F4 /* FenceSync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA28EBD31E352DB5003446F4 /* FenceSync.cpp */; }; + FA28EBD61E352DB5003446F4 /* FenceSync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA28EBD31E352DB5003446F4 /* FenceSync.cpp */; }; + FA28EBD71E352DB5003446F4 /* FenceSync.h in Headers */ = {isa = PBXBuildFile; fileRef = FA28EBD41E352DB5003446F4 /* FenceSync.h */; }; + FA29C0051E12355B00268CD8 /* StreamBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA29C0041E12355B00268CD8 /* StreamBuffer.cpp */; }; + FA29C0061E12355B00268CD8 /* StreamBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA29C0041E12355B00268CD8 /* StreamBuffer.cpp */; }; + FA2AF6741DAD64970032B62C /* vertex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA2AF6731DAD64970032B62C /* vertex.cpp */; }; + FA2AF6751DAD64970032B62C /* vertex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA2AF6731DAD64970032B62C /* vertex.cpp */; }; FA317EBA18F28B6D00B0BCD7 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA317EB918F28B6D00B0BCD7 /* libz.dylib */; }; + FA3C5E421F8C368C0003C579 /* ShaderStage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA3C5E401F8C368C0003C579 /* ShaderStage.cpp */; }; + FA3C5E431F8C368C0003C579 /* ShaderStage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA3C5E401F8C368C0003C579 /* ShaderStage.cpp */; }; + FA3C5E441F8C368C0003C579 /* ShaderStage.h in Headers */ = {isa = PBXBuildFile; fileRef = FA3C5E411F8C368C0003C579 /* ShaderStage.h */; }; + FA3C5E471F8D80CA0003C579 /* ShaderStage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA3C5E451F8D80CA0003C579 /* ShaderStage.cpp */; }; + FA3C5E481F8D80CA0003C579 /* ShaderStage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA3C5E451F8D80CA0003C579 /* ShaderStage.cpp */; }; + FA3C5E491F8D80CA0003C579 /* ShaderStage.h in Headers */ = {isa = PBXBuildFile; fileRef = FA3C5E461F8D80CA0003C579 /* ShaderStage.h */; }; FA41A3C81C0A1F950084430C /* ASTCHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA41A3C61C0A1F950084430C /* ASTCHandler.cpp */; }; FA41A3C91C0A1F950084430C /* ASTCHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA41A3C61C0A1F950084430C /* ASTCHandler.cpp */; }; FA41A3CA1C0A1F950084430C /* ASTCHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA41A3C71C0A1F950084430C /* ASTCHandler.h */; }; FA4B66C91ABBCF1900558F15 /* Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA4B66C81ABBCF1900558F15 /* Timer.cpp */; }; FA4B66CA1ABBCF1900558F15 /* Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA4B66C81ABBCF1900558F15 /* Timer.cpp */; }; + FA4F2B791DE0125B00CA37D7 /* xxhash.c in Sources */ = {isa = PBXBuildFile; fileRef = FA4F2B771DE0125B00CA37D7 /* xxhash.c */; }; + FA4F2B7A1DE0125B00CA37D7 /* xxhash.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4F2B781DE0125B00CA37D7 /* xxhash.h */; }; + FA4F2B7B1DE0181B00CA37D7 /* xxhash.c in Sources */ = {isa = PBXBuildFile; fileRef = FA4F2B771DE0125B00CA37D7 /* xxhash.c */; }; + FA4F2BA61DE1E36400CA37D7 /* RecordingDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA4F2BA21DE1E36400CA37D7 /* RecordingDevice.cpp */; }; + FA4F2BA71DE1E36400CA37D7 /* RecordingDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4F2BA31DE1E36400CA37D7 /* RecordingDevice.h */; }; + FA4F2BA81DE1E36400CA37D7 /* wrap_RecordingDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA4F2BA41DE1E36400CA37D7 /* wrap_RecordingDevice.cpp */; }; + FA4F2BA91DE1E36400CA37D7 /* wrap_RecordingDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4F2BA51DE1E36400CA37D7 /* wrap_RecordingDevice.h */; }; + FA4F2BAC1DE1E37000CA37D7 /* RecordingDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA4F2BAA1DE1E37000CA37D7 /* RecordingDevice.cpp */; }; + FA4F2BAD1DE1E37000CA37D7 /* RecordingDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4F2BAB1DE1E37000CA37D7 /* RecordingDevice.h */; }; + FA4F2BB01DE1E37B00CA37D7 /* RecordingDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA4F2BAE1DE1E37B00CA37D7 /* RecordingDevice.cpp */; }; + FA4F2BB11DE1E37B00CA37D7 /* RecordingDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4F2BAF1DE1E37B00CA37D7 /* RecordingDevice.h */; }; + FA4F2BB21DE1E4B400CA37D7 /* RecordingDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA4F2BAE1DE1E37B00CA37D7 /* RecordingDevice.cpp */; }; + FA4F2BB31DE1E4B800CA37D7 /* RecordingDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA4F2BA21DE1E36400CA37D7 /* RecordingDevice.cpp */; }; + FA4F2BB41DE1E4BD00CA37D7 /* RecordingDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA4F2BAA1DE1E37000CA37D7 /* RecordingDevice.cpp */; }; + FA4F2BB51DE1E4C300CA37D7 /* wrap_RecordingDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA4F2BA41DE1E36400CA37D7 /* wrap_RecordingDevice.cpp */; }; + FA4F2BE31DE6650600CA37D7 /* Transform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA4F2BDF1DE6650600CA37D7 /* Transform.cpp */; }; + FA4F2BE41DE6650600CA37D7 /* Transform.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4F2BE01DE6650600CA37D7 /* Transform.h */; }; + FA4F2BE51DE6650600CA37D7 /* wrap_Transform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA4F2BE11DE6650600CA37D7 /* wrap_Transform.cpp */; }; + FA4F2BE61DE6650600CA37D7 /* wrap_Transform.h in Headers */ = {isa = PBXBuildFile; fileRef = FA4F2BE21DE6650600CA37D7 /* wrap_Transform.h */; }; + FA4F2BE71DE6650D00CA37D7 /* Transform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA4F2BDF1DE6650600CA37D7 /* Transform.cpp */; }; + FA4F2BE81DE6651000CA37D7 /* wrap_Transform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA4F2BE11DE6650600CA37D7 /* wrap_Transform.cpp */; }; + FA4F2C031DE936C200CA37D7 /* auxiliar.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFB9D1D9F6D490055D849 /* auxiliar.c */; }; + FA4F2C041DE936C600CA37D7 /* buffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFB9F1D9F6D490055D849 /* buffer.c */; }; + FA4F2C051DE936C900CA37D7 /* compat.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBA11D9F6D490055D849 /* compat.c */; }; + FA4F2C061DE936CD00CA37D7 /* except.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBA31D9F6D490055D849 /* except.c */; }; + FA4F2C071DE936DA00CA37D7 /* inet.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBAB1D9F6D490055D849 /* inet.c */; }; + FA4F2C081DE936DD00CA37D7 /* io.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBAD1D9F6D490055D849 /* io.c */; }; + FA4F2C091DE936E200CA37D7 /* luasocket.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBB11D9F6D490055D849 /* luasocket.c */; }; + FA4F2C0A1DE936E600CA37D7 /* mime.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBB61D9F6D490055D849 /* mime.c */; }; + FA4F2C0B1DE936EA00CA37D7 /* options.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBBA1D9F6D490055D849 /* options.c */; }; + FA4F2C0C1DE936ED00CA37D7 /* select.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBBD1D9F6D490055D849 /* select.c */; }; + FA4F2C0D1DE936F100CA37D7 /* serial.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBBF1D9F6D490055D849 /* serial.c */; }; + FA4F2C0E1DE936FE00CA37D7 /* tcp.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBC51D9F6D490055D849 /* tcp.c */; }; + FA4F2C0F1DE936FE00CA37D7 /* timeout.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBC71D9F6D490055D849 /* timeout.c */; }; + FA4F2C101DE936FE00CA37D7 /* udp.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBCB1D9F6D490055D849 /* udp.c */; }; + FA4F2C111DE936FE00CA37D7 /* unix.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBCD1D9F6D490055D849 /* unix.c */; }; + FA4F2C121DE936FE00CA37D7 /* unixtcp.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBCF1D9F6D490055D849 /* unixtcp.c */; }; + FA4F2C131DE936FE00CA37D7 /* unixudp.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBD11D9F6D490055D849 /* unixudp.c */; }; + FA4F2C141DE936FE00CA37D7 /* usocket.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBD51D9F6D490055D849 /* usocket.c */; }; + FA56AA381FAFF02000A43D5F /* memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA56AA361FAFF02000A43D5F /* memory.cpp */; }; + FA56AA391FAFF02000A43D5F /* memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA56AA361FAFF02000A43D5F /* memory.cpp */; }; + FA56AA3A1FAFF02000A43D5F /* memory.h in Headers */ = {isa = PBXBuildFile; fileRef = FA56AA371FAFF02000A43D5F /* memory.h */; }; FA56D9BC1C208A0200D8D3C7 /* libmodplug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA56D9BA1C2089EE00D8D3C7 /* libmodplug.a */; }; FA577AB016C7507900860150 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7916C71A1700860150 /* Cocoa.framework */; }; - FA577AC216C7512D00860150 /* FreeType.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A6716C719D900860150 /* FreeType.framework */; }; FA577AC516C7513400860150 /* libmodplug.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A8216C71A5300860150 /* libmodplug.framework */; }; FA577AC716C7513A00860150 /* mpg123.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A6F16C719F000860150 /* mpg123.framework */; }; - FA577AC816C7513C00860150 /* Ogg.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7116C719F400860150 /* Ogg.framework */; }; + FA577AC816C7513C00860150 /* ogg.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7116C719F400860150 /* ogg.framework */; }; FA577ACA16C7514100860150 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7C16C71A2600860150 /* OpenGL.framework */; }; - FA577ACB16C7514400860150 /* physfs.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7316C719F900860150 /* physfs.framework */; }; - FA577ACD16C7514C00860150 /* Vorbis.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7716C71A0800860150 /* Vorbis.framework */; }; + FA577ACD16C7514C00860150 /* vorbis.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7716C71A0800860150 /* vorbis.framework */; }; FA57FB981AE1993600F2AD6D /* noise1234.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA57FB961AE1993600F2AD6D /* noise1234.cpp */; }; FA57FB991AE1993600F2AD6D /* noise1234.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA57FB961AE1993600F2AD6D /* noise1234.cpp */; }; FA57FB9A1AE1993600F2AD6D /* noise1234.h in Headers */ = {isa = PBXBuildFile; fileRef = FA57FB971AE1993600F2AD6D /* noise1234.h */; }; @@ -861,7 +902,6 @@ FA59A2D81C0649C200328DBA /* libtheora.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA59A2D61C0649BB00328DBA /* libtheora.a */; }; FA5D24B01A96D2EC00C6FC8F /* libFreetype2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA5D24A51A96D2EC00C6FC8F /* libFreetype2.a */; }; FA5D24B31A96D2EC00C6FC8F /* libogg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA5D24AB1A96D2EC00C6FC8F /* libogg.a */; }; - FA5D24B41A96D2EC00C6FC8F /* libphysfs.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA5D24AD1A96D2EC00C6FC8F /* libphysfs.a */; }; FA5D24B51A96D2EC00C6FC8F /* libvorbis.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA5D24AF1A96D2EC00C6FC8F /* libvorbis.a */; }; FA5D24CF1A96E68300C6FC8F /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA5D24CD1A96E63D00C6FC8F /* libSDL2.a */; }; FA620A321AA2F8DB005DB4C2 /* wrap_Quad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA620A2E1AA2F8DB005DB4C2 /* wrap_Quad.cpp */; }; @@ -872,36 +912,274 @@ FA620A371AA2F8DB005DB4C2 /* wrap_Texture.h in Headers */ = {isa = PBXBuildFile; fileRef = FA620A311AA2F8DB005DB4C2 /* wrap_Texture.h */; }; FA620A3A1AA305F6005DB4C2 /* types.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA620A391AA305F6005DB4C2 /* types.cpp */; }; FA620A3B1AA305F6005DB4C2 /* types.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA620A391AA305F6005DB4C2 /* types.cpp */; }; + FA6A2B661F5F7B6B0074C308 /* wrap_Data.h in Headers */ = {isa = PBXBuildFile; fileRef = FA6A2B641F5F7B6B0074C308 /* wrap_Data.h */; }; + FA6A2B671F5F7B6B0074C308 /* wrap_Data.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA6A2B651F5F7B6B0074C308 /* wrap_Data.cpp */; }; + FA6A2B6A1F5F7F560074C308 /* DataView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA6A2B681F5F7F560074C308 /* DataView.cpp */; }; + FA6A2B6B1F5F7F560074C308 /* DataView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA6A2B681F5F7F560074C308 /* DataView.cpp */; }; + FA6A2B6C1F5F7F560074C308 /* DataView.h in Headers */ = {isa = PBXBuildFile; fileRef = FA6A2B691F5F7F560074C308 /* DataView.h */; }; + FA6A2B6F1F5F845F0074C308 /* wrap_DataView.h in Headers */ = {isa = PBXBuildFile; fileRef = FA6A2B6D1F5F845F0074C308 /* wrap_DataView.h */; }; + FA6A2B701F5F845F0074C308 /* wrap_DataView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA6A2B6E1F5F845F0074C308 /* wrap_DataView.cpp */; }; + FA6A2B711F5F845F0074C308 /* wrap_DataView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA6A2B6E1F5F845F0074C308 /* wrap_DataView.cpp */; }; + FA6A2B741F60B6710074C308 /* ByteData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA6A2B721F60B6710074C308 /* ByteData.cpp */; }; + FA6A2B751F60B6710074C308 /* ByteData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA6A2B721F60B6710074C308 /* ByteData.cpp */; }; + FA6A2B761F60B6710074C308 /* ByteData.h in Headers */ = {isa = PBXBuildFile; fileRef = FA6A2B731F60B6710074C308 /* ByteData.h */; }; + FA6A2B791F60B8250074C308 /* wrap_ByteData.h in Headers */ = {isa = PBXBuildFile; fileRef = FA6A2B771F60B8250074C308 /* wrap_ByteData.h */; }; + FA6A2B7A1F60B8250074C308 /* wrap_ByteData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA6A2B781F60B8250074C308 /* wrap_ByteData.cpp */; }; + FA6A2B7B1F60B8250074C308 /* wrap_ByteData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA6A2B781F60B8250074C308 /* wrap_ByteData.cpp */; }; + FA6BDE5C1F31725300786805 /* Color.h in Headers */ = {isa = PBXBuildFile; fileRef = FA6BDE5B1F31725300786805 /* Color.h */; }; FA7550A81AEBE276003E311E /* libluajit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA7550A71AEBE276003E311E /* libluajit.a */; }; + FA76344A1E28722A0066EF9E /* StreamBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA7634481E28722A0066EF9E /* StreamBuffer.cpp */; }; + FA76344B1E28722A0066EF9E /* StreamBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA7634481E28722A0066EF9E /* StreamBuffer.cpp */; }; + FA76344C1E28722A0066EF9E /* StreamBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = FA7634491E28722A0066EF9E /* StreamBuffer.h */; }; FA8951A21AA2EDF300EC385A /* wrap_Event.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA8951A01AA2EDF300EC385A /* wrap_Event.cpp */; }; FA8951A31AA2EDF300EC385A /* wrap_Event.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA8951A01AA2EDF300EC385A /* wrap_Event.cpp */; }; FA8951A41AA2EDF300EC385A /* wrap_Event.h in Headers */ = {isa = PBXBuildFile; fileRef = FA8951A11AA2EDF300EC385A /* wrap_Event.h */; }; + FA91591E1CF1ED7500A7053F /* halffloat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA91591C1CF1ED7500A7053F /* halffloat.cpp */; }; + FA91591F1CF1ED7500A7053F /* halffloat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA91591C1CF1ED7500A7053F /* halffloat.cpp */; }; + FA9159201CF1ED7500A7053F /* halffloat.h in Headers */ = {isa = PBXBuildFile; fileRef = FA91591D1CF1ED7500A7053F /* halffloat.h */; }; + FA91DA8B1F377C3900C80E33 /* deprecation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA91DA891F377C3900C80E33 /* deprecation.cpp */; }; + FA91DA8C1F377C3900C80E33 /* deprecation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA91DA891F377C3900C80E33 /* deprecation.cpp */; }; + FA91DA8D1F377C3900C80E33 /* deprecation.h in Headers */ = {isa = PBXBuildFile; fileRef = FA91DA8A1F377C3900C80E33 /* deprecation.h */; }; + FA93C4531F315B960087CCD4 /* FormatHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA93C4501F315B960087CCD4 /* FormatHandler.h */; }; + FA93C4541F315B960087CCD4 /* FormatHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA93C4511F315B960087CCD4 /* FormatHandler.cpp */; }; FA9B4A0816E1578300074F42 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA9B4A0716E1578300074F42 /* SDL2.framework */; }; + FA9D53AC1F5307E900125C6B /* Deprecations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA9D53AA1F5307E900125C6B /* Deprecations.cpp */; }; + FA9D53AD1F5307E900125C6B /* Deprecations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA9D53AA1F5307E900125C6B /* Deprecations.cpp */; }; + FA9D53AE1F5307E900125C6B /* Deprecations.h in Headers */ = {isa = PBXBuildFile; fileRef = FA9D53AB1F5307E900125C6B /* Deprecations.h */; }; + FA9D8DD11DEB56C3002CD881 /* pixelformat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA9D8DCF1DEB56C3002CD881 /* pixelformat.cpp */; }; + FA9D8DD21DEB56C3002CD881 /* pixelformat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA9D8DCF1DEB56C3002CD881 /* pixelformat.cpp */; }; + FA9D8DD31DEB56C3002CD881 /* pixelformat.h in Headers */ = {isa = PBXBuildFile; fileRef = FA9D8DD01DEB56C3002CD881 /* pixelformat.h */; }; + FA9D8DD71DEF8411002CD881 /* Data.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA9D8DD41DEF8411002CD881 /* Data.cpp */; }; + FA9D8DD81DEF8411002CD881 /* Data.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA9D8DD41DEF8411002CD881 /* Data.cpp */; }; + FA9D8DD91DEF8411002CD881 /* Stream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA9D8DD51DEF8411002CD881 /* Stream.cpp */; }; + FA9D8DDA1DEF8411002CD881 /* Stream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA9D8DD51DEF8411002CD881 /* Stream.cpp */; }; + FA9D8DDB1DEF8411002CD881 /* Stream.h in Headers */ = {isa = PBXBuildFile; fileRef = FA9D8DD61DEF8411002CD881 /* Stream.h */; }; + FA9D8DDD1DEF842A002CD881 /* Drawable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA9D8DDC1DEF842A002CD881 /* Drawable.cpp */; }; + FA9D8DDE1DEF842A002CD881 /* Drawable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA9D8DDC1DEF842A002CD881 /* Drawable.cpp */; }; + FA9D8DE01DEF843D002CD881 /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA9D8DDF1DEF843D002CD881 /* Image.cpp */; }; + FA9D8DE11DEF843D002CD881 /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA9D8DDF1DEF843D002CD881 /* Image.cpp */; }; FAA3A9AE1B7D465A00CED060 /* android.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAA3A9AC1B7D465A00CED060 /* android.cpp */; }; FAA3A9AF1B7D465A00CED060 /* android.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAA3A9AC1B7D465A00CED060 /* android.cpp */; }; FAA3A9B01B7D465A00CED060 /* android.h in Headers */ = {isa = PBXBuildFile; fileRef = FAA3A9AD1B7D465A00CED060 /* android.h */; }; + FAA54ACA1F91660400A8FA7B /* OggDemuxer.h in Headers */ = {isa = PBXBuildFile; fileRef = FAA54AC61F91660400A8FA7B /* OggDemuxer.h */; }; + FAA54ACB1F91660400A8FA7B /* TheoraVideoStream.h in Headers */ = {isa = PBXBuildFile; fileRef = FAA54AC71F91660400A8FA7B /* TheoraVideoStream.h */; }; + FAA54ACC1F91660400A8FA7B /* TheoraVideoStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAA54AC81F91660400A8FA7B /* TheoraVideoStream.cpp */; }; + FAA54ACD1F91660400A8FA7B /* OggDemuxer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAA54AC91F91660400A8FA7B /* OggDemuxer.cpp */; }; FAA627CE18E7E1560080752D /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAA627CD18E7E1560080752D /* CoreServices.framework */; }; + FAAA3FD81F64B3AD00F89E99 /* lprefix.h in Headers */ = {isa = PBXBuildFile; fileRef = FAAA3FD31F64B3AD00F89E99 /* lprefix.h */; }; + FAAA3FD91F64B3AD00F89E99 /* lstrlib.c in Sources */ = {isa = PBXBuildFile; fileRef = FAAA3FD41F64B3AD00F89E99 /* lstrlib.c */; }; + FAAA3FDA1F64B3AD00F89E99 /* lstrlib.h in Headers */ = {isa = PBXBuildFile; fileRef = FAAA3FD51F64B3AD00F89E99 /* lstrlib.h */; }; + FAAA3FDB1F64B3AD00F89E99 /* lutf8lib.c in Sources */ = {isa = PBXBuildFile; fileRef = FAAA3FD61F64B3AD00F89E99 /* lutf8lib.c */; }; + FAAA3FDC1F64B3AD00F89E99 /* lutf8lib.h in Headers */ = {isa = PBXBuildFile; fileRef = FAAA3FD71F64B3AD00F89E99 /* lutf8lib.h */; }; FAAFF04416CB11C700CCDE45 /* OpenAL-Soft.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAAFF04316CB11C700CCDE45 /* OpenAL-Soft.framework */; }; - FAB17BE01ABFAA2000F9BA27 /* Compressor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB17BDE1ABFAA2000F9BA27 /* Compressor.cpp */; }; - FAB17BE11ABFAA2000F9BA27 /* Compressor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB17BDE1ABFAA2000F9BA27 /* Compressor.cpp */; }; - FAB17BE21ABFAA2000F9BA27 /* Compressor.h in Headers */ = {isa = PBXBuildFile; fileRef = FAB17BDF1ABFAA2000F9BA27 /* Compressor.h */; }; FAB17BE61ABFAA9000F9BA27 /* lz4.c in Sources */ = {isa = PBXBuildFile; fileRef = FAB17BE41ABFAA9000F9BA27 /* lz4.c */; }; FAB17BE71ABFAA9000F9BA27 /* lz4.c in Sources */ = {isa = PBXBuildFile; fileRef = FAB17BE41ABFAA9000F9BA27 /* lz4.c */; }; FAB17BE81ABFAA9000F9BA27 /* lz4.h in Headers */ = {isa = PBXBuildFile; fileRef = FAB17BE51ABFAA9000F9BA27 /* lz4.h */; }; - FAB17BEB1ABFAF1800F9BA27 /* CompressedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB17BE91ABFAF1800F9BA27 /* CompressedData.cpp */; }; - FAB17BEC1ABFAF1800F9BA27 /* CompressedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB17BE91ABFAF1800F9BA27 /* CompressedData.cpp */; }; - FAB17BED1ABFAF1800F9BA27 /* CompressedData.h in Headers */ = {isa = PBXBuildFile; fileRef = FAB17BEA1ABFAF1800F9BA27 /* CompressedData.h */; }; - FAB17BF01ABFB37500F9BA27 /* wrap_CompressedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB17BEE1ABFB37500F9BA27 /* wrap_CompressedData.cpp */; }; - FAB17BF11ABFB37500F9BA27 /* wrap_CompressedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB17BEE1ABFB37500F9BA27 /* wrap_CompressedData.cpp */; }; - FAB17BF21ABFB37500F9BA27 /* wrap_CompressedData.h in Headers */ = {isa = PBXBuildFile; fileRef = FAB17BEF1ABFB37500F9BA27 /* wrap_CompressedData.h */; }; FAB17BF51ABFC4B100F9BA27 /* lz4hc.c in Sources */ = {isa = PBXBuildFile; fileRef = FAB17BF31ABFC4B100F9BA27 /* lz4hc.c */; }; FAB17BF61ABFC4B100F9BA27 /* lz4hc.c in Sources */ = {isa = PBXBuildFile; fileRef = FAB17BF31ABFC4B100F9BA27 /* lz4hc.c */; }; FAB17BF71ABFC4B100F9BA27 /* lz4hc.h in Headers */ = {isa = PBXBuildFile; fileRef = FAB17BF41ABFC4B100F9BA27 /* lz4hc.h */; }; FAB2D5AA1AABDD8A008224A4 /* TrueTypeRasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB2D5A81AABDD8A008224A4 /* TrueTypeRasterizer.cpp */; }; FAB2D5AB1AABDD8A008224A4 /* TrueTypeRasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB2D5A81AABDD8A008224A4 /* TrueTypeRasterizer.cpp */; }; FAB2D5AC1AABDD8A008224A4 /* TrueTypeRasterizer.h in Headers */ = {isa = PBXBuildFile; fileRef = FAB2D5A91AABDD8A008224A4 /* TrueTypeRasterizer.h */; }; + FAC756F51E4F99B400B91289 /* Effect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC756F31E4F99B400B91289 /* Effect.cpp */; }; + FAC756F61E4F99B400B91289 /* Effect.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC756F41E4F99B400B91289 /* Effect.h */; }; + FAC756F71E4F99BC00B91289 /* Effect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC756F31E4F99B400B91289 /* Effect.cpp */; }; + FAC756FA1E4F99D200B91289 /* Effect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC756F81E4F99D200B91289 /* Effect.cpp */; }; + FAC756FB1E4F99D200B91289 /* Effect.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC756F91E4F99D200B91289 /* Effect.h */; }; + FAC756FC1E4F99DB00B91289 /* Effect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC756F81E4F99D200B91289 /* Effect.cpp */; }; + FAC7CD771FE35E95006A60C7 /* physfs_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC7CD5A1FE35E95006A60C7 /* physfs_internal.h */; }; + FAC7CD781FE35E95006A60C7 /* physfs_platform_qnx.c in Sources */ = {isa = PBXBuildFile; fileRef = FAC7CD5B1FE35E95006A60C7 /* physfs_platform_qnx.c */; }; + FAC7CD791FE35E95006A60C7 /* physfs.c in Sources */ = {isa = PBXBuildFile; fileRef = FAC7CD5C1FE35E95006A60C7 /* physfs.c */; }; + FAC7CD7A1FE35E95006A60C7 /* physfs_archiver_7z.c in Sources */ = {isa = PBXBuildFile; fileRef = FAC7CD5D1FE35E95006A60C7 /* physfs_archiver_7z.c */; }; + FAC7CD7B1FE35E95006A60C7 /* physfs_platform_unix.c in Sources */ = {isa = PBXBuildFile; fileRef = FAC7CD5E1FE35E95006A60C7 /* physfs_platform_unix.c */; }; + FAC7CD7C1FE35E95006A60C7 /* physfs_archiver_slb.c in Sources */ = {isa = PBXBuildFile; fileRef = FAC7CD5F1FE35E95006A60C7 /* physfs_archiver_slb.c */; }; + FAC7CD7D1FE35E95006A60C7 /* physfs_platform_winrt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC7CD601FE35E95006A60C7 /* physfs_platform_winrt.cpp */; }; + FAC7CD7E1FE35E95006A60C7 /* physfs_archiver_mvl.c in Sources */ = {isa = PBXBuildFile; fileRef = FAC7CD611FE35E95006A60C7 /* physfs_archiver_mvl.c */; }; + FAC7CD7F1FE35E95006A60C7 /* physfs_archiver_wad.c in Sources */ = {isa = PBXBuildFile; fileRef = FAC7CD621FE35E95006A60C7 /* physfs_archiver_wad.c */; }; + FAC7CD801FE35E95006A60C7 /* physfs_casefolding.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC7CD631FE35E95006A60C7 /* physfs_casefolding.h */; }; + FAC7CD811FE35E95006A60C7 /* physfs_platform_os2.c in Sources */ = {isa = PBXBuildFile; fileRef = FAC7CD641FE35E95006A60C7 /* physfs_platform_os2.c */; }; + FAC7CD821FE35E95006A60C7 /* physfs_platform_haiku.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC7CD651FE35E95006A60C7 /* physfs_platform_haiku.cpp */; }; + FAC7CD831FE35E95006A60C7 /* physfs_platform_windows.c in Sources */ = {isa = PBXBuildFile; fileRef = FAC7CD661FE35E95006A60C7 /* physfs_platform_windows.c */; }; + FAC7CD841FE35E95006A60C7 /* physfs_archiver_unpacked.c in Sources */ = {isa = PBXBuildFile; fileRef = FAC7CD671FE35E95006A60C7 /* physfs_archiver_unpacked.c */; }; + FAC7CD851FE35E95006A60C7 /* physfs_unicode.c in Sources */ = {isa = PBXBuildFile; fileRef = FAC7CD681FE35E95006A60C7 /* physfs_unicode.c */; }; + FAC7CD861FE35E95006A60C7 /* physfs.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC7CD691FE35E95006A60C7 /* physfs.h */; }; + FAC7CD871FE35E95006A60C7 /* physfs_archiver_vdf.c in Sources */ = {isa = PBXBuildFile; fileRef = FAC7CD6A1FE35E95006A60C7 /* physfs_archiver_vdf.c */; }; + FAC7CD881FE35E95006A60C7 /* physfs_platform_apple.m in Sources */ = {isa = PBXBuildFile; fileRef = FAC7CD6B1FE35E95006A60C7 /* physfs_platform_apple.m */; }; + FAC7CD891FE35E95006A60C7 /* physfs_archiver_dir.c in Sources */ = {isa = PBXBuildFile; fileRef = FAC7CD6C1FE35E95006A60C7 /* physfs_archiver_dir.c */; }; + FAC7CD8A1FE35E95006A60C7 /* physfs_byteorder.c in Sources */ = {isa = PBXBuildFile; fileRef = FAC7CD6D1FE35E95006A60C7 /* physfs_byteorder.c */; }; + FAC7CD8B1FE35E95006A60C7 /* physfs_archiver_iso9660.c in Sources */ = {isa = PBXBuildFile; fileRef = FAC7CD6E1FE35E95006A60C7 /* physfs_archiver_iso9660.c */; }; + FAC7CD8C1FE35E95006A60C7 /* physfs_archiver_qpak.c in Sources */ = {isa = PBXBuildFile; fileRef = FAC7CD6F1FE35E95006A60C7 /* physfs_archiver_qpak.c */; }; + FAC7CD8D1FE35E95006A60C7 /* physfs_platforms.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC7CD701FE35E95006A60C7 /* physfs_platforms.h */; }; + FAC7CD8E1FE35E95006A60C7 /* physfs_lzmasdk.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC7CD711FE35E95006A60C7 /* physfs_lzmasdk.h */; }; + FAC7CD8F1FE35E95006A60C7 /* physfs_platform_posix.c in Sources */ = {isa = PBXBuildFile; fileRef = FAC7CD721FE35E95006A60C7 /* physfs_platform_posix.c */; }; + FAC7CD901FE35E95006A60C7 /* physfs_miniz.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC7CD731FE35E95006A60C7 /* physfs_miniz.h */; }; + FAC7CD911FE35E95006A60C7 /* physfs_archiver_grp.c in Sources */ = {isa = PBXBuildFile; fileRef = FAC7CD741FE35E95006A60C7 /* physfs_archiver_grp.c */; }; + FAC7CD921FE35E95006A60C7 /* physfs_archiver_hog.c in Sources */ = {isa = PBXBuildFile; fileRef = FAC7CD751FE35E95006A60C7 /* physfs_archiver_hog.c */; }; + FAC7CD931FE35E95006A60C7 /* physfs_archiver_zip.c in Sources */ = {isa = PBXBuildFile; fileRef = FAC7CD761FE35E95006A60C7 /* physfs_archiver_zip.c */; }; + FAC7CD961FE755B4006A60C7 /* lz4opt.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC7CD951FE755B3006A60C7 /* lz4opt.h */; }; + FACA02EC1F5E396B0084B28F /* CompressedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FACA02E01F5E396B0084B28F /* CompressedData.cpp */; }; + FACA02ED1F5E396B0084B28F /* CompressedData.h in Headers */ = {isa = PBXBuildFile; fileRef = FACA02E11F5E396B0084B28F /* CompressedData.h */; }; + FACA02EE1F5E396B0084B28F /* Compressor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FACA02E21F5E396B0084B28F /* Compressor.cpp */; }; + FACA02EF1F5E396B0084B28F /* Compressor.h in Headers */ = {isa = PBXBuildFile; fileRef = FACA02E31F5E396B0084B28F /* Compressor.h */; }; + FACA02F01F5E396B0084B28F /* DataModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FACA02E41F5E396B0084B28F /* DataModule.cpp */; }; + FACA02F11F5E396B0084B28F /* DataModule.h in Headers */ = {isa = PBXBuildFile; fileRef = FACA02E51F5E396B0084B28F /* DataModule.h */; }; + FACA02F21F5E396B0084B28F /* HashFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FACA02E61F5E396B0084B28F /* HashFunction.cpp */; }; + FACA02F31F5E396B0084B28F /* HashFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = FACA02E71F5E396B0084B28F /* HashFunction.h */; }; + FACA02F41F5E396B0084B28F /* wrap_CompressedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FACA02E81F5E396B0084B28F /* wrap_CompressedData.cpp */; }; + FACA02F51F5E396B0084B28F /* wrap_CompressedData.h in Headers */ = {isa = PBXBuildFile; fileRef = FACA02E91F5E396B0084B28F /* wrap_CompressedData.h */; }; + FACA02F61F5E396B0084B28F /* wrap_DataModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FACA02EA1F5E396B0084B28F /* wrap_DataModule.cpp */; }; + FACA02F71F5E396B0084B28F /* wrap_DataModule.h in Headers */ = {isa = PBXBuildFile; fileRef = FACA02EB1F5E396B0084B28F /* wrap_DataModule.h */; }; + FACA02F81F5E39760084B28F /* CompressedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FACA02E01F5E396B0084B28F /* CompressedData.cpp */; }; + FACA02F91F5E39790084B28F /* Compressor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FACA02E21F5E396B0084B28F /* Compressor.cpp */; }; + FACA02FA1F5E397B0084B28F /* DataModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FACA02E41F5E396B0084B28F /* DataModule.cpp */; }; + FACA02FB1F5E397E0084B28F /* HashFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FACA02E61F5E396B0084B28F /* HashFunction.cpp */; }; + FACA02FC1F5E39810084B28F /* wrap_CompressedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FACA02E81F5E396B0084B28F /* wrap_CompressedData.cpp */; }; + FACA02FD1F5E39840084B28F /* wrap_DataModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FACA02EA1F5E396B0084B28F /* wrap_DataModule.cpp */; }; + FAD19A171DFF8CA200D5398A /* ImageDataBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAD19A151DFF8CA200D5398A /* ImageDataBase.cpp */; }; + FAD19A181DFF8CA200D5398A /* ImageDataBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAD19A151DFF8CA200D5398A /* ImageDataBase.cpp */; }; + FAD19A191DFF8CA200D5398A /* ImageDataBase.h in Headers */ = {isa = PBXBuildFile; fileRef = FAD19A161DFF8CA200D5398A /* ImageDataBase.h */; }; + FAD43ECC1FF312D800831BB8 /* freetype.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAD43ECB1FF312D800831BB8 /* freetype.framework */; }; + FADF53F81E3C7ACD00012CC0 /* Buffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF53F61E3C7ACD00012CC0 /* Buffer.cpp */; }; + FADF53F91E3C7ACD00012CC0 /* Buffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF53F61E3C7ACD00012CC0 /* Buffer.cpp */; }; + FADF53FA1E3C7ACD00012CC0 /* Buffer.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF53F71E3C7ACD00012CC0 /* Buffer.h */; }; + FADF53FD1E3D74F200012CC0 /* Text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF53FB1E3D74F200012CC0 /* Text.cpp */; }; + FADF53FE1E3D74F200012CC0 /* Text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF53FB1E3D74F200012CC0 /* Text.cpp */; }; + FADF53FF1E3D74F200012CC0 /* Text.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF53FC1E3D74F200012CC0 /* Text.h */; }; + FADF54021E3D77B500012CC0 /* wrap_Text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54001E3D77B500012CC0 /* wrap_Text.cpp */; }; + FADF54031E3D77B500012CC0 /* wrap_Text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54001E3D77B500012CC0 /* wrap_Text.cpp */; }; + FADF54041E3D77B500012CC0 /* wrap_Text.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF54011E3D77B500012CC0 /* wrap_Text.h */; }; + FADF54071E3D78F700012CC0 /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54051E3D78F700012CC0 /* Video.cpp */; }; + FADF54081E3D78F700012CC0 /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54051E3D78F700012CC0 /* Video.cpp */; }; + FADF54091E3D78F700012CC0 /* Video.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF54061E3D78F700012CC0 /* Video.h */; }; + FADF540D1E3D7CDD00012CC0 /* wrap_Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF540A1E3D7CDD00012CC0 /* wrap_Video.cpp */; }; + FADF540E1E3D7CDD00012CC0 /* wrap_Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF540A1E3D7CDD00012CC0 /* wrap_Video.cpp */; }; + FADF540F1E3D7CDD00012CC0 /* wrap_Video.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF540B1E3D7CDD00012CC0 /* wrap_Video.h */; }; + FADF54101E3D7CDD00012CC0 /* wrap_Video.lua in Resources */ = {isa = PBXBuildFile; fileRef = FADF540C1E3D7CDD00012CC0 /* wrap_Video.lua */; }; + FADF54161E3DA08E00012CC0 /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54141E3DA08E00012CC0 /* Image.cpp */; }; + FADF54171E3DA08E00012CC0 /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54141E3DA08E00012CC0 /* Image.cpp */; }; + FADF54181E3DA08E00012CC0 /* Image.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF54151E3DA08E00012CC0 /* Image.h */; }; + FADF541B1E3DA46C00012CC0 /* wrap_Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54191E3DA46C00012CC0 /* wrap_Image.cpp */; }; + FADF541C1E3DA46C00012CC0 /* wrap_Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54191E3DA46C00012CC0 /* wrap_Image.cpp */; }; + FADF541D1E3DA46C00012CC0 /* wrap_Image.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF541A1E3DA46C00012CC0 /* wrap_Image.h */; }; + FADF54201E3DA52C00012CC0 /* wrap_ParticleSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF541E1E3DA52C00012CC0 /* wrap_ParticleSystem.cpp */; }; + FADF54211E3DA52C00012CC0 /* wrap_ParticleSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF541E1E3DA52C00012CC0 /* wrap_ParticleSystem.cpp */; }; + FADF54221E3DA52C00012CC0 /* wrap_ParticleSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF541F1E3DA52C00012CC0 /* wrap_ParticleSystem.h */; }; + FADF54251E3DA5BA00012CC0 /* Mesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54231E3DA5BA00012CC0 /* Mesh.cpp */; }; + FADF54261E3DA5BA00012CC0 /* Mesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54231E3DA5BA00012CC0 /* Mesh.cpp */; }; + FADF54271E3DA5BA00012CC0 /* Mesh.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF54241E3DA5BA00012CC0 /* Mesh.h */; }; + FADF542A1E3DAADA00012CC0 /* wrap_Mesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54281E3DAADA00012CC0 /* wrap_Mesh.cpp */; }; + FADF542B1E3DAADA00012CC0 /* wrap_Mesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54281E3DAADA00012CC0 /* wrap_Mesh.cpp */; }; + FADF542C1E3DAADA00012CC0 /* wrap_Mesh.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF54291E3DAADA00012CC0 /* wrap_Mesh.h */; }; + FADF542F1E3DABF600012CC0 /* SpriteBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF542D1E3DABF600012CC0 /* SpriteBatch.cpp */; }; + FADF54301E3DABF600012CC0 /* SpriteBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF542D1E3DABF600012CC0 /* SpriteBatch.cpp */; }; + FADF54311E3DABF600012CC0 /* SpriteBatch.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF542E1E3DABF600012CC0 /* SpriteBatch.h */; }; + FADF54341E3DAE6E00012CC0 /* wrap_SpriteBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54321E3DAE6E00012CC0 /* wrap_SpriteBatch.cpp */; }; + FADF54351E3DAE6E00012CC0 /* wrap_SpriteBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54321E3DAE6E00012CC0 /* wrap_SpriteBatch.cpp */; }; + FADF54361E3DAE6E00012CC0 /* wrap_SpriteBatch.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF54331E3DAE6E00012CC0 /* wrap_SpriteBatch.h */; }; + FADF54381E3DAFBA00012CC0 /* wrap_Graphics.lua in Resources */ = {isa = PBXBuildFile; fileRef = FADF54371E3DAFBA00012CC0 /* wrap_Graphics.lua */; }; + FADF543B1E3DAFF700012CC0 /* wrap_Graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54391E3DAFF700012CC0 /* wrap_Graphics.cpp */; }; + FADF543C1E3DAFF700012CC0 /* wrap_Graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54391E3DAFF700012CC0 /* wrap_Graphics.cpp */; }; + FADF543D1E3DAFF700012CC0 /* wrap_Graphics.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF543A1E3DAFF700012CC0 /* wrap_Graphics.h */; }; FAE272521C05A15B00A67640 /* ParticleSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAE272501C05A15B00A67640 /* ParticleSystem.cpp */; }; FAE272531C05A15B00A67640 /* ParticleSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE272511C05A15B00A67640 /* ParticleSystem.h */; }; + FAECA1B21F3164700095D008 /* CompressedSlice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAECA1B01F3164700095D008 /* CompressedSlice.cpp */; }; + FAECA1B31F3164700095D008 /* CompressedSlice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAECA1B01F3164700095D008 /* CompressedSlice.cpp */; }; + FAECA1B41F3164700095D008 /* CompressedSlice.h in Headers */ = {isa = PBXBuildFile; fileRef = FAECA1B11F3164700095D008 /* CompressedSlice.h */; }; + FAECA1B51F31648A0095D008 /* FormatHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA93C4511F315B960087CCD4 /* FormatHandler.cpp */; }; + FAF140531E20934C00F898D2 /* CodeGen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FC21E20934C00F898D2 /* CodeGen.cpp */; }; + FAF140541E20934C00F898D2 /* CodeGen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FC21E20934C00F898D2 /* CodeGen.cpp */; }; + FAF140551E20934C00F898D2 /* Link.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FC31E20934C00F898D2 /* Link.cpp */; }; + FAF140561E20934C00F898D2 /* Link.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FC31E20934C00F898D2 /* Link.cpp */; }; + FAF140571E20934C00F898D2 /* arrays.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FC51E20934C00F898D2 /* arrays.h */; }; + FAF140581E20934C00F898D2 /* BaseTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FC61E20934C00F898D2 /* BaseTypes.h */; }; + FAF140591E20934C00F898D2 /* Common.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FC71E20934C00F898D2 /* Common.h */; }; + FAF1405A1E20934C00F898D2 /* ConstantUnion.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FC81E20934C00F898D2 /* ConstantUnion.h */; }; + FAF1405B1E20934C00F898D2 /* InfoSink.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FC91E20934C00F898D2 /* InfoSink.h */; }; + FAF1405C1E20934C00F898D2 /* InitializeGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FCA1E20934C00F898D2 /* InitializeGlobals.h */; }; + FAF1405D1E20934C00F898D2 /* intermediate.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FCB1E20934C00F898D2 /* intermediate.h */; }; + FAF1405E1E20934C00F898D2 /* PoolAlloc.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FCC1E20934C00F898D2 /* PoolAlloc.h */; }; + FAF1405F1E20934C00F898D2 /* ResourceLimits.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FCD1E20934C00F898D2 /* ResourceLimits.h */; }; + FAF140601E20934C00F898D2 /* revision.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FCE1E20934C00F898D2 /* revision.h */; }; + FAF140621E20934C00F898D2 /* ShHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FD01E20934C00F898D2 /* ShHandle.h */; }; + FAF140631E20934C00F898D2 /* Types.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FD11E20934C00F898D2 /* Types.h */; }; + FAF140641E20934C00F898D2 /* Constant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FD31E20934C00F898D2 /* Constant.cpp */; }; + FAF140651E20934C00F898D2 /* Constant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FD31E20934C00F898D2 /* Constant.cpp */; }; + FAF140661E20934C00F898D2 /* gl_types.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FD41E20934C00F898D2 /* gl_types.h */; }; + FAF140691E20934C00F898D2 /* glslang_tab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FD61E20934C00F898D2 /* glslang_tab.cpp */; }; + FAF1406A1E20934C00F898D2 /* glslang_tab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FD61E20934C00F898D2 /* glslang_tab.cpp */; }; + FAF1406B1E20934C00F898D2 /* glslang_tab.cpp.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FD71E20934C00F898D2 /* glslang_tab.cpp.h */; }; + FAF1406C1E20934C00F898D2 /* InfoSink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FD81E20934C00F898D2 /* InfoSink.cpp */; }; + FAF1406D1E20934C00F898D2 /* InfoSink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FD81E20934C00F898D2 /* InfoSink.cpp */; }; + FAF1406E1E20934C00F898D2 /* Initialize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FD91E20934C00F898D2 /* Initialize.cpp */; }; + FAF1406F1E20934C00F898D2 /* Initialize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FD91E20934C00F898D2 /* Initialize.cpp */; }; + FAF140701E20934C00F898D2 /* Initialize.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FDA1E20934C00F898D2 /* Initialize.h */; }; + FAF140711E20934C00F898D2 /* Intermediate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FDB1E20934C00F898D2 /* Intermediate.cpp */; }; + FAF140721E20934C00F898D2 /* Intermediate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FDB1E20934C00F898D2 /* Intermediate.cpp */; }; + FAF140731E20934C00F898D2 /* intermOut.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FDC1E20934C00F898D2 /* intermOut.cpp */; }; + FAF140741E20934C00F898D2 /* intermOut.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FDC1E20934C00F898D2 /* intermOut.cpp */; }; + FAF140751E20934C00F898D2 /* IntermTraverse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FDD1E20934C00F898D2 /* IntermTraverse.cpp */; }; + FAF140761E20934C00F898D2 /* IntermTraverse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FDD1E20934C00F898D2 /* IntermTraverse.cpp */; }; + FAF140771E20934C00F898D2 /* iomapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FDE1E20934C00F898D2 /* iomapper.cpp */; }; + FAF140781E20934C00F898D2 /* iomapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FDE1E20934C00F898D2 /* iomapper.cpp */; }; + FAF140791E20934C00F898D2 /* iomapper.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FDF1E20934C00F898D2 /* iomapper.h */; }; + FAF1407A1E20934C00F898D2 /* limits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FE01E20934C00F898D2 /* limits.cpp */; }; + FAF1407B1E20934C00F898D2 /* limits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FE01E20934C00F898D2 /* limits.cpp */; }; + FAF1407C1E20934C00F898D2 /* linkValidate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FE11E20934C00F898D2 /* linkValidate.cpp */; }; + FAF1407D1E20934C00F898D2 /* linkValidate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FE11E20934C00F898D2 /* linkValidate.cpp */; }; + FAF1407E1E20934C00F898D2 /* LiveTraverser.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FE21E20934C00F898D2 /* LiveTraverser.h */; }; + FAF1407F1E20934C00F898D2 /* localintermediate.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FE31E20934C00F898D2 /* localintermediate.h */; }; + FAF140801E20934C00F898D2 /* parseConst.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FE41E20934C00F898D2 /* parseConst.cpp */; }; + FAF140811E20934C00F898D2 /* parseConst.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FE41E20934C00F898D2 /* parseConst.cpp */; }; + FAF140821E20934C00F898D2 /* ParseContextBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FE51E20934C00F898D2 /* ParseContextBase.cpp */; }; + FAF140831E20934C00F898D2 /* ParseContextBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FE51E20934C00F898D2 /* ParseContextBase.cpp */; }; + FAF140841E20934C00F898D2 /* ParseHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FE61E20934C00F898D2 /* ParseHelper.cpp */; }; + FAF140851E20934C00F898D2 /* ParseHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FE61E20934C00F898D2 /* ParseHelper.cpp */; }; + FAF140861E20934C00F898D2 /* ParseHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FE71E20934C00F898D2 /* ParseHelper.h */; }; + FAF140871E20934C00F898D2 /* parseVersions.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FE81E20934C00F898D2 /* parseVersions.h */; }; + FAF140881E20934C00F898D2 /* PoolAlloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FE91E20934C00F898D2 /* PoolAlloc.cpp */; }; + FAF140891E20934C00F898D2 /* PoolAlloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FE91E20934C00F898D2 /* PoolAlloc.cpp */; }; + FAF1408A1E20934C00F898D2 /* Pp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FEB1E20934C00F898D2 /* Pp.cpp */; }; + FAF1408B1E20934C00F898D2 /* Pp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FEB1E20934C00F898D2 /* Pp.cpp */; }; + FAF1408C1E20934C00F898D2 /* PpAtom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FEC1E20934C00F898D2 /* PpAtom.cpp */; }; + FAF1408D1E20934C00F898D2 /* PpAtom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FEC1E20934C00F898D2 /* PpAtom.cpp */; }; + FAF1408E1E20934C00F898D2 /* PpContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FED1E20934C00F898D2 /* PpContext.cpp */; }; + FAF1408F1E20934C00F898D2 /* PpContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FED1E20934C00F898D2 /* PpContext.cpp */; }; + FAF140901E20934C00F898D2 /* PpContext.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FEE1E20934C00F898D2 /* PpContext.h */; }; + FAF140931E20934C00F898D2 /* PpScanner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF01E20934C00F898D2 /* PpScanner.cpp */; }; + FAF140941E20934C00F898D2 /* PpScanner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF01E20934C00F898D2 /* PpScanner.cpp */; }; + FAF140971E20934C00F898D2 /* PpTokens.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF21E20934C00F898D2 /* PpTokens.cpp */; }; + FAF140981E20934C00F898D2 /* PpTokens.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF21E20934C00F898D2 /* PpTokens.cpp */; }; + FAF140991E20934C00F898D2 /* PpTokens.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FF31E20934C00F898D2 /* PpTokens.h */; }; + FAF1409A1E20934C00F898D2 /* propagateNoContraction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF41E20934C00F898D2 /* propagateNoContraction.cpp */; }; + FAF1409B1E20934C00F898D2 /* propagateNoContraction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF41E20934C00F898D2 /* propagateNoContraction.cpp */; }; + FAF1409C1E20934C00F898D2 /* propagateNoContraction.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FF51E20934C00F898D2 /* propagateNoContraction.h */; }; + FAF1409D1E20934C00F898D2 /* reflection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF61E20934C00F898D2 /* reflection.cpp */; }; + FAF1409E1E20934C00F898D2 /* reflection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF61E20934C00F898D2 /* reflection.cpp */; }; + FAF1409F1E20934C00F898D2 /* reflection.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FF71E20934C00F898D2 /* reflection.h */; }; + FAF140A01E20934C00F898D2 /* RemoveTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF81E20934C00F898D2 /* RemoveTree.cpp */; }; + FAF140A11E20934C00F898D2 /* RemoveTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FF81E20934C00F898D2 /* RemoveTree.cpp */; }; + FAF140A21E20934C00F898D2 /* RemoveTree.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FF91E20934C00F898D2 /* RemoveTree.h */; }; + FAF140A31E20934C00F898D2 /* Scan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FFA1E20934C00F898D2 /* Scan.cpp */; }; + FAF140A41E20934C00F898D2 /* Scan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FFA1E20934C00F898D2 /* Scan.cpp */; }; + FAF140A51E20934C00F898D2 /* Scan.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FFB1E20934C00F898D2 /* Scan.h */; }; + FAF140A61E20934C00F898D2 /* ScanContext.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FFC1E20934C00F898D2 /* ScanContext.h */; }; + FAF140A71E20934C00F898D2 /* ShaderLang.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FFD1E20934C00F898D2 /* ShaderLang.cpp */; }; + FAF140A81E20934C00F898D2 /* ShaderLang.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FFD1E20934C00F898D2 /* ShaderLang.cpp */; }; + FAF140A91E20934C00F898D2 /* SymbolTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FFE1E20934C00F898D2 /* SymbolTable.cpp */; }; + FAF140AA1E20934C00F898D2 /* SymbolTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FFE1E20934C00F898D2 /* SymbolTable.cpp */; }; + FAF140AB1E20934C00F898D2 /* SymbolTable.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF13FFF1E20934C00F898D2 /* SymbolTable.h */; }; + FAF140AC1E20934C00F898D2 /* Versions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF140001E20934C00F898D2 /* Versions.cpp */; }; + FAF140AD1E20934C00F898D2 /* Versions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF140001E20934C00F898D2 /* Versions.cpp */; }; + FAF140AE1E20934C00F898D2 /* Versions.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF140011E20934C00F898D2 /* Versions.h */; }; + FAF140AF1E20934C00F898D2 /* osinclude.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF140031E20934C00F898D2 /* osinclude.h */; }; + FAF140BB1E20934C00F898D2 /* ossource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF140211E20934C00F898D2 /* ossource.cpp */; }; + FAF140BC1E20934C00F898D2 /* ossource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF140211E20934C00F898D2 /* ossource.cpp */; }; + FAF140C41E20934C00F898D2 /* ShaderLang.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF140291E20934C00F898D2 /* ShaderLang.h */; }; + FAF140DB1E20934C00F898D2 /* InitializeDll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF1403B1E20934C00F898D2 /* InitializeDll.cpp */; }; + FAF140DC1E20934C00F898D2 /* InitializeDll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF1403B1E20934C00F898D2 /* InitializeDll.cpp */; }; + FAF140DD1E20934C00F898D2 /* InitializeDll.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF1403C1E20934C00F898D2 /* InitializeDll.h */; }; + FAF1889F1E9DBC4B008C1479 /* depthstencil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF1889E1E9DBC4B008C1479 /* depthstencil.cpp */; }; + FAF188A01E9DBC4B008C1479 /* depthstencil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF1889E1E9DBC4B008C1479 /* depthstencil.cpp */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -917,11 +1195,68 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 217DFB9D1D9F6D490055D849 /* auxiliar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = auxiliar.c; sourceTree = ""; }; + 217DFB9E1D9F6D490055D849 /* auxiliar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = auxiliar.h; sourceTree = ""; }; + 217DFB9F1D9F6D490055D849 /* buffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = buffer.c; sourceTree = ""; }; + 217DFBA01D9F6D490055D849 /* buffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = buffer.h; sourceTree = ""; }; + 217DFBA11D9F6D490055D849 /* compat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = compat.c; sourceTree = ""; }; + 217DFBA21D9F6D490055D849 /* compat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = compat.h; sourceTree = ""; }; + 217DFBA31D9F6D490055D849 /* except.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = except.c; sourceTree = ""; }; + 217DFBA41D9F6D490055D849 /* except.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = except.h; sourceTree = ""; }; + 217DFBA51D9F6D490055D849 /* ftp.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ftp.lua; sourceTree = ""; }; + 217DFBA61D9F6D490055D849 /* ftp.lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ftp.lua.h; sourceTree = ""; }; + 217DFBA71D9F6D490055D849 /* headers.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = headers.lua; sourceTree = ""; }; + 217DFBA81D9F6D490055D849 /* headers.lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = headers.lua.h; sourceTree = ""; }; + 217DFBA91D9F6D490055D849 /* http.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = http.lua; sourceTree = ""; }; + 217DFBAA1D9F6D490055D849 /* http.lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = http.lua.h; sourceTree = ""; }; + 217DFBAB1D9F6D490055D849 /* inet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = inet.c; sourceTree = ""; }; + 217DFBAC1D9F6D490055D849 /* inet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = inet.h; sourceTree = ""; }; + 217DFBAD1D9F6D490055D849 /* io.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = io.c; sourceTree = ""; }; + 217DFBAE1D9F6D490055D849 /* io.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = io.h; sourceTree = ""; }; + 217DFBAF1D9F6D490055D849 /* ltn12.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ltn12.lua; sourceTree = ""; }; + 217DFBB01D9F6D490055D849 /* ltn12.lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ltn12.lua.h; sourceTree = ""; }; + 217DFBB11D9F6D490055D849 /* luasocket.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = luasocket.c; sourceTree = ""; }; + 217DFBB21D9F6D490055D849 /* luasocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = luasocket.h; sourceTree = ""; }; + 217DFBB41D9F6D490055D849 /* mbox.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mbox.lua; sourceTree = ""; }; + 217DFBB51D9F6D490055D849 /* mbox.lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mbox.lua.h; sourceTree = ""; }; + 217DFBB61D9F6D490055D849 /* mime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mime.c; sourceTree = ""; }; + 217DFBB71D9F6D490055D849 /* mime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mime.h; sourceTree = ""; }; + 217DFBB81D9F6D490055D849 /* mime.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mime.lua; sourceTree = ""; }; + 217DFBB91D9F6D490055D849 /* mime.lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mime.lua.h; sourceTree = ""; }; + 217DFBBA1D9F6D490055D849 /* options.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = options.c; sourceTree = ""; }; + 217DFBBB1D9F6D490055D849 /* options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = options.h; sourceTree = ""; }; + 217DFBBC1D9F6D490055D849 /* pierror.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pierror.h; sourceTree = ""; }; + 217DFBBD1D9F6D490055D849 /* select.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = select.c; sourceTree = ""; }; + 217DFBBE1D9F6D490055D849 /* select.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = select.h; sourceTree = ""; }; + 217DFBBF1D9F6D490055D849 /* serial.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = serial.c; sourceTree = ""; }; + 217DFBC01D9F6D490055D849 /* smtp.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = smtp.lua; sourceTree = ""; }; + 217DFBC11D9F6D490055D849 /* smtp.lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = smtp.lua.h; sourceTree = ""; }; + 217DFBC21D9F6D490055D849 /* socket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = socket.h; sourceTree = ""; }; + 217DFBC31D9F6D490055D849 /* socket.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = socket.lua; sourceTree = ""; }; + 217DFBC41D9F6D490055D849 /* socket.lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = socket.lua.h; sourceTree = ""; }; + 217DFBC51D9F6D490055D849 /* tcp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tcp.c; sourceTree = ""; }; + 217DFBC61D9F6D490055D849 /* tcp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tcp.h; sourceTree = ""; }; + 217DFBC71D9F6D490055D849 /* timeout.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = timeout.c; sourceTree = ""; }; + 217DFBC81D9F6D490055D849 /* timeout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = timeout.h; sourceTree = ""; }; + 217DFBC91D9F6D490055D849 /* tp.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tp.lua; sourceTree = ""; }; + 217DFBCA1D9F6D490055D849 /* tp.lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tp.lua.h; sourceTree = ""; }; + 217DFBCB1D9F6D490055D849 /* udp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = udp.c; sourceTree = ""; }; + 217DFBCC1D9F6D490055D849 /* udp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = udp.h; sourceTree = ""; }; + 217DFBCD1D9F6D490055D849 /* unix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = unix.c; sourceTree = ""; }; + 217DFBCE1D9F6D490055D849 /* unix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unix.h; sourceTree = ""; }; + 217DFBCF1D9F6D490055D849 /* unixtcp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = unixtcp.c; sourceTree = ""; }; + 217DFBD01D9F6D490055D849 /* unixtcp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unixtcp.h; sourceTree = ""; }; + 217DFBD11D9F6D490055D849 /* unixudp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = unixudp.c; sourceTree = ""; }; + 217DFBD21D9F6D490055D849 /* unixudp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unixudp.h; sourceTree = ""; }; + 217DFBD31D9F6D490055D849 /* url.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = url.lua; sourceTree = ""; }; + 217DFBD41D9F6D490055D849 /* url.lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = url.lua.h; sourceTree = ""; }; + 217DFBD51D9F6D490055D849 /* usocket.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = usocket.c; sourceTree = ""; }; + 217DFBD61D9F6D490055D849 /* usocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = usocket.h; sourceTree = ""; }; 503971A86B7167A91B670FBA /* boot.lua.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = boot.lua.h; sourceTree = ""; }; FA08F5AE16C7525600F007B5 /* liblove-macosx.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "liblove-macosx.plist"; path = "macosx/liblove-macosx.plist"; sourceTree = ""; }; FA0B78DD1A958B90000E1D17 /* liblove.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = liblove.a; sourceTree = BUILT_PRODUCTS_DIR; }; - FA0B78F71A958E3B000E1D17 /* b64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b64.cpp; sourceTree = ""; }; - FA0B78F81A958E3B000E1D17 /* b64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b64.h; sourceTree = ""; }; + FA0B78F71A958E3B000E1D17 /* b64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = b64.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; + FA0B78F81A958E3B000E1D17 /* b64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = b64.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; FA0B78F91A958E3B000E1D17 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = ""; }; FA0B78FA1A958E3B000E1D17 /* Data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Data.h; sourceTree = ""; }; FA0B78FB1A958E3B000E1D17 /* delay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = delay.cpp; sourceTree = ""; }; @@ -954,8 +1289,6 @@ FA0B79161A958E3B000E1D17 /* Vector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Vector.cpp; sourceTree = ""; }; FA0B79171A958E3B000E1D17 /* Vector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Vector.h; sourceTree = ""; }; FA0B79181A958E3B000E1D17 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = ""; }; - FA0B79191A958E3B000E1D17 /* wrap_Data.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Data.cpp; sourceTree = ""; }; - FA0B791A1A958E3B000E1D17 /* wrap_Data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Data.h; sourceTree = ""; }; FA0B794F1A958EA3000E1D17 /* Box2D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Box2D.h; sourceTree = ""; }; FA0B79511A958EA3000E1D17 /* b2BroadPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2BroadPhase.cpp; sourceTree = ""; }; FA0B79521A958EA3000E1D17 /* b2BroadPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2BroadPhase.h; sourceTree = ""; }; @@ -1077,58 +1410,8 @@ FA0B79D71A958EA3000E1D17 /* gladfuncs.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = gladfuncs.hpp; sourceTree = ""; }; FA0B79D91A958EA3000E1D17 /* lodepng.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lodepng.cpp; sourceTree = ""; }; FA0B79DA1A958EA3000E1D17 /* lodepng.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lodepng.h; sourceTree = ""; }; - FA0B79DD1A958EA3000E1D17 /* auxiliar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = auxiliar.c; sourceTree = ""; }; - FA0B79DE1A958EA3000E1D17 /* auxiliar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = auxiliar.h; sourceTree = ""; }; - FA0B79DF1A958EA3000E1D17 /* buffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = buffer.c; sourceTree = ""; }; - FA0B79E01A958EA3000E1D17 /* buffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = buffer.h; sourceTree = ""; }; - FA0B79E11A958EA3000E1D17 /* except.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = except.c; sourceTree = ""; }; - FA0B79E21A958EA3000E1D17 /* except.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = except.h; sourceTree = ""; }; - FA0B79E31A958EA3000E1D17 /* ftp.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ftp.lua; sourceTree = ""; }; - FA0B79E41A958EA3000E1D17 /* ftp.lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ftp.lua.h; sourceTree = ""; }; - FA0B79E51A958EA3000E1D17 /* http.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = http.lua; sourceTree = ""; }; - FA0B79E61A958EA3000E1D17 /* http.lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = http.lua.h; sourceTree = ""; }; - FA0B79E71A958EA3000E1D17 /* inet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = inet.c; sourceTree = ""; }; - FA0B79E81A958EA3000E1D17 /* inet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = inet.h; sourceTree = ""; }; - FA0B79E91A958EA3000E1D17 /* io.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = io.c; sourceTree = ""; }; - FA0B79EA1A958EA3000E1D17 /* io.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = io.h; sourceTree = ""; }; - FA0B79EB1A958EA3000E1D17 /* ltn12.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ltn12.lua; sourceTree = ""; }; - FA0B79EC1A958EA3000E1D17 /* ltn12.lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ltn12.lua.h; sourceTree = ""; }; - FA0B79ED1A958EA3000E1D17 /* lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua.h; sourceTree = ""; }; - FA0B79EE1A958EA3000E1D17 /* luasocket.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = luasocket.c; sourceTree = ""; }; - FA0B79EF1A958EA3000E1D17 /* luasocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = luasocket.h; sourceTree = ""; }; - FA0B79F01A958EA3000E1D17 /* mime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mime.c; sourceTree = ""; }; - FA0B79F11A958EA3000E1D17 /* mime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mime.h; sourceTree = ""; }; - FA0B79F21A958EA3000E1D17 /* mime.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mime.lua; sourceTree = ""; }; - FA0B79F31A958EA3000E1D17 /* mime.lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mime.lua.h; sourceTree = ""; }; - FA0B79F41A958EA3000E1D17 /* options.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = options.c; sourceTree = ""; }; - FA0B79F51A958EA3000E1D17 /* options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = options.h; sourceTree = ""; }; - FA0B79F61A958EA3000E1D17 /* pre.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = pre.lua; sourceTree = ""; }; - FA0B79F71A958EA3000E1D17 /* select.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = select.c; sourceTree = ""; }; - FA0B79F81A958EA3000E1D17 /* select.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = select.h; sourceTree = ""; }; - FA0B79F91A958EA3000E1D17 /* smtp.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = smtp.lua; sourceTree = ""; }; - FA0B79FA1A958EA3000E1D17 /* smtp.lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = smtp.lua.h; sourceTree = ""; }; - FA0B79FB1A958EA3000E1D17 /* socket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = socket.h; sourceTree = ""; }; - FA0B79FC1A958EA3000E1D17 /* socket.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = socket.lua; sourceTree = ""; }; - FA0B79FD1A958EA3000E1D17 /* socket.lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = socket.lua.h; sourceTree = ""; }; - FA0B79FE1A958EA3000E1D17 /* tcp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tcp.c; sourceTree = ""; }; - FA0B79FF1A958EA3000E1D17 /* tcp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tcp.h; sourceTree = ""; }; - FA0B7A001A958EA3000E1D17 /* timeout.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = timeout.c; sourceTree = ""; }; - FA0B7A011A958EA3000E1D17 /* timeout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = timeout.h; sourceTree = ""; }; - FA0B7A021A958EA3000E1D17 /* tp.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tp.lua; sourceTree = ""; }; - FA0B7A031A958EA3000E1D17 /* tp.lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tp.lua.h; sourceTree = ""; }; - FA0B7A041A958EA3000E1D17 /* udp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = udp.c; sourceTree = ""; }; - FA0B7A051A958EA3000E1D17 /* udp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = udp.h; sourceTree = ""; }; - FA0B7A061A958EA3000E1D17 /* unix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = unix.c; sourceTree = ""; }; - FA0B7A071A958EA3000E1D17 /* unix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unix.h; sourceTree = ""; }; - FA0B7A081A958EA3000E1D17 /* url.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = url.lua; sourceTree = ""; }; - FA0B7A091A958EA3000E1D17 /* url.lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = url.lua.h; sourceTree = ""; }; - FA0B7A0A1A958EA3000E1D17 /* usocket.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = usocket.c; sourceTree = ""; }; - FA0B7A0B1A958EA3000E1D17 /* usocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = usocket.h; sourceTree = ""; }; FA0B7A0E1A958EA3000E1D17 /* luasocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = luasocket.cpp; sourceTree = ""; }; FA0B7A0F1A958EA3000E1D17 /* luasocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = luasocket.h; sourceTree = ""; }; - FA0B7A111A958EA3000E1D17 /* lprefix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lprefix.h; sourceTree = ""; }; - FA0B7A121A958EA3000E1D17 /* lutf8lib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lutf8lib.c; sourceTree = ""; }; - FA0B7A131A958EA3000E1D17 /* lutf8lib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lutf8lib.h; sourceTree = ""; }; FA0B7A151A958EA3000E1D17 /* simplexnoise1234.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = simplexnoise1234.cpp; sourceTree = ""; }; FA0B7A161A958EA3000E1D17 /* simplexnoise1234.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = simplexnoise1234.h; sourceTree = ""; }; FA0B7A181A958EA3000E1D17 /* stb_image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stb_image.h; sourceTree = ""; }; @@ -1144,14 +1427,14 @@ FA0B7A251A958EA3000E1D17 /* wuff_internal.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wuff_internal.c; sourceTree = ""; }; FA0B7A261A958EA3000E1D17 /* wuff_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wuff_internal.h; sourceTree = ""; }; FA0B7A271A958EA3000E1D17 /* wuff_memory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wuff_memory.c; sourceTree = ""; }; - FA0B7B3E1A95902C000E1D17 /* Audio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Audio.cpp; sourceTree = ""; }; - FA0B7B3F1A95902C000E1D17 /* Audio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Audio.h; sourceTree = ""; }; - FA0B7B411A95902C000E1D17 /* Audio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Audio.cpp; sourceTree = ""; }; - FA0B7B421A95902C000E1D17 /* Audio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Audio.h; sourceTree = ""; }; + FA0B7B3E1A95902C000E1D17 /* Audio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = Audio.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; + FA0B7B3F1A95902C000E1D17 /* Audio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = Audio.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; + FA0B7B411A95902C000E1D17 /* Audio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = Audio.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; + FA0B7B421A95902C000E1D17 /* Audio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = Audio.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; FA0B7B431A95902C000E1D17 /* Source.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Source.cpp; sourceTree = ""; }; FA0B7B441A95902C000E1D17 /* Source.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Source.h; sourceTree = ""; }; - FA0B7B461A95902C000E1D17 /* Audio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Audio.cpp; sourceTree = ""; }; - FA0B7B471A95902C000E1D17 /* Audio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Audio.h; sourceTree = ""; }; + FA0B7B461A95902C000E1D17 /* Audio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = Audio.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; + FA0B7B471A95902C000E1D17 /* Audio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = Audio.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; FA0B7B481A95902C000E1D17 /* Pool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Pool.cpp; sourceTree = ""; }; FA0B7B491A95902C000E1D17 /* Pool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pool.h; sourceTree = ""; }; FA0B7B4A1A95902C000E1D17 /* Source.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Source.cpp; sourceTree = ""; }; @@ -1186,7 +1469,7 @@ FA0B7B6D1A95902C000E1D17 /* wrap_FileData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_FileData.h; sourceTree = ""; }; FA0B7B6E1A95902C000E1D17 /* wrap_Filesystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Filesystem.cpp; sourceTree = ""; }; FA0B7B6F1A95902C000E1D17 /* wrap_Filesystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Filesystem.h; sourceTree = ""; }; - FA0B7B711A95902C000E1D17 /* BMFontRasterizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BMFontRasterizer.cpp; sourceTree = ""; }; + FA0B7B711A95902C000E1D17 /* BMFontRasterizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = BMFontRasterizer.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; FA0B7B721A95902C000E1D17 /* BMFontRasterizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BMFontRasterizer.h; sourceTree = ""; }; FA0B7B731A95902C000E1D17 /* Font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Font.cpp; sourceTree = ""; }; FA0B7B741A95902C000E1D17 /* Font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Font.h; sourceTree = ""; }; @@ -1207,55 +1490,26 @@ FA0B7B841A95902C000E1D17 /* wrap_GlyphData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_GlyphData.h; sourceTree = ""; }; FA0B7B851A95902C000E1D17 /* wrap_Rasterizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Rasterizer.cpp; sourceTree = ""; }; FA0B7B861A95902C000E1D17 /* wrap_Rasterizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Rasterizer.h; sourceTree = ""; }; - FA0B7B881A95902C000E1D17 /* Color.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Color.h; sourceTree = ""; }; FA0B7B891A95902C000E1D17 /* Drawable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Drawable.h; sourceTree = ""; }; - FA0B7B8A1A95902C000E1D17 /* Graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Graphics.cpp; sourceTree = ""; }; + FA0B7B8A1A95902C000E1D17 /* Graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = Graphics.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; FA0B7B8B1A95902C000E1D17 /* Graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Graphics.h; sourceTree = ""; }; - FA0B7B8D1A95902C000E1D17 /* Canvas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Canvas.cpp; sourceTree = ""; }; + FA0B7B8D1A95902C000E1D17 /* Canvas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = Canvas.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; FA0B7B8E1A95902C000E1D17 /* Canvas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Canvas.h; sourceTree = ""; }; - FA0B7B8F1A95902C000E1D17 /* Font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Font.cpp; sourceTree = ""; }; - FA0B7B901A95902C000E1D17 /* Font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Font.h; sourceTree = ""; }; - FA0B7B911A95902C000E1D17 /* Graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Graphics.cpp; sourceTree = ""; }; + FA0B7B911A95902C000E1D17 /* Graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = Graphics.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; FA0B7B921A95902C000E1D17 /* Graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Graphics.h; sourceTree = ""; }; FA0B7B931A95902C000E1D17 /* Image.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Image.cpp; sourceTree = ""; }; FA0B7B941A95902C000E1D17 /* Image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = ""; }; - FA0B7B951A95902C000E1D17 /* Mesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Mesh.cpp; sourceTree = ""; }; - FA0B7B961A95902C000E1D17 /* Mesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Mesh.h; sourceTree = ""; }; FA0B7B971A95902C000E1D17 /* OpenGL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenGL.cpp; sourceTree = ""; }; FA0B7B981A95902C000E1D17 /* OpenGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenGL.h; sourceTree = ""; }; - FA0B7B991A95902C000E1D17 /* ParticleSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParticleSystem.cpp; sourceTree = ""; }; - FA0B7B9A1A95902C000E1D17 /* ParticleSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParticleSystem.h; sourceTree = ""; }; FA0B7B9B1A95902C000E1D17 /* Polyline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Polyline.cpp; sourceTree = ""; }; FA0B7B9C1A95902C000E1D17 /* Polyline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Polyline.h; sourceTree = ""; }; FA0B7B9D1A95902C000E1D17 /* Shader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Shader.cpp; sourceTree = ""; }; FA0B7B9E1A95902C000E1D17 /* Shader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Shader.h; sourceTree = ""; }; - FA0B7B9F1A95902C000E1D17 /* SpriteBatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpriteBatch.cpp; sourceTree = ""; }; - FA0B7BA01A95902C000E1D17 /* SpriteBatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpriteBatch.h; sourceTree = ""; }; - FA0B7BA11A95902C000E1D17 /* Text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Text.cpp; sourceTree = ""; }; - FA0B7BA21A95902C000E1D17 /* Text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Text.h; sourceTree = ""; }; - FA0B7BA41A95902C000E1D17 /* GLBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GLBuffer.cpp; sourceTree = ""; }; - FA0B7BA51A95902C000E1D17 /* GLBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLBuffer.h; sourceTree = ""; }; - FA0B7BA61A95902C000E1D17 /* wrap_Canvas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Canvas.cpp; sourceTree = ""; }; - FA0B7BA71A95902C000E1D17 /* wrap_Canvas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Canvas.h; sourceTree = ""; }; - FA0B7BA81A95902C000E1D17 /* wrap_Font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Font.cpp; sourceTree = ""; }; - FA0B7BA91A95902C000E1D17 /* wrap_Font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Font.h; sourceTree = ""; }; - FA0B7BAA1A95902C000E1D17 /* wrap_Graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Graphics.cpp; sourceTree = ""; }; - FA0B7BAB1A95902C000E1D17 /* wrap_Graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Graphics.h; sourceTree = ""; }; - FA0B7BAC1A95902C000E1D17 /* wrap_Image.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Image.cpp; sourceTree = ""; }; - FA0B7BAD1A95902C000E1D17 /* wrap_Image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Image.h; sourceTree = ""; }; - FA0B7BAE1A95902C000E1D17 /* wrap_Mesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Mesh.cpp; sourceTree = ""; }; - FA0B7BAF1A95902C000E1D17 /* wrap_Mesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Mesh.h; sourceTree = ""; }; - FA0B7BB01A95902C000E1D17 /* wrap_ParticleSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_ParticleSystem.cpp; sourceTree = ""; }; - FA0B7BB11A95902C000E1D17 /* wrap_ParticleSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_ParticleSystem.h; sourceTree = ""; }; - FA0B7BB41A95902C000E1D17 /* wrap_Shader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Shader.cpp; sourceTree = ""; }; - FA0B7BB51A95902C000E1D17 /* wrap_Shader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Shader.h; sourceTree = ""; }; - FA0B7BB61A95902C000E1D17 /* wrap_SpriteBatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_SpriteBatch.cpp; sourceTree = ""; }; - FA0B7BB71A95902C000E1D17 /* wrap_SpriteBatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_SpriteBatch.h; sourceTree = ""; }; - FA0B7BB81A95902C000E1D17 /* wrap_Text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Text.cpp; sourceTree = ""; }; - FA0B7BB91A95902C000E1D17 /* wrap_Text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Text.h; sourceTree = ""; }; + FA0B7BA41A95902C000E1D17 /* Buffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Buffer.cpp; sourceTree = ""; }; + FA0B7BA51A95902C000E1D17 /* Buffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Buffer.h; sourceTree = ""; }; FA0B7BBC1A95902C000E1D17 /* Quad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Quad.cpp; sourceTree = ""; }; FA0B7BBD1A95902C000E1D17 /* Quad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Quad.h; sourceTree = ""; }; - FA0B7BBE1A95902C000E1D17 /* Texture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Texture.cpp; sourceTree = ""; }; + FA0B7BBE1A95902C000E1D17 /* Texture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = Texture.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; FA0B7BBF1A95902C000E1D17 /* Texture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Texture.h; sourceTree = ""; }; FA0B7BC01A95902C000E1D17 /* Volatile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Volatile.cpp; sourceTree = ""; }; FA0B7BC11A95902C000E1D17 /* Volatile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Volatile.h; sourceTree = ""; }; @@ -1264,17 +1518,8 @@ FA0B7BC51A95902C000E1D17 /* Image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = ""; }; FA0B7BC61A95902C000E1D17 /* ImageData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageData.cpp; sourceTree = ""; }; FA0B7BC71A95902C000E1D17 /* ImageData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageData.h; sourceTree = ""; }; - FA0B7BC91A95902C000E1D17 /* CompressedImageData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CompressedImageData.cpp; sourceTree = ""; }; - FA0B7BCA1A95902C000E1D17 /* CompressedImageData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompressedImageData.h; sourceTree = ""; }; - FA0B7BCB1A95902C000E1D17 /* CompressedFormatHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompressedFormatHandler.h; sourceTree = ""; }; FA0B7BCC1A95902C000E1D17 /* ddsHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ddsHandler.cpp; sourceTree = ""; }; FA0B7BCD1A95902C000E1D17 /* ddsHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ddsHandler.h; sourceTree = ""; }; - FA0B7BCE1A95902C000E1D17 /* FormatHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FormatHandler.cpp; sourceTree = ""; }; - FA0B7BCF1A95902C000E1D17 /* FormatHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormatHandler.h; sourceTree = ""; }; - FA0B7BD01A95902C000E1D17 /* Image.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Image.cpp; sourceTree = ""; }; - FA0B7BD11A95902C000E1D17 /* Image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = ""; }; - FA0B7BD21A95902C000E1D17 /* ImageData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageData.cpp; sourceTree = ""; }; - FA0B7BD31A95902C000E1D17 /* ImageData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageData.h; sourceTree = ""; }; FA0B7BD81A95902C000E1D17 /* KTXHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KTXHandler.cpp; sourceTree = ""; }; FA0B7BD91A95902C000E1D17 /* KTXHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KTXHandler.h; sourceTree = ""; }; FA0B7BDA1A95902C000E1D17 /* PKMHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PKMHandler.cpp; sourceTree = ""; }; @@ -1310,8 +1555,8 @@ FA0B7BFC1A95902C000E1D17 /* wrap_Keyboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Keyboard.h; sourceTree = ""; }; FA0B7BFE1A95902C000E1D17 /* love.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = love.cpp; sourceTree = ""; }; FA0B7BFF1A95902C000E1D17 /* love.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = love.h; sourceTree = ""; }; - FA0B7C011A95902C000E1D17 /* BezierCurve.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BezierCurve.cpp; sourceTree = ""; }; - FA0B7C021A95902C000E1D17 /* BezierCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BezierCurve.h; sourceTree = ""; }; + FA0B7C011A95902C000E1D17 /* BezierCurve.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = BezierCurve.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; + FA0B7C021A95902C000E1D17 /* BezierCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = BezierCurve.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; FA0B7C031A95902C000E1D17 /* MathModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathModule.cpp; sourceTree = ""; }; FA0B7C041A95902C000E1D17 /* MathModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathModule.h; sourceTree = ""; }; FA0B7C051A95902C000E1D17 /* RandomGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RandomGenerator.cpp; sourceTree = ""; }; @@ -1431,7 +1676,6 @@ FA0B7C7E1A95902C000E1D17 /* CoreAudioDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CoreAudioDecoder.cpp; sourceTree = ""; }; FA0B7C7F1A95902C000E1D17 /* CoreAudioDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoreAudioDecoder.h; sourceTree = ""; }; FA0B7C801A95902C000E1D17 /* Decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Decoder.cpp; sourceTree = ""; }; - FA0B7C811A95902C000E1D17 /* Decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Decoder.h; sourceTree = ""; }; FA0B7C821A95902C000E1D17 /* FLACDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FLACDecoder.cpp; sourceTree = ""; }; FA0B7C831A95902C000E1D17 /* FLACDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLACDecoder.h; sourceTree = ""; }; FA0B7C841A95902C000E1D17 /* GmeDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GmeDecoder.cpp; sourceTree = ""; }; @@ -1481,8 +1725,6 @@ FA0B7CB41A95902C000E1D17 /* wrap_LuaThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_LuaThread.h; sourceTree = ""; }; FA0B7CB51A95902C000E1D17 /* wrap_ThreadModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_ThreadModule.cpp; sourceTree = ""; }; FA0B7CB61A95902C000E1D17 /* wrap_ThreadModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_ThreadModule.h; sourceTree = ""; }; - FA0B7CB91A95902C000E1D17 /* Timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Timer.cpp; sourceTree = ""; }; - FA0B7CBA1A95902C000E1D17 /* Timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Timer.h; sourceTree = ""; }; FA0B7CBB1A95902C000E1D17 /* Timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Timer.h; sourceTree = ""; }; FA0B7CBC1A95902C000E1D17 /* wrap_Timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Timer.cpp; sourceTree = ""; }; FA0B7CBD1A95902C000E1D17 /* wrap_Timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Timer.h; sourceTree = ""; }; @@ -1499,13 +1741,29 @@ FA0B7CCC1A95902C000E1D17 /* wrap_Window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Window.h; sourceTree = ""; }; FA0B7EF01A959D2C000E1D17 /* ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ios.h; sourceTree = ""; }; FA0B7EF11A959D2C000E1D17 /* ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ios.mm; sourceTree = ""; }; - FA19C4C21B4B0BD50059B0B3 /* wrap_Video.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Video.cpp; sourceTree = ""; }; - FA19C4C31B4B0BD50059B0B3 /* wrap_Video.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Video.h; sourceTree = ""; }; - FA19C4C41B4B0BD50059B0B3 /* wrap_Video.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = wrap_Video.lua; sourceTree = ""; }; + FA10DD7B1F9EC24E00E1FE3D /* Resource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Resource.h; sourceTree = ""; }; + FA1557BF1CE90A2C00AFF582 /* tinyexr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tinyexr.h; sourceTree = ""; }; + FA1557C11CE90BD200AFF582 /* EXRHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EXRHandler.cpp; sourceTree = ""; }; + FA1557C21CE90BD200AFF582 /* EXRHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EXRHandler.h; sourceTree = ""; }; + FA15DFAB1F9B8C850042AB22 /* StringMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringMap.cpp; sourceTree = ""; }; + FA1BA09B1E16CFCE00AA2803 /* Font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Font.cpp; sourceTree = ""; }; + FA1BA09C1E16CFCE00AA2803 /* Font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Font.h; sourceTree = ""; }; + FA1BA0A01E16D97500AA2803 /* wrap_Font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Font.cpp; sourceTree = ""; }; + FA1BA0A11E16D97500AA2803 /* wrap_Font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Font.h; sourceTree = ""; }; + FA1BA0A51E16F20600AA2803 /* Canvas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = Canvas.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; + FA1BA0A61E16F20600AA2803 /* Canvas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = Canvas.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; + FA1BA0AA1E16F9EE00AA2803 /* wrap_Canvas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = wrap_Canvas.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; + FA1BA0AB1E16F9EE00AA2803 /* wrap_Canvas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Canvas.h; sourceTree = ""; }; + FA1BA0AF1E16FD0800AA2803 /* Shader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Shader.cpp; sourceTree = ""; }; + FA1BA0B01E16FD0800AA2803 /* Shader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Shader.h; sourceTree = ""; }; + FA1BA0B51E17043400AA2803 /* wrap_Shader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Shader.cpp; sourceTree = ""; }; + FA1BA0B61E17043400AA2803 /* wrap_Shader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Shader.h; sourceTree = ""; }; + FA1E887C1DF363CD00E808AA /* Filter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Filter.cpp; sourceTree = ""; }; + FA1E887D1DF363CD00E808AA /* Filter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Filter.h; sourceTree = ""; }; + FA1E88811DF363DB00E808AA /* Filter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Filter.cpp; sourceTree = ""; }; + FA1E88821DF363DB00E808AA /* Filter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Filter.h; sourceTree = ""; }; FA27B38A1B498151008A9DCE /* Video.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Video.cpp; sourceTree = ""; }; FA27B38B1B498151008A9DCE /* Video.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Video.h; sourceTree = ""; }; - FA27B38C1B498151008A9DCE /* VideoStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VideoStream.cpp; sourceTree = ""; }; - FA27B38D1B498151008A9DCE /* VideoStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoStream.h; sourceTree = ""; }; FA27B3931B498151008A9DCE /* Video.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Video.h; sourceTree = ""; }; FA27B3941B498151008A9DCE /* VideoStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VideoStream.cpp; sourceTree = ""; }; FA27B3951B498151008A9DCE /* VideoStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoStream.h; sourceTree = ""; }; @@ -1513,27 +1771,49 @@ FA27B39C1B498151008A9DCE /* wrap_Video.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Video.h; sourceTree = ""; }; FA27B3B91B4985BF008A9DCE /* wrap_VideoStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_VideoStream.cpp; sourceTree = ""; }; FA27B3BA1B4985BF008A9DCE /* wrap_VideoStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_VideoStream.h; sourceTree = ""; }; - FA27B3C31B4985D8008A9DCE /* Video.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Video.cpp; sourceTree = ""; }; - FA27B3C41B4985D8008A9DCE /* Video.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Video.h; sourceTree = ""; }; - FA27B3C81B498623008A9DCE /* Theora.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Theora.framework; path = /Library/Frameworks/Theora.framework; sourceTree = ""; }; + FA27B3C81B498623008A9DCE /* theora.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = theora.framework; path = /Library/Frameworks/theora.framework; sourceTree = ""; }; FA283EDC1B27CFAA00C70067 /* nogame.lua */ = {isa = PBXFileReference; lastKnownFileType = text; path = nogame.lua; sourceTree = ""; }; FA283EDD1B27CFAA00C70067 /* nogame.lua.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = nogame.lua.h; sourceTree = ""; }; + FA28EBD31E352DB5003446F4 /* FenceSync.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FenceSync.cpp; sourceTree = ""; }; + FA28EBD41E352DB5003446F4 /* FenceSync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FenceSync.h; sourceTree = ""; }; + FA29C0041E12355B00268CD8 /* StreamBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StreamBuffer.cpp; sourceTree = ""; }; + FA2AF6711DAC76FF0032B62C /* vertex.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = vertex.h; sourceTree = ""; }; + FA2AF6721DAD62710032B62C /* StreamBuffer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StreamBuffer.h; sourceTree = ""; }; + FA2AF6731DAD64970032B62C /* vertex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vertex.cpp; sourceTree = ""; }; FA2E9BFE1C19E00C0004A1EE /* wrap_RandomGenerator.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = wrap_RandomGenerator.lua; sourceTree = ""; }; FA317EB918F28B6D00B0BCD7 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; - FA41A3C61C0A1F950084430C /* ASTCHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ASTCHandler.cpp; sourceTree = ""; }; - FA41A3C71C0A1F950084430C /* ASTCHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTCHandler.h; sourceTree = ""; }; + FA3C5E401F8C368C0003C579 /* ShaderStage.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ShaderStage.cpp; sourceTree = ""; }; + FA3C5E411F8C368C0003C579 /* ShaderStage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ShaderStage.h; sourceTree = ""; }; + FA3C5E451F8D80CA0003C579 /* ShaderStage.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ShaderStage.cpp; sourceTree = ""; }; + FA3C5E461F8D80CA0003C579 /* ShaderStage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ShaderStage.h; sourceTree = ""; }; + FA41A3C61C0A1F950084430C /* ASTCHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = ASTCHandler.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; + FA41A3C71C0A1F950084430C /* ASTCHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ASTCHandler.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; FA4B66C81ABBCF1900558F15 /* Timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Timer.cpp; sourceTree = ""; }; + FA4F2B771DE0125B00CA37D7 /* xxhash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xxhash.c; sourceTree = ""; }; + FA4F2B781DE0125B00CA37D7 /* xxhash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xxhash.h; sourceTree = ""; }; + FA4F2BA21DE1E36400CA37D7 /* RecordingDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RecordingDevice.cpp; sourceTree = ""; }; + FA4F2BA31DE1E36400CA37D7 /* RecordingDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecordingDevice.h; sourceTree = ""; }; + FA4F2BA41DE1E36400CA37D7 /* wrap_RecordingDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_RecordingDevice.cpp; sourceTree = ""; }; + FA4F2BA51DE1E36400CA37D7 /* wrap_RecordingDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_RecordingDevice.h; sourceTree = ""; }; + FA4F2BAA1DE1E37000CA37D7 /* RecordingDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RecordingDevice.cpp; sourceTree = ""; }; + FA4F2BAB1DE1E37000CA37D7 /* RecordingDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecordingDevice.h; sourceTree = ""; }; + FA4F2BAE1DE1E37B00CA37D7 /* RecordingDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RecordingDevice.cpp; sourceTree = ""; }; + FA4F2BAF1DE1E37B00CA37D7 /* RecordingDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecordingDevice.h; sourceTree = ""; }; + FA4F2BDF1DE6650600CA37D7 /* Transform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Transform.cpp; sourceTree = ""; }; + FA4F2BE01DE6650600CA37D7 /* Transform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Transform.h; sourceTree = ""; }; + FA4F2BE11DE6650600CA37D7 /* wrap_Transform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Transform.cpp; sourceTree = ""; }; + FA4F2BE21DE6650600CA37D7 /* wrap_Transform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Transform.h; sourceTree = ""; }; + FA56AA361FAFF02000A43D5F /* memory.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = memory.cpp; sourceTree = ""; }; + FA56AA371FAFF02000A43D5F /* memory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = memory.h; sourceTree = ""; }; FA56D9BA1C2089EE00D8D3C7 /* libmodplug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libmodplug.a; sourceTree = ""; }; - FA577A6716C719D900860150 /* FreeType.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FreeType.framework; path = /Library/Frameworks/FreeType.framework; sourceTree = ""; }; FA577A6D16C719EA00860150 /* Lua.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Lua.framework; path = /Library/Frameworks/Lua.framework; sourceTree = ""; }; FA577A6F16C719F000860150 /* mpg123.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mpg123.framework; path = /Library/Frameworks/mpg123.framework; sourceTree = ""; }; - FA577A7116C719F400860150 /* Ogg.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Ogg.framework; path = /Library/Frameworks/Ogg.framework; sourceTree = ""; }; - FA577A7316C719F900860150 /* physfs.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = physfs.framework; path = /Library/Frameworks/physfs.framework; sourceTree = ""; }; - FA577A7716C71A0800860150 /* Vorbis.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Vorbis.framework; path = /Library/Frameworks/Vorbis.framework; sourceTree = ""; }; + FA577A7116C719F400860150 /* ogg.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ogg.framework; path = /Library/Frameworks/ogg.framework; sourceTree = ""; }; + FA577A7716C71A0800860150 /* vorbis.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = vorbis.framework; path = /Library/Frameworks/vorbis.framework; sourceTree = ""; }; FA577A7916C71A1700860150 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; FA577A7C16C71A2600860150 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = ""; }; FA577A8216C71A5300860150 /* libmodplug.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = libmodplug.framework; path = /Library/Frameworks/libmodplug.framework; sourceTree = ""; }; - FA577A8C16C71D3600860150 /* auto.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = auto.lua; sourceTree = ""; }; + FA577A8C16C71D3600860150 /* auto.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; lineEnding = 0; path = auto.lua; sourceTree = ""; xcLanguageSpecificationIdentifier = ""; }; FA577A8D16C71D3600860150 /* boot.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = boot.lua; sourceTree = ""; }; FA577AAF16C7507900860150 /* love.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = love.framework; sourceTree = BUILT_PRODUCTS_DIR; }; FA57FB961AE1993600F2AD6D /* noise1234.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = noise1234.cpp; sourceTree = ""; }; @@ -1541,7 +1821,6 @@ FA59A2D61C0649BB00328DBA /* libtheora.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libtheora.a; sourceTree = ""; }; FA5D24A51A96D2EC00C6FC8F /* libFreetype2.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libFreetype2.a; sourceTree = ""; }; FA5D24AB1A96D2EC00C6FC8F /* libogg.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libogg.a; sourceTree = ""; }; - FA5D24AD1A96D2EC00C6FC8F /* libphysfs.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libphysfs.a; sourceTree = ""; }; FA5D24AF1A96D2EC00C6FC8F /* libvorbis.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libvorbis.a; sourceTree = ""; }; FA5D24CD1A96E63D00C6FC8F /* libSDL2.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libSDL2.a; sourceTree = ""; }; FA620A2E1AA2F8DB005DB4C2 /* wrap_Quad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Quad.cpp; sourceTree = ""; }; @@ -1549,32 +1828,206 @@ FA620A301AA2F8DB005DB4C2 /* wrap_Texture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Texture.cpp; sourceTree = ""; }; FA620A311AA2F8DB005DB4C2 /* wrap_Texture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Texture.h; sourceTree = ""; }; FA620A391AA305F6005DB4C2 /* types.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = types.cpp; sourceTree = ""; }; - FA6AE6041B3335EC00583D5C /* wrap_Graphics.lua */ = {isa = PBXFileReference; lastKnownFileType = text; path = wrap_Graphics.lua; sourceTree = ""; }; + FA6A2B641F5F7B6B0074C308 /* wrap_Data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Data.h; sourceTree = ""; }; + FA6A2B651F5F7B6B0074C308 /* wrap_Data.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Data.cpp; sourceTree = ""; }; + FA6A2B681F5F7F560074C308 /* DataView.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DataView.cpp; sourceTree = ""; }; + FA6A2B691F5F7F560074C308 /* DataView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DataView.h; sourceTree = ""; }; + FA6A2B6D1F5F845F0074C308 /* wrap_DataView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_DataView.h; sourceTree = ""; }; + FA6A2B6E1F5F845F0074C308 /* wrap_DataView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_DataView.cpp; sourceTree = ""; }; + FA6A2B721F60B6710074C308 /* ByteData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ByteData.cpp; sourceTree = ""; }; + FA6A2B731F60B6710074C308 /* ByteData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ByteData.h; sourceTree = ""; }; + FA6A2B771F60B8250074C308 /* wrap_ByteData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_ByteData.h; sourceTree = ""; }; + FA6A2B781F60B8250074C308 /* wrap_ByteData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_ByteData.cpp; sourceTree = ""; }; + FA6BDE5B1F31725300786805 /* Color.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Color.h; sourceTree = ""; }; FA7550A71AEBE276003E311E /* libluajit.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libluajit.a; sourceTree = ""; }; + FA7634481E28722A0066EF9E /* StreamBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StreamBuffer.cpp; sourceTree = ""; }; + FA7634491E28722A0066EF9E /* StreamBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StreamBuffer.h; sourceTree = ""; }; FA7DA04C1C16874A0056B200 /* wrap_Math.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = wrap_Math.lua; sourceTree = ""; }; FA8951A01AA2EDF300EC385A /* wrap_Event.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Event.cpp; sourceTree = ""; }; FA8951A11AA2EDF300EC385A /* wrap_Event.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Event.h; sourceTree = ""; }; + FA91591C1CF1ED7500A7053F /* halffloat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = halffloat.cpp; sourceTree = ""; }; + FA91591D1CF1ED7500A7053F /* halffloat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = halffloat.h; sourceTree = ""; }; + FA91DA891F377C3900C80E33 /* deprecation.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = deprecation.cpp; sourceTree = ""; }; + FA91DA8A1F377C3900C80E33 /* deprecation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = deprecation.h; sourceTree = ""; }; + FA93C4501F315B960087CCD4 /* FormatHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormatHandler.h; sourceTree = ""; }; + FA93C4511F315B960087CCD4 /* FormatHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FormatHandler.cpp; sourceTree = ""; }; FA9B4A0716E1578300074F42 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = /Library/Frameworks/SDL2.framework; sourceTree = ""; }; - FAA3A9AC1B7D465A00CED060 /* android.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = android.cpp; sourceTree = ""; }; - FAA3A9AD1B7D465A00CED060 /* android.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = android.h; sourceTree = ""; }; + FA9D53AA1F5307E900125C6B /* Deprecations.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Deprecations.cpp; sourceTree = ""; }; + FA9D53AB1F5307E900125C6B /* Deprecations.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Deprecations.h; sourceTree = ""; }; + FA9D8DCF1DEB56C3002CD881 /* pixelformat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pixelformat.cpp; sourceTree = ""; }; + FA9D8DD01DEB56C3002CD881 /* pixelformat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pixelformat.h; sourceTree = ""; }; + FA9D8DD41DEF8411002CD881 /* Data.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Data.cpp; sourceTree = ""; }; + FA9D8DD51DEF8411002CD881 /* Stream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Stream.cpp; sourceTree = ""; }; + FA9D8DD61DEF8411002CD881 /* Stream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Stream.h; sourceTree = ""; }; + FA9D8DDC1DEF842A002CD881 /* Drawable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Drawable.cpp; sourceTree = ""; }; + FA9D8DDF1DEF843D002CD881 /* Image.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Image.cpp; sourceTree = ""; }; + FAA3A9AC1B7D465A00CED060 /* android.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = android.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; + FAA3A9AD1B7D465A00CED060 /* android.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = android.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; + FAA54AC61F91660400A8FA7B /* OggDemuxer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OggDemuxer.h; sourceTree = ""; }; + FAA54AC71F91660400A8FA7B /* TheoraVideoStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TheoraVideoStream.h; sourceTree = ""; }; + FAA54AC81F91660400A8FA7B /* TheoraVideoStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TheoraVideoStream.cpp; sourceTree = ""; }; + FAA54AC91F91660400A8FA7B /* OggDemuxer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OggDemuxer.cpp; sourceTree = ""; }; FAA627CD18E7E1560080752D /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; }; + FAAA3FD31F64B3AD00F89E99 /* lprefix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lprefix.h; sourceTree = ""; }; + FAAA3FD41F64B3AD00F89E99 /* lstrlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lstrlib.c; sourceTree = ""; }; + FAAA3FD51F64B3AD00F89E99 /* lstrlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lstrlib.h; sourceTree = ""; }; + FAAA3FD61F64B3AD00F89E99 /* lutf8lib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lutf8lib.c; sourceTree = ""; }; + FAAA3FD71F64B3AD00F89E99 /* lutf8lib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lutf8lib.h; sourceTree = ""; }; FAAFF04316CB11C700CCDE45 /* OpenAL-Soft.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "OpenAL-Soft.framework"; path = "/Library/Frameworks/OpenAL-Soft.framework"; sourceTree = ""; }; - FAB17BDE1ABFAA2000F9BA27 /* Compressor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Compressor.cpp; sourceTree = ""; }; - FAB17BDF1ABFAA2000F9BA27 /* Compressor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Compressor.h; sourceTree = ""; }; FAB17BE41ABFAA9000F9BA27 /* lz4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lz4.c; sourceTree = ""; }; FAB17BE51ABFAA9000F9BA27 /* lz4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lz4.h; sourceTree = ""; }; - FAB17BE91ABFAF1800F9BA27 /* CompressedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CompressedData.cpp; sourceTree = ""; }; - FAB17BEA1ABFAF1800F9BA27 /* CompressedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompressedData.h; sourceTree = ""; }; - FAB17BEE1ABFB37500F9BA27 /* wrap_CompressedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_CompressedData.cpp; sourceTree = ""; }; - FAB17BEF1ABFB37500F9BA27 /* wrap_CompressedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_CompressedData.h; sourceTree = ""; }; FAB17BF31ABFC4B100F9BA27 /* lz4hc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lz4hc.c; sourceTree = ""; }; FAB17BF41ABFC4B100F9BA27 /* lz4hc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lz4hc.h; sourceTree = ""; }; FAB2D5A81AABDD8A008224A4 /* TrueTypeRasterizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TrueTypeRasterizer.cpp; sourceTree = ""; }; FAB2D5A91AABDD8A008224A4 /* TrueTypeRasterizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrueTypeRasterizer.h; sourceTree = ""; }; FAC734C11B2E021A00AB460A /* wrap_SoundData.lua */ = {isa = PBXFileReference; lastKnownFileType = text; path = wrap_SoundData.lua; sourceTree = ""; }; FAC734C21B2E628700AB460A /* wrap_ImageData.lua */ = {isa = PBXFileReference; lastKnownFileType = text; path = wrap_ImageData.lua; sourceTree = ""; }; + FAC756F31E4F99B400B91289 /* Effect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Effect.cpp; sourceTree = ""; }; + FAC756F41E4F99B400B91289 /* Effect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Effect.h; sourceTree = ""; }; + FAC756F81E4F99D200B91289 /* Effect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Effect.cpp; sourceTree = ""; }; + FAC756F91E4F99D200B91289 /* Effect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Effect.h; sourceTree = ""; }; + FAC7CD5A1FE35E95006A60C7 /* physfs_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = physfs_internal.h; sourceTree = ""; }; + FAC7CD5B1FE35E95006A60C7 /* physfs_platform_qnx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = physfs_platform_qnx.c; sourceTree = ""; }; + FAC7CD5C1FE35E95006A60C7 /* physfs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = physfs.c; sourceTree = ""; }; + FAC7CD5D1FE35E95006A60C7 /* physfs_archiver_7z.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = physfs_archiver_7z.c; sourceTree = ""; }; + FAC7CD5E1FE35E95006A60C7 /* physfs_platform_unix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = physfs_platform_unix.c; sourceTree = ""; }; + FAC7CD5F1FE35E95006A60C7 /* physfs_archiver_slb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = physfs_archiver_slb.c; sourceTree = ""; }; + FAC7CD601FE35E95006A60C7 /* physfs_platform_winrt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = physfs_platform_winrt.cpp; sourceTree = ""; }; + FAC7CD611FE35E95006A60C7 /* physfs_archiver_mvl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = physfs_archiver_mvl.c; sourceTree = ""; }; + FAC7CD621FE35E95006A60C7 /* physfs_archiver_wad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = physfs_archiver_wad.c; sourceTree = ""; }; + FAC7CD631FE35E95006A60C7 /* physfs_casefolding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = physfs_casefolding.h; sourceTree = ""; }; + FAC7CD641FE35E95006A60C7 /* physfs_platform_os2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = physfs_platform_os2.c; sourceTree = ""; }; + FAC7CD651FE35E95006A60C7 /* physfs_platform_haiku.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = physfs_platform_haiku.cpp; sourceTree = ""; }; + FAC7CD661FE35E95006A60C7 /* physfs_platform_windows.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = physfs_platform_windows.c; sourceTree = ""; }; + FAC7CD671FE35E95006A60C7 /* physfs_archiver_unpacked.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = physfs_archiver_unpacked.c; sourceTree = ""; }; + FAC7CD681FE35E95006A60C7 /* physfs_unicode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = physfs_unicode.c; sourceTree = ""; }; + FAC7CD691FE35E95006A60C7 /* physfs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = physfs.h; sourceTree = ""; }; + FAC7CD6A1FE35E95006A60C7 /* physfs_archiver_vdf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = physfs_archiver_vdf.c; sourceTree = ""; }; + FAC7CD6B1FE35E95006A60C7 /* physfs_platform_apple.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = physfs_platform_apple.m; sourceTree = ""; }; + FAC7CD6C1FE35E95006A60C7 /* physfs_archiver_dir.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = physfs_archiver_dir.c; sourceTree = ""; }; + FAC7CD6D1FE35E95006A60C7 /* physfs_byteorder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = physfs_byteorder.c; sourceTree = ""; }; + FAC7CD6E1FE35E95006A60C7 /* physfs_archiver_iso9660.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = physfs_archiver_iso9660.c; sourceTree = ""; }; + FAC7CD6F1FE35E95006A60C7 /* physfs_archiver_qpak.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = physfs_archiver_qpak.c; sourceTree = ""; }; + FAC7CD701FE35E95006A60C7 /* physfs_platforms.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = physfs_platforms.h; sourceTree = ""; }; + FAC7CD711FE35E95006A60C7 /* physfs_lzmasdk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = physfs_lzmasdk.h; sourceTree = ""; }; + FAC7CD721FE35E95006A60C7 /* physfs_platform_posix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = physfs_platform_posix.c; sourceTree = ""; }; + FAC7CD731FE35E95006A60C7 /* physfs_miniz.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = physfs_miniz.h; sourceTree = ""; }; + FAC7CD741FE35E95006A60C7 /* physfs_archiver_grp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = physfs_archiver_grp.c; sourceTree = ""; }; + FAC7CD751FE35E95006A60C7 /* physfs_archiver_hog.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = physfs_archiver_hog.c; sourceTree = ""; }; + FAC7CD761FE35E95006A60C7 /* physfs_archiver_zip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = physfs_archiver_zip.c; sourceTree = ""; }; + FAC7CD951FE755B3006A60C7 /* lz4opt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lz4opt.h; sourceTree = ""; }; + FACA02E01F5E396B0084B28F /* CompressedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CompressedData.cpp; sourceTree = ""; }; + FACA02E11F5E396B0084B28F /* CompressedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompressedData.h; sourceTree = ""; }; + FACA02E21F5E396B0084B28F /* Compressor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Compressor.cpp; sourceTree = ""; }; + FACA02E31F5E396B0084B28F /* Compressor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Compressor.h; sourceTree = ""; }; + FACA02E41F5E396B0084B28F /* DataModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DataModule.cpp; sourceTree = ""; }; + FACA02E51F5E396B0084B28F /* DataModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataModule.h; sourceTree = ""; }; + FACA02E61F5E396B0084B28F /* HashFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HashFunction.cpp; sourceTree = ""; }; + FACA02E71F5E396B0084B28F /* HashFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HashFunction.h; sourceTree = ""; }; + FACA02E81F5E396B0084B28F /* wrap_CompressedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_CompressedData.cpp; sourceTree = ""; }; + FACA02E91F5E396B0084B28F /* wrap_CompressedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_CompressedData.h; sourceTree = ""; }; + FACA02EA1F5E396B0084B28F /* wrap_DataModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_DataModule.cpp; sourceTree = ""; }; + FACA02EB1F5E396B0084B28F /* wrap_DataModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_DataModule.h; sourceTree = ""; }; + FAD19A151DFF8CA200D5398A /* ImageDataBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageDataBase.cpp; sourceTree = ""; }; + FAD19A161DFF8CA200D5398A /* ImageDataBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageDataBase.h; sourceTree = ""; }; + FAD43ECB1FF312D800831BB8 /* freetype.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = freetype.framework; path = /Library/Frameworks/freetype.framework; sourceTree = ""; }; + FADF53F61E3C7ACD00012CC0 /* Buffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Buffer.cpp; sourceTree = ""; }; + FADF53F71E3C7ACD00012CC0 /* Buffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Buffer.h; sourceTree = ""; }; + FADF53FB1E3D74F200012CC0 /* Text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Text.cpp; sourceTree = ""; }; + FADF53FC1E3D74F200012CC0 /* Text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Text.h; sourceTree = ""; }; + FADF54001E3D77B500012CC0 /* wrap_Text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Text.cpp; sourceTree = ""; }; + FADF54011E3D77B500012CC0 /* wrap_Text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Text.h; sourceTree = ""; }; + FADF54051E3D78F700012CC0 /* Video.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Video.cpp; sourceTree = ""; }; + FADF54061E3D78F700012CC0 /* Video.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Video.h; sourceTree = ""; }; + FADF540A1E3D7CDD00012CC0 /* wrap_Video.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Video.cpp; sourceTree = ""; }; + FADF540B1E3D7CDD00012CC0 /* wrap_Video.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Video.h; sourceTree = ""; }; + FADF540C1E3D7CDD00012CC0 /* wrap_Video.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = wrap_Video.lua; sourceTree = ""; }; + FADF54141E3DA08E00012CC0 /* Image.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Image.cpp; sourceTree = ""; }; + FADF54151E3DA08E00012CC0 /* Image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = ""; }; + FADF54191E3DA46C00012CC0 /* wrap_Image.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Image.cpp; sourceTree = ""; }; + FADF541A1E3DA46C00012CC0 /* wrap_Image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Image.h; sourceTree = ""; }; + FADF541E1E3DA52C00012CC0 /* wrap_ParticleSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_ParticleSystem.cpp; sourceTree = ""; }; + FADF541F1E3DA52C00012CC0 /* wrap_ParticleSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_ParticleSystem.h; sourceTree = ""; }; + FADF54231E3DA5BA00012CC0 /* Mesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Mesh.cpp; sourceTree = ""; }; + FADF54241E3DA5BA00012CC0 /* Mesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Mesh.h; sourceTree = ""; }; + FADF54281E3DAADA00012CC0 /* wrap_Mesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Mesh.cpp; sourceTree = ""; }; + FADF54291E3DAADA00012CC0 /* wrap_Mesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Mesh.h; sourceTree = ""; }; + FADF542D1E3DABF600012CC0 /* SpriteBatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpriteBatch.cpp; sourceTree = ""; }; + FADF542E1E3DABF600012CC0 /* SpriteBatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpriteBatch.h; sourceTree = ""; }; + FADF54321E3DAE6E00012CC0 /* wrap_SpriteBatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_SpriteBatch.cpp; sourceTree = ""; }; + FADF54331E3DAE6E00012CC0 /* wrap_SpriteBatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_SpriteBatch.h; sourceTree = ""; }; + FADF54371E3DAFBA00012CC0 /* wrap_Graphics.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = wrap_Graphics.lua; sourceTree = ""; }; + FADF54391E3DAFF700012CC0 /* wrap_Graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Graphics.cpp; sourceTree = ""; }; + FADF543A1E3DAFF700012CC0 /* wrap_Graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Graphics.h; sourceTree = ""; }; FAE272501C05A15B00A67640 /* ParticleSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParticleSystem.cpp; sourceTree = ""; }; FAE272511C05A15B00A67640 /* ParticleSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParticleSystem.h; sourceTree = ""; }; + FAECA1B01F3164700095D008 /* CompressedSlice.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CompressedSlice.cpp; sourceTree = ""; }; + FAECA1B11F3164700095D008 /* CompressedSlice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CompressedSlice.h; sourceTree = ""; }; + FAF13FC21E20934C00F898D2 /* CodeGen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeGen.cpp; sourceTree = ""; }; + FAF13FC31E20934C00F898D2 /* Link.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Link.cpp; sourceTree = ""; }; + FAF13FC51E20934C00F898D2 /* arrays.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = arrays.h; sourceTree = ""; }; + FAF13FC61E20934C00F898D2 /* BaseTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BaseTypes.h; sourceTree = ""; }; + FAF13FC71E20934C00F898D2 /* Common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Common.h; sourceTree = ""; }; + FAF13FC81E20934C00F898D2 /* ConstantUnion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstantUnion.h; sourceTree = ""; }; + FAF13FC91E20934C00F898D2 /* InfoSink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InfoSink.h; sourceTree = ""; }; + FAF13FCA1E20934C00F898D2 /* InitializeGlobals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InitializeGlobals.h; sourceTree = ""; }; + FAF13FCB1E20934C00F898D2 /* intermediate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = intermediate.h; sourceTree = ""; }; + FAF13FCC1E20934C00F898D2 /* PoolAlloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PoolAlloc.h; sourceTree = ""; }; + FAF13FCD1E20934C00F898D2 /* ResourceLimits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResourceLimits.h; sourceTree = ""; }; + FAF13FCE1E20934C00F898D2 /* revision.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = revision.h; sourceTree = ""; }; + FAF13FD01E20934C00F898D2 /* ShHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShHandle.h; sourceTree = ""; }; + FAF13FD11E20934C00F898D2 /* Types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Types.h; sourceTree = ""; }; + FAF13FD31E20934C00F898D2 /* Constant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Constant.cpp; sourceTree = ""; }; + FAF13FD41E20934C00F898D2 /* gl_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gl_types.h; sourceTree = ""; }; + FAF13FD61E20934C00F898D2 /* glslang_tab.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = glslang_tab.cpp; sourceTree = ""; }; + FAF13FD71E20934C00F898D2 /* glslang_tab.cpp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = glslang_tab.cpp.h; sourceTree = ""; }; + FAF13FD81E20934C00F898D2 /* InfoSink.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InfoSink.cpp; sourceTree = ""; }; + FAF13FD91E20934C00F898D2 /* Initialize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Initialize.cpp; sourceTree = ""; }; + FAF13FDA1E20934C00F898D2 /* Initialize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Initialize.h; sourceTree = ""; }; + FAF13FDB1E20934C00F898D2 /* Intermediate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Intermediate.cpp; sourceTree = ""; }; + FAF13FDC1E20934C00F898D2 /* intermOut.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = intermOut.cpp; sourceTree = ""; }; + FAF13FDD1E20934C00F898D2 /* IntermTraverse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntermTraverse.cpp; sourceTree = ""; }; + FAF13FDE1E20934C00F898D2 /* iomapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = iomapper.cpp; sourceTree = ""; }; + FAF13FDF1E20934C00F898D2 /* iomapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iomapper.h; sourceTree = ""; }; + FAF13FE01E20934C00F898D2 /* limits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = limits.cpp; sourceTree = ""; }; + FAF13FE11E20934C00F898D2 /* linkValidate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = linkValidate.cpp; sourceTree = ""; }; + FAF13FE21E20934C00F898D2 /* LiveTraverser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiveTraverser.h; sourceTree = ""; }; + FAF13FE31E20934C00F898D2 /* localintermediate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = localintermediate.h; sourceTree = ""; }; + FAF13FE41E20934C00F898D2 /* parseConst.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parseConst.cpp; sourceTree = ""; }; + FAF13FE51E20934C00F898D2 /* ParseContextBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParseContextBase.cpp; sourceTree = ""; }; + FAF13FE61E20934C00F898D2 /* ParseHelper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParseHelper.cpp; sourceTree = ""; }; + FAF13FE71E20934C00F898D2 /* ParseHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParseHelper.h; sourceTree = ""; }; + FAF13FE81E20934C00F898D2 /* parseVersions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = parseVersions.h; sourceTree = ""; }; + FAF13FE91E20934C00F898D2 /* PoolAlloc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PoolAlloc.cpp; sourceTree = ""; }; + FAF13FEB1E20934C00F898D2 /* Pp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Pp.cpp; sourceTree = ""; }; + FAF13FEC1E20934C00F898D2 /* PpAtom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PpAtom.cpp; sourceTree = ""; }; + FAF13FED1E20934C00F898D2 /* PpContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PpContext.cpp; sourceTree = ""; }; + FAF13FEE1E20934C00F898D2 /* PpContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PpContext.h; sourceTree = ""; }; + FAF13FF01E20934C00F898D2 /* PpScanner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PpScanner.cpp; sourceTree = ""; }; + FAF13FF21E20934C00F898D2 /* PpTokens.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PpTokens.cpp; sourceTree = ""; }; + FAF13FF31E20934C00F898D2 /* PpTokens.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PpTokens.h; sourceTree = ""; }; + FAF13FF41E20934C00F898D2 /* propagateNoContraction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = propagateNoContraction.cpp; sourceTree = ""; }; + FAF13FF51E20934C00F898D2 /* propagateNoContraction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = propagateNoContraction.h; sourceTree = ""; }; + FAF13FF61E20934C00F898D2 /* reflection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = reflection.cpp; sourceTree = ""; }; + FAF13FF71E20934C00F898D2 /* reflection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = reflection.h; sourceTree = ""; }; + FAF13FF81E20934C00F898D2 /* RemoveTree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RemoveTree.cpp; sourceTree = ""; }; + FAF13FF91E20934C00F898D2 /* RemoveTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoveTree.h; sourceTree = ""; }; + FAF13FFA1E20934C00F898D2 /* Scan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Scan.cpp; sourceTree = ""; }; + FAF13FFB1E20934C00F898D2 /* Scan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Scan.h; sourceTree = ""; }; + FAF13FFC1E20934C00F898D2 /* ScanContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScanContext.h; sourceTree = ""; }; + FAF13FFD1E20934C00F898D2 /* ShaderLang.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShaderLang.cpp; sourceTree = ""; }; + FAF13FFE1E20934C00F898D2 /* SymbolTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SymbolTable.cpp; sourceTree = ""; }; + FAF13FFF1E20934C00F898D2 /* SymbolTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolTable.h; sourceTree = ""; }; + FAF140001E20934C00F898D2 /* Versions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Versions.cpp; sourceTree = ""; }; + FAF140011E20934C00F898D2 /* Versions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Versions.h; sourceTree = ""; }; + FAF140031E20934C00F898D2 /* osinclude.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = osinclude.h; sourceTree = ""; }; + FAF140211E20934C00F898D2 /* ossource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossource.cpp; sourceTree = ""; }; + FAF140291E20934C00F898D2 /* ShaderLang.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShaderLang.h; sourceTree = ""; }; + FAF1403B1E20934C00F898D2 /* InitializeDll.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InitializeDll.cpp; sourceTree = ""; }; + FAF1403C1E20934C00F898D2 /* InitializeDll.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InitializeDll.h; sourceTree = ""; }; + FAF1889C1E9DA834008C1479 /* Optional.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Optional.h; sourceTree = ""; }; + FAF1889D1E9DBBC8008C1479 /* depthstencil.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = depthstencil.h; sourceTree = ""; }; + FAF1889E1E9DBC4B008C1479 /* depthstencil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = depthstencil.cpp; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -1587,7 +2040,6 @@ FA59A2D81C0649C200328DBA /* libtheora.a in Frameworks */, FA56D9BC1C208A0200D8D3C7 /* libmodplug.a in Frameworks */, FA5D24B01A96D2EC00C6FC8F /* libFreetype2.a in Frameworks */, - FA5D24B41A96D2EC00C6FC8F /* libphysfs.a in Frameworks */, FA7550A81AEBE276003E311E /* libluajit.a in Frameworks */, FA5D24CF1A96E68300C6FC8F /* libSDL2.a in Frameworks */, ); @@ -1597,19 +2049,18 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - FA27B3C91B498623008A9DCE /* Theora.framework in Frameworks */, + FA27B3C91B498623008A9DCE /* theora.framework in Frameworks */, FA317EBA18F28B6D00B0BCD7 /* libz.dylib in Frameworks */, FAA627CE18E7E1560080752D /* CoreServices.framework in Frameworks */, FA9B4A0816E1578300074F42 /* SDL2.framework in Frameworks */, FAAFF04416CB11C700CCDE45 /* OpenAL-Soft.framework in Frameworks */, + FAD43ECC1FF312D800831BB8 /* freetype.framework in Frameworks */, FA577AB016C7507900860150 /* Cocoa.framework in Frameworks */, - FA577AC216C7512D00860150 /* FreeType.framework in Frameworks */, FA577AC516C7513400860150 /* libmodplug.framework in Frameworks */, FA577AC716C7513A00860150 /* mpg123.framework in Frameworks */, - FA577AC816C7513C00860150 /* Ogg.framework in Frameworks */, + FA577AC816C7513C00860150 /* ogg.framework in Frameworks */, FA577ACA16C7514100860150 /* OpenGL.framework in Frameworks */, - FA577ACB16C7514400860150 /* physfs.framework in Frameworks */, - FA577ACD16C7514C00860150 /* Vorbis.framework in Frameworks */, + FA577ACD16C7514C00860150 /* vorbis.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1669,31 +2120,45 @@ FAA3A9AD1B7D465A00CED060 /* android.h */, FA0B78F71A958E3B000E1D17 /* b64.cpp */, FA0B78F81A958E3B000E1D17 /* b64.h */, + FA6BDE5B1F31725300786805 /* Color.h */, FA0B78F91A958E3B000E1D17 /* config.h */, + FA9D8DD41DEF8411002CD881 /* Data.cpp */, FA0B78FA1A958E3B000E1D17 /* Data.h */, FA0B78FB1A958E3B000E1D17 /* delay.cpp */, FA0B78FC1A958E3B000E1D17 /* delay.h */, + FA91DA891F377C3900C80E33 /* deprecation.cpp */, + FA91DA8A1F377C3900C80E33 /* deprecation.h */, FA0B78FD1A958E3B000E1D17 /* EnumMap.h */, FA0B78FE1A958E3B000E1D17 /* Exception.cpp */, FA0B78FF1A958E3B000E1D17 /* Exception.h */, + FA91591C1CF1ED7500A7053F /* halffloat.cpp */, + FA91591D1CF1ED7500A7053F /* halffloat.h */, FA0B79001A958E3B000E1D17 /* int.h */, FA0B7EF01A959D2C000E1D17 /* ios.h */, FA0B7EF11A959D2C000E1D17 /* ios.mm */, + FA0B790A1A958E3B000E1D17 /* macosx.h */, + FA0B790B1A958E3B000E1D17 /* macosx.mm */, FA0B79011A958E3B000E1D17 /* math.h */, FA0B79021A958E3B000E1D17 /* Matrix.cpp */, FA0B79031A958E3B000E1D17 /* Matrix.h */, FA0B79041A958E3B000E1D17 /* Memoizer.cpp */, FA0B79051A958E3B000E1D17 /* Memoizer.h */, + FA56AA361FAFF02000A43D5F /* memory.cpp */, + FA56AA371FAFF02000A43D5F /* memory.h */, FA0B79061A958E3B000E1D17 /* Module.cpp */, FA0B79071A958E3B000E1D17 /* Module.h */, FA0B79081A958E3B000E1D17 /* Object.cpp */, FA0B79091A958E3B000E1D17 /* Object.h */, - FA0B790A1A958E3B000E1D17 /* macosx.h */, - FA0B790B1A958E3B000E1D17 /* macosx.mm */, + FAF1889C1E9DA834008C1479 /* Optional.h */, + FA9D8DCF1DEB56C3002CD881 /* pixelformat.cpp */, + FA9D8DD01DEB56C3002CD881 /* pixelformat.h */, FA0B790C1A958E3B000E1D17 /* Reference.cpp */, FA0B790D1A958E3B000E1D17 /* Reference.h */, FA0B790E1A958E3B000E1D17 /* runtime.cpp */, FA0B790F1A958E3B000E1D17 /* runtime.h */, + FA9D8DD51DEF8411002CD881 /* Stream.cpp */, + FA9D8DD61DEF8411002CD881 /* Stream.h */, + FA15DFAB1F9B8C850042AB22 /* StringMap.cpp */, FA0B79101A958E3B000E1D17 /* StringMap.h */, FA620A391AA305F6005DB4C2 /* types.cpp */, FA0B79111A958E3B000E1D17 /* types.h */, @@ -1704,8 +2169,6 @@ FA0B79161A958E3B000E1D17 /* Vector.cpp */, FA0B79171A958E3B000E1D17 /* Vector.h */, FA0B79181A958E3B000E1D17 /* version.h */, - FA0B79191A958E3B000E1D17 /* wrap_Data.cpp */, - FA0B791A1A958E3B000E1D17 /* wrap_Data.h */, ); name = common; path = ../../src/common; @@ -1718,14 +2181,18 @@ FA0B79B41A958EA3000E1D17 /* ddsparse */, FA0B79B81A958EA3000E1D17 /* enet */, FA0B79D31A958EA3000E1D17 /* glad */, + FAF13FBF1E20934C00F898D2 /* glslang */, FA0B79D81A958EA3000E1D17 /* lodepng */, + FAAA3FD21F64B3AD00F89E99 /* lua53 */, FA0B79DB1A958EA3000E1D17 /* luasocket */, - FA0B7A101A958EA3000E1D17 /* luautf8 */, FAB17BE31ABFAA9000F9BA27 /* lz4 */, FA0B7A141A958EA3000E1D17 /* noise1234 */, + FAC7CD591FE35E95006A60C7 /* physfs */, FA0B7A171A958EA3000E1D17 /* stb */, + FA1557BE1CE90A2C00AFF582 /* tinyexr */, FA0B7A191A958EA3000E1D17 /* utf8 */, FA0B7A1F1A958EA3000E1D17 /* Wuff */, + FA4F2B761DE0125B00CA37D7 /* xxHash */, ); name = libraries; path = ../../src/libraries; @@ -1980,67 +2447,67 @@ FA0B79DC1A958EA3000E1D17 /* libluasocket */ = { isa = PBXGroup; children = ( - FA0B79DD1A958EA3000E1D17 /* auxiliar.c */, - FA0B79DE1A958EA3000E1D17 /* auxiliar.h */, - FA0B79DF1A958EA3000E1D17 /* buffer.c */, - FA0B79E01A958EA3000E1D17 /* buffer.h */, - FA0B79E11A958EA3000E1D17 /* except.c */, - FA0B79E21A958EA3000E1D17 /* except.h */, - FA0B79E31A958EA3000E1D17 /* ftp.lua */, - FA0B79E41A958EA3000E1D17 /* ftp.lua.h */, - FA0B79E51A958EA3000E1D17 /* http.lua */, - FA0B79E61A958EA3000E1D17 /* http.lua.h */, - FA0B79E71A958EA3000E1D17 /* inet.c */, - FA0B79E81A958EA3000E1D17 /* inet.h */, - FA0B79E91A958EA3000E1D17 /* io.c */, - FA0B79EA1A958EA3000E1D17 /* io.h */, - FA0B79EB1A958EA3000E1D17 /* ltn12.lua */, - FA0B79EC1A958EA3000E1D17 /* ltn12.lua.h */, - FA0B79ED1A958EA3000E1D17 /* lua.h */, - FA0B79EE1A958EA3000E1D17 /* luasocket.c */, - FA0B79EF1A958EA3000E1D17 /* luasocket.h */, - FA0B79F01A958EA3000E1D17 /* mime.c */, - FA0B79F11A958EA3000E1D17 /* mime.h */, - FA0B79F21A958EA3000E1D17 /* mime.lua */, - FA0B79F31A958EA3000E1D17 /* mime.lua.h */, - FA0B79F41A958EA3000E1D17 /* options.c */, - FA0B79F51A958EA3000E1D17 /* options.h */, - FA0B79F61A958EA3000E1D17 /* pre.lua */, - FA0B79F71A958EA3000E1D17 /* select.c */, - FA0B79F81A958EA3000E1D17 /* select.h */, - FA0B79F91A958EA3000E1D17 /* smtp.lua */, - FA0B79FA1A958EA3000E1D17 /* smtp.lua.h */, - FA0B79FB1A958EA3000E1D17 /* socket.h */, - FA0B79FC1A958EA3000E1D17 /* socket.lua */, - FA0B79FD1A958EA3000E1D17 /* socket.lua.h */, - FA0B79FE1A958EA3000E1D17 /* tcp.c */, - FA0B79FF1A958EA3000E1D17 /* tcp.h */, - FA0B7A001A958EA3000E1D17 /* timeout.c */, - FA0B7A011A958EA3000E1D17 /* timeout.h */, - FA0B7A021A958EA3000E1D17 /* tp.lua */, - FA0B7A031A958EA3000E1D17 /* tp.lua.h */, - FA0B7A041A958EA3000E1D17 /* udp.c */, - FA0B7A051A958EA3000E1D17 /* udp.h */, - FA0B7A061A958EA3000E1D17 /* unix.c */, - FA0B7A071A958EA3000E1D17 /* unix.h */, - FA0B7A081A958EA3000E1D17 /* url.lua */, - FA0B7A091A958EA3000E1D17 /* url.lua.h */, - FA0B7A0A1A958EA3000E1D17 /* usocket.c */, - FA0B7A0B1A958EA3000E1D17 /* usocket.h */, + 217DFB9D1D9F6D490055D849 /* auxiliar.c */, + 217DFB9E1D9F6D490055D849 /* auxiliar.h */, + 217DFB9F1D9F6D490055D849 /* buffer.c */, + 217DFBA01D9F6D490055D849 /* buffer.h */, + 217DFBA11D9F6D490055D849 /* compat.c */, + 217DFBA21D9F6D490055D849 /* compat.h */, + 217DFBA31D9F6D490055D849 /* except.c */, + 217DFBA41D9F6D490055D849 /* except.h */, + 217DFBA51D9F6D490055D849 /* ftp.lua */, + 217DFBA61D9F6D490055D849 /* ftp.lua.h */, + 217DFBA71D9F6D490055D849 /* headers.lua */, + 217DFBA81D9F6D490055D849 /* headers.lua.h */, + 217DFBA91D9F6D490055D849 /* http.lua */, + 217DFBAA1D9F6D490055D849 /* http.lua.h */, + 217DFBAB1D9F6D490055D849 /* inet.c */, + 217DFBAC1D9F6D490055D849 /* inet.h */, + 217DFBAD1D9F6D490055D849 /* io.c */, + 217DFBAE1D9F6D490055D849 /* io.h */, + 217DFBAF1D9F6D490055D849 /* ltn12.lua */, + 217DFBB01D9F6D490055D849 /* ltn12.lua.h */, + 217DFBB11D9F6D490055D849 /* luasocket.c */, + 217DFBB21D9F6D490055D849 /* luasocket.h */, + 217DFBB41D9F6D490055D849 /* mbox.lua */, + 217DFBB51D9F6D490055D849 /* mbox.lua.h */, + 217DFBB61D9F6D490055D849 /* mime.c */, + 217DFBB71D9F6D490055D849 /* mime.h */, + 217DFBB81D9F6D490055D849 /* mime.lua */, + 217DFBB91D9F6D490055D849 /* mime.lua.h */, + 217DFBBA1D9F6D490055D849 /* options.c */, + 217DFBBB1D9F6D490055D849 /* options.h */, + 217DFBBC1D9F6D490055D849 /* pierror.h */, + 217DFBBD1D9F6D490055D849 /* select.c */, + 217DFBBE1D9F6D490055D849 /* select.h */, + 217DFBBF1D9F6D490055D849 /* serial.c */, + 217DFBC01D9F6D490055D849 /* smtp.lua */, + 217DFBC11D9F6D490055D849 /* smtp.lua.h */, + 217DFBC21D9F6D490055D849 /* socket.h */, + 217DFBC31D9F6D490055D849 /* socket.lua */, + 217DFBC41D9F6D490055D849 /* socket.lua.h */, + 217DFBC51D9F6D490055D849 /* tcp.c */, + 217DFBC61D9F6D490055D849 /* tcp.h */, + 217DFBC71D9F6D490055D849 /* timeout.c */, + 217DFBC81D9F6D490055D849 /* timeout.h */, + 217DFBC91D9F6D490055D849 /* tp.lua */, + 217DFBCA1D9F6D490055D849 /* tp.lua.h */, + 217DFBCB1D9F6D490055D849 /* udp.c */, + 217DFBCC1D9F6D490055D849 /* udp.h */, + 217DFBCD1D9F6D490055D849 /* unix.c */, + 217DFBCE1D9F6D490055D849 /* unix.h */, + 217DFBCF1D9F6D490055D849 /* unixtcp.c */, + 217DFBD01D9F6D490055D849 /* unixtcp.h */, + 217DFBD11D9F6D490055D849 /* unixudp.c */, + 217DFBD21D9F6D490055D849 /* unixudp.h */, + 217DFBD31D9F6D490055D849 /* url.lua */, + 217DFBD41D9F6D490055D849 /* url.lua.h */, + 217DFBD51D9F6D490055D849 /* usocket.c */, + 217DFBD61D9F6D490055D849 /* usocket.h */, ); path = libluasocket; sourceTree = ""; }; - FA0B7A101A958EA3000E1D17 /* luautf8 */ = { - isa = PBXGroup; - children = ( - FA0B7A111A958EA3000E1D17 /* lprefix.h */, - FA0B7A121A958EA3000E1D17 /* lutf8lib.c */, - FA0B7A131A958EA3000E1D17 /* lutf8lib.h */, - ); - path = luautf8; - sourceTree = ""; - }; FA0B7A141A958EA3000E1D17 /* noise1234 */ = { isa = PBXGroup; children = ( @@ -2098,6 +2565,7 @@ isa = PBXGroup; children = ( FA0B7B3D1A95902C000E1D17 /* audio */, + FACA02DF1F5E396B0084B28F /* data */, FA0B7B521A95902C000E1D17 /* event */, FA0B7B5A1A95902C000E1D17 /* filesystem */, FA0B7B701A95902C000E1D17 /* font */, @@ -2126,12 +2594,20 @@ children = ( FA0B7B3E1A95902C000E1D17 /* Audio.cpp */, FA0B7B3F1A95902C000E1D17 /* Audio.h */, + FAC756F31E4F99B400B91289 /* Effect.cpp */, + FAC756F41E4F99B400B91289 /* Effect.h */, + FA1E887C1DF363CD00E808AA /* Filter.cpp */, + FA1E887D1DF363CD00E808AA /* Filter.h */, FA0B7B401A95902C000E1D17 /* null */, FA0B7B451A95902C000E1D17 /* openal */, + FA4F2BA21DE1E36400CA37D7 /* RecordingDevice.cpp */, + FA4F2BA31DE1E36400CA37D7 /* RecordingDevice.h */, FA0B7B4C1A95902C000E1D17 /* Source.cpp */, FA0B7B4D1A95902C000E1D17 /* Source.h */, FA0B7B4E1A95902C000E1D17 /* wrap_Audio.cpp */, FA0B7B4F1A95902C000E1D17 /* wrap_Audio.h */, + FA4F2BA41DE1E36400CA37D7 /* wrap_RecordingDevice.cpp */, + FA4F2BA51DE1E36400CA37D7 /* wrap_RecordingDevice.h */, FA0B7B501A95902C000E1D17 /* wrap_Source.cpp */, FA0B7B511A95902C000E1D17 /* wrap_Source.h */, ); @@ -2143,6 +2619,8 @@ children = ( FA0B7B411A95902C000E1D17 /* Audio.cpp */, FA0B7B421A95902C000E1D17 /* Audio.h */, + FA4F2BAA1DE1E37000CA37D7 /* RecordingDevice.cpp */, + FA4F2BAB1DE1E37000CA37D7 /* RecordingDevice.h */, FA0B7B431A95902C000E1D17 /* Source.cpp */, FA0B7B441A95902C000E1D17 /* Source.h */, ); @@ -2154,8 +2632,14 @@ children = ( FA0B7B461A95902C000E1D17 /* Audio.cpp */, FA0B7B471A95902C000E1D17 /* Audio.h */, + FAC756F81E4F99D200B91289 /* Effect.cpp */, + FAC756F91E4F99D200B91289 /* Effect.h */, + FA1E88811DF363DB00E808AA /* Filter.cpp */, + FA1E88821DF363DB00E808AA /* Filter.h */, FA0B7B481A95902C000E1D17 /* Pool.cpp */, FA0B7B491A95902C000E1D17 /* Pool.h */, + FA4F2BAE1DE1E37B00CA37D7 /* RecordingDevice.cpp */, + FA4F2BAF1DE1E37B00CA37D7 /* RecordingDevice.h */, FA0B7B4A1A95902C000E1D17 /* Source.cpp */, FA0B7B4B1A95902C000E1D17 /* Source.h */, ); @@ -2259,23 +2743,76 @@ FA0B7B871A95902C000E1D17 /* graphics */ = { isa = PBXGroup; children = ( - FA0B7B881A95902C000E1D17 /* Color.h */, + FADF53F61E3C7ACD00012CC0 /* Buffer.cpp */, + FADF53F71E3C7ACD00012CC0 /* Buffer.h */, + FA1BA0A51E16F20600AA2803 /* Canvas.cpp */, + FA1BA0A61E16F20600AA2803 /* Canvas.h */, + FA9D53AA1F5307E900125C6B /* Deprecations.cpp */, + FA9D53AB1F5307E900125C6B /* Deprecations.h */, + FAF1889E1E9DBC4B008C1479 /* depthstencil.cpp */, + FAF1889D1E9DBBC8008C1479 /* depthstencil.h */, + FA9D8DDC1DEF842A002CD881 /* Drawable.cpp */, FA0B7B891A95902C000E1D17 /* Drawable.h */, + FA1BA09B1E16CFCE00AA2803 /* Font.cpp */, + FA1BA09C1E16CFCE00AA2803 /* Font.h */, FA0B7B8A1A95902C000E1D17 /* Graphics.cpp */, FA0B7B8B1A95902C000E1D17 /* Graphics.h */, + FADF54141E3DA08E00012CC0 /* Image.cpp */, + FADF54151E3DA08E00012CC0 /* Image.h */, + FADF54231E3DA5BA00012CC0 /* Mesh.cpp */, + FADF54241E3DA5BA00012CC0 /* Mesh.h */, FA0B7B8C1A95902C000E1D17 /* opengl */, FAE272501C05A15B00A67640 /* ParticleSystem.cpp */, FAE272511C05A15B00A67640 /* ParticleSystem.h */, + FA0B7B9B1A95902C000E1D17 /* Polyline.cpp */, + FA0B7B9C1A95902C000E1D17 /* Polyline.h */, FA0B7BBC1A95902C000E1D17 /* Quad.cpp */, FA0B7BBD1A95902C000E1D17 /* Quad.h */, + FA10DD7B1F9EC24E00E1FE3D /* Resource.h */, + FA1BA0AF1E16FD0800AA2803 /* Shader.cpp */, + FA1BA0B01E16FD0800AA2803 /* Shader.h */, + FA3C5E401F8C368C0003C579 /* ShaderStage.cpp */, + FA3C5E411F8C368C0003C579 /* ShaderStage.h */, + FADF542D1E3DABF600012CC0 /* SpriteBatch.cpp */, + FADF542E1E3DABF600012CC0 /* SpriteBatch.h */, + FA29C0041E12355B00268CD8 /* StreamBuffer.cpp */, + FA2AF6721DAD62710032B62C /* StreamBuffer.h */, + FADF53FB1E3D74F200012CC0 /* Text.cpp */, + FADF53FC1E3D74F200012CC0 /* Text.h */, FA0B7BBE1A95902C000E1D17 /* Texture.cpp */, FA0B7BBF1A95902C000E1D17 /* Texture.h */, + FA2AF6731DAD64970032B62C /* vertex.cpp */, + FA2AF6711DAC76FF0032B62C /* vertex.h */, + FADF54051E3D78F700012CC0 /* Video.cpp */, + FADF54061E3D78F700012CC0 /* Video.h */, FA0B7BC01A95902C000E1D17 /* Volatile.cpp */, FA0B7BC11A95902C000E1D17 /* Volatile.h */, + FA1BA0AA1E16F9EE00AA2803 /* wrap_Canvas.cpp */, + FA1BA0AB1E16F9EE00AA2803 /* wrap_Canvas.h */, + FA1BA0A01E16D97500AA2803 /* wrap_Font.cpp */, + FA1BA0A11E16D97500AA2803 /* wrap_Font.h */, + FADF54391E3DAFF700012CC0 /* wrap_Graphics.cpp */, + FADF543A1E3DAFF700012CC0 /* wrap_Graphics.h */, + FADF54371E3DAFBA00012CC0 /* wrap_Graphics.lua */, + FADF54191E3DA46C00012CC0 /* wrap_Image.cpp */, + FADF541A1E3DA46C00012CC0 /* wrap_Image.h */, + FADF54281E3DAADA00012CC0 /* wrap_Mesh.cpp */, + FADF54291E3DAADA00012CC0 /* wrap_Mesh.h */, + FADF541E1E3DA52C00012CC0 /* wrap_ParticleSystem.cpp */, + FADF541F1E3DA52C00012CC0 /* wrap_ParticleSystem.h */, FA620A2E1AA2F8DB005DB4C2 /* wrap_Quad.cpp */, FA620A2F1AA2F8DB005DB4C2 /* wrap_Quad.h */, + FA1BA0B51E17043400AA2803 /* wrap_Shader.cpp */, + FA1BA0B61E17043400AA2803 /* wrap_Shader.h */, + FADF54321E3DAE6E00012CC0 /* wrap_SpriteBatch.cpp */, + FADF54331E3DAE6E00012CC0 /* wrap_SpriteBatch.h */, + FADF54001E3D77B500012CC0 /* wrap_Text.cpp */, + FADF54011E3D77B500012CC0 /* wrap_Text.h */, FA620A301AA2F8DB005DB4C2 /* wrap_Texture.cpp */, FA620A311AA2F8DB005DB4C2 /* wrap_Texture.h */, + FADF540A1E3D7CDD00012CC0 /* wrap_Video.cpp */, + FADF540B1E3D7CDD00012CC0 /* wrap_Video.h */, + FADF540C1E3D7CDD00012CC0 /* wrap_Video.lua */, ); path = graphics; sourceTree = ""; @@ -2283,54 +2820,24 @@ FA0B7B8C1A95902C000E1D17 /* opengl */ = { isa = PBXGroup; children = ( + FA0B7BA41A95902C000E1D17 /* Buffer.cpp */, + FA0B7BA51A95902C000E1D17 /* Buffer.h */, FA0B7B8D1A95902C000E1D17 /* Canvas.cpp */, FA0B7B8E1A95902C000E1D17 /* Canvas.h */, - FA0B7B8F1A95902C000E1D17 /* Font.cpp */, - FA0B7B901A95902C000E1D17 /* Font.h */, - FA0B7BA41A95902C000E1D17 /* GLBuffer.cpp */, - FA0B7BA51A95902C000E1D17 /* GLBuffer.h */, + FA28EBD31E352DB5003446F4 /* FenceSync.cpp */, + FA28EBD41E352DB5003446F4 /* FenceSync.h */, FA0B7B911A95902C000E1D17 /* Graphics.cpp */, FA0B7B921A95902C000E1D17 /* Graphics.h */, FA0B7B931A95902C000E1D17 /* Image.cpp */, FA0B7B941A95902C000E1D17 /* Image.h */, - FA0B7B951A95902C000E1D17 /* Mesh.cpp */, - FA0B7B961A95902C000E1D17 /* Mesh.h */, FA0B7B971A95902C000E1D17 /* OpenGL.cpp */, FA0B7B981A95902C000E1D17 /* OpenGL.h */, - FA0B7B991A95902C000E1D17 /* ParticleSystem.cpp */, - FA0B7B9A1A95902C000E1D17 /* ParticleSystem.h */, - FA0B7B9B1A95902C000E1D17 /* Polyline.cpp */, - FA0B7B9C1A95902C000E1D17 /* Polyline.h */, FA0B7B9D1A95902C000E1D17 /* Shader.cpp */, FA0B7B9E1A95902C000E1D17 /* Shader.h */, - FA0B7B9F1A95902C000E1D17 /* SpriteBatch.cpp */, - FA0B7BA01A95902C000E1D17 /* SpriteBatch.h */, - FA0B7BA11A95902C000E1D17 /* Text.cpp */, - FA0B7BA21A95902C000E1D17 /* Text.h */, - FA27B3C31B4985D8008A9DCE /* Video.cpp */, - FA27B3C41B4985D8008A9DCE /* Video.h */, - FA0B7BA61A95902C000E1D17 /* wrap_Canvas.cpp */, - FA0B7BA71A95902C000E1D17 /* wrap_Canvas.h */, - FA0B7BA81A95902C000E1D17 /* wrap_Font.cpp */, - FA0B7BA91A95902C000E1D17 /* wrap_Font.h */, - FA0B7BAA1A95902C000E1D17 /* wrap_Graphics.cpp */, - FA0B7BAB1A95902C000E1D17 /* wrap_Graphics.h */, - FA6AE6041B3335EC00583D5C /* wrap_Graphics.lua */, - FA0B7BAC1A95902C000E1D17 /* wrap_Image.cpp */, - FA0B7BAD1A95902C000E1D17 /* wrap_Image.h */, - FA0B7BAE1A95902C000E1D17 /* wrap_Mesh.cpp */, - FA0B7BAF1A95902C000E1D17 /* wrap_Mesh.h */, - FA0B7BB01A95902C000E1D17 /* wrap_ParticleSystem.cpp */, - FA0B7BB11A95902C000E1D17 /* wrap_ParticleSystem.h */, - FA0B7BB41A95902C000E1D17 /* wrap_Shader.cpp */, - FA0B7BB51A95902C000E1D17 /* wrap_Shader.h */, - FA0B7BB61A95902C000E1D17 /* wrap_SpriteBatch.cpp */, - FA0B7BB71A95902C000E1D17 /* wrap_SpriteBatch.h */, - FA0B7BB81A95902C000E1D17 /* wrap_Text.cpp */, - FA0B7BB91A95902C000E1D17 /* wrap_Text.h */, - FA19C4C21B4B0BD50059B0B3 /* wrap_Video.cpp */, - FA19C4C31B4B0BD50059B0B3 /* wrap_Video.h */, - FA19C4C41B4B0BD50059B0B3 /* wrap_Video.lua */, + FA3C5E451F8D80CA0003C579 /* ShaderStage.cpp */, + FA3C5E461F8D80CA0003C579 /* ShaderStage.h */, + FA7634481E28722A0066EF9E /* StreamBuffer.cpp */, + FA7634491E28722A0066EF9E /* StreamBuffer.h */, ); path = opengl; sourceTree = ""; @@ -2340,9 +2847,16 @@ children = ( FA0B7BC31A95902C000E1D17 /* CompressedImageData.cpp */, FA0B7BC41A95902C000E1D17 /* CompressedImageData.h */, + FAECA1B01F3164700095D008 /* CompressedSlice.cpp */, + FAECA1B11F3164700095D008 /* CompressedSlice.h */, + FA93C4511F315B960087CCD4 /* FormatHandler.cpp */, + FA93C4501F315B960087CCD4 /* FormatHandler.h */, + FA9D8DDF1DEF843D002CD881 /* Image.cpp */, FA0B7BC51A95902C000E1D17 /* Image.h */, FA0B7BC61A95902C000E1D17 /* ImageData.cpp */, FA0B7BC71A95902C000E1D17 /* ImageData.h */, + FAD19A151DFF8CA200D5398A /* ImageDataBase.cpp */, + FAD19A161DFF8CA200D5398A /* ImageDataBase.h */, FA0B7BC81A95902C000E1D17 /* magpie */, FA0B7BE21A95902C000E1D17 /* wrap_CompressedImageData.cpp */, FA0B7BE31A95902C000E1D17 /* wrap_CompressedImageData.h */, @@ -2360,17 +2874,10 @@ children = ( FA41A3C61C0A1F950084430C /* ASTCHandler.cpp */, FA41A3C71C0A1F950084430C /* ASTCHandler.h */, - FA0B7BCB1A95902C000E1D17 /* CompressedFormatHandler.h */, - FA0B7BC91A95902C000E1D17 /* CompressedImageData.cpp */, - FA0B7BCA1A95902C000E1D17 /* CompressedImageData.h */, FA0B7BCC1A95902C000E1D17 /* ddsHandler.cpp */, FA0B7BCD1A95902C000E1D17 /* ddsHandler.h */, - FA0B7BCE1A95902C000E1D17 /* FormatHandler.cpp */, - FA0B7BCF1A95902C000E1D17 /* FormatHandler.h */, - FA0B7BD01A95902C000E1D17 /* Image.cpp */, - FA0B7BD11A95902C000E1D17 /* Image.h */, - FA0B7BD21A95902C000E1D17 /* ImageData.cpp */, - FA0B7BD31A95902C000E1D17 /* ImageData.h */, + FA1557C11CE90BD200AFF582 /* EXRHandler.cpp */, + FA1557C21CE90BD200AFF582 /* EXRHandler.h */, FA0B7BD81A95902C000E1D17 /* KTXHandler.cpp */, FA0B7BD91A95902C000E1D17 /* KTXHandler.h */, FA0B7BDA1A95902C000E1D17 /* PKMHandler.cpp */, @@ -2446,24 +2953,22 @@ children = ( FA0B7C011A95902C000E1D17 /* BezierCurve.cpp */, FA0B7C021A95902C000E1D17 /* BezierCurve.h */, - FAB17BE91ABFAF1800F9BA27 /* CompressedData.cpp */, - FAB17BEA1ABFAF1800F9BA27 /* CompressedData.h */, - FAB17BDE1ABFAA2000F9BA27 /* Compressor.cpp */, - FAB17BDF1ABFAA2000F9BA27 /* Compressor.h */, FA0B7C031A95902C000E1D17 /* MathModule.cpp */, FA0B7C041A95902C000E1D17 /* MathModule.h */, FA0B7C051A95902C000E1D17 /* RandomGenerator.cpp */, FA0B7C061A95902C000E1D17 /* RandomGenerator.h */, + FA4F2BDF1DE6650600CA37D7 /* Transform.cpp */, + FA4F2BE01DE6650600CA37D7 /* Transform.h */, FA0B7C071A95902C000E1D17 /* wrap_BezierCurve.cpp */, FA0B7C081A95902C000E1D17 /* wrap_BezierCurve.h */, - FAB17BEE1ABFB37500F9BA27 /* wrap_CompressedData.cpp */, - FAB17BEF1ABFB37500F9BA27 /* wrap_CompressedData.h */, FA0B7C091A95902C000E1D17 /* wrap_Math.cpp */, FA0B7C0A1A95902C000E1D17 /* wrap_Math.h */, FA7DA04C1C16874A0056B200 /* wrap_Math.lua */, FA0B7C0B1A95902C000E1D17 /* wrap_RandomGenerator.cpp */, FA0B7C0C1A95902C000E1D17 /* wrap_RandomGenerator.h */, FA2E9BFE1C19E00C0004A1EE /* wrap_RandomGenerator.lua */, + FA4F2BE11DE6650600CA37D7 /* wrap_Transform.cpp */, + FA4F2BE21DE6650600CA37D7 /* wrap_Transform.h */, ); path = math; sourceTree = ""; @@ -2606,6 +3111,7 @@ FA0B7C7B1A95902C000E1D17 /* sound */ = { isa = PBXGroup; children = ( + FA0B7C801A95902C000E1D17 /* Decoder.cpp */, FA0B7C7C1A95902C000E1D17 /* Decoder.h */, FA0B7C7D1A95902C000E1D17 /* lullaby */, FA0B7C901A95902C000E1D17 /* Sound.cpp */, @@ -2628,8 +3134,6 @@ children = ( FA0B7C7E1A95902C000E1D17 /* CoreAudioDecoder.cpp */, FA0B7C7F1A95902C000E1D17 /* CoreAudioDecoder.h */, - FA0B7C801A95902C000E1D17 /* Decoder.cpp */, - FA0B7C811A95902C000E1D17 /* Decoder.h */, FA0B7C821A95902C000E1D17 /* FLACDecoder.cpp */, FA0B7C831A95902C000E1D17 /* FLACDecoder.h */, FA0B7C841A95902C000E1D17 /* GmeDecoder.cpp */, @@ -2706,7 +3210,6 @@ FA0B7CB71A95902C000E1D17 /* timer */ = { isa = PBXGroup; children = ( - FA0B7CB81A95902C000E1D17 /* sdl */, FA4B66C81ABBCF1900558F15 /* Timer.cpp */, FA0B7CBB1A95902C000E1D17 /* Timer.h */, FA0B7CBC1A95902C000E1D17 /* wrap_Timer.cpp */, @@ -2715,15 +3218,6 @@ path = timer; sourceTree = ""; }; - FA0B7CB81A95902C000E1D17 /* sdl */ = { - isa = PBXGroup; - children = ( - FA0B7CB91A95902C000E1D17 /* Timer.cpp */, - FA0B7CBA1A95902C000E1D17 /* Timer.h */, - ); - path = sdl; - sourceTree = ""; - }; FA0B7CBE1A95902C000E1D17 /* touch */ = { isa = PBXGroup; children = ( @@ -2768,24 +3262,31 @@ FA0B7EEB1A959125000E1D17 /* macosx */ = { isa = PBXGroup; children = ( - FA27B3C81B498623008A9DCE /* Theora.framework */, FA577A7916C71A1700860150 /* Cocoa.framework */, FAA627CD18E7E1560080752D /* CoreServices.framework */, - FA577A6716C719D900860150 /* FreeType.framework */, + FAD43ECB1FF312D800831BB8 /* freetype.framework */, FA577A8216C71A5300860150 /* libmodplug.framework */, FA317EB918F28B6D00B0BCD7 /* libz.dylib */, FA577A6D16C719EA00860150 /* Lua.framework */, FA577A6F16C719F000860150 /* mpg123.framework */, - FA577A7116C719F400860150 /* Ogg.framework */, + FA577A7116C719F400860150 /* ogg.framework */, FAAFF04316CB11C700CCDE45 /* OpenAL-Soft.framework */, FA577A7C16C71A2600860150 /* OpenGL.framework */, - FA577A7316C719F900860150 /* physfs.framework */, FA9B4A0716E1578300074F42 /* SDL2.framework */, - FA577A7716C71A0800860150 /* Vorbis.framework */, + FA27B3C81B498623008A9DCE /* theora.framework */, + FA577A7716C71A0800860150 /* vorbis.framework */, ); name = macosx; sourceTree = ""; }; + FA1557BE1CE90A2C00AFF582 /* tinyexr */ = { + isa = PBXGroup; + children = ( + FA1557BF1CE90A2C00AFF582 /* tinyexr.h */, + ); + path = tinyexr; + sourceTree = ""; + }; FA27B3881B498151008A9DCE /* video */ = { isa = PBXGroup; children = ( @@ -2804,14 +3305,25 @@ FA27B3891B498151008A9DCE /* theora */ = { isa = PBXGroup; children = ( + FAA54AC91F91660400A8FA7B /* OggDemuxer.cpp */, + FAA54AC61F91660400A8FA7B /* OggDemuxer.h */, + FAA54AC81F91660400A8FA7B /* TheoraVideoStream.cpp */, + FAA54AC71F91660400A8FA7B /* TheoraVideoStream.h */, FA27B38A1B498151008A9DCE /* Video.cpp */, FA27B38B1B498151008A9DCE /* Video.h */, - FA27B38C1B498151008A9DCE /* VideoStream.cpp */, - FA27B38D1B498151008A9DCE /* VideoStream.h */, ); path = theora; sourceTree = ""; }; + FA4F2B761DE0125B00CA37D7 /* xxHash */ = { + isa = PBXGroup; + children = ( + FA4F2B771DE0125B00CA37D7 /* xxhash.c */, + FA4F2B781DE0125B00CA37D7 /* xxhash.h */, + ); + path = xxHash; + sourceTree = ""; + }; FA56D9B91C2089CE00D8D3C7 /* modplug */ = { isa = PBXGroup; children = ( @@ -2853,7 +3365,6 @@ FA7550A61AEBE250003E311E /* luajit */, FA56D9B91C2089CE00D8D3C7 /* modplug */, FA5D24AA1A96D2EC00C6FC8F /* ogg */, - FA5D24AC1A96D2EC00C6FC8F /* physfs */, FA5D24CC1A96E63D00C6FC8F /* SDL2 */, FA59A2D51C0649BB00328DBA /* theora */, FA5D24AE1A96D2EC00C6FC8F /* vorbis */, @@ -2879,15 +3390,6 @@ path = ios/libraries/ogg; sourceTree = ""; }; - FA5D24AC1A96D2EC00C6FC8F /* physfs */ = { - isa = PBXGroup; - children = ( - FA5D24AD1A96D2EC00C6FC8F /* libphysfs.a */, - ); - name = physfs; - path = ios/libraries/physfs; - sourceTree = ""; - }; FA5D24AE1A96D2EC00C6FC8F /* vorbis */ = { isa = PBXGroup; children = ( @@ -2915,6 +3417,18 @@ path = ios/libraries/luajit; sourceTree = ""; }; + FAAA3FD21F64B3AD00F89E99 /* lua53 */ = { + isa = PBXGroup; + children = ( + FAAA3FD31F64B3AD00F89E99 /* lprefix.h */, + FAAA3FD41F64B3AD00F89E99 /* lstrlib.c */, + FAAA3FD51F64B3AD00F89E99 /* lstrlib.h */, + FAAA3FD61F64B3AD00F89E99 /* lutf8lib.c */, + FAAA3FD71F64B3AD00F89E99 /* lutf8lib.h */, + ); + path = lua53; + sourceTree = ""; + }; FAB17BE31ABFAA9000F9BA27 /* lz4 */ = { isa = PBXGroup; children = ( @@ -2922,10 +3436,217 @@ FAB17BE51ABFAA9000F9BA27 /* lz4.h */, FAB17BF31ABFC4B100F9BA27 /* lz4hc.c */, FAB17BF41ABFC4B100F9BA27 /* lz4hc.h */, + FAC7CD951FE755B3006A60C7 /* lz4opt.h */, ); path = lz4; sourceTree = ""; }; + FAC7CD591FE35E95006A60C7 /* physfs */ = { + isa = PBXGroup; + children = ( + FAC7CD5D1FE35E95006A60C7 /* physfs_archiver_7z.c */, + FAC7CD6C1FE35E95006A60C7 /* physfs_archiver_dir.c */, + FAC7CD741FE35E95006A60C7 /* physfs_archiver_grp.c */, + FAC7CD751FE35E95006A60C7 /* physfs_archiver_hog.c */, + FAC7CD6E1FE35E95006A60C7 /* physfs_archiver_iso9660.c */, + FAC7CD611FE35E95006A60C7 /* physfs_archiver_mvl.c */, + FAC7CD6F1FE35E95006A60C7 /* physfs_archiver_qpak.c */, + FAC7CD5F1FE35E95006A60C7 /* physfs_archiver_slb.c */, + FAC7CD671FE35E95006A60C7 /* physfs_archiver_unpacked.c */, + FAC7CD6A1FE35E95006A60C7 /* physfs_archiver_vdf.c */, + FAC7CD621FE35E95006A60C7 /* physfs_archiver_wad.c */, + FAC7CD761FE35E95006A60C7 /* physfs_archiver_zip.c */, + FAC7CD6D1FE35E95006A60C7 /* physfs_byteorder.c */, + FAC7CD631FE35E95006A60C7 /* physfs_casefolding.h */, + FAC7CD5A1FE35E95006A60C7 /* physfs_internal.h */, + FAC7CD711FE35E95006A60C7 /* physfs_lzmasdk.h */, + FAC7CD731FE35E95006A60C7 /* physfs_miniz.h */, + FAC7CD6B1FE35E95006A60C7 /* physfs_platform_apple.m */, + FAC7CD651FE35E95006A60C7 /* physfs_platform_haiku.cpp */, + FAC7CD641FE35E95006A60C7 /* physfs_platform_os2.c */, + FAC7CD721FE35E95006A60C7 /* physfs_platform_posix.c */, + FAC7CD5B1FE35E95006A60C7 /* physfs_platform_qnx.c */, + FAC7CD5E1FE35E95006A60C7 /* physfs_platform_unix.c */, + FAC7CD661FE35E95006A60C7 /* physfs_platform_windows.c */, + FAC7CD601FE35E95006A60C7 /* physfs_platform_winrt.cpp */, + FAC7CD701FE35E95006A60C7 /* physfs_platforms.h */, + FAC7CD681FE35E95006A60C7 /* physfs_unicode.c */, + FAC7CD5C1FE35E95006A60C7 /* physfs.c */, + FAC7CD691FE35E95006A60C7 /* physfs.h */, + ); + path = physfs; + sourceTree = ""; + }; + FACA02DF1F5E396B0084B28F /* data */ = { + isa = PBXGroup; + children = ( + FA6A2B721F60B6710074C308 /* ByteData.cpp */, + FA6A2B731F60B6710074C308 /* ByteData.h */, + FACA02E01F5E396B0084B28F /* CompressedData.cpp */, + FACA02E11F5E396B0084B28F /* CompressedData.h */, + FACA02E21F5E396B0084B28F /* Compressor.cpp */, + FACA02E31F5E396B0084B28F /* Compressor.h */, + FACA02E41F5E396B0084B28F /* DataModule.cpp */, + FACA02E51F5E396B0084B28F /* DataModule.h */, + FA6A2B681F5F7F560074C308 /* DataView.cpp */, + FA6A2B691F5F7F560074C308 /* DataView.h */, + FACA02E61F5E396B0084B28F /* HashFunction.cpp */, + FACA02E71F5E396B0084B28F /* HashFunction.h */, + FA6A2B781F60B8250074C308 /* wrap_ByteData.cpp */, + FA6A2B771F60B8250074C308 /* wrap_ByteData.h */, + FACA02E81F5E396B0084B28F /* wrap_CompressedData.cpp */, + FACA02E91F5E396B0084B28F /* wrap_CompressedData.h */, + FA6A2B651F5F7B6B0074C308 /* wrap_Data.cpp */, + FA6A2B641F5F7B6B0074C308 /* wrap_Data.h */, + FACA02EA1F5E396B0084B28F /* wrap_DataModule.cpp */, + FACA02EB1F5E396B0084B28F /* wrap_DataModule.h */, + FA6A2B6E1F5F845F0074C308 /* wrap_DataView.cpp */, + FA6A2B6D1F5F845F0074C308 /* wrap_DataView.h */, + ); + path = data; + sourceTree = ""; + }; + FAF13FBF1E20934C00F898D2 /* glslang */ = { + isa = PBXGroup; + children = ( + FAF13FC01E20934C00F898D2 /* glslang */, + FAF1403A1E20934C00F898D2 /* OGLCompilersDLL */, + ); + path = glslang; + sourceTree = ""; + }; + FAF13FC01E20934C00F898D2 /* glslang */ = { + isa = PBXGroup; + children = ( + FAF13FC11E20934C00F898D2 /* GenericCodeGen */, + FAF13FC41E20934C00F898D2 /* Include */, + FAF13FD21E20934C00F898D2 /* MachineIndependent */, + FAF140021E20934C00F898D2 /* OSDependent */, + FAF140281E20934C00F898D2 /* Public */, + ); + path = glslang; + sourceTree = ""; + }; + FAF13FC11E20934C00F898D2 /* GenericCodeGen */ = { + isa = PBXGroup; + children = ( + FAF13FC21E20934C00F898D2 /* CodeGen.cpp */, + FAF13FC31E20934C00F898D2 /* Link.cpp */, + ); + path = GenericCodeGen; + sourceTree = ""; + }; + FAF13FC41E20934C00F898D2 /* Include */ = { + isa = PBXGroup; + children = ( + FAF13FC51E20934C00F898D2 /* arrays.h */, + FAF13FC61E20934C00F898D2 /* BaseTypes.h */, + FAF13FC71E20934C00F898D2 /* Common.h */, + FAF13FC81E20934C00F898D2 /* ConstantUnion.h */, + FAF13FC91E20934C00F898D2 /* InfoSink.h */, + FAF13FCA1E20934C00F898D2 /* InitializeGlobals.h */, + FAF13FCB1E20934C00F898D2 /* intermediate.h */, + FAF13FCC1E20934C00F898D2 /* PoolAlloc.h */, + FAF13FCD1E20934C00F898D2 /* ResourceLimits.h */, + FAF13FCE1E20934C00F898D2 /* revision.h */, + FAF13FD01E20934C00F898D2 /* ShHandle.h */, + FAF13FD11E20934C00F898D2 /* Types.h */, + ); + path = Include; + sourceTree = ""; + }; + FAF13FD21E20934C00F898D2 /* MachineIndependent */ = { + isa = PBXGroup; + children = ( + FAF13FD31E20934C00F898D2 /* Constant.cpp */, + FAF13FD41E20934C00F898D2 /* gl_types.h */, + FAF13FD61E20934C00F898D2 /* glslang_tab.cpp */, + FAF13FD71E20934C00F898D2 /* glslang_tab.cpp.h */, + FAF13FD81E20934C00F898D2 /* InfoSink.cpp */, + FAF13FD91E20934C00F898D2 /* Initialize.cpp */, + FAF13FDA1E20934C00F898D2 /* Initialize.h */, + FAF13FDB1E20934C00F898D2 /* Intermediate.cpp */, + FAF13FDC1E20934C00F898D2 /* intermOut.cpp */, + FAF13FDD1E20934C00F898D2 /* IntermTraverse.cpp */, + FAF13FDE1E20934C00F898D2 /* iomapper.cpp */, + FAF13FDF1E20934C00F898D2 /* iomapper.h */, + FAF13FE01E20934C00F898D2 /* limits.cpp */, + FAF13FE11E20934C00F898D2 /* linkValidate.cpp */, + FAF13FE21E20934C00F898D2 /* LiveTraverser.h */, + FAF13FE31E20934C00F898D2 /* localintermediate.h */, + FAF13FE41E20934C00F898D2 /* parseConst.cpp */, + FAF13FE51E20934C00F898D2 /* ParseContextBase.cpp */, + FAF13FE61E20934C00F898D2 /* ParseHelper.cpp */, + FAF13FE71E20934C00F898D2 /* ParseHelper.h */, + FAF13FE81E20934C00F898D2 /* parseVersions.h */, + FAF13FE91E20934C00F898D2 /* PoolAlloc.cpp */, + FAF13FEA1E20934C00F898D2 /* preprocessor */, + FAF13FF41E20934C00F898D2 /* propagateNoContraction.cpp */, + FAF13FF51E20934C00F898D2 /* propagateNoContraction.h */, + FAF13FF61E20934C00F898D2 /* reflection.cpp */, + FAF13FF71E20934C00F898D2 /* reflection.h */, + FAF13FF81E20934C00F898D2 /* RemoveTree.cpp */, + FAF13FF91E20934C00F898D2 /* RemoveTree.h */, + FAF13FFA1E20934C00F898D2 /* Scan.cpp */, + FAF13FFB1E20934C00F898D2 /* Scan.h */, + FAF13FFC1E20934C00F898D2 /* ScanContext.h */, + FAF13FFD1E20934C00F898D2 /* ShaderLang.cpp */, + FAF13FFE1E20934C00F898D2 /* SymbolTable.cpp */, + FAF13FFF1E20934C00F898D2 /* SymbolTable.h */, + FAF140001E20934C00F898D2 /* Versions.cpp */, + FAF140011E20934C00F898D2 /* Versions.h */, + ); + path = MachineIndependent; + sourceTree = ""; + }; + FAF13FEA1E20934C00F898D2 /* preprocessor */ = { + isa = PBXGroup; + children = ( + FAF13FEB1E20934C00F898D2 /* Pp.cpp */, + FAF13FEC1E20934C00F898D2 /* PpAtom.cpp */, + FAF13FED1E20934C00F898D2 /* PpContext.cpp */, + FAF13FEE1E20934C00F898D2 /* PpContext.h */, + FAF13FF01E20934C00F898D2 /* PpScanner.cpp */, + FAF13FF21E20934C00F898D2 /* PpTokens.cpp */, + FAF13FF31E20934C00F898D2 /* PpTokens.h */, + ); + path = preprocessor; + sourceTree = ""; + }; + FAF140021E20934C00F898D2 /* OSDependent */ = { + isa = PBXGroup; + children = ( + FAF140031E20934C00F898D2 /* osinclude.h */, + FAF140041E20934C00F898D2 /* Unix */, + ); + path = OSDependent; + sourceTree = ""; + }; + FAF140041E20934C00F898D2 /* Unix */ = { + isa = PBXGroup; + children = ( + FAF140211E20934C00F898D2 /* ossource.cpp */, + ); + path = Unix; + sourceTree = ""; + }; + FAF140281E20934C00F898D2 /* Public */ = { + isa = PBXGroup; + children = ( + FAF140291E20934C00F898D2 /* ShaderLang.h */, + ); + path = Public; + sourceTree = ""; + }; + FAF1403A1E20934C00F898D2 /* OGLCompilersDLL */ = { + isa = PBXGroup; + children = ( + FAF1403B1E20934C00F898D2 /* InitializeDll.cpp */, + FAF1403C1E20934C00F898D2 /* InitializeDll.h */, + ); + path = OGLCompilersDLL; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -2933,42 +3654,54 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + FADF54221E3DA52C00012CC0 /* wrap_ParticleSystem.h in Headers */, + 217DFC0A1D9F6D490055D849 /* unix.h in Headers */, FA0B7D7E1A95902C000E1D17 /* Texture.h in Headers */, FA0B7E561A95902C000E1D17 /* wrap_GearJoint.h in Headers */, + FAF1409F1E20934C00F898D2 /* reflection.h in Headers */, FA0B7E1D1A95902C000E1D17 /* MouseJoint.h in Headers */, + FA1BA0B81E17043400AA2803 /* wrap_Shader.h in Headers */, + FA1557C41CE90BD200AFF582 /* EXRHandler.h in Headers */, FA0B7DC91A95902C000E1D17 /* Keyboard.h in Headers */, FA0B7D4A1A95902C000E1D17 /* Polyline.h in Headers */, + FAF1405C1E20934C00F898D2 /* InitializeGlobals.h in Headers */, FA0B7DB31A95902C000E1D17 /* wrap_Image.h in Headers */, - FA0B7D531A95902C000E1D17 /* Text.h in Headers */, - FA0B7D381A95902C000E1D17 /* Font.h in Headers */, + FAF140591E20934C00F898D2 /* Common.h in Headers */, FA0B7EC31A95902C000E1D17 /* threads.h in Headers */, FA0B7AC21A958EA3000E1D17 /* enet.h in Headers */, + FA4F2BA71DE1E36400CA37D7 /* RecordingDevice.h in Headers */, FA0B7E201A95902C000E1D17 /* Physics.h in Headers */, + FAF140791E20934C00F898D2 /* iomapper.h in Headers */, + 217DFBEA1D9F6D490055D849 /* io.h in Headers */, FA0B79221A958E3B000E1D17 /* delay.h in Headers */, FA0B79481A958E3B000E1D17 /* Vector.h in Headers */, FA0B7CCF1A95902C000E1D17 /* Audio.h in Headers */, FA0B7EC01A95902C000E1D17 /* Thread.h in Headers */, FA0B7E9C1A95902C000E1D17 /* VorbisDecoder.h in Headers */, + FAC756FB1E4F99D200B91289 /* Effect.h in Headers */, + FAC7CD901FE35E95006A60C7 /* physfs_miniz.h in Headers */, FA0B791D1A958E3B000E1D17 /* b64.h in Headers */, FA0B7DC61A95902C000E1D17 /* wrap_JoystickModule.h in Headers */, FA0B7D201A95902C000E1D17 /* ImageRasterizer.h in Headers */, FA0B7D241A95902C000E1D17 /* Vera.ttf.h in Headers */, + FADF54311E3DABF600012CC0 /* SpriteBatch.h in Headers */, FA0B7E5F1A95902C000E1D17 /* wrap_MouseJoint.h in Headers */, - FAB17BED1ABFAF1800F9BA27 /* CompressedData.h in Headers */, + 217DFC0C1D9F6D490055D849 /* unixtcp.h in Headers */, + FA76344C1E28722A0066EF9E /* StreamBuffer.h in Headers */, + FA6A2B761F60B6710074C308 /* ByteData.h in Headers */, + 217DFBF31D9F6D490055D849 /* mime.h in Headers */, FA0B7B361A958EA3000E1D17 /* wuff_convert.h in Headers */, - FA0B7D981A95902C000E1D17 /* ImageData.h in Headers */, FA0B7CDE1A95902C000E1D17 /* Source.h in Headers */, FA0B7E141A95902C000E1D17 /* GearJoint.h in Headers */, FA0B7D051A95902C000E1D17 /* wrap_DroppedFile.h in Headers */, - FA0B7B271A958EA3000E1D17 /* lutf8lib.h in Headers */, + FAAA3FDA1F64B3AD00F89E99 /* lstrlib.h in Headers */, FA0B7E9F1A95902C000E1D17 /* WaveDecoder.h in Headers */, + FAF140871E20934C00F898D2 /* parseVersions.h in Headers */, FA0B7AC61A958EA3000E1D17 /* types.h in Headers */, - FA0B7D751A95902C000E1D17 /* wrap_Text.h in Headers */, FA0B7DBD1A95902C000E1D17 /* Joystick.h in Headers */, FA0B7E901A95902C000E1D17 /* GmeDecoder.h in Headers */, FA0B7D0E1A95902C000E1D17 /* wrap_Filesystem.h in Headers */, FA0B7EE41A95902D000E1D17 /* Window.h in Headers */, - FA0B7D721A95902C000E1D17 /* wrap_SpriteBatch.h in Headers */, FA0B7CFC1A95902C000E1D17 /* Filesystem.h in Headers */, FA0B7AD81A958EA3000E1D17 /* lua-enet.h in Headers */, FA0B7A3A1A958EA3000E1D17 /* b2DynamicTree.h in Headers */, @@ -2976,58 +3709,91 @@ FA0B7EBA1A95902C000E1D17 /* Channel.h in Headers */, FA0B7D3E1A95902C000E1D17 /* Image.h in Headers */, FA0B7ECA1A95902C000E1D17 /* threads.h in Headers */, - FA0B7ED61A95902D000E1D17 /* Timer.h in Headers */, + FADF54361E3DAE6E00012CC0 /* wrap_SpriteBatch.h in Headers */, FA0B7DB01A95902C000E1D17 /* wrap_CompressedImageData.h in Headers */, + FAC7CD8D1FE35E95006A60C7 /* physfs_platforms.h in Headers */, FA0B7AC11A958EA3000E1D17 /* callbacks.h in Headers */, + FA3C5E491F8D80CA0003C579 /* ShaderStage.h in Headers */, FA0B7D8F1A95902C000E1D17 /* ddsHandler.h in Headers */, FAB2D5AC1AABDD8A008224A4 /* TrueTypeRasterizer.h in Headers */, + FAF140C41E20934C00F898D2 /* ShaderLang.h in Headers */, + FA1E887F1DF363CD00E808AA /* Filter.h in Headers */, FA27B3C21B4985BF008A9DCE /* wrap_VideoStream.h in Headers */, FA0B7AA31A958EA3000E1D17 /* b2PulleyJoint.h in Headers */, + FAF140621E20934C00F898D2 /* ShHandle.h in Headers */, FA0B7B2F1A958EA3000E1D17 /* utf8.h in Headers */, - FA19C4C71B4B0BD50059B0B3 /* wrap_Video.h in Headers */, FA0B79231A958E3B000E1D17 /* EnumMap.h in Headers */, + FAF140571E20934C00F898D2 /* arrays.h in Headers */, FA0B7A371A958EA3000E1D17 /* b2Distance.h in Headers */, FA0B7E681A95902C000E1D17 /* wrap_PrismaticJoint.h in Headers */, - FA0B7D571A95902C000E1D17 /* GLBuffer.h in Headers */, - FA27B3C71B4985D8008A9DCE /* Video.h in Headers */, + FA0B7D571A95902C000E1D17 /* Buffer.h in Headers */, + FAF140AB1E20934C00F898D2 /* SymbolTable.h in Headers */, FA0B7ED71A95902D000E1D17 /* Timer.h in Headers */, FA0B7AC31A958EA3000E1D17 /* list.h in Headers */, FA0B7B2D1A958EA3000E1D17 /* core.h in Headers */, + FA1E88841DF363DB00E808AA /* Filter.h in Headers */, + 217DFC061D9F6D490055D849 /* tp.lua.h in Headers */, FAB17BF71ABFC4B100F9BA27 /* lz4hc.h in Headers */, FA0B7E831A95902C000E1D17 /* Shape.h in Headers */, FAE272531C05A15B00A67640 /* ParticleSystem.h in Headers */, + FA6A2B6C1F5F7F560074C308 /* DataView.h in Headers */, + FAF140701E20934C00F898D2 /* Initialize.h in Headers */, + FAAA3FDC1F64B3AD00F89E99 /* lutf8lib.h in Headers */, + FAC7CD801FE35E95006A60C7 /* physfs_casefolding.h in Headers */, + FA1BA09F1E16CFCE00AA2803 /* Font.h in Headers */, FA0B7EDD1A95902D000E1D17 /* Touch.h in Headers */, FA0B7EDE1A95902D000E1D17 /* Touch.h in Headers */, + FAC7CD861FE35E95006A60C7 /* physfs.h in Headers */, FA0B7A541A958EA3000E1D17 /* b2Math.h in Headers */, + 217DFBEE1D9F6D490055D849 /* luasocket.h in Headers */, + FACA02F31F5E396B0084B28F /* HashFunction.h in Headers */, FA0B7ED01A95902C000E1D17 /* wrap_LuaThread.h in Headers */, + FA9159201CF1ED7500A7053F /* halffloat.h in Headers */, FA0B7CE41A95902C000E1D17 /* wrap_Audio.h in Headers */, FA0B7A7F1A958EA3000E1D17 /* b2ContactSolver.h in Headers */, + FADF540F1E3D7CDD00012CC0 /* wrap_Video.h in Headers */, + FAA54ACA1F91660400A8FA7B /* OggDemuxer.h in Headers */, FA0B79491A958E3B000E1D17 /* version.h in Headers */, + FAF140581E20934C00F898D2 /* BaseTypes.h in Headers */, FA0B7B2B1A958EA3000E1D17 /* stb_image.h in Headers */, + FAF140AE1E20934C00F898D2 /* Versions.h in Headers */, FA0B7CD21A95902C000E1D17 /* Audio.h in Headers */, FA0B79421A958E3B000E1D17 /* utf8.h in Headers */, FA0B7D171A95902C000E1D17 /* Font.h in Headers */, + FAECA1B41F3164700095D008 /* CompressedSlice.h in Headers */, FA0B7A6D1A958EA3000E1D17 /* b2World.h in Headers */, FA0B7EAE1A95902C000E1D17 /* wrap_SoundData.h in Headers */, FA0B7CFF1A95902C000E1D17 /* File.h in Headers */, FA0B7AB41A958EA3000E1D17 /* ddsinfo.h in Headers */, FA0B7DD21A95902C000E1D17 /* love.h in Headers */, + FA6A2B6F1F5F845F0074C308 /* wrap_DataView.h in Headers */, + FAF140861E20934C00F898D2 /* ParseHelper.h in Headers */, FA0B7CE71A95902C000E1D17 /* wrap_Source.h in Headers */, FA0B7B231A958EA3000E1D17 /* luasocket.h in Headers */, FA0B7D1D1A95902C000E1D17 /* GlyphData.h in Headers */, + FAC7CD8E1FE35E95006A60C7 /* physfs_lzmasdk.h in Headers */, FA0B7B391A958EA3000E1D17 /* wuff_internal.h in Headers */, + FAC7CD771FE35E95006A60C7 /* physfs_internal.h in Headers */, FA0B7A5A1A958EA3000E1D17 /* b2StackAllocator.h in Headers */, FA0B7D881A95902C000E1D17 /* ImageData.h in Headers */, FA0B7A661A958EA3000E1D17 /* b2Fixture.h in Headers */, FA0B7EE11A95902D000E1D17 /* wrap_Touch.h in Headers */, + FA9D8DDB1DEF8411002CD881 /* Stream.h in Headers */, FA0B7AA91A958EA3000E1D17 /* b2RopeJoint.h in Headers */, - FAB17BE21ABFAA2000F9BA27 /* Compressor.h in Headers */, + FACA02F71F5E396B0084B28F /* wrap_DataModule.h in Headers */, + FA56AA3A1FAFF02000A43D5F /* memory.h in Headers */, FA0B7E441A95902C000E1D17 /* wrap_CircleShape.h in Headers */, FA0B7EB41A95902C000E1D17 /* System.h in Headers */, + FAF1405A1E20934C00F898D2 /* ConstantUnion.h in Headers */, + FAF140A51E20934C00F898D2 /* Scan.h in Headers */, FA0B7CE11A95902C000E1D17 /* Source.h in Headers */, + FA1BA0AE1E16F9EE00AA2803 /* wrap_Canvas.h in Headers */, + FAF140901E20934C00F898D2 /* PpContext.h in Headers */, FA0B7E621A95902C000E1D17 /* wrap_Physics.h in Headers */, FA0B7DF01A95902C000E1D17 /* Mouse.h in Headers */, + 217DFBDC1D9F6D490055D849 /* buffer.h in Headers */, FA0B7DAD1A95902C000E1D17 /* STBHandler.h in Headers */, + FA1BA0A41E16D97500AA2803 /* wrap_Font.h in Headers */, FA0B7DE11A95902C000E1D17 /* wrap_Math.h in Headers */, FA0B7AAF1A958EA3000E1D17 /* b2WheelJoint.h in Headers */, FA0B7D1A1A95902C000E1D17 /* TrueTypeRasterizer.h in Headers */, @@ -3035,55 +3801,69 @@ FA0B7AC51A958EA3000E1D17 /* time.h in Headers */, FA0B793E1A958E3B000E1D17 /* StringMap.h in Headers */, FA0B793A1A958E3B000E1D17 /* Reference.h in Headers */, + FACA02F51F5E396B0084B28F /* wrap_CompressedData.h in Headers */, FA0B7DCC1A95902C000E1D17 /* Keyboard.h in Headers */, FA620A341AA2F8DB005DB4C2 /* wrap_Quad.h in Headers */, FA0B7EA51A95902C000E1D17 /* SoundData.h in Headers */, + FADF54271E3DA5BA00012CC0 /* Mesh.h in Headers */, + FAF1405E1E20934C00F898D2 /* PoolAlloc.h in Headers */, FA0B7A821A958EA3000E1D17 /* b2EdgeAndCircleContact.h in Headers */, FA0B79341A958E3B000E1D17 /* Object.h in Headers */, + 217DFBF11D9F6D490055D849 /* mbox.lua.h in Headers */, FA0B7CEA1A95902C000E1D17 /* Event.h in Headers */, FA0B7E351A95902C000E1D17 /* WeldJoint.h in Headers */, FA0B7E2F1A95902C000E1D17 /* RopeJoint.h in Headers */, FA0B7D141A95902C000E1D17 /* Font.h in Headers */, - FA0B7D411A95902C000E1D17 /* Mesh.h in Headers */, FA0B7E591A95902C000E1D17 /* wrap_Joint.h in Headers */, FA0B79351A958E3B000E1D17 /* macosx.h in Headers */, FA0B7A631A958EA3000E1D17 /* b2ContactManager.h in Headers */, FA0B7E771A95902C000E1D17 /* wrap_WeldJoint.h in Headers */, FA0B7A911A958EA3000E1D17 /* b2FrictionJoint.h in Headers */, FA0B7E291A95902C000E1D17 /* PulleyJoint.h in Headers */, - FA0B7D471A95902C000E1D17 /* ParticleSystem.h in Headers */, + FA6BDE5C1F31725300786805 /* Color.h in Headers */, FA0B7E231A95902C000E1D17 /* PolygonShape.h in Headers */, FA0B791E1A958E3B000E1D17 /* config.h in Headers */, FAB17BE81ABFAA9000F9BA27 /* lz4.h in Headers */, FA0B7E6B1A95902C000E1D17 /* wrap_PulleyJoint.h in Headers */, FA0B7E051A95902C000E1D17 /* Contact.h in Headers */, + FADF541D1E3DA46C00012CC0 /* wrap_Image.h in Headers */, + FA1BA0A91E16F20600AA2803 /* Canvas.h in Headers */, FA0B7A691A958EA3000E1D17 /* b2Island.h in Headers */, + FA4F2BE41DE6650600CA37D7 /* Transform.h in Headers */, FA0B7E0E1A95902C000E1D17 /* Fixture.h in Headers */, FA0B7A401A958EA3000E1D17 /* b2ChainShape.h in Headers */, + FA6A2B661F5F7B6B0074C308 /* wrap_Data.h in Headers */, + 217DFBE81D9F6D490055D849 /* inet.h in Headers */, + FADF53FA1E3C7ACD00012CC0 /* Buffer.h in Headers */, FA0B7AA61A958EA3000E1D17 /* b2RevoluteJoint.h in Headers */, FA0B7EEA1A95902D000E1D17 /* wrap_Window.h in Headers */, + FA1557C01CE90A2C00AFF582 /* tinyexr.h in Headers */, FA0B7E381A95902C000E1D17 /* WheelJoint.h in Headers */, FA0B7D851A95902C000E1D17 /* Image.h in Headers */, FA0B7E7D1A95902C000E1D17 /* wrap_World.h in Headers */, FA0B7EBD1A95902C000E1D17 /* LuaThread.h in Headers */, - FA0B7D601A95902C000E1D17 /* wrap_Graphics.h in Headers */, + FADF53FF1E3D74F200012CC0 /* Text.h in Headers */, FA0B7DC01A95902C000E1D17 /* JoystickModule.h in Headers */, FA0B7E871A95902C000E1D17 /* CoreAudioDecoder.h in Headers */, FA0B7CD51A95902C000E1D17 /* Source.h in Headers */, FA0B7A2B1A958EA3000E1D17 /* b2BroadPhase.h in Headers */, + 217DFBFD1D9F6D490055D849 /* smtp.lua.h in Headers */, FA27B39F1B498151008A9DCE /* Video.h in Headers */, - FA0B7D661A95902C000E1D17 /* wrap_Mesh.h in Headers */, FA0B7AAC1A958EA3000E1D17 /* b2WeldJoint.h in Headers */, + 217DFC041D9F6D490055D849 /* timeout.h in Headers */, FA0B7E7A1A95902C000E1D17 /* wrap_WheelJoint.h in Headers */, FA0B7A791A958EA3000E1D17 /* b2CircleContact.h in Headers */, FA0B7DD81A95902C000E1D17 /* MathModule.h in Headers */, - FA0B7D631A95902C000E1D17 /* wrap_Image.h in Headers */, FA0B7A341A958EA3000E1D17 /* b2Collision.h in Headers */, + 217DFBDA1D9F6D490055D849 /* auxiliar.h in Headers */, FA0B7EC71A95902C000E1D17 /* ThreadModule.h in Headers */, + FA4F2BAD1DE1E37000CA37D7 /* RecordingDevice.h in Headers */, FA0B792B1A958E3B000E1D17 /* Matrix.h in Headers */, FA0B7DA41A95902C000E1D17 /* PKMHandler.h in Headers */, FA0B7AC81A958EA3000E1D17 /* utility.h in Headers */, + 217DFC0E1D9F6D490055D849 /* unixudp.h in Headers */, FA0B791F1A958E3B000E1D17 /* Data.h in Headers */, + 217DFBE41D9F6D490055D849 /* headers.lua.h in Headers */, FA0B7D021A95902C000E1D17 /* Filesystem.h in Headers */, FA0B7E471A95902C000E1D17 /* wrap_Contact.h in Headers */, FA0B7E021A95902C000E1D17 /* CircleShape.h in Headers */, @@ -3091,41 +3871,56 @@ FA0B7AE01A958EA3000E1D17 /* lodepng.h in Headers */, FA0B7A4D1A958EA3000E1D17 /* b2BlockAllocator.h in Headers */, FA0B7ECD1A95902C000E1D17 /* wrap_Channel.h in Headers */, + FAF140AF1E20934C00F898D2 /* osinclude.h in Headers */, FA0B7A431A958EA3000E1D17 /* b2CircleShape.h in Headers */, + FA93C4531F315B960087CCD4 /* FormatHandler.h in Headers */, FA0B7CD81A95902C000E1D17 /* Audio.h in Headers */, FA0B7CF61A95902C000E1D17 /* File.h in Headers */, FA0B7E961A95902C000E1D17 /* Mpg123Decoder.h in Headers */, - FA0B7D501A95902C000E1D17 /* SpriteBatch.h in Headers */, + FADF54091E3D78F700012CC0 /* Video.h in Headers */, + FAA54ACB1F91660400A8FA7B /* TheoraVideoStream.h in Headers */, FA0B7DD51A95902C000E1D17 /* BezierCurve.h in Headers */, FA0B79271A958E3B000E1D17 /* int.h in Headers */, - FA27B3A21B498151008A9DCE /* VideoStream.h in Headers */, - FA0B7D8C1A95902C000E1D17 /* CompressedFormatHandler.h in Headers */, FA0B7E531A95902C000E1D17 /* wrap_FrictionJoint.h in Headers */, FA0B7EB71A95902C000E1D17 /* wrap_System.h in Headers */, FA27B3A91B498151008A9DCE /* Video.h in Headers */, + FAAA3FD81F64B3AD00F89E99 /* lprefix.h in Headers */, + 217DFBFA1D9F6D490055D849 /* select.h in Headers */, FA0B7DF61A95902C000E1D17 /* wrap_Mouse.h in Headers */, - FAB17BF21ABFB37500F9BA27 /* wrap_CompressedData.h in Headers */, + FAF140661E20934C00F898D2 /* gl_types.h in Headers */, FA0B7E801A95902C000E1D17 /* Joint.h in Headers */, FA0B7D2F1A95902C000E1D17 /* Drawable.h in Headers */, - FA0B7D951A95902C000E1D17 /* Image.h in Headers */, + 217DFBE21D9F6D490055D849 /* ftp.lua.h in Headers */, FA0B7EC41A95902C000E1D17 /* Thread.h in Headers */, FA0B7DFF1A95902C000E1D17 /* ChainShape.h in Headers */, FA0B7E4D1A95902C000E1D17 /* wrap_EdgeShape.h in Headers */, + FAF1405F1E20934C00F898D2 /* ResourceLimits.h in Headers */, FA0B7DDB1A95902C000E1D17 /* RandomGenerator.h in Headers */, FA0B7E841A95902C000E1D17 /* Decoder.h in Headers */, FA0B7A601A958EA3000E1D17 /* b2Body.h in Headers */, FA0B7EAB1A95902C000E1D17 /* wrap_Sound.h in Headers */, FA0B7B2C1A958EA3000E1D17 /* checked.h in Headers */, + FADF54181E3DA08E00012CC0 /* Image.h in Headers */, FA0B7D2A1A95902C000E1D17 /* wrap_GlyphData.h in Headers */, + FACA02F11F5E396B0084B28F /* DataModule.h in Headers */, FA0B7E741A95902C000E1D17 /* wrap_Shape.h in Headers */, FA0B7A5D1A958EA3000E1D17 /* b2Timer.h in Headers */, + FA91DA8D1F377C3900C80E33 /* deprecation.h in Headers */, FA0B7A4A1A958EA3000E1D17 /* b2Shape.h in Headers */, + FAF1407F1E20934C00F898D2 /* localintermediate.h in Headers */, + FAF1406B1E20934C00F898D2 /* glslang_tab.cpp.h in Headers */, + 217DFBF71D9F6D490055D849 /* options.h in Headers */, FA0B7E3B1A95902C000E1D17 /* World.h in Headers */, FA0B7DC31A95902C000E1D17 /* wrap_Joystick.h in Headers */, + FAF140631E20934C00F898D2 /* Types.h in Headers */, + FA4F2BE61DE6650600CA37D7 /* wrap_Transform.h in Headers */, FA0B7EE71A95902D000E1D17 /* Window.h in Headers */, FA0B7E651A95902C000E1D17 /* wrap_PolygonShape.h in Headers */, FA0B7AC91A958EA3000E1D17 /* win32.h in Headers */, FA0B7DFC1A95902C000E1D17 /* Body.h in Headers */, + FA1BA0B31E16FD0800AA2803 /* Shader.h in Headers */, + 217DFC101D9F6D490055D849 /* url.lua.h in Headers */, + FAF140DD1E20934C00F898D2 /* InitializeDll.h in Headers */, FA0B7A941A958EA3000E1D17 /* b2GearJoint.h in Headers */, FA0B7DF31A95902C000E1D17 /* wrap_Cursor.h in Headers */, FA0B7A461A958EA3000E1D17 /* b2EdgeShape.h in Headers */, @@ -3137,22 +3932,28 @@ FA0B7E261A95902C000E1D17 /* PrismaticJoint.h in Headers */, FA0B7E991A95902C000E1D17 /* Sound.h in Headers */, FA0B7D841A95902C000E1D17 /* CompressedImageData.h in Headers */, + FACA02ED1F5E396B0084B28F /* CompressedData.h in Headers */, + FAF1407E1E20934C00F898D2 /* LiveTraverser.h in Headers */, FA0B7D231A95902C000E1D17 /* Rasterizer.h in Headers */, + FAD19A191DFF8CA200D5398A /* ImageDataBase.h in Headers */, FA0B7CDB1A95902C000E1D17 /* Pool.h in Headers */, FA0B7D0B1A95902C000E1D17 /* wrap_FileData.h in Headers */, FA0B7DF91A95902C000E1D17 /* Body.h in Headers */, FA0B7DB91A95902C000E1D17 /* Joystick.h in Headers */, + FA4F2BB11DE1E37B00CA37D7 /* RecordingDevice.h in Headers */, FA0B7E2C1A95902C000E1D17 /* RevoluteJoint.h in Headers */, FA8951A41AA2EDF300EC385A /* wrap_Event.h in Headers */, FA0B7B2A1A958EA3000E1D17 /* simplexnoise1234.h in Headers */, + FA9D53AE1F5307E900125C6B /* Deprecations.h in Headers */, FA0B7ADC1A958EA3000E1D17 /* glad.hpp in Headers */, + FA6A2B791F60B8250074C308 /* wrap_ByteData.h in Headers */, FA0B7CF91A95902C000E1D17 /* FileData.h in Headers */, FA0B7DA71A95902C000E1D17 /* PNGHandler.h in Headers */, FA0B7AC41A958EA3000E1D17 /* protocol.h in Headers */, - FA0B7D8B1A95902C000E1D17 /* CompressedImageData.h in Headers */, + FAF140601E20934C00F898D2 /* revision.h in Headers */, + FAF140A21E20934C00F898D2 /* RemoveTree.h in Headers */, FA0B7A8E1A958EA3000E1D17 /* b2DistanceJoint.h in Headers */, FA0B7A8B1A958EA3000E1D17 /* b2PolygonContact.h in Headers */, - FA0B794C1A958E3B000E1D17 /* wrap_Data.h in Headers */, FA0B7D321A95902C000E1D17 /* Graphics.h in Headers */, FA0B7E321A95902C000E1D17 /* Shape.h in Headers */, FA620A371AA2F8DB005DB4C2 /* wrap_Texture.h in Headers */, @@ -3160,39 +3961,49 @@ FA0B792E1A958E3B000E1D17 /* Memoizer.h in Headers */, FA0B7A731A958EA3000E1D17 /* b2ChainAndCircleContact.h in Headers */, FA0B7AA01A958EA3000E1D17 /* b2PrismaticJoint.h in Headers */, - FA0B7B241A958EA3000E1D17 /* lprefix.h in Headers */, FA0B7DEA1A95902C000E1D17 /* Mouse.h in Headers */, FA0B7E931A95902C000E1D17 /* ModPlugDecoder.h in Headers */, FA0B7D111A95902C000E1D17 /* BMFontRasterizer.h in Headers */, - FA0B7E8A1A95902C000E1D17 /* Decoder.h in Headers */, + 217DFBE61D9F6D490055D849 /* http.lua.h in Headers */, FA0B7E3E1A95902C000E1D17 /* wrap_Body.h in Headers */, + FAF140991E20934C00F898D2 /* PpTokens.h in Headers */, FA0B7A571A958EA3000E1D17 /* b2Settings.h in Headers */, + FAF1405B1E20934C00F898D2 /* InfoSink.h in Headers */, FA0B7B321A958EA3000E1D17 /* wuff.h in Headers */, + 217DFBF81D9F6D490055D849 /* pierror.h in Headers */, + 217DFC021D9F6D490055D849 /* tcp.h in Headers */, FA0B7A3D1A958EA3000E1D17 /* b2TimeOfImpact.h in Headers */, + FA3C5E441F8C368C0003C579 /* ShaderStage.h in Headers */, FA0B79261A958E3B000E1D17 /* Exception.h in Headers */, FA0B7D4D1A95902C000E1D17 /* Shader.h in Headers */, FA0B793D1A958E3B000E1D17 /* runtime.h in Headers */, FA0B7A701A958EA3000E1D17 /* b2WorldCallbacks.h in Headers */, FA0B7A9D1A958EA3000E1D17 /* b2MouseJoint.h in Headers */, FA57FB9A1AE1993600F2AD6D /* noise1234.h in Headers */, + FACA02EF1F5E396B0084B28F /* Compressor.h in Headers */, FA0B7CED1A95902C000E1D17 /* Event.h in Headers */, FA0B7D811A95902C000E1D17 /* Volatile.h in Headers */, FA0B7B2E1A958EA3000E1D17 /* unchecked.h in Headers */, FA0B7D081A95902C000E1D17 /* wrap_File.h in Headers */, FA0B79451A958E3B000E1D17 /* Variant.h in Headers */, - FA0B7D691A95902C000E1D17 /* wrap_ParticleSystem.h in Headers */, FA0B7E5C1A95902C000E1D17 /* wrap_MotorJoint.h in Headers */, + FA4F2BA91DE1E36400CA37D7 /* wrap_RecordingDevice.h in Headers */, FA0B7A7C1A958EA3000E1D17 /* b2Contact.h in Headers */, FA0B7A881A958EA3000E1D17 /* b2PolygonAndCircleContact.h in Headers */, + FA4F2B7A1DE0125B00CA37D7 /* xxhash.h in Headers */, FA0B7DDE1A95902C000E1D17 /* wrap_BezierCurve.h in Headers */, FA0B7DED1A95902C000E1D17 /* Cursor.h in Headers */, FA0B7E501A95902C000E1D17 /* wrap_Fixture.h in Headers */, + FA28EBD71E352DB5003446F4 /* FenceSync.h in Headers */, + FADF542C1E3DAADA00012CC0 /* wrap_Mesh.h in Headers */, FAA3A9B01B7D465A00CED060 /* android.h in Headers */, + 217DFBDE1D9F6D490055D849 /* compat.h in Headers */, FA0B7A491A958EA3000E1D17 /* b2PolygonShape.h in Headers */, FA0B79281A958E3B000E1D17 /* math.h in Headers */, + 217DFC121D9F6D490055D849 /* usocket.h in Headers */, FA0B7A9A1A958EA3000E1D17 /* b2MotorJoint.h in Headers */, + 217DFC081D9F6D490055D849 /* udp.h in Headers */, FA0B7DCF1A95902C000E1D17 /* wrap_Keyboard.h in Headers */, - FA0B7D6F1A95902C000E1D17 /* wrap_Shader.h in Headers */, FA0B7EA21A95902C000E1D17 /* Sound.h in Headers */, FA0B7B331A958EA3000E1D17 /* wuff_config.h in Headers */, FA0B7CF31A95902C000E1D17 /* DroppedFile.h in Headers */, @@ -3201,18 +4012,26 @@ FA27B3AC1B498151008A9DCE /* VideoStream.h in Headers */, FA0B7AC71A958EA3000E1D17 /* unix.h in Headers */, FA0B7E8D1A95902C000E1D17 /* FLACDecoder.h in Headers */, + 217DFC001D9F6D490055D849 /* socket.lua.h in Headers */, FA0B7A501A958EA3000E1D17 /* b2Draw.h in Headers */, FA0B7DE71A95902C000E1D17 /* Cursor.h in Headers */, + 217DFBEC1D9F6D490055D849 /* ltn12.lua.h in Headers */, FA0B7DB61A95902C000E1D17 /* wrap_ImageData.h in Headers */, + FADF543D1E3DAFF700012CC0 /* wrap_Graphics.h in Headers */, + 217DFBFE1D9F6D490055D849 /* socket.h in Headers */, FA0B7A971A958EA3000E1D17 /* b2Joint.h in Headers */, FA0B7A851A958EA3000E1D17 /* b2EdgeAndPolygonContact.h in Headers */, + FAF1409C1E20934C00F898D2 /* propagateNoContraction.h in Headers */, FA0B7D2D1A95902C000E1D17 /* wrap_Rasterizer.h in Headers */, FA0B7AB71A958EA3000E1D17 /* ddsparse.h in Headers */, FA0B7DA11A95902C000E1D17 /* KTXHandler.h in Headers */, + 217DFBE01D9F6D490055D849 /* except.h in Headers */, FA0B79311A958E3B000E1D17 /* Module.h in Headers */, - FA0B7D5A1A95902C000E1D17 /* wrap_Canvas.h in Headers */, + 217DFBF51D9F6D490055D849 /* mime.lua.h in Headers */, + FAC7CD961FE755B4006A60C7 /* lz4opt.h in Headers */, + FA9D8DD31DEB56C3002CD881 /* pixelformat.h in Headers */, + FAF140A61E20934C00F898D2 /* ScanContext.h in Headers */, FA0B7E4A1A95902C000E1D17 /* wrap_DistanceJoint.h in Headers */, - FA0B7D2E1A95902C000E1D17 /* Color.h in Headers */, FA0B7A6A1A958EA3000E1D17 /* b2TimeStep.h in Headers */, FA0B7A281A958EA3000E1D17 /* Box2D.h in Headers */, FA0B7DE41A95902C000E1D17 /* wrap_RandomGenerator.h in Headers */, @@ -3228,11 +4047,12 @@ FA0B793F1A958E3B000E1D17 /* types.h in Headers */, FA0B7AB31A958EA3000E1D17 /* b2Rope.h in Headers */, FA41A3CA1C0A1F950084430C /* ASTCHandler.h in Headers */, - FA0B7D5D1A95902C000E1D17 /* wrap_Font.h in Headers */, + FADF54041E3D77B500012CC0 /* wrap_Text.h in Headers */, FA0B7ED31A95902C000E1D17 /* wrap_ThreadModule.h in Headers */, FA0B7A511A958EA3000E1D17 /* b2GrowableStack.h in Headers */, - FA0B7D921A95902C000E1D17 /* FormatHandler.h in Headers */, + FAC756F61E4F99B400B91289 /* Effect.h in Headers */, FA0B7ADD1A958EA3000E1D17 /* gladfuncs.hpp in Headers */, + FAF1405D1E20934C00F898D2 /* intermediate.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3280,7 +4100,7 @@ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0700; + LastUpgradeCheck = 0920; TargetAttributes = { FA0B78DC1A958B90000E1D17 = { CreatedOnToolsVersion = 6.1.1; @@ -3309,6 +4129,18 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 217DFC0F1D9F6D490055D849 /* url.lua in Resources */, + FADF54101E3D7CDD00012CC0 /* wrap_Video.lua in Resources */, + 217DFBFC1D9F6D490055D849 /* smtp.lua in Resources */, + FADF54381E3DAFBA00012CC0 /* wrap_Graphics.lua in Resources */, + 217DFBF01D9F6D490055D849 /* mbox.lua in Resources */, + 217DFBE11D9F6D490055D849 /* ftp.lua in Resources */, + 217DFBFF1D9F6D490055D849 /* socket.lua in Resources */, + 217DFC051D9F6D490055D849 /* tp.lua in Resources */, + 217DFBE51D9F6D490055D849 /* http.lua in Resources */, + 217DFBEB1D9F6D490055D849 /* ltn12.lua in Resources */, + 217DFBF41D9F6D490055D849 /* mime.lua in Resources */, + 217DFBE31D9F6D490055D849 /* headers.lua in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3319,290 +4151,363 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - FA0B7D741A95902C000E1D17 /* wrap_Text.cpp in Sources */, FA0B7DE01A95902C000E1D17 /* wrap_Math.cpp in Sources */, FA0B7DA91A95902C000E1D17 /* PVRHandler.cpp in Sources */, FA0B7EC61A95902C000E1D17 /* ThreadModule.cpp in Sources */, FA0B7D2C1A95902C000E1D17 /* wrap_Rasterizer.cpp in Sources */, - FA0B7D591A95902C000E1D17 /* wrap_Canvas.cpp in Sources */, + FADF54081E3D78F700012CC0 /* Video.cpp in Sources */, + FA9D8DD81DEF8411002CD881 /* Data.cpp in Sources */, FA0B7E8F1A95902C000E1D17 /* GmeDecoder.cpp in Sources */, + FADF542B1E3DAADA00012CC0 /* wrap_Mesh.cpp in Sources */, FA0B7CD71A95902C000E1D17 /* Audio.cpp in Sources */, FA0B7AC01A958EA3000E1D17 /* host.c in Sources */, FA0B7EB01A95902C000E1D17 /* System.cpp in Sources */, FA0B7EE31A95902D000E1D17 /* Window.cpp in Sources */, FA0B7AAB1A958EA3000E1D17 /* b2WeldJoint.cpp in Sources */, FA0B7EC21A95902C000E1D17 /* threads.cpp in Sources */, + FA4F2C051DE936C900CA37D7 /* compat.c in Sources */, FA0B79371A958E3B000E1D17 /* macosx.mm in Sources */, + FA4F2BE81DE6651000CA37D7 /* wrap_Transform.cpp in Sources */, FA0B7D011A95902C000E1D17 /* Filesystem.cpp in Sources */, + FAF140651E20934C00F898D2 /* Constant.cpp in Sources */, FA0B7ED91A95902D000E1D17 /* wrap_Timer.cpp in Sources */, + FAF1407D1E20934C00F898D2 /* linkValidate.cpp in Sources */, FA0B7DD11A95902C000E1D17 /* love.cpp in Sources */, + FA15DFAF1F9B8D390042AB22 /* lstrlib.c in Sources */, FA0B7AB61A958EA3000E1D17 /* ddsparse.cpp in Sources */, FA0B7D221A95902C000E1D17 /* Rasterizer.cpp in Sources */, FA0B7A4F1A958EA3000E1D17 /* b2Draw.cpp in Sources */, + FAF140BC1E20934C00F898D2 /* ossource.cpp in Sources */, FA0B7D7D1A95902C000E1D17 /* Texture.cpp in Sources */, + FACA02FB1F5E397E0084B28F /* HashFunction.cpp in Sources */, + FAF140A81E20934C00F898D2 /* ShaderLang.cpp in Sources */, + FA1BA09E1E16CFCE00AA2803 /* Font.cpp in Sources */, FA0B7ECC1A95902C000E1D17 /* wrap_Channel.cpp in Sources */, FA0B7E6D1A95902C000E1D17 /* wrap_RevoluteJoint.cpp in Sources */, - FA0B7B0F1A958EA3000E1D17 /* timeout.c in Sources */, FA0B7A5F1A958EA3000E1D17 /* b2Body.cpp in Sources */, - FA0B7B171A958EA3000E1D17 /* unix.c in Sources */, + FADF541C1E3DA46C00012CC0 /* wrap_Image.cpp in Sources */, + FACA02FA1F5E397B0084B28F /* DataModule.cpp in Sources */, FA0B7E641A95902C000E1D17 /* wrap_PolygonShape.cpp in Sources */, + FA4F2C031DE936C200CA37D7 /* auxiliar.c in Sources */, FA0B7E731A95902C000E1D17 /* wrap_Shape.cpp in Sources */, FA0B7CFE1A95902C000E1D17 /* File.cpp in Sources */, + FA3C5E481F8D80CA0003C579 /* ShaderStage.cpp in Sources */, FA27B39E1B498151008A9DCE /* Video.cpp in Sources */, FA0B7A751A958EA3000E1D17 /* b2ChainAndPolygonContact.cpp in Sources */, FA0B7E6A1A95902C000E1D17 /* wrap_PulleyJoint.cpp in Sources */, FA0B7DB81A95902C000E1D17 /* Joystick.cpp in Sources */, - FA0B794B1A958E3B000E1D17 /* wrap_Data.cpp in Sources */, - FAB17BEC1ABFAF1800F9BA27 /* CompressedData.cpp in Sources */, - FA0B7D371A95902C000E1D17 /* Font.cpp in Sources */, + FA91DA8C1F377C3900C80E33 /* deprecation.cpp in Sources */, + FA6A2B6B1F5F7F560074C308 /* DataView.cpp in Sources */, FA0B7E401A95902C000E1D17 /* wrap_ChainShape.cpp in Sources */, FA0B7DEC1A95902C000E1D17 /* Cursor.cpp in Sources */, FA0B7D871A95902C000E1D17 /* ImageData.cpp in Sources */, - FA0B7AE21A958EA3000E1D17 /* auxiliar.c in Sources */, FA0B7E101A95902C000E1D17 /* FrictionJoint.cpp in Sources */, + FAF140741E20934C00F898D2 /* intermOut.cpp in Sources */, FA620A361AA2F8DB005DB4C2 /* wrap_Texture.cpp in Sources */, FA0B7D0A1A95902C000E1D17 /* wrap_FileData.cpp in Sources */, + FAF140781E20934C00F898D2 /* iomapper.cpp in Sources */, FA0B7ABE1A958EA3000E1D17 /* compress.c in Sources */, FA0B7CF21A95902C000E1D17 /* DroppedFile.cpp in Sources */, - FA0B7D8A1A95902C000E1D17 /* CompressedImageData.cpp in Sources */, + FA4F2C141DE936FE00CA37D7 /* usocket.c in Sources */, + FAF140831E20934C00F898D2 /* ParseContextBase.cpp in Sources */, FA0B7AD21A958EA3000E1D17 /* protocol.c in Sources */, + FAF140A41E20934C00F898D2 /* Scan.cpp in Sources */, FA0B7D1F1A95902C000E1D17 /* ImageRasterizer.cpp in Sources */, FA0B7EA41A95902C000E1D17 /* SoundData.cpp in Sources */, FA0B7D041A95902C000E1D17 /* wrap_DroppedFile.cpp in Sources */, - FA0B7B261A958EA3000E1D17 /* lutf8lib.c in Sources */, - FA0B7D461A95902C000E1D17 /* ParticleSystem.cpp in Sources */, + FAF1406A1E20934C00F898D2 /* glslang_tab.cpp in Sources */, + FA91591F1CF1ED7500A7053F /* halffloat.cpp in Sources */, FA8951A31AA2EDF300EC385A /* wrap_Event.cpp in Sources */, + FADF540E1E3D7CDD00012CC0 /* wrap_Video.cpp in Sources */, FA0B7A361A958EA3000E1D17 /* b2Distance.cpp in Sources */, FA0B7D4C1A95902C000E1D17 /* Shader.cpp in Sources */, FA0B792A1A958E3B000E1D17 /* Matrix.cpp in Sources */, + FAF140981E20934C00F898D2 /* PpTokens.cpp in Sources */, + FAF140AA1E20934C00F898D2 /* SymbolTable.cpp in Sources */, FA0B7A8D1A958EA3000E1D17 /* b2DistanceJoint.cpp in Sources */, FA0B7A841A958EA3000E1D17 /* b2EdgeAndPolygonContact.cpp in Sources */, + FA3C5E431F8C368C0003C579 /* ShaderStage.cpp in Sources */, FA0B7E191A95902C000E1D17 /* MotorJoint.cpp in Sources */, + FAF1406F1E20934C00F898D2 /* Initialize.cpp in Sources */, FA0B7E4F1A95902C000E1D17 /* wrap_Fixture.cpp in Sources */, FA0B7EBF1A95902C000E1D17 /* Thread.cpp in Sources */, + FACA02F91F5E39790084B28F /* Compressor.cpp in Sources */, + FAF140811E20934C00F898D2 /* parseConst.cpp in Sources */, + FA4F2C121DE936FE00CA37D7 /* unixtcp.c in Sources */, FA0B7EB91A95902C000E1D17 /* Channel.cpp in Sources */, - FA0B7AFB1A958EA3000E1D17 /* mime.c in Sources */, FA4B66CA1ABBCF1900558F15 /* Timer.cpp in Sources */, FA0B7A3F1A958EA3000E1D17 /* b2ChainShape.cpp in Sources */, FA0B7E921A95902C000E1D17 /* ModPlugDecoder.cpp in Sources */, FA0B7E521A95902C000E1D17 /* wrap_FrictionJoint.cpp in Sources */, + FADF54351E3DAE6E00012CC0 /* wrap_SpriteBatch.cpp in Sources */, + FA4F2BB51DE1E4C300CA37D7 /* wrap_RecordingDevice.cpp in Sources */, FA0B7A311A958EA3000E1D17 /* b2CollidePolygon.cpp in Sources */, + FA4F2C111DE936FE00CA37D7 /* unix.c in Sources */, + FA1BA0A31E16D97500AA2803 /* wrap_Font.cpp in Sources */, FA0B7A931A958EA3000E1D17 /* b2GearJoint.cpp in Sources */, FA0B7E0D1A95902C000E1D17 /* Fixture.cpp in Sources */, + FADF53FE1E3D74F200012CC0 /* Text.cpp in Sources */, FA0B7D191A95902C000E1D17 /* TrueTypeRasterizer.cpp in Sources */, FA0B7CFB1A95902C000E1D17 /* Filesystem.cpp in Sources */, FA0B7D3D1A95902C000E1D17 /* Image.cpp in Sources */, FA0B7B351A958EA3000E1D17 /* wuff_convert.c in Sources */, + FAF140941E20934C00F898D2 /* PpScanner.cpp in Sources */, + FA9D53AD1F5307E900125C6B /* Deprecations.cpp in Sources */, FA0B7E431A95902C000E1D17 /* wrap_CircleShape.cpp in Sources */, FA0B7CE61A95902C000E1D17 /* wrap_Source.cpp in Sources */, FA0B7AA21A958EA3000E1D17 /* b2PulleyJoint.cpp in Sources */, + FA9D8DDE1DEF842A002CD881 /* Drawable.cpp in Sources */, FA0B7CCE1A95902C000E1D17 /* Audio.cpp in Sources */, + FADF54031E3D77B500012CC0 /* wrap_Text.cpp in Sources */, FA0B7DCB1A95902C000E1D17 /* Keyboard.cpp in Sources */, FA0B7A901A958EA3000E1D17 /* b2FrictionJoint.cpp in Sources */, FA0B7DFB1A95902C000E1D17 /* Body.cpp in Sources */, FA0B7ED21A95902C000E1D17 /* wrap_ThreadModule.cpp in Sources */, + FADF54261E3DA5BA00012CC0 /* Mesh.cpp in Sources */, FA0B7EE01A95902D000E1D17 /* wrap_Touch.cpp in Sources */, FA0B7A3C1A958EA3000E1D17 /* b2TimeOfImpact.cpp in Sources */, + FA4F2C081DE936DD00CA37D7 /* io.c in Sources */, FA0B7CDD1A95902C000E1D17 /* Source.cpp in Sources */, FA0B7DC51A95902C000E1D17 /* wrap_JoystickModule.cpp in Sources */, FA0B7E701A95902C000E1D17 /* wrap_RopeJoint.cpp in Sources */, + FACA02FC1F5E39810084B28F /* wrap_CompressedData.cpp in Sources */, + FAF140AD1E20934C00F898D2 /* Versions.cpp in Sources */, FA0B7A7B1A958EA3000E1D17 /* b2Contact.cpp in Sources */, FA0B7A6F1A958EA3000E1D17 /* b2WorldCallbacks.cpp in Sources */, FA0B793C1A958E3B000E1D17 /* runtime.cpp in Sources */, - FA27B3C61B4985D8008A9DCE /* Video.cpp in Sources */, + FAF140DC1E20934C00F898D2 /* InitializeDll.cpp in Sources */, FA0B7DBC1A95902C000E1D17 /* Joystick.cpp in Sources */, FA0B7DAF1A95902C000E1D17 /* wrap_CompressedImageData.cpp in Sources */, FA0B7A481A958EA3000E1D17 /* b2PolygonShape.cpp in Sources */, FA0B7A991A958EA3000E1D17 /* b2MotorJoint.cpp in Sources */, - FA0B7D681A95902C000E1D17 /* wrap_ParticleSystem.cpp in Sources */, FA0B7AD51A958EA3000E1D17 /* unix.c in Sources */, FAB17BE71ABFAA9000F9BA27 /* lz4.c in Sources */, - FA0B7B1C1A958EA3000E1D17 /* usocket.c in Sources */, - FA0B7D651A95902C000E1D17 /* wrap_Mesh.cpp in Sources */, + FA4F2BE71DE6650D00CA37D7 /* Transform.cpp in Sources */, FA0B7A531A958EA3000E1D17 /* b2Math.cpp in Sources */, + FAF140A11E20934C00F898D2 /* RemoveTree.cpp in Sources */, FA0B7CDA1A95902C000E1D17 /* Pool.cpp in Sources */, FA0B7E161A95902C000E1D17 /* Joint.cpp in Sources */, FA0B7EE91A95902D000E1D17 /* wrap_Window.cpp in Sources */, + FA1583E21E196180005E603B /* wrap_Shader.cpp in Sources */, FA0B7AB91A958EA3000E1D17 /* enet.cpp in Sources */, FA0B7E281A95902C000E1D17 /* PulleyJoint.cpp in Sources */, + FA56AA391FAFF02000A43D5F /* memory.cpp in Sources */, FA0B7A4C1A958EA3000E1D17 /* b2BlockAllocator.cpp in Sources */, + FAF1409E1E20934C00F898D2 /* reflection.cpp in Sources */, + FA15DFAE1F9B8D360042AB22 /* lutf8lib.c in Sources */, + FAF1408B1E20934C00F898D2 /* Pp.cpp in Sources */, + FA76344B1E28722A0066EF9E /* StreamBuffer.cpp in Sources */, FA0B7E041A95902C000E1D17 /* Contact.cpp in Sources */, FA0B7D831A95902C000E1D17 /* CompressedImageData.cpp in Sources */, FA0B7B311A958EA3000E1D17 /* wuff.c in Sources */, FA0B7DF21A95902C000E1D17 /* wrap_Cursor.cpp in Sources */, FA0B7E011A95902C000E1D17 /* CircleShape.cpp in Sources */, FA0B7E461A95902C000E1D17 /* wrap_Contact.cpp in Sources */, - FA0B7D401A95902C000E1D17 /* Mesh.cpp in Sources */, FA0B7D161A95902C000E1D17 /* Font.cpp in Sources */, FA0B7EB61A95902C000E1D17 /* wrap_System.cpp in Sources */, FA0B7DAC1A95902C000E1D17 /* STBHandler.cpp in Sources */, + FADF53F91E3C7ACD00012CC0 /* Buffer.cpp in Sources */, FA0B79301A958E3B000E1D17 /* Module.cpp in Sources */, + FAF1409B1E20934C00F898D2 /* propagateNoContraction.cpp in Sources */, FA0B7DDA1A95902C000E1D17 /* RandomGenerator.cpp in Sources */, - FA0B7AF81A958EA3000E1D17 /* luasocket.c in Sources */, + FA2AF6751DAD64970032B62C /* vertex.cpp in Sources */, + FAF140561E20934C00F898D2 /* Link.cpp in Sources */, + FAF140851E20934C00F898D2 /* ParseHelper.cpp in Sources */, FA0B7D801A95902C000E1D17 /* Volatile.cpp in Sources */, FA0B792D1A958E3B000E1D17 /* Memoizer.cpp in Sources */, + FA1BA0B21E16FD0800AA2803 /* Shader.cpp in Sources */, FA0B7EBC1A95902C000E1D17 /* LuaThread.cpp in Sources */, FA0B7A871A958EA3000E1D17 /* b2PolygonAndCircleContact.cpp in Sources */, FA0B7EF21A959D2C000E1D17 /* ios.mm in Sources */, FA0B7D3A1A95902C000E1D17 /* Graphics.cpp in Sources */, + FA4F2BB21DE1E4B400CA37D7 /* RecordingDevice.cpp in Sources */, FA0B7A2D1A958EA3000E1D17 /* b2CollideCircle.cpp in Sources */, + FA4F2C0F1DE936FE00CA37D7 /* timeout.c in Sources */, FA59A2D31C06481400328DBA /* ParticleSystem.cpp in Sources */, FA0B7E131A95902C000E1D17 /* GearJoint.cpp in Sources */, FA0B7DC21A95902C000E1D17 /* wrap_Joystick.cpp in Sources */, FA0B7CD41A95902C000E1D17 /* Source.cpp in Sources */, - FA0B7AEF1A958EA3000E1D17 /* inet.c in Sources */, FAA3A9AF1B7D465A00CED060 /* android.cpp in Sources */, FA0B7CD11A95902C000E1D17 /* Audio.cpp in Sources */, + FA4F2B7B1DE0181B00CA37D7 /* xxhash.c in Sources */, FA0B7D131A95902C000E1D17 /* Font.cpp in Sources */, FA0B7EC91A95902C000E1D17 /* threads.cpp in Sources */, FA0B7A781A958EA3000E1D17 /* b2CircleContact.cpp in Sources */, - FA0B7D5F1A95902C000E1D17 /* wrap_Graphics.cpp in Sources */, + FAF1408D1E20934C00F898D2 /* PpAtom.cpp in Sources */, FA0B7A9C1A958EA3000E1D17 /* b2MouseJoint.cpp in Sources */, + FAF140721E20934C00F898D2 /* Intermediate.cpp in Sources */, FA41A3C91C0A1F950084430C /* ASTCHandler.cpp in Sources */, FA0B7E551A95902C000E1D17 /* wrap_GearJoint.cpp in Sources */, FA0B7E791A95902C000E1D17 /* wrap_WheelJoint.cpp in Sources */, FA0B7DDD1A95902C000E1D17 /* wrap_BezierCurve.cpp in Sources */, FA0B7A2A1A958EA3000E1D17 /* b2BroadPhase.cpp in Sources */, FA0B7A811A958EA3000E1D17 /* b2EdgeAndCircleContact.cpp in Sources */, + FAF188A01E9DBC4B008C1479 /* depthstencil.cpp in Sources */, FA0B7D071A95902C000E1D17 /* wrap_File.cpp in Sources */, + FA6A2B751F60B6710074C308 /* ByteData.cpp in Sources */, + FAD19A181DFF8CA200D5398A /* ImageDataBase.cpp in Sources */, FA0B7AD01A958EA3000E1D17 /* peer.c in Sources */, FA27B3C11B4985BF008A9DCE /* wrap_VideoStream.cpp in Sources */, + FADF54211E3DA52C00012CC0 /* wrap_ParticleSystem.cpp in Sources */, FA0B791C1A958E3B000E1D17 /* b64.cpp in Sources */, - FA0B7D941A95902C000E1D17 /* Image.cpp in Sources */, + FA1E88851DF363E100E808AA /* Filter.cpp in Sources */, FA0B7DA01A95902C000E1D17 /* KTXHandler.cpp in Sources */, - FA27B3A11B498151008A9DCE /* VideoStream.cpp in Sources */, FA0B7A5C1A958EA3000E1D17 /* b2Timer.cpp in Sources */, FA0B7CEC1A95902C000E1D17 /* Event.cpp in Sources */, FA27B3AB1B498151008A9DCE /* VideoStream.cpp in Sources */, FA0B7A7E1A958EA3000E1D17 /* b2ContactSolver.cpp in Sources */, - FA0B7D971A95902C000E1D17 /* ImageData.cpp in Sources */, FA0B7E581A95902C000E1D17 /* wrap_Joint.cpp in Sources */, + FAECA1B51F31648A0095D008 /* FormatHandler.cpp in Sources */, + FA4F2C0A1DE936E600CA37D7 /* mime.c in Sources */, FA0B7E311A95902C000E1D17 /* Shape.cpp in Sources */, FA0B7E491A95902C000E1D17 /* wrap_DistanceJoint.cpp in Sources */, FA0B7A391A958EA3000E1D17 /* b2DynamicTree.cpp in Sources */, + FA4F2C101DE936FE00CA37D7 /* udp.c in Sources */, FA0B7A681A958EA3000E1D17 /* b2Island.cpp in Sources */, FA0B7E2B1A95902C000E1D17 /* RevoluteJoint.cpp in Sources */, FA0B7B291A958EA3000E1D17 /* simplexnoise1234.cpp in Sources */, FA0B7D261A95902C000E1D17 /* wrap_Font.cpp in Sources */, + FA4F2BB31DE1E4B800CA37D7 /* RecordingDevice.cpp in Sources */, + FA4F2C071DE936DA00CA37D7 /* inet.c in Sources */, + FA4F2C0B1DE936EA00CA37D7 /* options.c in Sources */, + FA4F2C0D1DE936F100CA37D7 /* serial.c in Sources */, FA0B7E0A1A95902C000E1D17 /* EdgeShape.cpp in Sources */, - FAB17BF11ABFB37500F9BA27 /* wrap_CompressedData.cpp in Sources */, + FADF54301E3DABF600012CC0 /* SpriteBatch.cpp in Sources */, FA0B7CF81A95902C000E1D17 /* FileData.cpp in Sources */, FA0B7DA61A95902C000E1D17 /* PNGHandler.cpp in Sources */, - FA0B7B041A958EA3000E1D17 /* select.c in Sources */, FA0B7E981A95902C000E1D17 /* Sound.cpp in Sources */, FA0B7E371A95902C000E1D17 /* WheelJoint.cpp in Sources */, FA0B7A8A1A958EA3000E1D17 /* b2PolygonContact.cpp in Sources */, + FA4F2C0C1DE936ED00CA37D7 /* select.c in Sources */, FA0B7D8E1A95902C000E1D17 /* ddsHandler.cpp in Sources */, FA0B7DFE1A95902C000E1D17 /* ChainShape.cpp in Sources */, FA0B7A451A958EA3000E1D17 /* b2EdgeShape.cpp in Sources */, - FA0B7D621A95902C000E1D17 /* wrap_Image.cpp in Sources */, + FA15DFB21F9B8D840042AB22 /* TheoraVideoStream.cpp in Sources */, + FAF1406D1E20934C00F898D2 /* InfoSink.cpp in Sources */, + FAF1407B1E20934C00F898D2 /* limits.cpp in Sources */, FA0B7ABB1A958EA3000E1D17 /* callbacks.c in Sources */, FA0B7A721A958EA3000E1D17 /* b2ChainAndCircleContact.cpp in Sources */, FA0B7EAA1A95902C000E1D17 /* wrap_Sound.cpp in Sources */, FA0B79391A958E3B000E1D17 /* Reference.cpp in Sources */, FA620A331AA2F8DB005DB4C2 /* wrap_Quad.cpp in Sources */, FA0B7E071A95902C000E1D17 /* DistanceJoint.cpp in Sources */, + FADF543C1E3DAFF700012CC0 /* wrap_Graphics.cpp in Sources */, FA0B7A331A958EA3000E1D17 /* b2Collision.cpp in Sources */, FA0B7E5E1A95902C000E1D17 /* wrap_MouseJoint.cpp in Sources */, FA0B7B3B1A958EA3000E1D17 /* wuff_memory.c in Sources */, FA0B79411A958E3B000E1D17 /* utf8.cpp in Sources */, - FAB17BE11ABFAA2000F9BA27 /* Compressor.cpp in Sources */, FA0B7ADF1A958EA3000E1D17 /* lodepng.cpp in Sources */, - FA0B7D711A95902C000E1D17 /* wrap_SpriteBatch.cpp in Sources */, FA0B7D341A95902C000E1D17 /* Canvas.cpp in Sources */, + FAF140761E20934C00F898D2 /* IntermTraverse.cpp in Sources */, FA0B7E8C1A95902C000E1D17 /* FLACDecoder.cpp in Sources */, FA0B7A421A958EA3000E1D17 /* b2CircleShape.cpp in Sources */, - FA0B7B141A958EA3000E1D17 /* udp.c in Sources */, FA0B7D491A95902C000E1D17 /* Polyline.cpp in Sources */, FA0B7CE31A95902C000E1D17 /* wrap_Audio.cpp in Sources */, FA0B7B381A958EA3000E1D17 /* wuff_internal.c in Sources */, FA0B7DF81A95902C000E1D17 /* Body.cpp in Sources */, + FA4F2BB41DE1E4BD00CA37D7 /* RecordingDevice.cpp in Sources */, FA0B7DF51A95902C000E1D17 /* wrap_Mouse.cpp in Sources */, - FA0B7D6E1A95902C000E1D17 /* wrap_Shader.cpp in Sources */, FA0B7E861A95902C000E1D17 /* CoreAudioDecoder.cpp in Sources */, FA0B7E761A95902C000E1D17 /* wrap_WeldJoint.cpp in Sources */, - FA0B7D561A95902C000E1D17 /* GLBuffer.cpp in Sources */, + FA0B7D561A95902C000E1D17 /* Buffer.cpp in Sources */, FA0B7A6C1A958EA3000E1D17 /* b2World.cpp in Sources */, + FA1557C51CE90BD900AFF582 /* EXRHandler.cpp in Sources */, FA57FB991AE1993600F2AD6D /* noise1234.cpp in Sources */, FA0B7E221A95902C000E1D17 /* PolygonShape.cpp in Sources */, FA0B7A651A958EA3000E1D17 /* b2Fixture.cpp in Sources */, - FA0B7D521A95902C000E1D17 /* Text.cpp in Sources */, + FA28EBD61E352DB5003446F4 /* FenceSync.cpp in Sources */, FA0B7DA31A95902C000E1D17 /* PKMHandler.cpp in Sources */, FA0B7AB21A958EA3000E1D17 /* b2Rope.cpp in Sources */, FAB17BF61ABFC4B100F9BA27 /* lz4hc.c in Sources */, + FAF1408F1E20934C00F898D2 /* PpContext.cpp in Sources */, FA0B7EA71A95902C000E1D17 /* wrap_Decoder.cpp in Sources */, FA0B7E1C1A95902C000E1D17 /* MouseJoint.cpp in Sources */, + FA29C0061E12355B00268CD8 /* StreamBuffer.cpp in Sources */, FA0B7CF51A95902C000E1D17 /* File.cpp in Sources */, FA0B7E341A95902C000E1D17 /* WeldJoint.cpp in Sources */, - FA0B7D5C1A95902C000E1D17 /* wrap_Font.cpp in Sources */, + FA4F2C091DE936E200CA37D7 /* luasocket.c in Sources */, + FA9D8DD21DEB56C3002CD881 /* pixelformat.cpp in Sources */, FA0B7B221A958EA3000E1D17 /* luasocket.cpp in Sources */, FA0B7D311A95902C000E1D17 /* Graphics.cpp in Sources */, FA0B7E9E1A95902C000E1D17 /* WaveDecoder.cpp in Sources */, FA0B7EB31A95902C000E1D17 /* System.cpp in Sources */, FA0B7D1C1A95902C000E1D17 /* GlyphData.cpp in Sources */, + FA4F2C061DE936CD00CA37D7 /* except.c in Sources */, FA0B7AAE1A958EA3000E1D17 /* b2WheelJoint.cpp in Sources */, + FA15DFB01F9B8D6A0042AB22 /* wrap_Data.cpp in Sources */, FA0B7E671A95902C000E1D17 /* wrap_PrismaticJoint.cpp in Sources */, FA0B7DCE1A95902C000E1D17 /* wrap_Keyboard.cpp in Sources */, FA0B7EE61A95902D000E1D17 /* Window.cpp in Sources */, FA0B7E3A1A95902C000E1D17 /* World.cpp in Sources */, FA0B79471A958E3B000E1D17 /* Vector.cpp in Sources */, - FA0B7B001A958EA3000E1D17 /* options.c in Sources */, + FAC756F71E4F99BC00B91289 /* Effect.cpp in Sources */, FA0B7E7F1A95902C000E1D17 /* Joint.cpp in Sources */, - FA0B7AE81A958EA3000E1D17 /* except.c in Sources */, FA0B7DB21A95902C000E1D17 /* wrap_Image.cpp in Sources */, FA0B7E891A95902C000E1D17 /* Decoder.cpp in Sources */, FA0B7A591A958EA3000E1D17 /* b2StackAllocator.cpp in Sources */, + FAECA1B31F3164700095D008 /* CompressedSlice.cpp in Sources */, FA0B7E3D1A95902C000E1D17 /* wrap_Body.cpp in Sources */, FA0B7D7A1A95902C000E1D17 /* Quad.cpp in Sources */, FA620A3B1AA305F6005DB4C2 /* types.cpp in Sources */, FA0B7DD41A95902C000E1D17 /* BezierCurve.cpp in Sources */, FA0B7E7C1A95902C000E1D17 /* wrap_World.cpp in Sources */, - FA0B7B0C1A958EA3000E1D17 /* tcp.c in Sources */, - FA0B7D911A95902C000E1D17 /* FormatHandler.cpp in Sources */, + FA4F2C0E1DE936FE00CA37D7 /* tcp.c in Sources */, FA0B7D431A95902C000E1D17 /* OpenGL.cpp in Sources */, - FA0B7AF21A958EA3000E1D17 /* io.c in Sources */, FA0B7DBF1A95902C000E1D17 /* JoystickModule.cpp in Sources */, - FA0B7D4F1A95902C000E1D17 /* SpriteBatch.cpp in Sources */, FAB2D5AB1AABDD8A008224A4 /* TrueTypeRasterizer.cpp in Sources */, FA0B7A9F1A958EA3000E1D17 /* b2PrismaticJoint.cpp in Sources */, + FA1BA0AD1E16F9EE00AA2803 /* wrap_Canvas.cpp in Sources */, FA0B79331A958E3B000E1D17 /* Object.cpp in Sources */, FA0B7E5B1A95902C000E1D17 /* wrap_MotorJoint.cpp in Sources */, FA0B79441A958E3B000E1D17 /* Variant.cpp in Sources */, + FA9D8DDA1DEF8411002CD881 /* Stream.cpp in Sources */, FA0B7DD71A95902C000E1D17 /* MathModule.cpp in Sources */, + FAC756FC1E4F99DB00B91289 /* Effect.cpp in Sources */, FA0B7D101A95902C000E1D17 /* BMFontRasterizer.cpp in Sources */, FA0B7E9B1A95902C000E1D17 /* VorbisDecoder.cpp in Sources */, FA0B7E4C1A95902C000E1D17 /* wrap_EdgeShape.cpp in Sources */, FA0B7E251A95902C000E1D17 /* PrismaticJoint.cpp in Sources */, FA0B7A561A958EA3000E1D17 /* b2Settings.cpp in Sources */, FA0B7E611A95902C000E1D17 /* wrap_Physics.cpp in Sources */, + FA4F2C041DE936C600CA37D7 /* buffer.c in Sources */, FA0B7DC81A95902C000E1D17 /* Keyboard.cpp in Sources */, FA0B7EAD1A95902C000E1D17 /* wrap_SoundData.cpp in Sources */, FA0B7E2E1A95902C000E1D17 /* RopeJoint.cpp in Sources */, FA0B7CE01A95902C000E1D17 /* Source.cpp in Sources */, + FADF54171E3DA08E00012CC0 /* Image.cpp in Sources */, FA0B7ECF1A95902C000E1D17 /* wrap_LuaThread.cpp in Sources */, + FA1BA0A81E16F20600AA2803 /* Canvas.cpp in Sources */, FA0B7AA51A958EA3000E1D17 /* b2RevoluteJoint.cpp in Sources */, FA0B7EA11A95902C000E1D17 /* Sound.cpp in Sources */, FA0B7DE61A95902C000E1D17 /* Cursor.cpp in Sources */, + FA6A2B711F5F845F0074C308 /* wrap_DataView.cpp in Sources */, FA0B7EDC1A95902D000E1D17 /* Touch.cpp in Sources */, FA0B7CE91A95902C000E1D17 /* Event.cpp in Sources */, + FA4F2C131DE936FE00CA37D7 /* unixudp.c in Sources */, + FA9D8DE11DEF843D002CD881 /* Image.cpp in Sources */, FA0B7A961A958EA3000E1D17 /* b2Joint.cpp in Sources */, FA0B7A621A958EA3000E1D17 /* b2ContactManager.cpp in Sources */, + FA15DFAD1F9B8CBA0042AB22 /* StringMap.cpp in Sources */, FA0B7A2F1A958EA3000E1D17 /* b2CollideEdge.cpp in Sources */, + FACA02F81F5E39760084B28F /* CompressedData.cpp in Sources */, FA0B7ADA1A958EA3000E1D17 /* glad.cpp in Sources */, + FAF140541E20934C00F898D2 /* CodeGen.cpp in Sources */, FA0B7E1F1A95902C000E1D17 /* Physics.cpp in Sources */, + FA6A2B7B1F60B8250074C308 /* wrap_ByteData.cpp in Sources */, FA0B7E821A95902C000E1D17 /* Shape.cpp in Sources */, FA0B7ACE1A958EA3000E1D17 /* packet.c in Sources */, - FA0B7ED51A95902D000E1D17 /* Timer.cpp in Sources */, - FA19C4C61B4B0BD50059B0B3 /* wrap_Video.cpp in Sources */, + FAF140891E20934C00F898D2 /* PoolAlloc.cpp in Sources */, FA27B3B41B498151008A9DCE /* wrap_Video.cpp in Sources */, + FA1E88801DF363D400E808AA /* Filter.cpp in Sources */, FA0B7AA81A958EA3000E1D17 /* b2RopeJoint.cpp in Sources */, FA0B7ACC1A958EA3000E1D17 /* list.c in Sources */, + FACA02FD1F5E39840084B28F /* wrap_DataModule.cpp in Sources */, FA0B7DEF1A95902C000E1D17 /* Mouse.cpp in Sources */, FA0B79251A958E3B000E1D17 /* Exception.cpp in Sources */, FA0B7D291A95902C000E1D17 /* wrap_GlyphData.cpp in Sources */, FA0B7DE31A95902C000E1D17 /* wrap_RandomGenerator.cpp in Sources */, FA0B7AD71A958EA3000E1D17 /* win32.c in Sources */, - FA0B7AE51A958EA3000E1D17 /* buffer.c in Sources */, + FA15DFB11F9B8D820042AB22 /* OggDemuxer.cpp in Sources */, FA0B7D0D1A95902C000E1D17 /* wrap_Filesystem.cpp in Sources */, FA0B79211A958E3B000E1D17 /* delay.cpp in Sources */, FA0B7DB51A95902C000E1D17 /* wrap_ImageData.cpp in Sources */, @@ -3613,14 +4518,18 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - FA0B7D731A95902C000E1D17 /* wrap_Text.cpp in Sources */, + 217DFBDD1D9F6D490055D849 /* compat.c in Sources */, FA0B7DDF1A95902C000E1D17 /* wrap_Math.cpp in Sources */, FA0B7DA81A95902C000E1D17 /* PVRHandler.cpp in Sources */, FA0B7EC51A95902C000E1D17 /* ThreadModule.cpp in Sources */, + FADF54071E3D78F700012CC0 /* Video.cpp in Sources */, + 217DFC031D9F6D490055D849 /* timeout.c in Sources */, + FA9D8DD71DEF8411002CD881 /* Data.cpp in Sources */, + FADF542A1E3DAADA00012CC0 /* wrap_Mesh.cpp in Sources */, FA0B7D2B1A95902C000E1D17 /* wrap_Rasterizer.cpp in Sources */, - FA0B7D581A95902C000E1D17 /* wrap_Canvas.cpp in Sources */, FA0B7E8E1A95902C000E1D17 /* GmeDecoder.cpp in Sources */, FA0B7CD61A95902C000E1D17 /* Audio.cpp in Sources */, + FA3C5E421F8C368C0003C579 /* ShaderStage.cpp in Sources */, FA0B7A9E1A958EA3000E1D17 /* b2PrismaticJoint.cpp in Sources */, FA0B7EAF1A95902C000E1D17 /* System.cpp in Sources */, FA0B7EE21A95902D000E1D17 /* Window.cpp in Sources */, @@ -3628,115 +4537,169 @@ FA0B7EC11A95902C000E1D17 /* threads.cpp in Sources */, FA0B79321A958E3B000E1D17 /* Object.cpp in Sources */, FA0B7D001A95902C000E1D17 /* Filesystem.cpp in Sources */, + FAF140641E20934C00F898D2 /* Constant.cpp in Sources */, FA0B7ED81A95902D000E1D17 /* wrap_Timer.cpp in Sources */, + FAF1407C1E20934C00F898D2 /* linkValidate.cpp in Sources */, FA0B7DD01A95902C000E1D17 /* love.cpp in Sources */, FA0B7A521A958EA3000E1D17 /* b2Math.cpp in Sources */, FA0B7D211A95902C000E1D17 /* Rasterizer.cpp in Sources */, - FA0B7B131A958EA3000E1D17 /* udp.c in Sources */, + FAC7CD7C1FE35E95006A60C7 /* physfs_archiver_slb.c in Sources */, + FAC7CD931FE35E95006A60C7 /* physfs_archiver_zip.c in Sources */, FA0B7D7C1A95902C000E1D17 /* Texture.cpp in Sources */, + FAF140BB1E20934C00F898D2 /* ossource.cpp in Sources */, FA0B7ECB1A95902C000E1D17 /* wrap_Channel.cpp in Sources */, + FACA02F21F5E396B0084B28F /* HashFunction.cpp in Sources */, + FAF140A71E20934C00F898D2 /* ShaderLang.cpp in Sources */, + FA1BA09D1E16CFCE00AA2803 /* Font.cpp in Sources */, FA0B7E6C1A95902C000E1D17 /* wrap_RevoluteJoint.cpp in Sources */, - FA0B7AFA1A958EA3000E1D17 /* mime.c in Sources */, FA0B7A5E1A958EA3000E1D17 /* b2Body.cpp in Sources */, - FA0B7B0E1A958EA3000E1D17 /* timeout.c in Sources */, FA0B7E631A95902C000E1D17 /* wrap_PolygonShape.cpp in Sources */, + FADF541B1E3DA46C00012CC0 /* wrap_Image.cpp in Sources */, + FAC7CD7B1FE35E95006A60C7 /* physfs_platform_unix.c in Sources */, + FACA02F01F5E396B0084B28F /* DataModule.cpp in Sources */, FA0B7E721A95902C000E1D17 /* wrap_Shape.cpp in Sources */, FA0B7CFD1A95902C000E1D17 /* File.cpp in Sources */, + FA4F2BB01DE1E37B00CA37D7 /* RecordingDevice.cpp in Sources */, + FAC7CD911FE35E95006A60C7 /* physfs_archiver_grp.c in Sources */, FA27B39D1B498151008A9DCE /* Video.cpp in Sources */, + FA15DFAC1F9B8C850042AB22 /* StringMap.cpp in Sources */, + FA4F2BAC1DE1E37000CA37D7 /* RecordingDevice.cpp in Sources */, FA0B7A2E1A958EA3000E1D17 /* b2CollideEdge.cpp in Sources */, FA0B7E691A95902C000E1D17 /* wrap_PulleyJoint.cpp in Sources */, FA0B7DB71A95902C000E1D17 /* Joystick.cpp in Sources */, FA0B7A321A958EA3000E1D17 /* b2Collision.cpp in Sources */, - FAB17BEB1ABFAF1800F9BA27 /* CompressedData.cpp in Sources */, - FA0B7D361A95902C000E1D17 /* Font.cpp in Sources */, + FA91DA8B1F377C3900C80E33 /* deprecation.cpp in Sources */, FA0B7E3F1A95902C000E1D17 /* wrap_ChainShape.cpp in Sources */, FA0B7DEB1A95902C000E1D17 /* Cursor.cpp in Sources */, FA0B7D861A95902C000E1D17 /* ImageData.cpp in Sources */, FA0B7A3E1A958EA3000E1D17 /* b2ChainShape.cpp in Sources */, + FAF140731E20934C00F898D2 /* intermOut.cpp in Sources */, FA0B7E0F1A95902C000E1D17 /* FrictionJoint.cpp in Sources */, FA620A351AA2F8DB005DB4C2 /* wrap_Texture.cpp in Sources */, + FAF140771E20934C00F898D2 /* iomapper.cpp in Sources */, FA0B7D091A95902C000E1D17 /* wrap_FileData.cpp in Sources */, FA0B7B341A958EA3000E1D17 /* wuff_convert.c in Sources */, FA0B7CF11A95902C000E1D17 /* DroppedFile.cpp in Sources */, - FA0B7D891A95902C000E1D17 /* CompressedImageData.cpp in Sources */, - FA0B7B031A958EA3000E1D17 /* select.c in Sources */, + FAF140821E20934C00F898D2 /* ParseContextBase.cpp in Sources */, FA0B7D1E1A95902C000E1D17 /* ImageRasterizer.cpp in Sources */, + FAF140A31E20934C00F898D2 /* Scan.cpp in Sources */, FA0B7EA31A95902C000E1D17 /* SoundData.cpp in Sources */, FA0B7D031A95902C000E1D17 /* wrap_DroppedFile.cpp in Sources */, FA0B79291A958E3B000E1D17 /* Matrix.cpp in Sources */, - FA0B7D451A95902C000E1D17 /* ParticleSystem.cpp in Sources */, FA8951A21AA2EDF300EC385A /* wrap_Event.cpp in Sources */, + FAF140691E20934C00F898D2 /* glslang_tab.cpp in Sources */, FA0B7ABF1A958EA3000E1D17 /* host.c in Sources */, FA0B7D4B1A95902C000E1D17 /* Shader.cpp in Sources */, + FADF540D1E3D7CDD00012CC0 /* wrap_Video.cpp in Sources */, FA0B7A581A958EA3000E1D17 /* b2StackAllocator.cpp in Sources */, FA0B7A301A958EA3000E1D17 /* b2CollidePolygon.cpp in Sources */, FA0B7A641A958EA3000E1D17 /* b2Fixture.cpp in Sources */, + FAF140971E20934C00F898D2 /* PpTokens.cpp in Sources */, + FAF140A91E20934C00F898D2 /* SymbolTable.cpp in Sources */, FA0B7E181A95902C000E1D17 /* MotorJoint.cpp in Sources */, FA0B7E4E1A95902C000E1D17 /* wrap_Fixture.cpp in Sources */, FA0B7EBE1A95902C000E1D17 /* Thread.cpp in Sources */, + FAC7CD8F1FE35E95006A60C7 /* physfs_platform_posix.c in Sources */, + FAF1406E1E20934C00F898D2 /* Initialize.cpp in Sources */, FA0B7EB81A95902C000E1D17 /* Channel.cpp in Sources */, + 217DFC091D9F6D490055D849 /* unix.c in Sources */, + FACA02EE1F5E396B0084B28F /* Compressor.cpp in Sources */, + FAF140801E20934C00F898D2 /* parseConst.cpp in Sources */, FA0B7AB11A958EA3000E1D17 /* b2Rope.cpp in Sources */, FA4B66C91ABBCF1900558F15 /* Timer.cpp in Sources */, FA0B7A351A958EA3000E1D17 /* b2Distance.cpp in Sources */, FA0B7E911A95902C000E1D17 /* ModPlugDecoder.cpp in Sources */, FA0B7E511A95902C000E1D17 /* wrap_FrictionJoint.cpp in Sources */, FA0B7AD61A958EA3000E1D17 /* win32.c in Sources */, - FA0B7B161A958EA3000E1D17 /* unix.c in Sources */, + FADF54341E3DAE6E00012CC0 /* wrap_SpriteBatch.cpp in Sources */, FA0B7E0C1A95902C000E1D17 /* Fixture.cpp in Sources */, FA0B7D181A95902C000E1D17 /* TrueTypeRasterizer.cpp in Sources */, FA0B7CFA1A95902C000E1D17 /* Filesystem.cpp in Sources */, + FA1BA0A21E16D97500AA2803 /* wrap_Font.cpp in Sources */, + FAC7CD781FE35E95006A60C7 /* physfs_platform_qnx.c in Sources */, FA0B7D3C1A95902C000E1D17 /* Image.cpp in Sources */, FA0B7A8C1A958EA3000E1D17 /* b2DistanceJoint.cpp in Sources */, + FADF53FD1E3D74F200012CC0 /* Text.cpp in Sources */, + FA6A2B741F60B6710074C308 /* ByteData.cpp in Sources */, + 217DFBE91D9F6D490055D849 /* io.c in Sources */, FA0B7E421A95902C000E1D17 /* wrap_CircleShape.cpp in Sources */, FA0B7CE51A95902C000E1D17 /* wrap_Source.cpp in Sources */, + FAC7CD921FE35E95006A60C7 /* physfs_archiver_hog.c in Sources */, FA0B792C1A958E3B000E1D17 /* Memoizer.cpp in Sources */, + FAF140931E20934C00F898D2 /* PpScanner.cpp in Sources */, + FA9D53AC1F5307E900125C6B /* Deprecations.cpp in Sources */, FA0B7CCD1A95902C000E1D17 /* Audio.cpp in Sources */, FA0B7DCA1A95902C000E1D17 /* Keyboard.cpp in Sources */, FA0B7AA41A958EA3000E1D17 /* b2RevoluteJoint.cpp in Sources */, + FA9D8DDD1DEF842A002CD881 /* Drawable.cpp in Sources */, FA0B7DFA1A95902C000E1D17 /* Body.cpp in Sources */, + FADF54021E3D77B500012CC0 /* wrap_Text.cpp in Sources */, FA0B7ED11A95902C000E1D17 /* wrap_ThreadModule.cpp in Sources */, + FAC7CD7F1FE35E95006A60C7 /* physfs_archiver_wad.c in Sources */, FA0B7EDF1A95902D000E1D17 /* wrap_Touch.cpp in Sources */, - FA0B794A1A958E3B000E1D17 /* wrap_Data.cpp in Sources */, + 217DFBFB1D9F6D490055D849 /* serial.c in Sources */, + FADF54251E3DA5BA00012CC0 /* Mesh.cpp in Sources */, + FA4F2BE51DE6650600CA37D7 /* wrap_Transform.cpp in Sources */, + 217DFC0D1D9F6D490055D849 /* unixudp.c in Sources */, FA0B7CDC1A95902C000E1D17 /* Source.cpp in Sources */, FA0B7DC41A95902C000E1D17 /* wrap_JoystickModule.cpp in Sources */, FA0B7E6F1A95902C000E1D17 /* wrap_RopeJoint.cpp in Sources */, FA0B7AB51A958EA3000E1D17 /* ddsparse.cpp in Sources */, + FACA02F41F5E396B0084B28F /* wrap_CompressedData.cpp in Sources */, + FAF140AC1E20934C00F898D2 /* Versions.cpp in Sources */, FA0B7A441A958EA3000E1D17 /* b2EdgeShape.cpp in Sources */, FA0B79461A958E3B000E1D17 /* Vector.cpp in Sources */, - FA27B3C51B4985D8008A9DCE /* Video.cpp in Sources */, + FAC7CD811FE35E95006A60C7 /* physfs_platform_os2.c in Sources */, FA0B7DBB1A95902C000E1D17 /* Joystick.cpp in Sources */, + FAF140DB1E20934C00F898D2 /* InitializeDll.cpp in Sources */, FA0B7DAE1A95902C000E1D17 /* wrap_CompressedImageData.cpp in Sources */, + FA6A2B701F5F845F0074C308 /* wrap_DataView.cpp in Sources */, FA0B7A6E1A958EA3000E1D17 /* b2WorldCallbacks.cpp in Sources */, FA0B7A831A958EA3000E1D17 /* b2EdgeAndPolygonContact.cpp in Sources */, - FA0B7D671A95902C000E1D17 /* wrap_ParticleSystem.cpp in Sources */, FA0B7AA11A958EA3000E1D17 /* b2PulleyJoint.cpp in Sources */, FAB17BE61ABFAA9000F9BA27 /* lz4.c in Sources */, FA0B7B211A958EA3000E1D17 /* luasocket.cpp in Sources */, - FA0B7D641A95902C000E1D17 /* wrap_Mesh.cpp in Sources */, FA0B7A5B1A958EA3000E1D17 /* b2Timer.cpp in Sources */, FA0B7CD91A95902C000E1D17 /* Pool.cpp in Sources */, + FAF140A01E20934C00F898D2 /* RemoveTree.cpp in Sources */, FA0B7E151A95902C000E1D17 /* Joint.cpp in Sources */, FA0B7EE81A95902D000E1D17 /* wrap_Window.cpp in Sources */, - FA0B7AF11A958EA3000E1D17 /* io.c in Sources */, FA0B7E271A95902C000E1D17 /* PulleyJoint.cpp in Sources */, + FA1BA0B71E17043400AA2803 /* wrap_Shader.cpp in Sources */, FA0B7B301A958EA3000E1D17 /* wuff.c in Sources */, + FA56AA381FAFF02000A43D5F /* memory.cpp in Sources */, FA0B7E031A95902C000E1D17 /* Contact.cpp in Sources */, FA0B7D821A95902C000E1D17 /* CompressedImageData.cpp in Sources */, + FAF1409D1E20934C00F898D2 /* reflection.cpp in Sources */, + FAAA3FDB1F64B3AD00F89E99 /* lutf8lib.c in Sources */, + FAF1408A1E20934C00F898D2 /* Pp.cpp in Sources */, + FA76344A1E28722A0066EF9E /* StreamBuffer.cpp in Sources */, FA0B7A7A1A958EA3000E1D17 /* b2Contact.cpp in Sources */, FA0B7DF11A95902C000E1D17 /* wrap_Cursor.cpp in Sources */, FA0B7E001A95902C000E1D17 /* CircleShape.cpp in Sources */, FA0B7E451A95902C000E1D17 /* wrap_Contact.cpp in Sources */, - FA0B7D3F1A95902C000E1D17 /* Mesh.cpp in Sources */, + 217DFBE71D9F6D490055D849 /* inet.c in Sources */, FA0B7D151A95902C000E1D17 /* Font.cpp in Sources */, FA0B7EB51A95902C000E1D17 /* wrap_System.cpp in Sources */, FA0B7DAB1A95902C000E1D17 /* STBHandler.cpp in Sources */, FA0B7AB81A958EA3000E1D17 /* enet.cpp in Sources */, + FADF53F81E3C7ACD00012CC0 /* Buffer.cpp in Sources */, FA0B7DD91A95902C000E1D17 /* RandomGenerator.cpp in Sources */, + FAF1409A1E20934C00F898D2 /* propagateNoContraction.cpp in Sources */, FA0B7A9B1A958EA3000E1D17 /* b2MouseJoint.cpp in Sources */, + FA2AF6741DAD64970032B62C /* vertex.cpp in Sources */, + FAC7CD851FE35E95006A60C7 /* physfs_unicode.c in Sources */, + FA6A2B7A1F60B8250074C308 /* wrap_ByteData.cpp in Sources */, + FAF140551E20934C00F898D2 /* Link.cpp in Sources */, + FAF140841E20934C00F898D2 /* ParseHelper.cpp in Sources */, FA0B7D7F1A95902C000E1D17 /* Volatile.cpp in Sources */, FA0B7A3B1A958EA3000E1D17 /* b2TimeOfImpact.cpp in Sources */, + FA1BA0B11E16FD0800AA2803 /* Shader.cpp in Sources */, + 217DFBED1D9F6D490055D849 /* luasocket.c in Sources */, + 217DFC011D9F6D490055D849 /* tcp.c in Sources */, FA0B7EBB1A95902C000E1D17 /* LuaThread.cpp in Sources */, FA0B79381A958E3B000E1D17 /* Reference.cpp in Sources */, + FAC7CD881FE35E95006A60C7 /* physfs_platform_apple.m in Sources */, FA0B7D391A95902C000E1D17 /* Graphics.cpp in Sources */, FA0B79361A958E3B000E1D17 /* macosx.mm in Sources */, FA0B7E121A95902C000E1D17 /* GearJoint.cpp in Sources */, @@ -3748,29 +4711,34 @@ FAA3A9AE1B7D465A00CED060 /* android.cpp in Sources */, FA0B7D121A95902C000E1D17 /* Font.cpp in Sources */, FA0B7EC81A95902C000E1D17 /* threads.cpp in Sources */, + FAC7CD8B1FE35E95006A60C7 /* physfs_archiver_iso9660.c in Sources */, + 217DFBF91D9F6D490055D849 /* select.c in Sources */, FA0B7A6B1A958EA3000E1D17 /* b2World.cpp in Sources */, - FA0B7D5E1A95902C000E1D17 /* wrap_Graphics.cpp in Sources */, + FAF1408C1E20934C00F898D2 /* PpAtom.cpp in Sources */, FA0B7A801A958EA3000E1D17 /* b2EdgeAndCircleContact.cpp in Sources */, + FAF140711E20934C00F898D2 /* Intermediate.cpp in Sources */, + FAC7CD7D1FE35E95006A60C7 /* physfs_platform_winrt.cpp in Sources */, FA0B7E541A95902C000E1D17 /* wrap_GearJoint.cpp in Sources */, FA41A3C81C0A1F950084430C /* ASTCHandler.cpp in Sources */, FA0B7E781A95902C000E1D17 /* wrap_WheelJoint.cpp in Sources */, FA0B7DDC1A95902C000E1D17 /* wrap_BezierCurve.cpp in Sources */, - FA0B7AF71A958EA3000E1D17 /* luasocket.c in Sources */, FA0B7A951A958EA3000E1D17 /* b2Joint.cpp in Sources */, FA0B7D061A95902C000E1D17 /* wrap_File.cpp in Sources */, + FAF1889F1E9DBC4B008C1479 /* depthstencil.cpp in Sources */, + FAC7CD871FE35E95006A60C7 /* physfs_archiver_vdf.c in Sources */, FA0B7A4E1A958EA3000E1D17 /* b2Draw.cpp in Sources */, - FA0B7AEE1A958EA3000E1D17 /* inet.c in Sources */, + FAD19A171DFF8CA200D5398A /* ImageDataBase.cpp in Sources */, FA27B3C01B4985BF008A9DCE /* wrap_VideoStream.cpp in Sources */, - FA0B7D931A95902C000E1D17 /* Image.cpp in Sources */, + FADF54201E3DA52C00012CC0 /* wrap_ParticleSystem.cpp in Sources */, FA0B7D9F1A95902C000E1D17 /* KTXHandler.cpp in Sources */, + FA1E88831DF363DB00E808AA /* Filter.cpp in Sources */, FA0B7A2C1A958EA3000E1D17 /* b2CollideCircle.cpp in Sources */, - FA27B3A01B498151008A9DCE /* VideoStream.cpp in Sources */, FA0B7CEB1A95902C000E1D17 /* Event.cpp in Sources */, - FA0B7B0B1A958EA3000E1D17 /* tcp.c in Sources */, + FA1557C31CE90BD200AFF582 /* EXRHandler.cpp in Sources */, FA27B3AA1B498151008A9DCE /* VideoStream.cpp in Sources */, - FA0B7D961A95902C000E1D17 /* ImageData.cpp in Sources */, FA0B7E571A95902C000E1D17 /* wrap_Joint.cpp in Sources */, FA0B7E301A95902C000E1D17 /* Shape.cpp in Sources */, + FA93C4541F315B960087CCD4 /* FormatHandler.cpp in Sources */, FA0B7E481A95902C000E1D17 /* wrap_DistanceJoint.cpp in Sources */, FA0B7A8F1A958EA3000E1D17 /* b2FrictionJoint.cpp in Sources */, FA0B792F1A958E3B000E1D17 /* Module.cpp in Sources */, @@ -3779,126 +4747,159 @@ FA0B7D251A95902C000E1D17 /* wrap_Font.cpp in Sources */, FA0B7E091A95902C000E1D17 /* EdgeShape.cpp in Sources */, FA0B7CF71A95902C000E1D17 /* FileData.cpp in Sources */, - FAB17BF01ABFB37500F9BA27 /* wrap_CompressedData.cpp in Sources */, + FAC7CD8C1FE35E95006A60C7 /* physfs_archiver_qpak.c in Sources */, FA0B7DA51A95902C000E1D17 /* PNGHandler.cpp in Sources */, FA0B7B371A958EA3000E1D17 /* wuff_internal.c in Sources */, FA0B7E971A95902C000E1D17 /* Sound.cpp in Sources */, + FA4F2B791DE0125B00CA37D7 /* xxhash.c in Sources */, FA0B7E361A95902C000E1D17 /* WheelJoint.cpp in Sources */, FA0B7A471A958EA3000E1D17 /* b2PolygonShape.cpp in Sources */, + FADF542F1E3DABF600012CC0 /* SpriteBatch.cpp in Sources */, FA0B7D8D1A95902C000E1D17 /* ddsHandler.cpp in Sources */, + FAAA3FD91F64B3AD00F89E99 /* lstrlib.c in Sources */, FA0B7DFD1A95902C000E1D17 /* ChainShape.cpp in Sources */, FA0B79201A958E3B000E1D17 /* delay.cpp in Sources */, - FA0B7D611A95902C000E1D17 /* wrap_Image.cpp in Sources */, FA0B7A4B1A958EA3000E1D17 /* b2BlockAllocator.cpp in Sources */, FA0B7A551A958EA3000E1D17 /* b2Settings.cpp in Sources */, FA0B7EA91A95902C000E1D17 /* wrap_Sound.cpp in Sources */, FA0B7A981A958EA3000E1D17 /* b2MotorJoint.cpp in Sources */, + FA6A2B671F5F7B6B0074C308 /* wrap_Data.cpp in Sources */, FA0B7E061A95902C000E1D17 /* DistanceJoint.cpp in Sources */, FA620A321AA2F8DB005DB4C2 /* wrap_Quad.cpp in Sources */, + FA4F2BA61DE1E36400CA37D7 /* RecordingDevice.cpp in Sources */, + FAF1406C1E20934C00F898D2 /* InfoSink.cpp in Sources */, + FAF1407A1E20934C00F898D2 /* limits.cpp in Sources */, + FAC7CD7E1FE35E95006A60C7 /* physfs_archiver_mvl.c in Sources */, FA0B793B1A958E3B000E1D17 /* runtime.cpp in Sources */, FA0B7E5D1A95902C000E1D17 /* wrap_MouseJoint.cpp in Sources */, FA0B7A741A958EA3000E1D17 /* b2ChainAndPolygonContact.cpp in Sources */, FA0B7AD41A958EA3000E1D17 /* unix.c in Sources */, FA0B7A771A958EA3000E1D17 /* b2CircleContact.cpp in Sources */, - FAB17BE01ABFAA2000F9BA27 /* Compressor.cpp in Sources */, - FA0B7D701A95902C000E1D17 /* wrap_SpriteBatch.cpp in Sources */, + FADF543B1E3DAFF700012CC0 /* wrap_Graphics.cpp in Sources */, FA0B7D331A95902C000E1D17 /* Canvas.cpp in Sources */, FA0B7E941A95902C000E1D17 /* Mpg123Decoder.cpp in Sources */, FA0B7E8B1A95902C000E1D17 /* FLACDecoder.cpp in Sources */, FA0B7B3A1A958EA3000E1D17 /* wuff_memory.c in Sources */, FA0B7A381A958EA3000E1D17 /* b2DynamicTree.cpp in Sources */, + FAECA1B21F3164700095D008 /* CompressedSlice.cpp in Sources */, FA0B7D481A95902C000E1D17 /* Polyline.cpp in Sources */, + 217DFC111D9F6D490055D849 /* usocket.c in Sources */, + FAC7CD891FE35E95006A60C7 /* physfs_archiver_dir.c in Sources */, + FAF140751E20934C00F898D2 /* IntermTraverse.cpp in Sources */, FA0B7CE21A95902C000E1D17 /* wrap_Audio.cpp in Sources */, FA0B7AAA1A958EA3000E1D17 /* b2WeldJoint.cpp in Sources */, FA0B7DF71A95902C000E1D17 /* Body.cpp in Sources */, FA0B7DF41A95902C000E1D17 /* wrap_Mouse.cpp in Sources */, - FA0B7D6D1A95902C000E1D17 /* wrap_Shader.cpp in Sources */, FA0B7E851A95902C000E1D17 /* CoreAudioDecoder.cpp in Sources */, FA0B7E751A95902C000E1D17 /* wrap_WeldJoint.cpp in Sources */, - FA0B7D551A95902C000E1D17 /* GLBuffer.cpp in Sources */, - FA0B7AFF1A958EA3000E1D17 /* options.c in Sources */, + FA0B7D551A95902C000E1D17 /* Buffer.cpp in Sources */, FA57FB981AE1993600F2AD6D /* noise1234.cpp in Sources */, FA0B7E211A95902C000E1D17 /* PolygonShape.cpp in Sources */, - FA0B7AE41A958EA3000E1D17 /* buffer.c in Sources */, - FA0B7D511A95902C000E1D17 /* Text.cpp in Sources */, FA0B7DA21A95902C000E1D17 /* PKMHandler.cpp in Sources */, FA0B7ABA1A958EA3000E1D17 /* callbacks.c in Sources */, FAB17BF51ABFC4B100F9BA27 /* lz4hc.c in Sources */, FA0B7EA61A95902C000E1D17 /* wrap_Decoder.cpp in Sources */, + 217DFBF21D9F6D490055D849 /* mime.c in Sources */, + 217DFBDF1D9F6D490055D849 /* except.c in Sources */, + FA28EBD51E352DB5003446F4 /* FenceSync.cpp in Sources */, FA0B7E1B1A95902C000E1D17 /* MouseJoint.cpp in Sources */, FA0B7CF41A95902C000E1D17 /* File.cpp in Sources */, + FAC7CD7A1FE35E95006A60C7 /* physfs_archiver_7z.c in Sources */, FA0B7E331A95902C000E1D17 /* WeldJoint.cpp in Sources */, - FA0B7D5B1A95902C000E1D17 /* wrap_Font.cpp in Sources */, - FA0B7AE71A958EA3000E1D17 /* except.c in Sources */, FA0B7D301A95902C000E1D17 /* Graphics.cpp in Sources */, + FAF1408E1E20934C00F898D2 /* PpContext.cpp in Sources */, FA0B7E9D1A95902C000E1D17 /* WaveDecoder.cpp in Sources */, + FA29C0051E12355B00268CD8 /* StreamBuffer.cpp in Sources */, FA0B7EB21A95902C000E1D17 /* System.cpp in Sources */, FA0B7D1B1A95902C000E1D17 /* GlyphData.cpp in Sources */, FA0B7AD11A958EA3000E1D17 /* protocol.c in Sources */, + FA9D8DD11DEB56C3002CD881 /* pixelformat.cpp in Sources */, FA0B7E661A95902C000E1D17 /* wrap_PrismaticJoint.cpp in Sources */, FA0B7DCD1A95902C000E1D17 /* wrap_Keyboard.cpp in Sources */, FA0B7EE51A95902D000E1D17 /* Window.cpp in Sources */, + FA6A2B6A1F5F7F560074C308 /* DataView.cpp in Sources */, + FA3C5E471F8D80CA0003C579 /* ShaderStage.cpp in Sources */, FA0B7E391A95902C000E1D17 /* World.cpp in Sources */, FA0B7ABD1A958EA3000E1D17 /* compress.c in Sources */, FA0B7ACB1A958EA3000E1D17 /* list.c in Sources */, FA0B7E7E1A95902C000E1D17 /* Joint.cpp in Sources */, FA0B7A861A958EA3000E1D17 /* b2PolygonAndCircleContact.cpp in Sources */, FA0B7DB11A95902C000E1D17 /* wrap_Image.cpp in Sources */, + FAC7CD831FE35E95006A60C7 /* physfs_platform_windows.c in Sources */, FA0B7E881A95902C000E1D17 /* Decoder.cpp in Sources */, - FA0B7B1B1A958EA3000E1D17 /* usocket.c in Sources */, FA0B7E3C1A95902C000E1D17 /* wrap_Body.cpp in Sources */, FA0B7D791A95902C000E1D17 /* Quad.cpp in Sources */, + FAC756F51E4F99B400B91289 /* Effect.cpp in Sources */, FA620A3A1AA305F6005DB4C2 /* types.cpp in Sources */, FA0B7DD31A95902C000E1D17 /* BezierCurve.cpp in Sources */, + FA91591E1CF1ED7500A7053F /* halffloat.cpp in Sources */, FA0B7E7B1A95902C000E1D17 /* wrap_World.cpp in Sources */, FA0B7B281A958EA3000E1D17 /* simplexnoise1234.cpp in Sources */, - FA0B7D901A95902C000E1D17 /* FormatHandler.cpp in Sources */, FA0B7D421A95902C000E1D17 /* OpenGL.cpp in Sources */, FA0B7A671A958EA3000E1D17 /* b2Island.cpp in Sources */, FA0B7DBE1A95902C000E1D17 /* JoystickModule.cpp in Sources */, - FA0B7D4E1A95902C000E1D17 /* SpriteBatch.cpp in Sources */, FAB2D5AA1AABDD8A008224A4 /* TrueTypeRasterizer.cpp in Sources */, FA0B7ACD1A958EA3000E1D17 /* packet.c in Sources */, FA0B7A921A958EA3000E1D17 /* b2GearJoint.cpp in Sources */, FA0B7E5A1A95902C000E1D17 /* wrap_MotorJoint.cpp in Sources */, FA0B7AA71A958EA3000E1D17 /* b2RopeJoint.cpp in Sources */, FA0B7DD61A95902C000E1D17 /* MathModule.cpp in Sources */, + FA1BA0AC1E16F9EE00AA2803 /* wrap_Canvas.cpp in Sources */, + FAC7CD8A1FE35E95006A60C7 /* physfs_byteorder.c in Sources */, FA0B7D0F1A95902C000E1D17 /* BMFontRasterizer.cpp in Sources */, FA0B7E9A1A95902C000E1D17 /* VorbisDecoder.cpp in Sources */, FA0B7E4B1A95902C000E1D17 /* wrap_EdgeShape.cpp in Sources */, + FA9D8DD91DEF8411002CD881 /* Stream.cpp in Sources */, FA0B7E241A95902C000E1D17 /* PrismaticJoint.cpp in Sources */, + FAC7CD791FE35E95006A60C7 /* physfs.c in Sources */, + FAC756FA1E4F99D200B91289 /* Effect.cpp in Sources */, FA0B7A7D1A958EA3000E1D17 /* b2ContactSolver.cpp in Sources */, FA0B7E601A95902C000E1D17 /* wrap_Physics.cpp in Sources */, FA0B7DC71A95902C000E1D17 /* Keyboard.cpp in Sources */, + 217DFC071D9F6D490055D849 /* udp.c in Sources */, FA0B7EAC1A95902C000E1D17 /* wrap_SoundData.cpp in Sources */, FA0B7E2D1A95902C000E1D17 /* RopeJoint.cpp in Sources */, FA0B7CDF1A95902C000E1D17 /* Source.cpp in Sources */, FA0B7ECE1A95902C000E1D17 /* wrap_LuaThread.cpp in Sources */, FA0B79431A958E3B000E1D17 /* Variant.cpp in Sources */, + FA4F2BE31DE6650600CA37D7 /* Transform.cpp in Sources */, FA0B7EA01A95902C000E1D17 /* Sound.cpp in Sources */, FA0B7DE51A95902C000E1D17 /* Cursor.cpp in Sources */, + FADF54161E3DA08E00012CC0 /* Image.cpp in Sources */, FA0B7EDB1A95902D000E1D17 /* Touch.cpp in Sources */, + FA1BA0A71E16F20600AA2803 /* Canvas.cpp in Sources */, FA0B7CE81A95902C000E1D17 /* Event.cpp in Sources */, FA0B7ACF1A958EA3000E1D17 /* peer.c in Sources */, FA0B7ADE1A958EA3000E1D17 /* lodepng.cpp in Sources */, FA0B7A291A958EA3000E1D17 /* b2BroadPhase.cpp in Sources */, FA0B7A891A958EA3000E1D17 /* b2PolygonContact.cpp in Sources */, FA0B7E1E1A95902C000E1D17 /* Physics.cpp in Sources */, + FA9D8DE01DEF843D002CD881 /* Image.cpp in Sources */, FA0B7E811A95902C000E1D17 /* Shape.cpp in Sources */, - FA0B7B251A958EA3000E1D17 /* lutf8lib.c in Sources */, - FA0B7ED41A95902D000E1D17 /* Timer.cpp in Sources */, - FA19C4C51B4B0BD50059B0B3 /* wrap_Video.cpp in Sources */, + FA4F2BA81DE1E36400CA37D7 /* wrap_RecordingDevice.cpp in Sources */, + FACA02EC1F5E396B0084B28F /* CompressedData.cpp in Sources */, + FAF140531E20934C00F898D2 /* CodeGen.cpp in Sources */, FA27B3B31B498151008A9DCE /* wrap_Video.cpp in Sources */, FA0B7A611A958EA3000E1D17 /* b2ContactManager.cpp in Sources */, + 217DFC0B1D9F6D490055D849 /* unixtcp.c in Sources */, + FAF140881E20934C00F898D2 /* PoolAlloc.cpp in Sources */, FA0B7AAD1A958EA3000E1D17 /* b2WheelJoint.cpp in Sources */, FA0B7DEE1A95902C000E1D17 /* Mouse.cpp in Sources */, - FA0B7AE11A958EA3000E1D17 /* auxiliar.c in Sources */, + FAA54ACC1F91660400A8FA7B /* TheoraVideoStream.cpp in Sources */, + FA1E887E1DF363CD00E808AA /* Filter.cpp in Sources */, FA0B7D281A95902C000E1D17 /* wrap_GlyphData.cpp in Sources */, FA0B7DE21A95902C000E1D17 /* wrap_RandomGenerator.cpp in Sources */, + FACA02F61F5E396B0084B28F /* wrap_DataModule.cpp in Sources */, FA0B79401A958E3B000E1D17 /* utf8.cpp in Sources */, FA0B79241A958E3B000E1D17 /* Exception.cpp in Sources */, FA0B7D0C1A95902C000E1D17 /* wrap_Filesystem.cpp in Sources */, FA0B7AD91A958EA3000E1D17 /* glad.cpp in Sources */, + FAC7CD841FE35E95006A60C7 /* physfs_archiver_unpacked.c in Sources */, + 217DFBF61D9F6D490055D849 /* options.c in Sources */, + FAA54ACD1F91660400A8FA7B /* OggDemuxer.cpp in Sources */, + FAC7CD821FE35E95006A60C7 /* physfs_platform_haiku.cpp in Sources */, + 217DFBD91D9F6D490055D849 /* auxiliar.c in Sources */, + 217DFBDB1D9F6D490055D849 /* buffer.c in Sources */, FA0B7DB41A95902C000E1D17 /* wrap_ImageData.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3913,19 +4914,30 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = NO; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; DEAD_CODE_STRIPPING = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ""; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 3; GCC_PREPROCESSOR_DEFINITIONS = LOVE_APPLE_USE_FRAMEWORKS; + GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; GCC_WARN_ABOUT_MISSING_NEWLINE = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -3962,23 +4974,34 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = NO; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; FRAMEWORK_SEARCH_PATHS = ""; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( LOVE_APPLE_USE_FRAMEWORKS, "DEBUG=1", ); + GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; GCC_WARN_ABOUT_MISSING_NEWLINE = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -4139,19 +5162,30 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = NO; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; DEAD_CODE_STRIPPING = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ""; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 3; GCC_PREPROCESSOR_DEFINITIONS = LOVE_APPLE_USE_FRAMEWORKS; + GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; GCC_WARN_ABOUT_MISSING_NEWLINE = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -4192,14 +5226,19 @@ DYLIB_CURRENT_VERSION = 9.0; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", + "$(PROJECT_DIR)/macosx/Frameworks", /Library/Frameworks, "$(LOCAL_LIBRARY_DIR)/Frameworks", + "$(PROJECT_DIR)", ); FRAMEWORK_VERSION = A; GCC_ENABLE_OBJC_EXCEPTIONS = YES; HEADER_SEARCH_PATHS = ( "$(inherited)", - /Library/Frameworks/FreeType.framework/Headers, + "$(PROJECT_DIR)/macosx/Frameworks/freetype.framework/Headers", + "$(PROJECT_DIR)/macosx/Frameworks/Lua.framework/Headers", + "$(PROJECT_DIR)/macosx/Frameworks/SDL2.framework/Headers", + /Library/Frameworks/freetype.framework/Headers, /Library/Frameworks/Lua.framework/Headers, /Library/Frameworks/SDL2.framework/Headers, ); @@ -4226,14 +5265,19 @@ DYLIB_CURRENT_VERSION = 9.0; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", + "$(PROJECT_DIR)/macosx/Frameworks", /Library/Frameworks, "$(LOCAL_LIBRARY_DIR)/Frameworks", + "$(PROJECT_DIR)", ); FRAMEWORK_VERSION = A; GCC_ENABLE_OBJC_EXCEPTIONS = YES; HEADER_SEARCH_PATHS = ( "$(inherited)", - /Library/Frameworks/FreeType.framework/Headers, + "$(PROJECT_DIR)/macosx/Frameworks/freetype.framework/Headers", + "$(PROJECT_DIR)/macosx/Frameworks/Lua.framework/Headers", + "$(PROJECT_DIR)/macosx/Frameworks/SDL2.framework/Headers", + /Library/Frameworks/freetype.framework/Headers, /Library/Frameworks/Lua.framework/Headers, /Library/Frameworks/SDL2.framework/Headers, ); @@ -4261,14 +5305,19 @@ DYLIB_CURRENT_VERSION = 9.0; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", + "$(PROJECT_DIR)/macosx/Frameworks", /Library/Frameworks, "$(LOCAL_LIBRARY_DIR)/Frameworks", + "$(PROJECT_DIR)", ); FRAMEWORK_VERSION = A; GCC_ENABLE_OBJC_EXCEPTIONS = YES; HEADER_SEARCH_PATHS = ( "$(inherited)", - /Library/Frameworks/FreeType.framework/Headers, + "$(PROJECT_DIR)/macosx/Frameworks/freetype.framework/Headers", + "$(PROJECT_DIR)/macosx/Frameworks/Lua.framework/Headers", + "$(PROJECT_DIR)/macosx/Frameworks/SDL2.framework/Headers", + /Library/Frameworks/freetype.framework/Headers, /Library/Frameworks/Lua.framework/Headers, /Library/Frameworks/SDL2.framework/Headers, ); diff --git a/love/src/jni/love/platform/xcode/love.xcodeproj/project.pbxproj b/love/src/jni/love/platform/xcode/love.xcodeproj/project.pbxproj index 3c46db73..f38e13c4 100644 --- a/love/src/jni/love/platform/xcode/love.xcodeproj/project.pbxproj +++ b/love/src/jni/love/platform/xcode/love.xcodeproj/project.pbxproj @@ -8,20 +8,21 @@ /* Begin PBXBuildFile section */ 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; - A9255DD11043183600BA1496 /* FreeType.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E4810420B4A007D418B /* FreeType.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; A9255DD31043183600BA1496 /* Lua.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E5310420B57007D418B /* Lua.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; - A9255E031043195A00BA1496 /* Vorbis.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9255E021043195A00BA1496 /* Vorbis.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; - A9255F58104324E100BA1496 /* Ogg.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9255F51104324D700BA1496 /* Ogg.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; + A9255E031043195A00BA1496 /* vorbis.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9255E021043195A00BA1496 /* vorbis.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; + A9255F58104324E100BA1496 /* ogg.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9255F51104324D700BA1496 /* ogg.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; A93E6E5510420B57007D418B /* Lua.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E5310420B57007D418B /* Lua.framework */; }; A93E6EED10420BA8007D418B /* love.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6A3410420AC0007D418B /* love.cpp */; }; A9D307F2106635D3004FEDF8 /* physfs.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9D307E9106635C3004FEDF8 /* physfs.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; A9F169AC109E825000FC83D1 /* mpg123.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9F169A6109E824900FC83D1 /* mpg123.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; A9F169AD109E825000FC83D1 /* libmodplug.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9F16926109E7BAD00FC83D1 /* libmodplug.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; + CE73F8001EEB64150052DAB3 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE73F7FF1EEB64150052DAB3 /* AVFoundation.framework */; }; FA0797991BF480A200034B7C /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA0797981BF480A200034B7C /* GameController.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; FA08F69616C766E000F007B5 /* love.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA08F69116C765A200F007B5 /* love.framework */; }; FA08F69716C766E700F007B5 /* love.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FA08F69116C765A200F007B5 /* love.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; FA0B7F301A95AC7D000E1D17 /* love.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6A3410420AC0007D418B /* love.cpp */; }; - FA27B3CB1B498696008A9DCE /* Theora.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA27B3CA1B498696008A9DCE /* Theora.framework */; }; + FA15DFB41F9B8D9E0042AB22 /* libbz2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = FA15DFB31F9B8D9E0042AB22 /* libbz2.tbd */; }; + FA27B3CB1B498696008A9DCE /* theora.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA27B3CA1B498696008A9DCE /* theora.framework */; }; FA5933751C6D625B000EC779 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FA5D249A1A96CF4300C6FC8F /* Images.xcassets */; }; FA5D24821A96CA1800C6FC8F /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA5D24811A96CA1800C6FC8F /* OpenAL.framework */; }; FA5D24841A96CA2700C6FC8F /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA5D24831A96CA2700C6FC8F /* OpenGLES.framework */; }; @@ -39,7 +40,8 @@ FA9B4A0B16E157B500074F42 /* SDL2.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FA9B4A0916E1579F00074F42 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; FAAFF04716CB120000CCDE45 /* OpenAL-Soft.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FAAFF04616CB120000CCDE45 /* OpenAL-Soft.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; FAC1A449196F5DC600125284 /* license.txt in Resources */ = {isa = PBXBuildFile; fileRef = FAC1A448196F5DC600125284 /* license.txt */; }; - FAD4B1731C1F50A3004CF150 /* Theora.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FA27B3CA1B498696008A9DCE /* Theora.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; + FAD43ED01FF3136500831BB8 /* freetype.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FAD43ECF1FF3133700831BB8 /* freetype.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + FAD4B1731C1F50A3004CF150 /* theora.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FA27B3CA1B498696008A9DCE /* theora.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -82,14 +84,14 @@ files = ( FA08F69716C766E700F007B5 /* love.framework in Copy Frameworks */, FA9B4A0B16E157B500074F42 /* SDL2.framework in Copy Frameworks */, - FAD4B1731C1F50A3004CF150 /* Theora.framework in Copy Frameworks */, + FAD4B1731C1F50A3004CF150 /* theora.framework in Copy Frameworks */, FAAFF04716CB120000CCDE45 /* OpenAL-Soft.framework in Copy Frameworks */, + FAD43ED01FF3136500831BB8 /* freetype.framework in Copy Frameworks */, A9F169AC109E825000FC83D1 /* mpg123.framework in Copy Frameworks */, A9F169AD109E825000FC83D1 /* libmodplug.framework in Copy Frameworks */, A9D307F2106635D3004FEDF8 /* physfs.framework in Copy Frameworks */, - A9255F58104324E100BA1496 /* Ogg.framework in Copy Frameworks */, - A9255E031043195A00BA1496 /* Vorbis.framework in Copy Frameworks */, - A9255DD11043183600BA1496 /* FreeType.framework in Copy Frameworks */, + A9255F58104324E100BA1496 /* ogg.framework in Copy Frameworks */, + A9255E031043195A00BA1496 /* vorbis.framework in Copy Frameworks */, A9255DD31043183600BA1496 /* Lua.framework in Copy Frameworks */, ); name = "Copy Frameworks"; @@ -100,20 +102,21 @@ /* Begin PBXFileReference section */ 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 8D1107320486CEB800E47090 /* love.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = love.app; sourceTree = BUILT_PRODUCTS_DIR; }; - A9255E021043195A00BA1496 /* Vorbis.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Vorbis.framework; path = /Library/Frameworks/Vorbis.framework; sourceTree = ""; }; - A9255F51104324D700BA1496 /* Ogg.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Ogg.framework; path = /Library/Frameworks/Ogg.framework; sourceTree = ""; }; + A9255E021043195A00BA1496 /* vorbis.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = vorbis.framework; path = /Library/Frameworks/vorbis.framework; sourceTree = ""; }; + A9255F51104324D700BA1496 /* ogg.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ogg.framework; path = /Library/Frameworks/ogg.framework; sourceTree = ""; }; A93E6A3410420AC0007D418B /* love.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = love.cpp; path = ../../src/love.cpp; sourceTree = ""; }; A93E6E4710420B4A007D418B /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = ""; }; - A93E6E4810420B4A007D418B /* FreeType.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FreeType.framework; path = /Library/Frameworks/FreeType.framework; sourceTree = ""; }; A93E6E5310420B57007D418B /* Lua.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Lua.framework; path = /Library/Frameworks/Lua.framework; sourceTree = ""; }; A97E3842132A9EDE00198A2F /* love-macosx.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "love-macosx.plist"; path = "macosx/love-macosx.plist"; sourceTree = ""; }; A9D307E9106635C3004FEDF8 /* physfs.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = physfs.framework; path = /Library/Frameworks/physfs.framework; sourceTree = ""; }; A9F16926109E7BAD00FC83D1 /* libmodplug.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = libmodplug.framework; path = /Library/Frameworks/libmodplug.framework; sourceTree = ""; }; A9F169A6109E824900FC83D1 /* mpg123.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mpg123.framework; path = /Library/Frameworks/mpg123.framework; sourceTree = ""; }; + CE73F7FF1EEB64150052DAB3 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.3.sdk/System/Library/Frameworks/AVFoundation.framework; sourceTree = DEVELOPER_DIR; }; FA0797981BF480A200034B7C /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.1.sdk/System/Library/Frameworks/GameController.framework; sourceTree = DEVELOPER_DIR; }; FA08F69116C765A200F007B5 /* love.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = love.framework; sourceTree = BUILT_PRODUCTS_DIR; }; FA0B7F061A95AAF3000E1D17 /* love.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = love.app; sourceTree = BUILT_PRODUCTS_DIR; }; - FA27B3CA1B498696008A9DCE /* Theora.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Theora.framework; path = /Library/Frameworks/Theora.framework; sourceTree = ""; }; + FA15DFB31F9B8D9E0042AB22 /* libbz2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libbz2.tbd; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.0.sdk/usr/lib/libbz2.tbd; sourceTree = DEVELOPER_DIR; }; + FA27B3CA1B498696008A9DCE /* theora.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = theora.framework; path = /Library/Frameworks/theora.framework; sourceTree = ""; }; FA577A9316C7217800860150 /* liblove.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = liblove.xcodeproj; sourceTree = ""; }; FA5D24811A96CA1800C6FC8F /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.1.sdk/System/Library/Frameworks/OpenAL.framework; sourceTree = DEVELOPER_DIR; }; FA5D24831A96CA2700C6FC8F /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.1.sdk/System/Library/Frameworks/OpenGLES.framework; sourceTree = DEVELOPER_DIR; }; @@ -130,6 +133,7 @@ FA9B4A0916E1579F00074F42 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = /Library/Frameworks/SDL2.framework; sourceTree = ""; }; FAAFF04616CB120000CCDE45 /* OpenAL-Soft.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "OpenAL-Soft.framework"; path = "/Library/Frameworks/OpenAL-Soft.framework"; sourceTree = ""; }; FAC1A448196F5DC600125284 /* license.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = license.txt; path = ../../license.txt; sourceTree = ""; }; + FAD43ECF1FF3133700831BB8 /* freetype.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = freetype.framework; path = /Library/Frameworks/freetype.framework; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -140,7 +144,7 @@ FA08F69616C766E000F007B5 /* love.framework in Frameworks */, 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, A93E6E5510420B57007D418B /* Lua.framework in Frameworks */, - FA27B3CB1B498696008A9DCE /* Theora.framework in Frameworks */, + FA27B3CB1B498696008A9DCE /* theora.framework in Frameworks */, FA9B4A0A16E1579F00074F42 /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -149,6 +153,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + FA15DFB41F9B8D9E0042AB22 /* libbz2.tbd in Frameworks */, + CE73F8001EEB64150052DAB3 /* AVFoundation.framework in Frameworks */, FA5D24D11A96E73300C6FC8F /* liblove.a in Frameworks */, FA5D24C21A96D78000C6FC8F /* Foundation.framework in Frameworks */, FA5D24961A96CAC200C6FC8F /* CoreMotion.framework in Frameworks */, @@ -169,6 +175,8 @@ 1058C7A0FEA54F0111CA2CBB /* Frameworks */ = { isa = PBXGroup; children = ( + FA15DFB31F9B8D9E0042AB22 /* libbz2.tbd */, + CE73F7FF1EEB64150052DAB3 /* AVFoundation.framework */, FA5D24801A96C97900C6FC8F /* ios */, FA0B7EEC1A959249000E1D17 /* macosx */, ); @@ -219,19 +227,19 @@ FA0B7EEC1A959249000E1D17 /* macosx */ = { isa = PBXGroup; children = ( - FA27B3CA1B498696008A9DCE /* Theora.framework */, 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, - A93E6E4810420B4A007D418B /* FreeType.framework */, + FAD43ECF1FF3133700831BB8 /* freetype.framework */, A9F16926109E7BAD00FC83D1 /* libmodplug.framework */, FA08F69116C765A200F007B5 /* love.framework */, A93E6E5310420B57007D418B /* Lua.framework */, A9F169A6109E824900FC83D1 /* mpg123.framework */, - A9255F51104324D700BA1496 /* Ogg.framework */, + A9255F51104324D700BA1496 /* ogg.framework */, FAAFF04616CB120000CCDE45 /* OpenAL-Soft.framework */, A93E6E4710420B4A007D418B /* OpenGL.framework */, A9D307E9106635C3004FEDF8 /* physfs.framework */, FA9B4A0916E1579F00074F42 /* SDL2.framework */, - A9255E021043195A00BA1496 /* Vorbis.framework */, + FA27B3CA1B498696008A9DCE /* theora.framework */, + A9255E021043195A00BA1496 /* vorbis.framework */, ); name = macosx; sourceTree = ""; @@ -318,7 +326,7 @@ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0700; + LastUpgradeCheck = 0920; TargetAttributes = { FA0B7F051A95AAF3000E1D17 = { CreatedOnToolsVersion = 6.1.1; @@ -430,6 +438,7 @@ COMBINE_HIDPI_IMAGES = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", + "$(PROJECT_DIR)/macosx/Frameworks", /Library/Frameworks, "\"$(SRCROOT)/build/Release\"", "\"$(SRCROOT)/build/Debug\"", @@ -439,6 +448,8 @@ GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( "$(inherited)", + "$(PROJECT_DIR)/macosx/Frameworks/Lua.framework/Headers", + "$(PROJECT_DIR)/macosx/Frameworks/SDL2.framework/Headers", /Library/Frameworks/Lua.framework/Headers, /Library/Frameworks/SDL2.framework/Headers, ); @@ -458,6 +469,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", + "$(PROJECT_DIR)/macosx/Frameworks", /Library/Frameworks, "\"$(SRCROOT)/build/Release\"", "\"$(SRCROOT)/build/Debug\"", @@ -465,6 +477,8 @@ ); HEADER_SEARCH_PATHS = ( "$(inherited)", + "$(PROJECT_DIR)/macosx/Frameworks/Lua.framework/Headers", + "$(PROJECT_DIR)/macosx/Frameworks/SDL2.framework/Headers", /Library/Frameworks/Lua.framework/Headers, /Library/Frameworks/SDL2.framework/Headers, ); @@ -480,16 +494,35 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_INCREASE_PRECOMPILED_HEADER_SHARING = YES; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = LOVE_APPLE_USE_FRAMEWORKS; GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_ABOUT_MISSING_NEWLINE = NO; GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; GCC_WARN_ABOUT_POINTER_SIGNEDNESS = YES; @@ -504,6 +537,9 @@ GCC_WARN_SHADOW = NO; GCC_WARN_SIGN_COMPARE = YES; GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ( "\"$(SRCROOT)/../../src\"", @@ -535,16 +571,35 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; DEPLOYMENT_POSTPROCESSING = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_INPUT_FILETYPE = automatic; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 3; GCC_PREPROCESSOR_DEFINITIONS = LOVE_APPLE_USE_FRAMEWORKS; GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_ABOUT_MISSING_NEWLINE = NO; GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; GCC_WARN_ABOUT_POINTER_SIGNEDNESS = YES; @@ -559,6 +614,9 @@ GCC_WARN_SHADOW = NO; GCC_WARN_SIGN_COMPARE = YES; GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_PARAMETER = NO; GCC_WARN_UNUSED_VALUE = NO; GCC_WARN_UNUSED_VARIABLE = YES; @@ -730,16 +788,35 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; DEPLOYMENT_POSTPROCESSING = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_INPUT_FILETYPE = automatic; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 3; GCC_PREPROCESSOR_DEFINITIONS = LOVE_APPLE_USE_FRAMEWORKS; GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_ABOUT_MISSING_NEWLINE = NO; GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; GCC_WARN_ABOUT_POINTER_SIGNEDNESS = YES; @@ -754,6 +831,9 @@ GCC_WARN_SHADOW = NO; GCC_WARN_SIGN_COMPARE = YES; GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_PARAMETER = NO; GCC_WARN_UNUSED_VALUE = NO; GCC_WARN_UNUSED_VARIABLE = YES; @@ -793,6 +873,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", + "$(PROJECT_DIR)/macosx/Frameworks", /Library/Frameworks, "\"$(SRCROOT)/build/Release\"", "\"$(SRCROOT)/build/Debug\"", @@ -800,6 +881,8 @@ ); HEADER_SEARCH_PATHS = ( "$(inherited)", + "$(PROJECT_DIR)/macosx/Frameworks/Lua.framework/Headers", + "$(PROJECT_DIR)/macosx/Frameworks/SDL2.framework/Headers", /Library/Frameworks/Lua.framework/Headers, /Library/Frameworks/SDL2.framework/Headers, ); diff --git a/love/src/jni/love/platform/xcode/love.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/love/src/jni/love/platform/xcode/love.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 00000000..0c67376e --- /dev/null +++ b/love/src/jni/love/platform/xcode/love.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,5 @@ + + + + + diff --git a/love/src/jni/love/platform/xcode/macosx/liblove-macosx.plist b/love/src/jni/love/platform/xcode/macosx/liblove-macosx.plist index b5aedb33..d6822def 100644 --- a/love/src/jni/love/platform/xcode/macosx/liblove-macosx.plist +++ b/love/src/jni/love/platform/xcode/macosx/liblove-macosx.plist @@ -17,7 +17,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.10.1 + 0.11.0 CFBundleSignature LoVe NSPrincipalClass diff --git a/love/src/jni/love/platform/xcode/macosx/love-macosx.plist b/love/src/jni/love/platform/xcode/macosx/love-macosx.plist index 8cf99c4a..44314b7f 100644 --- a/love/src/jni/love/platform/xcode/macosx/love-macosx.plist +++ b/love/src/jni/love/platform/xcode/macosx/love-macosx.plist @@ -62,7 +62,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.10.2 + 0.11.0 CFBundleSignature LoVe LSApplicationCategoryType @@ -70,9 +70,11 @@ NSHighResolutionCapable NSHumanReadableCopyright - © 2006-2016 LÖVE Development Team + © 2006-2018 LÖVE Development Team NSPrincipalClass NSApplication + NSSupportsAutomaticGraphicsSwitching + UTExportedTypeDeclarations diff --git a/love/src/jni/love/src/modules/graphics/Color.h b/love/src/jni/love/src/common/Color.h similarity index 74% rename from love/src/jni/love/src/modules/graphics/Color.h rename to love/src/jni/love/src/common/Color.h index 2c652213..995a37f1 100644 --- a/love/src/jni/love/src/modules/graphics/Color.h +++ b/love/src/jni/love/src/common/Color.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2011 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -18,13 +18,11 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -#ifndef LOVE_GRAPHICS_COLOR_H -#define LOVE_GRAPHICS_COLOR_H +#ifndef LOVE_COLOR_H +#define LOVE_COLOR_H namespace love { -namespace graphics -{ template struct ColorT @@ -48,6 +46,7 @@ struct ColorT bool operator!=(const ColorT &other) const; ColorT operator+=(const ColorT &other); + ColorT operator*=(const ColorT &other); ColorT operator*=(T s); ColorT operator/=(T s); }; @@ -74,6 +73,16 @@ ColorT ColorT::operator+=(const ColorT &other) return *this; } +template +ColorT ColorT::operator*=(const ColorT &other) +{ + r *= other.r; + g *= other.g; + b *= other.b; + a *= other.a; + return *this; +} + template ColorT ColorT::operator*=(T s) { @@ -101,6 +110,17 @@ ColorT operator+(const ColorT &a, const ColorT &b) return tmp += b; } +template +ColorT operator*(const ColorT &a, const ColorT &b) +{ + ColorT res; + res.r = a.r * b.r; + res.g = a.g * b.g; + res.b = a.b * b.b; + res.a = a.a * b.a; + return res; +} + template ColorT operator*(const ColorT &a, T s) { @@ -118,7 +138,19 @@ ColorT operator/(const ColorT &a, T s) typedef ColorT Color; typedef ColorT Colorf; -} // graphics +inline Color toColor(Colorf cf) +{ + return Color((unsigned char) (cf.r * 255.0f), + (unsigned char) (cf.g * 255.0f), + (unsigned char) (cf.b * 255.0f), + (unsigned char) (cf.a * 255.0f)); +} + +inline Colorf toColorf(Color c) +{ + return Colorf(c.r / 255.0f, c.g / 255.0f, c.b / 255.0f, c.a / 255.0f); +} + } // love -#endif // LOVE_GRAPHICS_COLOR_H +#endif // LOVE_COLOR_H diff --git a/love/src/jni/love/src/common/Data.cpp b/love/src/jni/love/src/common/Data.cpp new file mode 100644 index 00000000..4ef6bbf0 --- /dev/null +++ b/love/src/jni/love/src/common/Data.cpp @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2006-2018 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +// LOVE +#include "Data.h" + +namespace love +{ + +love::Type Data::type("Data", &Object::type); + +} // love diff --git a/love/src/jni/love/src/common/Data.h b/love/src/jni/love/src/common/Data.h index ef2c671b..34236258 100644 --- a/love/src/jni/love/src/common/Data.h +++ b/love/src/jni/love/src/common/Data.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -38,11 +38,17 @@ class Data : public Object { public: + static love::Type type; + /** * Destructor. **/ virtual ~Data() {} + /** + * Creates a duplicate of Data derived class instance. + **/ + virtual Data *clone() const = 0; /** * Gets a pointer to the data. This pointer will obviously not * be valid if the Data object is destroyed. diff --git a/love/src/jni/love/src/common/EnumMap.h b/love/src/jni/love/src/common/EnumMap.h index 34db3b22..a8b050c6 100644 --- a/love/src/jni/love/src/common/EnumMap.h +++ b/love/src/jni/love/src/common/EnumMap.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff --git a/love/src/jni/love/src/common/Exception.cpp b/love/src/jni/love/src/common/Exception.cpp index 79872a00..7f79f5d4 100644 --- a/love/src/jni/love/src/common/Exception.cpp +++ b/love/src/jni/love/src/common/Exception.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff --git a/love/src/jni/love/src/common/Exception.h b/love/src/jni/love/src/common/Exception.h index c3b74906..c9e24945 100644 --- a/love/src/jni/love/src/common/Exception.h +++ b/love/src/jni/love/src/common/Exception.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff --git a/love/src/jni/love/src/common/Matrix.cpp b/love/src/jni/love/src/common/Matrix.cpp index 67e71105..8af267ca 100644 --- a/love/src/jni/love/src/common/Matrix.cpp +++ b/love/src/jni/love/src/common/Matrix.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -19,38 +19,19 @@ **/ #include "Matrix.h" +#include "common/config.h" // STD #include // memcpy #include +#if defined(LOVE_SIMD_SSE) +#include +#endif + namespace love { -// | e0 e4 e8 e12 | -// | e1 e5 e9 e13 | -// | e2 e6 e10 e14 | -// | e3 e7 e11 e15 | - -Matrix4::Matrix4() -{ - setIdentity(); -} - -Matrix4::Matrix4(float t00, float t10, float t01, float t11, float x, float y) -{ - setRawTransformation(t00, t10, t01, t11, x, y); -} - -Matrix4::Matrix4(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) -{ - setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); -} - -Matrix4::~Matrix4() -{ -} - // | e0 e4 e8 e12 | // | e1 e5 e9 e13 | // | e2 e6 e10 e14 | @@ -60,37 +41,106 @@ Matrix4::~Matrix4() // | e2 e6 e10 e14 | // | e3 e7 e11 e15 | +void Matrix4::multiply(const Matrix4 &a, const Matrix4 &b, float t[16]) +{ + // NOTE: in my testing with ARM NEON instructions (on an iPhone 6 with arm64) + // it performed slightly worse than the regular add/multiply code. Further + // investigation would be useful. +#if defined(LOVE_SIMD_SSE) + + // We can't guarantee 16-bit alignment (e.g. for heap-allocated Matrix4 + // objects) so we use unaligned loads and stores. + __m128 col1 = _mm_loadu_ps(&a.e[0]); + __m128 col2 = _mm_loadu_ps(&a.e[4]); + __m128 col3 = _mm_loadu_ps(&a.e[8]); + __m128 col4 = _mm_loadu_ps(&a.e[12]); + + for (int i = 0; i < 4; i++) + { + __m128 brod1 = _mm_set1_ps(b.e[4*i + 0]); + __m128 brod2 = _mm_set1_ps(b.e[4*i + 1]); + __m128 brod3 = _mm_set1_ps(b.e[4*i + 2]); + __m128 brod4 = _mm_set1_ps(b.e[4*i + 3]); + + __m128 col = _mm_add_ps( + _mm_add_ps(_mm_mul_ps(brod1, col1), _mm_mul_ps(brod2, col2)), + _mm_add_ps(_mm_mul_ps(brod3, col3), _mm_mul_ps(brod4, col4)) + ); + + _mm_storeu_ps(&t[4*i], col); + } + +#else + + t[0] = (a.e[0]*b.e[0]) + (a.e[4]*b.e[1]) + (a.e[8]*b.e[2]) + (a.e[12]*b.e[3]); + t[4] = (a.e[0]*b.e[4]) + (a.e[4]*b.e[5]) + (a.e[8]*b.e[6]) + (a.e[12]*b.e[7]); + t[8] = (a.e[0]*b.e[8]) + (a.e[4]*b.e[9]) + (a.e[8]*b.e[10]) + (a.e[12]*b.e[11]); + t[12] = (a.e[0]*b.e[12]) + (a.e[4]*b.e[13]) + (a.e[8]*b.e[14]) + (a.e[12]*b.e[15]); + + t[1] = (a.e[1]*b.e[0]) + (a.e[5]*b.e[1]) + (a.e[9]*b.e[2]) + (a.e[13]*b.e[3]); + t[5] = (a.e[1]*b.e[4]) + (a.e[5]*b.e[5]) + (a.e[9]*b.e[6]) + (a.e[13]*b.e[7]); + t[9] = (a.e[1]*b.e[8]) + (a.e[5]*b.e[9]) + (a.e[9]*b.e[10]) + (a.e[13]*b.e[11]); + t[13] = (a.e[1]*b.e[12]) + (a.e[5]*b.e[13]) + (a.e[9]*b.e[14]) + (a.e[13]*b.e[15]); + + t[2] = (a.e[2]*b.e[0]) + (a.e[6]*b.e[1]) + (a.e[10]*b.e[2]) + (a.e[14]*b.e[3]); + t[6] = (a.e[2]*b.e[4]) + (a.e[6]*b.e[5]) + (a.e[10]*b.e[6]) + (a.e[14]*b.e[7]); + t[10] = (a.e[2]*b.e[8]) + (a.e[6]*b.e[9]) + (a.e[10]*b.e[10]) + (a.e[14]*b.e[11]); + t[14] = (a.e[2]*b.e[12]) + (a.e[6]*b.e[13]) + (a.e[10]*b.e[14]) + (a.e[14]*b.e[15]); + + t[3] = (a.e[3]*b.e[0]) + (a.e[7]*b.e[1]) + (a.e[11]*b.e[2]) + (a.e[15]*b.e[3]); + t[7] = (a.e[3]*b.e[4]) + (a.e[7]*b.e[5]) + (a.e[11]*b.e[6]) + (a.e[15]*b.e[7]); + t[11] = (a.e[3]*b.e[8]) + (a.e[7]*b.e[9]) + (a.e[11]*b.e[10]) + (a.e[15]*b.e[11]); + t[15] = (a.e[3]*b.e[12]) + (a.e[7]*b.e[13]) + (a.e[11]*b.e[14]) + (a.e[15]*b.e[15]); + +#endif +} + +void Matrix4::multiply(const Matrix4 &a, const Matrix4 &b, Matrix4 &t) +{ + multiply(a, b, t.e); +} + +// | e0 e4 e8 e12 | +// | e1 e5 e9 e13 | +// | e2 e6 e10 e14 | +// | e3 e7 e11 e15 | + +Matrix4::Matrix4() +{ + setIdentity(); +} + + +Matrix4::Matrix4(const float elements[16]) +{ + memcpy(e, elements, sizeof(float) * 16); +} + +Matrix4::Matrix4(float t00, float t10, float t01, float t11, float x, float y) +{ + setRawTransformation(t00, t10, t01, t11, x, y); +} + +Matrix4::Matrix4(const Matrix4 &a, const Matrix4 &b) +{ + multiply(a, b, e); +} + +Matrix4::Matrix4(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) +{ + setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); +} + Matrix4 Matrix4::operator * (const Matrix4 &m) const { - Matrix4 t; - - t.e[0] = (e[0]*m.e[0]) + (e[4]*m.e[1]) + (e[8]*m.e[2]) + (e[12]*m.e[3]); - t.e[4] = (e[0]*m.e[4]) + (e[4]*m.e[5]) + (e[8]*m.e[6]) + (e[12]*m.e[7]); - t.e[8] = (e[0]*m.e[8]) + (e[4]*m.e[9]) + (e[8]*m.e[10]) + (e[12]*m.e[11]); - t.e[12] = (e[0]*m.e[12]) + (e[4]*m.e[13]) + (e[8]*m.e[14]) + (e[12]*m.e[15]); - - t.e[1] = (e[1]*m.e[0]) + (e[5]*m.e[1]) + (e[9]*m.e[2]) + (e[13]*m.e[3]); - t.e[5] = (e[1]*m.e[4]) + (e[5]*m.e[5]) + (e[9]*m.e[6]) + (e[13]*m.e[7]); - t.e[9] = (e[1]*m.e[8]) + (e[5]*m.e[9]) + (e[9]*m.e[10]) + (e[13]*m.e[11]); - t.e[13] = (e[1]*m.e[12]) + (e[5]*m.e[13]) + (e[9]*m.e[14]) + (e[13]*m.e[15]); - - t.e[2] = (e[2]*m.e[0]) + (e[6]*m.e[1]) + (e[10]*m.e[2]) + (e[14]*m.e[3]); - t.e[6] = (e[2]*m.e[4]) + (e[6]*m.e[5]) + (e[10]*m.e[6]) + (e[14]*m.e[7]); - t.e[10] = (e[2]*m.e[8]) + (e[6]*m.e[9]) + (e[10]*m.e[10]) + (e[14]*m.e[11]); - t.e[14] = (e[2]*m.e[12]) + (e[6]*m.e[13]) + (e[10]*m.e[14]) + (e[14]*m.e[15]); - - t.e[3] = (e[3]*m.e[0]) + (e[7]*m.e[1]) + (e[11]*m.e[2]) + (e[15]*m.e[3]); - t.e[7] = (e[3]*m.e[4]) + (e[7]*m.e[5]) + (e[11]*m.e[6]) + (e[15]*m.e[7]); - t.e[11] = (e[3]*m.e[8]) + (e[7]*m.e[9]) + (e[11]*m.e[10]) + (e[15]*m.e[11]); - t.e[15] = (e[3]*m.e[12]) + (e[7]*m.e[13]) + (e[11]*m.e[14]) + (e[15]*m.e[15]); - - return t; + return Matrix4(*this, m); } void Matrix4::operator *= (const Matrix4 &m) { - Matrix4 t = (*this) * m; - memcpy(this->e, t.e, sizeof(float)*16); + float t[16]; + multiply(*this, m, t); + memcpy(this->e, t, sizeof(float)*16); } const float *Matrix4::getElements() const @@ -101,7 +151,7 @@ const float *Matrix4::getElements() const void Matrix4::setIdentity() { memset(e, 0, sizeof(float)*16); - e[0] = e[5] = e[10] = e[15] = 1; + e[15] = e[10] = e[5] = e[0] = 1; } void Matrix4::setTranslation(float x, float y) @@ -134,6 +184,12 @@ void Matrix4::setShear(float kx, float ky) e[1] = ky; e[4] = kx; } + +void Matrix4::getApproximateScale(float &sx, float &sy) const +{ + sx = sqrtf(e[0] * e[0] + e[4] * e[4]); + sy = sqrtf(e[1] * e[1] + e[5] * e[5]); +} void Matrix4::setRawTransformation(float t00, float t10, float t01, float t11, float x, float y) { @@ -194,16 +250,149 @@ void Matrix4::shear(float kx, float ky) this->operator *=(t); } -Matrix4 Matrix4::ortho(float left, float right, float bottom, float top) +bool Matrix4::isAffine2DTransform() const +{ + return fabsf(e[2] + e[3] + e[6] + e[7] + e[8] + e[9] + e[11] + e[14]) < 0.00001f + && fabsf(e[10] + e[15] - 2.0f) < 0.00001f; +} + +Matrix4 Matrix4::inverse() const +{ + Matrix4 inv; + + inv.e[0] = e[5] * e[10] * e[15] - + e[5] * e[11] * e[14] - + e[9] * e[6] * e[15] + + e[9] * e[7] * e[14] + + e[13] * e[6] * e[11] - + e[13] * e[7] * e[10]; + + inv.e[4] = -e[4] * e[10] * e[15] + + e[4] * e[11] * e[14] + + e[8] * e[6] * e[15] - + e[8] * e[7] * e[14] - + e[12] * e[6] * e[11] + + e[12] * e[7] * e[10]; + + inv.e[8] = e[4] * e[9] * e[15] - + e[4] * e[11] * e[13] - + e[8] * e[5] * e[15] + + e[8] * e[7] * e[13] + + e[12] * e[5] * e[11] - + e[12] * e[7] * e[9]; + + inv.e[12] = -e[4] * e[9] * e[14] + + e[4] * e[10] * e[13] + + e[8] * e[5] * e[14] - + e[8] * e[6] * e[13] - + e[12] * e[5] * e[10] + + e[12] * e[6] * e[9]; + + inv.e[1] = -e[1] * e[10] * e[15] + + e[1] * e[11] * e[14] + + e[9] * e[2] * e[15] - + e[9] * e[3] * e[14] - + e[13] * e[2] * e[11] + + e[13] * e[3] * e[10]; + + inv.e[5] = e[0] * e[10] * e[15] - + e[0] * e[11] * e[14] - + e[8] * e[2] * e[15] + + e[8] * e[3] * e[14] + + e[12] * e[2] * e[11] - + e[12] * e[3] * e[10]; + + inv.e[9] = -e[0] * e[9] * e[15] + + e[0] * e[11] * e[13] + + e[8] * e[1] * e[15] - + e[8] * e[3] * e[13] - + e[12] * e[1] * e[11] + + e[12] * e[3] * e[9]; + + inv.e[13] = e[0] * e[9] * e[14] - + e[0] * e[10] * e[13] - + e[8] * e[1] * e[14] + + e[8] * e[2] * e[13] + + e[12] * e[1] * e[10] - + e[12] * e[2] * e[9]; + + inv.e[2] = e[1] * e[6] * e[15] - + e[1] * e[7] * e[14] - + e[5] * e[2] * e[15] + + e[5] * e[3] * e[14] + + e[13] * e[2] * e[7] - + e[13] * e[3] * e[6]; + + inv.e[6] = -e[0] * e[6] * e[15] + + e[0] * e[7] * e[14] + + e[4] * e[2] * e[15] - + e[4] * e[3] * e[14] - + e[12] * e[2] * e[7] + + e[12] * e[3] * e[6]; + + inv.e[10] = e[0] * e[5] * e[15] - + e[0] * e[7] * e[13] - + e[4] * e[1] * e[15] + + e[4] * e[3] * e[13] + + e[12] * e[1] * e[7] - + e[12] * e[3] * e[5]; + + inv.e[14] = -e[0] * e[5] * e[14] + + e[0] * e[6] * e[13] + + e[4] * e[1] * e[14] - + e[4] * e[2] * e[13] - + e[12] * e[1] * e[6] + + e[12] * e[2] * e[5]; + + inv.e[3] = -e[1] * e[6] * e[11] + + e[1] * e[7] * e[10] + + e[5] * e[2] * e[11] - + e[5] * e[3] * e[10] - + e[9] * e[2] * e[7] + + e[9] * e[3] * e[6]; + + inv.e[7] = e[0] * e[6] * e[11] - + e[0] * e[7] * e[10] - + e[4] * e[2] * e[11] + + e[4] * e[3] * e[10] + + e[8] * e[2] * e[7] - + e[8] * e[3] * e[6]; + + inv.e[11] = -e[0] * e[5] * e[11] + + e[0] * e[7] * e[9] + + e[4] * e[1] * e[11] - + e[4] * e[3] * e[9] - + e[8] * e[1] * e[7] + + e[8] * e[3] * e[5]; + + inv.e[15] = e[0] * e[5] * e[10] - + e[0] * e[6] * e[9] - + e[4] * e[1] * e[10] + + e[4] * e[2] * e[9] + + e[8] * e[1] * e[6] - + e[8] * e[2] * e[5]; + + float det = e[0] * inv.e[0] + e[1] * inv.e[4] + e[2] * inv.e[8] + e[3] * inv.e[12]; + + float invdet = 1.0f / det; + + for (int i = 0; i < 16; i++) + inv.e[i] *= invdet; + + return inv; +} + +Matrix4 Matrix4::ortho(float left, float right, float bottom, float top, float near, float far) { Matrix4 m; m.e[0] = 2.0f / (right - left); m.e[5] = 2.0f / (top - bottom); - m.e[10] = -1.0; + m.e[10] = -2.0f / (far - near); m.e[12] = -(right + left) / (right - left); m.e[13] = -(top + bottom) / (top - bottom); + m.e[14] = -(far + near) / (far - near); return m; } diff --git a/love/src/jni/love/src/common/Matrix.h b/love/src/jni/love/src/common/Matrix.h index c1b62146..ed11e5c1 100644 --- a/love/src/jni/love/src/common/Matrix.h +++ b/love/src/jni/love/src/common/Matrix.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -34,8 +34,14 @@ namespace love **/ class Matrix4 { +private: + + static void multiply(const Matrix4 &a, const Matrix4 &b, float t[16]); + public: + static void multiply(const Matrix4 &a, const Matrix4 &b, Matrix4 &result); + /** * Creates a new identity matrix. **/ @@ -46,16 +52,23 @@ public: **/ Matrix4(float t00, float t10, float t01, float t11, float x, float y); + /** + * Creates a new matrix from the specified elements. Be sure to pass + * exactly 16 elements in! + **/ + Matrix4(const float elements[16]); + + /** + * Creates a new matrix from the result of multiplying the two specified + * matrices. + **/ + Matrix4(const Matrix4 &a, const Matrix4 &b); + /** * Creates a new matrix set to a transformation. **/ Matrix4(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky); - /** - * Destructor. - **/ - ~Matrix4(); - /** * Multiplies this Matrix with another Matrix, changing neither. * @param m The Matrix to multiply with this Matrix. @@ -106,6 +119,12 @@ public: * @param ky Shear along y-axis. **/ void setShear(float kx, float ky); + + /** + * Calculates the scale factors for a 2D affine transform. The output values + * are absolute (not signed). + **/ + void getApproximateScale(float &sx, float &sy) const; /** * Sets a transformation's values directly. Useful if you want to modify them inplace, @@ -166,21 +185,42 @@ public: void shear(float kx, float ky); /** - * Transforms an array of vertices by this Matrix. The sources and - * destination arrays may be the same. - * - * @param dst Storage for the transformed vertices. - * @param src The source vertices. - * @param size The number of vertices. + * Transforms an array of 2-component vertices by this Matrix. The source + * and destination arrays may be the same. **/ - template - void transform(V *dst, const V *src, int size) const; + template + void transformXY(Vdst *dst, const Vsrc *src, int size) const; /** - * Creates a new orthographic projection matrix with depth in the range of - * [-1, 1]. + * Transforms an array of 2-component vertices by this Matrix, and stores + * them in an array of 3-component vertices. **/ - static Matrix4 ortho(float left, float right, float bottom, float top); + template + void transformXY0(Vdst *dst, const Vsrc *src, int size) const; + + /** + * Transforms an array of 3-component vertices by this Matrix. The source + * and destination arrays may be the same. + **/ + template + void transformXYZ(Vdst *dst, const Vsrc *src, int size) const; + + /** + * Gets whether this matrix is an affine 2D transform (if the only non- + * identity elements are the upper-left 2x2 and 2 translation values in the + * 4th column). + **/ + bool isAffine2DTransform() const; + + /** + * Computes and returns the inverse of the matrix. + **/ + Matrix4 inverse() const; + + /** + * Creates a new orthographic projection matrix. + **/ + static Matrix4 ortho(float left, float right, float bottom, float top, float near, float far); private: @@ -249,8 +289,8 @@ public: /** * Transforms an array of vertices by this matrix. **/ - template - void transform(V *dst, const V *src, int size) const; + template + void transformXY(Vdst *dst, const Vsrc *src, int size) const; private: @@ -272,8 +312,8 @@ private: // | e2 e6 e10 e14 | // | e3 e7 e11 e15 | -template -void Matrix4::transform(V *dst, const V *src, int size) const +template +void Matrix4::transformXY(Vdst *dst, const Vsrc *src, int size) const { for (int i = 0; i < size; i++) { @@ -286,14 +326,55 @@ void Matrix4::transform(V *dst, const V *src, int size) const } } +template +void Matrix4::transformXY0(Vdst *dst, const Vsrc *src, int size) const +{ + for (int i = 0; i < size; i++) + { + // Store in temp variables in case src = dst + float x = (e[0]*src[i].x) + (e[4]*src[i].y) + (0) + (e[12]); + float y = (e[1]*src[i].x) + (e[5]*src[i].y) + (0) + (e[13]); + float z = (e[2]*src[i].x) + (e[6]*src[i].y) + (0) + (e[14]); + + dst[i].x = x; + dst[i].y = y; + dst[i].z = z; + } +} + +// | x | +// | y | +// | z | +// | 1 | +// | e0 e4 e8 e12 | +// | e1 e5 e9 e13 | +// | e2 e6 e10 e14 | +// | e3 e7 e11 e15 | + +template +void Matrix4::transformXYZ(Vdst *dst, const Vsrc *src, int size) const +{ + for (int i = 0; i < size; i++) + { + // Store in temp variables in case src = dst + float x = (e[0]*src[i].x) + (e[4]*src[i].y) + (e[ 8]*src[i].z) + (e[12]); + float y = (e[1]*src[i].x) + (e[5]*src[i].y) + (e[ 9]*src[i].z) + (e[13]); + float z = (e[2]*src[i].x) + (e[6]*src[i].y) + (e[10]*src[i].z) + (e[14]); + + dst[i].x = x; + dst[i].y = y; + dst[i].z = z; + } +} + // | x | // | y | // | 1 | // | e0 e3 e6 | // | e1 e4 e7 | // | e2 e5 e8 | -template -void Matrix3::transform(V *dst, const V *src, int size) const +template +void Matrix3::transformXY(Vdst *dst, const Vsrc *src, int size) const { for (int i = 0; i < size; i++) { diff --git a/love/src/jni/love/src/common/Memoizer.cpp b/love/src/jni/love/src/common/Memoizer.cpp index 6dd2d4e7..cab71006 100644 --- a/love/src/jni/love/src/common/Memoizer.cpp +++ b/love/src/jni/love/src/common/Memoizer.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff --git a/love/src/jni/love/src/common/Memoizer.h b/love/src/jni/love/src/common/Memoizer.h index db6fadb6..7e0047f7 100644 --- a/love/src/jni/love/src/common/Memoizer.h +++ b/love/src/jni/love/src/common/Memoizer.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff --git a/love/src/jni/love/src/common/Module.cpp b/love/src/jni/love/src/common/Module.cpp index 539804b0..0b054b77 100644 --- a/love/src/jni/love/src/common/Module.cpp +++ b/love/src/jni/love/src/common/Module.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -21,6 +21,7 @@ // LOVE #include "Module.h" #include "Exception.h" +#include "deprecation.h" // std #include @@ -58,8 +59,14 @@ namespace namespace love { +love::Type Module::type("Module", &Object::type); Module *Module::instances[] = {}; +Module::Module() +{ + initDeprecation(); +} + Module::~Module() { ModuleRegistry ®istry = registryInstance(); @@ -82,6 +89,8 @@ Module::~Module() } freeEmptyRegistry(); + + deinitDeprecation(); } void Module::registerInstance(Module *instance) diff --git a/love/src/jni/love/src/common/Module.h b/love/src/jni/love/src/common/Module.h index 25fc0996..89d76707 100644 --- a/love/src/jni/love/src/common/Module.h +++ b/love/src/jni/love/src/common/Module.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -34,9 +34,12 @@ class Module : public Object { public: + static love::Type type; + enum ModuleType { M_AUDIO, + M_DATA, M_EVENT, M_FILESYSTEM, M_FONT, @@ -52,11 +55,12 @@ public: M_THREAD, M_TIMER, M_TOUCH, - M_WINDOW, M_VIDEO, + M_WINDOW, M_MAX_ENUM }; + Module(); virtual ~Module(); /** diff --git a/love/src/jni/love/src/common/Object.cpp b/love/src/jni/love/src/common/Object.cpp index 1da5a7aa..dfedd482 100644 --- a/love/src/jni/love/src/common/Object.cpp +++ b/love/src/jni/love/src/common/Object.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -24,6 +24,8 @@ namespace love { +love::Type Object::type("Object", nullptr); + Object::Object() : count(1) { diff --git a/love/src/jni/love/src/common/Object.h b/love/src/jni/love/src/common/Object.h index 70562329..154b8e0c 100644 --- a/love/src/jni/love/src/common/Object.h +++ b/love/src/jni/love/src/common/Object.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -22,6 +22,7 @@ #define LOVE_OBJECT_H #include +#include "types.h" namespace love { @@ -38,6 +39,8 @@ class Object { public: + static love::Type type; + /** * Constructor. Sets reference count to one. **/ diff --git a/love/src/jni/love/src/common/Optional.h b/love/src/jni/love/src/common/Optional.h new file mode 100644 index 00000000..783bd31a --- /dev/null +++ b/love/src/jni/love/src/common/Optional.h @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2006-2018 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#pragma once + +namespace love +{ + +// Currently only meant for simple and small types. +template +struct Optional +{ + bool hasValue; + T value; + + Optional() + : hasValue(false) + , value(T()) + {} + + Optional(T val) + : hasValue(true) + , value(val) + {} + + void set(T val) + { + hasValue = true; + value = val; + } +}; + +typedef Optional OptionalBool; +typedef Optional OptionalFloat; +typedef Optional OptionalDouble; +typedef Optional OptionalInt; + +} // love diff --git a/love/src/jni/love/src/common/Reference.cpp b/love/src/jni/love/src/common/Reference.cpp index 6fa34e07..dff336d2 100644 --- a/love/src/jni/love/src/common/Reference.cpp +++ b/love/src/jni/love/src/common/Reference.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -45,7 +45,7 @@ Reference::~Reference() void Reference::ref(lua_State *L) { - unref(); // Just to be safe. + unref(); // Previously created reference needs to be cleared pinnedL = luax_getpinnedthread(L); luax_insist(L, LUA_REGISTRYINDEX, REFERENCE_TABLE_NAME); lua_insert(L, -2); // Move reference table behind value. diff --git a/love/src/jni/love/src/common/Reference.h b/love/src/jni/love/src/common/Reference.h index e5370c26..b50edf46 100644 --- a/love/src/jni/love/src/common/Reference.h +++ b/love/src/jni/love/src/common/Reference.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff --git a/love/src/jni/love/src/common/Stream.cpp b/love/src/jni/love/src/common/Stream.cpp new file mode 100644 index 00000000..d9139e35 --- /dev/null +++ b/love/src/jni/love/src/common/Stream.cpp @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2006-2015 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +// LOVE +#include "Stream.h" + +namespace love +{ + +love::Type Stream::type("Stream", &Object::type); + +} // love diff --git a/love/src/jni/love/src/common/Stream.h b/love/src/jni/love/src/common/Stream.h index 4b9b1db2..2b69144e 100644 --- a/love/src/jni/love/src/common/Stream.h +++ b/love/src/jni/love/src/common/Stream.h @@ -31,6 +31,8 @@ namespace love class Stream : public Object { public: + static love::Type type; + virtual ~Stream() {} // getData and getSize are assumed to talk about diff --git a/love/src/jni/love/src/common/StringMap.cpp b/love/src/jni/love/src/common/StringMap.cpp new file mode 100644 index 00000000..520ef08d --- /dev/null +++ b/love/src/jni/love/src/common/StringMap.cpp @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2006-2018 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#include "StringMap.h" + +// See the header +template class std::vector; +template decltype(std::vector().emplace_back("")) std::vector::emplace_back(const char *const&); diff --git a/love/src/jni/love/src/common/StringMap.h b/love/src/jni/love/src/common/StringMap.h index 5cc4d7aa..c9cbc24e 100644 --- a/love/src/jni/love/src/common/StringMap.h +++ b/love/src/jni/love/src/common/StringMap.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -23,6 +23,15 @@ #include "Exception.h" +#include +#include + +// As StringMap instantiates std::vector for instances that use +// getNames(), we end up with multiple copies in the object files. This +// declaration means we only emit it once (in StringMap.cpp). +extern template class std::vector; +extern template decltype(std::vector().emplace_back("")) std::vector::emplace_back(const char *const&); + namespace love { @@ -145,6 +154,18 @@ public: return hash; } + std::vector getNames() const + { + std::vector names; + names.reserve(SIZE); + + for (unsigned int i = 0; i < SIZE; ++i) + if (reverse[i] != nullptr) + names.emplace_back(reverse[i]); + + return names; + } + private: struct Record diff --git a/love/src/jni/love/src/common/Variant.cpp b/love/src/jni/love/src/common/Variant.cpp index 8fd893f3..fea1547f 100644 --- a/love/src/jni/love/src/common/Variant.cpp +++ b/love/src/jni/love/src/common/Variant.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -18,25 +18,27 @@ * 3. This notice may not be removed or altered from any source distribution. **/ +#include + #include "Variant.h" #include "common/StringMap.h" namespace love { -static love::Type extractudatatype(lua_State *L, int idx) +static Proxy *tryextractproxy(lua_State *L, int idx) { Proxy *u = (Proxy *)lua_touserdata(L, idx); - if (u == nullptr || u->type <= INVALID_ID || u->type >= TYPE_MAX_ENUM) - return INVALID_ID; + if (u == nullptr || u->type == nullptr) + return nullptr; // We could get rid of the dynamic_cast for more performance, but it would // be less safe... if (dynamic_cast(u->object) != nullptr) - return u->type; + return u; - return INVALID_ID; + return nullptr; } Variant::Variant() @@ -71,24 +73,20 @@ Variant::Variant(const char *string, size_t len) } } -Variant::Variant(void *userdata) +Variant::Variant(void *lightuserdata) : type(LUSERDATA) { - data.userdata = userdata; + data.userdata = lightuserdata; } -Variant::Variant(love::Type udatatype, void *userdata) - : type(FUSERDATA) - , udatatype(udatatype) +Variant::Variant(love::Type *lovetype, love::Object *object) + : type(LOVEOBJECT) { - if (udatatype != INVALID_ID) - { - Proxy *p = (Proxy *) userdata; - data.userdata = p->object; - p->object->retain(); - } - else - data.userdata = userdata; + data.objectproxy.type = lovetype; + data.objectproxy.object = object; + + if (data.objectproxy.object != nullptr) + data.objectproxy.object->retain(); } // Variant gets ownership of the vector. @@ -100,20 +98,18 @@ Variant::Variant(std::vector> *table) Variant::Variant(const Variant &v) : type(v.type) - , udatatype(v.udatatype) , data(v.data) { if (type == STRING) data.string->retain(); - else if (type == FUSERDATA) - ((love::Object *) data.userdata)->retain(); + else if (type == LOVEOBJECT && data.objectproxy.object != nullptr) + data.objectproxy.object->retain(); else if (type == TABLE) data.table->retain(); } Variant::Variant(Variant &&v) : type(std::move(v.type)) - , udatatype(std::move(v.udatatype)) , data(std::move(v.data)) { v.type = NIL; @@ -121,49 +117,41 @@ Variant::Variant(Variant &&v) Variant::~Variant() { - switch (type) - { - case STRING: + if (type == STRING) data.string->release(); - break; - case FUSERDATA: - ((love::Object *) data.userdata)->release(); - break; - case TABLE: + else if (type == LOVEOBJECT && data.objectproxy.object != nullptr) + data.objectproxy.object->release(); + else if (type == TABLE) data.table->release(); - break; - default: - break; - } } Variant &Variant::operator = (const Variant &v) { if (v.type == STRING) v.data.string->retain(); - else if (v.type == FUSERDATA) - ((love::Object *) v.data.userdata)->retain(); + else if (v.type == LOVEOBJECT && v.data.objectproxy.object != nullptr) + v.data.objectproxy.object->retain(); else if (v.type == TABLE) v.data.table->retain(); if (type == STRING) data.string->release(); - else if (type == FUSERDATA) - ((love::Object *) v.data.userdata)->release(); + else if (type == LOVEOBJECT && data.objectproxy.object != nullptr) + data.objectproxy.object->release(); else if (type == TABLE) data.table->release(); type = v.type; data = v.data; - udatatype = v.udatatype; return *this; } -Variant Variant::fromLua(lua_State *L, int n, bool allowTables) +Variant Variant::fromLua(lua_State *L, int n, std::set *tableSet) { size_t len; const char *str; + Proxy *p = nullptr; if (n < 0) // Fix the stack position, we might modify it later n += lua_gettop(L) + 1; @@ -180,15 +168,34 @@ Variant Variant::fromLua(lua_State *L, int n, bool allowTables) case LUA_TLIGHTUSERDATA: return Variant(lua_touserdata(L, n)); case LUA_TUSERDATA: - return Variant(extractudatatype(L, n), lua_touserdata(L, n)); + p = tryextractproxy(L, n); + if (p != nullptr) + return Variant(p->type, p->object); + else + { + luax_typerror(L, n, "love type"); + return Variant(); + } case LUA_TNIL: return Variant(); case LUA_TTABLE: - if (allowTables) { bool success = true; + std::unique_ptr> tableSetPtr; std::vector> *table = new std::vector>(); + // If we had no tables argument, allocate one now, and store it in our unique_ptr + if (tableSet == nullptr) + tableSetPtr.reset(tableSet = new std::set); + + // Now make sure this table wasn't already serialised + const void *tablePointer = lua_topointer(L, n); + { + auto result = tableSet->insert(tablePointer); + if (!result.second) // insertion failed + throw love::Exception("Cycle detected in table"); + } + size_t len = luax_objlen(L, -1); if (len > 0) table->reserve(len); @@ -197,7 +204,7 @@ Variant Variant::fromLua(lua_State *L, int n, bool allowTables) while (lua_next(L, n)) { - table->emplace_back(fromLua(L, -2), fromLua(L, -1)); + table->emplace_back(fromLua(L, -2, tableSet), fromLua(L, -1, tableSet)); lua_pop(L, 1); const auto &p = table->back(); @@ -208,6 +215,9 @@ Variant Variant::fromLua(lua_State *L, int n, bool allowTables) } } + // And remove the table from the set again + tableSet->erase(tablePointer); + if (success) return Variant(table); else @@ -240,14 +250,8 @@ void Variant::toLua(lua_State *L) const case LUSERDATA: lua_pushlightuserdata(L, data.userdata); break; - case FUSERDATA: - if (udatatype != INVALID_ID) - luax_pushtype(L, udatatype, (love::Object *) data.userdata); - else - lua_pushlightuserdata(L, data.userdata); - // I know this is not the same - // sadly, however, it's the most - // I can do (at the moment). + case LOVEOBJECT: + luax_pushtype(L, *data.objectproxy.type, data.objectproxy.object); break; case TABLE: { diff --git a/love/src/jni/love/src/common/Variant.h b/love/src/jni/love/src/common/Variant.h index 87e5d357..6ed6a624 100644 --- a/love/src/jni/love/src/common/Variant.h +++ b/love/src/jni/love/src/common/Variant.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -27,6 +27,7 @@ #include #include +#include namespace love { @@ -43,7 +44,7 @@ public: STRING, SMALLSTRING, LUSERDATA, - FUSERDATA, + LOVEOBJECT, NIL, TABLE }; @@ -52,8 +53,8 @@ public: Variant(bool boolean); Variant(double number); Variant(const char *string, size_t len); - Variant(void *userdata); - Variant(love::Type udatatype, void *userdata); + Variant(void *lightuserdata); + Variant(love::Type *type, love::Object *object); Variant(std::vector> *table); Variant(const Variant &v); Variant(Variant &&v); @@ -63,7 +64,7 @@ public: Type getType() const { return type; } - static Variant fromLua(lua_State *L, int n, bool allowTables = true); + static Variant fromLua(lua_State *L, int n, std::set *tableSet = nullptr); void toLua(lua_State *L) const; private: @@ -101,7 +102,6 @@ private: static const int MAX_SMALL_STRING_LENGTH = 15; Type type; - love::Type udatatype; union Data { @@ -109,6 +109,7 @@ private: double number; SharedString *string; void *userdata; + Proxy objectproxy; SharedTable *table; struct { diff --git a/love/src/jni/love/src/common/Vector.cpp b/love/src/jni/love/src/common/Vector.cpp index 30a6a06a..2ceb8f4f 100644 --- a/love/src/jni/love/src/common/Vector.cpp +++ b/love/src/jni/love/src/common/Vector.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff --git a/love/src/jni/love/src/common/Vector.h b/love/src/jni/love/src/common/Vector.h index 8aba271b..e333a3a1 100644 --- a/love/src/jni/love/src/common/Vector.h +++ b/love/src/jni/love/src/common/Vector.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -24,45 +24,30 @@ // STD #include -// LOVE -#include "Matrix.h" - namespace love { -/** - * 2D Vector class. - * - * @author Anders Ruud - * @date 2006-05-13 - **/ -class Vector +struct Vector2 { -public: - - // The components. float x, y; - /** - * Creates a new (1,1) Vector. - **/ - Vector(); + Vector2() + : x(0.0f), y(0.0f) + {} - /** - * Creates a new Vector. - * @param x The x position/dimension. - * @param y The y position/dimension. - **/ - Vector(float x, float y); + Vector2(float x, float y) + : x(x), y(y) + {} + + Vector2(const Vector2 &v) + : x(v.x), y(v.y) + {} /** * Gets the length of the Vector. - * @return The length of the Vector. - * - * This method requires sqrtf() and should be used - * carefully. **/ float getLength() const; + float getLengthSquare() const; /** * Normalizes the Vector. @@ -76,7 +61,7 @@ public: * To get the true (normalized) normal, use v.getNormal(1.0f / v.getLength()) * @return A normal to the Vector. **/ - Vector getNormal() const; + Vector2 getNormal() const; /** * Gets a vector perpendicular to the Vector. @@ -84,125 +69,177 @@ public: * @param scale factor to apply. * @return A normal to the Vector. **/ - Vector getNormal(float scale) const; + Vector2 getNormal(float scale) const; + + static inline float dot(const Vector2 &a, const Vector2 &b); + static inline float cross(const Vector2 &a, const Vector2 &b); /** * Adds a Vector to this Vector. - * @param v The Vector we want to add to this Vector. - * @return The resulting Vector. **/ - Vector operator + (const Vector &v) const; + Vector2 operator + (const Vector2 &v) const; /** - * Substracts a Vector to this Vector. - * @param v The Vector we want to subtract to this Vector. - * @return The resulting Vector. + * Substracts a Vector from this Vector. **/ - Vector operator - (const Vector &v) const; + Vector2 operator - (const Vector2 &v) const; /** - * Resizes a Vector by a scalar. - * @param s The scalar with which to resize the Vector. - * @return The resulting Vector. + * Component-wise multiplies the Vector by a scalar. **/ - Vector operator * (float s) const; + Vector2 operator * (float s) const; /** - * Resizes a Vector by a scalar. - * @param s The scalar with which to resize the Vector. - * @return The resulting Vector. + * Component-wise divides the Vector by a scalar. **/ - Vector operator / (float s) const; + Vector2 operator / (float s) const; /** - * Reverses the Vector. - * @return The reversed Vector. + * Component-wise negates the Vector. **/ - Vector operator - () const; + Vector2 operator - () const; /** * Adds a Vector to this Vector, and also saves changes in the first Vector. - * @param v The Vector we want to add to this Vector. **/ - void operator += (const Vector &v); + void operator += (const Vector2 &v); /** * Subtracts a Vector to this Vector, and also saves changes in the first Vector. - * @param v The Vector we want to subtract to this Vector. **/ - void operator -= (const Vector &v); + void operator -= (const Vector2 &v); /** * Resizes the Vector, and also saves changes in the first Vector. - * @param s The scalar by which we want to resize the Vector. **/ void operator *= (float s); /** * Resizes the Vector, and also saves changes in the first Vector. - * @param s The scalar by which we want to resize the Vector. **/ void operator /= (float s); - /** - * Calculates the dot product of two Vectors. - * @return The dot product of the two Vectors. - **/ - float operator * (const Vector &v) const; + bool operator == (const Vector2 &v) const; + bool operator != (const Vector2 &v) const; + +}; // Vector2 + + +struct Vector3 +{ + float x, y, z; + + Vector3() + : x(0.0f), y(0.0f), z(0.0f) + {} + + Vector3(float x, float y, float z) + : x(x), y(y), z(z) + {} + + Vector3(const Vector2 &v) + : x(v.x), y(v.y), z(0.0f) + {} /** - * Calculates the cross product of two Vectors. - * @return The cross product of the two Vectors. + * Gets the length of the Vector. **/ - float operator ^ (const Vector &v) const; - - bool operator == (const Vector &v) const; - - bool operator < (const Vector &v) const; - /** - * Gets the x value of the Vector. - * @return The x value of the Vector. - **/ - float getX() const; + float getLength() const; + float getLengthSquare() const; /** - * Gets the x value of the Vector. - * @return The x value of the Vector. + * Normalizes the Vector. + * @param length Desired length of the vector. + * @return The old length of the Vector. **/ - float getY() const; + float normalize(float length = 1.0); + + static inline float dot(const Vector3 &a, const Vector3 &b); + static inline Vector3 cross(const Vector3 &a, const Vector3 &b); /** - * Sets the x value of the Vector. - * @param x The x value of the Vector. + * Adds a Vector to this Vector. **/ - void setX(float x); + Vector3 operator + (const Vector3 &v) const; /** - * Sets the x value of the Vector. - * @param y The x value of the Vector. + * Substracts a Vector from this Vector. **/ - void setY(float y); + Vector3 operator - (const Vector3 &v) const; -}; + /** + * Component-wise multiplies the Vector by a scalar. + **/ + Vector3 operator * (float s) const; -inline float Vector::getLength() const + /** + * Component-wise divides the Vector by a scalar. + **/ + Vector3 operator / (float s) const; + + /** + * Component-wise negates the Vector. + **/ + Vector3 operator - () const; + + /** + * Adds a Vector to this Vector, and also saves changes in the first Vector. + **/ + void operator += (const Vector3 &v); + + /** + * Subtracts a Vector to this Vector, and also saves changes in the first Vector. + **/ + void operator -= (const Vector3 &v); + + /** + * Resizes the Vector, and also saves changes in the first Vector. + **/ + void operator *= (float s); + + /** + * Resizes the Vector, and also saves changes in the first Vector. + **/ + void operator /= (float s); + + bool operator == (const Vector3 &v) const; + bool operator != (const Vector3 &v) const; + +}; // Vector3 + + +inline float Vector2::getLength() const { return sqrtf(x*x + y*y); } -inline Vector Vector::getNormal() const +inline float Vector2::getLengthSquare() const { - return Vector(-y, x); + return x*x + y*y; } -inline Vector Vector::getNormal(float scale) const +inline Vector2 Vector2::getNormal() const { - return Vector(-y * scale, x * scale); + return Vector2(-y, x); } -inline float Vector::normalize(float length) +inline Vector2 Vector2::getNormal(float scale) const { + return Vector2(-y * scale, x * scale); +} +inline float Vector2::dot(const Vector2 &a, const Vector2 &b) +{ + return a.x * b.x + a.y * b.y; +} + +inline float Vector2::cross(const Vector2 &a, const Vector2 &b) +{ + return a.x * b.y - a.y * b.x; +} + +inline float Vector2::normalize(float length) +{ float length_current = getLength(); if (length_current > 0) @@ -211,113 +248,161 @@ inline float Vector::normalize(float length) return length_current; } -/** - * Inline methods must have body in header. - **/ - -inline Vector::Vector() - : x(0.0f) - , y(0.0f) +inline Vector2 Vector2::operator + (const Vector2 &v) const { + return Vector2(x + v.x, y + v.y); } -inline Vector::Vector(float x, float y) - : x(x) - , y(y) +inline Vector2 Vector2::operator - (const Vector2 &v) const { + return Vector2(x - v.x, y - v.y); } -inline Vector Vector::operator + (const Vector &v) const +inline Vector2 Vector2::operator * (float s) const { - return Vector(x + v.x, y + v.y); + return Vector2(x*s, y*s); } -inline Vector Vector::operator - (const Vector &v) const +inline Vector2 Vector2::operator / (float s) const { - return Vector(x - v.getX(), y - v.getY()); + float invs = 1.0f / s; + return Vector2(x*invs, y*invs); } -inline Vector Vector::operator * (float s) const +inline Vector2 Vector2::operator - () const { - return Vector(x*s, y*s); + return Vector2(-x, -y); } -inline Vector Vector::operator / (float s) const +inline void Vector2::operator += (const Vector2 &v) { - return Vector(x/s, y/s); + x += v.x; + y += v.y; } -inline Vector Vector::operator - () const +inline void Vector2::operator -= (const Vector2 &v) { - return Vector(-x, -y); + x -= v.x; + y -= v.y; } -inline void Vector::operator += (const Vector &v) -{ - x += v.getX(); - y += v.getY(); -} - -inline void Vector::operator -= (const Vector &v) -{ - x -= v.getX(); - y -= v.getY(); -} - -inline void Vector::operator *= (float s) +inline void Vector2::operator *= (float s) { x *= s; y *= s; } -inline void Vector::operator /= (float s) +inline void Vector2::operator /= (float s) { - x /= s; - y /= s; + float invs = 1.0f / s; + x *= invs; + y *= invs; } -inline float Vector::operator * (const Vector &v) const +inline bool Vector2::operator == (const Vector2 &v) const { - return x * v.getX() + y * v.getY(); + return x == v.x && y == v.y; } -inline float Vector::operator ^ (const Vector &v) const +inline bool Vector2::operator != (const Vector2 &v) const { - return x * v.getY() - y * v.getX(); + return x != v.x || y != v.y; } -inline bool Vector::operator == (const Vector &v) const + +inline float Vector3::getLength() const { - return getLength() == v.getLength(); + return sqrtf(x*x + y*y + z*z); } -inline bool Vector::operator < (const Vector &v) const +inline float Vector3::getLengthSquare() const { - return getLength() < v.getLength(); + return x*x + y*y + z*z; } -/** - * Accessor methods - **/ - -inline float Vector::getX() const +inline float Vector3::dot(const Vector3 &a, const Vector3 &b) { - return x; + return a.x * b.x + a.y * b.y + a.z * b.z; } -inline float Vector::getY() const +inline Vector3 Vector3::cross(const Vector3 &a, const Vector3 &b) { - return y; + return Vector3(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x); } -inline void Vector::setX(float x) +inline float Vector3::normalize(float length) { - this->x = x; + float length_current = getLength(); + + if (length_current > 0) + (*this) *= length / length_current; + + return length_current; } -inline void Vector::setY(float y) +inline Vector3 Vector3::operator + (const Vector3 &v) const { - this->y = y; + return Vector3(x + v.x, y + v.y, z + v.z); +} + +inline Vector3 Vector3::operator - (const Vector3 &v) const +{ + return Vector3(x - v.x, y - v.y, z - v.z); +} + +inline Vector3 Vector3::operator * (float s) const +{ + return Vector3(x*s, y*s, z*s); +} + +inline Vector3 Vector3::operator / (float s) const +{ + float invs = 1.0f / s; + return Vector3(x*invs, y*invs, z*invs); +} + +inline Vector3 Vector3::operator - () const +{ + return Vector3(-x, -y, -z); +} + +inline void Vector3::operator += (const Vector3 &v) +{ + x += v.x; + y += v.y; + z += v.z; +} + +inline void Vector3::operator -= (const Vector3 &v) +{ + x -= v.x; + y -= v.y; + z -= v.z; +} + +inline void Vector3::operator *= (float s) +{ + x *= s; + y *= s; + z *= s; +} + +inline void Vector3::operator /= (float s) +{ + float invs = 1.0f / s; + x *= invs; + y *= invs; + z *= invs; +} + +inline bool Vector3::operator == (const Vector3 &v) const +{ + return x == v.x && y == v.y && z == v.z; +} + +inline bool Vector3::operator != (const Vector3 &v) const +{ + return x != v.x || y != v.y || z != v.z; } } //love diff --git a/love/src/jni/love/src/common/android.cpp b/love/src/jni/love/src/common/android.cpp index 872ec2d4..8e758852 100644 --- a/love/src/jni/love/src/common/android.cpp +++ b/love/src/jni/love/src/common/android.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -225,6 +225,22 @@ bool createStorageDirectories() return true; } +bool hasBackgroundMusic() +{ + JNIEnv *env = (JNIEnv*) SDL_AndroidGetJNIEnv(); + jobject activity = (jobject) SDL_AndroidGetActivity(); + + jclass clazz(env->GetObjectClass(activity)); + jmethodID method_id = env->GetMethodID(clazz, "hasBackgroundMusic", "()Z"); + + jboolean result = env->CallBooleanMethod(activity, method_id); + + env->DeleteLocalRef(activity); + env->DeleteLocalRef(clazz); + + return result; +} + } // android } // love diff --git a/love/src/jni/love/src/common/android.h b/love/src/jni/love/src/common/android.h index 1e4e62a3..247fc8d9 100644 --- a/love/src/jni/love/src/common/android.h +++ b/love/src/jni/love/src/common/android.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -66,6 +66,8 @@ bool mkdir(const char *path); bool createStorageDirectories(); +bool hasBackgroundMusic(); + } // android } // love diff --git a/love/src/jni/love/src/common/b64.cpp b/love/src/jni/love/src/common/b64.cpp index bc3bd6f6..fb5dc1e7 100644 --- a/love/src/jni/love/src/common/b64.cpp +++ b/love/src/jni/love/src/common/b64.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -19,12 +19,98 @@ **/ #include "b64.h" +#include "Exception.h" + +#include +#include namespace love { +// Translation table as described in RFC1113 +static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +// Translation table to decode (created by Bob Trower) static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq"; +/** + * encode 3 8-bit binary bytes as 4 '6-bit' characters + **/ +static void b64_encode_block(char in[3], char out[4], int len) +{ + out[0] = (char) cb64[(int)(in[0] >> 2)]; + out[1] = (char) cb64[(int)(((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4))]; + out[2] = (char) (len > 1 ? cb64[(int)(((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6))] : '='); + out[3] = (char) (len > 2 ? cb64[(int)(in[2] & 0x3f)] : '='); +} + +char *b64_encode(const char *src, size_t srclen, size_t linelen, size_t &dstlen) +{ + if (linelen == 0) + linelen = std::numeric_limits::max(); + + size_t blocksout = 0; + size_t srcpos = 0; + + size_t adjustment = (srclen % 3) ? (3 - (srclen % 3)) : 0; + size_t paddedlen = ((srclen + adjustment) / 3) * 4; + + dstlen = paddedlen + paddedlen / linelen; + + if (dstlen == 0) + return nullptr; + + char *dst = nullptr; + try + { + dst = new char[dstlen + 1]; + } + catch (std::exception &) + { + throw love::Exception("Out of memory."); + } + + size_t dstpos = 0; + + while (srcpos < srclen) + { + char in[3] = {0}; + char out[4] = {0}; + + int len = 0; + + for (int i = 0; i < 3; i++) + { + if (srcpos >= srclen) + break; + + in[i] = src[srcpos++]; + len++; + } + + if (len > 0) + { + b64_encode_block(in, out, len); + + for (int i = 0; i < 4 && dstpos < dstlen; i++, dstpos++) + dst[dstpos] = out[i]; + + blocksout++; + } + + if (blocksout >= linelen / 4 || srcpos >= srclen) + { + if (blocksout > 0 && dstpos < dstlen) + dst[dstpos++] = '\n'; + + blocksout = 0; + } + } + + dst[dstpos] = '\0'; + return dst; +} + static void b64_decode_block(char in[4], char out[3]) { out[0] = (char)(in[0] << 2 | in[1] >> 4); @@ -32,36 +118,44 @@ static void b64_decode_block(char in[4], char out[3]) out[2] = (char)(((in[2] << 6) & 0xc0) | in[3]); } -char *b64_decode(const char *src, int slen, int &size) +char *b64_decode(const char *src, size_t srclen, size_t &size) { - // Actual output may be smaller due to padding and/or whitespace in the - // base64-encoded string. - int max_size = (slen / 4) * 3; + size_t paddedsize = (srclen / 4) * 3; + + char *dst = nullptr; + try + { + dst = new char[paddedsize]; + } + catch (std::exception &) + { + throw love::Exception("Out of memory."); + } - char *dst = new char[max_size]; char *d = dst; - char in[4] = {0}, out[3], v; - int i, len, pos = 0; + char in[4] = {0}; + char out[3] = {0}; + size_t i, len, srcpos = 0; - while (pos <= slen) + while (srcpos <= srclen) { - for (len = 0, i = 0; i < 4 && pos <= slen; i++) + for (len = 0, i = 0; i < 4 && srcpos <= srclen; i++) { - v = 0; + char v = 0; - while (pos <= slen && v == 0) + while (srcpos <= srclen && v == 0) { - v = src[pos++]; + v = src[srcpos++]; v = (char)((v < 43 || v > 122) ? 0 : cd64[v - 43]); - if (v) + if (v != 0) v = (char)((v == '$') ? 0 : v - 61); } - if (pos <= slen) + if (srcpos <= srclen) { len++; - if (v) + if (v != 0) in[i] = (char)(v - 1); } else @@ -72,12 +166,11 @@ char *b64_decode(const char *src, int slen, int &size) { b64_decode_block(in, out); for (i = 0; i < len - 1; i++) - *(d++) = out[i]; + *(d++) = out[i]; } } - size = int(d - dst); - + size = (size_t)(ptrdiff_t) (d - dst); return dst; } diff --git a/love/src/jni/love/src/common/b64.h b/love/src/jni/love/src/common/b64.h index ad586a6f..01e0ea5f 100644 --- a/love/src/jni/love/src/common/b64.h +++ b/love/src/jni/love/src/common/b64.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -20,21 +20,35 @@ #include "config.h" +#include + #ifndef LOVE_B64_H #define LOVE_B64_H namespace love { +/** + * Base64-encode data. + * + * @param src The data to encode. + * @param srclen The size in bytes of the data. + * @param linelen The maximum length of each line in the encoded string. + * 0 indicates no maximum length. + * @param dstlen The length of the encoded string is stored here. + * @return A string containing the base64-encoded data (allocated with new[]). + */ +char *b64_encode(const char *src, size_t srclen, size_t linelen, size_t &dstlen); + /** * Decode base64 encoded data. * * @param src The string containing the base64 data. - * @param slen The length of the string. - * @param size The size of the binary data is stored here. + * @param srclen The length of the string. + * @param dstlen The size of the binary data is stored here. * @return A chunk of memory containing the binary data (allocated with new[]). */ -char *b64_decode(const char *src, int slen, int &size); +char *b64_decode(const char *src, size_t srclen, size_t &dstlen); } // love diff --git a/love/src/jni/love/src/common/config.h b/love/src/jni/love/src/common/config.h index 8bb43bab..8180f6ae 100644 --- a/love/src/jni/love/src/common/config.h +++ b/love/src/jni/love/src/common/config.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -26,7 +26,7 @@ # define LOVE_WINDOWS 1 // If _USING_V110_SDK71_ is defined it means we are using the xp toolset. # if defined(_MSC_VER) && (_MSC_VER >= 1700) && !_USING_V110_SDK71_ -# include +# include # if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) # define LOVE_WINDOWS_UWP 1 # define LOVE_NO_MODPLUG 1 @@ -60,6 +60,22 @@ # define LOVE_LITTLE_ENDIAN 1 #endif +// SSE instructions. +#if defined(__SSE__) +# define LOVE_SIMD_SSE +#elif defined(_MSC_VER) +# if defined(_M_AMD64) || defined(_M_X64) +# define LOVE_SIMD_SSE +# elif _M_IX86_FP +# define LOVE_SIMD_SSE +# endif +#endif + +// NEON instructions. +#if defined(__ARM_NEON) +# define LOVE_SIMD_NEON +#endif + // Warnings. #ifndef _CRT_SECURE_NO_WARNINGS # define _CRT_SECURE_NO_WARNINGS @@ -70,6 +86,16 @@ # define LOVE_UNUSED(x) (void)sizeof(x) #endif + +// Warn on unused return values +#ifdef __GNUC__ +# define LOVE_WARN_UNUSED __attribute__((warn_unused_result)) +#elif _MSC_VER +# define LOVE_WARN_UNUSED _Check_return_ +#else +# define LOVE_WARN_UNUSED +#endif + #ifndef LOVE_BUILD # define LOVE_BUILD # define LOVE_BUILD_STANDALONE @@ -111,51 +137,30 @@ # define LOVE_LITTLE_ENDIAN 1 # endif #else -# define LOVE_ENABLE_AUDIO -# define LOVE_ENABLE_AUDIO_NULL -# define LOVE_ENABLE_AUDIO_OPENAL -# define LOVE_ENABLE_BOX2D -# define LOVE_ENABLE_DDSPARSE -# define LOVE_ENABLE_ENET -# define LOVE_ENABLE_EVENT -# define LOVE_ENABLE_EVENT_SDL -# define LOVE_ENABLE_FILESYSTEM -# define LOVE_ENABLE_FILESYSTEM_PHYSFS -# define LOVE_ENABLE_FONT -# define LOVE_ENABLE_FONT_FREETYPE -# define LOVE_ENABLE_GRAPHICS -# define LOVE_ENABLE_GRAPHICS_OPENGL -# define LOVE_ENABLE_IMAGE -# define LOVE_ENABLE_IMAGE_MAGPIE -# define LOVE_ENABLE_JOYSTICK -# define LOVE_ENABLE_JOYSTICK_SDL -# define LOVE_ENABLE_KEYBOARD -# define LOVE_ENABLE_KEYBOARD_SDL # define LOVE_ENABLE_LOVE -# define LOVE_ENABLE_LUASOCKET -# define LOVE_ENABLE_LUAUTF8 +# define LOVE_ENABLE_AUDIO +# define LOVE_ENABLE_DATA +# define LOVE_ENABLE_EVENT +# define LOVE_ENABLE_FILESYSTEM +# define LOVE_ENABLE_FONT +# define LOVE_ENABLE_GRAPHICS +# define LOVE_ENABLE_IMAGE +# define LOVE_ENABLE_JOYSTICK +# define LOVE_ENABLE_KEYBOARD # define LOVE_ENABLE_MATH # define LOVE_ENABLE_MOUSE -# define LOVE_ENABLE_MOUSE_SDL -# define LOVE_ENABLE_NOISE1234 # define LOVE_ENABLE_PHYSICS -# define LOVE_ENABLE_PHYSICS_BOX2D # define LOVE_ENABLE_SOUND -# define LOVE_ENABLE_SOUND_LULLABY # define LOVE_ENABLE_SYSTEM -# define LOVE_ENABLE_SYSTEM_SDL # define LOVE_ENABLE_THREAD -# define LOVE_ENABLE_THREAD_SDL # define LOVE_ENABLE_TIMER -# define LOVE_ENABLE_TIMER_SDL # define LOVE_ENABLE_TOUCH -# define LOVE_ENABLE_TOUCH_SDL -# define LOVE_ENABLE_UTF8 # define LOVE_ENABLE_VIDEO -# define LOVE_ENABLE_VIDEO_THEORA # define LOVE_ENABLE_WINDOW -# define LOVE_ENABLE_WINDOW_SDL -# define LOVE_ENABLE_WUFF + +# define LOVE_ENABLE_ENET +# define LOVE_ENABLE_LUASOCKET +# define LOVE_ENABLE_LUA53 #endif // Check we have a sane configuration diff --git a/love/src/jni/love/src/common/delay.cpp b/love/src/jni/love/src/common/delay.cpp index 9208f843..e803fc6d 100644 --- a/love/src/jni/love/src/common/delay.cpp +++ b/love/src/jni/love/src/common/delay.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -27,6 +27,8 @@ namespace love void sleep(unsigned int ms) { + // We don't need to initialize the SDL timer subsystem for SDL_Delay to + // function - and doing so causes SDL to create a worker thread. SDL_Delay(ms); } diff --git a/love/src/jni/love/src/common/delay.h b/love/src/jni/love/src/common/delay.h index 566139ca..1974da66 100644 --- a/love/src/jni/love/src/common/delay.h +++ b/love/src/jni/love/src/common/delay.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff --git a/love/src/jni/love/src/common/deprecation.cpp b/love/src/jni/love/src/common/deprecation.cpp new file mode 100644 index 00000000..1efb2952 --- /dev/null +++ b/love/src/jni/love/src/common/deprecation.cpp @@ -0,0 +1,187 @@ +/** + * Copyright (c) 2006-2018 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#include "common/config.h" +#include "deprecation.h" +#include "thread/threads.h" + +#include +#include + +namespace love +{ + +static std::map *deprecated = nullptr; +static std::vector *deprecatedList = nullptr; + +static std::atomic initCount; + +static thread::Mutex *mutex = nullptr; +static bool outputEnabled = false; + +void initDeprecation() +{ + if (initCount.fetch_add(1) == 0) + { + mutex = thread::newMutex(); + + // These are heap-allocated because we want to clear them on deinit, + // and deinit may be called when the program is shutting down in the + // middle of static variable cleanup (eg in the Math module destructor). + // Calling std::map::clear() in that case was causing segfaults. + deprecated = new std::map(); + deprecatedList = new std::vector(); + } +} + +void deinitDeprecation() +{ + if (initCount.fetch_sub(1) == 1) + { + delete deprecated; + delete deprecatedList; + delete mutex; + + deprecated = nullptr; + deprecatedList = nullptr; + mutex = nullptr; + } +} + +static void printDeprecationNotice(const DeprecationInfo &info) +{ + std::string notice = getDeprecationNotice(info, true); + printf("LOVE - Warning: %s\n", notice.c_str()); +} + +void setDeprecationOutputEnabled(bool enable) +{ + if (enable == outputEnabled) + return; + + outputEnabled = enable; + + if (enable) + { + GetDeprecated deprecated; + + for (const DeprecationInfo *info : deprecated.all) + { + if (info->uses == 1) + printDeprecationNotice(*info); + } + } +} + +bool isDeprecationOutputEnabled() +{ + return outputEnabled; +} + +std::string getDeprecationNotice(const DeprecationInfo &info, bool usewhere) +{ + std::string notice; + + if (usewhere) + notice += info.where; + + notice += "Using deprecated "; + + if (info.apiType == API_FUNCTION) + notice += "function "; + else if (info.apiType == API_METHOD) + notice += "method "; + else if (info.apiType == API_FIELD) + notice += "field "; + else if (info.apiType == API_CONSTANT) + notice += "constant "; + else + notice += "API "; + + notice += info.name; + + if (info.type == DEPRECATED_REPLACED && !info.replacement.empty()) + notice += " (replaced by " + info.replacement + ")"; + else if (info.type == DEPRECATED_RENAMED && !info.replacement.empty()) + notice += " (renamed to " + info.replacement + ")"; + + return notice; +} + +GetDeprecated::GetDeprecated() + : all(*deprecatedList) +{ + if (mutex != nullptr) + mutex->lock(); +} + +GetDeprecated::~GetDeprecated() +{ + if (mutex != nullptr) + mutex->unlock(); +} + +MarkDeprecated::MarkDeprecated(const char *name, APIType api) + : MarkDeprecated(name, api, DEPRECATED_NO_REPLACEMENT, nullptr) +{ +} + +MarkDeprecated::MarkDeprecated(const char *name, APIType api, DeprecationType type, const char *replacement) + : info(nullptr) +{ + if (mutex != nullptr) + mutex->lock(); + + auto it = deprecated->find(name); + + if (it != deprecated->end()) + { + it->second.uses++; + info = &it->second; + } + else + { + DeprecationInfo newinfo = {}; + + newinfo.type = type; + newinfo.apiType = api; + newinfo.uses = 1; + newinfo.name = name; + + if (replacement != nullptr) + newinfo.replacement = replacement; + + auto inserted = deprecated->insert(std::make_pair(newinfo.name, newinfo)); + + info = &inserted.first->second; + deprecatedList->push_back(info); + } +} + +MarkDeprecated::~MarkDeprecated() +{ + if (outputEnabled && info != nullptr && info->uses == 1) + printDeprecationNotice(*info); + + if (mutex != nullptr) + mutex->unlock(); +} + +} // love diff --git a/love/src/jni/love/src/common/deprecation.h b/love/src/jni/love/src/common/deprecation.h new file mode 100644 index 00000000..4d81e156 --- /dev/null +++ b/love/src/jni/love/src/common/deprecation.h @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2006-2018 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#pragma once + +#include "int.h" + +#include +#include + +namespace love +{ + +enum APIType +{ + API_FUNCTION, + API_METHOD, + API_FIELD, + API_CONSTANT, +}; + +enum DeprecationType +{ + DEPRECATED_NO_REPLACEMENT, + DEPRECATED_REPLACED, + DEPRECATED_RENAMED, +}; + +struct DeprecationInfo +{ + DeprecationType type; + APIType apiType; + int64 uses; + std::string name; + std::string replacement; + std::string where; +}; + +void initDeprecation(); +void deinitDeprecation(); + +void setDeprecationOutputEnabled(bool enable); +bool isDeprecationOutputEnabled(); + +std::string getDeprecationNotice(const DeprecationInfo &info, bool usewhere); + +struct GetDeprecated +{ + GetDeprecated(); + ~GetDeprecated(); + + const std::vector &all; +}; + +struct MarkDeprecated +{ + MarkDeprecated(const char *name, APIType api); + MarkDeprecated(const char *name, APIType api, DeprecationType type, const char *replacement); + ~MarkDeprecated(); + + DeprecationInfo *info; +}; + +} // love diff --git a/love/src/jni/love/src/common/halffloat.cpp b/love/src/jni/love/src/common/halffloat.cpp new file mode 100644 index 00000000..59eaacf5 --- /dev/null +++ b/love/src/jni/love/src/common/halffloat.cpp @@ -0,0 +1,156 @@ +/** + * Copyright (c) 2006-2018 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#include "halffloat.h" + +namespace love +{ + +// Code from ftp://www.fox-toolkit.org/pub/fasthalffloatconversion.pdf + +static bool initialized = false; + +// tables for half -> float conversions +static uint32 mantissatable[2048]; +static uint16 offsettable[64]; +static uint32 exponenttable[64]; + +// tables for float -> half conversions +static uint16 basetable[512]; +static uint8 shifttable[512]; + + +static uint32 convertMantissa(uint32 i) +{ + uint32 m = i << 13; // Zero pad mantissa bits + uint32 e = 0; // Zero exponent + + while (!(m & 0x00800000)) // While not normalized + { + e -= 0x00800000; // Decrement exponent (1<<23) + m <<= 1; // Shift mantissa + } + + m &= ~(0x00800000); // Clear leading 1 bit + e += 0x38800000; // Adjust bias ((127-14)<<23) + + return m | e; // Return combined number +} + +void halfInit() +{ + if (initialized) + return; + + initialized = true; + + + // tables for half -> float conversions. + + mantissatable[0] = 0; + + for (uint32 i = 1; i < 1024; i++) + mantissatable[i] = convertMantissa(i); + + for (uint32 i = 1024; i < 2048; i++) + mantissatable[i] = 0x38000000 + ((i - 1024) << 13); + + exponenttable[0] = 0; + exponenttable[32] = 0x80000000; + + for (uint32 i = 0; i < 31; i++) + exponenttable[i] = i << 23; + + for (uint32 i = 33; i < 63; i++) + exponenttable[i] = 0x80000000 + ((i - 32) << 23); + + exponenttable[31] = 0x47800000; + exponenttable[63] = 0xC7800000; + + for (int i = 0; i < 64; i++) + { + if (i == 0 || i == 32) + offsettable[i] = 0; + else + offsettable[i] = 1024; + } + + + // tables for float -> half conversions. + + for (uint32 i = 0; i < 256; i++) + { + int e = (int) i - 127; + + if (e < -24) // Very small numbers map to zero + { + basetable[i | 0x000] = 0x0000; + basetable[i | 0x100] = 0x8000; + shifttable[i | 0x000] = 24; + shifttable[i | 0x100] = 24; + } + else if (e < -14) // Small numbers map to denorms + { + basetable[i | 0x000] = (0x0400 >> (-e - 14)); + basetable[i | 0x100] = (0x0400 >> (-e - 14)) | 0x8000; + shifttable[i | 0x000] = -e - 1; + shifttable[i | 0x100] = -e - 1; + } + else if (e <= 15) // Normal numbers just lose precision + { + basetable[i | 0x000] = ((e + 15) << 10); + basetable[i | 0x100] = ((e + 15) << 10) | 0x8000; + shifttable[i | 0x000] = 13; + shifttable[i | 0x100] = 13; + } + else if (e < 128) // Large numbers map to Infinity + { + basetable[i | 0x000] = 0x7C00; + basetable[i | 0x100] = 0xFC00; + shifttable[i | 0x000] = 24; + shifttable[i | 0x100] = 24; + } + else // Infinity and NaN's stay Infinity and NaN's + { + basetable[i | 0x000] = 0x7C00; + basetable[i | 0x100] = 0xFC00; + shifttable[i | 0x000] = 13; + shifttable[i | 0x100] = 13; + } + } +} + +float halfToFloat(half h) +{ + union { float f; uint32 i; } conv; + + conv.i = mantissatable[offsettable[h >> 10] + (h & 0x3FF)] + exponenttable[h >> 10]; + return conv.f; +} + +half floatToHalf(float f) +{ + union { float f; uint32 i; } conv; + conv.f = f; + + return basetable[(conv.i >> 23) & 0x1FF] + ((conv.i & 0x007FFFFF) >> shifttable[(conv.i >> 23) & 0x1FF]); +} + +} // love diff --git a/love/src/jni/love/src/common/halffloat.h b/love/src/jni/love/src/common/halffloat.h new file mode 100644 index 00000000..6a300670 --- /dev/null +++ b/love/src/jni/love/src/common/halffloat.h @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2006-2018 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#ifndef LOVE_HALF_FLOAT_H +#define LOVE_HALF_FLOAT_H + +#include "int.h" + +namespace love +{ + +typedef uint16 half; + +void halfInit(); + +float halfToFloat(half h); +half floatToHalf(float f); + +} // love + +#endif // LOVE_HALF_FLOAT_H diff --git a/love/src/jni/love/src/common/int.h b/love/src/jni/love/src/common/int.h index e3dbd103..4d1ba21c 100644 --- a/love/src/jni/love/src/common/int.h +++ b/love/src/jni/love/src/common/int.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff --git a/love/src/jni/love/src/common/ios.h b/love/src/jni/love/src/common/ios.h index 43a4c7c7..1b973094 100644 --- a/love/src/jni/love/src/common/ios.h +++ b/love/src/jni/love/src/common/ios.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -64,6 +64,16 @@ std::string getExecutablePath(); **/ void vibrate(); +/** + * Enable mix mode (e.g. with background music apps) and playback with a muted device. + **/ +void setAudioMixWithOthers(bool mixEnabled); + +/** + * Returns whether another application is playing audio. + **/ +bool hasBackgroundMusic(); + } // ios } // love diff --git a/love/src/jni/love/src/common/ios.mm b/love/src/jni/love/src/common/ios.mm index c17c17bd..ff540620 100644 --- a/love/src/jni/love/src/common/ios.mm +++ b/love/src/jni/love/src/common/ios.mm @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -26,6 +26,7 @@ #import #import +#import #include @@ -344,6 +345,28 @@ void vibrate() } } +void setAudioMixWithOthers(bool mixEnabled) +{ + @autoreleasepool + { + NSString *category = AVAudioSessionCategorySoloAmbient; + NSError *err; + + if (mixEnabled) + category = AVAudioSessionCategoryAmbient; + + if (![[AVAudioSession sharedInstance] setCategory:category error:&err]) + NSLog(@"Error in AVAudioSession setCategory: %@", [err localizedDescription]); + } +} + +bool hasBackgroundMusic() +{ + if ([[AVAudioSession sharedInstance] respondsToSelector:@selector(secondaryAudioShouldBeSilencedHint)]) + return [[AVAudioSession sharedInstance] secondaryAudioShouldBeSilencedHint]; + return false; +} + } // ios } // love diff --git a/love/src/jni/love/src/common/macosx.h b/love/src/jni/love/src/common/macosx.h index 9afc64b0..e539c88d 100644 --- a/love/src/jni/love/src/common/macosx.h +++ b/love/src/jni/love/src/common/macosx.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff --git a/love/src/jni/love/src/common/macosx.mm b/love/src/jni/love/src/common/macosx.mm index b9055faf..597a2eb7 100644 --- a/love/src/jni/love/src/common/macosx.mm +++ b/love/src/jni/love/src/common/macosx.mm @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff --git a/love/src/jni/love/src/common/math.h b/love/src/jni/love/src/common/math.h index 0a77ee3b..ac2631f2 100644 --- a/love/src/jni/love/src/common/math.h +++ b/love/src/jni/love/src/common/math.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -61,11 +61,15 @@ namespace love { -struct Vertex +struct Rect { - float x, y; - float s, t; - unsigned char r, g, b, a; + int x, y; + int w, h; + + bool operator == (const Rect &rhs) const + { + return x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h; + } }; inline int nextP2(int x) diff --git a/love/src/jni/love/src/common/memory.cpp b/love/src/jni/love/src/common/memory.cpp new file mode 100644 index 00000000..33c75690 --- /dev/null +++ b/love/src/jni/love/src/common/memory.cpp @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2006-2018 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#include "config.h" +#include "memory.h" + +#include + +#ifdef LOVE_WINDOWS +#include +#else +#include // Assume POSIX support. +#endif + +namespace love +{ + +bool alignedMalloc(void **mem, size_t size, size_t alignment) +{ +#ifdef LOVE_WINDOWS + *mem = _aligned_malloc(size, alignment); + return *mem != nullptr; +#else + return posix_memalign(mem, alignment, size) == 0; +#endif +} + +void alignedFree(void *mem) +{ +#ifdef LOVE_WINDOWS + _aligned_free(mem); +#else + free(mem); +#endif +} + +size_t getPageSize() +{ +#ifdef LOVE_WINDOWS + // TODO: Do an actual query. + return 4096; +#else + static const long size = sysconf(_SC_PAGESIZE); + return size > 0 ? (size_t) size : 4096; +#endif +} + +size_t alignUp(size_t size, size_t alignment) +{ + return (size + alignment - 1) & (~(alignment - 1)); +} + +} // love diff --git a/love/src/jni/love/platform/macosx/OSX.h b/love/src/jni/love/src/common/memory.h similarity index 65% rename from love/src/jni/love/platform/macosx/OSX.h rename to love/src/jni/love/src/common/memory.h index 6a6d8b80..5cbba334 100644 --- a/love/src/jni/love/platform/macosx/OSX.h +++ b/love/src/jni/love/src/common/memory.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2014 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -18,30 +18,21 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -#ifndef LOVE_OSX_H -#define LOVE_OSX_H +#pragma once -#include +#include namespace love { -namespace osx -{ + +bool alignedMalloc(void **mem, size_t size, size_t alignment); +void alignedFree(void *mem); + +size_t getPageSize(); /** - * Returns the filepath of the first detected love file in the Resources folder - * in love.app. - * Returns an empty string if no love file is found. + * 'alignment' must be a power of two. **/ -std::string getLoveInResources(); +size_t alignUp(size_t size, size_t alignment); -/** - * Checks for drop-file events. Returns the filepath if an event occurred, or - * an empty string otherwise. - **/ -std::string checkDropEvents(); - -} // osx } // love - -#endif // LOVE_OSX_H diff --git a/love/src/jni/love/src/common/pixelformat.cpp b/love/src/jni/love/src/common/pixelformat.cpp new file mode 100644 index 00000000..99457068 --- /dev/null +++ b/love/src/jni/love/src/common/pixelformat.cpp @@ -0,0 +1,179 @@ +/** + * Copyright (c) 2006-2018 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#include "pixelformat.h" +#include "StringMap.h" + +namespace love +{ + +static StringMap::Entry formatEntries[] = +{ + { "unknown", PIXELFORMAT_UNKNOWN }, + + { "normal", PIXELFORMAT_NORMAL }, + { "hdr", PIXELFORMAT_HDR }, + + { "r8", PIXELFORMAT_R8 }, + { "rg8", PIXELFORMAT_RG8 }, + { "rgba8", PIXELFORMAT_RGBA8 }, + { "srgba8", PIXELFORMAT_sRGBA8 }, + { "r16", PIXELFORMAT_R16 }, + { "rg16", PIXELFORMAT_RG16 }, + { "rgba16", PIXELFORMAT_RGBA16 }, + { "r16f", PIXELFORMAT_R16F }, + { "rg16f", PIXELFORMAT_RG16F }, + { "rgba16f", PIXELFORMAT_RGBA16F }, + { "r32f", PIXELFORMAT_R32F }, + { "rg32f", PIXELFORMAT_RG32F }, + { "rgba32f", PIXELFORMAT_RGBA32F }, + + { "la8", PIXELFORMAT_LA8 }, + + { "rgba4", PIXELFORMAT_RGBA4 }, + { "rgb5a1", PIXELFORMAT_RGB5A1 }, + { "rgb565", PIXELFORMAT_RGB565 }, + { "rgb10a2", PIXELFORMAT_RGB10A2 }, + { "rg11b10f", PIXELFORMAT_RG11B10F }, + + { "stencil8", PIXELFORMAT_STENCIL8 }, + { "depth16", PIXELFORMAT_DEPTH16 }, + { "depth24", PIXELFORMAT_DEPTH24 }, + { "depth32f", PIXELFORMAT_DEPTH32F }, + { "depth24stencil8", PIXELFORMAT_DEPTH24_STENCIL8 }, + { "depth32fstencil8", PIXELFORMAT_DEPTH32F_STENCIL8 }, + + { "DXT1", PIXELFORMAT_DXT1 }, + { "DXT3", PIXELFORMAT_DXT3 }, + { "DXT5", PIXELFORMAT_DXT5 }, + { "BC4", PIXELFORMAT_BC4 }, + { "BC4s", PIXELFORMAT_BC4s }, + { "BC5", PIXELFORMAT_BC5 }, + { "BC5s", PIXELFORMAT_BC5s }, + { "BC6h", PIXELFORMAT_BC6H }, + { "BC6hs", PIXELFORMAT_BC6Hs }, + { "BC7", PIXELFORMAT_BC7 }, + { "PVR1rgb2", PIXELFORMAT_PVR1_RGB2 }, + { "PVR1rgb4", PIXELFORMAT_PVR1_RGB4 }, + { "PVR1rgba2", PIXELFORMAT_PVR1_RGBA2 }, + { "PVR1rgba4", PIXELFORMAT_PVR1_RGBA4 }, + { "ETC1", PIXELFORMAT_ETC1 }, + { "ETC2rgb", PIXELFORMAT_ETC2_RGB }, + { "ETC2rgba", PIXELFORMAT_ETC2_RGBA }, + { "ETC2rgba1", PIXELFORMAT_ETC2_RGBA1 }, + { "EACr", PIXELFORMAT_EAC_R }, + { "EACrs", PIXELFORMAT_EAC_Rs }, + { "EACrg", PIXELFORMAT_EAC_RG }, + { "EACrgs", PIXELFORMAT_EAC_RGs }, + { "ASTC4x4", PIXELFORMAT_ASTC_4x4 }, + { "ASTC5x4", PIXELFORMAT_ASTC_5x4 }, + { "ASTC5x5", PIXELFORMAT_ASTC_5x5 }, + { "ASTC6x5", PIXELFORMAT_ASTC_6x5 }, + { "ASTC6x6", PIXELFORMAT_ASTC_6x6 }, + { "ASTC8x5", PIXELFORMAT_ASTC_8x5 }, + { "ASTC8x6", PIXELFORMAT_ASTC_8x6 }, + { "ASTC8x8", PIXELFORMAT_ASTC_8x8 }, + { "ASTC10x5", PIXELFORMAT_ASTC_10x5 }, + { "ASTC10x6", PIXELFORMAT_ASTC_10x6 }, + { "ASTC10x8", PIXELFORMAT_ASTC_10x8 }, + { "ASTC10x10", PIXELFORMAT_ASTC_10x10 }, + { "ASTC12x10", PIXELFORMAT_ASTC_12x10 }, + { "ASTC12x12", PIXELFORMAT_ASTC_12x12 }, +}; + +static_assert(sizeof(formatEntries) / sizeof(formatEntries[0]) == (size_t) PIXELFORMAT_MAX_ENUM, "pixel format string map is missing entries!"); + +static StringMap formats(formatEntries, sizeof(formatEntries)); + +bool getConstant(const char *in, PixelFormat &out) +{ + return formats.find(in, out); +} + +bool getConstant(PixelFormat in, const char *&out) +{ + return formats.find(in, out); +} + +bool isPixelFormatCompressed(PixelFormat format) +{ + // I'm lazy + int iformat = (int) format; + return iformat >= (int) PIXELFORMAT_DXT1 && iformat < (int) PIXELFORMAT_MAX_ENUM; +} + +bool isPixelFormatDepthStencil(PixelFormat format) +{ + int iformat = (int) format; + return iformat >= (int) PIXELFORMAT_STENCIL8 && iformat <= (int) PIXELFORMAT_DEPTH32F_STENCIL8; +} + +bool isPixelFormatDepth(PixelFormat format) +{ + int iformat = (int) format; + return iformat >= (int) PIXELFORMAT_DEPTH16 && iformat <= (int) PIXELFORMAT_DEPTH32F_STENCIL8; +} + +bool isPixelFormatStencil(PixelFormat format) +{ + return format == PIXELFORMAT_STENCIL8 || format == PIXELFORMAT_DEPTH24_STENCIL8 || format == PIXELFORMAT_DEPTH32F_STENCIL8; +} + +size_t getPixelFormatSize(PixelFormat format) +{ + switch (format) + { + case PIXELFORMAT_R8: + case PIXELFORMAT_STENCIL8: + return 1; + case PIXELFORMAT_RG8: + case PIXELFORMAT_R16: + case PIXELFORMAT_R16F: + case PIXELFORMAT_LA8: + case PIXELFORMAT_RGBA4: + case PIXELFORMAT_RGB5A1: + case PIXELFORMAT_RGB565: + case PIXELFORMAT_DEPTH16: + return 2; + case PIXELFORMAT_RGBA8: + case PIXELFORMAT_sRGBA8: + case PIXELFORMAT_RG16: + case PIXELFORMAT_RG16F: + case PIXELFORMAT_R32F: + case PIXELFORMAT_RGB10A2: + case PIXELFORMAT_RG11B10F: + case PIXELFORMAT_DEPTH24: + case PIXELFORMAT_DEPTH32F: + case PIXELFORMAT_DEPTH24_STENCIL8: + return 4; + case PIXELFORMAT_RGBA16: + case PIXELFORMAT_RGBA16F: + case PIXELFORMAT_RG32F: + case PIXELFORMAT_DEPTH32F_STENCIL8: + return 8; + case PIXELFORMAT_RGBA32F: + return 16; + default: + // TODO: compressed formats + return 0; + } +} + +} // love diff --git a/love/src/jni/love/src/common/pixelformat.h b/love/src/jni/love/src/common/pixelformat.h new file mode 100644 index 00000000..e8557be1 --- /dev/null +++ b/love/src/jni/love/src/common/pixelformat.h @@ -0,0 +1,138 @@ +/** + * Copyright (c) 2006-2018 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#pragma once + +#include "stddef.h" + +namespace love +{ + +enum PixelFormat +{ + PIXELFORMAT_UNKNOWN, + + // these are converted to an actual format by love + PIXELFORMAT_NORMAL, + PIXELFORMAT_HDR, + + // "regular" formats + PIXELFORMAT_R8, + PIXELFORMAT_RG8, + PIXELFORMAT_RGBA8, + PIXELFORMAT_sRGBA8, + PIXELFORMAT_R16, + PIXELFORMAT_RG16, + PIXELFORMAT_RGBA16, + PIXELFORMAT_R16F, + PIXELFORMAT_RG16F, + PIXELFORMAT_RGBA16F, + PIXELFORMAT_R32F, + PIXELFORMAT_RG32F, + PIXELFORMAT_RGBA32F, + + PIXELFORMAT_LA8, // Same as RG8, but accessed as (L, L, L, A) + + // packed formats + PIXELFORMAT_RGBA4, + PIXELFORMAT_RGB5A1, + PIXELFORMAT_RGB565, + PIXELFORMAT_RGB10A2, + PIXELFORMAT_RG11B10F, + + // depth/stencil formats + PIXELFORMAT_STENCIL8, + PIXELFORMAT_DEPTH16, + PIXELFORMAT_DEPTH24, + PIXELFORMAT_DEPTH32F, + PIXELFORMAT_DEPTH24_STENCIL8, + PIXELFORMAT_DEPTH32F_STENCIL8, + + // compressed formats + PIXELFORMAT_DXT1, + PIXELFORMAT_DXT3, + PIXELFORMAT_DXT5, + PIXELFORMAT_BC4, + PIXELFORMAT_BC4s, + PIXELFORMAT_BC5, + PIXELFORMAT_BC5s, + PIXELFORMAT_BC6H, + PIXELFORMAT_BC6Hs, + PIXELFORMAT_BC7, + PIXELFORMAT_PVR1_RGB2, + PIXELFORMAT_PVR1_RGB4, + PIXELFORMAT_PVR1_RGBA2, + PIXELFORMAT_PVR1_RGBA4, + PIXELFORMAT_ETC1, + PIXELFORMAT_ETC2_RGB, + PIXELFORMAT_ETC2_RGBA, + PIXELFORMAT_ETC2_RGBA1, + PIXELFORMAT_EAC_R, + PIXELFORMAT_EAC_Rs, + PIXELFORMAT_EAC_RG, + PIXELFORMAT_EAC_RGs, + PIXELFORMAT_ASTC_4x4, + PIXELFORMAT_ASTC_5x4, + PIXELFORMAT_ASTC_5x5, + PIXELFORMAT_ASTC_6x5, + PIXELFORMAT_ASTC_6x6, + PIXELFORMAT_ASTC_8x5, + PIXELFORMAT_ASTC_8x6, + PIXELFORMAT_ASTC_8x8, + PIXELFORMAT_ASTC_10x5, + PIXELFORMAT_ASTC_10x6, + PIXELFORMAT_ASTC_10x8, + PIXELFORMAT_ASTC_10x10, + PIXELFORMAT_ASTC_12x10, + PIXELFORMAT_ASTC_12x12, + + PIXELFORMAT_MAX_ENUM +}; + +bool getConstant(PixelFormat in, const char *&out); +bool getConstant(const char *in, PixelFormat &out); + +/** + * Gets whether the specified pixel format is a compressed type. + **/ +bool isPixelFormatCompressed(PixelFormat format); + +/** + * Gets whether the specified pixel format is a depth or stencil type. + **/ +bool isPixelFormatDepthStencil(PixelFormat format); + +/** + * Gets whether the specified pixel format is a depth type. + **/ +bool isPixelFormatDepth(PixelFormat format); + +/** + * Gets whether the specified pixel format is a stencil type. + **/ +bool isPixelFormatStencil(PixelFormat format); + +/** + * Gets the size in bytes of the specified pixel format. + * NOTE: Currently returns 0 for compressed formats. + **/ +size_t getPixelFormatSize(PixelFormat format); + +} // love diff --git a/love/src/jni/love/src/common/runtime.cpp b/love/src/jni/love/src/common/runtime.cpp index f6ecdebf..23d0e986 100644 --- a/love/src/jni/love/src/common/runtime.cpp +++ b/love/src/jni/love/src/common/runtime.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -31,6 +31,7 @@ #include #include #include +#include namespace love { @@ -42,7 +43,11 @@ namespace love static int w__gc(lua_State *L) { Proxy *p = (Proxy *) lua_touserdata(L, 1); - p->object->release(); + if (p->object != nullptr) + { + p->object->release(); + p->object = nullptr; + } return 0; } @@ -63,8 +68,11 @@ static int w__type(lua_State *L) static int w__typeOf(lua_State *L) { Proxy *p = (Proxy *)lua_touserdata(L, 1); - Type t = luax_type(L, 2); - luax_pushboolean(L, typeFlags[p->type][t]); + Type *t = luax_type(L, 2); + if (!t) + luax_pushboolean(L, false); + else + luax_pushboolean(L, p->type->isa(*t)); return 1; } @@ -72,7 +80,35 @@ static int w__eq(lua_State *L) { Proxy *p1 = (Proxy *)lua_touserdata(L, 1); Proxy *p2 = (Proxy *)lua_touserdata(L, 2); - luax_pushboolean(L, p1->object == p2->object); + luax_pushboolean(L, p1->object == p2->object && p1->object != nullptr); + return 1; +} + +static int w__release(lua_State *L) +{ + Proxy *p = (Proxy *) lua_touserdata(L, 1); + Object *object = p->object; + + if (object != nullptr) + { + p->object = nullptr; + object->release(); + + // Fetch the registry table of instantiated objects. + luax_getregistry(L, REGISTRY_OBJECTS); + + if (lua_istable(L, -1)) + { + // loveobjects[object] = nil + lua_pushlightuserdata(L, object); + lua_pushnil(L); + lua_settable(L, -3); + } + + lua_pop(L, 1); + } + + luax_pushboolean(L, object != nullptr); return 1; } @@ -83,7 +119,7 @@ Reference *luax_refif(lua_State *L, int type) // Create a reference only if the test succeeds. if (lua_type(L, -1) == type) r = new Reference(L); - else // Pop the value even if it fails (but also if it succeeds). + else // Pop the value manually if it fails (done by Reference if it succeeds). lua_pop(L, 1); return r; @@ -95,11 +131,53 @@ void luax_printstack(lua_State *L) std::cout << i << " - " << luaL_typename(L, i) << std::endl; } +int luax_traceback(lua_State *L) +{ + if (!lua_isstring(L, 1)) // 'message' not a string? + return 1; // keep it intact + + lua_getglobal(L, "debug"); + if (!lua_istable(L, -1)) + { + lua_pop(L, 1); + return 1; + } + + lua_getfield(L, -1, "traceback"); + if (!lua_isfunction(L, -1)) + { + lua_pop(L, 2); + return 1; + } + + lua_pushvalue(L, 1); // pass error message + lua_pushinteger(L, 2); // skip this function and traceback + lua_call(L, 2, 1); // call debug.traceback + return 1; +} + +bool luax_isarrayoftables(lua_State *L, int idx) +{ + if (!lua_istable(L, idx)) + return false; + + lua_rawgeti(L, idx, 1); + bool tableoftables = lua_istable(L, -1); + lua_pop(L, 1); + return tableoftables; +} + bool luax_toboolean(lua_State *L, int idx) { return (lua_toboolean(L, idx) != 0); } +bool luax_checkboolean(lua_State *L, int idx) +{ + luaL_checktype(L, idx, LUA_TBOOLEAN); + return luax_toboolean(L, idx); +} + void luax_pushboolean(lua_State *L, bool b) { lua_pushboolean(L, b ? 1 : 0); @@ -159,6 +237,37 @@ int luax_intflag(lua_State *L, int table_index, const char *key, int defaultValu return retval; } +double luax_numberflag(lua_State *L, int table_index, const char *key, double defaultValue) +{ + lua_getfield(L, table_index, key); + + int retval; + if (!lua_isnumber(L, -1)) + retval = defaultValue; + else + retval = lua_tonumber(L, -1); + + lua_pop(L, 1); + return retval; +} + +int luax_checkintflag(lua_State *L, int table_index, const char *key) +{ + lua_getfield(L, table_index, key); + + int retval; + if (!lua_isnumber(L, -1)) + { + std::string err = "expected integer field " + std::string(key) + " in table"; + return luaL_argerror(L, table_index, err.c_str()); + } + else + retval = (int) luaL_checkinteger(L, -1); + lua_pop(L, 1); + + return retval; +} + int luax_assert_argc(lua_State *L, int min) { int argc = lua_gettop(L); @@ -216,7 +325,7 @@ int luax_require(lua_State *L, const char *name) int luax_register_module(lua_State *L, const WrappedModule &m) { - love::addTypeName(m.type, m.name); + m.type->init(); // Put a reference to the C++ module in Lua. luax_insistregistry(L, REGISTRY_MODULES); @@ -272,9 +381,9 @@ int luax_preload(lua_State *L, lua_CFunction f, const char *name) return 0; } -int luax_register_type(lua_State *L, love::Type type, const char *name, ...) +int luax_register_type(lua_State *L, love::Type *type, ...) { - love::addTypeName(type, name); + type->init(); // Get the place for storing and re-using instantiated love types. luax_getregistry(L, REGISTRY_OBJECTS); @@ -301,7 +410,7 @@ int luax_register_type(lua_State *L, love::Type type, const char *name, ...) else lua_pop(L, 1); - luaL_newmetatable(L, name); + luaL_newmetatable(L, type->getName()); // m.__index = m lua_pushvalue(L, -1); @@ -316,12 +425,12 @@ int luax_register_type(lua_State *L, love::Type type, const char *name, ...) lua_setfield(L, -2, "__eq"); // Add tostring function. - lua_pushstring(L, name); + lua_pushstring(L, type->getName()); lua_pushcclosure(L, w__tostring, 1); lua_setfield(L, -2, "__tostring"); // Add type - lua_pushstring(L, name); + lua_pushstring(L, type->getName()); lua_pushcclosure(L, w__type, 1); lua_setfield(L, -2, "type"); @@ -329,8 +438,12 @@ int luax_register_type(lua_State *L, love::Type type, const char *name, ...) lua_pushcfunction(L, w__typeOf); lua_setfield(L, -2, "typeOf"); + // Add release + lua_pushcfunction(L, w__release); + lua_setfield(L, -2, "release"); + va_list fs; - va_start(fs, name); + va_start(fs, type); for (const luaL_Reg *f = va_arg(fs, const luaL_Reg *); f; f = va_arg(fs, const luaL_Reg *)) luax_setfuncs(L, f); va_end(fs); @@ -339,13 +452,10 @@ int luax_register_type(lua_State *L, love::Type type, const char *name, ...) return 0; } -void luax_gettypemetatable(lua_State *L, love::Type type) +void luax_gettypemetatable(lua_State *L, love::Type &type) { - const char *name = nullptr; - if (getTypeName(type, name)) - lua_getfield(L, LUA_REGISTRYINDEX, name); - else - lua_pushnil(L); + const char *name = type.getName(); + lua_getfield(L, LUA_REGISTRYINDEX, name); } int luax_table_insert(lua_State *L, int tindex, int vindex, int pos) @@ -401,23 +511,34 @@ int luax_register_searcher(lua_State *L, lua_CFunction f, int pos) return 0; } -void luax_rawnewtype(lua_State *L, love::Type type, love::Object *object) +void luax_rawnewtype(lua_State *L, love::Type &type, love::Object *object) { Proxy *u = (Proxy *)lua_newuserdata(L, sizeof(Proxy)); object->retain(); u->object = object; - u->type = type; - - const char *name = "Invalid"; - getTypeName(type, name); + u->type = &type; + const char *name = type.getName(); luaL_newmetatable(L, name); + + lua_getfield(L, -1, "__gc"); + bool has_gc = !lua_isnoneornil(L, -1); + lua_pop(L, 1); + + // Make sure mt.__gc exists, so Lua states which don't have the object's + // module loaded will still clean the object up when it's collected. + if (!has_gc) + { + lua_pushcfunction(L, w__gc); + lua_setfield(L, -2, "__gc"); + } + lua_setmetatable(L, -2); } -void luax_pushtype(lua_State *L, love::Type type, love::Object *object) +void luax_pushtype(lua_State *L, love::Type &type, love::Object *object) { if (object == nullptr) { @@ -459,15 +580,15 @@ void luax_pushtype(lua_State *L, love::Type type, love::Object *object) // Keep the Proxy userdata on the stack. } -bool luax_istype(lua_State *L, int idx, love::Type type) +bool luax_istype(lua_State *L, int idx, love::Type &type) { if (lua_type(L, idx) != LUA_TUSERDATA) return false; Proxy *p = (Proxy *) lua_touserdata(L, idx); - if (p->type > INVALID_ID && p->type < TYPE_MAX_ENUM) - return typeFlags[p->type][type]; + if (p->type != nullptr) + return p->type->isa(type); else return false; } @@ -666,10 +787,29 @@ lua_State *luax_getpinnedthread(lua_State *L) return thread; } +void luax_markdeprecated(lua_State *L, const char *name, APIType api) +{ + luax_markdeprecated(L, name, api, DEPRECATED_NO_REPLACEMENT, nullptr); +} + +void luax_markdeprecated(lua_State *L, const char *name, APIType api, DeprecationType type, const char *replacement) +{ + MarkDeprecated deprecated(name, api, type, replacement); + + if (deprecated.info != nullptr && deprecated.info->uses == 1) + { + luaL_where(L, 1); + const char *where = lua_tostring(L, -1); + if (where != nullptr) + deprecated.info->where = where; + lua_pop(L, 1); + } +} + extern "C" int luax_typerror(lua_State *L, int narg, const char *tname) { int argtype = lua_type(L, narg); - const char *argtname = 0; + const char *argtname = nullptr; // We want to use the love type name for userdata, if possible. if (argtype == LUA_TUSERDATA && luaL_getmetafield(L, narg, "type") != 0) @@ -681,19 +821,37 @@ extern "C" int luax_typerror(lua_State *L, int narg, const char *tname) // Non-love userdata might have a type metamethod which doesn't // describe its type properly, so we only use it for love types. - love::Type t; - if (!love::getTypeName(argtname, t)) - argtname = 0; + if (!Type::byName(argtname)) + argtname = nullptr; } } - if (argtname == 0) + if (argtname == nullptr) argtname = lua_typename(L, argtype); const char *msg = lua_pushfstring(L, "%s expected, got %s", tname, argtname); return luaL_argerror(L, narg, msg); } +int luax_enumerror(lua_State *L, const char *enumName, const char *value) +{ + return luaL_error(L, "Invalid %s: %s", enumName, value); +} + +int luax_enumerror(lua_State *L, const char *enumName, const std::vector &values, const char *value) +{ + std::stringstream valueStream; + bool first = true; + for (auto value : values) + { + valueStream << (first ? "'" : ", '") << value << "'"; + first = false; + } + + std::string valueString = valueStream.str(); + return luaL_error(L, "Invalid %s '%s', expected one of: %s", enumName, value, valueString.c_str()); +} + size_t luax_objlen(lua_State *L, int ndx) { #if LUA_VERSION_NUM == 501 @@ -716,11 +874,9 @@ void luax_register(lua_State *L, const char *name, const luaL_Reg *l) } } -Type luax_type(lua_State *L, int idx) +Type *luax_type(lua_State *L, int idx) { - Type t = INVALID_ID; - getTypeName(luaL_checkstring(L, idx), t); - return t; + return Type::byName(luaL_checkstring(L, idx)); } } // love diff --git a/love/src/jni/love/src/common/runtime.h b/love/src/jni/love/src/common/runtime.h index 9072c99d..eee50cc1 100644 --- a/love/src/jni/love/src/common/runtime.h +++ b/love/src/jni/love/src/common/runtime.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -22,7 +22,9 @@ #define LOVE_RUNTIME_H // LOVE +#include "config.h" #include "types.h" +#include "deprecation.h" // Lua extern "C" { @@ -34,6 +36,7 @@ extern "C" { // C++ #include +#include namespace love { @@ -43,6 +46,9 @@ class Object; class Module; class Reference; +template +class StrongRef; + /** * Registries represent special tables which can be accessed with * luax_insistregistry and luax_getregistry. @@ -62,7 +68,7 @@ enum Registry struct Proxy { // Holds type information (see types.h). - Type type; + love::Type *type; // Pointer to the actual object. Object *object; @@ -80,7 +86,7 @@ struct WrappedModule const char *name; // The type of this module. - love::Type type; + love::Type *type; // The functions of the module (last element {0,0}). const luaL_Reg *functions; @@ -103,6 +109,16 @@ Reference *luax_refif(lua_State *L, int type); **/ void luax_printstack(lua_State *L); +/** + * Traceback function for use with lua_pcall. Calls debug.traceback. + **/ +int luax_traceback(lua_State *L); + +/** + * Gets whether the value at idx is an array of tables. + **/ +bool luax_isarrayoftables(lua_State *L, int idx); + /** * Converts the value at idx to a bool. It follow the same rules * as lua_toboolean, but returns a bool instead of an int. @@ -112,6 +128,12 @@ void luax_printstack(lua_State *L); **/ bool luax_toboolean(lua_State *L, int idx); +/** + * Returns the boolean value at idx. Causes a Lua error if the value is not + * a boolean. + **/ +bool luax_checkboolean(lua_State *L, int idx); + /** * Pushes a bool onto the stack. It's the same as lua_pushboolean, * but with bool instead of int. @@ -158,6 +180,9 @@ void luax_pushstring(lua_State *L, const std::string &str); bool luax_boolflag(lua_State *L, int table_index, const char *key, bool defaultValue); int luax_intflag(lua_State *L, int table_index, const char *key, int defaultValue); +double luax_numberflag(lua_State *L, int table_index, const char *key, double defaultValue); + +int luax_checkintflag(lua_State *L, int table_index, const char *key); /** * Convert the value at the specified index to an Lua number, and then @@ -181,6 +206,16 @@ inline float luax_checkfloat(lua_State *L, int idx) return static_cast(luaL_checknumber(L, idx)); } +inline lua_Number luax_checknumberclamped01(lua_State *L, int idx) +{ + return std::min(std::max(luaL_checknumber(L, idx), 0.0), 1.0); +} + +inline lua_Number luax_optnumberclamped01(lua_State *L, int idx, double def) +{ + return std::min(std::max(luaL_optnumber(L, idx, def), 0.0), 1.0); +} + /** * Require at least 'min' number of items on the stack. * @param L The Lua state. @@ -246,16 +281,17 @@ int luax_preload(lua_State *L, lua_CFunction f, const char *name); /** * Register a new type. + * NOTE: The type is passed by pointer instead of reference because calling va_start + * on a reference is undefined behaviour. * @param type The type. - * @param name The type's human-readable name * @param ... The list of lists of member functions for the type. (of type luaL_Reg*) **/ -int luax_register_type(lua_State *L, love::Type type, const char *name, ...); +int luax_register_type(lua_State *L, love::Type *type, ...); /** * Pushes the metatable of the specified type onto the stack. **/ -void luax_gettypemetatable(lua_State *L, love::Type type); +void luax_gettypemetatable(lua_State *L, love::Type &type); /** * Do a table.insert from C @@ -283,7 +319,19 @@ int luax_register_searcher(lua_State *L, lua_CFunction f, int pos = -1); * @param type The type information of the object. * @param object The pointer to the actual object. **/ -void luax_pushtype(lua_State *L, const love::Type type, love::Object *object); +void luax_pushtype(lua_State *L, love::Type &type, love::Object *object); + +template +void luax_pushtype(lua_State *L, T *object) +{ + luax_pushtype(L, T::type, object); +} + +template +void luax_pushtype(lua_State *L, StrongRef &object) +{ + luax_pushtype(L, T::type, object); +} /** * Creates a new Lua representation of the given object *without* checking if it @@ -296,7 +344,7 @@ void luax_pushtype(lua_State *L, const love::Type type, love::Object *object); * @param type The type information of the object. * @param object The pointer to the actual object. **/ -void luax_rawnewtype(lua_State *L, love::Type type, love::Object *object); +void luax_rawnewtype(lua_State *L, love::Type &type, love::Object *object); /** * Checks whether the value at idx is a certain type. @@ -305,7 +353,7 @@ void luax_rawnewtype(lua_State *L, love::Type type, love::Object *object); * @param type The type to check for. * @return True if the value is Proxy of the specified type, false otherwise. **/ -bool luax_istype(lua_State *L, int idx, love::Type type); +bool luax_istype(lua_State *L, int idx, love::Type &type); /** * Gets the function love.module.function and puts it on top of the stack (alone). If the @@ -412,10 +460,42 @@ lua_State *luax_insistpinnedthread(lua_State *L); **/ lua_State *luax_getpinnedthread(lua_State *L); +/** + * Mark a function as deprecated. Should only be called inside wrapper function + * code. + **/ +void luax_markdeprecated(lua_State *L, const char *name, APIType api); +void luax_markdeprecated(lua_State *L, const char *name, APIType api, DeprecationType type, const char *replacement); + extern "C" { // Also called from luasocket int luax_typerror(lua_State *L, int narg, const char *tname); } +int luax_enumerror(lua_State *L, const char *enumName, const char *value); +int luax_enumerror(lua_State *L, const char *enumName, const std::vector &values, const char *value); + +template +void luax_checktablefields(lua_State *L, int idx, const char *enumName, bool (*getConstant)(const char *, T &)) +{ + luaL_checktype(L, idx, LUA_TTABLE); + + // We want to error for invalid / misspelled fields in the table. + lua_pushnil(L); + while (lua_next(L, idx)) + { + if (lua_type(L, -2) != LUA_TSTRING) + luax_typerror(L, -2, "string"); + + const char *key = luaL_checkstring(L, -2); + T constantvalue; + + if (!getConstant(key, constantvalue)) + luax_enumerror(L, enumName, key); + + lua_pop(L, 1); + } +} + /** * Calls luax_objlen/lua_rawlen depending on version **/ @@ -434,42 +514,48 @@ extern "C" { // Called by enet and luasocket * @param type The type bit. **/ template -T *luax_checktype(lua_State *L, int idx, love::Type type) +T *luax_checktype(lua_State *L, int idx, const love::Type &type) { if (lua_type(L, idx) != LUA_TUSERDATA) { - const char *name = "Invalid"; - getTypeName(type, name); + const char *name = type.getName(); luax_typerror(L, idx, name); } Proxy *u = (Proxy *)lua_touserdata(L, idx); - if (u->type <= INVALID_ID || u->type >= TYPE_MAX_ENUM || !typeFlags[u->type][type]) + if (u->type == nullptr || !u->type->isa(type)) { - const char *name = "Invalid"; - getTypeName(type, name); + const char *name = type.getName(); luax_typerror(L, idx, name); } + if (u->object == nullptr) + luaL_error(L, "Cannot use object after it has been released."); + return (T *)u->object; } template -T *luax_getmodule(lua_State *L, love::Type type) +T *luax_checktype(lua_State *L, int idx) { - const char *name = "Invalid"; - getTypeName(type, name); + return luax_checktype(L, idx, T::type); +} + +template +T *luax_getmodule(lua_State *L, const love::Type &type) +{ + const char *name = type.getName(); luax_insistregistry(L, REGISTRY_MODULES); lua_getfield(L, -1, name); if (!lua_isuserdata(L, -1)) - luaL_error(L, "Tried to get nonexistant module %s.", name); + luaL_error(L, "Tried to get nonexistent module %s.", name); Proxy *u = (Proxy *)lua_touserdata(L, -1); - if (u->type <= INVALID_ID || u->type >= TYPE_MAX_ENUM || !typeFlags[u->type][type]) + if (u->type == nullptr || !u->type->isa(type)) luaL_error(L, "Incorrect module %s", name); lua_pop(L, 2); @@ -478,10 +564,15 @@ T *luax_getmodule(lua_State *L, love::Type type) } template -T *luax_optmodule(lua_State *L, love::Type type) +T *luax_getmodule(lua_State *L) { - const char *name = "Invalid"; - getTypeName(type, name); + return luax_getmodule(L, T::type); +} + +template +T *luax_optmodule(lua_State *L, const love::Type &type) +{ + const char *name = type.getName(); luax_insistregistry(L, REGISTRY_MODULES); lua_getfield(L, -1, name); @@ -494,7 +585,7 @@ T *luax_optmodule(lua_State *L, love::Type type) Proxy *u = (Proxy *)lua_touserdata(L, -1); - if (!typeFlags[u->type][type]) + if (!u->type->isa(type)) luaL_error(L, "Incorrect module %s", name); lua_pop(L, 2); @@ -502,6 +593,12 @@ T *luax_optmodule(lua_State *L, love::Type type) return (T *) u->object; } +template +T *luax_optmodule(lua_State *L) +{ + return luax_optmodule(L, T::type); +} + /** * Converts the value at idx to the specified type without checking that * this conversion is valid. If the type has been previously verified with @@ -511,12 +608,23 @@ T *luax_optmodule(lua_State *L, love::Type type) * @param type The type of the object. **/ template -T *luax_totype(lua_State *L, int idx, love::Type /*type*/) +T *luax_totype(lua_State *L, int idx, const love::Type& /*type*/) { - return (T *)(((Proxy *)lua_touserdata(L, idx))->object); + T *o = (T *)(((Proxy *)lua_touserdata(L, idx))->object); + + if (o == nullptr) + luaL_error(L, "Cannot use object after it has been released."); + + return o; } -Type luax_type(lua_State *L, int idx); +template +T *luax_totype(lua_State *L, int idx) +{ + return luax_totype(L, idx, T::type); +} + +Type *luax_type(lua_State *L, int idx); /** * Converts any exceptions thrown by the passed lambda function into a Lua error. diff --git a/love/src/jni/love/src/common/types.cpp b/love/src/jni/love/src/common/types.cpp index 4bb44ecc..89fd6608 100644 --- a/love/src/jni/love/src/common/types.cpp +++ b/love/src/jni/love/src/common/types.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -18,126 +18,63 @@ * 3. This notice may not be removed or altered from any source distribution. **/ +// STL +#include + #include "types.h" -#include "StringMap.h" namespace love { -static const TypeBits *createTypeFlags() +static std::unordered_map types; + +Type::Type(const char *name, Type *parent) + : name(name) + , parent(parent) + , id(0) + , inited(false) { - static TypeBits b[TYPE_MAX_ENUM]; - TypeBits one = TypeBits(1); - - b[INVALID_ID] = one << INVALID_ID; - - b[OBJECT_ID] = one << OBJECT_ID; - b[DATA_ID] = (one << DATA_ID) | b[OBJECT_ID]; - b[MODULE_ID] = (one << MODULE_ID) | b[OBJECT_ID]; - b[STREAM_ID] = (one << STREAM_ID) | b[OBJECT_ID]; - - // Filesystem. - b[FILESYSTEM_FILE_ID] = (one << FILESYSTEM_FILE_ID) | b[OBJECT_ID]; - b[FILESYSTEM_DROPPED_FILE_ID] = (one << FILESYSTEM_DROPPED_FILE_ID) | b[FILESYSTEM_FILE_ID]; - b[FILESYSTEM_FILE_DATA_ID] = (one << FILESYSTEM_FILE_DATA_ID) | b[DATA_ID]; - - b[FONT_GLYPH_DATA_ID] = (one << FONT_GLYPH_DATA_ID) | b[DATA_ID]; - b[FONT_RASTERIZER_ID] = (one << FONT_RASTERIZER_ID) | b[OBJECT_ID]; - - // Graphics. - b[GRAPHICS_DRAWABLE_ID] = (one << GRAPHICS_DRAWABLE_ID) | b[OBJECT_ID]; - b[GRAPHICS_TEXTURE_ID] = (one << GRAPHICS_TEXTURE_ID) | b[GRAPHICS_DRAWABLE_ID]; - b[GRAPHICS_IMAGE_ID] = (one << GRAPHICS_IMAGE_ID) | b[GRAPHICS_TEXTURE_ID]; - b[GRAPHICS_QUAD_ID] = (one << GRAPHICS_QUAD_ID) | b[OBJECT_ID]; - b[GRAPHICS_FONT_ID] = (one << GRAPHICS_FONT_ID) | b[OBJECT_ID]; - b[GRAPHICS_PARTICLE_SYSTEM_ID] = (one << GRAPHICS_PARTICLE_SYSTEM_ID) | b[GRAPHICS_DRAWABLE_ID]; - b[GRAPHICS_SPRITE_BATCH_ID] = (one << GRAPHICS_SPRITE_BATCH_ID) | b[GRAPHICS_DRAWABLE_ID]; - b[GRAPHICS_CANVAS_ID] = (one << GRAPHICS_CANVAS_ID) | b[GRAPHICS_TEXTURE_ID]; - b[GRAPHICS_SHADER_ID] = (one << GRAPHICS_SHADER_ID) | b[OBJECT_ID]; - b[GRAPHICS_MESH_ID] = (one << GRAPHICS_MESH_ID) | b[GRAPHICS_DRAWABLE_ID]; - b[GRAPHICS_TEXT_ID] = (one << GRAPHICS_TEXT_ID) | b[GRAPHICS_DRAWABLE_ID]; - b[GRAPHICS_VIDEO_ID] = (one << GRAPHICS_VIDEO_ID) | b[GRAPHICS_DRAWABLE_ID]; - - // Image. - b[IMAGE_IMAGE_DATA_ID] = (one << IMAGE_IMAGE_DATA_ID) | b[DATA_ID]; - b[IMAGE_COMPRESSED_IMAGE_DATA_ID] = (one << IMAGE_COMPRESSED_IMAGE_DATA_ID) | b[DATA_ID]; - - // Joystick. - b[JOYSTICK_JOYSTICK_ID] = (one << JOYSTICK_JOYSTICK_ID) | b[OBJECT_ID]; - - // Math. - b[MATH_RANDOM_GENERATOR_ID] = (one << MATH_RANDOM_GENERATOR_ID) | b[OBJECT_ID]; - b[MATH_BEZIER_CURVE_ID] = (one << MATH_BEZIER_CURVE_ID) | b[OBJECT_ID]; - b[MATH_COMPRESSED_DATA_ID] = (one < types(nullptr, 0); - -void addTypeName(Type type, const char *name) +void Type::init() { - const char *n; - if (!types.find(type, n)) - types.add(name, type); + static uint32 nextId = 1; + + // Make sure we don't init twice, that would be bad + if (inited) + return; + + // Note: we add it here, not in the constructor, because some Types can get initialized before the map! + types[name] = this; + id = nextId++; + bits[id] = true; + inited = true; + + if (!parent) + return; + if (!parent->inited) + parent->init(); + bits |= parent->bits; } -bool getTypeName(const char *in, love::Type &out) +uint32 Type::getId() { - return types.find(in, out); + if (!inited) + init(); + return id; } -bool getTypeName(love::Type in, const char *&out) +const char *Type::getName() const { - return types.find(in, out); + return name; +} + +Type *Type::byName(const char *name) +{ + auto pos = types.find(name); + if (pos == types.end()) + return nullptr; + return pos->second; } } // love diff --git a/love/src/jni/love/src/common/types.h b/love/src/jni/love/src/common/types.h index a1819194..4bbca69d 100644 --- a/love/src/jni/love/src/common/types.h +++ b/love/src/jni/love/src/common/types.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -21,117 +21,54 @@ #ifndef LOVE_TYPES_H #define LOVE_TYPES_H +#include "int.h" + // STD #include +#include namespace love { -enum Type +class Type { - INVALID_ID = 0, - // Cross-module types. - OBJECT_ID, - DATA_ID, - MODULE_ID, - STREAM_ID, +public: + static const uint32 MAX_TYPES = 128; - // Filesystem. - FILESYSTEM_FILE_ID, - FILESYSTEM_DROPPED_FILE_ID, - FILESYSTEM_FILE_DATA_ID, + Type(const char *name, Type *parent); + Type(const Type&) = delete; - // Font - FONT_GLYPH_DATA_ID, - FONT_RASTERIZER_ID, + static Type *byName(const char *name); - // Graphics - GRAPHICS_DRAWABLE_ID, - GRAPHICS_TEXTURE_ID, - GRAPHICS_IMAGE_ID, - GRAPHICS_QUAD_ID, - GRAPHICS_FONT_ID, - GRAPHICS_PARTICLE_SYSTEM_ID, - GRAPHICS_SPRITE_BATCH_ID, - GRAPHICS_CANVAS_ID, - GRAPHICS_SHADER_ID, - GRAPHICS_MESH_ID, - GRAPHICS_TEXT_ID, - GRAPHICS_VIDEO_ID, + void init(); + uint32 getId(); + const char *getName() const; - // Image - IMAGE_IMAGE_DATA_ID, - IMAGE_COMPRESSED_IMAGE_DATA_ID, + bool isa(const uint32 &other) + { + if (!inited) + init(); + return bits[other]; + } - // Joystick - JOYSTICK_JOYSTICK_ID, + bool isa(const Type &other) + { + if (!inited) + init(); + // Note that if this type implements the other + // calling init above will also have inited + // the other. + return bits[other.id]; + } - // Math - MATH_RANDOM_GENERATOR_ID, - MATH_BEZIER_CURVE_ID, - MATH_COMPRESSED_DATA_ID, - - // Audio - AUDIO_SOURCE_ID, - - // Sound - SOUND_SOUND_DATA_ID, - SOUND_DECODER_ID, - - // Mouse - MOUSE_CURSOR_ID, - - // Physics - PHYSICS_WORLD_ID, - PHYSICS_CONTACT_ID, - PHYSICS_BODY_ID, - PHYSICS_FIXTURE_ID, - PHYSICS_SHAPE_ID, - PHYSICS_CIRCLE_SHAPE_ID, - PHYSICS_POLYGON_SHAPE_ID, - PHYSICS_EDGE_SHAPE_ID, - PHYSICS_CHAIN_SHAPE_ID, - PHYSICS_JOINT_ID, - PHYSICS_MOUSE_JOINT_ID, - PHYSICS_DISTANCE_JOINT_ID, - PHYSICS_PRISMATIC_JOINT_ID, - PHYSICS_REVOLUTE_JOINT_ID, - PHYSICS_PULLEY_JOINT_ID, - PHYSICS_GEAR_JOINT_ID, - PHYSICS_FRICTION_JOINT_ID, - PHYSICS_WELD_JOINT_ID, - PHYSICS_ROPE_JOINT_ID, - PHYSICS_WHEEL_JOINT_ID, - PHYSICS_MOTOR_JOINT_ID, - - // Thread - THREAD_THREAD_ID, - THREAD_CHANNEL_ID, - - // Video - VIDEO_VIDEO_STREAM_ID, - - // The modules themselves. Only add abstracted modules here. - MODULE_FILESYSTEM_ID, - MODULE_GRAPHICS_ID, - MODULE_IMAGE_ID, - MODULE_SOUND_ID, - - // Count the number of bits needed. - TYPE_MAX_ENUM +private: + const char * const name; + Type * const parent; + uint32 id; + bool inited; + std::bitset bits; }; -typedef std::bitset TypeBits; - -/** - * Array of length TYPE_MAX_ENUM containing the flags for each love Type. - **/ -extern const TypeBits *typeFlags; - -void addTypeName(Type type, const char *name); -bool getTypeName(const char *in, Type &out); -bool getTypeName(Type in, const char *&out); - } // love #endif // LOVE_TYPES_H diff --git a/love/src/jni/love/src/common/utf8.cpp b/love/src/jni/love/src/common/utf8.cpp old mode 100755 new mode 100644 index 3bd44a1e..8e8a5c47 --- a/love/src/jni/love/src/common/utf8.cpp +++ b/love/src/jni/love/src/common/utf8.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff --git a/love/src/jni/love/src/common/utf8.h b/love/src/jni/love/src/common/utf8.h old mode 100755 new mode 100644 index 84087ef3..3d7febdd --- a/love/src/jni/love/src/common/utf8.h +++ b/love/src/jni/love/src/common/utf8.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff --git a/love/src/jni/love/src/common/version.h b/love/src/jni/love/src/common/version.h index 783445e4..d121e9cd 100644 --- a/love/src/jni/love/src/common/version.h +++ b/love/src/jni/love/src/common/version.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -25,13 +25,13 @@ namespace love { // Version stuff. -#define LOVE_VERSION_STRING "0.10.2" +#define LOVE_VERSION_STRING "0.11.0" static const int VERSION_MAJOR = 0; -static const int VERSION_MINOR = 10; -static const int VERSION_REV = 2; +static const int VERSION_MINOR = 11; +static const int VERSION_REV = 0; static const char *VERSION = LOVE_VERSION_STRING; -static const char *VERSION_COMPATIBILITY[] = { VERSION, "0.10.1", "0.10.0", 0 }; -static const char *VERSION_CODENAME = "Super Toast"; +static const char *VERSION_COMPATIBILITY[] = { VERSION, 0 }; +static const char *VERSION_CODENAME = ""; } // love diff --git a/love/src/jni/love/src/libraries/Box2D/Box2D.h b/love/src/jni/love/src/libraries/Box2D/Box2D.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Collision/Shapes/b2ChainShape.cpp b/love/src/jni/love/src/libraries/Box2D/Collision/Shapes/b2ChainShape.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Collision/Shapes/b2ChainShape.h b/love/src/jni/love/src/libraries/Box2D/Collision/Shapes/b2ChainShape.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Collision/Shapes/b2CircleShape.cpp b/love/src/jni/love/src/libraries/Box2D/Collision/Shapes/b2CircleShape.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Collision/Shapes/b2CircleShape.h b/love/src/jni/love/src/libraries/Box2D/Collision/Shapes/b2CircleShape.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Collision/Shapes/b2EdgeShape.cpp b/love/src/jni/love/src/libraries/Box2D/Collision/Shapes/b2EdgeShape.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Collision/Shapes/b2EdgeShape.h b/love/src/jni/love/src/libraries/Box2D/Collision/Shapes/b2EdgeShape.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Collision/Shapes/b2PolygonShape.cpp b/love/src/jni/love/src/libraries/Box2D/Collision/Shapes/b2PolygonShape.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Collision/Shapes/b2PolygonShape.h b/love/src/jni/love/src/libraries/Box2D/Collision/Shapes/b2PolygonShape.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Collision/Shapes/b2Shape.h b/love/src/jni/love/src/libraries/Box2D/Collision/Shapes/b2Shape.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Collision/b2BroadPhase.cpp b/love/src/jni/love/src/libraries/Box2D/Collision/b2BroadPhase.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Collision/b2BroadPhase.h b/love/src/jni/love/src/libraries/Box2D/Collision/b2BroadPhase.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Collision/b2CollideCircle.cpp b/love/src/jni/love/src/libraries/Box2D/Collision/b2CollideCircle.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Collision/b2CollideEdge.cpp b/love/src/jni/love/src/libraries/Box2D/Collision/b2CollideEdge.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Collision/b2CollidePolygon.cpp b/love/src/jni/love/src/libraries/Box2D/Collision/b2CollidePolygon.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Collision/b2Collision.cpp b/love/src/jni/love/src/libraries/Box2D/Collision/b2Collision.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Collision/b2Collision.h b/love/src/jni/love/src/libraries/Box2D/Collision/b2Collision.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Collision/b2Distance.cpp b/love/src/jni/love/src/libraries/Box2D/Collision/b2Distance.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Collision/b2Distance.h b/love/src/jni/love/src/libraries/Box2D/Collision/b2Distance.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Collision/b2DynamicTree.cpp b/love/src/jni/love/src/libraries/Box2D/Collision/b2DynamicTree.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Collision/b2DynamicTree.h b/love/src/jni/love/src/libraries/Box2D/Collision/b2DynamicTree.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Collision/b2TimeOfImpact.cpp b/love/src/jni/love/src/libraries/Box2D/Collision/b2TimeOfImpact.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Collision/b2TimeOfImpact.h b/love/src/jni/love/src/libraries/Box2D/Collision/b2TimeOfImpact.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Common/b2BlockAllocator.cpp b/love/src/jni/love/src/libraries/Box2D/Common/b2BlockAllocator.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Common/b2BlockAllocator.h b/love/src/jni/love/src/libraries/Box2D/Common/b2BlockAllocator.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Common/b2Draw.cpp b/love/src/jni/love/src/libraries/Box2D/Common/b2Draw.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Common/b2Draw.h b/love/src/jni/love/src/libraries/Box2D/Common/b2Draw.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Common/b2GrowableStack.h b/love/src/jni/love/src/libraries/Box2D/Common/b2GrowableStack.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Common/b2Math.cpp b/love/src/jni/love/src/libraries/Box2D/Common/b2Math.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Common/b2Math.h b/love/src/jni/love/src/libraries/Box2D/Common/b2Math.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Common/b2Settings.cpp b/love/src/jni/love/src/libraries/Box2D/Common/b2Settings.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Common/b2Settings.h b/love/src/jni/love/src/libraries/Box2D/Common/b2Settings.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Common/b2StackAllocator.cpp b/love/src/jni/love/src/libraries/Box2D/Common/b2StackAllocator.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Common/b2StackAllocator.h b/love/src/jni/love/src/libraries/Box2D/Common/b2StackAllocator.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Common/b2Timer.cpp b/love/src/jni/love/src/libraries/Box2D/Common/b2Timer.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Common/b2Timer.h b/love/src/jni/love/src/libraries/Box2D/Common/b2Timer.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2CircleContact.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2CircleContact.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2CircleContact.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2CircleContact.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2Contact.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2Contact.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2Contact.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2Contact.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2ContactSolver.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2PolygonContact.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2PolygonContact.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2PolygonContact.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/Contacts/b2PolygonContact.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2DistanceJoint.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2DistanceJoint.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2DistanceJoint.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2DistanceJoint.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2FrictionJoint.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2FrictionJoint.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2FrictionJoint.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2FrictionJoint.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2GearJoint.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2GearJoint.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2GearJoint.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2GearJoint.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2Joint.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2Joint.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2Joint.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2Joint.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2MotorJoint.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2MotorJoint.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2MotorJoint.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2MotorJoint.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2MouseJoint.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2MouseJoint.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2MouseJoint.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2MouseJoint.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2PrismaticJoint.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2PrismaticJoint.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2PulleyJoint.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2PulleyJoint.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2PulleyJoint.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2PulleyJoint.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2RevoluteJoint.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2RevoluteJoint.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2RopeJoint.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2RopeJoint.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2RopeJoint.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2RopeJoint.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2WeldJoint.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2WeldJoint.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2WeldJoint.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2WeldJoint.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2WheelJoint.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2WheelJoint.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2WheelJoint.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/Joints/b2WheelJoint.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/b2Body.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/b2Body.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/b2Body.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/b2Body.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/b2ContactManager.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/b2ContactManager.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/b2ContactManager.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/b2ContactManager.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/b2Fixture.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/b2Fixture.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/b2Fixture.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/b2Fixture.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/b2Island.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/b2Island.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/b2Island.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/b2Island.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/b2TimeStep.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/b2TimeStep.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/b2World.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/b2World.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/b2World.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/b2World.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/b2WorldCallbacks.cpp b/love/src/jni/love/src/libraries/Box2D/Dynamics/b2WorldCallbacks.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Dynamics/b2WorldCallbacks.h b/love/src/jni/love/src/libraries/Box2D/Dynamics/b2WorldCallbacks.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Rope/b2Rope.cpp b/love/src/jni/love/src/libraries/Box2D/Rope/b2Rope.cpp old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/Box2D/Rope/b2Rope.h b/love/src/jni/love/src/libraries/Box2D/Rope/b2Rope.h old mode 100755 new mode 100644 diff --git a/love/src/jni/love/src/libraries/ddsparse/ddsinfo.h b/love/src/jni/love/src/libraries/ddsparse/ddsinfo.h index 59760d0f..f653b31e 100644 --- a/love/src/jni/love/src/libraries/ddsparse/ddsinfo.h +++ b/love/src/jni/love/src/libraries/ddsparse/ddsinfo.h @@ -1,25 +1,23 @@ /** * Simple DDS data parser for compressed 2D textures. * - * Copyright (c) 2013 Alexander Szpakowski. + * Copyright (c) 2013-2017 Alex Szpakowski * - * 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: + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: * - * 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. + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. * * * Enums and structs copied from Microsoft. diff --git a/love/src/jni/love/src/libraries/ddsparse/ddsparse.cpp b/love/src/jni/love/src/libraries/ddsparse/ddsparse.cpp index 4fbdd16a..d583ff3a 100644 --- a/love/src/jni/love/src/libraries/ddsparse/ddsparse.cpp +++ b/love/src/jni/love/src/libraries/ddsparse/ddsparse.cpp @@ -1,25 +1,23 @@ /** * Simple DDS data parser for compressed 2D textures. * - * Copyright (c) 2013 Alexander Szpakowski. + * Copyright (c) 2013-2017 Alex Szpakowski * - * 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: + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: * - * 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. + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. **/ #include "ddsparse.h" diff --git a/love/src/jni/love/src/libraries/ddsparse/ddsparse.h b/love/src/jni/love/src/libraries/ddsparse/ddsparse.h index 425919ba..d6387574 100644 --- a/love/src/jni/love/src/libraries/ddsparse/ddsparse.h +++ b/love/src/jni/love/src/libraries/ddsparse/ddsparse.h @@ -1,25 +1,23 @@ /** * Simple DDS data parser for compressed 2D textures. * - * Copyright (c) 2013 Alexander Szpakowski. + * Copyright (c) 2013-2017 Alex Szpakowski * - * 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: + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: * - * 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. + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. **/ #ifndef DDS_PARSE_H diff --git a/love/src/jni/love/src/libraries/enet/enet.cpp b/love/src/jni/love/src/libraries/enet/enet.cpp index 510a4ea9..dbc2e7b5 100644 --- a/love/src/jni/love/src/libraries/enet/enet.cpp +++ b/love/src/jni/love/src/libraries/enet/enet.cpp @@ -712,8 +712,14 @@ static int peer_send(lua_State *l) { ENetPacket *packet = read_packet(l, 2, &channel_id); // printf("sending, channel_id=%d\n", channel_id); - enet_peer_send(peer, channel_id, packet); - return 0; + int ret = enet_peer_send(peer, channel_id, packet); + if (ret < 0) { + enet_packet_destroy(packet); + } + + lua_pushinteger(l, ret); + + return 1; } static const struct luaL_Reg enet_funcs [] = { @@ -734,9 +740,6 @@ static const struct luaL_Reg enet_host_funcs [] = { // Since ENetSocket isn't part of enet-lua, we should try to keep // naming conventions the same as the rest of the lib. {"get_socket_address", host_get_socket_address}, - // TODO: Remove the line below in future versions, it's for backward - // compatibility only. - {"socket_get_address", host_get_socket_address}, // We need this function to free up our ports when needed! {"destroy", host_gc}, @@ -803,7 +806,7 @@ int luaopen_enet(lua_State *l) { lua_setfield(l, LUA_REGISTRYINDEX, "enet_peers"); - luax_register(l, "enet", enet_funcs); + luax_register(l, nullptr, enet_funcs); // return the enet table created with luaL_register return 1; diff --git a/love/src/jni/love/src/libraries/enet/lua-enet.h b/love/src/jni/love/src/libraries/enet/lua-enet.h index 2512ce45..de40b213 100644 --- a/love/src/jni/love/src/libraries/enet/lua-enet.h +++ b/love/src/jni/love/src/libraries/enet/lua-enet.h @@ -1,5 +1,5 @@ /** -* Copyright (c) 2006-2016 LOVE Development Team +* Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff --git a/love/src/jni/love/src/libraries/glslang/OGLCompilersDLL/InitializeDll.cpp b/love/src/jni/love/src/libraries/glslang/OGLCompilersDLL/InitializeDll.cpp new file mode 100644 index 00000000..abea9108 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/OGLCompilersDLL/InitializeDll.cpp @@ -0,0 +1,165 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#define SH_EXPORTING + +#include + +#include "InitializeDll.h" +#include "../glslang/Include/InitializeGlobals.h" +#include "../glslang/Public/ShaderLang.h" +#include "../glslang/Include/PoolAlloc.h" + +namespace glslang { + +OS_TLSIndex ThreadInitializeIndex = OS_INVALID_TLS_INDEX; + +// Per-process initialization. +// Needs to be called at least once before parsing, etc. is done. +// Will also do thread initialization for the calling thread; other +// threads will need to do that explicitly. +bool InitProcess() +{ + glslang::GetGlobalLock(); + + if (ThreadInitializeIndex != OS_INVALID_TLS_INDEX) { + // + // Function is re-entrant. + // + + glslang::ReleaseGlobalLock(); + return true; + } + + ThreadInitializeIndex = OS_AllocTLSIndex(); + + if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) { + assert(0 && "InitProcess(): Failed to allocate TLS area for init flag"); + + glslang::ReleaseGlobalLock(); + return false; + } + + if (! InitializePoolIndex()) { + assert(0 && "InitProcess(): Failed to initialize global pool"); + + glslang::ReleaseGlobalLock(); + return false; + } + + if (! InitThread()) { + assert(0 && "InitProcess(): Failed to initialize thread"); + + glslang::ReleaseGlobalLock(); + return false; + } + + glslang::ReleaseGlobalLock(); + return true; +} + +// Per-thread scoped initialization. +// Must be called at least once by each new thread sharing the +// symbol tables, etc., needed to parse. +bool InitThread() +{ + // + // This function is re-entrant + // + if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) { + assert(0 && "InitThread(): Process hasn't been initalised."); + return false; + } + + if (OS_GetTLSValue(ThreadInitializeIndex) != 0) + return true; + + if (! OS_SetTLSValue(ThreadInitializeIndex, (void *)1)) { + assert(0 && "InitThread(): Unable to set init flag."); + return false; + } + + glslang::SetThreadPoolAllocator(nullptr); + + return true; +} + +// Not necessary to call this: InitThread() is reentrant, and the need +// to do per thread tear down has been removed. +// +// This is kept, with memory management removed, to satisfy any exiting +// calls to it that rely on it. +bool DetachThread() +{ + bool success = true; + + if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) + return true; + + // + // Function is re-entrant and this thread may not have been initialized. + // + if (OS_GetTLSValue(ThreadInitializeIndex) != 0) { + if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)0)) { + assert(0 && "DetachThread(): Unable to clear init flag."); + success = false; + } + } + + return success; +} + +// Not necessary to call this: InitProcess() is reentrant. +// +// This is kept, with memory management removed, to satisfy any exiting +// calls to it that rely on it. +// +// Users of glslang should call shFinalize() or glslang::FinalizeProcess() for +// process-scoped memory tear down. +bool DetachProcess() +{ + bool success = true; + + if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) + return true; + + success = DetachThread(); + + OS_FreeTLSIndex(ThreadInitializeIndex); + ThreadInitializeIndex = OS_INVALID_TLS_INDEX; + + return success; +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/OGLCompilersDLL/InitializeDll.h b/love/src/jni/love/src/libraries/glslang/OGLCompilersDLL/InitializeDll.h new file mode 100644 index 00000000..661cee4d --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/OGLCompilersDLL/InitializeDll.h @@ -0,0 +1,49 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +#ifndef __INITIALIZEDLL_H +#define __INITIALIZEDLL_H + +#include "../glslang/OSDependent/osinclude.h" + +namespace glslang { + +bool InitProcess(); +bool InitThread(); +bool DetachThread(); // not called from standalone, perhaps other tools rely on parts of it +bool DetachProcess(); // not called from standalone, perhaps other tools rely on parts of it + +} // end namespace glslang + +#endif // __INITIALIZEDLL_H + diff --git a/love/src/jni/love/src/libraries/glslang/glslang/GenericCodeGen/CodeGen.cpp b/love/src/jni/love/src/libraries/glslang/glslang/GenericCodeGen/CodeGen.cpp new file mode 100644 index 00000000..b3c7226d --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/GenericCodeGen/CodeGen.cpp @@ -0,0 +1,76 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#include "../Include/Common.h" +#include "../Include/ShHandle.h" +#include "../MachineIndependent/Versions.h" + +// +// Here is where real machine specific high-level data would be defined. +// +class TGenericCompiler : public TCompiler { +public: + TGenericCompiler(EShLanguage l, int dOptions) : TCompiler(l, infoSink), debugOptions(dOptions) { } + virtual bool compile(TIntermNode* root, int version = 0, EProfile profile = ENoProfile); + TInfoSink infoSink; + int debugOptions; +}; + +// +// This function must be provided to create the actual +// compile object used by higher level code. It returns +// a subclass of TCompiler. +// +TCompiler* ConstructCompiler(EShLanguage language, int debugOptions) +{ + return new TGenericCompiler(language, debugOptions); +} + +// +// Delete the compiler made by ConstructCompiler +// +void DeleteCompiler(TCompiler* compiler) +{ + delete compiler; +} + +// +// Generate code from the given parse tree +// +bool TGenericCompiler::compile(TIntermNode* /*root*/, int /*version*/, EProfile /*profile*/) +{ + haveValidObjectCode = true; + + return haveValidObjectCode; +} diff --git a/love/src/jni/love/src/libraries/glslang/glslang/GenericCodeGen/Link.cpp b/love/src/jni/love/src/libraries/glslang/glslang/GenericCodeGen/Link.cpp new file mode 100644 index 00000000..c38db0f6 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/GenericCodeGen/Link.cpp @@ -0,0 +1,91 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +// +// The top level algorithms for linking multiple +// shaders together. +// +#include "../Include/Common.h" +#include "../Include/ShHandle.h" + +// +// Actual link object, derived from the shader handle base classes. +// +class TGenericLinker : public TLinker { +public: + TGenericLinker(EShExecutable e, int dOptions) : TLinker(e, infoSink), debugOptions(dOptions) { } + bool link(TCompilerList&, TUniformMap*) { return true; } + void getAttributeBindings(ShBindingTable const **) const { } + TInfoSink infoSink; + int debugOptions; +}; + +// +// The internal view of a uniform/float object exchanged with the driver. +// +class TUniformLinkedMap : public TUniformMap { +public: + TUniformLinkedMap() { } + virtual int getLocation(const char*) { return 0; } +}; + +TShHandleBase* ConstructLinker(EShExecutable executable, int debugOptions) +{ + return new TGenericLinker(executable, debugOptions); +} + +void DeleteLinker(TShHandleBase* linker) +{ + delete linker; +} + +TUniformMap* ConstructUniformMap() +{ + return new TUniformLinkedMap(); +} + +void DeleteUniformMap(TUniformMap* map) +{ + delete map; +} + +TShHandleBase* ConstructBindings() +{ + return 0; +} + +void DeleteBindingList(TShHandleBase* bindingList) +{ + delete bindingList; +} diff --git a/love/src/jni/love/src/libraries/glslang/glslang/Include/BaseTypes.h b/love/src/jni/love/src/libraries/glslang/glslang/Include/BaseTypes.h new file mode 100644 index 00000000..050c2c4b --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/Include/BaseTypes.h @@ -0,0 +1,387 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2012-2013 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef _BASICTYPES_INCLUDED_ +#define _BASICTYPES_INCLUDED_ + +namespace glslang { + +// +// Basic type. Arrays, vectors, sampler details, etc., are orthogonal to this. +// +enum TBasicType { + EbtVoid, + EbtFloat, + EbtDouble, +#ifdef AMD_EXTENSIONS + EbtFloat16, +#endif + EbtInt, + EbtUint, + EbtInt64, + EbtUint64, +#ifdef AMD_EXTENSIONS + EbtInt16, + EbtUint16, +#endif + EbtBool, + EbtAtomicUint, + EbtSampler, + EbtStruct, + EbtBlock, + + // HLSL types that live only temporarily. + EbtString, + + EbtNumTypes +}; + +// +// Storage qualifiers. Should align with different kinds of storage or +// resource or GLSL storage qualifier. Expansion is deprecated. +// +// N.B.: You probably DON'T want to add anything here, but rather just add it +// to the built-in variables. See the comment above TBuiltInVariable. +// +// A new built-in variable will normally be an existing qualifier, like 'in', 'out', etc. +// DO NOT follow the design pattern of, say EvqInstanceId, etc. +// +enum TStorageQualifier { + EvqTemporary, // For temporaries (within a function), read/write + EvqGlobal, // For globals read/write + EvqConst, // User-defined constant values, will be semantically constant and constant folded + EvqVaryingIn, // pipeline input, read only, also supercategory for all built-ins not included in this enum (see TBuiltInVariable) + EvqVaryingOut, // pipeline output, read/write, also supercategory for all built-ins not included in this enum (see TBuiltInVariable) + EvqUniform, // read only, shared with app + EvqBuffer, // read/write, shared with app + EvqShared, // compute shader's read/write 'shared' qualifier + + // parameters + EvqIn, // also, for 'in' in the grammar before we know if it's a pipeline input or an 'in' parameter + EvqOut, // also, for 'out' in the grammar before we know if it's a pipeline output or an 'out' parameter + EvqInOut, + EvqConstReadOnly, // input; also other read-only types having neither a constant value nor constant-value semantics + + // built-ins read by vertex shader + EvqVertexId, + EvqInstanceId, + + // built-ins written by vertex shader + EvqPosition, + EvqPointSize, + EvqClipVertex, + + // built-ins read by fragment shader + EvqFace, + EvqFragCoord, + EvqPointCoord, + + // built-ins written by fragment shader + EvqFragColor, + EvqFragDepth, + + // end of list + EvqLast +}; + +// +// Subcategories of the TStorageQualifier, simply to give a direct mapping +// between built-in variable names and an numerical value (the enum). +// +// For backward compatibility, there is some redundancy between the +// TStorageQualifier and these. Existing members should both be maintained accurately. +// However, any new built-in variable (and any existing non-redundant one) +// must follow the pattern that the specific built-in is here, and only its +// general qualifier is in TStorageQualifier. +// +// Something like gl_Position, which is sometimes 'in' and sometimes 'out' +// shows up as two different built-in variables in a single stage, but +// only has a single enum in TBuiltInVariable, so both the +// TStorageQualifier and the TBuitinVariable are needed to distinguish +// between them. +// +enum TBuiltInVariable { + EbvNone, + EbvNumWorkGroups, + EbvWorkGroupSize, + EbvWorkGroupId, + EbvLocalInvocationId, + EbvGlobalInvocationId, + EbvLocalInvocationIndex, + EbvSubGroupSize, + EbvSubGroupInvocation, + EbvSubGroupEqMask, + EbvSubGroupGeMask, + EbvSubGroupGtMask, + EbvSubGroupLeMask, + EbvSubGroupLtMask, + EbvVertexId, + EbvInstanceId, + EbvVertexIndex, + EbvInstanceIndex, + EbvBaseVertex, + EbvBaseInstance, + EbvDrawId, + EbvPosition, + EbvPointSize, + EbvClipVertex, + EbvClipDistance, + EbvCullDistance, + EbvNormal, + EbvVertex, + EbvMultiTexCoord0, + EbvMultiTexCoord1, + EbvMultiTexCoord2, + EbvMultiTexCoord3, + EbvMultiTexCoord4, + EbvMultiTexCoord5, + EbvMultiTexCoord6, + EbvMultiTexCoord7, + EbvFrontColor, + EbvBackColor, + EbvFrontSecondaryColor, + EbvBackSecondaryColor, + EbvTexCoord, + EbvFogFragCoord, + EbvInvocationId, + EbvPrimitiveId, + EbvLayer, + EbvViewportIndex, + EbvPatchVertices, + EbvTessLevelOuter, + EbvTessLevelInner, + EbvBoundingBox, + EbvTessCoord, + EbvColor, + EbvSecondaryColor, + EbvFace, + EbvFragCoord, + EbvPointCoord, + EbvFragColor, + EbvFragData, + EbvFragDepth, + EbvFragStencilRef, + EbvSampleId, + EbvSamplePosition, + EbvSampleMask, + EbvHelperInvocation, + +#ifdef AMD_EXTENSIONS + EbvBaryCoordNoPersp, + EbvBaryCoordNoPerspCentroid, + EbvBaryCoordNoPerspSample, + EbvBaryCoordSmooth, + EbvBaryCoordSmoothCentroid, + EbvBaryCoordSmoothSample, + EbvBaryCoordPullModel, +#endif + + EbvViewIndex, + EbvDeviceIndex, + +#ifdef NV_EXTENSIONS + EbvViewportMaskNV, + EbvSecondaryPositionNV, + EbvSecondaryViewportMaskNV, + EbvPositionPerViewNV, + EbvViewportMaskPerViewNV, + EbvFragFullyCoveredNV, +#endif + + // HLSL built-ins that live only temporarily, until they get remapped + // to one of the above. + EbvFragDepthGreater, + EbvFragDepthLesser, + EbvGsOutputStream, + EbvOutputPatch, + EbvInputPatch, + + // structbuffer types + EbvAppendConsume, // no need to differentiate append and consume + EbvRWStructuredBuffer, + EbvStructuredBuffer, + EbvByteAddressBuffer, + EbvRWByteAddressBuffer, + + EbvLast +}; + +// These will show up in error messages +__inline const char* GetStorageQualifierString(TStorageQualifier q) +{ + switch (q) { + case EvqTemporary: return "temp"; break; + case EvqGlobal: return "global"; break; + case EvqConst: return "const"; break; + case EvqConstReadOnly: return "const (read only)"; break; + case EvqVaryingIn: return "in"; break; + case EvqVaryingOut: return "out"; break; + case EvqUniform: return "uniform"; break; + case EvqBuffer: return "buffer"; break; + case EvqShared: return "shared"; break; + case EvqIn: return "in"; break; + case EvqOut: return "out"; break; + case EvqInOut: return "inout"; break; + case EvqVertexId: return "gl_VertexId"; break; + case EvqInstanceId: return "gl_InstanceId"; break; + case EvqPosition: return "gl_Position"; break; + case EvqPointSize: return "gl_PointSize"; break; + case EvqClipVertex: return "gl_ClipVertex"; break; + case EvqFace: return "gl_FrontFacing"; break; + case EvqFragCoord: return "gl_FragCoord"; break; + case EvqPointCoord: return "gl_PointCoord"; break; + case EvqFragColor: return "fragColor"; break; + case EvqFragDepth: return "gl_FragDepth"; break; + default: return "unknown qualifier"; + } +} + +__inline const char* GetBuiltInVariableString(TBuiltInVariable v) +{ + switch (v) { + case EbvNone: return ""; + case EbvNumWorkGroups: return "NumWorkGroups"; + case EbvWorkGroupSize: return "WorkGroupSize"; + case EbvWorkGroupId: return "WorkGroupID"; + case EbvLocalInvocationId: return "LocalInvocationID"; + case EbvGlobalInvocationId: return "GlobalInvocationID"; + case EbvLocalInvocationIndex: return "LocalInvocationIndex"; + case EbvSubGroupSize: return "SubGroupSize"; + case EbvSubGroupInvocation: return "SubGroupInvocation"; + case EbvSubGroupEqMask: return "SubGroupEqMask"; + case EbvSubGroupGeMask: return "SubGroupGeMask"; + case EbvSubGroupGtMask: return "SubGroupGtMask"; + case EbvSubGroupLeMask: return "SubGroupLeMask"; + case EbvSubGroupLtMask: return "SubGroupLtMask"; + case EbvVertexId: return "VertexId"; + case EbvInstanceId: return "InstanceId"; + case EbvVertexIndex: return "VertexIndex"; + case EbvInstanceIndex: return "InstanceIndex"; + case EbvBaseVertex: return "BaseVertex"; + case EbvBaseInstance: return "BaseInstance"; + case EbvDrawId: return "DrawId"; + case EbvPosition: return "Position"; + case EbvPointSize: return "PointSize"; + case EbvClipVertex: return "ClipVertex"; + case EbvClipDistance: return "ClipDistance"; + case EbvCullDistance: return "CullDistance"; + case EbvNormal: return "Normal"; + case EbvVertex: return "Vertex"; + case EbvMultiTexCoord0: return "MultiTexCoord0"; + case EbvMultiTexCoord1: return "MultiTexCoord1"; + case EbvMultiTexCoord2: return "MultiTexCoord2"; + case EbvMultiTexCoord3: return "MultiTexCoord3"; + case EbvMultiTexCoord4: return "MultiTexCoord4"; + case EbvMultiTexCoord5: return "MultiTexCoord5"; + case EbvMultiTexCoord6: return "MultiTexCoord6"; + case EbvMultiTexCoord7: return "MultiTexCoord7"; + case EbvFrontColor: return "FrontColor"; + case EbvBackColor: return "BackColor"; + case EbvFrontSecondaryColor: return "FrontSecondaryColor"; + case EbvBackSecondaryColor: return "BackSecondaryColor"; + case EbvTexCoord: return "TexCoord"; + case EbvFogFragCoord: return "FogFragCoord"; + case EbvInvocationId: return "InvocationID"; + case EbvPrimitiveId: return "PrimitiveID"; + case EbvLayer: return "Layer"; + case EbvViewportIndex: return "ViewportIndex"; + case EbvPatchVertices: return "PatchVertices"; + case EbvTessLevelOuter: return "TessLevelOuter"; + case EbvTessLevelInner: return "TessLevelInner"; + case EbvBoundingBox: return "BoundingBox"; + case EbvTessCoord: return "TessCoord"; + case EbvColor: return "Color"; + case EbvSecondaryColor: return "SecondaryColor"; + case EbvFace: return "Face"; + case EbvFragCoord: return "FragCoord"; + case EbvPointCoord: return "PointCoord"; + case EbvFragColor: return "FragColor"; + case EbvFragData: return "FragData"; + case EbvFragDepth: return "FragDepth"; + case EbvFragStencilRef: return "FragStencilRef"; + case EbvSampleId: return "SampleId"; + case EbvSamplePosition: return "SamplePosition"; + case EbvSampleMask: return "SampleMaskIn"; + case EbvHelperInvocation: return "HelperInvocation"; + +#ifdef AMD_EXTENSIONS + case EbvBaryCoordNoPersp: return "BaryCoordNoPersp"; + case EbvBaryCoordNoPerspCentroid: return "BaryCoordNoPerspCentroid"; + case EbvBaryCoordNoPerspSample: return "BaryCoordNoPerspSample"; + case EbvBaryCoordSmooth: return "BaryCoordSmooth"; + case EbvBaryCoordSmoothCentroid: return "BaryCoordSmoothCentroid"; + case EbvBaryCoordSmoothSample: return "BaryCoordSmoothSample"; + case EbvBaryCoordPullModel: return "BaryCoordPullModel"; +#endif + + case EbvViewIndex: return "ViewIndex"; + case EbvDeviceIndex: return "DeviceIndex"; + +#ifdef NV_EXTENSIONS + case EbvViewportMaskNV: return "ViewportMaskNV"; + case EbvSecondaryPositionNV: return "SecondaryPositionNV"; + case EbvSecondaryViewportMaskNV: return "SecondaryViewportMaskNV"; + case EbvPositionPerViewNV: return "PositionPerViewNV"; + case EbvViewportMaskPerViewNV: return "ViewportMaskPerViewNV"; + case EbvFragFullyCoveredNV: return "FragFullyCoveredNV"; +#endif + default: return "unknown built-in variable"; + } +} + +// In this enum, order matters; users can assume higher precision is a bigger value +// and EpqNone is 0. +enum TPrecisionQualifier { + EpqNone = 0, + EpqLow, + EpqMedium, + EpqHigh +}; + +__inline const char* GetPrecisionQualifierString(TPrecisionQualifier p) +{ + switch(p) { + case EpqNone: return ""; break; + case EpqLow: return "lowp"; break; + case EpqMedium: return "mediump"; break; + case EpqHigh: return "highp"; break; + default: return "unknown precision qualifier"; + } +} + +} // end namespace glslang + +#endif // _BASICTYPES_INCLUDED_ diff --git a/love/src/jni/love/src/libraries/glslang/glslang/Include/Common.h b/love/src/jni/love/src/libraries/glslang/glslang/Include/Common.h new file mode 100644 index 00000000..06a94755 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/Include/Common.h @@ -0,0 +1,274 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2012-2013 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef _COMMON_INCLUDED_ +#define _COMMON_INCLUDED_ + +#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/) || defined MINGW_HAS_SECURE_API + #include + #define snprintf sprintf_s + #define safe_vsprintf(buf,max,format,args) vsnprintf_s((buf), (max), (max), (format), (args)) +#elif defined (solaris) + #define safe_vsprintf(buf,max,format,args) vsnprintf((buf), (max), (format), (args)) + #include + #define UINT_PTR uintptr_t +#else + #define safe_vsprintf(buf,max,format,args) vsnprintf((buf), (max), (format), (args)) + #include + #define UINT_PTR uintptr_t +#endif + +#if defined(__ANDROID__) || _MSC_VER < 1700 +#include +namespace std { +template +std::string to_string(const T& val) { + std::ostringstream os; + os << val; + return os.str(); +} +} +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1800 +inline long long int strtoll (const char* str, char** endptr, int base) +{ + return _strtoi64(str, endptr, base); +} +inline unsigned long long int strtoull (const char* str, char** endptr, int base) +{ + return _strtoui64(str, endptr, base); +} +inline long long int atoll (const char* str) +{ + return strtoll(str, NULL, 10); +} +#endif + +#if defined(_MSC_VER) +#define strdup _strdup +#endif + +/* windows only pragma */ +#ifdef _MSC_VER + #pragma warning(disable : 4786) // Don't warn about too long identifiers + #pragma warning(disable : 4514) // unused inline method + #pragma warning(disable : 4201) // nameless union +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "PoolAlloc.h" + +// +// Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme. +// +#define POOL_ALLOCATOR_NEW_DELETE(A) \ + void* operator new(size_t s) { return (A).allocate(s); } \ + void* operator new(size_t, void *_Where) { return (_Where); } \ + void operator delete(void*) { } \ + void operator delete(void *, void *) { } \ + void* operator new[](size_t s) { return (A).allocate(s); } \ + void* operator new[](size_t, void *_Where) { return (_Where); } \ + void operator delete[](void*) { } \ + void operator delete[](void *, void *) { } + +namespace glslang { + + // + // Pool version of string. + // + typedef pool_allocator TStringAllocator; + typedef std::basic_string , TStringAllocator> TString; + +} // end namespace glslang + +// Repackage the std::hash for use by unordered map/set with a TString key. +namespace std { + + template<> struct hash { + std::size_t operator()(const glslang::TString& s) const + { + const unsigned _FNV_offset_basis = 2166136261U; + const unsigned _FNV_prime = 16777619U; + unsigned _Val = _FNV_offset_basis; + size_t _Count = s.size(); + const char* _First = s.c_str(); + for (size_t _Next = 0; _Next < _Count; ++_Next) + { + _Val ^= (unsigned)_First[_Next]; + _Val *= _FNV_prime; + } + + return _Val; + } + }; +} + +namespace glslang { + +inline TString* NewPoolTString(const char* s) +{ + void* memory = GetThreadPoolAllocator().allocate(sizeof(TString)); + return new(memory) TString(s); +} + +template inline T* NewPoolObject(T) +{ + return new(GetThreadPoolAllocator().allocate(sizeof(T))) T; +} + +template inline T* NewPoolObject(T, int instances) +{ + return new(GetThreadPoolAllocator().allocate(instances * sizeof(T))) T[instances]; +} + +// +// Pool allocator versions of vectors, lists, and maps +// +template class TVector : public std::vector > { +public: + POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) + + typedef typename std::vector >::size_type size_type; + TVector() : std::vector >() {} + TVector(const pool_allocator& a) : std::vector >(a) {} + TVector(size_type i) : std::vector >(i) {} + TVector(size_type i, const T& val) : std::vector >(i, val) {} +}; + +template class TList : public std::list > { +}; + +template > +class TMap : public std::map > > { +}; + +template , class PRED = std::equal_to > +class TUnorderedMap : public std::unordered_map > > { +}; + +// +// Persistent string memory. Should only be used for strings that survive +// across compiles/links. +// +typedef std::basic_string TPersistString; + +// +// templatized min and max functions. +// +template T Min(const T a, const T b) { return a < b ? a : b; } +template T Max(const T a, const T b) { return a > b ? a : b; } + +// +// Create a TString object from an integer. +// +#if defined _MSC_VER || defined MINGW_HAS_SECURE_API +inline const TString String(const int i, const int base = 10) +{ + char text[16]; // 32 bit ints are at most 10 digits in base 10 + _itoa_s(i, text, sizeof(text), base); + return text; +} +#else +inline const TString String(const int i, const int /*base*/ = 10) +{ + char text[16]; // 32 bit ints are at most 10 digits in base 10 + + // we assume base 10 for all cases + snprintf(text, sizeof(text), "%d", i); + + return text; +} +#endif + +struct TSourceLoc { + void init() { name = nullptr; string = 0; line = 0; column = 0; } + void init(int stringNum) { init(); string = stringNum; } + // Returns the name if it exists. Otherwise, returns the string number. + std::string getStringNameOrNum(bool quoteStringName = true) const + { + if (name != nullptr) + return quoteStringName ? ("\"" + std::string(name) + "\"") : name; + return std::to_string((long long)string); + } + const char* name; // descriptive name for this string + int string; + int line; + int column; +}; + +class TPragmaTable : public TMap { +public: + POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) +}; + +const int MaxTokenLength = 1024; + +template bool IsPow2(T powerOf2) +{ + if (powerOf2 <= 0) + return false; + + return (powerOf2 & (powerOf2 - 1)) == 0; +} + +// Round number up to a multiple of the given powerOf2, which is not +// a power, just a number that must be a power of 2. +template void RoundToPow2(T& number, int powerOf2) +{ + assert(IsPow2(powerOf2)); + number = (number + powerOf2 - 1) & ~(powerOf2 - 1); +} + +template bool IsMultipleOfPow2(T number, int powerOf2) +{ + assert(IsPow2(powerOf2)); + return ! (number & (powerOf2 - 1)); +} + +} // end namespace glslang + +#endif // _COMMON_INCLUDED_ diff --git a/love/src/jni/love/src/libraries/glslang/glslang/Include/ConstantUnion.h b/love/src/jni/love/src/libraries/glslang/glslang/Include/ConstantUnion.h new file mode 100644 index 00000000..f66a7ff5 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/Include/ConstantUnion.h @@ -0,0 +1,625 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2013 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef _CONSTANT_UNION_INCLUDED_ +#define _CONSTANT_UNION_INCLUDED_ + +namespace glslang { + +class TConstUnion { +public: + POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) + + TConstUnion() : iConst(0), type(EbtInt) { } + + void setIConst(int i) + { + iConst = i; + type = EbtInt; + } + + void setUConst(unsigned int u) + { + uConst = u; + type = EbtUint; + } + + void setI64Const(long long i64) + { + i64Const = i64; + type = EbtInt64; + } + + void setU64Const(unsigned long long u64) + { + u64Const = u64; + type = EbtUint64; + } + + void setDConst(double d) + { + dConst = d; + type = EbtDouble; + } + + void setBConst(bool b) + { + bConst = b; + type = EbtBool; + } + + void setSConst(const TString* s) + { + sConst = s; + type = EbtString; + } + + int getIConst() const { return iConst; } + unsigned int getUConst() const { return uConst; } + long long getI64Const() const { return i64Const; } + unsigned long long getU64Const() const { return u64Const; } + double getDConst() const { return dConst; } + bool getBConst() const { return bConst; } + const TString* getSConst() const { return sConst; } + + bool operator==(const int i) const + { + if (i == iConst) + return true; + + return false; + } + + bool operator==(const unsigned int u) const + { + if (u == uConst) + return true; + + return false; + } + + bool operator==(const long long i64) const + { + if (i64 == i64Const) + return true; + + return false; + } + + bool operator==(const unsigned long long u64) const + { + if (u64 == u64Const) + return true; + + return false; + } + + bool operator==(const double d) const + { + if (d == dConst) + return true; + + return false; + } + + bool operator==(const bool b) const + { + if (b == bConst) + return true; + + return false; + } + + bool operator==(const TConstUnion& constant) const + { + if (constant.type != type) + return false; + + switch (type) { + case EbtInt: + if (constant.iConst == iConst) + return true; + + break; + case EbtUint: + if (constant.uConst == uConst) + return true; + + break; + case EbtInt64: + if (constant.i64Const == i64Const) + return true; + + break; + case EbtUint64: + if (constant.u64Const == u64Const) + return true; + + break; + case EbtDouble: + if (constant.dConst == dConst) + return true; + + break; + case EbtBool: + if (constant.bConst == bConst) + return true; + + break; + default: + assert(false && "Default missing"); + } + + return false; + } + + bool operator!=(const int i) const + { + return !operator==(i); + } + + bool operator!=(const unsigned int u) const + { + return !operator==(u); + } + + bool operator!=(const long long i) const + { + return !operator==(i); + } + + bool operator!=(const unsigned long long u) const + { + return !operator==(u); + } + + bool operator!=(const float f) const + { + return !operator==(f); + } + + bool operator!=(const bool b) const + { + return !operator==(b); + } + + bool operator!=(const TConstUnion& constant) const + { + return !operator==(constant); + } + + bool operator>(const TConstUnion& constant) const + { + assert(type == constant.type); + switch (type) { + case EbtInt: + if (iConst > constant.iConst) + return true; + + return false; + case EbtUint: + if (uConst > constant.uConst) + return true; + + return false; + case EbtInt64: + if (i64Const > constant.i64Const) + return true; + + return false; + case EbtUint64: + if (u64Const > constant.u64Const) + return true; + + return false; + case EbtDouble: + if (dConst > constant.dConst) + return true; + + return false; + default: + assert(false && "Default missing"); + return false; + } + } + + bool operator<(const TConstUnion& constant) const + { + assert(type == constant.type); + switch (type) { + case EbtInt: + if (iConst < constant.iConst) + return true; + + return false; + case EbtUint: + if (uConst < constant.uConst) + return true; + + return false; + case EbtInt64: + if (i64Const < constant.i64Const) + return true; + + return false; + case EbtUint64: + if (u64Const < constant.u64Const) + return true; + + return false; + case EbtDouble: + if (dConst < constant.dConst) + return true; + + return false; + default: + assert(false && "Default missing"); + return false; + } + } + + TConstUnion operator+(const TConstUnion& constant) const + { + TConstUnion returnValue; + assert(type == constant.type); + switch (type) { + case EbtInt: returnValue.setIConst(iConst + constant.iConst); break; + case EbtInt64: returnValue.setI64Const(i64Const + constant.i64Const); break; + case EbtUint: returnValue.setUConst(uConst + constant.uConst); break; + case EbtUint64: returnValue.setU64Const(u64Const + constant.u64Const); break; + case EbtDouble: returnValue.setDConst(dConst + constant.dConst); break; + default: assert(false && "Default missing"); + } + + return returnValue; + } + + TConstUnion operator-(const TConstUnion& constant) const + { + TConstUnion returnValue; + assert(type == constant.type); + switch (type) { + case EbtInt: returnValue.setIConst(iConst - constant.iConst); break; + case EbtInt64: returnValue.setI64Const(i64Const - constant.i64Const); break; + case EbtUint: returnValue.setUConst(uConst - constant.uConst); break; + case EbtUint64: returnValue.setU64Const(u64Const - constant.u64Const); break; + case EbtDouble: returnValue.setDConst(dConst - constant.dConst); break; + default: assert(false && "Default missing"); + } + + return returnValue; + } + + TConstUnion operator*(const TConstUnion& constant) const + { + TConstUnion returnValue; + assert(type == constant.type); + switch (type) { + case EbtInt: returnValue.setIConst(iConst * constant.iConst); break; + case EbtInt64: returnValue.setI64Const(i64Const * constant.i64Const); break; + case EbtUint: returnValue.setUConst(uConst * constant.uConst); break; + case EbtUint64: returnValue.setU64Const(u64Const * constant.u64Const); break; + case EbtDouble: returnValue.setDConst(dConst * constant.dConst); break; + default: assert(false && "Default missing"); + } + + return returnValue; + } + + TConstUnion operator%(const TConstUnion& constant) const + { + TConstUnion returnValue; + assert(type == constant.type); + switch (type) { + case EbtInt: returnValue.setIConst(iConst % constant.iConst); break; + case EbtInt64: returnValue.setI64Const(i64Const % constant.i64Const); break; + case EbtUint: returnValue.setUConst(uConst % constant.uConst); break; + case EbtUint64: returnValue.setU64Const(u64Const % constant.u64Const); break; + default: assert(false && "Default missing"); + } + + return returnValue; + } + + TConstUnion operator>>(const TConstUnion& constant) const + { + TConstUnion returnValue; + switch (type) { + case EbtInt: + switch (constant.type) { + case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break; + case EbtUint: returnValue.setIConst(iConst >> constant.uConst); break; + case EbtInt64: returnValue.setIConst(iConst >> constant.i64Const); break; + case EbtUint64: returnValue.setIConst(iConst >> constant.u64Const); break; + default: assert(false && "Default missing"); + } + break; + case EbtUint: + switch (constant.type) { + case EbtInt: returnValue.setUConst(uConst >> constant.iConst); break; + case EbtUint: returnValue.setUConst(uConst >> constant.uConst); break; + case EbtInt64: returnValue.setUConst(uConst >> constant.i64Const); break; + case EbtUint64: returnValue.setUConst(uConst >> constant.u64Const); break; + default: assert(false && "Default missing"); + } + break; + case EbtInt64: + switch (constant.type) { + case EbtInt: returnValue.setI64Const(i64Const >> constant.iConst); break; + case EbtUint: returnValue.setI64Const(i64Const >> constant.uConst); break; + case EbtInt64: returnValue.setI64Const(i64Const >> constant.i64Const); break; + case EbtUint64: returnValue.setI64Const(i64Const >> constant.u64Const); break; + default: assert(false && "Default missing"); + } + break; + case EbtUint64: + switch (constant.type) { + case EbtInt: returnValue.setU64Const(u64Const >> constant.iConst); break; + case EbtUint: returnValue.setU64Const(u64Const >> constant.uConst); break; + case EbtInt64: returnValue.setU64Const(u64Const >> constant.i64Const); break; + case EbtUint64: returnValue.setU64Const(u64Const >> constant.u64Const); break; + default: assert(false && "Default missing"); + } + break; + default: assert(false && "Default missing"); + } + + return returnValue; + } + + TConstUnion operator<<(const TConstUnion& constant) const + { + TConstUnion returnValue; + switch (type) { + case EbtInt: + switch (constant.type) { + case EbtInt: returnValue.setIConst(iConst << constant.iConst); break; + case EbtUint: returnValue.setIConst(iConst << constant.uConst); break; + case EbtInt64: returnValue.setIConst(iConst << constant.i64Const); break; + case EbtUint64: returnValue.setIConst(iConst << constant.u64Const); break; + default: assert(false && "Default missing"); + } + break; + case EbtUint: + switch (constant.type) { + case EbtInt: returnValue.setUConst(uConst << constant.iConst); break; + case EbtUint: returnValue.setUConst(uConst << constant.uConst); break; + case EbtInt64: returnValue.setUConst(uConst << constant.i64Const); break; + case EbtUint64: returnValue.setUConst(uConst << constant.u64Const); break; + default: assert(false && "Default missing"); + } + break; + case EbtInt64: + switch (constant.type) { + case EbtInt: returnValue.setI64Const(i64Const << constant.iConst); break; + case EbtUint: returnValue.setI64Const(i64Const << constant.uConst); break; + case EbtInt64: returnValue.setI64Const(i64Const << constant.i64Const); break; + case EbtUint64: returnValue.setI64Const(i64Const << constant.u64Const); break; + default: assert(false && "Default missing"); + } + break; + case EbtUint64: + switch (constant.type) { + case EbtInt: returnValue.setU64Const(u64Const << constant.iConst); break; + case EbtUint: returnValue.setU64Const(u64Const << constant.uConst); break; + case EbtInt64: returnValue.setU64Const(u64Const << constant.i64Const); break; + case EbtUint64: returnValue.setU64Const(u64Const << constant.u64Const); break; + default: assert(false && "Default missing"); + } + break; + default: assert(false && "Default missing"); + } + + return returnValue; + } + + TConstUnion operator&(const TConstUnion& constant) const + { + TConstUnion returnValue; + assert(type == constant.type); + switch (type) { + case EbtInt: returnValue.setIConst(iConst & constant.iConst); break; + case EbtUint: returnValue.setUConst(uConst & constant.uConst); break; + case EbtInt64: returnValue.setI64Const(i64Const & constant.i64Const); break; + case EbtUint64: returnValue.setU64Const(u64Const & constant.u64Const); break; + default: assert(false && "Default missing"); + } + + return returnValue; + } + + TConstUnion operator|(const TConstUnion& constant) const + { + TConstUnion returnValue; + assert(type == constant.type); + switch (type) { + case EbtInt: returnValue.setIConst(iConst | constant.iConst); break; + case EbtUint: returnValue.setUConst(uConst | constant.uConst); break; + case EbtInt64: returnValue.setI64Const(i64Const | constant.i64Const); break; + case EbtUint64: returnValue.setU64Const(u64Const | constant.u64Const); break; + default: assert(false && "Default missing"); + } + + return returnValue; + } + + TConstUnion operator^(const TConstUnion& constant) const + { + TConstUnion returnValue; + assert(type == constant.type); + switch (type) { + case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break; + case EbtUint: returnValue.setUConst(uConst ^ constant.uConst); break; + case EbtInt64: returnValue.setI64Const(i64Const ^ constant.i64Const); break; + case EbtUint64: returnValue.setU64Const(u64Const ^ constant.u64Const); break; + default: assert(false && "Default missing"); + } + + return returnValue; + } + + TConstUnion operator~() const + { + TConstUnion returnValue; + switch (type) { + case EbtInt: returnValue.setIConst(~iConst); break; + case EbtUint: returnValue.setUConst(~uConst); break; + case EbtInt64: returnValue.setI64Const(~i64Const); break; + case EbtUint64: returnValue.setU64Const(~u64Const); break; + default: assert(false && "Default missing"); + } + + return returnValue; + } + + TConstUnion operator&&(const TConstUnion& constant) const + { + TConstUnion returnValue; + assert(type == constant.type); + switch (type) { + case EbtBool: returnValue.setBConst(bConst && constant.bConst); break; + default: assert(false && "Default missing"); + } + + return returnValue; + } + + TConstUnion operator||(const TConstUnion& constant) const + { + TConstUnion returnValue; + assert(type == constant.type); + switch (type) { + case EbtBool: returnValue.setBConst(bConst || constant.bConst); break; + default: assert(false && "Default missing"); + } + + return returnValue; + } + + TBasicType getType() const { return type; } + +private: + union { + int iConst; // used for ivec, scalar ints + unsigned int uConst; // used for uvec, scalar uints + long long i64Const; // used for i64vec, scalar int64s + unsigned long long u64Const; // used for u64vec, scalar uint64s + bool bConst; // used for bvec, scalar bools + double dConst; // used for vec, dvec, mat, dmat, scalar floats and doubles + const TString* sConst; // string constant + }; + + TBasicType type; +}; + +// Encapsulate having a pointer to an array of TConstUnion, +// which only needs to be allocated if its size is going to be +// bigger than 0. +// +// One convenience is being able to use [] to go inside the array, instead +// of C++ assuming it as an array of pointers to vectors. +// +// General usage is that the size is known up front, and it is +// created once with the proper size. +// +class TConstUnionArray { +public: + POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) + + TConstUnionArray() : unionArray(nullptr) { } + virtual ~TConstUnionArray() { } + + explicit TConstUnionArray(int size) + { + if (size == 0) + unionArray = nullptr; + else + unionArray = new TConstUnionVector(size); + } + TConstUnionArray(const TConstUnionArray& a) : unionArray(a.unionArray) { } + TConstUnionArray(const TConstUnionArray& a, int start, int size) + { + unionArray = new TConstUnionVector(size); + for (int i = 0; i < size; ++i) + (*unionArray)[i] = a[start + i]; + } + + // Use this constructor for a smear operation + TConstUnionArray(int size, const TConstUnion& val) + { + unionArray = new TConstUnionVector(size, val); + } + + int size() const { return unionArray ? (int)unionArray->size() : 0; } + TConstUnion& operator[](size_t index) { return (*unionArray)[index]; } + const TConstUnion& operator[](size_t index) const { return (*unionArray)[index]; } + bool operator==(const TConstUnionArray& rhs) const + { + // this includes the case that both are unallocated + if (unionArray == rhs.unionArray) + return true; + + if (! unionArray || ! rhs.unionArray) + return false; + + if (! unionArray || ! rhs.unionArray) + return false; + + return *unionArray == *rhs.unionArray; + } + bool operator!=(const TConstUnionArray& rhs) const { return ! operator==(rhs); } + + double dot(const TConstUnionArray& rhs) + { + assert(rhs.unionArray->size() == unionArray->size()); + double sum = 0.0; + + for (size_t comp = 0; comp < unionArray->size(); ++comp) + sum += (*this)[comp].getDConst() * rhs[comp].getDConst(); + + return sum; + } + + bool empty() const { return unionArray == nullptr; } + +protected: + typedef TVector TConstUnionVector; + TConstUnionVector* unionArray; +}; + +} // end namespace glslang + +#endif // _CONSTANT_UNION_INCLUDED_ diff --git a/love/src/jni/love/src/libraries/glslang/glslang/Include/InfoSink.h b/love/src/jni/love/src/libraries/glslang/glslang/Include/InfoSink.h new file mode 100644 index 00000000..dceb603c --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/Include/InfoSink.h @@ -0,0 +1,144 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef _INFOSINK_INCLUDED_ +#define _INFOSINK_INCLUDED_ + +#include "../Include/Common.h" +#include + +namespace glslang { + +// +// TPrefixType is used to centralize how info log messages start. +// See below. +// +enum TPrefixType { + EPrefixNone, + EPrefixWarning, + EPrefixError, + EPrefixInternalError, + EPrefixUnimplemented, + EPrefixNote +}; + +enum TOutputStream { + ENull = 0, + EDebugger = 0x01, + EStdOut = 0x02, + EString = 0x04, +}; +// +// Encapsulate info logs for all objects that have them. +// +// The methods are a general set of tools for getting a variety of +// messages and types inserted into the log. +// +class TInfoSinkBase { +public: + TInfoSinkBase() : outputStream(4) {} + void erase() { sink.erase(); } + TInfoSinkBase& operator<<(const TPersistString& t) { append(t); return *this; } + TInfoSinkBase& operator<<(char c) { append(1, c); return *this; } + TInfoSinkBase& operator<<(const char* s) { append(s); return *this; } + TInfoSinkBase& operator<<(int n) { append(String(n)); return *this; } + TInfoSinkBase& operator<<(unsigned int n) { append(String(n)); return *this; } + TInfoSinkBase& operator<<(float n) { const int size = 40; char buf[size]; + snprintf(buf, size, (fabs(n) > 1e-8 && fabs(n) < 1e8) || n == 0.0f ? "%f" : "%g", n); + append(buf); + return *this; } + TInfoSinkBase& operator+(const TPersistString& t) { append(t); return *this; } + TInfoSinkBase& operator+(const TString& t) { append(t); return *this; } + TInfoSinkBase& operator<<(const TString& t) { append(t); return *this; } + TInfoSinkBase& operator+(const char* s) { append(s); return *this; } + const char* c_str() const { return sink.c_str(); } + void prefix(TPrefixType message) { + switch(message) { + case EPrefixNone: break; + case EPrefixWarning: append("WARNING: "); break; + case EPrefixError: append("ERROR: "); break; + case EPrefixInternalError: append("INTERNAL ERROR: "); break; + case EPrefixUnimplemented: append("UNIMPLEMENTED: "); break; + case EPrefixNote: append("NOTE: "); break; + default: append("UNKNOWN ERROR: "); break; + } + } + void location(const TSourceLoc& loc) { + const int maxSize = 24; + char locText[maxSize]; + snprintf(locText, maxSize, ":%d", loc.line); + append(loc.getStringNameOrNum(false).c_str()); + append(locText); + append(": "); + } + void message(TPrefixType message, const char* s) { + prefix(message); + append(s); + append("\n"); + } + void message(TPrefixType message, const char* s, const TSourceLoc& loc) { + prefix(message); + location(loc); + append(s); + append("\n"); + } + + void setOutputStream(int output = 4) + { + outputStream = output; + } + +protected: + void append(const char* s); + + void append(int count, char c); + void append(const TPersistString& t); + void append(const TString& t); + + void checkMem(size_t growth) { if (sink.capacity() < sink.size() + growth + 2) + sink.reserve(sink.capacity() + sink.capacity() / 2); } + void appendToStream(const char* s); + TPersistString sink; + int outputStream; +}; + +} // end namespace glslang + +class TInfoSink { +public: + glslang::TInfoSinkBase info; + glslang::TInfoSinkBase debug; +}; + +#endif // _INFOSINK_INCLUDED_ diff --git a/love/src/jni/love/src/libraries/glslang/glslang/Include/InitializeGlobals.h b/love/src/jni/love/src/libraries/glslang/glslang/Include/InitializeGlobals.h new file mode 100644 index 00000000..95d0a40e --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/Include/InitializeGlobals.h @@ -0,0 +1,44 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef __INITIALIZE_GLOBALS_INCLUDED_ +#define __INITIALIZE_GLOBALS_INCLUDED_ + +namespace glslang { + +bool InitializePoolIndex(); + +} // end namespace glslang + +#endif // __INITIALIZE_GLOBALS_INCLUDED_ diff --git a/love/src/jni/love/src/libraries/glslang/glslang/Include/PoolAlloc.h b/love/src/jni/love/src/libraries/glslang/glslang/Include/PoolAlloc.h new file mode 100644 index 00000000..cc7f4000 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/Include/PoolAlloc.h @@ -0,0 +1,318 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2012-2013 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef _POOLALLOC_INCLUDED_ +#define _POOLALLOC_INCLUDED_ + +#ifdef _DEBUG +# define GUARD_BLOCKS // define to enable guard block sanity checking +#endif + +// +// This header defines an allocator that can be used to efficiently +// allocate a large number of small requests for heap memory, with the +// intention that they are not individually deallocated, but rather +// collectively deallocated at one time. +// +// This simultaneously +// +// * Makes each individual allocation much more efficient; the +// typical allocation is trivial. +// * Completely avoids the cost of doing individual deallocation. +// * Saves the trouble of tracking down and plugging a large class of leaks. +// +// Individual classes can use this allocator by supplying their own +// new and delete methods. +// +// STL containers can use this allocator by using the pool_allocator +// class as the allocator (second) template argument. +// + +#include +#include +#include + +namespace glslang { + +// If we are using guard blocks, we must track each individual +// allocation. If we aren't using guard blocks, these +// never get instantiated, so won't have any impact. +// + +class TAllocation { +public: + TAllocation(size_t size, unsigned char* mem, TAllocation* prev = 0) : + size(size), mem(mem), prevAlloc(prev) { + // Allocations are bracketed: + // [allocationHeader][initialGuardBlock][userData][finalGuardBlock] + // This would be cleaner with if (guardBlockSize)..., but that + // makes the compiler print warnings about 0 length memsets, + // even with the if() protecting them. +# ifdef GUARD_BLOCKS + memset(preGuard(), guardBlockBeginVal, guardBlockSize); + memset(data(), userDataFill, size); + memset(postGuard(), guardBlockEndVal, guardBlockSize); +# endif + } + + void check() const { + checkGuardBlock(preGuard(), guardBlockBeginVal, "before"); + checkGuardBlock(postGuard(), guardBlockEndVal, "after"); + } + + void checkAllocList() const; + + // Return total size needed to accommodate user buffer of 'size', + // plus our tracking data. + inline static size_t allocationSize(size_t size) { + return size + 2 * guardBlockSize + headerSize(); + } + + // Offset from surrounding buffer to get to user data buffer. + inline static unsigned char* offsetAllocation(unsigned char* m) { + return m + guardBlockSize + headerSize(); + } + +private: + void checkGuardBlock(unsigned char* blockMem, unsigned char val, const char* locText) const; + + // Find offsets to pre and post guard blocks, and user data buffer + unsigned char* preGuard() const { return mem + headerSize(); } + unsigned char* data() const { return preGuard() + guardBlockSize; } + unsigned char* postGuard() const { return data() + size; } + + size_t size; // size of the user data area + unsigned char* mem; // beginning of our allocation (pts to header) + TAllocation* prevAlloc; // prior allocation in the chain + + const static unsigned char guardBlockBeginVal; + const static unsigned char guardBlockEndVal; + const static unsigned char userDataFill; + + const static size_t guardBlockSize; +# ifdef GUARD_BLOCKS + inline static size_t headerSize() { return sizeof(TAllocation); } +# else + inline static size_t headerSize() { return 0; } +# endif +}; + +// +// There are several stacks. One is to track the pushing and popping +// of the user, and not yet implemented. The others are simply a +// repositories of free pages or used pages. +// +// Page stacks are linked together with a simple header at the beginning +// of each allocation obtained from the underlying OS. Multi-page allocations +// are returned to the OS. Individual page allocations are kept for future +// re-use. +// +// The "page size" used is not, nor must it match, the underlying OS +// page size. But, having it be about that size or equal to a set of +// pages is likely most optimal. +// +class TPoolAllocator { +public: + TPoolAllocator(int growthIncrement = 8*1024, int allocationAlignment = 16); + + // + // Don't call the destructor just to free up the memory, call pop() + // + ~TPoolAllocator(); + + // + // Call push() to establish a new place to pop memory too. Does not + // have to be called to get things started. + // + void push(); + + // + // Call pop() to free all memory allocated since the last call to push(), + // or if no last call to push, frees all memory since first allocation. + // + void pop(); + + // + // Call popAll() to free all memory allocated. + // + void popAll(); + + // + // Call allocate() to actually acquire memory. Returns 0 if no memory + // available, otherwise a properly aligned pointer to 'numBytes' of memory. + // + void* allocate(size_t numBytes); + + // + // There is no deallocate. The point of this class is that + // deallocation can be skipped by the user of it, as the model + // of use is to simultaneously deallocate everything at once + // by calling pop(), and to not have to solve memory leak problems. + // + +protected: + friend struct tHeader; + + struct tHeader { + tHeader(tHeader* nextPage, size_t pageCount) : +#ifdef GUARD_BLOCKS + lastAllocation(0), +#endif + nextPage(nextPage), pageCount(pageCount) { } + + ~tHeader() { +#ifdef GUARD_BLOCKS + if (lastAllocation) + lastAllocation->checkAllocList(); +#endif + } + +#ifdef GUARD_BLOCKS + TAllocation* lastAllocation; +#endif + tHeader* nextPage; + size_t pageCount; + }; + + struct tAllocState { + size_t offset; + tHeader* page; + }; + typedef std::vector tAllocStack; + + // Track allocations if and only if we're using guard blocks +#ifndef GUARD_BLOCKS + void* initializeAllocation(tHeader*, unsigned char* memory, size_t) { +#else + void* initializeAllocation(tHeader* block, unsigned char* memory, size_t numBytes) { + new(memory) TAllocation(numBytes, memory, block->lastAllocation); + block->lastAllocation = reinterpret_cast(memory); +#endif + + // This is optimized entirely away if GUARD_BLOCKS is not defined. + return TAllocation::offsetAllocation(memory); + } + + size_t pageSize; // granularity of allocation from the OS + size_t alignment; // all returned allocations will be aligned at + // this granularity, which will be a power of 2 + size_t alignmentMask; + size_t headerSkip; // amount of memory to skip to make room for the + // header (basically, size of header, rounded + // up to make it aligned + size_t currentPageOffset; // next offset in top of inUseList to allocate from + tHeader* freeList; // list of popped memory + tHeader* inUseList; // list of all memory currently being used + tAllocStack stack; // stack of where to allocate from, to partition pool + + int numCalls; // just an interesting statistic + size_t totalBytes; // just an interesting statistic +private: + TPoolAllocator& operator=(const TPoolAllocator&); // don't allow assignment operator + TPoolAllocator(const TPoolAllocator&); // don't allow default copy constructor +}; + +// +// There could potentially be many pools with pops happening at +// different times. But a simple use is to have a global pop +// with everyone using the same global allocator. +// +extern TPoolAllocator& GetThreadPoolAllocator(); +void SetThreadPoolAllocator(TPoolAllocator* poolAllocator); + +// +// This STL compatible allocator is intended to be used as the allocator +// parameter to templatized STL containers, like vector and map. +// +// It will use the pools for allocation, and not +// do any deallocation, but will still do destruction. +// +template +class pool_allocator { +public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T *pointer; + typedef const T *const_pointer; + typedef T& reference; + typedef const T& const_reference; + typedef T value_type; + template + struct rebind { + typedef pool_allocator other; + }; + pointer address(reference x) const { return &x; } + const_pointer address(const_reference x) const { return &x; } + + pool_allocator() : allocator(GetThreadPoolAllocator()) { } + pool_allocator(TPoolAllocator& a) : allocator(a) { } + pool_allocator(const pool_allocator& p) : allocator(p.allocator) { } + + pool_allocator& operator=(const pool_allocator&) { return *this; } + + template + pool_allocator(const pool_allocator& p) : allocator(p.getAllocator()) { } + + pointer allocate(size_type n) { + return reinterpret_cast(getAllocator().allocate(n * sizeof(T))); } + pointer allocate(size_type n, const void*) { + return reinterpret_cast(getAllocator().allocate(n * sizeof(T))); } + + void deallocate(void*, size_type) { } + void deallocate(pointer, size_type) { } + + pointer _Charalloc(size_t n) { + return reinterpret_cast(getAllocator().allocate(n)); } + + void construct(pointer p, const T& val) { new ((void *)p) T(val); } + void destroy(pointer p) { p->T::~T(); } + + bool operator==(const pool_allocator& rhs) const { return &getAllocator() == &rhs.getAllocator(); } + bool operator!=(const pool_allocator& rhs) const { return &getAllocator() != &rhs.getAllocator(); } + + size_type max_size() const { return static_cast(-1) / sizeof(T); } + size_type max_size(int size) const { return static_cast(-1) / size; } + + void setAllocator(TPoolAllocator* a) { allocator = *a; } + TPoolAllocator& getAllocator() const { return allocator; } + +protected: + TPoolAllocator& allocator; +}; + +} // end namespace glslang + +#endif // _POOLALLOC_INCLUDED_ diff --git a/love/src/jni/love/src/libraries/glslang/glslang/Include/ResourceLimits.h b/love/src/jni/love/src/libraries/glslang/glslang/Include/ResourceLimits.h new file mode 100644 index 00000000..0d07b8c8 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/Include/ResourceLimits.h @@ -0,0 +1,140 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2013 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef _RESOURCE_LIMITS_INCLUDED_ +#define _RESOURCE_LIMITS_INCLUDED_ + +struct TLimits { + bool nonInductiveForLoops; + bool whileLoops; + bool doWhileLoops; + bool generalUniformIndexing; + bool generalAttributeMatrixVectorIndexing; + bool generalVaryingIndexing; + bool generalSamplerIndexing; + bool generalVariableIndexing; + bool generalConstantMatrixVectorIndexing; +}; + +struct TBuiltInResource { + int maxLights; + int maxClipPlanes; + int maxTextureUnits; + int maxTextureCoords; + int maxVertexAttribs; + int maxVertexUniformComponents; + int maxVaryingFloats; + int maxVertexTextureImageUnits; + int maxCombinedTextureImageUnits; + int maxTextureImageUnits; + int maxFragmentUniformComponents; + int maxDrawBuffers; + int maxVertexUniformVectors; + int maxVaryingVectors; + int maxFragmentUniformVectors; + int maxVertexOutputVectors; + int maxFragmentInputVectors; + int minProgramTexelOffset; + int maxProgramTexelOffset; + int maxClipDistances; + int maxComputeWorkGroupCountX; + int maxComputeWorkGroupCountY; + int maxComputeWorkGroupCountZ; + int maxComputeWorkGroupSizeX; + int maxComputeWorkGroupSizeY; + int maxComputeWorkGroupSizeZ; + int maxComputeUniformComponents; + int maxComputeTextureImageUnits; + int maxComputeImageUniforms; + int maxComputeAtomicCounters; + int maxComputeAtomicCounterBuffers; + int maxVaryingComponents; + int maxVertexOutputComponents; + int maxGeometryInputComponents; + int maxGeometryOutputComponents; + int maxFragmentInputComponents; + int maxImageUnits; + int maxCombinedImageUnitsAndFragmentOutputs; + int maxCombinedShaderOutputResources; + int maxImageSamples; + int maxVertexImageUniforms; + int maxTessControlImageUniforms; + int maxTessEvaluationImageUniforms; + int maxGeometryImageUniforms; + int maxFragmentImageUniforms; + int maxCombinedImageUniforms; + int maxGeometryTextureImageUnits; + int maxGeometryOutputVertices; + int maxGeometryTotalOutputComponents; + int maxGeometryUniformComponents; + int maxGeometryVaryingComponents; + int maxTessControlInputComponents; + int maxTessControlOutputComponents; + int maxTessControlTextureImageUnits; + int maxTessControlUniformComponents; + int maxTessControlTotalOutputComponents; + int maxTessEvaluationInputComponents; + int maxTessEvaluationOutputComponents; + int maxTessEvaluationTextureImageUnits; + int maxTessEvaluationUniformComponents; + int maxTessPatchComponents; + int maxPatchVertices; + int maxTessGenLevel; + int maxViewports; + int maxVertexAtomicCounters; + int maxTessControlAtomicCounters; + int maxTessEvaluationAtomicCounters; + int maxGeometryAtomicCounters; + int maxFragmentAtomicCounters; + int maxCombinedAtomicCounters; + int maxAtomicCounterBindings; + int maxVertexAtomicCounterBuffers; + int maxTessControlAtomicCounterBuffers; + int maxTessEvaluationAtomicCounterBuffers; + int maxGeometryAtomicCounterBuffers; + int maxFragmentAtomicCounterBuffers; + int maxCombinedAtomicCounterBuffers; + int maxAtomicCounterBufferSize; + int maxTransformFeedbackBuffers; + int maxTransformFeedbackInterleavedComponents; + int maxCullDistances; + int maxCombinedClipAndCullDistances; + int maxSamples; + + TLimits limits; +}; + +#endif // _RESOURCE_LIMITS_INCLUDED_ diff --git a/love/src/jni/love/src/libraries/glslang/glslang/Include/ShHandle.h b/love/src/jni/love/src/libraries/glslang/glslang/Include/ShHandle.h new file mode 100644 index 00000000..df07bd8e --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/Include/ShHandle.h @@ -0,0 +1,176 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef _SHHANDLE_INCLUDED_ +#define _SHHANDLE_INCLUDED_ + +// +// Machine independent part of the compiler private objects +// sent as ShHandle to the driver. +// +// This should not be included by driver code. +// + +#define SH_EXPORTING +#include "../Public/ShaderLang.h" +#include "../MachineIndependent/Versions.h" +#include "InfoSink.h" + +class TCompiler; +class TLinker; +class TUniformMap; + +// +// The base class used to back handles returned to the driver. +// +class TShHandleBase { +public: + TShHandleBase() { pool = new glslang::TPoolAllocator; } + virtual ~TShHandleBase() { delete pool; } + virtual TCompiler* getAsCompiler() { return 0; } + virtual TLinker* getAsLinker() { return 0; } + virtual TUniformMap* getAsUniformMap() { return 0; } + virtual glslang::TPoolAllocator* getPool() const { return pool; } +private: + glslang::TPoolAllocator* pool; +}; + +// +// The base class for the machine dependent linker to derive from +// for managing where uniforms live. +// +class TUniformMap : public TShHandleBase { +public: + TUniformMap() { } + virtual ~TUniformMap() { } + virtual TUniformMap* getAsUniformMap() { return this; } + virtual int getLocation(const char* name) = 0; + virtual TInfoSink& getInfoSink() { return infoSink; } + TInfoSink infoSink; +}; + +class TIntermNode; + +// +// The base class for the machine dependent compiler to derive from +// for managing object code from the compile. +// +class TCompiler : public TShHandleBase { +public: + TCompiler(EShLanguage l, TInfoSink& sink) : infoSink(sink) , language(l), haveValidObjectCode(false) { } + virtual ~TCompiler() { } + EShLanguage getLanguage() { return language; } + virtual TInfoSink& getInfoSink() { return infoSink; } + + virtual bool compile(TIntermNode* root, int version = 0, EProfile profile = ENoProfile) = 0; + + virtual TCompiler* getAsCompiler() { return this; } + virtual bool linkable() { return haveValidObjectCode; } + + TInfoSink& infoSink; +protected: + TCompiler& operator=(TCompiler&); + + EShLanguage language; + bool haveValidObjectCode; +}; + +// +// Link operations are based on a list of compile results... +// +typedef glslang::TVector TCompilerList; +typedef glslang::TVector THandleList; + +// +// The base class for the machine dependent linker to derive from +// to manage the resulting executable. +// + +class TLinker : public TShHandleBase { +public: + TLinker(EShExecutable e, TInfoSink& iSink) : + infoSink(iSink), + executable(e), + haveReturnableObjectCode(false), + appAttributeBindings(0), + fixedAttributeBindings(0), + excludedAttributes(0), + excludedCount(0), + uniformBindings(0) { } + virtual TLinker* getAsLinker() { return this; } + virtual ~TLinker() { } + virtual bool link(TCompilerList&, TUniformMap*) = 0; + virtual bool link(THandleList&) { return false; } + virtual void setAppAttributeBindings(const ShBindingTable* t) { appAttributeBindings = t; } + virtual void setFixedAttributeBindings(const ShBindingTable* t) { fixedAttributeBindings = t; } + virtual void getAttributeBindings(ShBindingTable const **t) const = 0; + virtual void setExcludedAttributes(const int* attributes, int count) { excludedAttributes = attributes; excludedCount = count; } + virtual ShBindingTable* getUniformBindings() const { return uniformBindings; } + virtual const void* getObjectCode() const { return 0; } // a real compiler would be returning object code here + virtual TInfoSink& getInfoSink() { return infoSink; } + TInfoSink& infoSink; +protected: + TLinker& operator=(TLinker&); + EShExecutable executable; + bool haveReturnableObjectCode; // true when objectCode is acceptable to send to driver + + const ShBindingTable* appAttributeBindings; + const ShBindingTable* fixedAttributeBindings; + const int* excludedAttributes; + int excludedCount; + ShBindingTable* uniformBindings; // created by the linker +}; + +// +// This is the interface between the machine independent code +// and the machine dependent code. +// +// The machine dependent code should derive from the classes +// above. Then Construct*() and Delete*() will create and +// destroy the machine dependent objects, which contain the +// above machine independent information. +// +TCompiler* ConstructCompiler(EShLanguage, int); + +TShHandleBase* ConstructLinker(EShExecutable, int); +TShHandleBase* ConstructBindings(); +void DeleteLinker(TShHandleBase*); +void DeleteBindingList(TShHandleBase* bindingList); + +TUniformMap* ConstructUniformMap(); +void DeleteCompiler(TCompiler*); + +void DeleteUniformMap(TUniformMap*); + +#endif // _SHHANDLE_INCLUDED_ diff --git a/love/src/jni/love/src/libraries/glslang/glslang/Include/Types.h b/love/src/jni/love/src/libraries/glslang/glslang/Include/Types.h new file mode 100644 index 00000000..cc847b5e --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/Include/Types.h @@ -0,0 +1,1924 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2012-2016 LunarG, Inc. +// Copyright (C) 2015-2016 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef _TYPES_INCLUDED +#define _TYPES_INCLUDED + +#include "../Include/Common.h" +#include "../Include/BaseTypes.h" +#include "../Public/ShaderLang.h" +#include "arrays.h" + +#include + +namespace glslang { + +const int GlslangMaxTypeLength = 200; // TODO: need to print block/struct one member per line, so this can stay bounded + +const char* const AnonymousPrefix = "anon@"; // for something like a block whose members can be directly accessed +inline bool IsAnonymous(const TString& name) +{ + return name.compare(0, 5, AnonymousPrefix) == 0; +} + +// +// Details within a sampler type +// +enum TSamplerDim { + EsdNone, + Esd1D, + Esd2D, + Esd3D, + EsdCube, + EsdRect, + EsdBuffer, + EsdSubpass, // goes only with non-sampled image (image is true) + EsdNumDims +}; + +struct TSampler { // misnomer now; includes images, textures without sampler, and textures with sampler + TBasicType type : 8; // type returned by sampler + TSamplerDim dim : 8; + bool arrayed : 1; + bool shadow : 1; + bool ms : 1; + bool image : 1; // image, combined should be false + bool combined : 1; // true means texture is combined with a sampler, false means texture with no sampler + bool sampler : 1; // true means a pure sampler, other fields should be clear() + bool external : 1; // GL_OES_EGL_image_external + unsigned int vectorSize : 3; // vector return type size. + + // Some languages support structures as sample results. Storing the whole structure in the + // TSampler is too large, so there is an index to a separate table. + static const unsigned structReturnIndexBits = 4; // number of index bits to use. + static const unsigned structReturnSlots = (1< TTypeList; + +typedef TVector TIdentifierList; + +// +// Following are a series of helper enums for managing layouts and qualifiers, +// used for TPublicType, TType, others. +// + +enum TLayoutPacking { + ElpNone, + ElpShared, // default, but different than saying nothing + ElpStd140, + ElpStd430, + ElpPacked, + ElpCount // If expanding, see bitfield width below +}; + +enum TLayoutMatrix { + ElmNone, + ElmRowMajor, + ElmColumnMajor, // default, but different than saying nothing + ElmCount // If expanding, see bitfield width below +}; + +// Union of geometry shader and tessellation shader geometry types. +// They don't go into TType, but rather have current state per shader or +// active parser type (TPublicType). +enum TLayoutGeometry { + ElgNone, + ElgPoints, + ElgLines, + ElgLinesAdjacency, + ElgLineStrip, + ElgTriangles, + ElgTrianglesAdjacency, + ElgTriangleStrip, + ElgQuads, + ElgIsolines, +}; + +enum TVertexSpacing { + EvsNone, + EvsEqual, + EvsFractionalEven, + EvsFractionalOdd +}; + +enum TVertexOrder { + EvoNone, + EvoCw, + EvoCcw +}; + +// Note: order matters, as type of format is done by comparison. +enum TLayoutFormat { + ElfNone, + + // Float image + ElfRgba32f, + ElfRgba16f, + ElfR32f, + ElfRgba8, + ElfRgba8Snorm, + + ElfEsFloatGuard, // to help with comparisons + + ElfRg32f, + ElfRg16f, + ElfR11fG11fB10f, + ElfR16f, + ElfRgba16, + ElfRgb10A2, + ElfRg16, + ElfRg8, + ElfR16, + ElfR8, + ElfRgba16Snorm, + ElfRg16Snorm, + ElfRg8Snorm, + ElfR16Snorm, + ElfR8Snorm, + + ElfFloatGuard, // to help with comparisons + + // Int image + ElfRgba32i, + ElfRgba16i, + ElfRgba8i, + ElfR32i, + + ElfEsIntGuard, // to help with comparisons + + ElfRg32i, + ElfRg16i, + ElfRg8i, + ElfR16i, + ElfR8i, + + ElfIntGuard, // to help with comparisons + + // Uint image + ElfRgba32ui, + ElfRgba16ui, + ElfRgba8ui, + ElfR32ui, + + ElfEsUintGuard, // to help with comparisons + + ElfRg32ui, + ElfRg16ui, + ElfRgb10a2ui, + ElfRg8ui, + ElfR16ui, + ElfR8ui, + + ElfCount +}; + +enum TLayoutDepth { + EldNone, + EldAny, + EldGreater, + EldLess, + EldUnchanged, + + EldCount +}; + +enum TBlendEquationShift { + // No 'EBlendNone': + // These are used as bit-shift amounts. A mask of such shifts will have type 'int', + // and in that space, 0 means no bits set, or none. In this enum, 0 means (1 << 0), a bit is set. + EBlendMultiply, + EBlendScreen, + EBlendOverlay, + EBlendDarken, + EBlendLighten, + EBlendColordodge, + EBlendColorburn, + EBlendHardlight, + EBlendSoftlight, + EBlendDifference, + EBlendExclusion, + EBlendHslHue, + EBlendHslSaturation, + EBlendHslColor, + EBlendHslLuminosity, + EBlendAllEquations, + + EBlendCount +}; + +class TQualifier { +public: + static const int layoutNotSet = -1; + + void clear() + { + precision = EpqNone; + invariant = false; + noContraction = false; + makeTemporary(); + declaredBuiltIn = EbvNone; + } + + // drop qualifiers that don't belong in a temporary variable + void makeTemporary() + { + semanticName = nullptr; + storage = EvqTemporary; + builtIn = EbvNone; + clearInterstage(); + clearMemory(); + specConstant = false; + clearLayout(); + } + + void clearInterstage() + { + clearInterpolation(); + patch = false; + sample = false; + } + + void clearInterpolation() + { + centroid = false; + smooth = false; + flat = false; + nopersp = false; +#ifdef AMD_EXTENSIONS + explicitInterp = false; +#endif + } + + void clearMemory() + { + coherent = false; + volatil = false; + restrict = false; + readonly = false; + writeonly = false; + } + + // Drop just the storage qualification, which perhaps should + // never be done, as it is fundamentally inconsistent, but need to + // explore what downstream consumers need. + // E.g., in a deference, it is an inconsistency between: + // A) partially dereferenced resource is still in the storage class it started in + // B) partially dereferenced resource is a new temporary object + // If A, then nothing should change, if B, then everything should change, but this is half way. + void makePartialTemporary() + { + storage = EvqTemporary; + specConstant = false; + } + + const char* semanticName; + TStorageQualifier storage : 6; + TBuiltInVariable builtIn : 8; + TBuiltInVariable declaredBuiltIn : 8; + TPrecisionQualifier precision : 3; + bool invariant : 1; // require canonical treatment for cross-shader invariance + bool noContraction: 1; // prevent contraction and reassociation, e.g., for 'precise' keyword, and expressions it affects + bool centroid : 1; + bool smooth : 1; + bool flat : 1; + bool nopersp : 1; +#ifdef AMD_EXTENSIONS + bool explicitInterp : 1; +#endif + bool patch : 1; + bool sample : 1; + bool coherent : 1; + bool volatil : 1; + bool restrict : 1; + bool readonly : 1; + bool writeonly : 1; + bool specConstant : 1; // having a constant_id is not sufficient: expressions have no id, but are still specConstant + + bool isMemory() const + { + return coherent || volatil || restrict || readonly || writeonly; + } + bool isInterpolation() const + { +#ifdef AMD_EXTENSIONS + return flat || smooth || nopersp || explicitInterp; +#else + return flat || smooth || nopersp; +#endif + } + bool isAuxiliary() const + { + return centroid || patch || sample; + } + + bool isPipeInput() const + { + switch (storage) { + case EvqVaryingIn: + case EvqFragCoord: + case EvqPointCoord: + case EvqFace: + case EvqVertexId: + case EvqInstanceId: + return true; + default: + return false; + } + } + + bool isPipeOutput() const + { + switch (storage) { + case EvqPosition: + case EvqPointSize: + case EvqClipVertex: + case EvqVaryingOut: + case EvqFragColor: + case EvqFragDepth: + return true; + default: + return false; + } + } + + bool isParamInput() const + { + switch (storage) { + case EvqIn: + case EvqInOut: + case EvqConstReadOnly: + return true; + default: + return false; + } + } + + bool isParamOutput() const + { + switch (storage) { + case EvqOut: + case EvqInOut: + return true; + default: + return false; + } + } + + bool isUniformOrBuffer() const + { + switch (storage) { + case EvqUniform: + case EvqBuffer: + return true; + default: + return false; + } + } + + bool isIo() const + { + switch (storage) { + case EvqUniform: + case EvqBuffer: + case EvqVaryingIn: + case EvqFragCoord: + case EvqPointCoord: + case EvqFace: + case EvqVertexId: + case EvqInstanceId: + case EvqPosition: + case EvqPointSize: + case EvqClipVertex: + case EvqVaryingOut: + case EvqFragColor: + case EvqFragDepth: + return true; + default: + return false; + } + } + + // True if this type of IO is supposed to be arrayed with extra level for per-vertex data + bool isArrayedIo(EShLanguage language) const + { + switch (language) { + case EShLangGeometry: + return isPipeInput(); + case EShLangTessControl: + return ! patch && (isPipeInput() || isPipeOutput()); + case EShLangTessEvaluation: + return ! patch && isPipeInput(); + default: + return false; + } + } + + // Implementing an embedded layout-qualifier class here, since C++ can't have a real class bitfield + void clearLayout() // all layout + { + clearUniformLayout(); + + layoutPushConstant = false; +#ifdef NV_EXTENSIONS + layoutPassthrough = false; + layoutViewportRelative = false; + // -2048 as the default value indicating layoutSecondaryViewportRelative is not set + layoutSecondaryViewportRelativeOffset = -2048; +#endif + + clearInterstageLayout(); + + layoutSpecConstantId = layoutSpecConstantIdEnd; + + layoutFormat = ElfNone; + } + void clearInterstageLayout() + { + layoutLocation = layoutLocationEnd; + layoutComponent = layoutComponentEnd; + layoutIndex = layoutIndexEnd; + clearStreamLayout(); + clearXfbLayout(); + } + void clearStreamLayout() + { + layoutStream = layoutStreamEnd; + } + void clearXfbLayout() + { + layoutXfbBuffer = layoutXfbBufferEnd; + layoutXfbStride = layoutXfbStrideEnd; + layoutXfbOffset = layoutXfbOffsetEnd; + } + + bool hasNonXfbLayout() const + { + return hasUniformLayout() || + hasAnyLocation() || + hasStream() || + hasFormat() || + layoutPushConstant; + } + bool hasLayout() const + { + return hasNonXfbLayout() || + hasXfb(); + } + TLayoutMatrix layoutMatrix : 3; + TLayoutPacking layoutPacking : 4; + int layoutOffset; + int layoutAlign; + + unsigned int layoutLocation :12; + static const unsigned int layoutLocationEnd = 0xFFF; + + unsigned int layoutComponent : 3; + static const unsigned int layoutComponentEnd = 4; + + unsigned int layoutSet : 7; + static const unsigned int layoutSetEnd = 0x3F; + + unsigned int layoutBinding : 16; + static const unsigned int layoutBindingEnd = 0xFFFF; + + unsigned int layoutIndex : 8; + static const unsigned int layoutIndexEnd = 0xFF; + + unsigned int layoutStream : 8; + static const unsigned int layoutStreamEnd = 0xFF; + + unsigned int layoutXfbBuffer : 4; + static const unsigned int layoutXfbBufferEnd = 0xF; + + unsigned int layoutXfbStride : 10; + static const unsigned int layoutXfbStrideEnd = 0x3FF; + + unsigned int layoutXfbOffset : 10; + static const unsigned int layoutXfbOffsetEnd = 0x3FF; + + unsigned int layoutAttachment : 8; // for input_attachment_index + static const unsigned int layoutAttachmentEnd = 0XFF; + + unsigned int layoutSpecConstantId : 11; + static const unsigned int layoutSpecConstantIdEnd = 0x7FF; + + TLayoutFormat layoutFormat : 8; + + bool layoutPushConstant; + +#ifdef NV_EXTENSIONS + bool layoutPassthrough; + bool layoutViewportRelative; + int layoutSecondaryViewportRelativeOffset; +#endif + + bool hasUniformLayout() const + { + return hasMatrix() || + hasPacking() || + hasOffset() || + hasBinding() || + hasSet() || + hasAlign(); + } + void clearUniformLayout() // only uniform specific + { + layoutMatrix = ElmNone; + layoutPacking = ElpNone; + layoutOffset = layoutNotSet; + layoutAlign = layoutNotSet; + + layoutSet = layoutSetEnd; + layoutBinding = layoutBindingEnd; + layoutAttachment = layoutAttachmentEnd; + } + + bool hasMatrix() const + { + return layoutMatrix != ElmNone; + } + bool hasPacking() const + { + return layoutPacking != ElpNone; + } + bool hasOffset() const + { + return layoutOffset != layoutNotSet; + } + bool hasAlign() const + { + return layoutAlign != layoutNotSet; + } + bool hasAnyLocation() const + { + return hasLocation() || + hasComponent() || + hasIndex(); + } + bool hasLocation() const + { + return layoutLocation != layoutLocationEnd; + } + bool hasComponent() const + { + return layoutComponent != layoutComponentEnd; + } + bool hasIndex() const + { + return layoutIndex != layoutIndexEnd; + } + bool hasSet() const + { + return layoutSet != layoutSetEnd; + } + bool hasBinding() const + { + return layoutBinding != layoutBindingEnd; + } + bool hasStream() const + { + return layoutStream != layoutStreamEnd; + } + bool hasFormat() const + { + return layoutFormat != ElfNone; + } + bool hasXfb() const + { + return hasXfbBuffer() || + hasXfbStride() || + hasXfbOffset(); + } + bool hasXfbBuffer() const + { + return layoutXfbBuffer != layoutXfbBufferEnd; + } + bool hasXfbStride() const + { + return layoutXfbStride != layoutXfbStrideEnd; + } + bool hasXfbOffset() const + { + return layoutXfbOffset != layoutXfbOffsetEnd; + } + bool hasAttachment() const + { + return layoutAttachment != layoutAttachmentEnd; + } + bool hasSpecConstantId() const + { + // Not the same thing as being a specialization constant, this + // is just whether or not it was declared with an ID. + return layoutSpecConstantId != layoutSpecConstantIdEnd; + } + bool isSpecConstant() const + { + // True if type is a specialization constant, whether or not it + // had a specialization-constant ID, and false if it is not a + // true front-end constant. + return specConstant; + } + bool isFrontEndConstant() const + { + // True if the front-end knows the final constant value. + // This allows front-end constant folding. + return storage == EvqConst && ! specConstant; + } + bool isConstant() const + { + // True if is either kind of constant; specialization or regular. + return isFrontEndConstant() || isSpecConstant(); + } + void makeSpecConstant() + { + storage = EvqConst; + specConstant = true; + } + static const char* getLayoutPackingString(TLayoutPacking packing) + { + switch (packing) { + case ElpPacked: return "packed"; + case ElpShared: return "shared"; + case ElpStd140: return "std140"; + case ElpStd430: return "std430"; + default: return "none"; + } + } + static const char* getLayoutMatrixString(TLayoutMatrix m) + { + switch (m) { + case ElmColumnMajor: return "column_major"; + case ElmRowMajor: return "row_major"; + default: return "none"; + } + } + static const char* getLayoutFormatString(TLayoutFormat f) + { + switch (f) { + case ElfRgba32f: return "rgba32f"; + case ElfRgba16f: return "rgba16f"; + case ElfRg32f: return "rg32f"; + case ElfRg16f: return "rg16f"; + case ElfR11fG11fB10f: return "r11f_g11f_b10f"; + case ElfR32f: return "r32f"; + case ElfR16f: return "r16f"; + case ElfRgba16: return "rgba16"; + case ElfRgb10A2: return "rgb10_a2"; + case ElfRgba8: return "rgba8"; + case ElfRg16: return "rg16"; + case ElfRg8: return "rg8"; + case ElfR16: return "r16"; + case ElfR8: return "r8"; + case ElfRgba16Snorm: return "rgba16_snorm"; + case ElfRgba8Snorm: return "rgba8_snorm"; + case ElfRg16Snorm: return "rg16_snorm"; + case ElfRg8Snorm: return "rg8_snorm"; + case ElfR16Snorm: return "r16_snorm"; + case ElfR8Snorm: return "r8_snorm"; + + case ElfRgba32i: return "rgba32i"; + case ElfRgba16i: return "rgba16i"; + case ElfRgba8i: return "rgba8i"; + case ElfRg32i: return "rg32i"; + case ElfRg16i: return "rg16i"; + case ElfRg8i: return "rg8i"; + case ElfR32i: return "r32i"; + case ElfR16i: return "r16i"; + case ElfR8i: return "r8i"; + + case ElfRgba32ui: return "rgba32ui"; + case ElfRgba16ui: return "rgba16ui"; + case ElfRgba8ui: return "rgba8ui"; + case ElfRg32ui: return "rg32ui"; + case ElfRg16ui: return "rg16ui"; + case ElfRgb10a2ui: return "rgb10_a2ui"; + case ElfRg8ui: return "rg8ui"; + case ElfR32ui: return "r32ui"; + case ElfR16ui: return "r16ui"; + case ElfR8ui: return "r8ui"; + default: return "none"; + } + } + static const char* getLayoutDepthString(TLayoutDepth d) + { + switch (d) { + case EldAny: return "depth_any"; + case EldGreater: return "depth_greater"; + case EldLess: return "depth_less"; + case EldUnchanged: return "depth_unchanged"; + default: return "none"; + } + } + static const char* getBlendEquationString(TBlendEquationShift e) + { + switch (e) { + case EBlendMultiply: return "blend_support_multiply"; + case EBlendScreen: return "blend_support_screen"; + case EBlendOverlay: return "blend_support_overlay"; + case EBlendDarken: return "blend_support_darken"; + case EBlendLighten: return "blend_support_lighten"; + case EBlendColordodge: return "blend_support_colordodge"; + case EBlendColorburn: return "blend_support_colorburn"; + case EBlendHardlight: return "blend_support_hardlight"; + case EBlendSoftlight: return "blend_support_softlight"; + case EBlendDifference: return "blend_support_difference"; + case EBlendExclusion: return "blend_support_exclusion"; + case EBlendHslHue: return "blend_support_hsl_hue"; + case EBlendHslSaturation: return "blend_support_hsl_saturation"; + case EBlendHslColor: return "blend_support_hsl_color"; + case EBlendHslLuminosity: return "blend_support_hsl_luminosity"; + case EBlendAllEquations: return "blend_support_all_equations"; + default: return "unknown"; + } + } + static const char* getGeometryString(TLayoutGeometry geometry) + { + switch (geometry) { + case ElgPoints: return "points"; + case ElgLines: return "lines"; + case ElgLinesAdjacency: return "lines_adjacency"; + case ElgLineStrip: return "line_strip"; + case ElgTriangles: return "triangles"; + case ElgTrianglesAdjacency: return "triangles_adjacency"; + case ElgTriangleStrip: return "triangle_strip"; + case ElgQuads: return "quads"; + case ElgIsolines: return "isolines"; + default: return "none"; + } + } + static const char* getVertexSpacingString(TVertexSpacing spacing) + { + switch (spacing) { + case EvsEqual: return "equal_spacing"; + case EvsFractionalEven: return "fractional_even_spacing"; + case EvsFractionalOdd: return "fractional_odd_spacing"; + default: return "none"; + } + } + static const char* getVertexOrderString(TVertexOrder order) + { + switch (order) { + case EvoCw: return "cw"; + case EvoCcw: return "ccw"; + default: return "none"; + } + } + static int mapGeometryToSize(TLayoutGeometry geometry) + { + switch (geometry) { + case ElgPoints: return 1; + case ElgLines: return 2; + case ElgLinesAdjacency: return 4; + case ElgTriangles: return 3; + case ElgTrianglesAdjacency: return 6; + default: return 0; + } + } +}; + +// Qualifiers that don't need to be keep per object. They have shader scope, not object scope. +// So, they will not be part of TType, TQualifier, etc. +struct TShaderQualifiers { + TLayoutGeometry geometry; // geometry/tessellation shader in/out primitives + bool pixelCenterInteger; // fragment shader + bool originUpperLeft; // fragment shader + int invocations; + int vertices; // both for tessellation "vertices" and geometry "max_vertices" + TVertexSpacing spacing; + TVertexOrder order; + bool pointMode; + int localSize[3]; // compute shader + int localSizeSpecId[3]; // compute shader specialization id for gl_WorkGroupSize + bool earlyFragmentTests; // fragment input + bool postDepthCoverage; // fragment input + TLayoutDepth layoutDepth; + bool blendEquation; // true if any blend equation was specified + int numViews; // multiview extenstions + +#ifdef NV_EXTENSIONS + bool layoutOverrideCoverage; // true if layout override_coverage set +#endif + + void init() + { + geometry = ElgNone; + originUpperLeft = false; + pixelCenterInteger = false; + invocations = TQualifier::layoutNotSet; + vertices = TQualifier::layoutNotSet; + spacing = EvsNone; + order = EvoNone; + pointMode = false; + localSize[0] = 1; + localSize[1] = 1; + localSize[2] = 1; + localSizeSpecId[0] = TQualifier::layoutNotSet; + localSizeSpecId[1] = TQualifier::layoutNotSet; + localSizeSpecId[2] = TQualifier::layoutNotSet; + earlyFragmentTests = false; + postDepthCoverage = false; + layoutDepth = EldNone; + blendEquation = false; + numViews = TQualifier::layoutNotSet; +#ifdef NV_EXTENSIONS + layoutOverrideCoverage = false; +#endif + } + + // Merge in characteristics from the 'src' qualifier. They can override when + // set, but never erase when not set. + void merge(const TShaderQualifiers& src) + { + if (src.geometry != ElgNone) + geometry = src.geometry; + if (src.pixelCenterInteger) + pixelCenterInteger = src.pixelCenterInteger; + if (src.originUpperLeft) + originUpperLeft = src.originUpperLeft; + if (src.invocations != TQualifier::layoutNotSet) + invocations = src.invocations; + if (src.vertices != TQualifier::layoutNotSet) + vertices = src.vertices; + if (src.spacing != EvsNone) + spacing = src.spacing; + if (src.order != EvoNone) + order = src.order; + if (src.pointMode) + pointMode = true; + for (int i = 0; i < 3; ++i) { + if (src.localSize[i] > 1) + localSize[i] = src.localSize[i]; + } + for (int i = 0; i < 3; ++i) { + if (src.localSizeSpecId[i] != TQualifier::layoutNotSet) + localSizeSpecId[i] = src.localSizeSpecId[i]; + } + if (src.earlyFragmentTests) + earlyFragmentTests = true; + if (src.postDepthCoverage) + postDepthCoverage = true; + if (src.layoutDepth) + layoutDepth = src.layoutDepth; + if (src.blendEquation) + blendEquation = src.blendEquation; + if (src.numViews != TQualifier::layoutNotSet) + numViews = src.numViews; +#ifdef NV_EXTENSIONS + if (src.layoutOverrideCoverage) + layoutOverrideCoverage = src.layoutOverrideCoverage; +#endif + } +}; + +// +// TPublicType is just temporarily used while parsing and not quite the same +// information kept per node in TType. Due to the bison stack, it can't have +// types that it thinks have non-trivial constructors. It should +// just be used while recognizing the grammar, not anything else. +// Once enough is known about the situation, the proper information +// moved into a TType, or the parse context, etc. +// +class TPublicType { +public: + TBasicType basicType; + TSampler sampler; + TQualifier qualifier; + TShaderQualifiers shaderQualifiers; + int vectorSize : 4; + int matrixCols : 4; + int matrixRows : 4; + TArraySizes* arraySizes; + const TType* userDef; + TSourceLoc loc; + + void initType(const TSourceLoc& l) + { + basicType = EbtVoid; + vectorSize = 1; + matrixRows = 0; + matrixCols = 0; + arraySizes = nullptr; + userDef = nullptr; + loc = l; + } + + void initQualifiers(bool global = false) + { + qualifier.clear(); + if (global) + qualifier.storage = EvqGlobal; + } + + void init(const TSourceLoc& l, bool global = false) + { + initType(l); + sampler.clear(); + initQualifiers(global); + shaderQualifiers.init(); + } + + void setVector(int s) + { + matrixRows = 0; + matrixCols = 0; + vectorSize = s; + } + + void setMatrix(int c, int r) + { + matrixRows = r; + matrixCols = c; + vectorSize = 0; + } + + bool isScalar() const + { + return matrixCols == 0 && vectorSize == 1 && arraySizes == nullptr && userDef == nullptr; + } + + // "Image" is a superset of "Subpass" + bool isImage() const { return basicType == EbtSampler && sampler.isImage(); } + bool isSubpass() const { return basicType == EbtSampler && sampler.isSubpass(); } +}; + +// +// Base class for things that have a type. +// +class TType { +public: + POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) + + // for "empty" type (no args) or simple scalar/vector/matrix + explicit TType(TBasicType t = EbtVoid, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0, + bool isVector = false) : + basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), + arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr) + { + sampler.clear(); + qualifier.clear(); + qualifier.storage = q; + assert(!(isMatrix() && vectorSize != 0)); // prevent vectorSize != 0 on matrices + } + // for explicit precision qualifier + TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0, + bool isVector = false) : + basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), + arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr) + { + sampler.clear(); + qualifier.clear(); + qualifier.storage = q; + qualifier.precision = p; + assert(p >= EpqNone && p <= EpqHigh); + assert(!(isMatrix() && vectorSize != 0)); // prevent vectorSize != 0 on matrices + } + // for turning a TPublicType into a TType, using a shallow copy + explicit TType(const TPublicType& p) : + basicType(p.basicType), + vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false), + arraySizes(p.arraySizes), structure(nullptr), fieldName(nullptr), typeName(nullptr) + { + if (basicType == EbtSampler) + sampler = p.sampler; + else + sampler.clear(); + qualifier = p.qualifier; + if (p.userDef) { + structure = p.userDef->getWritableStruct(); // public type is short-lived; there are no sharing issues + typeName = NewPoolTString(p.userDef->getTypeName().c_str()); + } + } + // for construction of sampler types + TType(const TSampler& sampler, TStorageQualifier q = EvqUniform, TArraySizes* as = nullptr) : + basicType(EbtSampler), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), + arraySizes(as), structure(nullptr), fieldName(nullptr), typeName(nullptr), + sampler(sampler) + { + qualifier.clear(); + qualifier.storage = q; + } + // to efficiently make a dereferenced type + // without ever duplicating the outer structure that will be thrown away + // and using only shallow copy + TType(const TType& type, int derefIndex, bool rowMajor = false) + { + if (type.isArray()) { + shallowCopy(type); + if (type.getArraySizes()->getNumDims() == 1) { + arraySizes = nullptr; + } else { + // want our own copy of the array, so we can edit it + arraySizes = new TArraySizes; + arraySizes->copyDereferenced(*type.arraySizes); + } + } else if (type.basicType == EbtStruct || type.basicType == EbtBlock) { + // do a structure dereference + const TTypeList& memberList = *type.getStruct(); + shallowCopy(*memberList[derefIndex].type); + return; + } else { + // do a vector/matrix dereference + shallowCopy(type); + if (matrixCols > 0) { + // dereference from matrix to vector + if (rowMajor) + vectorSize = matrixCols; + else + vectorSize = matrixRows; + matrixCols = 0; + matrixRows = 0; + if (vectorSize == 1) + vector1 = true; + } else if (isVector()) { + // dereference from vector to scalar + vectorSize = 1; + vector1 = false; + } + } + } + // for making structures, ... + TType(TTypeList* userDef, const TString& n) : + basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), + arraySizes(nullptr), structure(userDef), fieldName(nullptr) + { + sampler.clear(); + qualifier.clear(); + typeName = NewPoolTString(n.c_str()); + } + // For interface blocks + TType(TTypeList* userDef, const TString& n, const TQualifier& q) : + basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), + qualifier(q), arraySizes(nullptr), structure(userDef), fieldName(nullptr) + { + sampler.clear(); + typeName = NewPoolTString(n.c_str()); + } + virtual ~TType() {} + + // Not for use across pool pops; it will cause multiple instances of TType to point to the same information. + // This only works if that information (like a structure's list of types) does not change and + // the instances are sharing the same pool. + void shallowCopy(const TType& copyOf) + { + basicType = copyOf.basicType; + sampler = copyOf.sampler; + qualifier = copyOf.qualifier; + vectorSize = copyOf.vectorSize; + matrixCols = copyOf.matrixCols; + matrixRows = copyOf.matrixRows; + vector1 = copyOf.vector1; + arraySizes = copyOf.arraySizes; // copying the pointer only, not the contents + structure = copyOf.structure; + fieldName = copyOf.fieldName; + typeName = copyOf.typeName; + } + + // Make complete copy of the whole type graph rooted at 'copyOf'. + void deepCopy(const TType& copyOf) + { + TMap copied; // to enable copying a type graph as a graph, not a tree + deepCopy(copyOf, copied); + } + + // Recursively make temporary + void makeTemporary() + { + getQualifier().makeTemporary(); + + if (isStruct()) + for (unsigned int i = 0; i < structure->size(); ++i) + (*structure)[i].type->makeTemporary(); + } + + TType* clone() const + { + TType *newType = new TType(); + newType->deepCopy(*this); + + return newType; + } + + void makeVector() { vector1 = true; } + + // Merge type from parent, where a parentType is at the beginning of a declaration, + // establishing some characteristics for all subsequent names, while this type + // is on the individual names. + void mergeType(const TPublicType& parentType) + { + // arrayness is currently the only child aspect that has to be preserved + basicType = parentType.basicType; + vectorSize = parentType.vectorSize; + matrixCols = parentType.matrixCols; + matrixRows = parentType.matrixRows; + vector1 = false; // TPublicType is only GLSL which so far has no vec1 + qualifier = parentType.qualifier; + sampler = parentType.sampler; + if (parentType.arraySizes) + newArraySizes(*parentType.arraySizes); + if (parentType.userDef) { + structure = parentType.userDef->getWritableStruct(); + setTypeName(parentType.userDef->getTypeName()); + } + } + + virtual void hideMember() { basicType = EbtVoid; vectorSize = 1; } + virtual bool hiddenMember() const { return basicType == EbtVoid; } + + virtual void setTypeName(const TString& n) { typeName = NewPoolTString(n.c_str()); } + virtual void setFieldName(const TString& n) { fieldName = NewPoolTString(n.c_str()); } + virtual const TString& getTypeName() const + { + assert(typeName); + return *typeName; + } + + virtual const TString& getFieldName() const + { + assert(fieldName); + return *fieldName; + } + + virtual TBasicType getBasicType() const { return basicType; } + virtual const TSampler& getSampler() const { return sampler; } + virtual TSampler& getSampler() { return sampler; } + + virtual TQualifier& getQualifier() { return qualifier; } + virtual const TQualifier& getQualifier() const { return qualifier; } + + virtual int getVectorSize() const { return vectorSize; } // returns 1 for either scalar or vector of size 1, valid for both + virtual int getMatrixCols() const { return matrixCols; } + virtual int getMatrixRows() const { return matrixRows; } + virtual int getOuterArraySize() const { return arraySizes->getOuterSize(); } + virtual TIntermTyped* getOuterArrayNode() const { return arraySizes->getOuterNode(); } + virtual int getCumulativeArraySize() const { return arraySizes->getCumulativeSize(); } + virtual bool isArrayOfArrays() const { return arraySizes != nullptr && arraySizes->getNumDims() > 1; } + virtual int getImplicitArraySize() const { return arraySizes->getImplicitSize(); } + virtual const TArraySizes* getArraySizes() const { return arraySizes; } + virtual TArraySizes& getArraySizes() { assert(arraySizes != nullptr); return *arraySizes; } + + virtual bool isScalar() const { return ! isVector() && ! isMatrix() && ! isStruct() && ! isArray(); } + virtual bool isScalarOrVec1() const { return isScalar() || vector1; } + virtual bool isVector() const { return vectorSize > 1 || vector1; } + virtual bool isMatrix() const { return matrixCols ? true : false; } + virtual bool isArray() const { return arraySizes != nullptr; } + virtual bool isExplicitlySizedArray() const { return isArray() && getOuterArraySize() != UnsizedArraySize; } + virtual bool isImplicitlySizedArray() const { return isArray() && getOuterArraySize() == UnsizedArraySize && qualifier.storage != EvqBuffer; } + virtual bool isRuntimeSizedArray() const { return isArray() && getOuterArraySize() == UnsizedArraySize && qualifier.storage == EvqBuffer; } + virtual bool isStruct() const { return structure != nullptr; } +#ifdef AMD_EXTENSIONS + virtual bool isFloatingDomain() const { return basicType == EbtFloat || basicType == EbtDouble || basicType == EbtFloat16; } +#else + virtual bool isFloatingDomain() const { return basicType == EbtFloat || basicType == EbtDouble; } +#endif + virtual bool isIntegerDomain() const + { + switch (basicType) { + case EbtInt: + case EbtUint: + case EbtInt64: + case EbtUint64: +#ifdef AMD_EXTENSIONS + case EbtInt16: + case EbtUint16: +#endif + case EbtAtomicUint: + return true; + default: + break; + } + return false; + } + virtual bool isOpaque() const { return basicType == EbtSampler || basicType == EbtAtomicUint; } + virtual bool isBuiltIn() const { return getQualifier().builtIn != EbvNone; } + + // "Image" is a superset of "Subpass" + virtual bool isImage() const { return basicType == EbtSampler && getSampler().isImage(); } + virtual bool isSubpass() const { return basicType == EbtSampler && getSampler().isSubpass(); } + + // return true if this type contains any subtype which satisfies the given predicate. + template + bool contains(P predicate) const + { + if (predicate(this)) + return true; + + const auto hasa = [predicate](const TTypeLoc& tl) { return tl.type->contains(predicate); }; + + return structure && std::any_of(structure->begin(), structure->end(), hasa); + } + + // Recursively checks if the type contains the given basic type + virtual bool containsBasicType(TBasicType checkType) const + { + return contains([checkType](const TType* t) { return t->basicType == checkType; } ); + } + + // Recursively check the structure for any arrays, needed for some error checks + virtual bool containsArray() const + { + return contains([](const TType* t) { return t->isArray(); } ); + } + + // Check the structure for any structures, needed for some error checks + virtual bool containsStructure() const + { + return contains([this](const TType* t) { return t != this && t->isStruct(); } ); + } + + // Recursively check the structure for any implicitly-sized arrays, needed for triggering a copyUp(). + virtual bool containsImplicitlySizedArray() const + { + return contains([](const TType* t) { return t->isImplicitlySizedArray(); } ); + } + + virtual bool containsOpaque() const + { + return contains([](const TType* t) { return t->isOpaque(); } ); + } + + // Recursively checks if the type contains a built-in variable + virtual bool containsBuiltIn() const + { + return contains([](const TType* t) { return t->isBuiltIn(); } ); + } + + virtual bool containsNonOpaque() const + { + const auto nonOpaque = [](const TType* t) { + switch (t->basicType) { + case EbtVoid: + case EbtFloat: + case EbtDouble: +#ifdef AMD_EXTENSIONS + case EbtFloat16: +#endif + case EbtInt: + case EbtUint: + case EbtInt64: + case EbtUint64: +#ifdef AMD_EXTENSIONS + case EbtInt16: + case EbtUint16: +#endif + case EbtBool: + return true; + default: + return false; + } + }; + + return contains(nonOpaque); + } + + virtual bool containsSpecializationSize() const + { + return contains([](const TType* t) { return t->isArray() && t->arraySizes->isOuterSpecialization(); } ); + } + + // Array editing methods. Array descriptors can be shared across + // type instances. This allows all uses of the same array + // to be updated at once. E.g., all nodes can be explicitly sized + // by tracking and correcting one implicit size. Or, all nodes + // can get the explicit size on a redeclaration that gives size. + // + // N.B.: Don't share with the shared symbol tables (symbols are + // marked as isReadOnly(). Such symbols with arrays that will be + // edited need to copyUp() on first use, so that + // A) the edits don't effect the shared symbol table, and + // B) the edits are shared across all users. + void updateArraySizes(const TType& type) + { + // For when we may already be sharing existing array descriptors, + // keeping the pointers the same, just updating the contents. + assert(arraySizes != nullptr); + assert(type.arraySizes != nullptr); + *arraySizes = *type.arraySizes; + } + void newArraySizes(const TArraySizes& s) + { + // For setting a fresh new set of array sizes, not yet worrying about sharing. + arraySizes = new TArraySizes; + *arraySizes = s; + } + void clearArraySizes() + { + arraySizes = 0; + } + void addArrayOuterSizes(const TArraySizes& s) + { + if (arraySizes == nullptr) + newArraySizes(s); + else + arraySizes->addOuterSizes(s); + } + void changeOuterArraySize(int s) { arraySizes->changeOuterSize(s); } + void setImplicitArraySize(int s) { arraySizes->setImplicitSize(s); } + + // Recursively make the implicit array size the explicit array size, through the type tree. + void adoptImplicitArraySizes() + { + if (isImplicitlySizedArray()) + changeOuterArraySize(getImplicitArraySize()); + if (isStruct()) { + for (int i = 0; i < (int)structure->size(); ++i) + (*structure)[i].type->adoptImplicitArraySizes(); + } + } + + const char* getBasicString() const + { + return TType::getBasicString(basicType); + } + + static const char* getBasicString(TBasicType t) + { + switch (t) { + case EbtVoid: return "void"; + case EbtFloat: return "float"; + case EbtDouble: return "double"; +#ifdef AMD_EXTENSIONS + case EbtFloat16: return "float16_t"; +#endif + case EbtInt: return "int"; + case EbtUint: return "uint"; + case EbtInt64: return "int64_t"; + case EbtUint64: return "uint64_t"; +#ifdef AMD_EXTENSIONS + case EbtInt16: return "int16_t"; + case EbtUint16: return "uint16_t"; +#endif + case EbtBool: return "bool"; + case EbtAtomicUint: return "atomic_uint"; + case EbtSampler: return "sampler/image"; + case EbtStruct: return "structure"; + case EbtBlock: return "block"; + default: return "unknown type"; + } + } + + TString getCompleteString() const + { + TString typeString; + + const auto appendStr = [&](const char* s) { typeString.append(s); }; + const auto appendUint = [&](unsigned int u) { typeString.append(std::to_string(u).c_str()); }; + const auto appendInt = [&](int i) { typeString.append(std::to_string(i).c_str()); }; + + if (qualifier.hasLayout()) { + // To reduce noise, skip this if the only layout is an xfb_buffer + // with no triggering xfb_offset. + TQualifier noXfbBuffer = qualifier; + noXfbBuffer.layoutXfbBuffer = TQualifier::layoutXfbBufferEnd; + if (noXfbBuffer.hasLayout()) { + appendStr("layout("); + if (qualifier.hasAnyLocation()) { + appendStr(" location="); + appendUint(qualifier.layoutLocation); + if (qualifier.hasComponent()) { + appendStr(" component="); + appendUint(qualifier.layoutComponent); + } + if (qualifier.hasIndex()) { + appendStr(" index="); + appendUint(qualifier.layoutIndex); + } + } + if (qualifier.hasSet()) { + appendStr(" set="); + appendUint(qualifier.layoutSet); + } + if (qualifier.hasBinding()) { + appendStr(" binding="); + appendUint(qualifier.layoutBinding); + } + if (qualifier.hasStream()) { + appendStr(" stream="); + appendUint(qualifier.layoutStream); + } + if (qualifier.hasMatrix()) { + appendStr(" "); + appendStr(TQualifier::getLayoutMatrixString(qualifier.layoutMatrix)); + } + if (qualifier.hasPacking()) { + appendStr(" "); + appendStr(TQualifier::getLayoutPackingString(qualifier.layoutPacking)); + } + if (qualifier.hasOffset()) { + appendStr(" offset="); + appendInt(qualifier.layoutOffset); + } + if (qualifier.hasAlign()) { + appendStr(" align="); + appendInt(qualifier.layoutAlign); + } + if (qualifier.hasFormat()) { + appendStr(" "); + appendStr(TQualifier::getLayoutFormatString(qualifier.layoutFormat)); + } + if (qualifier.hasXfbBuffer() && qualifier.hasXfbOffset()) { + appendStr(" xfb_buffer="); + appendUint(qualifier.layoutXfbBuffer); + } + if (qualifier.hasXfbOffset()) { + appendStr(" xfb_offset="); + appendUint(qualifier.layoutXfbOffset); + } + if (qualifier.hasXfbStride()) { + appendStr(" xfb_stride="); + appendUint(qualifier.layoutXfbStride); + } + if (qualifier.hasAttachment()) { + appendStr(" input_attachment_index="); + appendUint(qualifier.layoutAttachment); + } + if (qualifier.hasSpecConstantId()) { + appendStr(" constant_id="); + appendUint(qualifier.layoutSpecConstantId); + } + if (qualifier.layoutPushConstant) + appendStr(" push_constant"); + +#ifdef NV_EXTENSIONS + if (qualifier.layoutPassthrough) + appendStr(" passthrough"); + if (qualifier.layoutViewportRelative) + appendStr(" layoutViewportRelative"); + if (qualifier.layoutSecondaryViewportRelativeOffset != -2048) { + appendStr(" layoutSecondaryViewportRelativeOffset="); + appendInt(qualifier.layoutSecondaryViewportRelativeOffset); + } +#endif + + appendStr(")"); + } + } + + if (qualifier.invariant) + appendStr(" invariant"); + if (qualifier.noContraction) + appendStr(" noContraction"); + if (qualifier.centroid) + appendStr(" centroid"); + if (qualifier.smooth) + appendStr(" smooth"); + if (qualifier.flat) + appendStr(" flat"); + if (qualifier.nopersp) + appendStr(" noperspective"); +#ifdef AMD_EXTENSIONS + if (qualifier.explicitInterp) + appendStr(" __explicitInterpAMD"); +#endif + if (qualifier.patch) + appendStr(" patch"); + if (qualifier.sample) + appendStr(" sample"); + if (qualifier.coherent) + appendStr(" coherent"); + if (qualifier.volatil) + appendStr(" volatile"); + if (qualifier.restrict) + appendStr(" restrict"); + if (qualifier.readonly) + appendStr(" readonly"); + if (qualifier.writeonly) + appendStr(" writeonly"); + if (qualifier.specConstant) + appendStr(" specialization-constant"); + appendStr(" "); + appendStr(getStorageQualifierString()); + if (isArray()) { + for(int i = 0; i < (int)arraySizes->getNumDims(); ++i) { + int size = arraySizes->getDimSize(i); + if (size == 0) + appendStr(" implicitly-sized array of"); + else { + appendStr(" "); + appendInt(arraySizes->getDimSize(i)); + appendStr("-element array of"); + } + } + } + if (qualifier.precision != EpqNone) { + appendStr(" "); + appendStr(getPrecisionQualifierString()); + } + if (isMatrix()) { + appendStr(" "); + appendInt(matrixCols); + appendStr("X"); + appendInt(matrixRows); + appendStr(" matrix of"); + } else if (isVector()) { + appendStr(" "); + appendInt(vectorSize); + appendStr("-component vector of"); + } + + appendStr(" "); + typeString.append(getBasicTypeString()); + + if (qualifier.builtIn != EbvNone) { + appendStr(" "); + appendStr(getBuiltInVariableString()); + } + + // Add struct/block members + if (structure) { + appendStr("{"); + for (size_t i = 0; i < structure->size(); ++i) { + if (! (*structure)[i].type->hiddenMember()) { + typeString.append((*structure)[i].type->getCompleteString()); + typeString.append(" "); + typeString.append((*structure)[i].type->getFieldName()); + if (i < structure->size() - 1) + appendStr(", "); + } + } + appendStr("}"); + } + + return typeString; + } + + TString getBasicTypeString() const + { + if (basicType == EbtSampler) + return sampler.getString(); + else + return getBasicString(); + } + + const char* getStorageQualifierString() const { return GetStorageQualifierString(qualifier.storage); } + const char* getBuiltInVariableString() const { return GetBuiltInVariableString(qualifier.builtIn); } + const char* getPrecisionQualifierString() const { return GetPrecisionQualifierString(qualifier.precision); } + const TTypeList* getStruct() const { return structure; } + void setStruct(TTypeList* s) { structure = s; } + TTypeList* getWritableStruct() const { return structure; } // This should only be used when known to not be sharing with other threads + + int computeNumComponents() const + { + int components = 0; + + if (getBasicType() == EbtStruct || getBasicType() == EbtBlock) { + for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++) + components += ((*tl).type)->computeNumComponents(); + } else if (matrixCols) + components = matrixCols * matrixRows; + else + components = vectorSize; + + if (arraySizes != nullptr) { + components *= arraySizes->getCumulativeSize(); + } + + return components; + } + + // append this type's mangled name to the passed in 'name' + void appendMangledName(TString& name) const + { + buildMangledName(name); + name += ';' ; + } + + // Do two structure types match? They could be declared independently, + // in different places, but still might satisfy the definition of matching. + // From the spec: + // + // "Structures must have the same name, sequence of type names, and + // type definitions, and member names to be considered the same type. + // This rule applies recursively for nested or embedded types." + // + bool sameStructType(const TType& right) const + { + // Most commonly, they are both nullptr, or the same pointer to the same actual structure + if (structure == right.structure) + return true; + + // Both being nullptr was caught above, now they both have to be structures of the same number of elements + if (structure == nullptr || right.structure == nullptr || + structure->size() != right.structure->size()) + return false; + + // Structure names have to match + if (*typeName != *right.typeName) + return false; + + // Compare the names and types of all the members, which have to match + for (unsigned int i = 0; i < structure->size(); ++i) { + if ((*structure)[i].type->getFieldName() != (*right.structure)[i].type->getFieldName()) + return false; + + if (*(*structure)[i].type != *(*right.structure)[i].type) + return false; + } + + return true; + } + + // See if two types match, in all aspects except arrayness + bool sameElementType(const TType& right) const + { + return basicType == right.basicType && sameElementShape(right); + } + + // See if two type's arrayness match + bool sameArrayness(const TType& right) const + { + return ((arraySizes == nullptr && right.arraySizes == nullptr) || + (arraySizes != nullptr && right.arraySizes != nullptr && *arraySizes == *right.arraySizes)); + } + + // See if two type's arrayness match in everything except their outer dimension + bool sameInnerArrayness(const TType& right) const + { + assert(arraySizes != nullptr && right.arraySizes != nullptr); + return arraySizes->sameInnerArrayness(*right.arraySizes); + } + + // See if two type's elements match in all ways except basic type + bool sameElementShape(const TType& right) const + { + return sampler == right.sampler && + vectorSize == right.vectorSize && + matrixCols == right.matrixCols && + matrixRows == right.matrixRows && + vector1 == right.vector1 && + sameStructType(right); + } + + // See if two types match in all ways (just the actual type, not qualification) + bool operator==(const TType& right) const + { + return sameElementType(right) && sameArrayness(right); + } + + bool operator!=(const TType& right) const + { + return ! operator==(right); + } + +protected: + // Require consumer to pick between deep copy and shallow copy. + TType(const TType& type); + TType& operator=(const TType& type); + + // Recursively copy a type graph, while preserving the graph-like + // quality. That is, don't make more than one copy of a structure that + // gets reused multiple times in the type graph. + void deepCopy(const TType& copyOf, TMap& copiedMap) + { + shallowCopy(copyOf); + + if (copyOf.arraySizes) { + arraySizes = new TArraySizes; + *arraySizes = *copyOf.arraySizes; + } + + if (copyOf.structure) { + auto prevCopy = copiedMap.find(copyOf.structure); + if (prevCopy != copiedMap.end()) + structure = prevCopy->second; + else { + structure = new TTypeList; + copiedMap[copyOf.structure] = structure; + for (unsigned int i = 0; i < copyOf.structure->size(); ++i) { + TTypeLoc typeLoc; + typeLoc.loc = (*copyOf.structure)[i].loc; + typeLoc.type = new TType(); + typeLoc.type->deepCopy(*(*copyOf.structure)[i].type, copiedMap); + structure->push_back(typeLoc); + } + } + } + + if (copyOf.fieldName) + fieldName = NewPoolTString(copyOf.fieldName->c_str()); + if (copyOf.typeName) + typeName = NewPoolTString(copyOf.typeName->c_str()); + } + + + void buildMangledName(TString&) const; + + TBasicType basicType : 8; + int vectorSize : 4; // 1 means either scalar or 1-component vector; see vector1 to disambiguate. + int matrixCols : 4; + int matrixRows : 4; + bool vector1 : 1; // Backward-compatible tracking of a 1-component vector distinguished from a scalar. + // GLSL 4.5 never has a 1-component vector; so this will always be false until such + // functionality is added. + // HLSL does have a 1-component vectors, so this will be true to disambiguate + // from a scalar. + TQualifier qualifier; + + TArraySizes* arraySizes; // nullptr unless an array; can be shared across types + TTypeList* structure; // nullptr unless this is a struct; can be shared across types + TString *fieldName; // for structure field names + TString *typeName; // for structure type name + TSampler sampler; +}; + +} // end namespace glslang + +#endif // _TYPES_INCLUDED_ diff --git a/love/src/jni/love/src/libraries/glslang/glslang/Include/arrays.h b/love/src/jni/love/src/libraries/glslang/glslang/Include/arrays.h new file mode 100644 index 00000000..1660a99f --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/Include/arrays.h @@ -0,0 +1,329 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2012-2013 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +// +// Implement types for tracking GLSL arrays, arrays of arrays, etc. +// + +#ifndef _ARRAYS_INCLUDED +#define _ARRAYS_INCLUDED + +namespace glslang { + +// This is used to mean there is no size yet (unsized), it is waiting to get a size from somewhere else. +const int UnsizedArraySize = 0; + +class TIntermTyped; +extern bool SameSpecializationConstants(TIntermTyped*, TIntermTyped*); + +// Specialization constants need both a nominal size and a node that defines +// the specialization constant being used. Array types are the same when their +// size and specialization constant nodes are the same. +struct TArraySize { + unsigned int size; + TIntermTyped* node; // nullptr means no specialization constant node + bool operator==(const TArraySize& rhs) const + { + if (size != rhs.size) + return false; + if (node == nullptr || rhs.node == nullptr) + return node == rhs.node; + + return SameSpecializationConstants(node, rhs.node); + } +}; + +// +// TSmallArrayVector is used as the container for the set of sizes in TArraySizes. +// It has generic-container semantics, while TArraySizes has array-of-array semantics. +// That is, TSmallArrayVector should be more focused on mechanism and TArraySizes on policy. +// +struct TSmallArrayVector { + // + // TODO: memory: TSmallArrayVector is intended to be smaller. + // Almost all arrays could be handled by two sizes each fitting + // in 16 bits, needing a real vector only in the cases where there + // are more than 3 sizes or a size needing more than 16 bits. + // + POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) + + TSmallArrayVector() : sizes(nullptr) { } + virtual ~TSmallArrayVector() { dealloc(); } + + // For breaking into two non-shared copies, independently modifiable. + TSmallArrayVector& operator=(const TSmallArrayVector& from) + { + if (from.sizes == nullptr) + sizes = nullptr; + else { + alloc(); + *sizes = *from.sizes; + } + + return *this; + } + + int size() const + { + if (sizes == nullptr) + return 0; + return (int)sizes->size(); + } + + unsigned int frontSize() const + { + assert(sizes != nullptr && sizes->size() > 0); + return sizes->front().size; + } + + TIntermTyped* frontNode() const + { + assert(sizes != nullptr && sizes->size() > 0); + return sizes->front().node; + } + + void changeFront(unsigned int s) + { + assert(sizes != nullptr); + // this should only happen for implicitly sized arrays, not specialization constants + assert(sizes->front().node == nullptr); + sizes->front().size = s; + } + + void push_back(unsigned int e, TIntermTyped* n) + { + alloc(); + TArraySize pair = { e, n }; + sizes->push_back(pair); + } + + void push_front(const TSmallArrayVector& newDims) + { + alloc(); + sizes->insert(sizes->begin(), newDims.sizes->begin(), newDims.sizes->end()); + } + + void pop_front() + { + assert(sizes != nullptr && sizes->size() > 0); + if (sizes->size() == 1) + dealloc(); + else + sizes->erase(sizes->begin()); + } + + // 'this' should currently not be holding anything, and copyNonFront + // will make it hold a copy of all but the first element of rhs. + // (This would be useful for making a type that is dereferenced by + // one dimension.) + void copyNonFront(const TSmallArrayVector& rhs) + { + assert(sizes == nullptr); + if (rhs.size() > 1) { + alloc(); + sizes->insert(sizes->begin(), rhs.sizes->begin() + 1, rhs.sizes->end()); + } + } + + unsigned int getDimSize(int i) const + { + assert(sizes != nullptr && (int)sizes->size() > i); + return (*sizes)[i].size; + } + + void setDimSize(int i, unsigned int size) const + { + assert(sizes != nullptr && (int)sizes->size() > i); + assert((*sizes)[i].node == nullptr); + (*sizes)[i].size = size; + } + + TIntermTyped* getDimNode(int i) const + { + assert(sizes != nullptr && (int)sizes->size() > i); + return (*sizes)[i].node; + } + + bool operator==(const TSmallArrayVector& rhs) const + { + if (sizes == nullptr && rhs.sizes == nullptr) + return true; + if (sizes == nullptr || rhs.sizes == nullptr) + return false; + return *sizes == *rhs.sizes; + } + bool operator!=(const TSmallArrayVector& rhs) const { return ! operator==(rhs); } + +protected: + TSmallArrayVector(const TSmallArrayVector&); + + void alloc() + { + if (sizes == nullptr) + sizes = new TVector; + } + void dealloc() + { + delete sizes; + sizes = nullptr; + } + + TVector* sizes; // will either hold such a pointer, or in the future, hold the two array sizes +}; + +// +// Represent an array, or array of arrays, to arbitrary depth. This is not +// done through a hierarchy of types in a type tree, rather all contiguous arrayness +// in the type hierarchy is localized into this single cumulative object. +// +// The arrayness in TTtype is a pointer, so that it can be non-allocated and zero +// for the vast majority of types that are non-array types. +// +// Order Policy: these are all identical: +// - left to right order within a contiguous set of ...[..][..][..]... in the source language +// - index order 0, 1, 2, ... within the 'sizes' member below +// - outer-most to inner-most +// +struct TArraySizes { + POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) + + TArraySizes() : implicitArraySize(1) { } + + // For breaking into two non-shared copies, independently modifiable. + TArraySizes& operator=(const TArraySizes& from) + { + implicitArraySize = from.implicitArraySize; + sizes = from.sizes; + + return *this; + } + + // translate from array-of-array semantics to container semantics + int getNumDims() const { return sizes.size(); } + int getDimSize(int dim) const { return sizes.getDimSize(dim); } + TIntermTyped* getDimNode(int dim) const { return sizes.getDimNode(dim); } + void setDimSize(int dim, int size) { sizes.setDimSize(dim, size); } + int getOuterSize() const { return sizes.frontSize(); } + TIntermTyped* getOuterNode() const { return sizes.frontNode(); } + int getCumulativeSize() const + { + int size = 1; + for (int d = 0; d < sizes.size(); ++d) { + // this only makes sense in paths that have a known array size + assert(sizes.getDimSize(d) != UnsizedArraySize); + size *= sizes.getDimSize(d); + } + return size; + } + void addInnerSize() { addInnerSize((unsigned)UnsizedArraySize); } + void addInnerSize(int s) { addInnerSize((unsigned)s, nullptr); } + void addInnerSize(int s, TIntermTyped* n) { sizes.push_back((unsigned)s, n); } + void addInnerSize(TArraySize pair) { sizes.push_back(pair.size, pair.node); } + void changeOuterSize(int s) { sizes.changeFront((unsigned)s); } + int getImplicitSize() const { return (int)implicitArraySize; } + void setImplicitSize(int s) { implicitArraySize = s; } + bool isInnerImplicit() const + { + for (int d = 1; d < sizes.size(); ++d) { + if (sizes.getDimSize(d) == (unsigned)UnsizedArraySize) + return true; + } + + return false; + } + bool clearInnerImplicit() + { + for (int d = 1; d < sizes.size(); ++d) { + if (sizes.getDimSize(d) == (unsigned)UnsizedArraySize) + setDimSize(d, 1); + } + + return false; + } + bool isInnerSpecialization() const + { + for (int d = 1; d < sizes.size(); ++d) { + if (sizes.getDimNode(d) != nullptr) + return true; + } + + return false; + } + bool isOuterSpecialization() + { + return sizes.getDimNode(0) != nullptr; + } + + bool isImplicit() const { return getOuterSize() == UnsizedArraySize || isInnerImplicit(); } + void addOuterSizes(const TArraySizes& s) { sizes.push_front(s.sizes); } + void dereference() { sizes.pop_front(); } + void copyDereferenced(const TArraySizes& rhs) + { + assert(sizes.size() == 0); + if (rhs.sizes.size() > 1) + sizes.copyNonFront(rhs.sizes); + } + + bool sameInnerArrayness(const TArraySizes& rhs) const + { + if (sizes.size() != rhs.sizes.size()) + return false; + + for (int d = 1; d < sizes.size(); ++d) { + if (sizes.getDimSize(d) != rhs.sizes.getDimSize(d) || + sizes.getDimNode(d) != rhs.sizes.getDimNode(d)) + return false; + } + + return true; + } + + bool operator==(const TArraySizes& rhs) { return sizes == rhs.sizes; } + bool operator!=(const TArraySizes& rhs) { return sizes != rhs.sizes; } + +protected: + TSmallArrayVector sizes; + + TArraySizes(const TArraySizes&); + + // for tracking maximum referenced index, before an explicit size is given + // applies only to the outer-most dimension + int implicitArraySize; +}; + +} // end namespace glslang + +#endif // _ARRAYS_INCLUDED_ diff --git a/love/src/jni/love/src/libraries/glslang/glslang/Include/intermediate.h b/love/src/jni/love/src/libraries/glslang/glslang/Include/intermediate.h new file mode 100644 index 00000000..58760195 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/Include/intermediate.h @@ -0,0 +1,1481 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2012-2016 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +// +// Definition of the in-memory high-level intermediate representation +// of shaders. This is a tree that parser creates. +// +// Nodes in the tree are defined as a hierarchy of classes derived from +// TIntermNode. Each is a node in a tree. There is no preset branching factor; +// each node can have it's own type of list of children. +// + +#ifndef __INTERMEDIATE_H +#define __INTERMEDIATE_H + +#if _MSC_VER >= 1900 + #pragma warning(disable : 4464) // relative include path contains '..' + #pragma warning(disable : 5026) // 'glslang::TIntermUnary': move constructor was implicitly defined as deleted +#endif + +#include "../Include/Common.h" +#include "../Include/Types.h" +#include "../Include/ConstantUnion.h" + +namespace glslang { + +class TIntermediate; + +// +// Operators used by the high-level (parse tree) representation. +// +enum TOperator { + EOpNull, // if in a node, should only mean a node is still being built + EOpSequence, // denotes a list of statements, or parameters, etc. + EOpLinkerObjects, // for aggregate node of objects the linker may need, if not reference by the rest of the AST + EOpFunctionCall, + EOpFunction, // For function definition + EOpParameters, // an aggregate listing the parameters to a function + + // + // Unary operators + // + + EOpNegative, + EOpLogicalNot, + EOpVectorLogicalNot, + EOpBitwiseNot, + + EOpPostIncrement, + EOpPostDecrement, + EOpPreIncrement, + EOpPreDecrement, + + EOpConvIntToBool, + EOpConvUintToBool, + EOpConvFloatToBool, + EOpConvDoubleToBool, + EOpConvInt64ToBool, + EOpConvUint64ToBool, + EOpConvBoolToFloat, + EOpConvIntToFloat, + EOpConvUintToFloat, + EOpConvDoubleToFloat, + EOpConvInt64ToFloat, + EOpConvUint64ToFloat, + EOpConvUintToInt, + EOpConvFloatToInt, + EOpConvBoolToInt, + EOpConvDoubleToInt, + EOpConvInt64ToInt, + EOpConvUint64ToInt, + EOpConvIntToUint, + EOpConvFloatToUint, + EOpConvBoolToUint, + EOpConvDoubleToUint, + EOpConvInt64ToUint, + EOpConvUint64ToUint, + EOpConvIntToDouble, + EOpConvUintToDouble, + EOpConvFloatToDouble, + EOpConvBoolToDouble, + EOpConvInt64ToDouble, + EOpConvUint64ToDouble, + EOpConvBoolToInt64, + EOpConvIntToInt64, + EOpConvUintToInt64, + EOpConvFloatToInt64, + EOpConvDoubleToInt64, + EOpConvUint64ToInt64, + EOpConvBoolToUint64, + EOpConvIntToUint64, + EOpConvUintToUint64, + EOpConvFloatToUint64, + EOpConvDoubleToUint64, + EOpConvInt64ToUint64, +#ifdef AMD_EXTENSIONS + EOpConvBoolToFloat16, + EOpConvIntToFloat16, + EOpConvUintToFloat16, + EOpConvFloatToFloat16, + EOpConvDoubleToFloat16, + EOpConvInt64ToFloat16, + EOpConvUint64ToFloat16, + EOpConvFloat16ToBool, + EOpConvFloat16ToInt, + EOpConvFloat16ToUint, + EOpConvFloat16ToFloat, + EOpConvFloat16ToDouble, + EOpConvFloat16ToInt64, + EOpConvFloat16ToUint64, + + EOpConvBoolToInt16, + EOpConvIntToInt16, + EOpConvUintToInt16, + EOpConvFloatToInt16, + EOpConvDoubleToInt16, + EOpConvFloat16ToInt16, + EOpConvInt64ToInt16, + EOpConvUint64ToInt16, + EOpConvUint16ToInt16, + EOpConvInt16ToBool, + EOpConvInt16ToInt, + EOpConvInt16ToUint, + EOpConvInt16ToFloat, + EOpConvInt16ToDouble, + EOpConvInt16ToFloat16, + EOpConvInt16ToInt64, + EOpConvInt16ToUint64, + + EOpConvBoolToUint16, + EOpConvIntToUint16, + EOpConvUintToUint16, + EOpConvFloatToUint16, + EOpConvDoubleToUint16, + EOpConvFloat16ToUint16, + EOpConvInt64ToUint16, + EOpConvUint64ToUint16, + EOpConvInt16ToUint16, + EOpConvUint16ToBool, + EOpConvUint16ToInt, + EOpConvUint16ToUint, + EOpConvUint16ToFloat, + EOpConvUint16ToDouble, + EOpConvUint16ToFloat16, + EOpConvUint16ToInt64, + EOpConvUint16ToUint64, +#endif + + // + // binary operations + // + + EOpAdd, + EOpSub, + EOpMul, + EOpDiv, + EOpMod, + EOpRightShift, + EOpLeftShift, + EOpAnd, + EOpInclusiveOr, + EOpExclusiveOr, + EOpEqual, + EOpNotEqual, + EOpVectorEqual, + EOpVectorNotEqual, + EOpLessThan, + EOpGreaterThan, + EOpLessThanEqual, + EOpGreaterThanEqual, + EOpComma, + + EOpVectorTimesScalar, + EOpVectorTimesMatrix, + EOpMatrixTimesVector, + EOpMatrixTimesScalar, + + EOpLogicalOr, + EOpLogicalXor, + EOpLogicalAnd, + + EOpIndexDirect, + EOpIndexIndirect, + EOpIndexDirectStruct, + + EOpVectorSwizzle, + + EOpMethod, + EOpScoping, + + // + // Built-in functions mapped to operators + // + + EOpRadians, + EOpDegrees, + EOpSin, + EOpCos, + EOpTan, + EOpAsin, + EOpAcos, + EOpAtan, + EOpSinh, + EOpCosh, + EOpTanh, + EOpAsinh, + EOpAcosh, + EOpAtanh, + + EOpPow, + EOpExp, + EOpLog, + EOpExp2, + EOpLog2, + EOpSqrt, + EOpInverseSqrt, + + EOpAbs, + EOpSign, + EOpFloor, + EOpTrunc, + EOpRound, + EOpRoundEven, + EOpCeil, + EOpFract, + EOpModf, + EOpMin, + EOpMax, + EOpClamp, + EOpMix, + EOpStep, + EOpSmoothStep, + + EOpIsNan, + EOpIsInf, + + EOpFma, + + EOpFrexp, + EOpLdexp, + + EOpFloatBitsToInt, + EOpFloatBitsToUint, + EOpIntBitsToFloat, + EOpUintBitsToFloat, + EOpDoubleBitsToInt64, + EOpDoubleBitsToUint64, + EOpInt64BitsToDouble, + EOpUint64BitsToDouble, +#ifdef AMD_EXTENSIONS + EOpFloat16BitsToInt16, + EOpFloat16BitsToUint16, + EOpInt16BitsToFloat16, + EOpUint16BitsToFloat16, +#endif + EOpPackSnorm2x16, + EOpUnpackSnorm2x16, + EOpPackUnorm2x16, + EOpUnpackUnorm2x16, + EOpPackSnorm4x8, + EOpUnpackSnorm4x8, + EOpPackUnorm4x8, + EOpUnpackUnorm4x8, + EOpPackHalf2x16, + EOpUnpackHalf2x16, + EOpPackDouble2x32, + EOpUnpackDouble2x32, + EOpPackInt2x32, + EOpUnpackInt2x32, + EOpPackUint2x32, + EOpUnpackUint2x32, +#ifdef AMD_EXTENSIONS + EOpPackFloat2x16, + EOpUnpackFloat2x16, + EOpPackInt2x16, + EOpUnpackInt2x16, + EOpPackUint2x16, + EOpUnpackUint2x16, + EOpPackInt4x16, + EOpUnpackInt4x16, + EOpPackUint4x16, + EOpUnpackUint4x16, +#endif + + EOpLength, + EOpDistance, + EOpDot, + EOpCross, + EOpNormalize, + EOpFaceForward, + EOpReflect, + EOpRefract, + +#ifdef AMD_EXTENSIONS + EOpMin3, + EOpMax3, + EOpMid3, +#endif + + EOpDPdx, // Fragment only + EOpDPdy, // Fragment only + EOpFwidth, // Fragment only + EOpDPdxFine, // Fragment only + EOpDPdyFine, // Fragment only + EOpFwidthFine, // Fragment only + EOpDPdxCoarse, // Fragment only + EOpDPdyCoarse, // Fragment only + EOpFwidthCoarse, // Fragment only + + EOpInterpolateAtCentroid, // Fragment only + EOpInterpolateAtSample, // Fragment only + EOpInterpolateAtOffset, // Fragment only + +#ifdef AMD_EXTENSIONS + EOpInterpolateAtVertex, +#endif + + EOpMatrixTimesMatrix, + EOpOuterProduct, + EOpDeterminant, + EOpMatrixInverse, + EOpTranspose, + + EOpFtransform, + + EOpNoise, + + EOpEmitVertex, // geometry only + EOpEndPrimitive, // geometry only + EOpEmitStreamVertex, // geometry only + EOpEndStreamPrimitive, // geometry only + + EOpBarrier, + EOpMemoryBarrier, + EOpMemoryBarrierAtomicCounter, + EOpMemoryBarrierBuffer, + EOpMemoryBarrierImage, + EOpMemoryBarrierShared, // compute only + EOpGroupMemoryBarrier, // compute only + + EOpBallot, + EOpReadInvocation, + EOpReadFirstInvocation, + + EOpAnyInvocation, + EOpAllInvocations, + EOpAllInvocationsEqual, + +#ifdef AMD_EXTENSIONS + EOpMinInvocations, + EOpMaxInvocations, + EOpAddInvocations, + EOpMinInvocationsNonUniform, + EOpMaxInvocationsNonUniform, + EOpAddInvocationsNonUniform, + EOpMinInvocationsInclusiveScan, + EOpMaxInvocationsInclusiveScan, + EOpAddInvocationsInclusiveScan, + EOpMinInvocationsInclusiveScanNonUniform, + EOpMaxInvocationsInclusiveScanNonUniform, + EOpAddInvocationsInclusiveScanNonUniform, + EOpMinInvocationsExclusiveScan, + EOpMaxInvocationsExclusiveScan, + EOpAddInvocationsExclusiveScan, + EOpMinInvocationsExclusiveScanNonUniform, + EOpMaxInvocationsExclusiveScanNonUniform, + EOpAddInvocationsExclusiveScanNonUniform, + EOpSwizzleInvocations, + EOpSwizzleInvocationsMasked, + EOpWriteInvocation, + EOpMbcnt, + + EOpCubeFaceIndex, + EOpCubeFaceCoord, + EOpTime, +#endif + + EOpAtomicAdd, + EOpAtomicMin, + EOpAtomicMax, + EOpAtomicAnd, + EOpAtomicOr, + EOpAtomicXor, + EOpAtomicExchange, + EOpAtomicCompSwap, + + EOpAtomicCounterIncrement, // results in pre-increment value + EOpAtomicCounterDecrement, // results in post-decrement value + EOpAtomicCounter, + EOpAtomicCounterAdd, + EOpAtomicCounterSubtract, + EOpAtomicCounterMin, + EOpAtomicCounterMax, + EOpAtomicCounterAnd, + EOpAtomicCounterOr, + EOpAtomicCounterXor, + EOpAtomicCounterExchange, + EOpAtomicCounterCompSwap, + + EOpAny, + EOpAll, + + // + // Branch + // + + EOpKill, // Fragment only + EOpReturn, + EOpBreak, + EOpContinue, + EOpCase, + EOpDefault, + + // + // Constructors + // + + EOpConstructGuardStart, + EOpConstructInt, // these first scalar forms also identify what implicit conversion is needed + EOpConstructUint, + EOpConstructInt64, + EOpConstructUint64, +#ifdef AMD_EXTENSIONS + EOpConstructInt16, + EOpConstructUint16, +#endif + EOpConstructBool, + EOpConstructFloat, + EOpConstructDouble, +#ifdef AMD_EXTENSIONS + EOpConstructFloat16, +#endif + EOpConstructVec2, + EOpConstructVec3, + EOpConstructVec4, + EOpConstructDVec2, + EOpConstructDVec3, + EOpConstructDVec4, +#ifdef AMD_EXTENSIONS + EOpConstructF16Vec2, + EOpConstructF16Vec3, + EOpConstructF16Vec4, +#endif + EOpConstructBVec2, + EOpConstructBVec3, + EOpConstructBVec4, + EOpConstructIVec2, + EOpConstructIVec3, + EOpConstructIVec4, + EOpConstructUVec2, + EOpConstructUVec3, + EOpConstructUVec4, + EOpConstructI64Vec2, + EOpConstructI64Vec3, + EOpConstructI64Vec4, + EOpConstructU64Vec2, + EOpConstructU64Vec3, + EOpConstructU64Vec4, +#ifdef AMD_EXTENSIONS + EOpConstructI16Vec2, + EOpConstructI16Vec3, + EOpConstructI16Vec4, + EOpConstructU16Vec2, + EOpConstructU16Vec3, + EOpConstructU16Vec4, +#endif + EOpConstructMat2x2, + EOpConstructMat2x3, + EOpConstructMat2x4, + EOpConstructMat3x2, + EOpConstructMat3x3, + EOpConstructMat3x4, + EOpConstructMat4x2, + EOpConstructMat4x3, + EOpConstructMat4x4, + EOpConstructDMat2x2, + EOpConstructDMat2x3, + EOpConstructDMat2x4, + EOpConstructDMat3x2, + EOpConstructDMat3x3, + EOpConstructDMat3x4, + EOpConstructDMat4x2, + EOpConstructDMat4x3, + EOpConstructDMat4x4, + EOpConstructIMat2x2, + EOpConstructIMat2x3, + EOpConstructIMat2x4, + EOpConstructIMat3x2, + EOpConstructIMat3x3, + EOpConstructIMat3x4, + EOpConstructIMat4x2, + EOpConstructIMat4x3, + EOpConstructIMat4x4, + EOpConstructUMat2x2, + EOpConstructUMat2x3, + EOpConstructUMat2x4, + EOpConstructUMat3x2, + EOpConstructUMat3x3, + EOpConstructUMat3x4, + EOpConstructUMat4x2, + EOpConstructUMat4x3, + EOpConstructUMat4x4, + EOpConstructBMat2x2, + EOpConstructBMat2x3, + EOpConstructBMat2x4, + EOpConstructBMat3x2, + EOpConstructBMat3x3, + EOpConstructBMat3x4, + EOpConstructBMat4x2, + EOpConstructBMat4x3, + EOpConstructBMat4x4, +#ifdef AMD_EXTENSIONS + EOpConstructF16Mat2x2, + EOpConstructF16Mat2x3, + EOpConstructF16Mat2x4, + EOpConstructF16Mat3x2, + EOpConstructF16Mat3x3, + EOpConstructF16Mat3x4, + EOpConstructF16Mat4x2, + EOpConstructF16Mat4x3, + EOpConstructF16Mat4x4, +#endif + EOpConstructStruct, + EOpConstructTextureSampler, + EOpConstructGuardEnd, + + // + // moves + // + + EOpAssign, + EOpAddAssign, + EOpSubAssign, + EOpMulAssign, + EOpVectorTimesMatrixAssign, + EOpVectorTimesScalarAssign, + EOpMatrixTimesScalarAssign, + EOpMatrixTimesMatrixAssign, + EOpDivAssign, + EOpModAssign, + EOpAndAssign, + EOpInclusiveOrAssign, + EOpExclusiveOrAssign, + EOpLeftShiftAssign, + EOpRightShiftAssign, + + // + // Array operators + // + + EOpArrayLength, // "Array" distinguishes from length(v) built-in function, but it applies to vectors and matrices as well. + + // + // Image operations + // + + EOpImageGuardBegin, + + EOpImageQuerySize, + EOpImageQuerySamples, + EOpImageLoad, + EOpImageStore, +#ifdef AMD_EXTENSIONS + EOpImageLoadLod, + EOpImageStoreLod, +#endif + EOpImageAtomicAdd, + EOpImageAtomicMin, + EOpImageAtomicMax, + EOpImageAtomicAnd, + EOpImageAtomicOr, + EOpImageAtomicXor, + EOpImageAtomicExchange, + EOpImageAtomicCompSwap, + + EOpSubpassLoad, + EOpSubpassLoadMS, + EOpSparseImageLoad, +#ifdef AMD_EXTENSIONS + EOpSparseImageLoadLod, +#endif + + EOpImageGuardEnd, + + // + // Texture operations + // + + EOpTextureGuardBegin, + + EOpTextureQuerySize, + EOpTextureQueryLod, + EOpTextureQueryLevels, + EOpTextureQuerySamples, + + EOpSamplingGuardBegin, + + EOpTexture, + EOpTextureProj, + EOpTextureLod, + EOpTextureOffset, + EOpTextureFetch, + EOpTextureFetchOffset, + EOpTextureProjOffset, + EOpTextureLodOffset, + EOpTextureProjLod, + EOpTextureProjLodOffset, + EOpTextureGrad, + EOpTextureGradOffset, + EOpTextureProjGrad, + EOpTextureProjGradOffset, + EOpTextureGather, + EOpTextureGatherOffset, + EOpTextureGatherOffsets, + EOpTextureClamp, + EOpTextureOffsetClamp, + EOpTextureGradClamp, + EOpTextureGradOffsetClamp, +#ifdef AMD_EXTENSIONS + EOpTextureGatherLod, + EOpTextureGatherLodOffset, + EOpTextureGatherLodOffsets, + EOpFragmentMaskFetch, + EOpFragmentFetch, +#endif + + EOpSparseTextureGuardBegin, + + EOpSparseTexture, + EOpSparseTextureLod, + EOpSparseTextureOffset, + EOpSparseTextureFetch, + EOpSparseTextureFetchOffset, + EOpSparseTextureLodOffset, + EOpSparseTextureGrad, + EOpSparseTextureGradOffset, + EOpSparseTextureGather, + EOpSparseTextureGatherOffset, + EOpSparseTextureGatherOffsets, + EOpSparseTexelsResident, + EOpSparseTextureClamp, + EOpSparseTextureOffsetClamp, + EOpSparseTextureGradClamp, + EOpSparseTextureGradOffsetClamp, +#ifdef AMD_EXTENSIONS + EOpSparseTextureGatherLod, + EOpSparseTextureGatherLodOffset, + EOpSparseTextureGatherLodOffsets, +#endif + + EOpSparseTextureGuardEnd, + EOpSamplingGuardEnd, + EOpTextureGuardEnd, + + // + // Integer operations + // + + EOpAddCarry, + EOpSubBorrow, + EOpUMulExtended, + EOpIMulExtended, + EOpBitfieldExtract, + EOpBitfieldInsert, + EOpBitFieldReverse, + EOpBitCount, + EOpFindLSB, + EOpFindMSB, + + // + // HLSL operations + // + + EOpClip, // discard if input value < 0 + EOpIsFinite, + EOpLog10, // base 10 log + EOpRcp, // 1/x + EOpSaturate, // clamp from 0 to 1 + EOpSinCos, // sin and cos in out parameters + EOpGenMul, // mul(x,y) on any of mat/vec/scalars + EOpDst, // x = 1, y=src0.y * src1.y, z=src0.z, w=src1.w + EOpInterlockedAdd, // atomic ops, but uses [optional] out arg instead of return + EOpInterlockedAnd, // ... + EOpInterlockedCompareExchange, // ... + EOpInterlockedCompareStore, // ... + EOpInterlockedExchange, // ... + EOpInterlockedMax, // ... + EOpInterlockedMin, // ... + EOpInterlockedOr, // ... + EOpInterlockedXor, // ... + EOpAllMemoryBarrierWithGroupSync, // memory barriers without non-hlsl AST equivalents + EOpDeviceMemoryBarrier, // ... + EOpDeviceMemoryBarrierWithGroupSync, // ... + EOpWorkgroupMemoryBarrier, // ... + EOpWorkgroupMemoryBarrierWithGroupSync, // ... + EOpEvaluateAttributeSnapped, // InterpolateAtOffset with int position on 16x16 grid + EOpF32tof16, // HLSL conversion: half of a PackHalf2x16 + EOpF16tof32, // HLSL conversion: half of an UnpackHalf2x16 + EOpLit, // HLSL lighting coefficient vector + EOpTextureBias, // HLSL texture bias: will be lowered to EOpTexture + EOpAsDouble, // slightly different from EOpUint64BitsToDouble + EOpD3DCOLORtoUBYTE4, // convert and swizzle 4-component color to UBYTE4 range + + EOpMethodSample, // Texture object methods. These are translated to existing + EOpMethodSampleBias, // AST methods, and exist to represent HLSL semantics until that + EOpMethodSampleCmp, // translation is performed. See HlslParseContext::decomposeSampleMethods(). + EOpMethodSampleCmpLevelZero, // ... + EOpMethodSampleGrad, // ... + EOpMethodSampleLevel, // ... + EOpMethodLoad, // ... + EOpMethodGetDimensions, // ... + EOpMethodGetSamplePosition, // ... + EOpMethodGather, // ... + EOpMethodCalculateLevelOfDetail, // ... + EOpMethodCalculateLevelOfDetailUnclamped, // ... + + // Load already defined above for textures + EOpMethodLoad2, // Structure buffer object methods. These are translated to existing + EOpMethodLoad3, // AST methods, and exist to represent HLSL semantics until that + EOpMethodLoad4, // translation is performed. See HlslParseContext::decomposeSampleMethods(). + EOpMethodStore, // ... + EOpMethodStore2, // ... + EOpMethodStore3, // ... + EOpMethodStore4, // ... + EOpMethodIncrementCounter, // ... + EOpMethodDecrementCounter, // ... + // EOpMethodAppend is defined for geo shaders below + EOpMethodConsume, + + // SM5 texture methods + EOpMethodGatherRed, // These are covered under the above EOpMethodSample comment about + EOpMethodGatherGreen, // translation to existing AST opcodes. They exist temporarily + EOpMethodGatherBlue, // because HLSL arguments are slightly different. + EOpMethodGatherAlpha, // ... + EOpMethodGatherCmp, // ... + EOpMethodGatherCmpRed, // ... + EOpMethodGatherCmpGreen, // ... + EOpMethodGatherCmpBlue, // ... + EOpMethodGatherCmpAlpha, // ... + + // geometry methods + EOpMethodAppend, // Geometry shader methods + EOpMethodRestartStrip, // ... + + // matrix + EOpMatrixSwizzle, // select multiple matrix components (non-column) +}; + +class TIntermTraverser; +class TIntermOperator; +class TIntermAggregate; +class TIntermUnary; +class TIntermBinary; +class TIntermConstantUnion; +class TIntermSelection; +class TIntermSwitch; +class TIntermBranch; +class TIntermTyped; +class TIntermMethod; +class TIntermSymbol; +class TIntermLoop; + +} // end namespace glslang + +// +// Base class for the tree nodes +// +// (Put outside the glslang namespace, as it's used as part of the external interface.) +// +class TIntermNode { +public: + POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator()) + + TIntermNode() { loc.init(); } + virtual const glslang::TSourceLoc& getLoc() const { return loc; } + virtual void setLoc(const glslang::TSourceLoc& l) { loc = l; } + virtual void traverse(glslang::TIntermTraverser*) = 0; + virtual glslang::TIntermTyped* getAsTyped() { return 0; } + virtual glslang::TIntermOperator* getAsOperator() { return 0; } + virtual glslang::TIntermConstantUnion* getAsConstantUnion() { return 0; } + virtual glslang::TIntermAggregate* getAsAggregate() { return 0; } + virtual glslang::TIntermUnary* getAsUnaryNode() { return 0; } + virtual glslang::TIntermBinary* getAsBinaryNode() { return 0; } + virtual glslang::TIntermSelection* getAsSelectionNode() { return 0; } + virtual glslang::TIntermSwitch* getAsSwitchNode() { return 0; } + virtual glslang::TIntermMethod* getAsMethodNode() { return 0; } + virtual glslang::TIntermSymbol* getAsSymbolNode() { return 0; } + virtual glslang::TIntermBranch* getAsBranchNode() { return 0; } + virtual glslang::TIntermLoop* getAsLoopNode() { return 0; } + + virtual const glslang::TIntermTyped* getAsTyped() const { return 0; } + virtual const glslang::TIntermOperator* getAsOperator() const { return 0; } + virtual const glslang::TIntermConstantUnion* getAsConstantUnion() const { return 0; } + virtual const glslang::TIntermAggregate* getAsAggregate() const { return 0; } + virtual const glslang::TIntermUnary* getAsUnaryNode() const { return 0; } + virtual const glslang::TIntermBinary* getAsBinaryNode() const { return 0; } + virtual const glslang::TIntermSelection* getAsSelectionNode() const { return 0; } + virtual const glslang::TIntermSwitch* getAsSwitchNode() const { return 0; } + virtual const glslang::TIntermMethod* getAsMethodNode() const { return 0; } + virtual const glslang::TIntermSymbol* getAsSymbolNode() const { return 0; } + virtual const glslang::TIntermBranch* getAsBranchNode() const { return 0; } + virtual const glslang::TIntermLoop* getAsLoopNode() const { return 0; } + virtual ~TIntermNode() { } + +protected: + TIntermNode(const TIntermNode&); + TIntermNode& operator=(const TIntermNode&); + glslang::TSourceLoc loc; +}; + +namespace glslang { + +// +// This is just to help yacc. +// +struct TIntermNodePair { + TIntermNode* node1; + TIntermNode* node2; +}; + +// +// Intermediate class for nodes that have a type. +// +class TIntermTyped : public TIntermNode { +public: + TIntermTyped(const TType& t) { type.shallowCopy(t); } + TIntermTyped(TBasicType basicType) { TType bt(basicType); type.shallowCopy(bt); } + virtual TIntermTyped* getAsTyped() { return this; } + virtual const TIntermTyped* getAsTyped() const { return this; } + virtual void setType(const TType& t) { type.shallowCopy(t); } + virtual const TType& getType() const { return type; } + virtual TType& getWritableType() { return type; } + + virtual TBasicType getBasicType() const { return type.getBasicType(); } + virtual TQualifier& getQualifier() { return type.getQualifier(); } + virtual const TQualifier& getQualifier() const { return type.getQualifier(); } + virtual void propagatePrecision(TPrecisionQualifier); + virtual int getVectorSize() const { return type.getVectorSize(); } + virtual int getMatrixCols() const { return type.getMatrixCols(); } + virtual int getMatrixRows() const { return type.getMatrixRows(); } + virtual bool isMatrix() const { return type.isMatrix(); } + virtual bool isArray() const { return type.isArray(); } + virtual bool isVector() const { return type.isVector(); } + virtual bool isScalar() const { return type.isScalar(); } + virtual bool isStruct() const { return type.isStruct(); } + virtual bool isFloatingDomain() const { return type.isFloatingDomain(); } + virtual bool isIntegerDomain() const { return type.isIntegerDomain(); } + TString getCompleteString() const { return type.getCompleteString(); } + +protected: + TIntermTyped& operator=(const TIntermTyped&); + TType type; +}; + +// +// Selection control hints +// +enum TSelectionControl { + ESelectionControlNone, + ESelectionControlFlatten, + ESelectionControlDontFlatten, +}; + +// +// Loop control hints +// +enum TLoopControl { + ELoopControlNone, + ELoopControlUnroll, + ELoopControlDontUnroll, +}; + +// +// Handle for, do-while, and while loops. +// +class TIntermLoop : public TIntermNode { +public: + TIntermLoop(TIntermNode* aBody, TIntermTyped* aTest, TIntermTyped* aTerminal, bool testFirst) : + body(aBody), + test(aTest), + terminal(aTerminal), + first(testFirst), + control(ELoopControlNone) + { } + + virtual TIntermLoop* getAsLoopNode() { return this; } + virtual const TIntermLoop* getAsLoopNode() const { return this; } + virtual void traverse(TIntermTraverser*); + TIntermNode* getBody() const { return body; } + TIntermTyped* getTest() const { return test; } + TIntermTyped* getTerminal() const { return terminal; } + bool testFirst() const { return first; } + + void setLoopControl(TLoopControl c) { control = c; } + TLoopControl getLoopControl() const { return control; } + +protected: + TIntermNode* body; // code to loop over + TIntermTyped* test; // exit condition associated with loop, could be 0 for 'for' loops + TIntermTyped* terminal; // exists for for-loops + bool first; // true for while and for, not for do-while + TLoopControl control; // loop control hint +}; + +// +// Handle case, break, continue, return, and kill. +// +class TIntermBranch : public TIntermNode { +public: + TIntermBranch(TOperator op, TIntermTyped* e) : + flowOp(op), + expression(e) { } + virtual TIntermBranch* getAsBranchNode() { return this; } + virtual const TIntermBranch* getAsBranchNode() const { return this; } + virtual void traverse(TIntermTraverser*); + TOperator getFlowOp() const { return flowOp; } + TIntermTyped* getExpression() const { return expression; } +protected: + TOperator flowOp; + TIntermTyped* expression; +}; + +// +// Represent method names before seeing their calling signature +// or resolving them to operations. Just an expression as the base object +// and a textural name. +// +class TIntermMethod : public TIntermTyped { +public: + TIntermMethod(TIntermTyped* o, const TType& t, const TString& m) : TIntermTyped(t), object(o), method(m) { } + virtual TIntermMethod* getAsMethodNode() { return this; } + virtual const TIntermMethod* getAsMethodNode() const { return this; } + virtual const TString& getMethodName() const { return method; } + virtual TIntermTyped* getObject() const { return object; } + virtual void traverse(TIntermTraverser*); +protected: + TIntermTyped* object; + TString method; +}; + +// +// Nodes that correspond to symbols or constants in the source code. +// +class TIntermSymbol : public TIntermTyped { +public: + // if symbol is initialized as symbol(sym), the memory comes from the pool allocator of sym. If sym comes from + // per process threadPoolAllocator, then it causes increased memory usage per compile + // it is essential to use "symbol = sym" to assign to symbol + TIntermSymbol(int i, const TString& n, const TType& t) + : TIntermTyped(t), id(i), +#ifdef ENABLE_HLSL + flattenSubset(-1), +#endif + constSubtree(nullptr) + { name = n; } + virtual int getId() const { return id; } + virtual const TString& getName() const { return name; } + virtual void traverse(TIntermTraverser*); + virtual TIntermSymbol* getAsSymbolNode() { return this; } + virtual const TIntermSymbol* getAsSymbolNode() const { return this; } + void setConstArray(const TConstUnionArray& c) { constArray = c; } + const TConstUnionArray& getConstArray() const { return constArray; } + void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; } + TIntermTyped* getConstSubtree() const { return constSubtree; } +#ifdef ENABLE_HLSL + void setFlattenSubset(int subset) { flattenSubset = subset; } + int getFlattenSubset() const { return flattenSubset; } // -1 means full object +#endif + + // This is meant for cases where a node has already been constructed, and + // later on, it becomes necessary to switch to a different symbol. + virtual void switchId(int newId) { id = newId; } + +protected: + int id; // the unique id of the symbol this node represents +#ifdef ENABLE_HLSL + int flattenSubset; // how deeply the flattened object rooted at id has been dereferenced +#endif + TString name; // the name of the symbol this node represents + TConstUnionArray constArray; // if the symbol is a front-end compile-time constant, this is its value + TIntermTyped* constSubtree; +}; + +class TIntermConstantUnion : public TIntermTyped { +public: + TIntermConstantUnion(const TConstUnionArray& ua, const TType& t) : TIntermTyped(t), constArray(ua), literal(false) { } + const TConstUnionArray& getConstArray() const { return constArray; } + virtual TIntermConstantUnion* getAsConstantUnion() { return this; } + virtual const TIntermConstantUnion* getAsConstantUnion() const { return this; } + virtual void traverse(TIntermTraverser*); + virtual TIntermTyped* fold(TOperator, const TIntermTyped*) const; + virtual TIntermTyped* fold(TOperator, const TType&) const; + void setLiteral() { literal = true; } + void setExpression() { literal = false; } + bool isLiteral() const { return literal; } + +protected: + TIntermConstantUnion& operator=(const TIntermConstantUnion&); + + const TConstUnionArray constArray; + bool literal; // true if node represents a literal in the source code +}; + +// Represent the independent aspects of a texturing TOperator +struct TCrackedTextureOp { + bool query; + bool proj; + bool lod; + bool fetch; + bool offset; + bool offsets; + bool gather; + bool grad; + bool subpass; + bool lodClamp; +#ifdef AMD_EXTENSIONS + bool fragMask; +#endif +}; + +// +// Intermediate class for node types that hold operators. +// +class TIntermOperator : public TIntermTyped { +public: + virtual TIntermOperator* getAsOperator() { return this; } + virtual const TIntermOperator* getAsOperator() const { return this; } + TOperator getOp() const { return op; } + void setOp(TOperator newOp) { op = newOp; } + bool modifiesState() const; + bool isConstructor() const; + bool isTexture() const { return op > EOpTextureGuardBegin && op < EOpTextureGuardEnd; } + bool isSampling() const { return op > EOpSamplingGuardBegin && op < EOpSamplingGuardEnd; } + bool isImage() const { return op > EOpImageGuardBegin && op < EOpImageGuardEnd; } + bool isSparseTexture() const { return op > EOpSparseTextureGuardBegin && op < EOpSparseTextureGuardEnd; } + bool isSparseImage() const { return op == EOpSparseImageLoad; } + + void setOperationPrecision(TPrecisionQualifier p) { operationPrecision = p; } + TPrecisionQualifier getOperationPrecision() const { return operationPrecision != EpqNone ? + operationPrecision : + type.getQualifier().precision; } + TString getCompleteString() const + { + TString cs = type.getCompleteString(); + if (getOperationPrecision() != type.getQualifier().precision) { + cs += ", operation at "; + cs += GetPrecisionQualifierString(getOperationPrecision()); + } + + return cs; + } + + // Crack the op into the individual dimensions of texturing operation. + void crackTexture(TSampler sampler, TCrackedTextureOp& cracked) const + { + cracked.query = false; + cracked.proj = false; + cracked.lod = false; + cracked.fetch = false; + cracked.offset = false; + cracked.offsets = false; + cracked.gather = false; + cracked.grad = false; + cracked.subpass = false; + cracked.lodClamp = false; +#ifdef AMD_EXTENSIONS + cracked.fragMask = false; +#endif + + switch (op) { + case EOpImageQuerySize: + case EOpImageQuerySamples: + case EOpTextureQuerySize: + case EOpTextureQueryLod: + case EOpTextureQueryLevels: + case EOpTextureQuerySamples: + case EOpSparseTexelsResident: + cracked.query = true; + break; + case EOpTexture: + case EOpSparseTexture: + break; + case EOpTextureClamp: + case EOpSparseTextureClamp: + cracked.lodClamp = true; + break; + case EOpTextureProj: + cracked.proj = true; + break; + case EOpTextureLod: + case EOpSparseTextureLod: + cracked.lod = true; + break; + case EOpTextureOffset: + case EOpSparseTextureOffset: + cracked.offset = true; + break; + case EOpTextureOffsetClamp: + case EOpSparseTextureOffsetClamp: + cracked.offset = true; + cracked.lodClamp = true; + break; + case EOpTextureFetch: + case EOpSparseTextureFetch: + cracked.fetch = true; + if (sampler.dim == Esd1D || (sampler.dim == Esd2D && ! sampler.ms) || sampler.dim == Esd3D) + cracked.lod = true; + break; + case EOpTextureFetchOffset: + case EOpSparseTextureFetchOffset: + cracked.fetch = true; + cracked.offset = true; + if (sampler.dim == Esd1D || (sampler.dim == Esd2D && ! sampler.ms) || sampler.dim == Esd3D) + cracked.lod = true; + break; + case EOpTextureProjOffset: + cracked.offset = true; + cracked.proj = true; + break; + case EOpTextureLodOffset: + case EOpSparseTextureLodOffset: + cracked.offset = true; + cracked.lod = true; + break; + case EOpTextureProjLod: + cracked.lod = true; + cracked.proj = true; + break; + case EOpTextureProjLodOffset: + cracked.offset = true; + cracked.lod = true; + cracked.proj = true; + break; + case EOpTextureGrad: + case EOpSparseTextureGrad: + cracked.grad = true; + break; + case EOpTextureGradClamp: + case EOpSparseTextureGradClamp: + cracked.grad = true; + cracked.lodClamp = true; + break; + case EOpTextureGradOffset: + case EOpSparseTextureGradOffset: + cracked.grad = true; + cracked.offset = true; + break; + case EOpTextureProjGrad: + cracked.grad = true; + cracked.proj = true; + break; + case EOpTextureProjGradOffset: + cracked.grad = true; + cracked.offset = true; + cracked.proj = true; + break; + case EOpTextureGradOffsetClamp: + case EOpSparseTextureGradOffsetClamp: + cracked.grad = true; + cracked.offset = true; + cracked.lodClamp = true; + break; + case EOpTextureGather: + case EOpSparseTextureGather: + cracked.gather = true; + break; + case EOpTextureGatherOffset: + case EOpSparseTextureGatherOffset: + cracked.gather = true; + cracked.offset = true; + break; + case EOpTextureGatherOffsets: + case EOpSparseTextureGatherOffsets: + cracked.gather = true; + cracked.offsets = true; + break; +#ifdef AMD_EXTENSIONS + case EOpTextureGatherLod: + case EOpSparseTextureGatherLod: + cracked.gather = true; + cracked.lod = true; + break; + case EOpTextureGatherLodOffset: + case EOpSparseTextureGatherLodOffset: + cracked.gather = true; + cracked.offset = true; + cracked.lod = true; + break; + case EOpTextureGatherLodOffsets: + case EOpSparseTextureGatherLodOffsets: + cracked.gather = true; + cracked.offsets = true; + cracked.lod = true; + break; + case EOpImageLoadLod: + case EOpImageStoreLod: + case EOpSparseImageLoadLod: + cracked.lod = true; + break; + case EOpFragmentMaskFetch: + cracked.subpass = sampler.dim == EsdSubpass; + cracked.fragMask = true; + break; + case EOpFragmentFetch: + cracked.subpass = sampler.dim == EsdSubpass; + cracked.fragMask = true; + break; +#endif + case EOpSubpassLoad: + case EOpSubpassLoadMS: + cracked.subpass = true; + break; + default: + break; + } + } + +protected: + TIntermOperator(TOperator o) : TIntermTyped(EbtFloat), op(o), operationPrecision(EpqNone) {} + TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o), operationPrecision(EpqNone) {} + TOperator op; + // The result precision is in the inherited TType, and is usually meant to be both + // the operation precision and the result precision. However, some more complex things, + // like built-in function calls, distinguish between the two, in which case non-EqpNone + // 'operationPrecision' overrides the result precision as far as operation precision + // is concerned. + TPrecisionQualifier operationPrecision; +}; + +// +// Nodes for all the basic binary math operators. +// +class TIntermBinary : public TIntermOperator { +public: + TIntermBinary(TOperator o) : TIntermOperator(o) {} + virtual void traverse(TIntermTraverser*); + virtual void setLeft(TIntermTyped* n) { left = n; } + virtual void setRight(TIntermTyped* n) { right = n; } + virtual TIntermTyped* getLeft() const { return left; } + virtual TIntermTyped* getRight() const { return right; } + virtual TIntermBinary* getAsBinaryNode() { return this; } + virtual const TIntermBinary* getAsBinaryNode() const { return this; } + virtual void updatePrecision(); +protected: + TIntermTyped* left; + TIntermTyped* right; +}; + +// +// Nodes for unary math operators. +// +class TIntermUnary : public TIntermOperator { +public: + TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0) {} + TIntermUnary(TOperator o) : TIntermOperator(o), operand(0) {} + virtual void traverse(TIntermTraverser*); + virtual void setOperand(TIntermTyped* o) { operand = o; } + virtual TIntermTyped* getOperand() { return operand; } + virtual const TIntermTyped* getOperand() const { return operand; } + virtual TIntermUnary* getAsUnaryNode() { return this; } + virtual const TIntermUnary* getAsUnaryNode() const { return this; } + virtual void updatePrecision(); +protected: + TIntermTyped* operand; +}; + +typedef TVector TIntermSequence; +typedef TVector TQualifierList; +// +// Nodes that operate on an arbitrary sized set of children. +// +class TIntermAggregate : public TIntermOperator { +public: + TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(nullptr) { } + TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(nullptr) { } + ~TIntermAggregate() { delete pragmaTable; } + virtual TIntermAggregate* getAsAggregate() { return this; } + virtual const TIntermAggregate* getAsAggregate() const { return this; } + virtual void setOperator(TOperator o) { op = o; } + virtual TIntermSequence& getSequence() { return sequence; } + virtual const TIntermSequence& getSequence() const { return sequence; } + virtual void setName(const TString& n) { name = n; } + virtual const TString& getName() const { return name; } + virtual void traverse(TIntermTraverser*); + virtual void setUserDefined() { userDefined = true; } + virtual bool isUserDefined() { return userDefined; } + virtual TQualifierList& getQualifierList() { return qualifier; } + virtual const TQualifierList& getQualifierList() const { return qualifier; } + void setOptimize(bool o) { optimize = o; } + void setDebug(bool d) { debug = d; } + bool getOptimize() const { return optimize; } + bool getDebug() const { return debug; } + void setPragmaTable(const TPragmaTable& pTable); + const TPragmaTable& getPragmaTable() const { return *pragmaTable; } +protected: + TIntermAggregate(const TIntermAggregate&); // disallow copy constructor + TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator + TIntermSequence sequence; + TQualifierList qualifier; + TString name; + bool userDefined; // used for user defined function names + bool optimize; + bool debug; + TPragmaTable* pragmaTable; +}; + +// +// For if tests. +// +class TIntermSelection : public TIntermTyped { +public: + TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) : + TIntermTyped(EbtVoid), condition(cond), trueBlock(trueB), falseBlock(falseB), control(ESelectionControlNone) {} + TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) : + TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB), control(ESelectionControlNone) {} + virtual void traverse(TIntermTraverser*); + virtual TIntermTyped* getCondition() const { return condition; } + virtual TIntermNode* getTrueBlock() const { return trueBlock; } + virtual TIntermNode* getFalseBlock() const { return falseBlock; } + virtual TIntermSelection* getAsSelectionNode() { return this; } + virtual const TIntermSelection* getAsSelectionNode() const { return this; } + void setSelectionControl(TSelectionControl c) { control = c; } + TSelectionControl getSelectionControl() const { return control; } +protected: + TIntermTyped* condition; + TIntermNode* trueBlock; + TIntermNode* falseBlock; + TSelectionControl control; // selection control hint +}; + +// +// For switch statements. Designed use is that a switch will have sequence of nodes +// that are either case/default nodes or a *single* node that represents all the code +// in between (if any) consecutive case/defaults. So, a traversal need only deal with +// 0 or 1 nodes per case/default statement. +// +class TIntermSwitch : public TIntermNode { +public: + TIntermSwitch(TIntermTyped* cond, TIntermAggregate* b) : condition(cond), body(b), control(ESelectionControlNone) { } + virtual void traverse(TIntermTraverser*); + virtual TIntermNode* getCondition() const { return condition; } + virtual TIntermAggregate* getBody() const { return body; } + virtual TIntermSwitch* getAsSwitchNode() { return this; } + virtual const TIntermSwitch* getAsSwitchNode() const { return this; } + void setSelectionControl(TSelectionControl c) { control = c; } + TSelectionControl getSelectionControl() const { return control; } +protected: + TIntermTyped* condition; + TIntermAggregate* body; + TSelectionControl control; // selection control hint +}; + +enum TVisit +{ + EvPreVisit, + EvInVisit, + EvPostVisit +}; + +// +// For traversing the tree. User should derive from this, +// put their traversal specific data in it, and then pass +// it to a Traverse method. +// +// When using this, just fill in the methods for nodes you want visited. +// Return false from a pre-visit to skip visiting that node's subtree. +// +// Explicitly set postVisit to true if you want post visiting, otherwise, +// filled in methods will only be called at pre-visit time (before processing +// the subtree). Similarly for inVisit for in-order visiting of nodes with +// multiple children. +// +// If you only want post-visits, explicitly turn off preVisit (and inVisit) +// and turn on postVisit. +// +// In general, for the visit*() methods, return true from interior nodes +// to have the traversal continue on to children. +// +// If you process children yourself, or don't want them processed, return false. +// +class TIntermTraverser { +public: + POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator()) + TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) : + preVisit(preVisit), + inVisit(inVisit), + postVisit(postVisit), + rightToLeft(rightToLeft), + depth(0), + maxDepth(0) { } + virtual ~TIntermTraverser() { } + + virtual void visitSymbol(TIntermSymbol*) { } + virtual void visitConstantUnion(TIntermConstantUnion*) { } + virtual bool visitBinary(TVisit, TIntermBinary*) { return true; } + virtual bool visitUnary(TVisit, TIntermUnary*) { return true; } + virtual bool visitSelection(TVisit, TIntermSelection*) { return true; } + virtual bool visitAggregate(TVisit, TIntermAggregate*) { return true; } + virtual bool visitLoop(TVisit, TIntermLoop*) { return true; } + virtual bool visitBranch(TVisit, TIntermBranch*) { return true; } + virtual bool visitSwitch(TVisit, TIntermSwitch*) { return true; } + + int getMaxDepth() const { return maxDepth; } + + void incrementDepth(TIntermNode *current) + { + depth++; + maxDepth = (std::max)(maxDepth, depth); + path.push_back(current); + } + + void decrementDepth() + { + depth--; + path.pop_back(); + } + + TIntermNode *getParentNode() + { + return path.size() == 0 ? NULL : path.back(); + } + + const bool preVisit; + const bool inVisit; + const bool postVisit; + const bool rightToLeft; + +protected: + TIntermTraverser& operator=(TIntermTraverser&); + + int depth; + int maxDepth; + + // All the nodes from root to the current node's parent during traversing. + TVector path; +}; + +// KHR_vulkan_glsl says "Two arrays sized with specialization constants are the same type only if +// sized with the same symbol, involving no operations" +inline bool SameSpecializationConstants(TIntermTyped* node1, TIntermTyped* node2) +{ + return node1->getAsSymbolNode() && node2->getAsSymbolNode() && + node1->getAsSymbolNode()->getId() == node2->getAsSymbolNode()->getId(); +} + +} // end namespace glslang + +#endif // __INTERMEDIATE_H diff --git a/love/src/jni/love/src/libraries/glslang/glslang/Include/revision.h b/love/src/jni/love/src/libraries/glslang/glslang/Include/revision.h new file mode 100644 index 00000000..218f8b67 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/Include/revision.h @@ -0,0 +1,6 @@ +// This header is generated by the make-revision script. +// For the version, it uses the latest git tag followed by the number of commits. +// For the date, it uses the current date (when then script is run). + +#define GLSLANG_REVISION "Overload400-PrecQual.2000" +#define GLSLANG_DATE "12-Apr-2017" diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/Constant.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/Constant.cpp new file mode 100644 index 00000000..1b73d969 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/Constant.cpp @@ -0,0 +1,1053 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2012-2013 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#include "localintermediate.h" +#include +#include +#include +#include + +namespace { + +using namespace glslang; + +typedef union { + double d; + int i[2]; +} DoubleIntUnion; + +// Some helper functions + +bool isNan(double x) +{ + DoubleIntUnion u; + // tough to find a platform independent library function, do it directly + u.d = x; + int bitPatternL = u.i[0]; + int bitPatternH = u.i[1]; + return (bitPatternH & 0x7ff80000) == 0x7ff80000 && + ((bitPatternH & 0xFFFFF) != 0 || bitPatternL != 0); +} + +bool isInf(double x) +{ + DoubleIntUnion u; + // tough to find a platform independent library function, do it directly + u.d = x; + int bitPatternL = u.i[0]; + int bitPatternH = u.i[1]; + return (bitPatternH & 0x7ff00000) == 0x7ff00000 && + (bitPatternH & 0xFFFFF) == 0 && bitPatternL == 0; +} + +const double pi = 3.1415926535897932384626433832795; + +} // end anonymous namespace + + +namespace glslang { + +// +// The fold functions see if an operation on a constant can be done in place, +// without generating run-time code. +// +// Returns the node to keep using, which may or may not be the node passed in. +// +// Note: As of version 1.2, all constant operations must be folded. It is +// not opportunistic, but rather a semantic requirement. +// + +// +// Do folding between a pair of nodes. +// 'this' is the left-hand operand and 'rightConstantNode' is the right-hand operand. +// +// Returns a new node representing the result. +// +TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* rightConstantNode) const +{ + // For most cases, the return type matches the argument type, so set that + // up and just code to exceptions below. + TType returnType; + returnType.shallowCopy(getType()); + + // + // A pair of nodes is to be folded together + // + + const TIntermConstantUnion *rightNode = rightConstantNode->getAsConstantUnion(); + TConstUnionArray leftUnionArray = getConstArray(); + TConstUnionArray rightUnionArray = rightNode->getConstArray(); + + // Figure out the size of the result + int newComps; + int constComps; + switch(op) { + case EOpMatrixTimesMatrix: + newComps = rightNode->getMatrixCols() * getMatrixRows(); + break; + case EOpMatrixTimesVector: + newComps = getMatrixRows(); + break; + case EOpVectorTimesMatrix: + newComps = rightNode->getMatrixCols(); + break; + default: + newComps = getType().computeNumComponents(); + constComps = rightConstantNode->getType().computeNumComponents(); + if (constComps == 1 && newComps > 1) { + // for a case like vec4 f = vec4(2,3,4,5) + 1.2; + TConstUnionArray smearedArray(newComps, rightNode->getConstArray()[0]); + rightUnionArray = smearedArray; + } else if (constComps > 1 && newComps == 1) { + // for a case like vec4 f = 1.2 + vec4(2,3,4,5); + newComps = constComps; + rightUnionArray = rightNode->getConstArray(); + TConstUnionArray smearedArray(newComps, getConstArray()[0]); + leftUnionArray = smearedArray; + returnType.shallowCopy(rightNode->getType()); + } + break; + } + + TConstUnionArray newConstArray(newComps); + TType constBool(EbtBool, EvqConst); + + switch(op) { + case EOpAdd: + for (int i = 0; i < newComps; i++) + newConstArray[i] = leftUnionArray[i] + rightUnionArray[i]; + break; + case EOpSub: + for (int i = 0; i < newComps; i++) + newConstArray[i] = leftUnionArray[i] - rightUnionArray[i]; + break; + + case EOpMul: + case EOpVectorTimesScalar: + case EOpMatrixTimesScalar: + for (int i = 0; i < newComps; i++) + newConstArray[i] = leftUnionArray[i] * rightUnionArray[i]; + break; + case EOpMatrixTimesMatrix: + for (int row = 0; row < getMatrixRows(); row++) { + for (int column = 0; column < rightNode->getMatrixCols(); column++) { + double sum = 0.0f; + for (int i = 0; i < rightNode->getMatrixRows(); i++) + sum += leftUnionArray[i * getMatrixRows() + row].getDConst() * rightUnionArray[column * rightNode->getMatrixRows() + i].getDConst(); + newConstArray[column * getMatrixRows() + row].setDConst(sum); + } + } + returnType.shallowCopy(TType(getType().getBasicType(), EvqConst, 0, rightNode->getMatrixCols(), getMatrixRows())); + break; + case EOpDiv: + for (int i = 0; i < newComps; i++) { + switch (getType().getBasicType()) { + case EbtDouble: + case EbtFloat: +#ifdef AMD_EXTENSIONS + case EbtFloat16: +#endif + newConstArray[i].setDConst(leftUnionArray[i].getDConst() / rightUnionArray[i].getDConst()); + break; + + case EbtInt: + if (rightUnionArray[i] == 0) + newConstArray[i].setIConst(0x7FFFFFFF); + else if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == (int)0x80000000) + newConstArray[i].setIConst(0x80000000); + else + newConstArray[i].setIConst(leftUnionArray[i].getIConst() / rightUnionArray[i].getIConst()); + break; + + case EbtUint: + if (rightUnionArray[i] == 0) { + newConstArray[i].setUConst(0xFFFFFFFFu); + } else + newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst()); + break; + + case EbtInt64: + if (rightUnionArray[i] == 0) + newConstArray[i].setI64Const(0x7FFFFFFFFFFFFFFFll); + else if (rightUnionArray[i].getI64Const() == -1 && leftUnionArray[i].getI64Const() == (long long)0x8000000000000000) + newConstArray[i].setI64Const(0x8000000000000000); + else + newConstArray[i].setI64Const(leftUnionArray[i].getI64Const() / rightUnionArray[i].getI64Const()); + break; + + case EbtUint64: + if (rightUnionArray[i] == 0) { + newConstArray[i].setU64Const(0xFFFFFFFFFFFFFFFFull); + } else + newConstArray[i].setU64Const(leftUnionArray[i].getU64Const() / rightUnionArray[i].getU64Const()); + break; +#ifdef AMD_EXTENSIONS + case EbtInt16: + if (rightUnionArray[i] == 0) + newConstArray[i].setIConst(0x7FFF); + else if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == (int)0x8000) + newConstArray[i].setIConst(0x8000); + else + newConstArray[i].setIConst(leftUnionArray[i].getIConst() / rightUnionArray[i].getIConst()); + break; + + case EbtUint16: + if (rightUnionArray[i] == 0) { + newConstArray[i].setUConst(0xFFFFu); + } else + newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst()); + break; +#endif + default: + return 0; + } + } + break; + + case EOpMatrixTimesVector: + for (int i = 0; i < getMatrixRows(); i++) { + double sum = 0.0f; + for (int j = 0; j < rightNode->getVectorSize(); j++) { + sum += leftUnionArray[j*getMatrixRows() + i].getDConst() * rightUnionArray[j].getDConst(); + } + newConstArray[i].setDConst(sum); + } + + returnType.shallowCopy(TType(getBasicType(), EvqConst, getMatrixRows())); + break; + + case EOpVectorTimesMatrix: + for (int i = 0; i < rightNode->getMatrixCols(); i++) { + double sum = 0.0f; + for (int j = 0; j < getVectorSize(); j++) + sum += leftUnionArray[j].getDConst() * rightUnionArray[i*rightNode->getMatrixRows() + j].getDConst(); + newConstArray[i].setDConst(sum); + } + + returnType.shallowCopy(TType(getBasicType(), EvqConst, rightNode->getMatrixCols())); + break; + + case EOpMod: + for (int i = 0; i < newComps; i++) { + if (rightUnionArray[i] == 0) + newConstArray[i] = leftUnionArray[i]; + else { + switch (getType().getBasicType()) { + case EbtInt: + if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == INT_MIN) { + newConstArray[i].setIConst(0); + break; + } else goto modulo_default; + + case EbtInt64: + if (rightUnionArray[i].getI64Const() == -1 && leftUnionArray[i].getI64Const() == LLONG_MIN) { + newConstArray[i].setI64Const(0); + break; + } else goto modulo_default; +#ifdef AMD_EXTENSIONS + case EbtInt16: + if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == SHRT_MIN) { + newConstArray[i].setIConst(0); + break; + } else goto modulo_default; +#endif + default: + modulo_default: + newConstArray[i] = leftUnionArray[i] % rightUnionArray[i]; + } + } + } + break; + + case EOpRightShift: + for (int i = 0; i < newComps; i++) + newConstArray[i] = leftUnionArray[i] >> rightUnionArray[i]; + break; + + case EOpLeftShift: + for (int i = 0; i < newComps; i++) + newConstArray[i] = leftUnionArray[i] << rightUnionArray[i]; + break; + + case EOpAnd: + for (int i = 0; i < newComps; i++) + newConstArray[i] = leftUnionArray[i] & rightUnionArray[i]; + break; + case EOpInclusiveOr: + for (int i = 0; i < newComps; i++) + newConstArray[i] = leftUnionArray[i] | rightUnionArray[i]; + break; + case EOpExclusiveOr: + for (int i = 0; i < newComps; i++) + newConstArray[i] = leftUnionArray[i] ^ rightUnionArray[i]; + break; + + case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently + for (int i = 0; i < newComps; i++) + newConstArray[i] = leftUnionArray[i] && rightUnionArray[i]; + break; + + case EOpLogicalOr: // this code is written for possible future use, will not get executed currently + for (int i = 0; i < newComps; i++) + newConstArray[i] = leftUnionArray[i] || rightUnionArray[i]; + break; + + case EOpLogicalXor: + for (int i = 0; i < newComps; i++) { + switch (getType().getBasicType()) { + case EbtBool: newConstArray[i].setBConst((leftUnionArray[i] == rightUnionArray[i]) ? false : true); break; + default: assert(false && "Default missing"); + } + } + break; + + case EOpLessThan: + newConstArray[0].setBConst(leftUnionArray[0] < rightUnionArray[0]); + returnType.shallowCopy(constBool); + break; + case EOpGreaterThan: + newConstArray[0].setBConst(leftUnionArray[0] > rightUnionArray[0]); + returnType.shallowCopy(constBool); + break; + case EOpLessThanEqual: + newConstArray[0].setBConst(! (leftUnionArray[0] > rightUnionArray[0])); + returnType.shallowCopy(constBool); + break; + case EOpGreaterThanEqual: + newConstArray[0].setBConst(! (leftUnionArray[0] < rightUnionArray[0])); + returnType.shallowCopy(constBool); + break; + case EOpEqual: + newConstArray[0].setBConst(rightNode->getConstArray() == leftUnionArray); + returnType.shallowCopy(constBool); + break; + case EOpNotEqual: + newConstArray[0].setBConst(rightNode->getConstArray() != leftUnionArray); + returnType.shallowCopy(constBool); + break; + + default: + return 0; + } + + TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, returnType); + newNode->setLoc(getLoc()); + + return newNode; +} + +// +// Do single unary node folding +// +// Returns a new node representing the result. +// +TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) const +{ + // First, size the result, which is mostly the same as the argument's size, + // but not always, and classify what is componentwise. + // Also, eliminate cases that can't be compile-time constant. + int resultSize; + bool componentWise = true; + + int objectSize = getType().computeNumComponents(); + switch (op) { + case EOpDeterminant: + case EOpAny: + case EOpAll: + case EOpLength: + componentWise = false; + resultSize = 1; + break; + + case EOpEmitStreamVertex: + case EOpEndStreamPrimitive: + // These don't actually fold + return 0; + + case EOpPackSnorm2x16: + case EOpPackUnorm2x16: + case EOpPackHalf2x16: + componentWise = false; + resultSize = 1; + break; + + case EOpUnpackSnorm2x16: + case EOpUnpackUnorm2x16: + case EOpUnpackHalf2x16: + componentWise = false; + resultSize = 2; + break; + + case EOpNormalize: + componentWise = false; + resultSize = objectSize; + break; + + default: + resultSize = objectSize; + break; + } + + // Set up for processing + TConstUnionArray newConstArray(resultSize); + const TConstUnionArray& unionArray = getConstArray(); + + // Process non-component-wise operations + switch (op) { + case EOpLength: + case EOpNormalize: + { + double sum = 0; + for (int i = 0; i < objectSize; i++) + sum += unionArray[i].getDConst() * unionArray[i].getDConst(); + double length = sqrt(sum); + if (op == EOpLength) + newConstArray[0].setDConst(length); + else { + for (int i = 0; i < objectSize; i++) + newConstArray[i].setDConst(unionArray[i].getDConst() / length); + } + break; + } + + case EOpAny: + { + bool result = false; + for (int i = 0; i < objectSize; i++) { + if (unionArray[i].getBConst()) + result = true; + } + newConstArray[0].setBConst(result); + break; + } + case EOpAll: + { + bool result = true; + for (int i = 0; i < objectSize; i++) { + if (! unionArray[i].getBConst()) + result = false; + } + newConstArray[0].setBConst(result); + break; + } + + // TODO: 3.0 Functionality: unary constant folding: the rest of the ops have to be fleshed out + + case EOpPackSnorm2x16: + case EOpPackUnorm2x16: + case EOpPackHalf2x16: + + case EOpUnpackSnorm2x16: + case EOpUnpackUnorm2x16: + case EOpUnpackHalf2x16: + + case EOpDeterminant: + case EOpMatrixInverse: + case EOpTranspose: + return 0; + + default: + assert(componentWise); + break; + } + + // Turn off the componentwise loop + if (! componentWise) + objectSize = 0; + + // Process component-wise operations + for (int i = 0; i < objectSize; i++) { + switch (op) { + case EOpNegative: + switch (getType().getBasicType()) { + case EbtDouble: +#ifdef AMD_EXTENSIONS + case EbtFloat16: +#endif + case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break; +#ifdef AMD_EXTENSIONS + case EbtInt16: +#endif + case EbtInt: newConstArray[i].setIConst(-unionArray[i].getIConst()); break; +#ifdef AMD_EXTENSIONS + case EbtUint16: +#endif + case EbtUint: newConstArray[i].setUConst(static_cast(-static_cast(unionArray[i].getUConst()))); break; + case EbtInt64: newConstArray[i].setI64Const(-unionArray[i].getI64Const()); break; + case EbtUint64: newConstArray[i].setU64Const(static_cast(-static_cast(unionArray[i].getU64Const()))); break; + default: + return 0; + } + break; + case EOpLogicalNot: + case EOpVectorLogicalNot: + switch (getType().getBasicType()) { + case EbtBool: newConstArray[i].setBConst(!unionArray[i].getBConst()); break; + default: + return 0; + } + break; + case EOpBitwiseNot: + newConstArray[i] = ~unionArray[i]; + break; + case EOpRadians: + newConstArray[i].setDConst(unionArray[i].getDConst() * pi / 180.0); + break; + case EOpDegrees: + newConstArray[i].setDConst(unionArray[i].getDConst() * 180.0 / pi); + break; + case EOpSin: + newConstArray[i].setDConst(sin(unionArray[i].getDConst())); + break; + case EOpCos: + newConstArray[i].setDConst(cos(unionArray[i].getDConst())); + break; + case EOpTan: + newConstArray[i].setDConst(tan(unionArray[i].getDConst())); + break; + case EOpAsin: + newConstArray[i].setDConst(asin(unionArray[i].getDConst())); + break; + case EOpAcos: + newConstArray[i].setDConst(acos(unionArray[i].getDConst())); + break; + case EOpAtan: + newConstArray[i].setDConst(atan(unionArray[i].getDConst())); + break; + + case EOpDPdx: + case EOpDPdy: + case EOpFwidth: + case EOpDPdxFine: + case EOpDPdyFine: + case EOpFwidthFine: + case EOpDPdxCoarse: + case EOpDPdyCoarse: + case EOpFwidthCoarse: + // The derivatives are all mandated to create a constant 0. + newConstArray[i].setDConst(0.0); + break; + + case EOpExp: + newConstArray[i].setDConst(exp(unionArray[i].getDConst())); + break; + case EOpLog: + newConstArray[i].setDConst(log(unionArray[i].getDConst())); + break; + case EOpExp2: + { + const double inv_log2_e = 0.69314718055994530941723212145818; + newConstArray[i].setDConst(exp(unionArray[i].getDConst() * inv_log2_e)); + break; + } + case EOpLog2: + { + const double log2_e = 1.4426950408889634073599246810019; + newConstArray[i].setDConst(log2_e * log(unionArray[i].getDConst())); + break; + } + case EOpSqrt: + newConstArray[i].setDConst(sqrt(unionArray[i].getDConst())); + break; + case EOpInverseSqrt: + newConstArray[i].setDConst(1.0 / sqrt(unionArray[i].getDConst())); + break; + + case EOpAbs: + if (unionArray[i].getType() == EbtDouble) + newConstArray[i].setDConst(fabs(unionArray[i].getDConst())); + else if (unionArray[i].getType() == EbtInt) + newConstArray[i].setIConst(abs(unionArray[i].getIConst())); + else + newConstArray[i] = unionArray[i]; + break; + case EOpSign: + #define SIGN(X) (X == 0 ? 0 : (X < 0 ? -1 : 1)) + if (unionArray[i].getType() == EbtDouble) + newConstArray[i].setDConst(SIGN(unionArray[i].getDConst())); + else + newConstArray[i].setIConst(SIGN(unionArray[i].getIConst())); + break; + case EOpFloor: + newConstArray[i].setDConst(floor(unionArray[i].getDConst())); + break; + case EOpTrunc: + if (unionArray[i].getDConst() > 0) + newConstArray[i].setDConst(floor(unionArray[i].getDConst())); + else + newConstArray[i].setDConst(ceil(unionArray[i].getDConst())); + break; + case EOpRound: + newConstArray[i].setDConst(floor(0.5 + unionArray[i].getDConst())); + break; + case EOpRoundEven: + { + double flr = floor(unionArray[i].getDConst()); + bool even = flr / 2.0 == floor(flr / 2.0); + double rounded = even ? ceil(unionArray[i].getDConst() - 0.5) : floor(unionArray[i].getDConst() + 0.5); + newConstArray[i].setDConst(rounded); + break; + } + case EOpCeil: + newConstArray[i].setDConst(ceil(unionArray[i].getDConst())); + break; + case EOpFract: + { + double x = unionArray[i].getDConst(); + newConstArray[i].setDConst(x - floor(x)); + break; + } + + case EOpIsNan: + { + newConstArray[i].setBConst(isNan(unionArray[i].getDConst())); + break; + } + case EOpIsInf: + { + newConstArray[i].setBConst(isInf(unionArray[i].getDConst())); + break; + } + + // TODO: 3.0 Functionality: unary constant folding: the rest of the ops have to be fleshed out + + case EOpSinh: + case EOpCosh: + case EOpTanh: + case EOpAsinh: + case EOpAcosh: + case EOpAtanh: + + case EOpFloatBitsToInt: + case EOpFloatBitsToUint: + case EOpIntBitsToFloat: + case EOpUintBitsToFloat: + case EOpDoubleBitsToInt64: + case EOpDoubleBitsToUint64: + case EOpInt64BitsToDouble: + case EOpUint64BitsToDouble: +#ifdef AMD_EXTENSIONS + case EOpFloat16BitsToInt16: + case EOpFloat16BitsToUint16: + case EOpInt16BitsToFloat16: + case EOpUint16BitsToFloat16: +#endif + + default: + return 0; + } + } + + TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, returnType); + newNode->getWritableType().getQualifier().storage = EvqConst; + newNode->setLoc(getLoc()); + + return newNode; +} + +// +// Do constant folding for an aggregate node that has all its children +// as constants and an operator that requires constant folding. +// +TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) +{ + if (aggrNode == nullptr) + return aggrNode; + + if (! areAllChildConst(aggrNode)) + return aggrNode; + + if (aggrNode->isConstructor()) + return foldConstructor(aggrNode); + + TIntermSequence& children = aggrNode->getSequence(); + + // First, see if this is an operation to constant fold, kick out if not, + // see what size the result is if so. + + bool componentwise = false; // will also say componentwise if a scalar argument gets repeated to make per-component results + int objectSize; + switch (aggrNode->getOp()) { + case EOpAtan: + case EOpPow: + case EOpMin: + case EOpMax: + case EOpMix: + case EOpClamp: + case EOpLessThan: + case EOpGreaterThan: + case EOpLessThanEqual: + case EOpGreaterThanEqual: + case EOpVectorEqual: + case EOpVectorNotEqual: + componentwise = true; + objectSize = children[0]->getAsConstantUnion()->getType().computeNumComponents(); + break; + case EOpCross: + case EOpReflect: + case EOpRefract: + case EOpFaceForward: + objectSize = children[0]->getAsConstantUnion()->getType().computeNumComponents(); + break; + case EOpDistance: + case EOpDot: + objectSize = 1; + break; + case EOpOuterProduct: + objectSize = children[0]->getAsTyped()->getType().getVectorSize() * + children[1]->getAsTyped()->getType().getVectorSize(); + break; + case EOpStep: + componentwise = true; + objectSize = std::max(children[0]->getAsTyped()->getType().getVectorSize(), + children[1]->getAsTyped()->getType().getVectorSize()); + break; + case EOpSmoothStep: + componentwise = true; + objectSize = std::max(children[0]->getAsTyped()->getType().getVectorSize(), + children[2]->getAsTyped()->getType().getVectorSize()); + break; + default: + return aggrNode; + } + TConstUnionArray newConstArray(objectSize); + + TVector childConstUnions; + for (unsigned int arg = 0; arg < children.size(); ++arg) + childConstUnions.push_back(children[arg]->getAsConstantUnion()->getConstArray()); + + // Second, do the actual folding + + bool isFloatingPoint = children[0]->getAsTyped()->getBasicType() == EbtFloat || +#ifdef AMD_EXTENSIONS + children[0]->getAsTyped()->getBasicType() == EbtFloat16 || +#endif + children[0]->getAsTyped()->getBasicType() == EbtDouble; + bool isSigned = children[0]->getAsTyped()->getBasicType() == EbtInt || +#ifdef AMD_EXTENSIONS + children[0]->getAsTyped()->getBasicType() == EbtInt16 || +#endif + children[0]->getAsTyped()->getBasicType() == EbtInt64; + bool isInt64 = children[0]->getAsTyped()->getBasicType() == EbtInt64 || + children[0]->getAsTyped()->getBasicType() == EbtUint64; + if (componentwise) { + for (int comp = 0; comp < objectSize; comp++) { + + // some arguments are scalars instead of matching vectors; simulate a smear + int arg0comp = std::min(comp, children[0]->getAsTyped()->getType().getVectorSize() - 1); + int arg1comp = 0; + if (children.size() > 1) + arg1comp = std::min(comp, children[1]->getAsTyped()->getType().getVectorSize() - 1); + int arg2comp = 0; + if (children.size() > 2) + arg2comp = std::min(comp, children[2]->getAsTyped()->getType().getVectorSize() - 1); + + switch (aggrNode->getOp()) { + case EOpAtan: + newConstArray[comp].setDConst(atan2(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst())); + break; + case EOpPow: + newConstArray[comp].setDConst(pow(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst())); + break; + case EOpMin: + if (isFloatingPoint) + newConstArray[comp].setDConst(std::min(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst())); + else if (isSigned) { + if (isInt64) + newConstArray[comp].setI64Const(std::min(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const())); + else + newConstArray[comp].setIConst(std::min(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst())); + } else { + if (isInt64) + newConstArray[comp].setU64Const(std::min(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const())); + else + newConstArray[comp].setUConst(std::min(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst())); + } + break; + case EOpMax: + if (isFloatingPoint) + newConstArray[comp].setDConst(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst())); + else if (isSigned) { + if (isInt64) + newConstArray[comp].setI64Const(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const())); + else + newConstArray[comp].setIConst(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst())); + } else { + if (isInt64) + newConstArray[comp].setU64Const(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const())); + else + newConstArray[comp].setUConst(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst())); + } + break; + case EOpClamp: + if (isFloatingPoint) + newConstArray[comp].setDConst(std::min(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()), + childConstUnions[2][arg2comp].getDConst())); + else if (isSigned) { + if (isInt64) + newConstArray[comp].setI64Const(std::min(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()), + childConstUnions[2][arg2comp].getI64Const())); + else + newConstArray[comp].setIConst(std::min(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()), + childConstUnions[2][arg2comp].getIConst())); + } else { + if (isInt64) + newConstArray[comp].setU64Const(std::min(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()), + childConstUnions[2][arg2comp].getU64Const())); + else + newConstArray[comp].setUConst(std::min(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()), + childConstUnions[2][arg2comp].getUConst())); + } + break; + case EOpLessThan: + newConstArray[comp].setBConst(childConstUnions[0][arg0comp] < childConstUnions[1][arg1comp]); + break; + case EOpGreaterThan: + newConstArray[comp].setBConst(childConstUnions[0][arg0comp] > childConstUnions[1][arg1comp]); + break; + case EOpLessThanEqual: + newConstArray[comp].setBConst(! (childConstUnions[0][arg0comp] > childConstUnions[1][arg1comp])); + break; + case EOpGreaterThanEqual: + newConstArray[comp].setBConst(! (childConstUnions[0][arg0comp] < childConstUnions[1][arg1comp])); + break; + case EOpVectorEqual: + newConstArray[comp].setBConst(childConstUnions[0][arg0comp] == childConstUnions[1][arg1comp]); + break; + case EOpVectorNotEqual: + newConstArray[comp].setBConst(childConstUnions[0][arg0comp] != childConstUnions[1][arg1comp]); + break; + case EOpMix: + if (children[2]->getAsTyped()->getBasicType() == EbtBool) + newConstArray[comp].setDConst(childConstUnions[2][arg2comp].getBConst() ? childConstUnions[1][arg1comp].getDConst() : + childConstUnions[0][arg0comp].getDConst()); + else + newConstArray[comp].setDConst(childConstUnions[0][arg0comp].getDConst() * (1.0 - childConstUnions[2][arg2comp].getDConst()) + + childConstUnions[1][arg1comp].getDConst() * childConstUnions[2][arg2comp].getDConst()); + break; + case EOpStep: + newConstArray[comp].setDConst(childConstUnions[1][arg1comp].getDConst() < childConstUnions[0][arg0comp].getDConst() ? 0.0 : 1.0); + break; + case EOpSmoothStep: + { + double t = (childConstUnions[2][arg2comp].getDConst() - childConstUnions[0][arg0comp].getDConst()) / + (childConstUnions[1][arg1comp].getDConst() - childConstUnions[0][arg0comp].getDConst()); + if (t < 0.0) + t = 0.0; + if (t > 1.0) + t = 1.0; + newConstArray[comp].setDConst(t * t * (3.0 - 2.0 * t)); + break; + } + default: + return aggrNode; + } + } + } else { + // Non-componentwise... + + int numComps = children[0]->getAsConstantUnion()->getType().computeNumComponents(); + double dot; + + switch (aggrNode->getOp()) { + case EOpDistance: + { + double sum = 0.0; + for (int comp = 0; comp < numComps; ++comp) { + double diff = childConstUnions[1][comp].getDConst() - childConstUnions[0][comp].getDConst(); + sum += diff * diff; + } + newConstArray[0].setDConst(sqrt(sum)); + break; + } + case EOpDot: + newConstArray[0].setDConst(childConstUnions[0].dot(childConstUnions[1])); + break; + case EOpCross: + newConstArray[0] = childConstUnions[0][1] * childConstUnions[1][2] - childConstUnions[0][2] * childConstUnions[1][1]; + newConstArray[1] = childConstUnions[0][2] * childConstUnions[1][0] - childConstUnions[0][0] * childConstUnions[1][2]; + newConstArray[2] = childConstUnions[0][0] * childConstUnions[1][1] - childConstUnions[0][1] * childConstUnions[1][0]; + break; + case EOpFaceForward: + // If dot(Nref, I) < 0 return N, otherwise return -N: Arguments are (N, I, Nref). + dot = childConstUnions[1].dot(childConstUnions[2]); + for (int comp = 0; comp < numComps; ++comp) { + if (dot < 0.0) + newConstArray[comp] = childConstUnions[0][comp]; + else + newConstArray[comp].setDConst(-childConstUnions[0][comp].getDConst()); + } + break; + case EOpReflect: + // I - 2 * dot(N, I) * N: Arguments are (I, N). + dot = childConstUnions[0].dot(childConstUnions[1]); + dot *= 2.0; + for (int comp = 0; comp < numComps; ++comp) + newConstArray[comp].setDConst(childConstUnions[0][comp].getDConst() - dot * childConstUnions[1][comp].getDConst()); + break; + case EOpRefract: + { + // Arguments are (I, N, eta). + // k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I)) + // if (k < 0.0) + // return dvec(0.0) + // else + // return eta * I - (eta * dot(N, I) + sqrt(k)) * N + dot = childConstUnions[0].dot(childConstUnions[1]); + double eta = childConstUnions[2][0].getDConst(); + double k = 1.0 - eta * eta * (1.0 - dot * dot); + if (k < 0.0) { + for (int comp = 0; comp < numComps; ++comp) + newConstArray[comp].setDConst(0.0); + } else { + for (int comp = 0; comp < numComps; ++comp) + newConstArray[comp].setDConst(eta * childConstUnions[0][comp].getDConst() - (eta * dot + sqrt(k)) * childConstUnions[1][comp].getDConst()); + } + break; + } + case EOpOuterProduct: + { + int numRows = numComps; + int numCols = children[1]->getAsConstantUnion()->getType().computeNumComponents(); + for (int row = 0; row < numRows; ++row) + for (int col = 0; col < numCols; ++col) + newConstArray[col * numRows + row] = childConstUnions[0][row] * childConstUnions[1][col]; + break; + } + default: + return aggrNode; + } + } + + TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, aggrNode->getType()); + newNode->getWritableType().getQualifier().storage = EvqConst; + newNode->setLoc(aggrNode->getLoc()); + + return newNode; +} + +bool TIntermediate::areAllChildConst(TIntermAggregate* aggrNode) +{ + bool allConstant = true; + + // check if all the child nodes are constants so that they can be inserted into + // the parent node + if (aggrNode) { + TIntermSequence& childSequenceVector = aggrNode->getSequence(); + for (TIntermSequence::iterator p = childSequenceVector.begin(); + p != childSequenceVector.end(); p++) { + if (!(*p)->getAsTyped()->getAsConstantUnion()) + return false; + } + } + + return allConstant; +} + +TIntermTyped* TIntermediate::foldConstructor(TIntermAggregate* aggrNode) +{ + bool error = false; + + TConstUnionArray unionArray(aggrNode->getType().computeNumComponents()); + if (aggrNode->getSequence().size() == 1) + error = parseConstTree(aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType(), true); + else + error = parseConstTree(aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType()); + + if (error) + return aggrNode; + + return addConstantUnion(unionArray, aggrNode->getType(), aggrNode->getLoc()); +} + +// +// Constant folding of a bracket (array-style) dereference or struct-like dot +// dereference. Can handle anything except a multi-character swizzle, though +// all swizzles may go to foldSwizzle(). +// +TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, const TSourceLoc& loc) +{ + TType dereferencedType(node->getType(), index); + dereferencedType.getQualifier().storage = EvqConst; + TIntermTyped* result = 0; + int size = dereferencedType.computeNumComponents(); + + // arrays, vectors, matrices, all use simple multiplicative math + // while structures need to add up heterogeneous members + int start; + if (node->isArray() || ! node->isStruct()) + start = size * index; + else { + // it is a structure + assert(node->isStruct()); + start = 0; + for (int i = 0; i < index; ++i) + start += (*node->getType().getStruct())[i].type->computeNumComponents(); + } + + result = addConstantUnion(TConstUnionArray(node->getAsConstantUnion()->getConstArray(), start, size), node->getType(), loc); + + if (result == 0) + result = node; + else + result->setType(dereferencedType); + + return result; +} + +// +// Make a constant vector node or constant scalar node, representing a given +// constant vector and constant swizzle into it. +// +TIntermTyped* TIntermediate::foldSwizzle(TIntermTyped* node, TSwizzleSelectors& selectors, const TSourceLoc& loc) +{ + const TConstUnionArray& unionArray = node->getAsConstantUnion()->getConstArray(); + TConstUnionArray constArray(selectors.size()); + + for (int i = 0; i < selectors.size(); i++) + constArray[i] = unionArray[selectors[i]]; + + TIntermTyped* result = addConstantUnion(constArray, node->getType(), loc); + + if (result == 0) + result = node; + else + result->setType(TType(node->getBasicType(), EvqConst, selectors.size())); + + return result; +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/InfoSink.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/InfoSink.cpp new file mode 100644 index 00000000..d00c4225 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/InfoSink.cpp @@ -0,0 +1,113 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#include "../Include/InfoSink.h" + +#include + +namespace glslang { + +void TInfoSinkBase::append(const char* s) +{ + if (outputStream & EString) { + if (s == nullptr) + sink.append("(null)"); + else { + checkMem(strlen(s)); + sink.append(s); + } + } + +//#ifdef _WIN32 +// if (outputStream & EDebugger) +// OutputDebugString(s); +//#endif + + if (outputStream & EStdOut) + fprintf(stdout, "%s", s); +} + +void TInfoSinkBase::append(int count, char c) +{ + if (outputStream & EString) { + checkMem(count); + sink.append(count, c); + } + +//#ifdef _WIN32 +// if (outputStream & EDebugger) { +// char str[2]; +// str[0] = c; +// str[1] = '\0'; +// OutputDebugString(str); +// } +//#endif + + if (outputStream & EStdOut) + fprintf(stdout, "%c", c); +} + +void TInfoSinkBase::append(const TPersistString& t) +{ + if (outputStream & EString) { + checkMem(t.size()); + sink.append(t); + } + +//#ifdef _WIN32 +// if (outputStream & EDebugger) +// OutputDebugString(t.c_str()); +//#endif + + if (outputStream & EStdOut) + fprintf(stdout, "%s", t.c_str()); +} + +void TInfoSinkBase::append(const TString& t) +{ + if (outputStream & EString) { + checkMem(t.size()); + sink.append(t.c_str()); + } + +//#ifdef _WIN32 +// if (outputStream & EDebugger) +// OutputDebugString(t.c_str()); +//#endif + + if (outputStream & EStdOut) + fprintf(stdout, "%s", t.c_str()); +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/Initialize.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/Initialize.cpp new file mode 100644 index 00000000..4364bb66 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/Initialize.cpp @@ -0,0 +1,6478 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2012-2016 LunarG, Inc. +// Copyright (C) 2015-2017 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +// +// Create strings that declare built-in definitions, add built-ins programmatically +// that cannot be expressed in the strings, and establish mappings between +// built-in functions and operators. +// +// Where to put a built-in: +// TBuiltIns::initialize(version,profile) context-independent textual built-ins; add them to the right string +// TBuiltIns::initialize(resources,...) context-dependent textual built-ins; add them to the right string +// TBuiltIns::identifyBuiltIns(...,symbolTable) context-independent programmatic additions/mappings to the symbol table, +// including identifying what extensions are needed if a version does not allow a symbol +// TBuiltIns::identifyBuiltIns(...,symbolTable, resources) context-dependent programmatic additions/mappings to the symbol table, +// including identifying what extensions are needed if a version does not allow a symbol +// + +#include "../Include/intermediate.h" +#include "Initialize.h" + +namespace glslang { + +// TODO: ARB_Compatability: do full extension support +const bool ARBCompatibility = true; + +const bool ForwardCompatibility = false; + +// change this back to false if depending on textual spellings of texturing calls when consuming the AST +// Using PureOperatorBuiltins=false is deprecated. +bool PureOperatorBuiltins = true; + +inline bool IncludeLegacy(int version, EProfile profile, const SpvVersion& spvVersion) +{ + return profile != EEsProfile && (version <= 130 || (spvVersion.spv == 0 && ARBCompatibility) || profile == ECompatibilityProfile); +} + +// Construct TBuiltInParseables base class. This can be used for language-common constructs. +TBuiltInParseables::TBuiltInParseables() +{ +} + +// Destroy TBuiltInParseables. +TBuiltInParseables::~TBuiltInParseables() +{ +} + +TBuiltIns::TBuiltIns() +{ + // Set up textual representations for making all the permutations + // of texturing/imaging functions. + prefixes[EbtFloat] = ""; + prefixes[EbtInt] = "i"; + prefixes[EbtUint] = "u"; + postfixes[2] = "2"; + postfixes[3] = "3"; + postfixes[4] = "4"; + + // Map from symbolic class of texturing dimension to numeric dimensions. + dimMap[Esd1D] = 1; + dimMap[Esd2D] = 2; + dimMap[EsdRect] = 2; + dimMap[Esd3D] = 3; + dimMap[EsdCube] = 3; + dimMap[EsdBuffer] = 1; + dimMap[EsdSubpass] = 2; // potientially unused for now +} + +TBuiltIns::~TBuiltIns() +{ +} + + +// +// Add all context-independent built-in functions and variables that are present +// for the given version and profile. Share common ones across stages, otherwise +// make stage-specific entries. +// +// Most built-ins variables can be added as simple text strings. Some need to +// be added programmatically, which is done later in IdentifyBuiltIns() below. +// +void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvVersion) +{ + //============================================================================ + // + // Prototypes for built-in functions seen by both vertex and fragment shaders. + // + //============================================================================ + + // + // Angle and Trigonometric Functions. + // + commonBuiltins.append( + "float radians(float degrees);" + "vec2 radians(vec2 degrees);" + "vec3 radians(vec3 degrees);" + "vec4 radians(vec4 degrees);" + + "float degrees(float radians);" + "vec2 degrees(vec2 radians);" + "vec3 degrees(vec3 radians);" + "vec4 degrees(vec4 radians);" + + "float sin(float angle);" + "vec2 sin(vec2 angle);" + "vec3 sin(vec3 angle);" + "vec4 sin(vec4 angle);" + + "float cos(float angle);" + "vec2 cos(vec2 angle);" + "vec3 cos(vec3 angle);" + "vec4 cos(vec4 angle);" + + "float tan(float angle);" + "vec2 tan(vec2 angle);" + "vec3 tan(vec3 angle);" + "vec4 tan(vec4 angle);" + + "float asin(float x);" + "vec2 asin(vec2 x);" + "vec3 asin(vec3 x);" + "vec4 asin(vec4 x);" + + "float acos(float x);" + "vec2 acos(vec2 x);" + "vec3 acos(vec3 x);" + "vec4 acos(vec4 x);" + + "float atan(float y, float x);" + "vec2 atan(vec2 y, vec2 x);" + "vec3 atan(vec3 y, vec3 x);" + "vec4 atan(vec4 y, vec4 x);" + + "float atan(float y_over_x);" + "vec2 atan(vec2 y_over_x);" + "vec3 atan(vec3 y_over_x);" + "vec4 atan(vec4 y_over_x);" + + "\n"); + + if (version >= 130) { + commonBuiltins.append( + "float sinh(float angle);" + "vec2 sinh(vec2 angle);" + "vec3 sinh(vec3 angle);" + "vec4 sinh(vec4 angle);" + + "float cosh(float angle);" + "vec2 cosh(vec2 angle);" + "vec3 cosh(vec3 angle);" + "vec4 cosh(vec4 angle);" + + "float tanh(float angle);" + "vec2 tanh(vec2 angle);" + "vec3 tanh(vec3 angle);" + "vec4 tanh(vec4 angle);" + + "float asinh(float x);" + "vec2 asinh(vec2 x);" + "vec3 asinh(vec3 x);" + "vec4 asinh(vec4 x);" + + "float acosh(float x);" + "vec2 acosh(vec2 x);" + "vec3 acosh(vec3 x);" + "vec4 acosh(vec4 x);" + + "float atanh(float y_over_x);" + "vec2 atanh(vec2 y_over_x);" + "vec3 atanh(vec3 y_over_x);" + "vec4 atanh(vec4 y_over_x);" + + "\n"); + } + + // + // Exponential Functions. + // + commonBuiltins.append( + "float pow(float x, float y);" + "vec2 pow(vec2 x, vec2 y);" + "vec3 pow(vec3 x, vec3 y);" + "vec4 pow(vec4 x, vec4 y);" + + "float exp(float x);" + "vec2 exp(vec2 x);" + "vec3 exp(vec3 x);" + "vec4 exp(vec4 x);" + + "float log(float x);" + "vec2 log(vec2 x);" + "vec3 log(vec3 x);" + "vec4 log(vec4 x);" + + "float exp2(float x);" + "vec2 exp2(vec2 x);" + "vec3 exp2(vec3 x);" + "vec4 exp2(vec4 x);" + + "float log2(float x);" + "vec2 log2(vec2 x);" + "vec3 log2(vec3 x);" + "vec4 log2(vec4 x);" + + "float sqrt(float x);" + "vec2 sqrt(vec2 x);" + "vec3 sqrt(vec3 x);" + "vec4 sqrt(vec4 x);" + + "float inversesqrt(float x);" + "vec2 inversesqrt(vec2 x);" + "vec3 inversesqrt(vec3 x);" + "vec4 inversesqrt(vec4 x);" + + "\n"); + + // + // Common Functions. + // + commonBuiltins.append( + "float abs(float x);" + "vec2 abs(vec2 x);" + "vec3 abs(vec3 x);" + "vec4 abs(vec4 x);" + + "float sign(float x);" + "vec2 sign(vec2 x);" + "vec3 sign(vec3 x);" + "vec4 sign(vec4 x);" + + "float floor(float x);" + "vec2 floor(vec2 x);" + "vec3 floor(vec3 x);" + "vec4 floor(vec4 x);" + + "float ceil(float x);" + "vec2 ceil(vec2 x);" + "vec3 ceil(vec3 x);" + "vec4 ceil(vec4 x);" + + "float fract(float x);" + "vec2 fract(vec2 x);" + "vec3 fract(vec3 x);" + "vec4 fract(vec4 x);" + + "float mod(float x, float y);" + "vec2 mod(vec2 x, float y);" + "vec3 mod(vec3 x, float y);" + "vec4 mod(vec4 x, float y);" + "vec2 mod(vec2 x, vec2 y);" + "vec3 mod(vec3 x, vec3 y);" + "vec4 mod(vec4 x, vec4 y);" + + "float min(float x, float y);" + "vec2 min(vec2 x, float y);" + "vec3 min(vec3 x, float y);" + "vec4 min(vec4 x, float y);" + "vec2 min(vec2 x, vec2 y);" + "vec3 min(vec3 x, vec3 y);" + "vec4 min(vec4 x, vec4 y);" + + "float max(float x, float y);" + "vec2 max(vec2 x, float y);" + "vec3 max(vec3 x, float y);" + "vec4 max(vec4 x, float y);" + "vec2 max(vec2 x, vec2 y);" + "vec3 max(vec3 x, vec3 y);" + "vec4 max(vec4 x, vec4 y);" + + "float clamp(float x, float minVal, float maxVal);" + "vec2 clamp(vec2 x, float minVal, float maxVal);" + "vec3 clamp(vec3 x, float minVal, float maxVal);" + "vec4 clamp(vec4 x, float minVal, float maxVal);" + "vec2 clamp(vec2 x, vec2 minVal, vec2 maxVal);" + "vec3 clamp(vec3 x, vec3 minVal, vec3 maxVal);" + "vec4 clamp(vec4 x, vec4 minVal, vec4 maxVal);" + + "float mix(float x, float y, float a);" + "vec2 mix(vec2 x, vec2 y, float a);" + "vec3 mix(vec3 x, vec3 y, float a);" + "vec4 mix(vec4 x, vec4 y, float a);" + "vec2 mix(vec2 x, vec2 y, vec2 a);" + "vec3 mix(vec3 x, vec3 y, vec3 a);" + "vec4 mix(vec4 x, vec4 y, vec4 a);" + + "float step(float edge, float x);" + "vec2 step(vec2 edge, vec2 x);" + "vec3 step(vec3 edge, vec3 x);" + "vec4 step(vec4 edge, vec4 x);" + "vec2 step(float edge, vec2 x);" + "vec3 step(float edge, vec3 x);" + "vec4 step(float edge, vec4 x);" + + "float smoothstep(float edge0, float edge1, float x);" + "vec2 smoothstep(vec2 edge0, vec2 edge1, vec2 x);" + "vec3 smoothstep(vec3 edge0, vec3 edge1, vec3 x);" + "vec4 smoothstep(vec4 edge0, vec4 edge1, vec4 x);" + "vec2 smoothstep(float edge0, float edge1, vec2 x);" + "vec3 smoothstep(float edge0, float edge1, vec3 x);" + "vec4 smoothstep(float edge0, float edge1, vec4 x);" + + "\n"); + + if (version >= 130) { + commonBuiltins.append( + " int abs( int x);" + "ivec2 abs(ivec2 x);" + "ivec3 abs(ivec3 x);" + "ivec4 abs(ivec4 x);" + + " int sign( int x);" + "ivec2 sign(ivec2 x);" + "ivec3 sign(ivec3 x);" + "ivec4 sign(ivec4 x);" + + "float trunc(float x);" + "vec2 trunc(vec2 x);" + "vec3 trunc(vec3 x);" + "vec4 trunc(vec4 x);" + + "float round(float x);" + "vec2 round(vec2 x);" + "vec3 round(vec3 x);" + "vec4 round(vec4 x);" + + "float roundEven(float x);" + "vec2 roundEven(vec2 x);" + "vec3 roundEven(vec3 x);" + "vec4 roundEven(vec4 x);" + + "float modf(float, out float);" + "vec2 modf(vec2, out vec2 );" + "vec3 modf(vec3, out vec3 );" + "vec4 modf(vec4, out vec4 );" + + " int min(int x, int y);" + "ivec2 min(ivec2 x, int y);" + "ivec3 min(ivec3 x, int y);" + "ivec4 min(ivec4 x, int y);" + "ivec2 min(ivec2 x, ivec2 y);" + "ivec3 min(ivec3 x, ivec3 y);" + "ivec4 min(ivec4 x, ivec4 y);" + + " uint min(uint x, uint y);" + "uvec2 min(uvec2 x, uint y);" + "uvec3 min(uvec3 x, uint y);" + "uvec4 min(uvec4 x, uint y);" + "uvec2 min(uvec2 x, uvec2 y);" + "uvec3 min(uvec3 x, uvec3 y);" + "uvec4 min(uvec4 x, uvec4 y);" + + " int max(int x, int y);" + "ivec2 max(ivec2 x, int y);" + "ivec3 max(ivec3 x, int y);" + "ivec4 max(ivec4 x, int y);" + "ivec2 max(ivec2 x, ivec2 y);" + "ivec3 max(ivec3 x, ivec3 y);" + "ivec4 max(ivec4 x, ivec4 y);" + + " uint max(uint x, uint y);" + "uvec2 max(uvec2 x, uint y);" + "uvec3 max(uvec3 x, uint y);" + "uvec4 max(uvec4 x, uint y);" + "uvec2 max(uvec2 x, uvec2 y);" + "uvec3 max(uvec3 x, uvec3 y);" + "uvec4 max(uvec4 x, uvec4 y);" + + "int clamp(int x, int minVal, int maxVal);" + "ivec2 clamp(ivec2 x, int minVal, int maxVal);" + "ivec3 clamp(ivec3 x, int minVal, int maxVal);" + "ivec4 clamp(ivec4 x, int minVal, int maxVal);" + "ivec2 clamp(ivec2 x, ivec2 minVal, ivec2 maxVal);" + "ivec3 clamp(ivec3 x, ivec3 minVal, ivec3 maxVal);" + "ivec4 clamp(ivec4 x, ivec4 minVal, ivec4 maxVal);" + + "uint clamp(uint x, uint minVal, uint maxVal);" + "uvec2 clamp(uvec2 x, uint minVal, uint maxVal);" + "uvec3 clamp(uvec3 x, uint minVal, uint maxVal);" + "uvec4 clamp(uvec4 x, uint minVal, uint maxVal);" + "uvec2 clamp(uvec2 x, uvec2 minVal, uvec2 maxVal);" + "uvec3 clamp(uvec3 x, uvec3 minVal, uvec3 maxVal);" + "uvec4 clamp(uvec4 x, uvec4 minVal, uvec4 maxVal);" + + "float mix(float x, float y, bool a);" + "vec2 mix(vec2 x, vec2 y, bvec2 a);" + "vec3 mix(vec3 x, vec3 y, bvec3 a);" + "vec4 mix(vec4 x, vec4 y, bvec4 a);" + + "bool isnan(float x);" + "bvec2 isnan(vec2 x);" + "bvec3 isnan(vec3 x);" + "bvec4 isnan(vec4 x);" + + "bool isinf(float x);" + "bvec2 isinf(vec2 x);" + "bvec3 isinf(vec3 x);" + "bvec4 isinf(vec4 x);" + + "\n"); + } + + // + // double functions added to desktop 4.00, but not fma, frexp, ldexp, or pack/unpack + // + if (profile != EEsProfile && version >= 400) { + commonBuiltins.append( + + "double sqrt(double);" + "dvec2 sqrt(dvec2);" + "dvec3 sqrt(dvec3);" + "dvec4 sqrt(dvec4);" + + "double inversesqrt(double);" + "dvec2 inversesqrt(dvec2);" + "dvec3 inversesqrt(dvec3);" + "dvec4 inversesqrt(dvec4);" + + "double abs(double);" + "dvec2 abs(dvec2);" + "dvec3 abs(dvec3);" + "dvec4 abs(dvec4);" + + "double sign(double);" + "dvec2 sign(dvec2);" + "dvec3 sign(dvec3);" + "dvec4 sign(dvec4);" + + "double floor(double);" + "dvec2 floor(dvec2);" + "dvec3 floor(dvec3);" + "dvec4 floor(dvec4);" + + "double trunc(double);" + "dvec2 trunc(dvec2);" + "dvec3 trunc(dvec3);" + "dvec4 trunc(dvec4);" + + "double round(double);" + "dvec2 round(dvec2);" + "dvec3 round(dvec3);" + "dvec4 round(dvec4);" + + "double roundEven(double);" + "dvec2 roundEven(dvec2);" + "dvec3 roundEven(dvec3);" + "dvec4 roundEven(dvec4);" + + "double ceil(double);" + "dvec2 ceil(dvec2);" + "dvec3 ceil(dvec3);" + "dvec4 ceil(dvec4);" + + "double fract(double);" + "dvec2 fract(dvec2);" + "dvec3 fract(dvec3);" + "dvec4 fract(dvec4);" + + "double mod(double, double);" + "dvec2 mod(dvec2 , double);" + "dvec3 mod(dvec3 , double);" + "dvec4 mod(dvec4 , double);" + "dvec2 mod(dvec2 , dvec2);" + "dvec3 mod(dvec3 , dvec3);" + "dvec4 mod(dvec4 , dvec4);" + + "double modf(double, out double);" + "dvec2 modf(dvec2, out dvec2);" + "dvec3 modf(dvec3, out dvec3);" + "dvec4 modf(dvec4, out dvec4);" + + "double min(double, double);" + "dvec2 min(dvec2, double);" + "dvec3 min(dvec3, double);" + "dvec4 min(dvec4, double);" + "dvec2 min(dvec2, dvec2);" + "dvec3 min(dvec3, dvec3);" + "dvec4 min(dvec4, dvec4);" + + "double max(double, double);" + "dvec2 max(dvec2 , double);" + "dvec3 max(dvec3 , double);" + "dvec4 max(dvec4 , double);" + "dvec2 max(dvec2 , dvec2);" + "dvec3 max(dvec3 , dvec3);" + "dvec4 max(dvec4 , dvec4);" + + "double clamp(double, double, double);" + "dvec2 clamp(dvec2 , double, double);" + "dvec3 clamp(dvec3 , double, double);" + "dvec4 clamp(dvec4 , double, double);" + "dvec2 clamp(dvec2 , dvec2 , dvec2);" + "dvec3 clamp(dvec3 , dvec3 , dvec3);" + "dvec4 clamp(dvec4 , dvec4 , dvec4);" + + "double mix(double, double, double);" + "dvec2 mix(dvec2, dvec2, double);" + "dvec3 mix(dvec3, dvec3, double);" + "dvec4 mix(dvec4, dvec4, double);" + "dvec2 mix(dvec2, dvec2, dvec2);" + "dvec3 mix(dvec3, dvec3, dvec3);" + "dvec4 mix(dvec4, dvec4, dvec4);" + "double mix(double, double, bool);" + "dvec2 mix(dvec2, dvec2, bvec2);" + "dvec3 mix(dvec3, dvec3, bvec3);" + "dvec4 mix(dvec4, dvec4, bvec4);" + + "double step(double, double);" + "dvec2 step(dvec2 , dvec2);" + "dvec3 step(dvec3 , dvec3);" + "dvec4 step(dvec4 , dvec4);" + "dvec2 step(double, dvec2);" + "dvec3 step(double, dvec3);" + "dvec4 step(double, dvec4);" + + "double smoothstep(double, double, double);" + "dvec2 smoothstep(dvec2 , dvec2 , dvec2);" + "dvec3 smoothstep(dvec3 , dvec3 , dvec3);" + "dvec4 smoothstep(dvec4 , dvec4 , dvec4);" + "dvec2 smoothstep(double, double, dvec2);" + "dvec3 smoothstep(double, double, dvec3);" + "dvec4 smoothstep(double, double, dvec4);" + + "bool isnan(double);" + "bvec2 isnan(dvec2);" + "bvec3 isnan(dvec3);" + "bvec4 isnan(dvec4);" + + "bool isinf(double);" + "bvec2 isinf(dvec2);" + "bvec3 isinf(dvec3);" + "bvec4 isinf(dvec4);" + + "double length(double);" + "double length(dvec2);" + "double length(dvec3);" + "double length(dvec4);" + + "double distance(double, double);" + "double distance(dvec2 , dvec2);" + "double distance(dvec3 , dvec3);" + "double distance(dvec4 , dvec4);" + + "double dot(double, double);" + "double dot(dvec2 , dvec2);" + "double dot(dvec3 , dvec3);" + "double dot(dvec4 , dvec4);" + + "dvec3 cross(dvec3, dvec3);" + + "double normalize(double);" + "dvec2 normalize(dvec2);" + "dvec3 normalize(dvec3);" + "dvec4 normalize(dvec4);" + + "double faceforward(double, double, double);" + "dvec2 faceforward(dvec2, dvec2, dvec2);" + "dvec3 faceforward(dvec3, dvec3, dvec3);" + "dvec4 faceforward(dvec4, dvec4, dvec4);" + + "double reflect(double, double);" + "dvec2 reflect(dvec2 , dvec2 );" + "dvec3 reflect(dvec3 , dvec3 );" + "dvec4 reflect(dvec4 , dvec4 );" + + "double refract(double, double, double);" + "dvec2 refract(dvec2 , dvec2 , double);" + "dvec3 refract(dvec3 , dvec3 , double);" + "dvec4 refract(dvec4 , dvec4 , double);" + + "dmat2 matrixCompMult(dmat2, dmat2);" + "dmat3 matrixCompMult(dmat3, dmat3);" + "dmat4 matrixCompMult(dmat4, dmat4);" + "dmat2x3 matrixCompMult(dmat2x3, dmat2x3);" + "dmat2x4 matrixCompMult(dmat2x4, dmat2x4);" + "dmat3x2 matrixCompMult(dmat3x2, dmat3x2);" + "dmat3x4 matrixCompMult(dmat3x4, dmat3x4);" + "dmat4x2 matrixCompMult(dmat4x2, dmat4x2);" + "dmat4x3 matrixCompMult(dmat4x3, dmat4x3);" + + "dmat2 outerProduct(dvec2, dvec2);" + "dmat3 outerProduct(dvec3, dvec3);" + "dmat4 outerProduct(dvec4, dvec4);" + "dmat2x3 outerProduct(dvec3, dvec2);" + "dmat3x2 outerProduct(dvec2, dvec3);" + "dmat2x4 outerProduct(dvec4, dvec2);" + "dmat4x2 outerProduct(dvec2, dvec4);" + "dmat3x4 outerProduct(dvec4, dvec3);" + "dmat4x3 outerProduct(dvec3, dvec4);" + + "dmat2 transpose(dmat2);" + "dmat3 transpose(dmat3);" + "dmat4 transpose(dmat4);" + "dmat2x3 transpose(dmat3x2);" + "dmat3x2 transpose(dmat2x3);" + "dmat2x4 transpose(dmat4x2);" + "dmat4x2 transpose(dmat2x4);" + "dmat3x4 transpose(dmat4x3);" + "dmat4x3 transpose(dmat3x4);" + + "double determinant(dmat2);" + "double determinant(dmat3);" + "double determinant(dmat4);" + + "dmat2 inverse(dmat2);" + "dmat3 inverse(dmat3);" + "dmat4 inverse(dmat4);" + + "bvec2 lessThan(dvec2, dvec2);" + "bvec3 lessThan(dvec3, dvec3);" + "bvec4 lessThan(dvec4, dvec4);" + + "bvec2 lessThanEqual(dvec2, dvec2);" + "bvec3 lessThanEqual(dvec3, dvec3);" + "bvec4 lessThanEqual(dvec4, dvec4);" + + "bvec2 greaterThan(dvec2, dvec2);" + "bvec3 greaterThan(dvec3, dvec3);" + "bvec4 greaterThan(dvec4, dvec4);" + + "bvec2 greaterThanEqual(dvec2, dvec2);" + "bvec3 greaterThanEqual(dvec3, dvec3);" + "bvec4 greaterThanEqual(dvec4, dvec4);" + + "bvec2 equal(dvec2, dvec2);" + "bvec3 equal(dvec3, dvec3);" + "bvec4 equal(dvec4, dvec4);" + + "bvec2 notEqual(dvec2, dvec2);" + "bvec3 notEqual(dvec3, dvec3);" + "bvec4 notEqual(dvec4, dvec4);" + + "\n"); + } + + if (profile != EEsProfile && version >= 450) { + commonBuiltins.append( + + "int64_t abs(int64_t);" + "i64vec2 abs(i64vec2);" + "i64vec3 abs(i64vec3);" + "i64vec4 abs(i64vec4);" + + "int64_t sign(int64_t);" + "i64vec2 sign(i64vec2);" + "i64vec3 sign(i64vec3);" + "i64vec4 sign(i64vec4);" + + "int64_t min(int64_t, int64_t);" + "i64vec2 min(i64vec2, int64_t);" + "i64vec3 min(i64vec3, int64_t);" + "i64vec4 min(i64vec4, int64_t);" + "i64vec2 min(i64vec2, i64vec2);" + "i64vec3 min(i64vec3, i64vec3);" + "i64vec4 min(i64vec4, i64vec4);" + "uint64_t min(uint64_t, uint64_t);" + "u64vec2 min(u64vec2, uint64_t);" + "u64vec3 min(u64vec3, uint64_t);" + "u64vec4 min(u64vec4, uint64_t);" + "u64vec2 min(u64vec2, u64vec2);" + "u64vec3 min(u64vec3, u64vec3);" + "u64vec4 min(u64vec4, u64vec4);" + + "int64_t max(int64_t, int64_t);" + "i64vec2 max(i64vec2, int64_t);" + "i64vec3 max(i64vec3, int64_t);" + "i64vec4 max(i64vec4, int64_t);" + "i64vec2 max(i64vec2, i64vec2);" + "i64vec3 max(i64vec3, i64vec3);" + "i64vec4 max(i64vec4, i64vec4);" + "uint64_t max(uint64_t, uint64_t);" + "u64vec2 max(u64vec2, uint64_t);" + "u64vec3 max(u64vec3, uint64_t);" + "u64vec4 max(u64vec4, uint64_t);" + "u64vec2 max(u64vec2, u64vec2);" + "u64vec3 max(u64vec3, u64vec3);" + "u64vec4 max(u64vec4, u64vec4);" + + "int64_t clamp(int64_t, int64_t, int64_t);" + "i64vec2 clamp(i64vec2, int64_t, int64_t);" + "i64vec3 clamp(i64vec3, int64_t, int64_t);" + "i64vec4 clamp(i64vec4, int64_t, int64_t);" + "i64vec2 clamp(i64vec2, i64vec2, i64vec2);" + "i64vec3 clamp(i64vec3, i64vec3, i64vec3);" + "i64vec4 clamp(i64vec4, i64vec4, i64vec4);" + "uint64_t clamp(uint64_t, uint64_t, uint64_t);" + "u64vec2 clamp(u64vec2, uint64_t, uint64_t);" + "u64vec3 clamp(u64vec3, uint64_t, uint64_t);" + "u64vec4 clamp(u64vec4, uint64_t, uint64_t);" + "u64vec2 clamp(u64vec2, u64vec2, u64vec2);" + "u64vec3 clamp(u64vec3, u64vec3, u64vec3);" + "u64vec4 clamp(u64vec4, u64vec4, u64vec4);" + + "int64_t mix(int64_t, int64_t, bool);" + "i64vec2 mix(i64vec2, i64vec2, bvec2);" + "i64vec3 mix(i64vec3, i64vec3, bvec3);" + "i64vec4 mix(i64vec4, i64vec4, bvec4);" + "uint64_t mix(uint64_t, uint64_t, bool);" + "u64vec2 mix(u64vec2, u64vec2, bvec2);" + "u64vec3 mix(u64vec3, u64vec3, bvec3);" + "u64vec4 mix(u64vec4, u64vec4, bvec4);" + + "int64_t doubleBitsToInt64(double);" + "i64vec2 doubleBitsToInt64(dvec2);" + "i64vec3 doubleBitsToInt64(dvec3);" + "i64vec4 doubleBitsToInt64(dvec4);" + + "uint64_t doubleBitsToUint64(double);" + "u64vec2 doubleBitsToUint64(dvec2);" + "u64vec3 doubleBitsToUint64(dvec3);" + "u64vec4 doubleBitsToUint64(dvec4);" + + "double int64BitsToDouble(int64_t);" + "dvec2 int64BitsToDouble(i64vec2);" + "dvec3 int64BitsToDouble(i64vec3);" + "dvec4 int64BitsToDouble(i64vec4);" + + "double uint64BitsToDouble(uint64_t);" + "dvec2 uint64BitsToDouble(u64vec2);" + "dvec3 uint64BitsToDouble(u64vec3);" + "dvec4 uint64BitsToDouble(u64vec4);" + + "int64_t packInt2x32(ivec2);" + "uint64_t packUint2x32(uvec2);" + "ivec2 unpackInt2x32(int64_t);" + "uvec2 unpackUint2x32(uint64_t);" + + "bvec2 lessThan(i64vec2, i64vec2);" + "bvec3 lessThan(i64vec3, i64vec3);" + "bvec4 lessThan(i64vec4, i64vec4);" + "bvec2 lessThan(u64vec2, u64vec2);" + "bvec3 lessThan(u64vec3, u64vec3);" + "bvec4 lessThan(u64vec4, u64vec4);" + + "bvec2 lessThanEqual(i64vec2, i64vec2);" + "bvec3 lessThanEqual(i64vec3, i64vec3);" + "bvec4 lessThanEqual(i64vec4, i64vec4);" + "bvec2 lessThanEqual(u64vec2, u64vec2);" + "bvec3 lessThanEqual(u64vec3, u64vec3);" + "bvec4 lessThanEqual(u64vec4, u64vec4);" + + "bvec2 greaterThan(i64vec2, i64vec2);" + "bvec3 greaterThan(i64vec3, i64vec3);" + "bvec4 greaterThan(i64vec4, i64vec4);" + "bvec2 greaterThan(u64vec2, u64vec2);" + "bvec3 greaterThan(u64vec3, u64vec3);" + "bvec4 greaterThan(u64vec4, u64vec4);" + + "bvec2 greaterThanEqual(i64vec2, i64vec2);" + "bvec3 greaterThanEqual(i64vec3, i64vec3);" + "bvec4 greaterThanEqual(i64vec4, i64vec4);" + "bvec2 greaterThanEqual(u64vec2, u64vec2);" + "bvec3 greaterThanEqual(u64vec3, u64vec3);" + "bvec4 greaterThanEqual(u64vec4, u64vec4);" + + "bvec2 equal(i64vec2, i64vec2);" + "bvec3 equal(i64vec3, i64vec3);" + "bvec4 equal(i64vec4, i64vec4);" + "bvec2 equal(u64vec2, u64vec2);" + "bvec3 equal(u64vec3, u64vec3);" + "bvec4 equal(u64vec4, u64vec4);" + + "bvec2 notEqual(i64vec2, i64vec2);" + "bvec3 notEqual(i64vec3, i64vec3);" + "bvec4 notEqual(i64vec4, i64vec4);" + "bvec2 notEqual(u64vec2, u64vec2);" + "bvec3 notEqual(u64vec3, u64vec3);" + "bvec4 notEqual(u64vec4, u64vec4);" + +#ifdef AMD_EXTENSIONS + "int findLSB(int64_t);" + "ivec2 findLSB(i64vec2);" + "ivec3 findLSB(i64vec3);" + "ivec4 findLSB(i64vec4);" + + "int findLSB(uint64_t);" + "ivec2 findLSB(u64vec2);" + "ivec3 findLSB(u64vec3);" + "ivec4 findLSB(u64vec4);" + + "int findMSB(int64_t);" + "ivec2 findMSB(i64vec2);" + "ivec3 findMSB(i64vec3);" + "ivec4 findMSB(i64vec4);" + + "int findMSB(uint64_t);" + "ivec2 findMSB(u64vec2);" + "ivec3 findMSB(u64vec3);" + "ivec4 findMSB(u64vec4);" +#endif + "\n" + ); + } + +#ifdef AMD_EXTENSIONS + // GL_AMD_shader_trinary_minmax + if (profile != EEsProfile && version >= 430) { + commonBuiltins.append( + "float min3(float, float, float);" + "vec2 min3(vec2, vec2, vec2);" + "vec3 min3(vec3, vec3, vec3);" + "vec4 min3(vec4, vec4, vec4);" + + "int min3(int, int, int);" + "ivec2 min3(ivec2, ivec2, ivec2);" + "ivec3 min3(ivec3, ivec3, ivec3);" + "ivec4 min3(ivec4, ivec4, ivec4);" + + "uint min3(uint, uint, uint);" + "uvec2 min3(uvec2, uvec2, uvec2);" + "uvec3 min3(uvec3, uvec3, uvec3);" + "uvec4 min3(uvec4, uvec4, uvec4);" + + "float max3(float, float, float);" + "vec2 max3(vec2, vec2, vec2);" + "vec3 max3(vec3, vec3, vec3);" + "vec4 max3(vec4, vec4, vec4);" + + "int max3(int, int, int);" + "ivec2 max3(ivec2, ivec2, ivec2);" + "ivec3 max3(ivec3, ivec3, ivec3);" + "ivec4 max3(ivec4, ivec4, ivec4);" + + "uint max3(uint, uint, uint);" + "uvec2 max3(uvec2, uvec2, uvec2);" + "uvec3 max3(uvec3, uvec3, uvec3);" + "uvec4 max3(uvec4, uvec4, uvec4);" + + "float mid3(float, float, float);" + "vec2 mid3(vec2, vec2, vec2);" + "vec3 mid3(vec3, vec3, vec3);" + "vec4 mid3(vec4, vec4, vec4);" + + "int mid3(int, int, int);" + "ivec2 mid3(ivec2, ivec2, ivec2);" + "ivec3 mid3(ivec3, ivec3, ivec3);" + "ivec4 mid3(ivec4, ivec4, ivec4);" + + "uint mid3(uint, uint, uint);" + "uvec2 mid3(uvec2, uvec2, uvec2);" + "uvec3 mid3(uvec3, uvec3, uvec3);" + "uvec4 mid3(uvec4, uvec4, uvec4);" + + "float16_t min3(float16_t, float16_t, float16_t);" + "f16vec2 min3(f16vec2, f16vec2, f16vec2);" + "f16vec3 min3(f16vec3, f16vec3, f16vec3);" + "f16vec4 min3(f16vec4, f16vec4, f16vec4);" + + "float16_t max3(float16_t, float16_t, float16_t);" + "f16vec2 max3(f16vec2, f16vec2, f16vec2);" + "f16vec3 max3(f16vec3, f16vec3, f16vec3);" + "f16vec4 max3(f16vec4, f16vec4, f16vec4);" + + "float16_t mid3(float16_t, float16_t, float16_t);" + "f16vec2 mid3(f16vec2, f16vec2, f16vec2);" + "f16vec3 mid3(f16vec3, f16vec3, f16vec3);" + "f16vec4 mid3(f16vec4, f16vec4, f16vec4);" + + "\n" + ); + } +#endif + + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 430)) { + commonBuiltins.append( + "uint atomicAdd(coherent volatile inout uint, uint);" + " int atomicAdd(coherent volatile inout int, int);" + + "uint atomicMin(coherent volatile inout uint, uint);" + " int atomicMin(coherent volatile inout int, int);" + + "uint atomicMax(coherent volatile inout uint, uint);" + " int atomicMax(coherent volatile inout int, int);" + + "uint atomicAnd(coherent volatile inout uint, uint);" + " int atomicAnd(coherent volatile inout int, int);" + + "uint atomicOr (coherent volatile inout uint, uint);" + " int atomicOr (coherent volatile inout int, int);" + + "uint atomicXor(coherent volatile inout uint, uint);" + " int atomicXor(coherent volatile inout int, int);" + + "uint atomicExchange(coherent volatile inout uint, uint);" + " int atomicExchange(coherent volatile inout int, int);" + + "uint atomicCompSwap(coherent volatile inout uint, uint, uint);" + " int atomicCompSwap(coherent volatile inout int, int, int);" + + "\n"); + } + +#ifdef NV_EXTENSIONS + if (profile != EEsProfile && version >= 440) { + commonBuiltins.append( + "uint64_t atomicMin(coherent volatile inout uint64_t, uint64_t);" + " int64_t atomicMin(coherent volatile inout int64_t, int64_t);" + + "uint64_t atomicMax(coherent volatile inout uint64_t, uint64_t);" + " int64_t atomicMax(coherent volatile inout int64_t, int64_t);" + + "uint64_t atomicAnd(coherent volatile inout uint64_t, uint64_t);" + " int64_t atomicAnd(coherent volatile inout int64_t, int64_t);" + + "uint64_t atomicOr (coherent volatile inout uint64_t, uint64_t);" + " int64_t atomicOr (coherent volatile inout int64_t, int64_t);" + + "uint64_t atomicXor(coherent volatile inout uint64_t, uint64_t);" + " int64_t atomicXor(coherent volatile inout int64_t, int64_t);" + + " int64_t atomicAdd(coherent volatile inout int64_t, int64_t);" + " int64_t atomicExchange(coherent volatile inout int64_t, int64_t);" + " int64_t atomicCompSwap(coherent volatile inout int64_t, int64_t, int64_t);" + + "\n"); + } +#endif + + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 450)) { + commonBuiltins.append( + "int mix(int x, int y, bool a);" + "ivec2 mix(ivec2 x, ivec2 y, bvec2 a);" + "ivec3 mix(ivec3 x, ivec3 y, bvec3 a);" + "ivec4 mix(ivec4 x, ivec4 y, bvec4 a);" + + "uint mix(uint x, uint y, bool a);" + "uvec2 mix(uvec2 x, uvec2 y, bvec2 a);" + "uvec3 mix(uvec3 x, uvec3 y, bvec3 a);" + "uvec4 mix(uvec4 x, uvec4 y, bvec4 a);" + + "bool mix(bool x, bool y, bool a);" + "bvec2 mix(bvec2 x, bvec2 y, bvec2 a);" + "bvec3 mix(bvec3 x, bvec3 y, bvec3 a);" + "bvec4 mix(bvec4 x, bvec4 y, bvec4 a);" + + "\n"); + } + + if ((profile == EEsProfile && version >= 300) || + (profile != EEsProfile && version >= 330)) { + commonBuiltins.append( + "int floatBitsToInt(highp float value);" + "ivec2 floatBitsToInt(highp vec2 value);" + "ivec3 floatBitsToInt(highp vec3 value);" + "ivec4 floatBitsToInt(highp vec4 value);" + + "uint floatBitsToUint(highp float value);" + "uvec2 floatBitsToUint(highp vec2 value);" + "uvec3 floatBitsToUint(highp vec3 value);" + "uvec4 floatBitsToUint(highp vec4 value);" + + "float intBitsToFloat(highp int value);" + "vec2 intBitsToFloat(highp ivec2 value);" + "vec3 intBitsToFloat(highp ivec3 value);" + "vec4 intBitsToFloat(highp ivec4 value);" + + "float uintBitsToFloat(highp uint value);" + "vec2 uintBitsToFloat(highp uvec2 value);" + "vec3 uintBitsToFloat(highp uvec3 value);" + "vec4 uintBitsToFloat(highp uvec4 value);" + + "\n"); + } + + if ((profile != EEsProfile && version >= 400) || + (profile == EEsProfile && version >= 310)) { // GL_OES_gpu_shader5 + + commonBuiltins.append( + "float fma(float, float, float );" + "vec2 fma(vec2, vec2, vec2 );" + "vec3 fma(vec3, vec3, vec3 );" + "vec4 fma(vec4, vec4, vec4 );" + "\n"); + + if (profile != EEsProfile) { + commonBuiltins.append( + "double fma(double, double, double);" + "dvec2 fma(dvec2, dvec2, dvec2 );" + "dvec3 fma(dvec3, dvec3, dvec3 );" + "dvec4 fma(dvec4, dvec4, dvec4 );" + "\n"); + } + } + + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 400)) { + commonBuiltins.append( + "float frexp(highp float, out highp int);" + "vec2 frexp(highp vec2, out highp ivec2);" + "vec3 frexp(highp vec3, out highp ivec3);" + "vec4 frexp(highp vec4, out highp ivec4);" + + "float ldexp(highp float, highp int);" + "vec2 ldexp(highp vec2, highp ivec2);" + "vec3 ldexp(highp vec3, highp ivec3);" + "vec4 ldexp(highp vec4, highp ivec4);" + + "\n"); + } + + if (profile != EEsProfile && version >= 400) { + commonBuiltins.append( + "double frexp(double, out int);" + "dvec2 frexp( dvec2, out ivec2);" + "dvec3 frexp( dvec3, out ivec3);" + "dvec4 frexp( dvec4, out ivec4);" + + "double ldexp(double, int);" + "dvec2 ldexp( dvec2, ivec2);" + "dvec3 ldexp( dvec3, ivec3);" + "dvec4 ldexp( dvec4, ivec4);" + + "double packDouble2x32(uvec2);" + "uvec2 unpackDouble2x32(double);" + + "\n"); + } + + if ((profile == EEsProfile && version >= 300) || + (profile != EEsProfile && version >= 400)) { + commonBuiltins.append( + "highp uint packUnorm2x16(vec2);" + "vec2 unpackUnorm2x16(highp uint);" + "\n"); + } + + if ((profile == EEsProfile && version >= 300) || + (profile != EEsProfile && version >= 420)) { + commonBuiltins.append( + "highp uint packSnorm2x16(vec2);" + " vec2 unpackSnorm2x16(highp uint);" + "highp uint packHalf2x16(vec2);" + "\n"); + } + + if (profile == EEsProfile && version >= 300) { + commonBuiltins.append( + "mediump vec2 unpackHalf2x16(highp uint);" + "\n"); + } else if (profile != EEsProfile && version >= 420) { + commonBuiltins.append( + " vec2 unpackHalf2x16(highp uint);" + "\n"); + } + + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 400)) { + commonBuiltins.append( + "highp uint packSnorm4x8(vec4);" + "highp uint packUnorm4x8(vec4);" + "\n"); + } + + if (profile == EEsProfile && version >= 310) { + commonBuiltins.append( + "mediump vec4 unpackSnorm4x8(highp uint);" + "mediump vec4 unpackUnorm4x8(highp uint);" + "\n"); + } else if (profile != EEsProfile && version >= 400) { + commonBuiltins.append( + "vec4 unpackSnorm4x8(highp uint);" + "vec4 unpackUnorm4x8(highp uint);" + "\n"); + } + + // + // Geometric Functions. + // + commonBuiltins.append( + "float length(float x);" + "float length(vec2 x);" + "float length(vec3 x);" + "float length(vec4 x);" + + "float distance(float p0, float p1);" + "float distance(vec2 p0, vec2 p1);" + "float distance(vec3 p0, vec3 p1);" + "float distance(vec4 p0, vec4 p1);" + + "float dot(float x, float y);" + "float dot(vec2 x, vec2 y);" + "float dot(vec3 x, vec3 y);" + "float dot(vec4 x, vec4 y);" + + "vec3 cross(vec3 x, vec3 y);" + "float normalize(float x);" + "vec2 normalize(vec2 x);" + "vec3 normalize(vec3 x);" + "vec4 normalize(vec4 x);" + + "float faceforward(float N, float I, float Nref);" + "vec2 faceforward(vec2 N, vec2 I, vec2 Nref);" + "vec3 faceforward(vec3 N, vec3 I, vec3 Nref);" + "vec4 faceforward(vec4 N, vec4 I, vec4 Nref);" + + "float reflect(float I, float N);" + "vec2 reflect(vec2 I, vec2 N);" + "vec3 reflect(vec3 I, vec3 N);" + "vec4 reflect(vec4 I, vec4 N);" + + "float refract(float I, float N, float eta);" + "vec2 refract(vec2 I, vec2 N, float eta);" + "vec3 refract(vec3 I, vec3 N, float eta);" + "vec4 refract(vec4 I, vec4 N, float eta);" + + "\n"); + + // + // Matrix Functions. + // + commonBuiltins.append( + "mat2 matrixCompMult(mat2 x, mat2 y);" + "mat3 matrixCompMult(mat3 x, mat3 y);" + "mat4 matrixCompMult(mat4 x, mat4 y);" + + "\n"); + + // 120 is correct for both ES and desktop + if (version >= 120) { + commonBuiltins.append( + "mat2 outerProduct(vec2 c, vec2 r);" + "mat3 outerProduct(vec3 c, vec3 r);" + "mat4 outerProduct(vec4 c, vec4 r);" + "mat2x3 outerProduct(vec3 c, vec2 r);" + "mat3x2 outerProduct(vec2 c, vec3 r);" + "mat2x4 outerProduct(vec4 c, vec2 r);" + "mat4x2 outerProduct(vec2 c, vec4 r);" + "mat3x4 outerProduct(vec4 c, vec3 r);" + "mat4x3 outerProduct(vec3 c, vec4 r);" + + "mat2 transpose(mat2 m);" + "mat3 transpose(mat3 m);" + "mat4 transpose(mat4 m);" + "mat2x3 transpose(mat3x2 m);" + "mat3x2 transpose(mat2x3 m);" + "mat2x4 transpose(mat4x2 m);" + "mat4x2 transpose(mat2x4 m);" + "mat3x4 transpose(mat4x3 m);" + "mat4x3 transpose(mat3x4 m);" + + "mat2x3 matrixCompMult(mat2x3, mat2x3);" + "mat2x4 matrixCompMult(mat2x4, mat2x4);" + "mat3x2 matrixCompMult(mat3x2, mat3x2);" + "mat3x4 matrixCompMult(mat3x4, mat3x4);" + "mat4x2 matrixCompMult(mat4x2, mat4x2);" + "mat4x3 matrixCompMult(mat4x3, mat4x3);" + + "\n"); + + // 150 is correct for both ES and desktop + if (version >= 150) { + commonBuiltins.append( + "float determinant(mat2 m);" + "float determinant(mat3 m);" + "float determinant(mat4 m);" + + "mat2 inverse(mat2 m);" + "mat3 inverse(mat3 m);" + "mat4 inverse(mat4 m);" + + "\n"); + } + } + + // + // Vector relational functions. + // + commonBuiltins.append( + "bvec2 lessThan(vec2 x, vec2 y);" + "bvec3 lessThan(vec3 x, vec3 y);" + "bvec4 lessThan(vec4 x, vec4 y);" + + "bvec2 lessThan(ivec2 x, ivec2 y);" + "bvec3 lessThan(ivec3 x, ivec3 y);" + "bvec4 lessThan(ivec4 x, ivec4 y);" + + "bvec2 lessThanEqual(vec2 x, vec2 y);" + "bvec3 lessThanEqual(vec3 x, vec3 y);" + "bvec4 lessThanEqual(vec4 x, vec4 y);" + + "bvec2 lessThanEqual(ivec2 x, ivec2 y);" + "bvec3 lessThanEqual(ivec3 x, ivec3 y);" + "bvec4 lessThanEqual(ivec4 x, ivec4 y);" + + "bvec2 greaterThan(vec2 x, vec2 y);" + "bvec3 greaterThan(vec3 x, vec3 y);" + "bvec4 greaterThan(vec4 x, vec4 y);" + + "bvec2 greaterThan(ivec2 x, ivec2 y);" + "bvec3 greaterThan(ivec3 x, ivec3 y);" + "bvec4 greaterThan(ivec4 x, ivec4 y);" + + "bvec2 greaterThanEqual(vec2 x, vec2 y);" + "bvec3 greaterThanEqual(vec3 x, vec3 y);" + "bvec4 greaterThanEqual(vec4 x, vec4 y);" + + "bvec2 greaterThanEqual(ivec2 x, ivec2 y);" + "bvec3 greaterThanEqual(ivec3 x, ivec3 y);" + "bvec4 greaterThanEqual(ivec4 x, ivec4 y);" + + "bvec2 equal(vec2 x, vec2 y);" + "bvec3 equal(vec3 x, vec3 y);" + "bvec4 equal(vec4 x, vec4 y);" + + "bvec2 equal(ivec2 x, ivec2 y);" + "bvec3 equal(ivec3 x, ivec3 y);" + "bvec4 equal(ivec4 x, ivec4 y);" + + "bvec2 equal(bvec2 x, bvec2 y);" + "bvec3 equal(bvec3 x, bvec3 y);" + "bvec4 equal(bvec4 x, bvec4 y);" + + "bvec2 notEqual(vec2 x, vec2 y);" + "bvec3 notEqual(vec3 x, vec3 y);" + "bvec4 notEqual(vec4 x, vec4 y);" + + "bvec2 notEqual(ivec2 x, ivec2 y);" + "bvec3 notEqual(ivec3 x, ivec3 y);" + "bvec4 notEqual(ivec4 x, ivec4 y);" + + "bvec2 notEqual(bvec2 x, bvec2 y);" + "bvec3 notEqual(bvec3 x, bvec3 y);" + "bvec4 notEqual(bvec4 x, bvec4 y);" + + "bool any(bvec2 x);" + "bool any(bvec3 x);" + "bool any(bvec4 x);" + + "bool all(bvec2 x);" + "bool all(bvec3 x);" + "bool all(bvec4 x);" + + "bvec2 not(bvec2 x);" + "bvec3 not(bvec3 x);" + "bvec4 not(bvec4 x);" + + "\n"); + + if (version >= 130) { + commonBuiltins.append( + "bvec2 lessThan(uvec2 x, uvec2 y);" + "bvec3 lessThan(uvec3 x, uvec3 y);" + "bvec4 lessThan(uvec4 x, uvec4 y);" + + "bvec2 lessThanEqual(uvec2 x, uvec2 y);" + "bvec3 lessThanEqual(uvec3 x, uvec3 y);" + "bvec4 lessThanEqual(uvec4 x, uvec4 y);" + + "bvec2 greaterThan(uvec2 x, uvec2 y);" + "bvec3 greaterThan(uvec3 x, uvec3 y);" + "bvec4 greaterThan(uvec4 x, uvec4 y);" + + "bvec2 greaterThanEqual(uvec2 x, uvec2 y);" + "bvec3 greaterThanEqual(uvec3 x, uvec3 y);" + "bvec4 greaterThanEqual(uvec4 x, uvec4 y);" + + "bvec2 equal(uvec2 x, uvec2 y);" + "bvec3 equal(uvec3 x, uvec3 y);" + "bvec4 equal(uvec4 x, uvec4 y);" + + "bvec2 notEqual(uvec2 x, uvec2 y);" + "bvec3 notEqual(uvec3 x, uvec3 y);" + "bvec4 notEqual(uvec4 x, uvec4 y);" + + "\n"); + } + + // + // Original-style texture functions existing in all stages. + // (Per-stage functions below.) + // + if ((profile == EEsProfile && version == 100) || + profile == ECompatibilityProfile || + (profile == ECoreProfile && version < 420) || + profile == ENoProfile) { + if (spvVersion.spv == 0) { + commonBuiltins.append( + "vec4 texture2D(sampler2D, vec2);" + + "vec4 texture2DProj(sampler2D, vec3);" + "vec4 texture2DProj(sampler2D, vec4);" + + "vec4 texture3D(sampler3D, vec3);" // OES_texture_3D, but caught by keyword check + "vec4 texture3DProj(sampler3D, vec4);" // OES_texture_3D, but caught by keyword check + + "vec4 textureCube(samplerCube, vec3);" + + "vec4 texture2DArray(sampler2DArray, vec3);" // GL_EXT_texture_array + + "\n"); + } + } + + if ( profile == ECompatibilityProfile || + (profile == ECoreProfile && version < 420) || + profile == ENoProfile) { + if (spvVersion.spv == 0) { + commonBuiltins.append( + "vec4 texture1D(sampler1D, float);" + + "vec4 texture1DProj(sampler1D, vec2);" + "vec4 texture1DProj(sampler1D, vec4);" + + "vec4 shadow1D(sampler1DShadow, vec3);" + "vec4 shadow2D(sampler2DShadow, vec3);" + "vec4 shadow1DProj(sampler1DShadow, vec4);" + "vec4 shadow2DProj(sampler2DShadow, vec4);" + + "vec4 texture2DRect(sampler2DRect, vec2);" // GL_ARB_texture_rectangle, caught by keyword check + "vec4 texture2DRectProj(sampler2DRect, vec3);" // GL_ARB_texture_rectangle, caught by keyword check + "vec4 texture2DRectProj(sampler2DRect, vec4);" // GL_ARB_texture_rectangle, caught by keyword check + "vec4 shadow2DRect(sampler2DRectShadow, vec3);" // GL_ARB_texture_rectangle, caught by keyword check + "vec4 shadow2DRectProj(sampler2DRectShadow, vec4);" // GL_ARB_texture_rectangle, caught by keyword check + + "vec4 texture1DArray(sampler1DArray, vec2);" // GL_EXT_texture_array + "vec4 shadow1DArray(sampler1DArrayShadow, vec3);" // GL_EXT_texture_array + "vec4 shadow2DArray(sampler2DArrayShadow, vec4);" // GL_EXT_texture_array + + "\n"); + } + } + + if (profile == EEsProfile) { + if (spvVersion.spv == 0) { + if (version < 300) { + commonBuiltins.append( + "vec4 texture2D(samplerExternalOES, vec2 coord);" // GL_OES_EGL_image_external + "vec4 texture2DProj(samplerExternalOES, vec3);" // GL_OES_EGL_image_external + "vec4 texture2DProj(samplerExternalOES, vec4);" // GL_OES_EGL_image_external + "\n"); + } else { + commonBuiltins.append( + "highp ivec2 textureSize(samplerExternalOES, int lod);" // GL_OES_EGL_image_external_essl3 + "vec4 texture(samplerExternalOES, vec2);" // GL_OES_EGL_image_external_essl3 + "vec4 texture(samplerExternalOES, vec2, float bias);" // GL_OES_EGL_image_external_essl3 + "vec4 textureProj(samplerExternalOES, vec3);" // GL_OES_EGL_image_external_essl3 + "vec4 textureProj(samplerExternalOES, vec3, float bias);" // GL_OES_EGL_image_external_essl3 + "vec4 textureProj(samplerExternalOES, vec4);" // GL_OES_EGL_image_external_essl3 + "vec4 textureProj(samplerExternalOES, vec4, float bias);" // GL_OES_EGL_image_external_essl3 + "vec4 texelFetch(samplerExternalOES, ivec2, int lod);" // GL_OES_EGL_image_external_essl3 + "\n"); + } + commonBuiltins.append( + "vec4 texture2DGradEXT(sampler2D, vec2, vec2, vec2);" // GL_EXT_shader_texture_lod + "vec4 texture2DProjGradEXT(sampler2D, vec3, vec2, vec2);" // GL_EXT_shader_texture_lod + "vec4 texture2DProjGradEXT(sampler2D, vec4, vec2, vec2);" // GL_EXT_shader_texture_lod + "vec4 textureCubeGradEXT(samplerCube, vec3, vec3, vec3);" // GL_EXT_shader_texture_lod + + "float shadow2DEXT(sampler2DShadow, vec3);" // GL_EXT_shadow_samplers + "float shadow2DProjEXT(sampler2DShadow, vec4);" // GL_EXT_shadow_samplers + + "\n"); + } + } + + // + // Noise functions. + // + if (spvVersion.spv == 0 && profile != EEsProfile) { + commonBuiltins.append( + "float noise1(float x);" + "float noise1(vec2 x);" + "float noise1(vec3 x);" + "float noise1(vec4 x);" + + "vec2 noise2(float x);" + "vec2 noise2(vec2 x);" + "vec2 noise2(vec3 x);" + "vec2 noise2(vec4 x);" + + "vec3 noise3(float x);" + "vec3 noise3(vec2 x);" + "vec3 noise3(vec3 x);" + "vec3 noise3(vec4 x);" + + "vec4 noise4(float x);" + "vec4 noise4(vec2 x);" + "vec4 noise4(vec3 x);" + "vec4 noise4(vec4 x);" + + "\n"); + } + + if (spvVersion.vulkan == 0) { + // + // Atomic counter functions. + // + if ((profile != EEsProfile && version >= 300) || + (profile == EEsProfile && version >= 310)) { + commonBuiltins.append( + "uint atomicCounterIncrement(atomic_uint);" + "uint atomicCounterDecrement(atomic_uint);" + "uint atomicCounter(atomic_uint);" + + "\n"); + } + if (profile != EEsProfile && version >= 460) { + commonBuiltins.append( + "uint atomicCounterAdd(atomic_uint, uint);" + "uint atomicCounterSubtract(atomic_uint, uint);" + "uint atomicCounterMin(atomic_uint, uint);" + "uint atomicCounterMax(atomic_uint, uint);" + "uint atomicCounterAnd(atomic_uint, uint);" + "uint atomicCounterOr(atomic_uint, uint);" + "uint atomicCounterXor(atomic_uint, uint);" + "uint atomicCounterExchange(atomic_uint, uint);" + "uint atomicCounterCompSwap(atomic_uint, uint, uint);" + + "\n"); + } + } + + // Bitfield + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 400)) { + commonBuiltins.append( + " int bitfieldExtract( int, int, int);" + "ivec2 bitfieldExtract(ivec2, int, int);" + "ivec3 bitfieldExtract(ivec3, int, int);" + "ivec4 bitfieldExtract(ivec4, int, int);" + + " uint bitfieldExtract( uint, int, int);" + "uvec2 bitfieldExtract(uvec2, int, int);" + "uvec3 bitfieldExtract(uvec3, int, int);" + "uvec4 bitfieldExtract(uvec4, int, int);" + + " int bitfieldInsert( int base, int, int, int);" + "ivec2 bitfieldInsert(ivec2 base, ivec2, int, int);" + "ivec3 bitfieldInsert(ivec3 base, ivec3, int, int);" + "ivec4 bitfieldInsert(ivec4 base, ivec4, int, int);" + + " uint bitfieldInsert( uint base, uint, int, int);" + "uvec2 bitfieldInsert(uvec2 base, uvec2, int, int);" + "uvec3 bitfieldInsert(uvec3 base, uvec3, int, int);" + "uvec4 bitfieldInsert(uvec4 base, uvec4, int, int);" + + "\n"); + } + + if (profile != EEsProfile && version >= 400) { + commonBuiltins.append( + " int findLSB( int);" + "ivec2 findLSB(ivec2);" + "ivec3 findLSB(ivec3);" + "ivec4 findLSB(ivec4);" + + " int findLSB( uint);" + "ivec2 findLSB(uvec2);" + "ivec3 findLSB(uvec3);" + "ivec4 findLSB(uvec4);" + + "\n"); + } else if (profile == EEsProfile && version >= 310) { + commonBuiltins.append( + "lowp int findLSB( int);" + "lowp ivec2 findLSB(ivec2);" + "lowp ivec3 findLSB(ivec3);" + "lowp ivec4 findLSB(ivec4);" + + "lowp int findLSB( uint);" + "lowp ivec2 findLSB(uvec2);" + "lowp ivec3 findLSB(uvec3);" + "lowp ivec4 findLSB(uvec4);" + + "\n"); + } + + if (profile != EEsProfile && version >= 400) { + commonBuiltins.append( + " int bitCount( int);" + "ivec2 bitCount(ivec2);" + "ivec3 bitCount(ivec3);" + "ivec4 bitCount(ivec4);" + + " int bitCount( uint);" + "ivec2 bitCount(uvec2);" + "ivec3 bitCount(uvec3);" + "ivec4 bitCount(uvec4);" + + " int findMSB(highp int);" + "ivec2 findMSB(highp ivec2);" + "ivec3 findMSB(highp ivec3);" + "ivec4 findMSB(highp ivec4);" + + " int findMSB(highp uint);" + "ivec2 findMSB(highp uvec2);" + "ivec3 findMSB(highp uvec3);" + "ivec4 findMSB(highp uvec4);" + + "\n"); + } + + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 400)) { + commonBuiltins.append( + " uint uaddCarry(highp uint, highp uint, out lowp uint carry);" + "uvec2 uaddCarry(highp uvec2, highp uvec2, out lowp uvec2 carry);" + "uvec3 uaddCarry(highp uvec3, highp uvec3, out lowp uvec3 carry);" + "uvec4 uaddCarry(highp uvec4, highp uvec4, out lowp uvec4 carry);" + + " uint usubBorrow(highp uint, highp uint, out lowp uint borrow);" + "uvec2 usubBorrow(highp uvec2, highp uvec2, out lowp uvec2 borrow);" + "uvec3 usubBorrow(highp uvec3, highp uvec3, out lowp uvec3 borrow);" + "uvec4 usubBorrow(highp uvec4, highp uvec4, out lowp uvec4 borrow);" + + "void umulExtended(highp uint, highp uint, out highp uint, out highp uint lsb);" + "void umulExtended(highp uvec2, highp uvec2, out highp uvec2, out highp uvec2 lsb);" + "void umulExtended(highp uvec3, highp uvec3, out highp uvec3, out highp uvec3 lsb);" + "void umulExtended(highp uvec4, highp uvec4, out highp uvec4, out highp uvec4 lsb);" + + "void imulExtended(highp int, highp int, out highp int, out highp int lsb);" + "void imulExtended(highp ivec2, highp ivec2, out highp ivec2, out highp ivec2 lsb);" + "void imulExtended(highp ivec3, highp ivec3, out highp ivec3, out highp ivec3 lsb);" + "void imulExtended(highp ivec4, highp ivec4, out highp ivec4, out highp ivec4 lsb);" + + " int bitfieldReverse(highp int);" + "ivec2 bitfieldReverse(highp ivec2);" + "ivec3 bitfieldReverse(highp ivec3);" + "ivec4 bitfieldReverse(highp ivec4);" + + " uint bitfieldReverse(highp uint);" + "uvec2 bitfieldReverse(highp uvec2);" + "uvec3 bitfieldReverse(highp uvec3);" + "uvec4 bitfieldReverse(highp uvec4);" + + "\n"); + } + + if (profile == EEsProfile && version >= 310) { + commonBuiltins.append( + "lowp int bitCount( int);" + "lowp ivec2 bitCount(ivec2);" + "lowp ivec3 bitCount(ivec3);" + "lowp ivec4 bitCount(ivec4);" + + "lowp int bitCount( uint);" + "lowp ivec2 bitCount(uvec2);" + "lowp ivec3 bitCount(uvec3);" + "lowp ivec4 bitCount(uvec4);" + + "lowp int findMSB(highp int);" + "lowp ivec2 findMSB(highp ivec2);" + "lowp ivec3 findMSB(highp ivec3);" + "lowp ivec4 findMSB(highp ivec4);" + + "lowp int findMSB(highp uint);" + "lowp ivec2 findMSB(highp uvec2);" + "lowp ivec3 findMSB(highp uvec3);" + "lowp ivec4 findMSB(highp uvec4);" + + "\n"); + } + + // GL_ARB_shader_ballot + if (profile != EEsProfile && version >= 450) { + commonBuiltins.append( + "uint64_t ballotARB(bool);" + + "float readInvocationARB(float, uint);" + "vec2 readInvocationARB(vec2, uint);" + "vec3 readInvocationARB(vec3, uint);" + "vec4 readInvocationARB(vec4, uint);" + + "int readInvocationARB(int, uint);" + "ivec2 readInvocationARB(ivec2, uint);" + "ivec3 readInvocationARB(ivec3, uint);" + "ivec4 readInvocationARB(ivec4, uint);" + + "uint readInvocationARB(uint, uint);" + "uvec2 readInvocationARB(uvec2, uint);" + "uvec3 readInvocationARB(uvec3, uint);" + "uvec4 readInvocationARB(uvec4, uint);" + + "float readFirstInvocationARB(float);" + "vec2 readFirstInvocationARB(vec2);" + "vec3 readFirstInvocationARB(vec3);" + "vec4 readFirstInvocationARB(vec4);" + + "int readFirstInvocationARB(int);" + "ivec2 readFirstInvocationARB(ivec2);" + "ivec3 readFirstInvocationARB(ivec3);" + "ivec4 readFirstInvocationARB(ivec4);" + + "uint readFirstInvocationARB(uint);" + "uvec2 readFirstInvocationARB(uvec2);" + "uvec3 readFirstInvocationARB(uvec3);" + "uvec4 readFirstInvocationARB(uvec4);" + + "\n"); + } + + // GL_ARB_shader_group_vote + if (profile != EEsProfile && version >= 430) { + commonBuiltins.append( + "bool anyInvocationARB(bool);" + "bool allInvocationsARB(bool);" + "bool allInvocationsEqualARB(bool);" + + "\n"); + } + + if (profile != EEsProfile && version >= 460) { + commonBuiltins.append( + "bool anyInvocation(bool);" + "bool allInvocations(bool);" + "bool allInvocationsEqual(bool);" + + "\n"); + } + +#ifdef AMD_EXTENSIONS + // GL_AMD_shader_ballot + if (profile != EEsProfile && version >= 450) { + commonBuiltins.append( + "float minInvocationsAMD(float);" + "vec2 minInvocationsAMD(vec2);" + "vec3 minInvocationsAMD(vec3);" + "vec4 minInvocationsAMD(vec4);" + + "int minInvocationsAMD(int);" + "ivec2 minInvocationsAMD(ivec2);" + "ivec3 minInvocationsAMD(ivec3);" + "ivec4 minInvocationsAMD(ivec4);" + + "uint minInvocationsAMD(uint);" + "uvec2 minInvocationsAMD(uvec2);" + "uvec3 minInvocationsAMD(uvec3);" + "uvec4 minInvocationsAMD(uvec4);" + + "double minInvocationsAMD(double);" + "dvec2 minInvocationsAMD(dvec2);" + "dvec3 minInvocationsAMD(dvec3);" + "dvec4 minInvocationsAMD(dvec4);" + + "int64_t minInvocationsAMD(int64_t);" + "i64vec2 minInvocationsAMD(i64vec2);" + "i64vec3 minInvocationsAMD(i64vec3);" + "i64vec4 minInvocationsAMD(i64vec4);" + + "uint64_t minInvocationsAMD(uint64_t);" + "u64vec2 minInvocationsAMD(u64vec2);" + "u64vec3 minInvocationsAMD(u64vec3);" + "u64vec4 minInvocationsAMD(u64vec4);" + + "float16_t minInvocationsAMD(float16_t);" + "f16vec2 minInvocationsAMD(f16vec2);" + "f16vec3 minInvocationsAMD(f16vec3);" + "f16vec4 minInvocationsAMD(f16vec4);" + + "float minInvocationsInclusiveScanAMD(float);" + "vec2 minInvocationsInclusiveScanAMD(vec2);" + "vec3 minInvocationsInclusiveScanAMD(vec3);" + "vec4 minInvocationsInclusiveScanAMD(vec4);" + + "int minInvocationsInclusiveScanAMD(int);" + "ivec2 minInvocationsInclusiveScanAMD(ivec2);" + "ivec3 minInvocationsInclusiveScanAMD(ivec3);" + "ivec4 minInvocationsInclusiveScanAMD(ivec4);" + + "uint minInvocationsInclusiveScanAMD(uint);" + "uvec2 minInvocationsInclusiveScanAMD(uvec2);" + "uvec3 minInvocationsInclusiveScanAMD(uvec3);" + "uvec4 minInvocationsInclusiveScanAMD(uvec4);" + + "double minInvocationsInclusiveScanAMD(double);" + "dvec2 minInvocationsInclusiveScanAMD(dvec2);" + "dvec3 minInvocationsInclusiveScanAMD(dvec3);" + "dvec4 minInvocationsInclusiveScanAMD(dvec4);" + + "int64_t minInvocationsInclusiveScanAMD(int64_t);" + "i64vec2 minInvocationsInclusiveScanAMD(i64vec2);" + "i64vec3 minInvocationsInclusiveScanAMD(i64vec3);" + "i64vec4 minInvocationsInclusiveScanAMD(i64vec4);" + + "uint64_t minInvocationsInclusiveScanAMD(uint64_t);" + "u64vec2 minInvocationsInclusiveScanAMD(u64vec2);" + "u64vec3 minInvocationsInclusiveScanAMD(u64vec3);" + "u64vec4 minInvocationsInclusiveScanAMD(u64vec4);" + + "float16_t minInvocationsInclusiveScanAMD(float16_t);" + "f16vec2 minInvocationsInclusiveScanAMD(f16vec2);" + "f16vec3 minInvocationsInclusiveScanAMD(f16vec3);" + "f16vec4 minInvocationsInclusiveScanAMD(f16vec4);" + + "float minInvocationsExclusiveScanAMD(float);" + "vec2 minInvocationsExclusiveScanAMD(vec2);" + "vec3 minInvocationsExclusiveScanAMD(vec3);" + "vec4 minInvocationsExclusiveScanAMD(vec4);" + + "int minInvocationsExclusiveScanAMD(int);" + "ivec2 minInvocationsExclusiveScanAMD(ivec2);" + "ivec3 minInvocationsExclusiveScanAMD(ivec3);" + "ivec4 minInvocationsExclusiveScanAMD(ivec4);" + + "uint minInvocationsExclusiveScanAMD(uint);" + "uvec2 minInvocationsExclusiveScanAMD(uvec2);" + "uvec3 minInvocationsExclusiveScanAMD(uvec3);" + "uvec4 minInvocationsExclusiveScanAMD(uvec4);" + + "double minInvocationsExclusiveScanAMD(double);" + "dvec2 minInvocationsExclusiveScanAMD(dvec2);" + "dvec3 minInvocationsExclusiveScanAMD(dvec3);" + "dvec4 minInvocationsExclusiveScanAMD(dvec4);" + + "int64_t minInvocationsExclusiveScanAMD(int64_t);" + "i64vec2 minInvocationsExclusiveScanAMD(i64vec2);" + "i64vec3 minInvocationsExclusiveScanAMD(i64vec3);" + "i64vec4 minInvocationsExclusiveScanAMD(i64vec4);" + + "uint64_t minInvocationsExclusiveScanAMD(uint64_t);" + "u64vec2 minInvocationsExclusiveScanAMD(u64vec2);" + "u64vec3 minInvocationsExclusiveScanAMD(u64vec3);" + "u64vec4 minInvocationsExclusiveScanAMD(u64vec4);" + + "float16_t minInvocationsExclusiveScanAMD(float16_t);" + "f16vec2 minInvocationsExclusiveScanAMD(f16vec2);" + "f16vec3 minInvocationsExclusiveScanAMD(f16vec3);" + "f16vec4 minInvocationsExclusiveScanAMD(f16vec4);" + + "float maxInvocationsAMD(float);" + "vec2 maxInvocationsAMD(vec2);" + "vec3 maxInvocationsAMD(vec3);" + "vec4 maxInvocationsAMD(vec4);" + + "int maxInvocationsAMD(int);" + "ivec2 maxInvocationsAMD(ivec2);" + "ivec3 maxInvocationsAMD(ivec3);" + "ivec4 maxInvocationsAMD(ivec4);" + + "uint maxInvocationsAMD(uint);" + "uvec2 maxInvocationsAMD(uvec2);" + "uvec3 maxInvocationsAMD(uvec3);" + "uvec4 maxInvocationsAMD(uvec4);" + + "double maxInvocationsAMD(double);" + "dvec2 maxInvocationsAMD(dvec2);" + "dvec3 maxInvocationsAMD(dvec3);" + "dvec4 maxInvocationsAMD(dvec4);" + + "int64_t maxInvocationsAMD(int64_t);" + "i64vec2 maxInvocationsAMD(i64vec2);" + "i64vec3 maxInvocationsAMD(i64vec3);" + "i64vec4 maxInvocationsAMD(i64vec4);" + + "uint64_t maxInvocationsAMD(uint64_t);" + "u64vec2 maxInvocationsAMD(u64vec2);" + "u64vec3 maxInvocationsAMD(u64vec3);" + "u64vec4 maxInvocationsAMD(u64vec4);" + + "float16_t maxInvocationsAMD(float16_t);" + "f16vec2 maxInvocationsAMD(f16vec2);" + "f16vec3 maxInvocationsAMD(f16vec3);" + "f16vec4 maxInvocationsAMD(f16vec4);" + + "float maxInvocationsInclusiveScanAMD(float);" + "vec2 maxInvocationsInclusiveScanAMD(vec2);" + "vec3 maxInvocationsInclusiveScanAMD(vec3);" + "vec4 maxInvocationsInclusiveScanAMD(vec4);" + + "int maxInvocationsInclusiveScanAMD(int);" + "ivec2 maxInvocationsInclusiveScanAMD(ivec2);" + "ivec3 maxInvocationsInclusiveScanAMD(ivec3);" + "ivec4 maxInvocationsInclusiveScanAMD(ivec4);" + + "uint maxInvocationsInclusiveScanAMD(uint);" + "uvec2 maxInvocationsInclusiveScanAMD(uvec2);" + "uvec3 maxInvocationsInclusiveScanAMD(uvec3);" + "uvec4 maxInvocationsInclusiveScanAMD(uvec4);" + + "double maxInvocationsInclusiveScanAMD(double);" + "dvec2 maxInvocationsInclusiveScanAMD(dvec2);" + "dvec3 maxInvocationsInclusiveScanAMD(dvec3);" + "dvec4 maxInvocationsInclusiveScanAMD(dvec4);" + + "int64_t maxInvocationsInclusiveScanAMD(int64_t);" + "i64vec2 maxInvocationsInclusiveScanAMD(i64vec2);" + "i64vec3 maxInvocationsInclusiveScanAMD(i64vec3);" + "i64vec4 maxInvocationsInclusiveScanAMD(i64vec4);" + + "uint64_t maxInvocationsInclusiveScanAMD(uint64_t);" + "u64vec2 maxInvocationsInclusiveScanAMD(u64vec2);" + "u64vec3 maxInvocationsInclusiveScanAMD(u64vec3);" + "u64vec4 maxInvocationsInclusiveScanAMD(u64vec4);" + + "float16_t maxInvocationsInclusiveScanAMD(float16_t);" + "f16vec2 maxInvocationsInclusiveScanAMD(f16vec2);" + "f16vec3 maxInvocationsInclusiveScanAMD(f16vec3);" + "f16vec4 maxInvocationsInclusiveScanAMD(f16vec4);" + + "float maxInvocationsExclusiveScanAMD(float);" + "vec2 maxInvocationsExclusiveScanAMD(vec2);" + "vec3 maxInvocationsExclusiveScanAMD(vec3);" + "vec4 maxInvocationsExclusiveScanAMD(vec4);" + + "int maxInvocationsExclusiveScanAMD(int);" + "ivec2 maxInvocationsExclusiveScanAMD(ivec2);" + "ivec3 maxInvocationsExclusiveScanAMD(ivec3);" + "ivec4 maxInvocationsExclusiveScanAMD(ivec4);" + + "uint maxInvocationsExclusiveScanAMD(uint);" + "uvec2 maxInvocationsExclusiveScanAMD(uvec2);" + "uvec3 maxInvocationsExclusiveScanAMD(uvec3);" + "uvec4 maxInvocationsExclusiveScanAMD(uvec4);" + + "double maxInvocationsExclusiveScanAMD(double);" + "dvec2 maxInvocationsExclusiveScanAMD(dvec2);" + "dvec3 maxInvocationsExclusiveScanAMD(dvec3);" + "dvec4 maxInvocationsExclusiveScanAMD(dvec4);" + + "int64_t maxInvocationsExclusiveScanAMD(int64_t);" + "i64vec2 maxInvocationsExclusiveScanAMD(i64vec2);" + "i64vec3 maxInvocationsExclusiveScanAMD(i64vec3);" + "i64vec4 maxInvocationsExclusiveScanAMD(i64vec4);" + + "uint64_t maxInvocationsExclusiveScanAMD(uint64_t);" + "u64vec2 maxInvocationsExclusiveScanAMD(u64vec2);" + "u64vec3 maxInvocationsExclusiveScanAMD(u64vec3);" + "u64vec4 maxInvocationsExclusiveScanAMD(u64vec4);" + + "float16_t maxInvocationsExclusiveScanAMD(float16_t);" + "f16vec2 maxInvocationsExclusiveScanAMD(f16vec2);" + "f16vec3 maxInvocationsExclusiveScanAMD(f16vec3);" + "f16vec4 maxInvocationsExclusiveScanAMD(f16vec4);" + + "float addInvocationsAMD(float);" + "vec2 addInvocationsAMD(vec2);" + "vec3 addInvocationsAMD(vec3);" + "vec4 addInvocationsAMD(vec4);" + + "int addInvocationsAMD(int);" + "ivec2 addInvocationsAMD(ivec2);" + "ivec3 addInvocationsAMD(ivec3);" + "ivec4 addInvocationsAMD(ivec4);" + + "uint addInvocationsAMD(uint);" + "uvec2 addInvocationsAMD(uvec2);" + "uvec3 addInvocationsAMD(uvec3);" + "uvec4 addInvocationsAMD(uvec4);" + + "double addInvocationsAMD(double);" + "dvec2 addInvocationsAMD(dvec2);" + "dvec3 addInvocationsAMD(dvec3);" + "dvec4 addInvocationsAMD(dvec4);" + + "int64_t addInvocationsAMD(int64_t);" + "i64vec2 addInvocationsAMD(i64vec2);" + "i64vec3 addInvocationsAMD(i64vec3);" + "i64vec4 addInvocationsAMD(i64vec4);" + + "uint64_t addInvocationsAMD(uint64_t);" + "u64vec2 addInvocationsAMD(u64vec2);" + "u64vec3 addInvocationsAMD(u64vec3);" + "u64vec4 addInvocationsAMD(u64vec4);" + + "float16_t addInvocationsAMD(float16_t);" + "f16vec2 addInvocationsAMD(f16vec2);" + "f16vec3 addInvocationsAMD(f16vec3);" + "f16vec4 addInvocationsAMD(f16vec4);" + + "float addInvocationsInclusiveScanAMD(float);" + "vec2 addInvocationsInclusiveScanAMD(vec2);" + "vec3 addInvocationsInclusiveScanAMD(vec3);" + "vec4 addInvocationsInclusiveScanAMD(vec4);" + + "int addInvocationsInclusiveScanAMD(int);" + "ivec2 addInvocationsInclusiveScanAMD(ivec2);" + "ivec3 addInvocationsInclusiveScanAMD(ivec3);" + "ivec4 addInvocationsInclusiveScanAMD(ivec4);" + + "uint addInvocationsInclusiveScanAMD(uint);" + "uvec2 addInvocationsInclusiveScanAMD(uvec2);" + "uvec3 addInvocationsInclusiveScanAMD(uvec3);" + "uvec4 addInvocationsInclusiveScanAMD(uvec4);" + + "double addInvocationsInclusiveScanAMD(double);" + "dvec2 addInvocationsInclusiveScanAMD(dvec2);" + "dvec3 addInvocationsInclusiveScanAMD(dvec3);" + "dvec4 addInvocationsInclusiveScanAMD(dvec4);" + + "int64_t addInvocationsInclusiveScanAMD(int64_t);" + "i64vec2 addInvocationsInclusiveScanAMD(i64vec2);" + "i64vec3 addInvocationsInclusiveScanAMD(i64vec3);" + "i64vec4 addInvocationsInclusiveScanAMD(i64vec4);" + + "uint64_t addInvocationsInclusiveScanAMD(uint64_t);" + "u64vec2 addInvocationsInclusiveScanAMD(u64vec2);" + "u64vec3 addInvocationsInclusiveScanAMD(u64vec3);" + "u64vec4 addInvocationsInclusiveScanAMD(u64vec4);" + + "float16_t addInvocationsInclusiveScanAMD(float16_t);" + "f16vec2 addInvocationsInclusiveScanAMD(f16vec2);" + "f16vec3 addInvocationsInclusiveScanAMD(f16vec3);" + "f16vec4 addInvocationsInclusiveScanAMD(f16vec4);" + + "float addInvocationsExclusiveScanAMD(float);" + "vec2 addInvocationsExclusiveScanAMD(vec2);" + "vec3 addInvocationsExclusiveScanAMD(vec3);" + "vec4 addInvocationsExclusiveScanAMD(vec4);" + + "int addInvocationsExclusiveScanAMD(int);" + "ivec2 addInvocationsExclusiveScanAMD(ivec2);" + "ivec3 addInvocationsExclusiveScanAMD(ivec3);" + "ivec4 addInvocationsExclusiveScanAMD(ivec4);" + + "uint addInvocationsExclusiveScanAMD(uint);" + "uvec2 addInvocationsExclusiveScanAMD(uvec2);" + "uvec3 addInvocationsExclusiveScanAMD(uvec3);" + "uvec4 addInvocationsExclusiveScanAMD(uvec4);" + + "double addInvocationsExclusiveScanAMD(double);" + "dvec2 addInvocationsExclusiveScanAMD(dvec2);" + "dvec3 addInvocationsExclusiveScanAMD(dvec3);" + "dvec4 addInvocationsExclusiveScanAMD(dvec4);" + + "int64_t addInvocationsExclusiveScanAMD(int64_t);" + "i64vec2 addInvocationsExclusiveScanAMD(i64vec2);" + "i64vec3 addInvocationsExclusiveScanAMD(i64vec3);" + "i64vec4 addInvocationsExclusiveScanAMD(i64vec4);" + + "uint64_t addInvocationsExclusiveScanAMD(uint64_t);" + "u64vec2 addInvocationsExclusiveScanAMD(u64vec2);" + "u64vec3 addInvocationsExclusiveScanAMD(u64vec3);" + "u64vec4 addInvocationsExclusiveScanAMD(u64vec4);" + + "float16_t addInvocationsExclusiveScanAMD(float16_t);" + "f16vec2 addInvocationsExclusiveScanAMD(f16vec2);" + "f16vec3 addInvocationsExclusiveScanAMD(f16vec3);" + "f16vec4 addInvocationsExclusiveScanAMD(f16vec4);" + + "float minInvocationsNonUniformAMD(float);" + "vec2 minInvocationsNonUniformAMD(vec2);" + "vec3 minInvocationsNonUniformAMD(vec3);" + "vec4 minInvocationsNonUniformAMD(vec4);" + + "int minInvocationsNonUniformAMD(int);" + "ivec2 minInvocationsNonUniformAMD(ivec2);" + "ivec3 minInvocationsNonUniformAMD(ivec3);" + "ivec4 minInvocationsNonUniformAMD(ivec4);" + + "uint minInvocationsNonUniformAMD(uint);" + "uvec2 minInvocationsNonUniformAMD(uvec2);" + "uvec3 minInvocationsNonUniformAMD(uvec3);" + "uvec4 minInvocationsNonUniformAMD(uvec4);" + + "double minInvocationsNonUniformAMD(double);" + "dvec2 minInvocationsNonUniformAMD(dvec2);" + "dvec3 minInvocationsNonUniformAMD(dvec3);" + "dvec4 minInvocationsNonUniformAMD(dvec4);" + + "int64_t minInvocationsNonUniformAMD(int64_t);" + "i64vec2 minInvocationsNonUniformAMD(i64vec2);" + "i64vec3 minInvocationsNonUniformAMD(i64vec3);" + "i64vec4 minInvocationsNonUniformAMD(i64vec4);" + + "uint64_t minInvocationsNonUniformAMD(uint64_t);" + "u64vec2 minInvocationsNonUniformAMD(u64vec2);" + "u64vec3 minInvocationsNonUniformAMD(u64vec3);" + "u64vec4 minInvocationsNonUniformAMD(u64vec4);" + + "float16_t minInvocationsNonUniformAMD(float16_t);" + "f16vec2 minInvocationsNonUniformAMD(f16vec2);" + "f16vec3 minInvocationsNonUniformAMD(f16vec3);" + "f16vec4 minInvocationsNonUniformAMD(f16vec4);" + + "float minInvocationsInclusiveScanNonUniformAMD(float);" + "vec2 minInvocationsInclusiveScanNonUniformAMD(vec2);" + "vec3 minInvocationsInclusiveScanNonUniformAMD(vec3);" + "vec4 minInvocationsInclusiveScanNonUniformAMD(vec4);" + + "int minInvocationsInclusiveScanNonUniformAMD(int);" + "ivec2 minInvocationsInclusiveScanNonUniformAMD(ivec2);" + "ivec3 minInvocationsInclusiveScanNonUniformAMD(ivec3);" + "ivec4 minInvocationsInclusiveScanNonUniformAMD(ivec4);" + + "uint minInvocationsInclusiveScanNonUniformAMD(uint);" + "uvec2 minInvocationsInclusiveScanNonUniformAMD(uvec2);" + "uvec3 minInvocationsInclusiveScanNonUniformAMD(uvec3);" + "uvec4 minInvocationsInclusiveScanNonUniformAMD(uvec4);" + + "double minInvocationsInclusiveScanNonUniformAMD(double);" + "dvec2 minInvocationsInclusiveScanNonUniformAMD(dvec2);" + "dvec3 minInvocationsInclusiveScanNonUniformAMD(dvec3);" + "dvec4 minInvocationsInclusiveScanNonUniformAMD(dvec4);" + + "int64_t minInvocationsInclusiveScanNonUniformAMD(int64_t);" + "i64vec2 minInvocationsInclusiveScanNonUniformAMD(i64vec2);" + "i64vec3 minInvocationsInclusiveScanNonUniformAMD(i64vec3);" + "i64vec4 minInvocationsInclusiveScanNonUniformAMD(i64vec4);" + + "uint64_t minInvocationsInclusiveScanNonUniformAMD(uint64_t);" + "u64vec2 minInvocationsInclusiveScanNonUniformAMD(u64vec2);" + "u64vec3 minInvocationsInclusiveScanNonUniformAMD(u64vec3);" + "u64vec4 minInvocationsInclusiveScanNonUniformAMD(u64vec4);" + + "float16_t minInvocationsInclusiveScanNonUniformAMD(float16_t);" + "f16vec2 minInvocationsInclusiveScanNonUniformAMD(f16vec2);" + "f16vec3 minInvocationsInclusiveScanNonUniformAMD(f16vec3);" + "f16vec4 minInvocationsInclusiveScanNonUniformAMD(f16vec4);" + + "float minInvocationsExclusiveScanNonUniformAMD(float);" + "vec2 minInvocationsExclusiveScanNonUniformAMD(vec2);" + "vec3 minInvocationsExclusiveScanNonUniformAMD(vec3);" + "vec4 minInvocationsExclusiveScanNonUniformAMD(vec4);" + + "int minInvocationsExclusiveScanNonUniformAMD(int);" + "ivec2 minInvocationsExclusiveScanNonUniformAMD(ivec2);" + "ivec3 minInvocationsExclusiveScanNonUniformAMD(ivec3);" + "ivec4 minInvocationsExclusiveScanNonUniformAMD(ivec4);" + + "uint minInvocationsExclusiveScanNonUniformAMD(uint);" + "uvec2 minInvocationsExclusiveScanNonUniformAMD(uvec2);" + "uvec3 minInvocationsExclusiveScanNonUniformAMD(uvec3);" + "uvec4 minInvocationsExclusiveScanNonUniformAMD(uvec4);" + + "double minInvocationsExclusiveScanNonUniformAMD(double);" + "dvec2 minInvocationsExclusiveScanNonUniformAMD(dvec2);" + "dvec3 minInvocationsExclusiveScanNonUniformAMD(dvec3);" + "dvec4 minInvocationsExclusiveScanNonUniformAMD(dvec4);" + + "int64_t minInvocationsExclusiveScanNonUniformAMD(int64_t);" + "i64vec2 minInvocationsExclusiveScanNonUniformAMD(i64vec2);" + "i64vec3 minInvocationsExclusiveScanNonUniformAMD(i64vec3);" + "i64vec4 minInvocationsExclusiveScanNonUniformAMD(i64vec4);" + + "uint64_t minInvocationsExclusiveScanNonUniformAMD(uint64_t);" + "u64vec2 minInvocationsExclusiveScanNonUniformAMD(u64vec2);" + "u64vec3 minInvocationsExclusiveScanNonUniformAMD(u64vec3);" + "u64vec4 minInvocationsExclusiveScanNonUniformAMD(u64vec4);" + + "float16_t minInvocationsExclusiveScanNonUniformAMD(float16_t);" + "f16vec2 minInvocationsExclusiveScanNonUniformAMD(f16vec2);" + "f16vec3 minInvocationsExclusiveScanNonUniformAMD(f16vec3);" + "f16vec4 minInvocationsExclusiveScanNonUniformAMD(f16vec4);" + + "float maxInvocationsNonUniformAMD(float);" + "vec2 maxInvocationsNonUniformAMD(vec2);" + "vec3 maxInvocationsNonUniformAMD(vec3);" + "vec4 maxInvocationsNonUniformAMD(vec4);" + + "int maxInvocationsNonUniformAMD(int);" + "ivec2 maxInvocationsNonUniformAMD(ivec2);" + "ivec3 maxInvocationsNonUniformAMD(ivec3);" + "ivec4 maxInvocationsNonUniformAMD(ivec4);" + + "uint maxInvocationsNonUniformAMD(uint);" + "uvec2 maxInvocationsNonUniformAMD(uvec2);" + "uvec3 maxInvocationsNonUniformAMD(uvec3);" + "uvec4 maxInvocationsNonUniformAMD(uvec4);" + + "double maxInvocationsNonUniformAMD(double);" + "dvec2 maxInvocationsNonUniformAMD(dvec2);" + "dvec3 maxInvocationsNonUniformAMD(dvec3);" + "dvec4 maxInvocationsNonUniformAMD(dvec4);" + + "int64_t maxInvocationsNonUniformAMD(int64_t);" + "i64vec2 maxInvocationsNonUniformAMD(i64vec2);" + "i64vec3 maxInvocationsNonUniformAMD(i64vec3);" + "i64vec4 maxInvocationsNonUniformAMD(i64vec4);" + + "uint64_t maxInvocationsNonUniformAMD(uint64_t);" + "u64vec2 maxInvocationsNonUniformAMD(u64vec2);" + "u64vec3 maxInvocationsNonUniformAMD(u64vec3);" + "u64vec4 maxInvocationsNonUniformAMD(u64vec4);" + + "float16_t maxInvocationsNonUniformAMD(float16_t);" + "f16vec2 maxInvocationsNonUniformAMD(f16vec2);" + "f16vec3 maxInvocationsNonUniformAMD(f16vec3);" + "f16vec4 maxInvocationsNonUniformAMD(f16vec4);" + + "float maxInvocationsInclusiveScanNonUniformAMD(float);" + "vec2 maxInvocationsInclusiveScanNonUniformAMD(vec2);" + "vec3 maxInvocationsInclusiveScanNonUniformAMD(vec3);" + "vec4 maxInvocationsInclusiveScanNonUniformAMD(vec4);" + + "int maxInvocationsInclusiveScanNonUniformAMD(int);" + "ivec2 maxInvocationsInclusiveScanNonUniformAMD(ivec2);" + "ivec3 maxInvocationsInclusiveScanNonUniformAMD(ivec3);" + "ivec4 maxInvocationsInclusiveScanNonUniformAMD(ivec4);" + + "uint maxInvocationsInclusiveScanNonUniformAMD(uint);" + "uvec2 maxInvocationsInclusiveScanNonUniformAMD(uvec2);" + "uvec3 maxInvocationsInclusiveScanNonUniformAMD(uvec3);" + "uvec4 maxInvocationsInclusiveScanNonUniformAMD(uvec4);" + + "double maxInvocationsInclusiveScanNonUniformAMD(double);" + "dvec2 maxInvocationsInclusiveScanNonUniformAMD(dvec2);" + "dvec3 maxInvocationsInclusiveScanNonUniformAMD(dvec3);" + "dvec4 maxInvocationsInclusiveScanNonUniformAMD(dvec4);" + + "int64_t maxInvocationsInclusiveScanNonUniformAMD(int64_t);" + "i64vec2 maxInvocationsInclusiveScanNonUniformAMD(i64vec2);" + "i64vec3 maxInvocationsInclusiveScanNonUniformAMD(i64vec3);" + "i64vec4 maxInvocationsInclusiveScanNonUniformAMD(i64vec4);" + + "uint64_t maxInvocationsInclusiveScanNonUniformAMD(uint64_t);" + "u64vec2 maxInvocationsInclusiveScanNonUniformAMD(u64vec2);" + "u64vec3 maxInvocationsInclusiveScanNonUniformAMD(u64vec3);" + "u64vec4 maxInvocationsInclusiveScanNonUniformAMD(u64vec4);" + + "float16_t maxInvocationsInclusiveScanNonUniformAMD(float16_t);" + "f16vec2 maxInvocationsInclusiveScanNonUniformAMD(f16vec2);" + "f16vec3 maxInvocationsInclusiveScanNonUniformAMD(f16vec3);" + "f16vec4 maxInvocationsInclusiveScanNonUniformAMD(f16vec4);" + + "float maxInvocationsExclusiveScanNonUniformAMD(float);" + "vec2 maxInvocationsExclusiveScanNonUniformAMD(vec2);" + "vec3 maxInvocationsExclusiveScanNonUniformAMD(vec3);" + "vec4 maxInvocationsExclusiveScanNonUniformAMD(vec4);" + + "int maxInvocationsExclusiveScanNonUniformAMD(int);" + "ivec2 maxInvocationsExclusiveScanNonUniformAMD(ivec2);" + "ivec3 maxInvocationsExclusiveScanNonUniformAMD(ivec3);" + "ivec4 maxInvocationsExclusiveScanNonUniformAMD(ivec4);" + + "uint maxInvocationsExclusiveScanNonUniformAMD(uint);" + "uvec2 maxInvocationsExclusiveScanNonUniformAMD(uvec2);" + "uvec3 maxInvocationsExclusiveScanNonUniformAMD(uvec3);" + "uvec4 maxInvocationsExclusiveScanNonUniformAMD(uvec4);" + + "double maxInvocationsExclusiveScanNonUniformAMD(double);" + "dvec2 maxInvocationsExclusiveScanNonUniformAMD(dvec2);" + "dvec3 maxInvocationsExclusiveScanNonUniformAMD(dvec3);" + "dvec4 maxInvocationsExclusiveScanNonUniformAMD(dvec4);" + + "int64_t maxInvocationsExclusiveScanNonUniformAMD(int64_t);" + "i64vec2 maxInvocationsExclusiveScanNonUniformAMD(i64vec2);" + "i64vec3 maxInvocationsExclusiveScanNonUniformAMD(i64vec3);" + "i64vec4 maxInvocationsExclusiveScanNonUniformAMD(i64vec4);" + + "uint64_t maxInvocationsExclusiveScanNonUniformAMD(uint64_t);" + "u64vec2 maxInvocationsExclusiveScanNonUniformAMD(u64vec2);" + "u64vec3 maxInvocationsExclusiveScanNonUniformAMD(u64vec3);" + "u64vec4 maxInvocationsExclusiveScanNonUniformAMD(u64vec4);" + + "float16_t maxInvocationsExclusiveScanNonUniformAMD(float16_t);" + "f16vec2 maxInvocationsExclusiveScanNonUniformAMD(f16vec2);" + "f16vec3 maxInvocationsExclusiveScanNonUniformAMD(f16vec3);" + "f16vec4 maxInvocationsExclusiveScanNonUniformAMD(f16vec4);" + + "float addInvocationsNonUniformAMD(float);" + "vec2 addInvocationsNonUniformAMD(vec2);" + "vec3 addInvocationsNonUniformAMD(vec3);" + "vec4 addInvocationsNonUniformAMD(vec4);" + + "int addInvocationsNonUniformAMD(int);" + "ivec2 addInvocationsNonUniformAMD(ivec2);" + "ivec3 addInvocationsNonUniformAMD(ivec3);" + "ivec4 addInvocationsNonUniformAMD(ivec4);" + + "uint addInvocationsNonUniformAMD(uint);" + "uvec2 addInvocationsNonUniformAMD(uvec2);" + "uvec3 addInvocationsNonUniformAMD(uvec3);" + "uvec4 addInvocationsNonUniformAMD(uvec4);" + + "double addInvocationsNonUniformAMD(double);" + "dvec2 addInvocationsNonUniformAMD(dvec2);" + "dvec3 addInvocationsNonUniformAMD(dvec3);" + "dvec4 addInvocationsNonUniformAMD(dvec4);" + + "int64_t addInvocationsNonUniformAMD(int64_t);" + "i64vec2 addInvocationsNonUniformAMD(i64vec2);" + "i64vec3 addInvocationsNonUniformAMD(i64vec3);" + "i64vec4 addInvocationsNonUniformAMD(i64vec4);" + + "uint64_t addInvocationsNonUniformAMD(uint64_t);" + "u64vec2 addInvocationsNonUniformAMD(u64vec2);" + "u64vec3 addInvocationsNonUniformAMD(u64vec3);" + "u64vec4 addInvocationsNonUniformAMD(u64vec4);" + + "float16_t addInvocationsNonUniformAMD(float16_t);" + "f16vec2 addInvocationsNonUniformAMD(f16vec2);" + "f16vec3 addInvocationsNonUniformAMD(f16vec3);" + "f16vec4 addInvocationsNonUniformAMD(f16vec4);" + + "float addInvocationsInclusiveScanNonUniformAMD(float);" + "vec2 addInvocationsInclusiveScanNonUniformAMD(vec2);" + "vec3 addInvocationsInclusiveScanNonUniformAMD(vec3);" + "vec4 addInvocationsInclusiveScanNonUniformAMD(vec4);" + + "int addInvocationsInclusiveScanNonUniformAMD(int);" + "ivec2 addInvocationsInclusiveScanNonUniformAMD(ivec2);" + "ivec3 addInvocationsInclusiveScanNonUniformAMD(ivec3);" + "ivec4 addInvocationsInclusiveScanNonUniformAMD(ivec4);" + + "uint addInvocationsInclusiveScanNonUniformAMD(uint);" + "uvec2 addInvocationsInclusiveScanNonUniformAMD(uvec2);" + "uvec3 addInvocationsInclusiveScanNonUniformAMD(uvec3);" + "uvec4 addInvocationsInclusiveScanNonUniformAMD(uvec4);" + + "double addInvocationsInclusiveScanNonUniformAMD(double);" + "dvec2 addInvocationsInclusiveScanNonUniformAMD(dvec2);" + "dvec3 addInvocationsInclusiveScanNonUniformAMD(dvec3);" + "dvec4 addInvocationsInclusiveScanNonUniformAMD(dvec4);" + + "int64_t addInvocationsInclusiveScanNonUniformAMD(int64_t);" + "i64vec2 addInvocationsInclusiveScanNonUniformAMD(i64vec2);" + "i64vec3 addInvocationsInclusiveScanNonUniformAMD(i64vec3);" + "i64vec4 addInvocationsInclusiveScanNonUniformAMD(i64vec4);" + + "uint64_t addInvocationsInclusiveScanNonUniformAMD(uint64_t);" + "u64vec2 addInvocationsInclusiveScanNonUniformAMD(u64vec2);" + "u64vec3 addInvocationsInclusiveScanNonUniformAMD(u64vec3);" + "u64vec4 addInvocationsInclusiveScanNonUniformAMD(u64vec4);" + + "float16_t addInvocationsInclusiveScanNonUniformAMD(float16_t);" + "f16vec2 addInvocationsInclusiveScanNonUniformAMD(f16vec2);" + "f16vec3 addInvocationsInclusiveScanNonUniformAMD(f16vec3);" + "f16vec4 addInvocationsInclusiveScanNonUniformAMD(f16vec4);" + + "float addInvocationsExclusiveScanNonUniformAMD(float);" + "vec2 addInvocationsExclusiveScanNonUniformAMD(vec2);" + "vec3 addInvocationsExclusiveScanNonUniformAMD(vec3);" + "vec4 addInvocationsExclusiveScanNonUniformAMD(vec4);" + + "int addInvocationsExclusiveScanNonUniformAMD(int);" + "ivec2 addInvocationsExclusiveScanNonUniformAMD(ivec2);" + "ivec3 addInvocationsExclusiveScanNonUniformAMD(ivec3);" + "ivec4 addInvocationsExclusiveScanNonUniformAMD(ivec4);" + + "uint addInvocationsExclusiveScanNonUniformAMD(uint);" + "uvec2 addInvocationsExclusiveScanNonUniformAMD(uvec2);" + "uvec3 addInvocationsExclusiveScanNonUniformAMD(uvec3);" + "uvec4 addInvocationsExclusiveScanNonUniformAMD(uvec4);" + + "double addInvocationsExclusiveScanNonUniformAMD(double);" + "dvec2 addInvocationsExclusiveScanNonUniformAMD(dvec2);" + "dvec3 addInvocationsExclusiveScanNonUniformAMD(dvec3);" + "dvec4 addInvocationsExclusiveScanNonUniformAMD(dvec4);" + + "int64_t addInvocationsExclusiveScanNonUniformAMD(int64_t);" + "i64vec2 addInvocationsExclusiveScanNonUniformAMD(i64vec2);" + "i64vec3 addInvocationsExclusiveScanNonUniformAMD(i64vec3);" + "i64vec4 addInvocationsExclusiveScanNonUniformAMD(i64vec4);" + + "uint64_t addInvocationsExclusiveScanNonUniformAMD(uint64_t);" + "u64vec2 addInvocationsExclusiveScanNonUniformAMD(u64vec2);" + "u64vec3 addInvocationsExclusiveScanNonUniformAMD(u64vec3);" + "u64vec4 addInvocationsExclusiveScanNonUniformAMD(u64vec4);" + + "float16_t addInvocationsExclusiveScanNonUniformAMD(float16_t);" + "f16vec2 addInvocationsExclusiveScanNonUniformAMD(f16vec2);" + "f16vec3 addInvocationsExclusiveScanNonUniformAMD(f16vec3);" + "f16vec4 addInvocationsExclusiveScanNonUniformAMD(f16vec4);" + + "float swizzleInvocationsAMD(float, uvec4);" + "vec2 swizzleInvocationsAMD(vec2, uvec4);" + "vec3 swizzleInvocationsAMD(vec3, uvec4);" + "vec4 swizzleInvocationsAMD(vec4, uvec4);" + + "int swizzleInvocationsAMD(int, uvec4);" + "ivec2 swizzleInvocationsAMD(ivec2, uvec4);" + "ivec3 swizzleInvocationsAMD(ivec3, uvec4);" + "ivec4 swizzleInvocationsAMD(ivec4, uvec4);" + + "uint swizzleInvocationsAMD(uint, uvec4);" + "uvec2 swizzleInvocationsAMD(uvec2, uvec4);" + "uvec3 swizzleInvocationsAMD(uvec3, uvec4);" + "uvec4 swizzleInvocationsAMD(uvec4, uvec4);" + + "float swizzleInvocationsMaskedAMD(float, uvec3);" + "vec2 swizzleInvocationsMaskedAMD(vec2, uvec3);" + "vec3 swizzleInvocationsMaskedAMD(vec3, uvec3);" + "vec4 swizzleInvocationsMaskedAMD(vec4, uvec3);" + + "int swizzleInvocationsMaskedAMD(int, uvec3);" + "ivec2 swizzleInvocationsMaskedAMD(ivec2, uvec3);" + "ivec3 swizzleInvocationsMaskedAMD(ivec3, uvec3);" + "ivec4 swizzleInvocationsMaskedAMD(ivec4, uvec3);" + + "uint swizzleInvocationsMaskedAMD(uint, uvec3);" + "uvec2 swizzleInvocationsMaskedAMD(uvec2, uvec3);" + "uvec3 swizzleInvocationsMaskedAMD(uvec3, uvec3);" + "uvec4 swizzleInvocationsMaskedAMD(uvec4, uvec3);" + + "float writeInvocationAMD(float, float, uint);" + "vec2 writeInvocationAMD(vec2, vec2, uint);" + "vec3 writeInvocationAMD(vec3, vec3, uint);" + "vec4 writeInvocationAMD(vec4, vec4, uint);" + + "int writeInvocationAMD(int, int, uint);" + "ivec2 writeInvocationAMD(ivec2, ivec2, uint);" + "ivec3 writeInvocationAMD(ivec3, ivec3, uint);" + "ivec4 writeInvocationAMD(ivec4, ivec4, uint);" + + "uint writeInvocationAMD(uint, uint, uint);" + "uvec2 writeInvocationAMD(uvec2, uvec2, uint);" + "uvec3 writeInvocationAMD(uvec3, uvec3, uint);" + "uvec4 writeInvocationAMD(uvec4, uvec4, uint);" + + "uint mbcntAMD(uint64_t);" + + "\n"); + } + + // GL_AMD_gcn_shader + if (profile != EEsProfile && version >= 450) { + commonBuiltins.append( + "float cubeFaceIndexAMD(vec3);" + "vec2 cubeFaceCoordAMD(vec3);" + "uint64_t timeAMD();" + + "\n"); + } + + // GL_AMD_gpu_shader_half_float + if (profile != EEsProfile && version >= 450) { + commonBuiltins.append( + "float16_t radians(float16_t);" + "f16vec2 radians(f16vec2);" + "f16vec3 radians(f16vec3);" + "f16vec4 radians(f16vec4);" + + "float16_t degrees(float16_t);" + "f16vec2 degrees(f16vec2);" + "f16vec3 degrees(f16vec3);" + "f16vec4 degrees(f16vec4);" + + "float16_t sin(float16_t);" + "f16vec2 sin(f16vec2);" + "f16vec3 sin(f16vec3);" + "f16vec4 sin(f16vec4);" + + "float16_t cos(float16_t);" + "f16vec2 cos(f16vec2);" + "f16vec3 cos(f16vec3);" + "f16vec4 cos(f16vec4);" + + "float16_t tan(float16_t);" + "f16vec2 tan(f16vec2);" + "f16vec3 tan(f16vec3);" + "f16vec4 tan(f16vec4);" + + "float16_t asin(float16_t);" + "f16vec2 asin(f16vec2);" + "f16vec3 asin(f16vec3);" + "f16vec4 asin(f16vec4);" + + "float16_t acos(float16_t);" + "f16vec2 acos(f16vec2);" + "f16vec3 acos(f16vec3);" + "f16vec4 acos(f16vec4);" + + "float16_t atan(float16_t, float16_t);" + "f16vec2 atan(f16vec2, f16vec2);" + "f16vec3 atan(f16vec3, f16vec3);" + "f16vec4 atan(f16vec4, f16vec4);" + + "float16_t atan(float16_t);" + "f16vec2 atan(f16vec2);" + "f16vec3 atan(f16vec3);" + "f16vec4 atan(f16vec4);" + + "float16_t sinh(float16_t);" + "f16vec2 sinh(f16vec2);" + "f16vec3 sinh(f16vec3);" + "f16vec4 sinh(f16vec4);" + + "float16_t cosh(float16_t);" + "f16vec2 cosh(f16vec2);" + "f16vec3 cosh(f16vec3);" + "f16vec4 cosh(f16vec4);" + + "float16_t tanh(float16_t);" + "f16vec2 tanh(f16vec2);" + "f16vec3 tanh(f16vec3);" + "f16vec4 tanh(f16vec4);" + + "float16_t asinh(float16_t);" + "f16vec2 asinh(f16vec2);" + "f16vec3 asinh(f16vec3);" + "f16vec4 asinh(f16vec4);" + + "float16_t acosh(float16_t);" + "f16vec2 acosh(f16vec2);" + "f16vec3 acosh(f16vec3);" + "f16vec4 acosh(f16vec4);" + + "float16_t atanh(float16_t);" + "f16vec2 atanh(f16vec2);" + "f16vec3 atanh(f16vec3);" + "f16vec4 atanh(f16vec4);" + + "float16_t pow(float16_t, float16_t);" + "f16vec2 pow(f16vec2, f16vec2);" + "f16vec3 pow(f16vec3, f16vec3);" + "f16vec4 pow(f16vec4, f16vec4);" + + "float16_t exp(float16_t);" + "f16vec2 exp(f16vec2);" + "f16vec3 exp(f16vec3);" + "f16vec4 exp(f16vec4);" + + "float16_t log(float16_t);" + "f16vec2 log(f16vec2);" + "f16vec3 log(f16vec3);" + "f16vec4 log(f16vec4);" + + "float16_t exp2(float16_t);" + "f16vec2 exp2(f16vec2);" + "f16vec3 exp2(f16vec3);" + "f16vec4 exp2(f16vec4);" + + "float16_t log2(float16_t);" + "f16vec2 log2(f16vec2);" + "f16vec3 log2(f16vec3);" + "f16vec4 log2(f16vec4);" + + "float16_t sqrt(float16_t);" + "f16vec2 sqrt(f16vec2);" + "f16vec3 sqrt(f16vec3);" + "f16vec4 sqrt(f16vec4);" + + "float16_t inversesqrt(float16_t);" + "f16vec2 inversesqrt(f16vec2);" + "f16vec3 inversesqrt(f16vec3);" + "f16vec4 inversesqrt(f16vec4);" + + "float16_t abs(float16_t);" + "f16vec2 abs(f16vec2);" + "f16vec3 abs(f16vec3);" + "f16vec4 abs(f16vec4);" + + "float16_t sign(float16_t);" + "f16vec2 sign(f16vec2);" + "f16vec3 sign(f16vec3);" + "f16vec4 sign(f16vec4);" + + "float16_t floor(float16_t);" + "f16vec2 floor(f16vec2);" + "f16vec3 floor(f16vec3);" + "f16vec4 floor(f16vec4);" + + "float16_t trunc(float16_t);" + "f16vec2 trunc(f16vec2);" + "f16vec3 trunc(f16vec3);" + "f16vec4 trunc(f16vec4);" + + "float16_t round(float16_t);" + "f16vec2 round(f16vec2);" + "f16vec3 round(f16vec3);" + "f16vec4 round(f16vec4);" + + "float16_t roundEven(float16_t);" + "f16vec2 roundEven(f16vec2);" + "f16vec3 roundEven(f16vec3);" + "f16vec4 roundEven(f16vec4);" + + "float16_t ceil(float16_t);" + "f16vec2 ceil(f16vec2);" + "f16vec3 ceil(f16vec3);" + "f16vec4 ceil(f16vec4);" + + "float16_t fract(float16_t);" + "f16vec2 fract(f16vec2);" + "f16vec3 fract(f16vec3);" + "f16vec4 fract(f16vec4);" + + "float16_t mod(float16_t, float16_t);" + "f16vec2 mod(f16vec2, float16_t);" + "f16vec3 mod(f16vec3, float16_t);" + "f16vec4 mod(f16vec4, float16_t);" + "f16vec2 mod(f16vec2, f16vec2);" + "f16vec3 mod(f16vec3, f16vec3);" + "f16vec4 mod(f16vec4, f16vec4);" + + "float16_t modf(float16_t, out float16_t);" + "f16vec2 modf(f16vec2, out f16vec2);" + "f16vec3 modf(f16vec3, out f16vec3);" + "f16vec4 modf(f16vec4, out f16vec4);" + + "float16_t min(float16_t, float16_t);" + "f16vec2 min(f16vec2, float16_t);" + "f16vec3 min(f16vec3, float16_t);" + "f16vec4 min(f16vec4, float16_t);" + "f16vec2 min(f16vec2, f16vec2);" + "f16vec3 min(f16vec3, f16vec3);" + "f16vec4 min(f16vec4, f16vec4);" + + "float16_t max(float16_t, float16_t);" + "f16vec2 max(f16vec2, float16_t);" + "f16vec3 max(f16vec3, float16_t);" + "f16vec4 max(f16vec4, float16_t);" + "f16vec2 max(f16vec2, f16vec2);" + "f16vec3 max(f16vec3, f16vec3);" + "f16vec4 max(f16vec4, f16vec4);" + + "float16_t clamp(float16_t, float16_t, float16_t);" + "f16vec2 clamp(f16vec2, float16_t, float16_t);" + "f16vec3 clamp(f16vec3, float16_t, float16_t);" + "f16vec4 clamp(f16vec4, float16_t, float16_t);" + "f16vec2 clamp(f16vec2, f16vec2, f16vec2);" + "f16vec3 clamp(f16vec3, f16vec3, f16vec3);" + "f16vec4 clamp(f16vec4, f16vec4, f16vec4);" + + "float16_t mix(float16_t, float16_t, float16_t);" + "f16vec2 mix(f16vec2, f16vec2, float16_t);" + "f16vec3 mix(f16vec3, f16vec3, float16_t);" + "f16vec4 mix(f16vec4, f16vec4, float16_t);" + "f16vec2 mix(f16vec2, f16vec2, f16vec2);" + "f16vec3 mix(f16vec3, f16vec3, f16vec3);" + "f16vec4 mix(f16vec4, f16vec4, f16vec4);" + "float16_t mix(float16_t, float16_t, bool);" + "f16vec2 mix(f16vec2, f16vec2, bvec2);" + "f16vec3 mix(f16vec3, f16vec3, bvec3);" + "f16vec4 mix(f16vec4, f16vec4, bvec4);" + + "float16_t step(float16_t, float16_t);" + "f16vec2 step(f16vec2, f16vec2);" + "f16vec3 step(f16vec3, f16vec3);" + "f16vec4 step(f16vec4, f16vec4);" + "f16vec2 step(float16_t, f16vec2);" + "f16vec3 step(float16_t, f16vec3);" + "f16vec4 step(float16_t, f16vec4);" + + "float16_t smoothstep(float16_t, float16_t, float16_t);" + "f16vec2 smoothstep(f16vec2, f16vec2, f16vec2);" + "f16vec3 smoothstep(f16vec3, f16vec3, f16vec3);" + "f16vec4 smoothstep(f16vec4, f16vec4, f16vec4);" + "f16vec2 smoothstep(float16_t, float16_t, f16vec2);" + "f16vec3 smoothstep(float16_t, float16_t, f16vec3);" + "f16vec4 smoothstep(float16_t, float16_t, f16vec4);" + + "bool isnan(float16_t);" + "bvec2 isnan(f16vec2);" + "bvec3 isnan(f16vec3);" + "bvec4 isnan(f16vec4);" + + "bool isinf(float16_t);" + "bvec2 isinf(f16vec2);" + "bvec3 isinf(f16vec3);" + "bvec4 isinf(f16vec4);" + + "float16_t fma(float16_t, float16_t, float16_t);" + "f16vec2 fma(f16vec2, f16vec2, f16vec2);" + "f16vec3 fma(f16vec3, f16vec3, f16vec3);" + "f16vec4 fma(f16vec4, f16vec4, f16vec4);" + + "float16_t frexp(float16_t, out int);" + "f16vec2 frexp(f16vec2, out ivec2);" + "f16vec3 frexp(f16vec3, out ivec3);" + "f16vec4 frexp(f16vec4, out ivec4);" + + "float16_t ldexp(float16_t, in int);" + "f16vec2 ldexp(f16vec2, in ivec2);" + "f16vec3 ldexp(f16vec3, in ivec3);" + "f16vec4 ldexp(f16vec4, in ivec4);" + + "uint packFloat2x16(f16vec2);" + "f16vec2 unpackFloat2x16(uint);" + + "float16_t length(float16_t);" + "float16_t length(f16vec2);" + "float16_t length(f16vec3);" + "float16_t length(f16vec4);" + + "float16_t distance(float16_t, float16_t);" + "float16_t distance(f16vec2, f16vec2);" + "float16_t distance(f16vec3, f16vec3);" + "float16_t distance(f16vec4, f16vec4);" + + "float16_t dot(float16_t, float16_t);" + "float16_t dot(f16vec2, f16vec2);" + "float16_t dot(f16vec3, f16vec3);" + "float16_t dot(f16vec4, f16vec4);" + + "f16vec3 cross(f16vec3, f16vec3);" + + "float16_t normalize(float16_t);" + "f16vec2 normalize(f16vec2);" + "f16vec3 normalize(f16vec3);" + "f16vec4 normalize(f16vec4);" + + "float16_t faceforward(float16_t, float16_t, float16_t);" + "f16vec2 faceforward(f16vec2, f16vec2, f16vec2);" + "f16vec3 faceforward(f16vec3, f16vec3, f16vec3);" + "f16vec4 faceforward(f16vec4, f16vec4, f16vec4);" + + "float16_t reflect(float16_t, float16_t);" + "f16vec2 reflect(f16vec2, f16vec2);" + "f16vec3 reflect(f16vec3, f16vec3);" + "f16vec4 reflect(f16vec4, f16vec4);" + + "float16_t refract(float16_t, float16_t, float16_t);" + "f16vec2 refract(f16vec2, f16vec2, float16_t);" + "f16vec3 refract(f16vec3, f16vec3, float16_t);" + "f16vec4 refract(f16vec4, f16vec4, float16_t);" + + "f16mat2 matrixCompMult(f16mat2, f16mat2);" + "f16mat3 matrixCompMult(f16mat3, f16mat3);" + "f16mat4 matrixCompMult(f16mat4, f16mat4);" + "f16mat2x3 matrixCompMult(f16mat2x3, f16mat2x3);" + "f16mat2x4 matrixCompMult(f16mat2x4, f16mat2x4);" + "f16mat3x2 matrixCompMult(f16mat3x2, f16mat3x2);" + "f16mat3x4 matrixCompMult(f16mat3x4, f16mat3x4);" + "f16mat4x2 matrixCompMult(f16mat4x2, f16mat4x2);" + "f16mat4x3 matrixCompMult(f16mat4x3, f16mat4x3);" + + "f16mat2 outerProduct(f16vec2, f16vec2);" + "f16mat3 outerProduct(f16vec3, f16vec3);" + "f16mat4 outerProduct(f16vec4, f16vec4);" + "f16mat2x3 outerProduct(f16vec3, f16vec2);" + "f16mat3x2 outerProduct(f16vec2, f16vec3);" + "f16mat2x4 outerProduct(f16vec4, f16vec2);" + "f16mat4x2 outerProduct(f16vec2, f16vec4);" + "f16mat3x4 outerProduct(f16vec4, f16vec3);" + "f16mat4x3 outerProduct(f16vec3, f16vec4);" + + "f16mat2 transpose(f16mat2);" + "f16mat3 transpose(f16mat3);" + "f16mat4 transpose(f16mat4);" + "f16mat2x3 transpose(f16mat3x2);" + "f16mat3x2 transpose(f16mat2x3);" + "f16mat2x4 transpose(f16mat4x2);" + "f16mat4x2 transpose(f16mat2x4);" + "f16mat3x4 transpose(f16mat4x3);" + "f16mat4x3 transpose(f16mat3x4);" + + "float16_t determinant(f16mat2);" + "float16_t determinant(f16mat3);" + "float16_t determinant(f16mat4);" + + "f16mat2 inverse(f16mat2);" + "f16mat3 inverse(f16mat3);" + "f16mat4 inverse(f16mat4);" + + "bvec2 lessThan(f16vec2, f16vec2);" + "bvec3 lessThan(f16vec3, f16vec3);" + "bvec4 lessThan(f16vec4, f16vec4);" + + "bvec2 lessThanEqual(f16vec2, f16vec2);" + "bvec3 lessThanEqual(f16vec3, f16vec3);" + "bvec4 lessThanEqual(f16vec4, f16vec4);" + + "bvec2 greaterThan(f16vec2, f16vec2);" + "bvec3 greaterThan(f16vec3, f16vec3);" + "bvec4 greaterThan(f16vec4, f16vec4);" + + "bvec2 greaterThanEqual(f16vec2, f16vec2);" + "bvec3 greaterThanEqual(f16vec3, f16vec3);" + "bvec4 greaterThanEqual(f16vec4, f16vec4);" + + "bvec2 equal(f16vec2, f16vec2);" + "bvec3 equal(f16vec3, f16vec3);" + "bvec4 equal(f16vec4, f16vec4);" + + "bvec2 notEqual(f16vec2, f16vec2);" + "bvec3 notEqual(f16vec3, f16vec3);" + "bvec4 notEqual(f16vec4, f16vec4);" + + "\n"); + } + + // GL_AMD_gpu_shader_int16 + if (profile != EEsProfile && version >= 450) { + commonBuiltins.append( + "int16_t abs(int16_t);" + "i16vec2 abs(i16vec2);" + "i16vec3 abs(i16vec3);" + "i16vec4 abs(i16vec4);" + + "int16_t sign(int16_t);" + "i16vec2 sign(i16vec2);" + "i16vec3 sign(i16vec3);" + "i16vec4 sign(i16vec4);" + + "int16_t min(int16_t, int16_t);" + "i16vec2 min(i16vec2, int16_t);" + "i16vec3 min(i16vec3, int16_t);" + "i16vec4 min(i16vec4, int16_t);" + "i16vec2 min(i16vec2, i16vec2);" + "i16vec3 min(i16vec3, i16vec3);" + "i16vec4 min(i16vec4, i16vec4);" + "uint16_t min(uint16_t, uint16_t);" + "u16vec2 min(u16vec2, uint16_t);" + "u16vec3 min(u16vec3, uint16_t);" + "u16vec4 min(u16vec4, uint16_t);" + "u16vec2 min(u16vec2, u16vec2);" + "u16vec3 min(u16vec3, u16vec3);" + "u16vec4 min(u16vec4, u16vec4);" + + "int16_t max(int16_t, int16_t);" + "i16vec2 max(i16vec2, int16_t);" + "i16vec3 max(i16vec3, int16_t);" + "i16vec4 max(i16vec4, int16_t);" + "i16vec2 max(i16vec2, i16vec2);" + "i16vec3 max(i16vec3, i16vec3);" + "i16vec4 max(i16vec4, i16vec4);" + "uint16_t max(uint16_t, uint16_t);" + "u16vec2 max(u16vec2, uint16_t);" + "u16vec3 max(u16vec3, uint16_t);" + "u16vec4 max(u16vec4, uint16_t);" + "u16vec2 max(u16vec2, u16vec2);" + "u16vec3 max(u16vec3, u16vec3);" + "u16vec4 max(u16vec4, u16vec4);" + + "int16_t clamp(int16_t, int16_t, int16_t);" + "i16vec2 clamp(i16vec2, int16_t, int16_t);" + "i16vec3 clamp(i16vec3, int16_t, int16_t);" + "i16vec4 clamp(i16vec4, int16_t, int16_t);" + "i16vec2 clamp(i16vec2, i16vec2, i16vec2);" + "i16vec3 clamp(i16vec3, i16vec3, i16vec3);" + "i16vec4 clamp(i16vec4, i16vec4, i16vec4);" + "uint16_t clamp(uint16_t, uint16_t, uint16_t);" + "u16vec2 clamp(u16vec2, uint16_t, uint16_t);" + "u16vec3 clamp(u16vec3, uint16_t, uint16_t);" + "u16vec4 clamp(u16vec4, uint16_t, uint16_t);" + "u16vec2 clamp(u16vec2, u16vec2, u16vec2);" + "u16vec3 clamp(u16vec3, u16vec3, u16vec3);" + "u16vec4 clamp(u16vec4, u16vec4, u16vec4);" + + "int16_t mix(int16_t, int16_t, bool);" + "i16vec2 mix(i16vec2, i16vec2, bvec2);" + "i16vec3 mix(i16vec3, i16vec3, bvec3);" + "i16vec4 mix(i16vec4, i16vec4, bvec4);" + "uint16_t mix(uint16_t, uint16_t, bool);" + "u16vec2 mix(u16vec2, u16vec2, bvec2);" + "u16vec3 mix(u16vec3, u16vec3, bvec3);" + "u16vec4 mix(u16vec4, u16vec4, bvec4);" + + "float16_t frexp(float16_t, out int16_t);" + "f16vec2 frexp(f16vec2, out i16vec2);" + "f16vec3 frexp(f16vec3, out i16vec3);" + "f16vec4 frexp(f16vec4, out i16vec4);" + + "float16_t ldexp(float16_t, int16_t);" + "f16vec2 ldexp(f16vec2, i16vec2);" + "f16vec3 ldexp(f16vec3, i16vec3);" + "f16vec4 ldexp(f16vec4, i16vec4);" + + "int16_t float16BitsToInt16(float16_t);" + "i16vec2 float16BitsToInt16(f16vec2);" + "i16vec3 float16BitsToInt16(f16vec3);" + "i16vec4 float16BitsToInt16(f16vec4);" + + "uint16_t float16BitsToUint16(float16_t);" + "u16vec2 float16BitsToUint16(f16vec2);" + "u16vec3 float16BitsToUint16(f16vec3);" + "u16vec4 float16BitsToUint16(f16vec4);" + + "float16_t int16BitsToFloat16(int16_t);" + "f16vec2 int16BitsToFloat16(i16vec2);" + "f16vec3 int16BitsToFloat16(i16vec3);" + "f16vec4 int16BitsToFloat16(i16vec4);" + + "float16_t uint16BitsToFloat16(uint16_t);" + "f16vec2 uint16BitsToFloat16(u16vec2);" + "f16vec3 uint16BitsToFloat16(u16vec3);" + "f16vec4 uint16BitsToFloat16(u16vec4);" + + "int packInt2x16(i16vec2);" + "uint packUint2x16(u16vec2);" + "int64_t packInt4x16(i16vec4);" + "uint64_t packUint4x16(u16vec4);" + "i16vec2 unpackInt2x16(int);" + "u16vec2 unpackUint2x16(uint);" + "i16vec4 unpackInt4x16(int64_t);" + "u16vec4 unpackUint4x16(uint64_t);" + + "bvec2 lessThan(i16vec2, i16vec2);" + "bvec3 lessThan(i16vec3, i16vec3);" + "bvec4 lessThan(i16vec4, i16vec4);" + "bvec2 lessThan(u16vec2, u16vec2);" + "bvec3 lessThan(u16vec3, u16vec3);" + "bvec4 lessThan(u16vec4, u16vec4);" + + "bvec2 lessThanEqual(i16vec2, i16vec2);" + "bvec3 lessThanEqual(i16vec3, i16vec3);" + "bvec4 lessThanEqual(i16vec4, i16vec4);" + "bvec2 lessThanEqual(u16vec2, u16vec2);" + "bvec3 lessThanEqual(u16vec3, u16vec3);" + "bvec4 lessThanEqual(u16vec4, u16vec4);" + + "bvec2 greaterThan(i16vec2, i16vec2);" + "bvec3 greaterThan(i16vec3, i16vec3);" + "bvec4 greaterThan(i16vec4, i16vec4);" + "bvec2 greaterThan(u16vec2, u16vec2);" + "bvec3 greaterThan(u16vec3, u16vec3);" + "bvec4 greaterThan(u16vec4, u16vec4);" + + "bvec2 greaterThanEqual(i16vec2, i16vec2);" + "bvec3 greaterThanEqual(i16vec3, i16vec3);" + "bvec4 greaterThanEqual(i16vec4, i16vec4);" + "bvec2 greaterThanEqual(u16vec2, u16vec2);" + "bvec3 greaterThanEqual(u16vec3, u16vec3);" + "bvec4 greaterThanEqual(u16vec4, u16vec4);" + + "bvec2 equal(i16vec2, i16vec2);" + "bvec3 equal(i16vec3, i16vec3);" + "bvec4 equal(i16vec4, i16vec4);" + "bvec2 equal(u16vec2, u16vec2);" + "bvec3 equal(u16vec3, u16vec3);" + "bvec4 equal(u16vec4, u16vec4);" + + "bvec2 notEqual(i16vec2, i16vec2);" + "bvec3 notEqual(i16vec3, i16vec3);" + "bvec4 notEqual(i16vec4, i16vec4);" + "bvec2 notEqual(u16vec2, u16vec2);" + "bvec3 notEqual(u16vec3, u16vec3);" + "bvec4 notEqual(u16vec4, u16vec4);" + + "\n"); + } + + // GL_AMD_shader_fragment_mask + if (profile != EEsProfile && version >= 450) { + commonBuiltins.append( + "uint fragmentMaskFetchAMD(sampler2DMS, ivec2);" + "uint fragmentMaskFetchAMD(isampler2DMS, ivec2);" + "uint fragmentMaskFetchAMD(usampler2DMS, ivec2);" + + "uint fragmentMaskFetchAMD(sampler2DMSArray, ivec3);" + "uint fragmentMaskFetchAMD(isampler2DMSArray, ivec3);" + "uint fragmentMaskFetchAMD(usampler2DMSArray, ivec3);" + + "vec4 fragmentFetchAMD(sampler2DMS, ivec2, uint);" + "ivec4 fragmentFetchAMD(isampler2DMS, ivec2, uint);" + "uvec4 fragmentFetchAMD(usampler2DMS, ivec2, uint);" + + "vec4 fragmentFetchAMD(sampler2DMSArray, ivec3, uint);" + "ivec4 fragmentFetchAMD(isampler2DMSArray, ivec3, uint);" + "uvec4 fragmentFetchAMD(usampler2DMSArray, ivec3, uint);" + + "\n"); + } + +#endif + + //============================================================================ + // + // Prototypes for built-in functions seen by vertex shaders only. + // (Except legacy lod functions, where it depends which release they are + // vertex only.) + // + //============================================================================ + + // + // Geometric Functions. + // + if (IncludeLegacy(version, profile, spvVersion)) + stageBuiltins[EShLangVertex].append("vec4 ftransform();"); + + // + // Original-style texture Functions with lod. + // + TString* s; + if (version == 100) + s = &stageBuiltins[EShLangVertex]; + else + s = &commonBuiltins; + if ((profile == EEsProfile && version == 100) || + profile == ECompatibilityProfile || + (profile == ECoreProfile && version < 420) || + profile == ENoProfile) { + if (spvVersion.spv == 0) { + s->append( + "vec4 texture2DLod(sampler2D, vec2, float);" // GL_ARB_shader_texture_lod + "vec4 texture2DProjLod(sampler2D, vec3, float);" // GL_ARB_shader_texture_lod + "vec4 texture2DProjLod(sampler2D, vec4, float);" // GL_ARB_shader_texture_lod + "vec4 texture3DLod(sampler3D, vec3, float);" // GL_ARB_shader_texture_lod // OES_texture_3D, but caught by keyword check + "vec4 texture3DProjLod(sampler3D, vec4, float);" // GL_ARB_shader_texture_lod // OES_texture_3D, but caught by keyword check + "vec4 textureCubeLod(samplerCube, vec3, float);" // GL_ARB_shader_texture_lod + + "vec4 texture2DArrayLod(sampler2DArray, vec3, float);" // GL_EXT_texture_array + + "\n"); + } + } + if ( profile == ECompatibilityProfile || + (profile == ECoreProfile && version < 420) || + profile == ENoProfile) { + if (spvVersion.spv == 0) { + s->append( + "vec4 texture1DLod(sampler1D, float, float);" // GL_ARB_shader_texture_lod + "vec4 texture1DProjLod(sampler1D, vec2, float);" // GL_ARB_shader_texture_lod + "vec4 texture1DProjLod(sampler1D, vec4, float);" // GL_ARB_shader_texture_lod + "vec4 shadow1DLod(sampler1DShadow, vec3, float);" // GL_ARB_shader_texture_lod + "vec4 shadow2DLod(sampler2DShadow, vec3, float);" // GL_ARB_shader_texture_lod + "vec4 shadow1DProjLod(sampler1DShadow, vec4, float);" // GL_ARB_shader_texture_lod + "vec4 shadow2DProjLod(sampler2DShadow, vec4, float);" // GL_ARB_shader_texture_lod + + "vec4 texture1DGradARB(sampler1D, float, float, float);" // GL_ARB_shader_texture_lod + "vec4 texture1DProjGradARB(sampler1D, vec2, float, float);" // GL_ARB_shader_texture_lod + "vec4 texture1DProjGradARB(sampler1D, vec4, float, float);" // GL_ARB_shader_texture_lod + "vec4 texture2DGradARB(sampler2D, vec2, vec2, vec2);" // GL_ARB_shader_texture_lod + "vec4 texture2DProjGradARB(sampler2D, vec3, vec2, vec2);" // GL_ARB_shader_texture_lod + "vec4 texture2DProjGradARB(sampler2D, vec4, vec2, vec2);" // GL_ARB_shader_texture_lod + "vec4 texture3DGradARB(sampler3D, vec3, vec3, vec3);" // GL_ARB_shader_texture_lod + "vec4 texture3DProjGradARB(sampler3D, vec4, vec3, vec3);" // GL_ARB_shader_texture_lod + "vec4 textureCubeGradARB(samplerCube, vec3, vec3, vec3);" // GL_ARB_shader_texture_lod + "vec4 shadow1DGradARB(sampler1DShadow, vec3, float, float);" // GL_ARB_shader_texture_lod + "vec4 shadow1DProjGradARB( sampler1DShadow, vec4, float, float);" // GL_ARB_shader_texture_lod + "vec4 shadow2DGradARB(sampler2DShadow, vec3, vec2, vec2);" // GL_ARB_shader_texture_lod + "vec4 shadow2DProjGradARB( sampler2DShadow, vec4, vec2, vec2);" // GL_ARB_shader_texture_lod + "vec4 texture2DRectGradARB(sampler2DRect, vec2, vec2, vec2);" // GL_ARB_shader_texture_lod + "vec4 texture2DRectProjGradARB( sampler2DRect, vec3, vec2, vec2);" // GL_ARB_shader_texture_lod + "vec4 texture2DRectProjGradARB( sampler2DRect, vec4, vec2, vec2);" // GL_ARB_shader_texture_lod + "vec4 shadow2DRectGradARB( sampler2DRectShadow, vec3, vec2, vec2);" // GL_ARB_shader_texture_lod + "vec4 shadow2DRectProjGradARB(sampler2DRectShadow, vec4, vec2, vec2);" // GL_ARB_shader_texture_lod + + "vec4 texture1DArrayLod(sampler1DArray, vec2, float);" // GL_EXT_texture_array + "vec4 shadow1DArrayLod(sampler1DArrayShadow, vec3, float);" // GL_EXT_texture_array + "vec4 shadow2DArrayLod(sampler2DArrayShadow, vec4, float);" // GL_EXT_texture_array + + "\n"); + } + } + + if ((profile != EEsProfile && version >= 150) || + (profile == EEsProfile && version >= 310)) { + //============================================================================ + // + // Prototypes for built-in functions seen by geometry shaders only. + // + //============================================================================ + + if (profile != EEsProfile && version >= 400) { + stageBuiltins[EShLangGeometry].append( + "void EmitStreamVertex(int);" + "void EndStreamPrimitive(int);" + ); + } + stageBuiltins[EShLangGeometry].append( + "void EmitVertex();" + "void EndPrimitive();" + "\n"); + } + + //============================================================================ + // + // Prototypes for all control functions. + // + //============================================================================ + bool esBarrier = (profile == EEsProfile && version >= 310); + if ((profile != EEsProfile && version >= 150) || esBarrier) + stageBuiltins[EShLangTessControl].append( + "void barrier();" + ); + if ((profile != EEsProfile && version >= 420) || esBarrier) + stageBuiltins[EShLangCompute].append( + "void barrier();" + ); + if ((profile != EEsProfile && version >= 130) || esBarrier) + commonBuiltins.append( + "void memoryBarrier();" + ); + if ((profile != EEsProfile && version >= 420) || esBarrier) { + commonBuiltins.append( + "void memoryBarrierAtomicCounter();" + "void memoryBarrierBuffer();" + "void memoryBarrierImage();" + ); + stageBuiltins[EShLangCompute].append( + "void memoryBarrierShared();" + "void groupMemoryBarrier();" + ); + } + + //============================================================================ + // + // Prototypes for built-in functions seen by fragment shaders only. + // + //============================================================================ + + // + // Original-style texture Functions with bias. + // + if (spvVersion.spv == 0 && (profile != EEsProfile || version == 100)) { + stageBuiltins[EShLangFragment].append( + "vec4 texture2D(sampler2D, vec2, float);" + "vec4 texture2DProj(sampler2D, vec3, float);" + "vec4 texture2DProj(sampler2D, vec4, float);" + "vec4 texture3D(sampler3D, vec3, float);" // OES_texture_3D + "vec4 texture3DProj(sampler3D, vec4, float);" // OES_texture_3D + "vec4 textureCube(samplerCube, vec3, float);" + "vec4 texture2DArray(sampler2DArray, vec3, float);" // GL_EXT_texture_array + + "\n"); + } + if (spvVersion.spv == 0 && (profile != EEsProfile && version > 100)) { + stageBuiltins[EShLangFragment].append( + "vec4 texture1D(sampler1D, float, float);" + "vec4 texture1DProj(sampler1D, vec2, float);" + "vec4 texture1DProj(sampler1D, vec4, float);" + "vec4 shadow1D(sampler1DShadow, vec3, float);" + "vec4 shadow2D(sampler2DShadow, vec3, float);" + "vec4 shadow1DProj(sampler1DShadow, vec4, float);" + "vec4 shadow2DProj(sampler2DShadow, vec4, float);" + "vec4 texture1DArray(sampler1DArray, vec2, float);" // GL_EXT_texture_array + "vec4 shadow1DArray(sampler1DArrayShadow, vec3, float);" // GL_EXT_texture_array + "vec4 shadow2DArray(sampler2DArrayShadow, vec4, float);" // GL_EXT_texture_array + "\n"); + } + if (spvVersion.spv == 0 && profile == EEsProfile) { + stageBuiltins[EShLangFragment].append( + "vec4 texture2DLodEXT(sampler2D, vec2, float);" // GL_EXT_shader_texture_lod + "vec4 texture2DProjLodEXT(sampler2D, vec3, float);" // GL_EXT_shader_texture_lod + "vec4 texture2DProjLodEXT(sampler2D, vec4, float);" // GL_EXT_shader_texture_lod + "vec4 textureCubeLodEXT(samplerCube, vec3, float);" // GL_EXT_shader_texture_lod + + "\n"); + } + + stageBuiltins[EShLangFragment].append( + "float dFdx(float p);" + "vec2 dFdx(vec2 p);" + "vec3 dFdx(vec3 p);" + "vec4 dFdx(vec4 p);" + + "float dFdy(float p);" + "vec2 dFdy(vec2 p);" + "vec3 dFdy(vec3 p);" + "vec4 dFdy(vec4 p);" + + "float fwidth(float p);" + "vec2 fwidth(vec2 p);" + "vec3 fwidth(vec3 p);" + "vec4 fwidth(vec4 p);" + + "\n"); + + // GL_ARB_derivative_control + if (profile != EEsProfile && version >= 400) { + stageBuiltins[EShLangFragment].append( + "float dFdxFine(float p);" + "vec2 dFdxFine(vec2 p);" + "vec3 dFdxFine(vec3 p);" + "vec4 dFdxFine(vec4 p);" + + "float dFdyFine(float p);" + "vec2 dFdyFine(vec2 p);" + "vec3 dFdyFine(vec3 p);" + "vec4 dFdyFine(vec4 p);" + + "float fwidthFine(float p);" + "vec2 fwidthFine(vec2 p);" + "vec3 fwidthFine(vec3 p);" + "vec4 fwidthFine(vec4 p);" + + "\n"); + + stageBuiltins[EShLangFragment].append( + "float dFdxCoarse(float p);" + "vec2 dFdxCoarse(vec2 p);" + "vec3 dFdxCoarse(vec3 p);" + "vec4 dFdxCoarse(vec4 p);" + + "float dFdyCoarse(float p);" + "vec2 dFdyCoarse(vec2 p);" + "vec3 dFdyCoarse(vec3 p);" + "vec4 dFdyCoarse(vec4 p);" + + "float fwidthCoarse(float p);" + "vec2 fwidthCoarse(vec2 p);" + "vec3 fwidthCoarse(vec3 p);" + "vec4 fwidthCoarse(vec4 p);" + + "\n"); + } + + // GL_OES_shader_multisample_interpolation + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 400)) { + stageBuiltins[EShLangFragment].append( + "float interpolateAtCentroid(float);" + "vec2 interpolateAtCentroid(vec2);" + "vec3 interpolateAtCentroid(vec3);" + "vec4 interpolateAtCentroid(vec4);" + + "float interpolateAtSample(float, int);" + "vec2 interpolateAtSample(vec2, int);" + "vec3 interpolateAtSample(vec3, int);" + "vec4 interpolateAtSample(vec4, int);" + + "float interpolateAtOffset(float, vec2);" + "vec2 interpolateAtOffset(vec2, vec2);" + "vec3 interpolateAtOffset(vec3, vec2);" + "vec4 interpolateAtOffset(vec4, vec2);" + + "\n"); + } + +#ifdef AMD_EXTENSIONS + // GL_AMD_shader_explicit_vertex_parameter + if (profile != EEsProfile && version >= 450) { + stageBuiltins[EShLangFragment].append( + "float interpolateAtVertexAMD(float, uint);" + "vec2 interpolateAtVertexAMD(vec2, uint);" + "vec3 interpolateAtVertexAMD(vec3, uint);" + "vec4 interpolateAtVertexAMD(vec4, uint);" + + "int interpolateAtVertexAMD(int, uint);" + "ivec2 interpolateAtVertexAMD(ivec2, uint);" + "ivec3 interpolateAtVertexAMD(ivec3, uint);" + "ivec4 interpolateAtVertexAMD(ivec4, uint);" + + "uint interpolateAtVertexAMD(uint, uint);" + "uvec2 interpolateAtVertexAMD(uvec2, uint);" + "uvec3 interpolateAtVertexAMD(uvec3, uint);" + "uvec4 interpolateAtVertexAMD(uvec4, uint);" + + "float16_t interpolateAtVertexAMD(float16_t, uint);" + "f16vec2 interpolateAtVertexAMD(f16vec2, uint);" + "f16vec3 interpolateAtVertexAMD(f16vec3, uint);" + "f16vec4 interpolateAtVertexAMD(f16vec4, uint);" + + "\n"); + } + + // GL_AMD_gpu_shader_half_float + if (profile != EEsProfile && version >= 450) { + stageBuiltins[EShLangFragment].append( + "float16_t dFdx(float16_t);" + "f16vec2 dFdx(f16vec2);" + "f16vec3 dFdx(f16vec3);" + "f16vec4 dFdx(f16vec4);" + + "float16_t dFdy(float16_t);" + "f16vec2 dFdy(f16vec2);" + "f16vec3 dFdy(f16vec3);" + "f16vec4 dFdy(f16vec4);" + + "float16_t dFdxFine(float16_t);" + "f16vec2 dFdxFine(f16vec2);" + "f16vec3 dFdxFine(f16vec3);" + "f16vec4 dFdxFine(f16vec4);" + + "float16_t dFdyFine(float16_t);" + "f16vec2 dFdyFine(f16vec2);" + "f16vec3 dFdyFine(f16vec3);" + "f16vec4 dFdyFine(f16vec4);" + + "float16_t dFdxCoarse(float16_t);" + "f16vec2 dFdxCoarse(f16vec2);" + "f16vec3 dFdxCoarse(f16vec3);" + "f16vec4 dFdxCoarse(f16vec4);" + + "float16_t dFdyCoarse(float16_t);" + "f16vec2 dFdyCoarse(f16vec2);" + "f16vec3 dFdyCoarse(f16vec3);" + "f16vec4 dFdyCoarse(f16vec4);" + + "float16_t fwidth(float16_t);" + "f16vec2 fwidth(f16vec2);" + "f16vec3 fwidth(f16vec3);" + "f16vec4 fwidth(f16vec4);" + + "float16_t fwidthFine(float16_t);" + "f16vec2 fwidthFine(f16vec2);" + "f16vec3 fwidthFine(f16vec3);" + "f16vec4 fwidthFine(f16vec4);" + + "float16_t fwidthCoarse(float16_t);" + "f16vec2 fwidthCoarse(f16vec2);" + "f16vec3 fwidthCoarse(f16vec3);" + "f16vec4 fwidthCoarse(f16vec4);" + + "float16_t interpolateAtCentroid(float16_t);" + "f16vec2 interpolateAtCentroid(f16vec2);" + "f16vec3 interpolateAtCentroid(f16vec3);" + "f16vec4 interpolateAtCentroid(f16vec4);" + + "float16_t interpolateAtSample(float16_t, int);" + "f16vec2 interpolateAtSample(f16vec2, int);" + "f16vec3 interpolateAtSample(f16vec3, int);" + "f16vec4 interpolateAtSample(f16vec4, int);" + + "float16_t interpolateAtOffset(float16_t, f16vec2);" + "f16vec2 interpolateAtOffset(f16vec2, f16vec2);" + "f16vec3 interpolateAtOffset(f16vec3, f16vec2);" + "f16vec4 interpolateAtOffset(f16vec4, f16vec2);" + + "\n"); + } + + // GL_AMD_shader_fragment_mask + if (profile != EEsProfile && version >= 450 && spvVersion.vulkan >= 100) { + stageBuiltins[EShLangFragment].append( + "uint fragmentMaskFetchAMD(subpassInputMS);" + "uint fragmentMaskFetchAMD(isubpassInputMS);" + "uint fragmentMaskFetchAMD(usubpassInputMS);" + + "vec4 fragmentFetchAMD(subpassInputMS, uint);" + "ivec4 fragmentFetchAMD(isubpassInputMS, uint);" + "uvec4 fragmentFetchAMD(usubpassInputMS, uint);" + + "\n"); + } +#endif + + //============================================================================ + // + // Standard Uniforms + // + //============================================================================ + + // + // Depth range in window coordinates, p. 33 + // + if (spvVersion.spv == 0) { + commonBuiltins.append( + "struct gl_DepthRangeParameters {" + ); + if (profile == EEsProfile) { + commonBuiltins.append( + "highp float near;" // n + "highp float far;" // f + "highp float diff;" // f - n + ); + } else { + commonBuiltins.append( + "float near;" // n + "float far;" // f + "float diff;" // f - n + ); + } + + commonBuiltins.append( + "};" + "uniform gl_DepthRangeParameters gl_DepthRange;" + "\n"); + } + + if (spvVersion.spv == 0 && IncludeLegacy(version, profile, spvVersion)) { + // + // Matrix state. p. 31, 32, 37, 39, 40. + // + commonBuiltins.append( + "uniform mat4 gl_ModelViewMatrix;" + "uniform mat4 gl_ProjectionMatrix;" + "uniform mat4 gl_ModelViewProjectionMatrix;" + + // + // Derived matrix state that provides inverse and transposed versions + // of the matrices above. + // + "uniform mat3 gl_NormalMatrix;" + + "uniform mat4 gl_ModelViewMatrixInverse;" + "uniform mat4 gl_ProjectionMatrixInverse;" + "uniform mat4 gl_ModelViewProjectionMatrixInverse;" + + "uniform mat4 gl_ModelViewMatrixTranspose;" + "uniform mat4 gl_ProjectionMatrixTranspose;" + "uniform mat4 gl_ModelViewProjectionMatrixTranspose;" + + "uniform mat4 gl_ModelViewMatrixInverseTranspose;" + "uniform mat4 gl_ProjectionMatrixInverseTranspose;" + "uniform mat4 gl_ModelViewProjectionMatrixInverseTranspose;" + + // + // Normal scaling p. 39. + // + "uniform float gl_NormalScale;" + + // + // Point Size, p. 66, 67. + // + "struct gl_PointParameters {" + "float size;" + "float sizeMin;" + "float sizeMax;" + "float fadeThresholdSize;" + "float distanceConstantAttenuation;" + "float distanceLinearAttenuation;" + "float distanceQuadraticAttenuation;" + "};" + + "uniform gl_PointParameters gl_Point;" + + // + // Material State p. 50, 55. + // + "struct gl_MaterialParameters {" + "vec4 emission;" // Ecm + "vec4 ambient;" // Acm + "vec4 diffuse;" // Dcm + "vec4 specular;" // Scm + "float shininess;" // Srm + "};" + "uniform gl_MaterialParameters gl_FrontMaterial;" + "uniform gl_MaterialParameters gl_BackMaterial;" + + // + // Light State p 50, 53, 55. + // + "struct gl_LightSourceParameters {" + "vec4 ambient;" // Acli + "vec4 diffuse;" // Dcli + "vec4 specular;" // Scli + "vec4 position;" // Ppli + "vec4 halfVector;" // Derived: Hi + "vec3 spotDirection;" // Sdli + "float spotExponent;" // Srli + "float spotCutoff;" // Crli + // (range: [0.0,90.0], 180.0) + "float spotCosCutoff;" // Derived: cos(Crli) + // (range: [1.0,0.0],-1.0) + "float constantAttenuation;" // K0 + "float linearAttenuation;" // K1 + "float quadraticAttenuation;"// K2 + "};" + + "struct gl_LightModelParameters {" + "vec4 ambient;" // Acs + "};" + + "uniform gl_LightModelParameters gl_LightModel;" + + // + // Derived state from products of light and material. + // + "struct gl_LightModelProducts {" + "vec4 sceneColor;" // Derived. Ecm + Acm * Acs + "};" + + "uniform gl_LightModelProducts gl_FrontLightModelProduct;" + "uniform gl_LightModelProducts gl_BackLightModelProduct;" + + "struct gl_LightProducts {" + "vec4 ambient;" // Acm * Acli + "vec4 diffuse;" // Dcm * Dcli + "vec4 specular;" // Scm * Scli + "};" + + // + // Fog p. 161 + // + "struct gl_FogParameters {" + "vec4 color;" + "float density;" + "float start;" + "float end;" + "float scale;" // 1 / (gl_FogEnd - gl_FogStart) + "};" + + "uniform gl_FogParameters gl_Fog;" + + "\n"); + } + + //============================================================================ + // + // Define the interface to the compute shader. + // + //============================================================================ + + if ((profile != EEsProfile && version >= 420) || + (profile == EEsProfile && version >= 310)) { + stageBuiltins[EShLangCompute].append( + "in highp uvec3 gl_NumWorkGroups;" + "const highp uvec3 gl_WorkGroupSize = uvec3(1,1,1);" + + "in highp uvec3 gl_WorkGroupID;" + "in highp uvec3 gl_LocalInvocationID;" + + "in highp uvec3 gl_GlobalInvocationID;" + "in highp uint gl_LocalInvocationIndex;" + + "\n"); + } + + if ((profile != EEsProfile && version >= 140) || + (profile == EEsProfile && version >= 310)) { + stageBuiltins[EShLangCompute].append( + "in highp int gl_DeviceIndex;" // GL_EXT_device_group + "\n"); + } + + //============================================================================ + // + // Define the interface to the vertex shader. + // + //============================================================================ + + if (profile != EEsProfile) { + if (version < 130) { + stageBuiltins[EShLangVertex].append( + "attribute vec4 gl_Color;" + "attribute vec4 gl_SecondaryColor;" + "attribute vec3 gl_Normal;" + "attribute vec4 gl_Vertex;" + "attribute vec4 gl_MultiTexCoord0;" + "attribute vec4 gl_MultiTexCoord1;" + "attribute vec4 gl_MultiTexCoord2;" + "attribute vec4 gl_MultiTexCoord3;" + "attribute vec4 gl_MultiTexCoord4;" + "attribute vec4 gl_MultiTexCoord5;" + "attribute vec4 gl_MultiTexCoord6;" + "attribute vec4 gl_MultiTexCoord7;" + "attribute float gl_FogCoord;" + "\n"); + } else if (IncludeLegacy(version, profile, spvVersion)) { + stageBuiltins[EShLangVertex].append( + "in vec4 gl_Color;" + "in vec4 gl_SecondaryColor;" + "in vec3 gl_Normal;" + "in vec4 gl_Vertex;" + "in vec4 gl_MultiTexCoord0;" + "in vec4 gl_MultiTexCoord1;" + "in vec4 gl_MultiTexCoord2;" + "in vec4 gl_MultiTexCoord3;" + "in vec4 gl_MultiTexCoord4;" + "in vec4 gl_MultiTexCoord5;" + "in vec4 gl_MultiTexCoord6;" + "in vec4 gl_MultiTexCoord7;" + "in float gl_FogCoord;" + "\n"); + } + + if (version < 150) { + if (version < 130) { + stageBuiltins[EShLangVertex].append( + " vec4 gl_ClipVertex;" // needs qualifier fixed later + "varying vec4 gl_FrontColor;" + "varying vec4 gl_BackColor;" + "varying vec4 gl_FrontSecondaryColor;" + "varying vec4 gl_BackSecondaryColor;" + "varying vec4 gl_TexCoord[];" + "varying float gl_FogFragCoord;" + "\n"); + } else if (IncludeLegacy(version, profile, spvVersion)) { + stageBuiltins[EShLangVertex].append( + " vec4 gl_ClipVertex;" // needs qualifier fixed later + "out vec4 gl_FrontColor;" + "out vec4 gl_BackColor;" + "out vec4 gl_FrontSecondaryColor;" + "out vec4 gl_BackSecondaryColor;" + "out vec4 gl_TexCoord[];" + "out float gl_FogFragCoord;" + "\n"); + } + stageBuiltins[EShLangVertex].append( + "vec4 gl_Position;" // needs qualifier fixed later + "float gl_PointSize;" // needs qualifier fixed later + ); + + if (version == 130 || version == 140) + stageBuiltins[EShLangVertex].append( + "out float gl_ClipDistance[];" + ); + } else { + // version >= 150 + stageBuiltins[EShLangVertex].append( + "out gl_PerVertex {" + "vec4 gl_Position;" // needs qualifier fixed later + "float gl_PointSize;" // needs qualifier fixed later + "float gl_ClipDistance[];" + ); + if (IncludeLegacy(version, profile, spvVersion)) + stageBuiltins[EShLangVertex].append( + "vec4 gl_ClipVertex;" // needs qualifier fixed later + "vec4 gl_FrontColor;" + "vec4 gl_BackColor;" + "vec4 gl_FrontSecondaryColor;" + "vec4 gl_BackSecondaryColor;" + "vec4 gl_TexCoord[];" + "float gl_FogFragCoord;" + ); + if (version >= 450) + stageBuiltins[EShLangVertex].append( + "float gl_CullDistance[];" + ); + stageBuiltins[EShLangVertex].append( + "};" + "\n"); + } + if (version >= 130 && spvVersion.vulkan == 0) + stageBuiltins[EShLangVertex].append( + "int gl_VertexID;" // needs qualifier fixed later + ); + if (version >= 140 && spvVersion.vulkan == 0) + stageBuiltins[EShLangVertex].append( + "int gl_InstanceID;" // needs qualifier fixed later + ); + if (spvVersion.vulkan >= 100 && version >= 140) + stageBuiltins[EShLangVertex].append( + "in int gl_VertexIndex;" + "in int gl_InstanceIndex;" + ); + if (version >= 440) { + stageBuiltins[EShLangVertex].append( + "in int gl_BaseVertexARB;" + "in int gl_BaseInstanceARB;" + "in int gl_DrawIDARB;" + ); + } + if (version >= 410) { + stageBuiltins[EShLangVertex].append( + "out int gl_ViewportIndex;" + "out int gl_Layer;" + ); + } + if (version >= 460) { + stageBuiltins[EShLangVertex].append( + "in int gl_BaseVertex;" + "in int gl_BaseInstance;" + "in int gl_DrawID;" + ); + } + +#ifdef NV_EXTENSIONS + if (version >= 450) + stageBuiltins[EShLangVertex].append( + "out int gl_ViewportMask[];" // GL_NV_viewport_array2 + "out int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering + "out vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering + "out vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes + "out int gl_ViewportMaskPerViewNV[];" // GL_NVX_multiview_per_view_attributes + ); +#endif + + } else { + // ES profile + if (version == 100) { + stageBuiltins[EShLangVertex].append( + "highp vec4 gl_Position;" // needs qualifier fixed later + "mediump float gl_PointSize;" // needs qualifier fixed later + ); + } else { + if (spvVersion.vulkan == 0) + stageBuiltins[EShLangVertex].append( + "in highp int gl_VertexID;" // needs qualifier fixed later + "in highp int gl_InstanceID;" // needs qualifier fixed later + ); + if (spvVersion.vulkan >= 100) + stageBuiltins[EShLangVertex].append( + "in highp int gl_VertexIndex;" + "in highp int gl_InstanceIndex;" + ); + if (version < 310) + stageBuiltins[EShLangVertex].append( + "highp vec4 gl_Position;" // needs qualifier fixed later + "highp float gl_PointSize;" // needs qualifier fixed later + ); + else + stageBuiltins[EShLangVertex].append( + "out gl_PerVertex {" + "highp vec4 gl_Position;" // needs qualifier fixed later + "highp float gl_PointSize;" // needs qualifier fixed later + "};" + ); + } + } + + if ((profile != EEsProfile && version >= 140) || + (profile == EEsProfile && version >= 310)) { + stageBuiltins[EShLangVertex].append( + "in highp int gl_DeviceIndex;" // GL_EXT_device_group + "in highp int gl_ViewIndex;" // GL_EXT_multiview + "\n"); + } + + if (version >= 300 /* both ES and non-ES */) { + stageBuiltins[EShLangVertex].append( + "in highp uint gl_ViewID_OVR;" // GL_OVR_multiview, GL_OVR_multiview2 + "\n"); + } + + + //============================================================================ + // + // Define the interface to the geometry shader. + // + //============================================================================ + + if (profile == ECoreProfile || profile == ECompatibilityProfile) { + stageBuiltins[EShLangGeometry].append( + "in gl_PerVertex {" + "vec4 gl_Position;" + "float gl_PointSize;" + "float gl_ClipDistance[];" + ); + if (profile == ECompatibilityProfile) + stageBuiltins[EShLangGeometry].append( + "vec4 gl_ClipVertex;" + "vec4 gl_FrontColor;" + "vec4 gl_BackColor;" + "vec4 gl_FrontSecondaryColor;" + "vec4 gl_BackSecondaryColor;" + "vec4 gl_TexCoord[];" + "float gl_FogFragCoord;" + ); + if (version >= 450) + stageBuiltins[EShLangGeometry].append( + "float gl_CullDistance[];" +#ifdef NV_EXTENSIONS + "vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering + "vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes +#endif + ); + stageBuiltins[EShLangGeometry].append( + "} gl_in[];" + + "in int gl_PrimitiveIDIn;" + "out gl_PerVertex {" + "vec4 gl_Position;" + "float gl_PointSize;" + "float gl_ClipDistance[];" + "\n"); + if (profile == ECompatibilityProfile && version >= 400) + stageBuiltins[EShLangGeometry].append( + "vec4 gl_ClipVertex;" + "vec4 gl_FrontColor;" + "vec4 gl_BackColor;" + "vec4 gl_FrontSecondaryColor;" + "vec4 gl_BackSecondaryColor;" + "vec4 gl_TexCoord[];" + "float gl_FogFragCoord;" + ); + if (version >= 450) + stageBuiltins[EShLangGeometry].append( + "float gl_CullDistance[];" + ); + stageBuiltins[EShLangGeometry].append( + "};" + + "out int gl_PrimitiveID;" + "out int gl_Layer;"); + + if (version >= 150) + stageBuiltins[EShLangGeometry].append( + "out int gl_ViewportIndex;" + ); + + if (profile == ECompatibilityProfile && version < 400) + stageBuiltins[EShLangGeometry].append( + "out vec4 gl_ClipVertex;" + ); + + if (version >= 400) + stageBuiltins[EShLangGeometry].append( + "in int gl_InvocationID;" + ); + +#ifdef NV_EXTENSIONS + if (version >= 450) + stageBuiltins[EShLangGeometry].append( + "out int gl_ViewportMask[];" // GL_NV_viewport_array2 + "out int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering + "out vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering + "out vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes + "out int gl_ViewportMaskPerViewNV[];" // GL_NVX_multiview_per_view_attributes + ); +#endif + + stageBuiltins[EShLangGeometry].append("\n"); + } else if (profile == EEsProfile && version >= 310) { + stageBuiltins[EShLangGeometry].append( + "in gl_PerVertex {" + "highp vec4 gl_Position;" + "highp float gl_PointSize;" + "} gl_in[];" + "\n" + "in highp int gl_PrimitiveIDIn;" + "in highp int gl_InvocationID;" + "\n" + "out gl_PerVertex {" + "highp vec4 gl_Position;" + "highp float gl_PointSize;" + "};" + "\n" + "out highp int gl_PrimitiveID;" + "out highp int gl_Layer;" + "\n" + ); + } + + if ((profile != EEsProfile && version >= 140) || + (profile == EEsProfile && version >= 310)) { + stageBuiltins[EShLangGeometry].append( + "in highp int gl_DeviceIndex;" // GL_EXT_device_group + "in highp int gl_ViewIndex;" // GL_EXT_multiview + "\n"); + } + + //============================================================================ + // + // Define the interface to the tessellation control shader. + // + //============================================================================ + + if (profile != EEsProfile && version >= 150) { + // Note: "in gl_PerVertex {...} gl_in[gl_MaxPatchVertices];" is declared in initialize() below, + // as it depends on the resource sizing of gl_MaxPatchVertices. + + stageBuiltins[EShLangTessControl].append( + "in int gl_PatchVerticesIn;" + "in int gl_PrimitiveID;" + "in int gl_InvocationID;" + + "out gl_PerVertex {" + "vec4 gl_Position;" + "float gl_PointSize;" + "float gl_ClipDistance[];" + ); + if (profile == ECompatibilityProfile) + stageBuiltins[EShLangTessControl].append( + "vec4 gl_ClipVertex;" + "vec4 gl_FrontColor;" + "vec4 gl_BackColor;" + "vec4 gl_FrontSecondaryColor;" + "vec4 gl_BackSecondaryColor;" + "vec4 gl_TexCoord[];" + "float gl_FogFragCoord;" + ); + if (version >= 450) + stageBuiltins[EShLangTessControl].append( + "float gl_CullDistance[];" +#ifdef NV_EXTENSIONS + "int gl_ViewportMask[];" // GL_NV_viewport_array2 + "vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering + "int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering + "vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes + "int gl_ViewportMaskPerViewNV[];" // GL_NVX_multiview_per_view_attributes +#endif + ); + stageBuiltins[EShLangTessControl].append( + "} gl_out[];" + + "patch out float gl_TessLevelOuter[4];" + "patch out float gl_TessLevelInner[2];" + "\n"); + + if (version >= 410) + stageBuiltins[EShLangTessControl].append( + "out int gl_ViewportIndex;" + "out int gl_Layer;" + "\n"); + + } else { + // Note: "in gl_PerVertex {...} gl_in[gl_MaxPatchVertices];" is declared in initialize() below, + // as it depends on the resource sizing of gl_MaxPatchVertices. + + stageBuiltins[EShLangTessControl].append( + "in highp int gl_PatchVerticesIn;" + "in highp int gl_PrimitiveID;" + "in highp int gl_InvocationID;" + + "out gl_PerVertex {" + "highp vec4 gl_Position;" + "highp float gl_PointSize;" + ); + stageBuiltins[EShLangTessControl].append( + "} gl_out[];" + + "patch out highp float gl_TessLevelOuter[4];" + "patch out highp float gl_TessLevelInner[2];" + "patch out highp vec4 gl_BoundingBoxOES[2];" + "\n"); + } + + if ((profile != EEsProfile && version >= 140) || + (profile == EEsProfile && version >= 310)) { + stageBuiltins[EShLangTessControl].append( + "in highp int gl_DeviceIndex;" // GL_EXT_device_group + "in highp int gl_ViewIndex;" // GL_EXT_multiview + "\n"); + } + + //============================================================================ + // + // Define the interface to the tessellation evaluation shader. + // + //============================================================================ + + if (profile != EEsProfile && version >= 150) { + // Note: "in gl_PerVertex {...} gl_in[gl_MaxPatchVertices];" is declared in initialize() below, + // as it depends on the resource sizing of gl_MaxPatchVertices. + + stageBuiltins[EShLangTessEvaluation].append( + "in int gl_PatchVerticesIn;" + "in int gl_PrimitiveID;" + "in vec3 gl_TessCoord;" + + "patch in float gl_TessLevelOuter[4];" + "patch in float gl_TessLevelInner[2];" + + "out gl_PerVertex {" + "vec4 gl_Position;" + "float gl_PointSize;" + "float gl_ClipDistance[];" + ); + if (version >= 400 && profile == ECompatibilityProfile) + stageBuiltins[EShLangTessEvaluation].append( + "vec4 gl_ClipVertex;" + "vec4 gl_FrontColor;" + "vec4 gl_BackColor;" + "vec4 gl_FrontSecondaryColor;" + "vec4 gl_BackSecondaryColor;" + "vec4 gl_TexCoord[];" + "float gl_FogFragCoord;" + ); + if (version >= 450) + stageBuiltins[EShLangTessEvaluation].append( + "float gl_CullDistance[];" + ); + stageBuiltins[EShLangTessEvaluation].append( + "};" + "\n"); + + if (version >= 410) + stageBuiltins[EShLangTessEvaluation].append( + "out int gl_ViewportIndex;" + "out int gl_Layer;" + "\n"); + +#ifdef NV_EXTENSIONS + if (version >= 450) + stageBuiltins[EShLangTessEvaluation].append( + "out int gl_ViewportMask[];" // GL_NV_viewport_array2 + "out vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering + "out int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering + "out vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes + "out int gl_ViewportMaskPerViewNV[];" // GL_NVX_multiview_per_view_attributes + ); +#endif + + } else if (profile == EEsProfile && version >= 310) { + // Note: "in gl_PerVertex {...} gl_in[gl_MaxPatchVertices];" is declared in initialize() below, + // as it depends on the resource sizing of gl_MaxPatchVertices. + + stageBuiltins[EShLangTessEvaluation].append( + "in highp int gl_PatchVerticesIn;" + "in highp int gl_PrimitiveID;" + "in highp vec3 gl_TessCoord;" + + "patch in highp float gl_TessLevelOuter[4];" + "patch in highp float gl_TessLevelInner[2];" + + "out gl_PerVertex {" + "highp vec4 gl_Position;" + "highp float gl_PointSize;" + ); + stageBuiltins[EShLangTessEvaluation].append( + "};" + "\n"); + } + + if ((profile != EEsProfile && version >= 140) || + (profile == EEsProfile && version >= 310)) { + stageBuiltins[EShLangTessEvaluation].append( + "in highp int gl_DeviceIndex;" // GL_EXT_device_group + "in highp int gl_ViewIndex;" // GL_EXT_multiview + "\n"); + } + + //============================================================================ + // + // Define the interface to the fragment shader. + // + //============================================================================ + + if (profile != EEsProfile) { + + stageBuiltins[EShLangFragment].append( + "vec4 gl_FragCoord;" // needs qualifier fixed later + "bool gl_FrontFacing;" // needs qualifier fixed later + "float gl_FragDepth;" // needs qualifier fixed later + ); + if (version >= 120) + stageBuiltins[EShLangFragment].append( + "vec2 gl_PointCoord;" // needs qualifier fixed later + ); + if (version >= 140) + stageBuiltins[EShLangFragment].append( + "out int gl_FragStencilRefARB;" + ); + if (IncludeLegacy(version, profile, spvVersion) || (! ForwardCompatibility && version < 420)) + stageBuiltins[EShLangFragment].append( + "vec4 gl_FragColor;" // needs qualifier fixed later + ); + + if (version < 130) { + stageBuiltins[EShLangFragment].append( + "varying vec4 gl_Color;" + "varying vec4 gl_SecondaryColor;" + "varying vec4 gl_TexCoord[];" + "varying float gl_FogFragCoord;" + ); + } else { + stageBuiltins[EShLangFragment].append( + "in float gl_ClipDistance[];" + ); + + if (IncludeLegacy(version, profile, spvVersion)) { + if (version < 150) + stageBuiltins[EShLangFragment].append( + "in float gl_FogFragCoord;" + "in vec4 gl_TexCoord[];" + "in vec4 gl_Color;" + "in vec4 gl_SecondaryColor;" + ); + else + stageBuiltins[EShLangFragment].append( + "in gl_PerFragment {" + "in float gl_FogFragCoord;" + "in vec4 gl_TexCoord[];" + "in vec4 gl_Color;" + "in vec4 gl_SecondaryColor;" + "};" + ); + } + } + + if (version >= 150) + stageBuiltins[EShLangFragment].append( + "flat in int gl_PrimitiveID;" + ); + + if (version >= 400) { + stageBuiltins[EShLangFragment].append( + "flat in int gl_SampleID;" + " in vec2 gl_SamplePosition;" + "flat in int gl_SampleMaskIn[];" + " out int gl_SampleMask[];" + ); + if (spvVersion.spv == 0) + stageBuiltins[EShLangFragment].append( + "uniform int gl_NumSamples;" + ); + } + + if (version >= 430) + stageBuiltins[EShLangFragment].append( + "flat in int gl_Layer;" + "flat in int gl_ViewportIndex;" + ); + + if (version >= 450) + stageBuiltins[EShLangFragment].append( + "in float gl_CullDistance[];" + "bool gl_HelperInvocation;" // needs qualifier fixed later + ); + +#ifdef AMD_EXTENSIONS + if (version >= 450) + stageBuiltins[EShLangFragment].append( + "in vec2 gl_BaryCoordNoPerspAMD;" + "in vec2 gl_BaryCoordNoPerspCentroidAMD;" + "in vec2 gl_BaryCoordNoPerspSampleAMD;" + "in vec2 gl_BaryCoordSmoothAMD;" + "in vec2 gl_BaryCoordSmoothCentroidAMD;" + "in vec2 gl_BaryCoordSmoothSampleAMD;" + "in vec3 gl_BaryCoordPullModelAMD;" + ); +#endif + +#ifdef NV_EXTENSIONS + if (version >= 430) + stageBuiltins[EShLangFragment].append( + "in bool gl_FragFullyCoveredNV;" + ); +#endif + } else { + // ES profile + + if (version == 100) { + stageBuiltins[EShLangFragment].append( + "mediump vec4 gl_FragCoord;" // needs qualifier fixed later + " bool gl_FrontFacing;" // needs qualifier fixed later + "mediump vec4 gl_FragColor;" // needs qualifier fixed later + "mediump vec2 gl_PointCoord;" // needs qualifier fixed later + ); + } + if (version >= 300) { + stageBuiltins[EShLangFragment].append( + "highp vec4 gl_FragCoord;" // needs qualifier fixed later + " bool gl_FrontFacing;" // needs qualifier fixed later + "mediump vec2 gl_PointCoord;" // needs qualifier fixed later + "highp float gl_FragDepth;" // needs qualifier fixed later + ); + } + if (version >= 310) { + stageBuiltins[EShLangFragment].append( + "bool gl_HelperInvocation;" // needs qualifier fixed later + "flat in highp int gl_PrimitiveID;" // needs qualifier fixed later + "flat in highp int gl_Layer;" // needs qualifier fixed later + ); + + stageBuiltins[EShLangFragment].append( // GL_OES_sample_variables + "flat in lowp int gl_SampleID;" + " in mediump vec2 gl_SamplePosition;" + "flat in highp int gl_SampleMaskIn[];" + " out highp int gl_SampleMask[];" + ); + if (spvVersion.spv == 0) + stageBuiltins[EShLangFragment].append( // GL_OES_sample_variables + "uniform lowp int gl_NumSamples;" + ); + } + stageBuiltins[EShLangFragment].append( + "highp float gl_FragDepthEXT;" // GL_EXT_frag_depth + ); + } + stageBuiltins[EShLangFragment].append("\n"); + + if (version >= 130) + add2ndGenerationSamplingImaging(version, profile, spvVersion); + + // GL_ARB_shader_ballot + if (profile != EEsProfile && version >= 450) { + commonBuiltins.append( + "uniform uint gl_SubGroupSizeARB;" + + "in uint gl_SubGroupInvocationARB;" + "in uint64_t gl_SubGroupEqMaskARB;" + "in uint64_t gl_SubGroupGeMaskARB;" + "in uint64_t gl_SubGroupGtMaskARB;" + "in uint64_t gl_SubGroupLeMaskARB;" + "in uint64_t gl_SubGroupLtMaskARB;" + + "\n"); + } + + if ((profile != EEsProfile && version >= 140) || + (profile == EEsProfile && version >= 310)) { + stageBuiltins[EShLangFragment].append( + "flat in highp int gl_DeviceIndex;" // GL_EXT_device_group + "flat in highp int gl_ViewIndex;" // GL_EXT_multiview + "\n"); + } + + if (version >= 300 /* both ES and non-ES */) { + stageBuiltins[EShLangFragment].append( + "flat in highp uint gl_ViewID_OVR;" // GL_OVR_multiview, GL_OVR_multiview2 + "\n"); + } + + // printf("%s\n", commonBuiltins.c_str()); + // printf("%s\n", stageBuiltins[EShLangFragment].c_str()); +} + +// +// Helper function for initialize(), to add the second set of names for texturing, +// when adding context-independent built-in functions. +// +void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, const SpvVersion& spvVersion) +{ + // + // In this function proper, enumerate the types, then calls the next set of functions + // to enumerate all the uses for that type. + // + + TBasicType bTypes[3] = { EbtFloat, EbtInt, EbtUint }; + bool skipBuffer = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 140); + bool skipCubeArrayed = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 130); + + // enumerate all the types + for (int image = 0; image <= 1; ++image) { // loop over "bool" image vs sampler + + for (int shadow = 0; shadow <= 1; ++shadow) { // loop over "bool" shadow or not + for (int ms = 0; ms <=1; ++ms) { + if ((ms || image) && shadow) + continue; + if (ms && profile != EEsProfile && version < 150) + continue; + if (ms && image && profile == EEsProfile) + continue; + if (ms && profile == EEsProfile && version < 310) + continue; + + for (int arrayed = 0; arrayed <= 1; ++arrayed) { // loop over "bool" arrayed or not + for (int dim = Esd1D; dim < EsdNumDims; ++dim) { // 1D, 2D, ..., buffer + if (dim == EsdSubpass && spvVersion.vulkan == 0) + continue; + if (dim == EsdSubpass && (image || shadow || arrayed)) + continue; + if ((dim == Esd1D || dim == EsdRect) && profile == EEsProfile) + continue; + if (dim != Esd2D && dim != EsdSubpass && ms) + continue; + if ((dim == Esd3D || dim == EsdRect) && arrayed) + continue; + if (dim == Esd3D && shadow) + continue; + if (dim == EsdCube && arrayed && skipCubeArrayed) + continue; + if (dim == EsdBuffer && skipBuffer) + continue; + if (dim == EsdBuffer && (shadow || arrayed || ms)) + continue; + if (ms && arrayed && profile == EEsProfile && version < 310) + continue; + + for (int bType = 0; bType < 3; ++bType) { // float, int, uint results + + if (shadow && bType > 0) + continue; + + if (dim == EsdRect && version < 140 && bType > 0) + continue; + + // + // Now, make all the function prototypes for the type we just built... + // + + TSampler sampler; + if (dim == EsdSubpass) { + sampler.setSubpass(bTypes[bType], ms ? true : false); + } else if (image) { + sampler.setImage(bTypes[bType], (TSamplerDim)dim, arrayed ? true : false, + shadow ? true : false, + ms ? true : false); + } else { + sampler.set(bTypes[bType], (TSamplerDim)dim, arrayed ? true : false, + shadow ? true : false, + ms ? true : false); + } + + TString typeName = sampler.getString(); + + if (dim == EsdSubpass) { + addSubpassSampling(sampler, typeName, version, profile); + continue; + } + + addQueryFunctions(sampler, typeName, version, profile); + + if (image) + addImageFunctions(sampler, typeName, version, profile); + else { + addSamplingFunctions(sampler, typeName, version, profile); + addGatherFunctions(sampler, typeName, version, profile); + + if (spvVersion.vulkan > 0 && sampler.dim == EsdBuffer && sampler.isCombined()) { + // Vulkan wants a textureBuffer to allow texelFetch() -- + // a sampled image with no sampler. + // So, add sampling functions for both the + // samplerBuffer and textureBuffer types. + sampler.setTexture(sampler.type, sampler.dim, sampler.arrayed, sampler.shadow, + sampler.ms); + TString textureTypeName = sampler.getString(); + addSamplingFunctions(sampler, textureTypeName, version, profile); + } + } + } + } + } + } + } + } + + // + // sparseTexelsResidentARB() + // + + if (profile != EEsProfile && version >= 450) { + commonBuiltins.append("bool sparseTexelsResidentARB(int code);\n"); + } +} + +// +// Helper function for add2ndGenerationSamplingImaging(), +// when adding context-independent built-in functions. +// +// Add all the query functions for the given type. +// +void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int version, EProfile profile) +{ + if (sampler.image && ((profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 430))) + return; + + // + // textureSize() and imageSize() + // + + int sizeDims = dimMap[sampler.dim] + (sampler.arrayed ? 1 : 0) - (sampler.dim == EsdCube ? 1 : 0); + if (profile == EEsProfile) + commonBuiltins.append("highp "); + if (sizeDims == 1) + commonBuiltins.append("int"); + else { + commonBuiltins.append("ivec"); + commonBuiltins.append(postfixes[sizeDims]); + } + if (sampler.image) + commonBuiltins.append(" imageSize(readonly writeonly volatile coherent "); + else + commonBuiltins.append(" textureSize("); + commonBuiltins.append(typeName); + if (! sampler.image && sampler.dim != EsdRect && sampler.dim != EsdBuffer && ! sampler.ms) + commonBuiltins.append(",int);\n"); + else + commonBuiltins.append(");\n"); + + // + // textureSamples() and imageSamples() + // + + // GL_ARB_shader_texture_image_samples + // TODO: spec issue? there are no memory qualifiers; how to query a writeonly/readonly image, etc? + if (profile != EEsProfile && version >= 430 && sampler.ms) { + commonBuiltins.append("int "); + if (sampler.image) + commonBuiltins.append("imageSamples(readonly writeonly volatile coherent "); + else + commonBuiltins.append("textureSamples("); + commonBuiltins.append(typeName); + commonBuiltins.append(");\n"); + } + + // + // textureQueryLod(), fragment stage only + // + + if (profile != EEsProfile && version >= 400 && ! sampler.image && sampler.dim != EsdRect && ! sampler.ms && sampler.dim != EsdBuffer) { + stageBuiltins[EShLangFragment].append("vec2 textureQueryLod("); + stageBuiltins[EShLangFragment].append(typeName); + if (dimMap[sampler.dim] == 1) + stageBuiltins[EShLangFragment].append(", float"); + else { + stageBuiltins[EShLangFragment].append(", vec"); + stageBuiltins[EShLangFragment].append(postfixes[dimMap[sampler.dim]]); + } + stageBuiltins[EShLangFragment].append(");\n"); + } + + // + // textureQueryLevels() + // + + if (profile != EEsProfile && version >= 430 && ! sampler.image && sampler.dim != EsdRect && ! sampler.ms && sampler.dim != EsdBuffer) { + commonBuiltins.append("int textureQueryLevels("); + commonBuiltins.append(typeName); + commonBuiltins.append(");\n"); + } +} + +// +// Helper function for add2ndGenerationSamplingImaging(), +// when adding context-independent built-in functions. +// +// Add all the image access functions for the given type. +// +void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int version, EProfile profile) +{ + int dims = dimMap[sampler.dim]; + // most things with an array add a dimension, except for cubemaps + if (sampler.arrayed && sampler.dim != EsdCube) + ++dims; + + TString imageParams = typeName; + if (dims == 1) + imageParams.append(", int"); + else { + imageParams.append(", ivec"); + imageParams.append(postfixes[dims]); + } + if (sampler.ms) + imageParams.append(", int"); + + if (profile == EEsProfile) + commonBuiltins.append("highp "); + commonBuiltins.append(prefixes[sampler.type]); + commonBuiltins.append("vec4 imageLoad(readonly volatile coherent "); + commonBuiltins.append(imageParams); + commonBuiltins.append(");\n"); + + commonBuiltins.append("void imageStore(writeonly volatile coherent "); + commonBuiltins.append(imageParams); + commonBuiltins.append(", "); + commonBuiltins.append(prefixes[sampler.type]); + commonBuiltins.append("vec4);\n"); + + if (sampler.dim != Esd1D && sampler.dim != EsdBuffer && profile != EEsProfile && version >= 450) { + commonBuiltins.append("int sparseImageLoadARB(readonly volatile coherent "); + commonBuiltins.append(imageParams); + commonBuiltins.append(", out "); + commonBuiltins.append(prefixes[sampler.type]); + commonBuiltins.append("vec4"); + commonBuiltins.append(");\n"); + } + + if ( profile != EEsProfile || + (profile == EEsProfile && version >= 310)) { + if (sampler.type == EbtInt || sampler.type == EbtUint) { + const char* dataType = sampler.type == EbtInt ? "highp int" : "highp uint"; + + const int numBuiltins = 7; + + static const char* atomicFunc[numBuiltins] = { + " imageAtomicAdd(volatile coherent ", + " imageAtomicMin(volatile coherent ", + " imageAtomicMax(volatile coherent ", + " imageAtomicAnd(volatile coherent ", + " imageAtomicOr(volatile coherent ", + " imageAtomicXor(volatile coherent ", + " imageAtomicExchange(volatile coherent " + }; + + for (size_t i = 0; i < numBuiltins; ++i) { + commonBuiltins.append(dataType); + commonBuiltins.append(atomicFunc[i]); + commonBuiltins.append(imageParams); + commonBuiltins.append(", "); + commonBuiltins.append(dataType); + commonBuiltins.append(");\n"); + } + + commonBuiltins.append(dataType); + commonBuiltins.append(" imageAtomicCompSwap(volatile coherent "); + commonBuiltins.append(imageParams); + commonBuiltins.append(", "); + commonBuiltins.append(dataType); + commonBuiltins.append(", "); + commonBuiltins.append(dataType); + commonBuiltins.append(");\n"); + } else { + // not int or uint + // GL_ARB_ES3_1_compatibility + // TODO: spec issue: are there restrictions on the kind of layout() that can be used? what about dropping memory qualifiers? + if ((profile != EEsProfile && version >= 450) || + (profile == EEsProfile && version >= 310)) { + commonBuiltins.append("float imageAtomicExchange(volatile coherent "); + commonBuiltins.append(imageParams); + commonBuiltins.append(", float);\n"); + } + } + } + +#ifdef AMD_EXTENSIONS + if (sampler.dim == EsdRect || sampler.dim == EsdBuffer || sampler.shadow || sampler.ms) + return; + + if (profile == EEsProfile || version < 450) + return; + + TString imageLodParams = typeName; + if (dims == 1) + imageLodParams.append(", int"); + else { + imageLodParams.append(", ivec"); + imageLodParams.append(postfixes[dims]); + } + imageLodParams.append(", int"); + + commonBuiltins.append(prefixes[sampler.type]); + commonBuiltins.append("vec4 imageLoadLodAMD(readonly volatile coherent "); + commonBuiltins.append(imageLodParams); + commonBuiltins.append(");\n"); + + commonBuiltins.append("void imageStoreLodAMD(writeonly volatile coherent "); + commonBuiltins.append(imageLodParams); + commonBuiltins.append(", "); + commonBuiltins.append(prefixes[sampler.type]); + commonBuiltins.append("vec4);\n"); + + if (sampler.dim != Esd1D) { + commonBuiltins.append("int sparseImageLoadLodAMD(readonly volatile coherent "); + commonBuiltins.append(imageLodParams); + commonBuiltins.append(", out "); + commonBuiltins.append(prefixes[sampler.type]); + commonBuiltins.append("vec4"); + commonBuiltins.append(");\n"); + } +#endif +} + +// +// Helper function for initialize(), +// when adding context-independent built-in functions. +// +// Add all the subpass access functions for the given type. +// +void TBuiltIns::addSubpassSampling(TSampler sampler, const TString& typeName, int /*version*/, EProfile /*profile*/) +{ + stageBuiltins[EShLangFragment].append(prefixes[sampler.type]); + stageBuiltins[EShLangFragment].append("vec4 subpassLoad"); + stageBuiltins[EShLangFragment].append("("); + stageBuiltins[EShLangFragment].append(typeName.c_str()); + if (sampler.ms) + stageBuiltins[EShLangFragment].append(", int"); + stageBuiltins[EShLangFragment].append(");\n"); +} + +// +// Helper function for add2ndGenerationSamplingImaging(), +// when adding context-independent built-in functions. +// +// Add all the texture lookup functions for the given type. +// +void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, int version, EProfile profile) +{ + // + // texturing + // + for (int proj = 0; proj <= 1; ++proj) { // loop over "bool" projective or not + + if (proj && (sampler.dim == EsdCube || sampler.dim == EsdBuffer || sampler.arrayed || sampler.ms)) + continue; + + for (int lod = 0; lod <= 1; ++lod) { + + if (lod && (sampler.dim == EsdBuffer || sampler.dim == EsdRect || sampler.ms)) + continue; + if (lod && sampler.dim == Esd2D && sampler.arrayed && sampler.shadow) + continue; + if (lod && sampler.dim == EsdCube && sampler.shadow) + continue; + + for (int bias = 0; bias <= 1; ++bias) { + + if (bias && (lod || sampler.ms)) + continue; + if (bias && sampler.dim == Esd2D && sampler.shadow && sampler.arrayed) + continue; + if (bias && (sampler.dim == EsdRect || sampler.dim == EsdBuffer)) + continue; + + for (int offset = 0; offset <= 1; ++offset) { // loop over "bool" offset or not + + if (proj + offset + bias + lod > 3) + continue; + if (offset && (sampler.dim == EsdCube || sampler.dim == EsdBuffer || sampler.ms)) + continue; + + for (int fetch = 0; fetch <= 1; ++fetch) { // loop over "bool" fetch or not + + if (proj + offset + fetch + bias + lod > 3) + continue; + if (fetch && (lod || bias)) + continue; + if (fetch && (sampler.shadow || sampler.dim == EsdCube)) + continue; + if (fetch == 0 && (sampler.ms || sampler.dim == EsdBuffer)) + continue; + + for (int grad = 0; grad <= 1; ++grad) { // loop over "bool" grad or not + + if (grad && (lod || bias || sampler.ms)) + continue; + if (grad && sampler.dim == EsdBuffer) + continue; + if (proj + offset + fetch + grad + bias + lod > 3) + continue; + + for (int extraProj = 0; extraProj <= 1; ++extraProj) { + bool compare = false; + int totalDims = dimMap[sampler.dim] + (sampler.arrayed ? 1 : 0); + // skip dummy unused second component for 1D non-array shadows + if (sampler.shadow && totalDims < 2) + totalDims = 2; + totalDims += (sampler.shadow ? 1 : 0) + proj; + if (totalDims > 4 && sampler.shadow) { + compare = true; + totalDims = 4; + } + assert(totalDims <= 4); + + if (extraProj && ! proj) + continue; + if (extraProj && (sampler.dim == Esd3D || sampler.shadow)) + continue; + + for (int lodClamp = 0; lodClamp <= 1 ;++lodClamp) { // loop over "bool" lod clamp + + if (lodClamp && (profile == EEsProfile || version < 450)) + continue; + if (lodClamp && (proj || lod || fetch)) + continue; + + for (int sparse = 0; sparse <= 1; ++sparse) { // loop over "bool" sparse or not + + if (sparse && (profile == EEsProfile || version < 450)) + continue; + // Sparse sampling is not for 1D/1D array texture, buffer texture, and projective texture + if (sparse && (sampler.dim == Esd1D || sampler.dim == EsdBuffer || proj)) + continue; + + TString s; + + // return type + if (sparse) + s.append("int "); + else { + if (sampler.shadow) + s.append("float "); + else { + s.append(prefixes[sampler.type]); + s.append("vec4 "); + } + } + + // name + if (sparse) { + if (fetch) + s.append("sparseTexel"); + else + s.append("sparseTexture"); + } else { + if (fetch) + s.append("texel"); + else + s.append("texture"); + } + if (proj) + s.append("Proj"); + if (lod) + s.append("Lod"); + if (grad) + s.append("Grad"); + if (fetch) + s.append("Fetch"); + if (offset) + s.append("Offset"); + if (lodClamp) + s.append("Clamp"); + if (lodClamp || sparse) + s.append("ARB"); + s.append("("); + + // sampler type + s.append(typeName); + + // P coordinate + if (extraProj) + s.append(",vec4"); + else { + s.append(","); + TBasicType t = fetch ? EbtInt : EbtFloat; + if (totalDims == 1) + s.append(TType::getBasicString(t)); + else { + s.append(prefixes[t]); + s.append("vec"); + s.append(postfixes[totalDims]); + } + } + + if (bias && compare) + continue; + + // non-optional lod argument (lod that's not driven by lod loop) or sample + if ((fetch && sampler.dim != EsdBuffer && sampler.dim != EsdRect && !sampler.ms) || + (sampler.ms && fetch)) + s.append(",int"); + + // non-optional lod + if (lod) + s.append(",float"); + + // gradient arguments + if (grad) { + if (dimMap[sampler.dim] == 1) + s.append(",float,float"); + else { + s.append(",vec"); + s.append(postfixes[dimMap[sampler.dim]]); + s.append(",vec"); + s.append(postfixes[dimMap[sampler.dim]]); + } + } + + // offset + if (offset) { + if (dimMap[sampler.dim] == 1) + s.append(",int"); + else { + s.append(",ivec"); + s.append(postfixes[dimMap[sampler.dim]]); + } + } + + // non-optional compare + if (compare) + s.append(",float"); + + // lod clamp + if (lodClamp) + s.append(",float"); + + // texel out (for sparse texture) + if (sparse) { + s.append(",out "); + if (sampler.shadow) + s.append("float "); + else { + s.append(prefixes[sampler.type]); + s.append("vec4 "); + } + } + + // optional bias + if (bias) + s.append(",float"); + + s.append(");\n"); + + // Add to the per-language set of built-ins + + if (bias || lodClamp) + stageBuiltins[EShLangFragment].append(s); + else + commonBuiltins.append(s); + } + } + } + } + } + } + } + } + } +} + +// +// Helper function for add2ndGenerationSamplingImaging(), +// when adding context-independent built-in functions. +// +// Add all the texture gather functions for the given type. +// +void TBuiltIns::addGatherFunctions(TSampler sampler, const TString& typeName, int version, EProfile profile) +{ + switch (sampler.dim) { + case Esd2D: + case EsdRect: + case EsdCube: + break; + default: + return; + } + + if (sampler.ms) + return; + + if (version < 140 && sampler.dim == EsdRect && sampler.type != EbtFloat) + return; + + for (int offset = 0; offset < 3; ++offset) { // loop over three forms of offset in the call name: none, Offset, and Offsets + + for (int comp = 0; comp < 2; ++comp) { // loop over presence of comp argument + + if (comp > 0 && sampler.shadow) + continue; + + if (offset > 0 && sampler.dim == EsdCube) + continue; + + for (int sparse = 0; sparse <= 1; ++sparse) { // loop over "bool" sparse or not + if (sparse && (profile == EEsProfile || version < 450)) + continue; + + TString s; + + // return type + if (sparse) + s.append("int "); + else { + s.append(prefixes[sampler.type]); + s.append("vec4 "); + } + + // name + if (sparse) + s.append("sparseTextureGather"); + else + s.append("textureGather"); + switch (offset) { + case 1: + s.append("Offset"); + break; + case 2: + s.append("Offsets"); + default: + break; + } + + if (sparse) + s.append("ARB"); + s.append("("); + + // sampler type argument + s.append(typeName); + + // P coordinate argument + s.append(",vec"); + int totalDims = dimMap[sampler.dim] + (sampler.arrayed ? 1 : 0); + s.append(postfixes[totalDims]); + + // refZ argument + if (sampler.shadow) + s.append(",float"); + + // offset argument + if (offset > 0) { + s.append(",ivec2"); + if (offset == 2) + s.append("[4]"); + } + + // texel out (for sparse texture) + if (sparse) { + s.append(",out "); + s.append(prefixes[sampler.type]); + s.append("vec4 "); + } + + // comp argument + if (comp) + s.append(",int"); + + s.append(");\n"); + commonBuiltins.append(s); + } + } + } + +#ifdef AMD_EXTENSIONS + if (sampler.dim == EsdRect || sampler.shadow) + return; + + if (profile == EEsProfile || version < 450) + return; + + for (int bias = 0; bias < 2; ++bias) { // loop over presence of bias argument + + for (int lod = 0; lod < 2; ++lod) { // loop over presence of lod argument + + if ((lod && bias) || (lod == 0 && bias == 0)) + continue; + + for (int offset = 0; offset < 3; ++offset) { // loop over three forms of offset in the call name: none, Offset, and Offsets + + for (int comp = 0; comp < 2; ++comp) { // loop over presence of comp argument + + if (comp == 0 && bias) + continue; + + if (offset > 0 && sampler.dim == EsdCube) + continue; + + for (int sparse = 0; sparse <= 1; ++sparse) { // loop over "bool" sparse or not + if (sparse && (profile == EEsProfile || version < 450)) + continue; + + TString s; + + // return type + if (sparse) + s.append("int "); + else { + s.append(prefixes[sampler.type]); + s.append("vec4 "); + } + + // name + if (sparse) + s.append("sparseTextureGather"); + else + s.append("textureGather"); + + if (lod) + s.append("Lod"); + + switch (offset) { + case 1: + s.append("Offset"); + break; + case 2: + s.append("Offsets"); + default: + break; + } + + if (lod) + s.append("AMD"); + else if (sparse) + s.append("ARB"); + + s.append("("); + + // sampler type argument + s.append(typeName); + + // P coordinate argument + s.append(",vec"); + int totalDims = dimMap[sampler.dim] + (sampler.arrayed ? 1 : 0); + s.append(postfixes[totalDims]); + + // lod argument + if (lod) + s.append(",float"); + + // offset argument + if (offset > 0) { + s.append(",ivec2"); + if (offset == 2) + s.append("[4]"); + } + + // texel out (for sparse texture) + if (sparse) { + s.append(",out "); + s.append(prefixes[sampler.type]); + s.append("vec4 "); + } + + // comp argument + if (comp) + s.append(",int"); + + // bias argument + if (bias) + s.append(",float"); + + s.append(");\n"); + if (bias) + stageBuiltins[EShLangFragment].append(s); + else + commonBuiltins.append(s); + } + } + } + } + } +#endif +} + +// +// Add context-dependent built-in functions and variables that are present +// for the given version and profile. All the results are put into just the +// commonBuiltins, because it is called for just a specific stage. So, +// add stage-specific entries to the commonBuiltins, and only if that stage +// was requested. +// +void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language) +{ + // + // Initialize the context-dependent (resource-dependent) built-in strings for parsing. + // + + //============================================================================ + // + // Standard Uniforms + // + //============================================================================ + + TString& s = commonBuiltins; + const int maxSize = 80; + char builtInConstant[maxSize]; + + // + // Build string of implementation dependent constants. + // + + if (profile == EEsProfile) { + snprintf(builtInConstant, maxSize, "const mediump int gl_MaxVertexAttribs = %d;", resources.maxVertexAttribs); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const mediump int gl_MaxVertexUniformVectors = %d;", resources.maxVertexUniformVectors); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const mediump int gl_MaxVertexTextureImageUnits = %d;", resources.maxVertexTextureImageUnits); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const mediump int gl_MaxCombinedTextureImageUnits = %d;", resources.maxCombinedTextureImageUnits); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const mediump int gl_MaxTextureImageUnits = %d;", resources.maxTextureImageUnits); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const mediump int gl_MaxFragmentUniformVectors = %d;", resources.maxFragmentUniformVectors); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const mediump int gl_MaxDrawBuffers = %d;", resources.maxDrawBuffers); + s.append(builtInConstant); + + if (version == 100) { + snprintf(builtInConstant, maxSize, "const mediump int gl_MaxVaryingVectors = %d;", resources.maxVaryingVectors); + s.append(builtInConstant); + } else { + snprintf(builtInConstant, maxSize, "const mediump int gl_MaxVertexOutputVectors = %d;", resources.maxVertexOutputVectors); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const mediump int gl_MaxFragmentInputVectors = %d;", resources.maxFragmentInputVectors); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const mediump int gl_MinProgramTexelOffset = %d;", resources.minProgramTexelOffset); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const mediump int gl_MaxProgramTexelOffset = %d;", resources.maxProgramTexelOffset); + s.append(builtInConstant); + } + + if (version >= 310) { + // geometry + + snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryInputComponents = %d;", resources.maxGeometryInputComponents); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryOutputComponents = %d;", resources.maxGeometryOutputComponents); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryImageUniforms = %d;", resources.maxGeometryImageUniforms); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryTextureImageUnits = %d;", resources.maxGeometryTextureImageUnits); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryOutputVertices = %d;", resources.maxGeometryOutputVertices); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryTotalOutputComponents = %d;", resources.maxGeometryTotalOutputComponents); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryUniformComponents = %d;", resources.maxGeometryUniformComponents); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryAtomicCounters = %d;", resources.maxGeometryAtomicCounters); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryAtomicCounterBuffers = %d;", resources.maxGeometryAtomicCounterBuffers); + s.append(builtInConstant); + + // tessellation + + snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlInputComponents = %d;", resources.maxTessControlInputComponents); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlOutputComponents = %d;", resources.maxTessControlOutputComponents); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlTextureImageUnits = %d;", resources.maxTessControlTextureImageUnits); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlUniformComponents = %d;", resources.maxTessControlUniformComponents); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlTotalOutputComponents = %d;", resources.maxTessControlTotalOutputComponents); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationInputComponents = %d;", resources.maxTessEvaluationInputComponents); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationOutputComponents = %d;", resources.maxTessEvaluationOutputComponents); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationTextureImageUnits = %d;", resources.maxTessEvaluationTextureImageUnits); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationUniformComponents = %d;", resources.maxTessEvaluationUniformComponents); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const int gl_MaxTessPatchComponents = %d;", resources.maxTessPatchComponents); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const int gl_MaxPatchVertices = %d;", resources.maxPatchVertices); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessGenLevel = %d;", resources.maxTessGenLevel); + s.append(builtInConstant); + + // this is here instead of with the others in initialize(version, profile) due to the dependence on gl_MaxPatchVertices + if (language == EShLangTessControl || language == EShLangTessEvaluation) { + s.append( + "in gl_PerVertex {" + "highp vec4 gl_Position;" + "highp float gl_PointSize;" +#ifdef NV_EXTENSIONS + "highp vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering + "highp vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes +#endif + "} gl_in[gl_MaxPatchVertices];" + "\n"); + } + } + + } else { + // non-ES profile + + snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAttribs = %d;", resources.maxVertexAttribs); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const int gl_MaxVertexTextureImageUnits = %d;", resources.maxVertexTextureImageUnits); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedTextureImageUnits = %d;", resources.maxCombinedTextureImageUnits); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const int gl_MaxTextureImageUnits = %d;", resources.maxTextureImageUnits); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const int gl_MaxDrawBuffers = %d;", resources.maxDrawBuffers); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const int gl_MaxLights = %d;", resources.maxLights); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const int gl_MaxClipPlanes = %d;", resources.maxClipPlanes); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const int gl_MaxTextureUnits = %d;", resources.maxTextureUnits); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const int gl_MaxTextureCoords = %d;", resources.maxTextureCoords); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const int gl_MaxVertexUniformComponents = %d;", resources.maxVertexUniformComponents); + s.append(builtInConstant); + + if (version < 150 || ARBCompatibility) { + snprintf(builtInConstant, maxSize, "const int gl_MaxVaryingFloats = %d;", resources.maxVaryingFloats); + s.append(builtInConstant); + } + + snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentUniformComponents = %d;", resources.maxFragmentUniformComponents); + s.append(builtInConstant); + + if (spvVersion.spv == 0 && IncludeLegacy(version, profile, spvVersion)) { + // + // OpenGL'uniform' state. Page numbers are in reference to version + // 1.4 of the OpenGL specification. + // + + // + // Matrix state. p. 31, 32, 37, 39, 40. + // + s.append("uniform mat4 gl_TextureMatrix[gl_MaxTextureCoords];" + + // + // Derived matrix state that provides inverse and transposed versions + // of the matrices above. + // + "uniform mat4 gl_TextureMatrixInverse[gl_MaxTextureCoords];" + + "uniform mat4 gl_TextureMatrixTranspose[gl_MaxTextureCoords];" + + "uniform mat4 gl_TextureMatrixInverseTranspose[gl_MaxTextureCoords];" + + // + // Clip planes p. 42. + // + "uniform vec4 gl_ClipPlane[gl_MaxClipPlanes];" + + // + // Light State p 50, 53, 55. + // + "uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights];" + + // + // Derived state from products of light. + // + "uniform gl_LightProducts gl_FrontLightProduct[gl_MaxLights];" + "uniform gl_LightProducts gl_BackLightProduct[gl_MaxLights];" + + // + // Texture Environment and Generation, p. 152, p. 40-42. + // + "uniform vec4 gl_TextureEnvColor[gl_MaxTextureImageUnits];" + "uniform vec4 gl_EyePlaneS[gl_MaxTextureCoords];" + "uniform vec4 gl_EyePlaneT[gl_MaxTextureCoords];" + "uniform vec4 gl_EyePlaneR[gl_MaxTextureCoords];" + "uniform vec4 gl_EyePlaneQ[gl_MaxTextureCoords];" + "uniform vec4 gl_ObjectPlaneS[gl_MaxTextureCoords];" + "uniform vec4 gl_ObjectPlaneT[gl_MaxTextureCoords];" + "uniform vec4 gl_ObjectPlaneR[gl_MaxTextureCoords];" + "uniform vec4 gl_ObjectPlaneQ[gl_MaxTextureCoords];"); + } + + if (version >= 130) { + snprintf(builtInConstant, maxSize, "const int gl_MaxClipDistances = %d;", resources.maxClipDistances); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxVaryingComponents = %d;", resources.maxVaryingComponents); + s.append(builtInConstant); + + // GL_ARB_shading_language_420pack + snprintf(builtInConstant, maxSize, "const mediump int gl_MinProgramTexelOffset = %d;", resources.minProgramTexelOffset); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const mediump int gl_MaxProgramTexelOffset = %d;", resources.maxProgramTexelOffset); + s.append(builtInConstant); + } + + // geometry + if (version >= 150) { + snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryInputComponents = %d;", resources.maxGeometryInputComponents); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryOutputComponents = %d;", resources.maxGeometryOutputComponents); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryTextureImageUnits = %d;", resources.maxGeometryTextureImageUnits); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryOutputVertices = %d;", resources.maxGeometryOutputVertices); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryTotalOutputComponents = %d;", resources.maxGeometryTotalOutputComponents); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryUniformComponents = %d;", resources.maxGeometryUniformComponents); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryVaryingComponents = %d;", resources.maxGeometryVaryingComponents); + s.append(builtInConstant); + + } + + if (version >= 150) { + snprintf(builtInConstant, maxSize, "const int gl_MaxVertexOutputComponents = %d;", resources.maxVertexOutputComponents); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentInputComponents = %d;", resources.maxFragmentInputComponents); + s.append(builtInConstant); + } + + // tessellation + if (version >= 150) { + snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlInputComponents = %d;", resources.maxTessControlInputComponents); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlOutputComponents = %d;", resources.maxTessControlOutputComponents); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlTextureImageUnits = %d;", resources.maxTessControlTextureImageUnits); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlUniformComponents = %d;", resources.maxTessControlUniformComponents); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlTotalOutputComponents = %d;", resources.maxTessControlTotalOutputComponents); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationInputComponents = %d;", resources.maxTessEvaluationInputComponents); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationOutputComponents = %d;", resources.maxTessEvaluationOutputComponents); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationTextureImageUnits = %d;", resources.maxTessEvaluationTextureImageUnits); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationUniformComponents = %d;", resources.maxTessEvaluationUniformComponents); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const int gl_MaxTessPatchComponents = %d;", resources.maxTessPatchComponents); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessGenLevel = %d;", resources.maxTessGenLevel); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxPatchVertices = %d;", resources.maxPatchVertices); + s.append(builtInConstant); + + // this is here instead of with the others in initialize(version, profile) due to the dependence on gl_MaxPatchVertices + if (language == EShLangTessControl || language == EShLangTessEvaluation) { + s.append( + "in gl_PerVertex {" + "vec4 gl_Position;" + "float gl_PointSize;" + "float gl_ClipDistance[];" + ); + if (profile == ECompatibilityProfile) + s.append( + "vec4 gl_ClipVertex;" + "vec4 gl_FrontColor;" + "vec4 gl_BackColor;" + "vec4 gl_FrontSecondaryColor;" + "vec4 gl_BackSecondaryColor;" + "vec4 gl_TexCoord[];" + "float gl_FogFragCoord;" + ); + if (profile != EEsProfile && version >= 450) + s.append( + "float gl_CullDistance[];" +#ifdef NV_EXTENSIONS + "vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering + "vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes +#endif + ); + s.append( + "} gl_in[gl_MaxPatchVertices];" + "\n"); + } + } + + if (version >= 150) { + snprintf(builtInConstant, maxSize, "const int gl_MaxViewports = %d;", resources.maxViewports); + s.append(builtInConstant); + } + + // images + if (version >= 130) { + snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedImageUnitsAndFragmentOutputs = %d;", resources.maxCombinedImageUnitsAndFragmentOutputs); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxImageSamples = %d;", resources.maxImageSamples); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlImageUniforms = %d;", resources.maxTessControlImageUniforms); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationImageUniforms = %d;", resources.maxTessEvaluationImageUniforms); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryImageUniforms = %d;", resources.maxGeometryImageUniforms); + s.append(builtInConstant); + } + + // enhanced layouts + if (version >= 430) { + snprintf(builtInConstant, maxSize, "const int gl_MaxTransformFeedbackBuffers = %d;", resources.maxTransformFeedbackBuffers); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTransformFeedbackInterleavedComponents = %d;", resources.maxTransformFeedbackInterleavedComponents); + s.append(builtInConstant); + } + } + + // images (some in compute below) + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 130)) { + snprintf(builtInConstant, maxSize, "const int gl_MaxImageUnits = %d;", resources.maxImageUnits); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedShaderOutputResources = %d;", resources.maxCombinedShaderOutputResources); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxVertexImageUniforms = %d;", resources.maxVertexImageUniforms); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentImageUniforms = %d;", resources.maxFragmentImageUniforms); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedImageUniforms = %d;", resources.maxCombinedImageUniforms); + s.append(builtInConstant); + } + + // atomic counters (some in compute below) + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 420)) { + snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAtomicCounters = %d;", resources. maxVertexAtomicCounters); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentAtomicCounters = %d;", resources. maxFragmentAtomicCounters); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedAtomicCounters = %d;", resources. maxCombinedAtomicCounters); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxAtomicCounterBindings = %d;", resources. maxAtomicCounterBindings); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAtomicCounterBuffers = %d;", resources. maxVertexAtomicCounterBuffers); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentAtomicCounterBuffers = %d;", resources. maxFragmentAtomicCounterBuffers); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedAtomicCounterBuffers = %d;", resources. maxCombinedAtomicCounterBuffers); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxAtomicCounterBufferSize = %d;", resources. maxAtomicCounterBufferSize); + s.append(builtInConstant); + } + if (profile != EEsProfile && version >= 420) { + snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlAtomicCounters = %d;", resources. maxTessControlAtomicCounters); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationAtomicCounters = %d;", resources. maxTessEvaluationAtomicCounters); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryAtomicCounters = %d;", resources. maxGeometryAtomicCounters); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlAtomicCounterBuffers = %d;", resources. maxTessControlAtomicCounterBuffers); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationAtomicCounterBuffers = %d;", resources. maxTessEvaluationAtomicCounterBuffers); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryAtomicCounterBuffers = %d;", resources. maxGeometryAtomicCounterBuffers); + s.append(builtInConstant); + + s.append("\n"); + } + + // compute + if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 420)) { + snprintf(builtInConstant, maxSize, "const ivec3 gl_MaxComputeWorkGroupCount = ivec3(%d,%d,%d);", resources.maxComputeWorkGroupCountX, + resources.maxComputeWorkGroupCountY, + resources.maxComputeWorkGroupCountZ); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const ivec3 gl_MaxComputeWorkGroupSize = ivec3(%d,%d,%d);", resources.maxComputeWorkGroupSizeX, + resources.maxComputeWorkGroupSizeY, + resources.maxComputeWorkGroupSizeZ); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const int gl_MaxComputeUniformComponents = %d;", resources.maxComputeUniformComponents); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxComputeTextureImageUnits = %d;", resources.maxComputeTextureImageUnits); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxComputeImageUniforms = %d;", resources.maxComputeImageUniforms); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxComputeAtomicCounters = %d;", resources.maxComputeAtomicCounters); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxComputeAtomicCounterBuffers = %d;", resources.maxComputeAtomicCounterBuffers); + s.append(builtInConstant); + + s.append("\n"); + } + + // GL_ARB_cull_distance + if (profile != EEsProfile && version >= 450) { + snprintf(builtInConstant, maxSize, "const int gl_MaxCullDistances = %d;", resources.maxCullDistances); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedClipAndCullDistances = %d;", resources.maxCombinedClipAndCullDistances); + s.append(builtInConstant); + } + + // GL_ARB_ES3_1_compatibility + if ((profile != EEsProfile && version >= 450) || + (profile == EEsProfile && version >= 310)) { + snprintf(builtInConstant, maxSize, "const int gl_MaxSamples = %d;", resources.maxSamples); + s.append(builtInConstant); + } + +#ifdef AMD_EXTENSIONS + // GL_AMD_gcn_shader + if (profile != EEsProfile && version >= 450) { + snprintf(builtInConstant, maxSize, "const int gl_SIMDGroupSizeAMD = 64;"); + s.append(builtInConstant); + } +#endif + + s.append("\n"); +} + +// +// To support special built-ins that have a special qualifier that cannot be declared textually +// in a shader, like gl_Position. +// +// This lets the type of the built-in be declared textually, and then have just its qualifier be +// updated afterward. +// +// Safe to call even if name is not present. +// +// Only use this for built-in variables that have a special qualifier in TStorageQualifier. +// New built-in variables should use a generic (textually declarable) qualifier in +// TStoraregQualifier and only call BuiltInVariable(). +// +static void SpecialQualifier(const char* name, TStorageQualifier qualifier, TBuiltInVariable builtIn, TSymbolTable& symbolTable) +{ + TSymbol* symbol = symbolTable.find(name); + if (symbol) { + TQualifier& symQualifier = symbol->getWritableType().getQualifier(); + symQualifier.storage = qualifier; + symQualifier.builtIn = builtIn; + } +} + +// +// To tag built-in variables with their TBuiltInVariable enum. Use this when the +// normal declaration text already gets the qualifier right, and all that's needed +// is setting the builtIn field. This should be the normal way for all new +// built-in variables. +// +// If SpecialQualifier() was called, this does not need to be called. +// +// Safe to call even if name is not present. +// +static void BuiltInVariable(const char* name, TBuiltInVariable builtIn, TSymbolTable& symbolTable) +{ + TSymbol* symbol = symbolTable.find(name); + if (! symbol) + return; + + TQualifier& symQualifier = symbol->getWritableType().getQualifier(); + symQualifier.builtIn = builtIn; +} + +// +// For built-in variables inside a named block. +// SpecialQualifier() won't ever go inside a block; their member's qualifier come +// from the qualification of the block. +// +// See comments above for other detail. +// +static void BuiltInVariable(const char* blockName, const char* name, TBuiltInVariable builtIn, TSymbolTable& symbolTable) +{ + TSymbol* symbol = symbolTable.find(blockName); + if (! symbol) + return; + + TTypeList& structure = *symbol->getWritableType().getWritableStruct(); + for (int i = 0; i < (int)structure.size(); ++i) { + if (structure[i].type->getFieldName().compare(name) == 0) { + structure[i].type->getQualifier().builtIn = builtIn; + return; + } + } +} + +// +// Finish adding/processing context-independent built-in symbols. +// 1) Programmatically add symbols that could not be added by simple text strings above. +// 2) Map built-in functions to operators, for those that will turn into an operation node +// instead of remaining a function call. +// 3) Tag extension-related symbols added to their base version with their extensions, so +// that if an early version has the extension turned off, there is an error reported on use. +// +void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable) +{ + // + // Tag built-in variables and functions with additional qualifier and extension information + // that cannot be declared with the text strings. + // + + // N.B.: a symbol should only be tagged once, and this function is called multiple times, once + // per stage that's used for this profile. So + // - generally, stick common ones in the fragment stage to ensure they are tagged exactly once + // - for ES, which has different precisions for different stages, the coarsest-grained tagging + // for a built-in used in many stages needs to be once for the fragment stage and once for + // the vertex stage + + switch(language) { + case EShLangVertex: + if (profile != EEsProfile) { + if (version >= 440) { + symbolTable.setVariableExtensions("gl_BaseVertexARB", 1, &E_GL_ARB_shader_draw_parameters); + symbolTable.setVariableExtensions("gl_BaseInstanceARB", 1, &E_GL_ARB_shader_draw_parameters); + symbolTable.setVariableExtensions("gl_DrawIDARB", 1, &E_GL_ARB_shader_draw_parameters); + BuiltInVariable("gl_BaseVertexARB", EbvBaseVertex, symbolTable); + BuiltInVariable("gl_BaseInstanceARB", EbvBaseInstance, symbolTable); + BuiltInVariable("gl_DrawIDARB", EbvDrawId, symbolTable); + } + if (version >= 460) { + BuiltInVariable("gl_BaseVertex", EbvBaseVertex, symbolTable); + BuiltInVariable("gl_BaseInstance", EbvBaseInstance, symbolTable); + BuiltInVariable("gl_DrawID", EbvDrawId, symbolTable); + } + symbolTable.setVariableExtensions("gl_SubGroupSizeARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupInvocationARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupEqMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupGeMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupGtMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupLeMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupLtMaskARB", 1, &E_GL_ARB_shader_ballot); + + symbolTable.setFunctionExtensions("ballotARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setFunctionExtensions("readInvocationARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setFunctionExtensions("readFirstInvocationARB", 1, &E_GL_ARB_shader_ballot); + + BuiltInVariable("gl_SubGroupInvocationARB", EbvSubGroupInvocation, symbolTable); + BuiltInVariable("gl_SubGroupEqMaskARB", EbvSubGroupEqMask, symbolTable); + BuiltInVariable("gl_SubGroupGeMaskARB", EbvSubGroupGeMask, symbolTable); + BuiltInVariable("gl_SubGroupGtMaskARB", EbvSubGroupGtMask, symbolTable); + BuiltInVariable("gl_SubGroupLeMaskARB", EbvSubGroupLeMask, symbolTable); + BuiltInVariable("gl_SubGroupLtMaskARB", EbvSubGroupLtMask, symbolTable); + + if (spvVersion.vulkan >= 100) + // Treat "gl_SubGroupSizeARB" as shader input instead of uniform for Vulkan + SpecialQualifier("gl_SubGroupSizeARB", EvqVaryingIn, EbvSubGroupSize, symbolTable); + + if (version >= 430) { + symbolTable.setFunctionExtensions("anyInvocationARB", 1, &E_GL_ARB_shader_group_vote); + symbolTable.setFunctionExtensions("allInvocationsARB", 1, &E_GL_ARB_shader_group_vote); + symbolTable.setFunctionExtensions("allInvocationsEqualARB", 1, &E_GL_ARB_shader_group_vote); + } + } + +#ifdef AMD_EXTENSIONS + if (profile != EEsProfile) { + symbolTable.setFunctionExtensions("minInvocationsAMD", 1, &E_GL_AMD_shader_ballot); + symbolTable.setFunctionExtensions("maxInvocationsAMD", 1, &E_GL_AMD_shader_ballot); + symbolTable.setFunctionExtensions("addInvocationsAMD", 1, &E_GL_AMD_shader_ballot); + symbolTable.setFunctionExtensions("minInvocationsNonUniformAMD", 1, &E_GL_AMD_shader_ballot); + symbolTable.setFunctionExtensions("maxInvocationsNonUniformAMD", 1, &E_GL_AMD_shader_ballot); + symbolTable.setFunctionExtensions("addInvocationsNonUniformAMD", 1, &E_GL_AMD_shader_ballot); + symbolTable.setFunctionExtensions("swizzleInvocationsAMD", 1, &E_GL_AMD_shader_ballot); + symbolTable.setFunctionExtensions("swizzleInvocationsWithPatternAMD", 1, &E_GL_AMD_shader_ballot); + symbolTable.setFunctionExtensions("writeInvocationAMD", 1, &E_GL_AMD_shader_ballot); + symbolTable.setFunctionExtensions("mbcntAMD", 1, &E_GL_AMD_shader_ballot); + + symbolTable.setFunctionExtensions("minInvocationsInclusiveScanAMD", 1, &E_GL_AMD_shader_ballot); + symbolTable.setFunctionExtensions("maxInvocationsInclusiveScanAMD", 1, &E_GL_AMD_shader_ballot); + symbolTable.setFunctionExtensions("addInvocationsInclusiveScanAMD", 1, &E_GL_AMD_shader_ballot); + symbolTable.setFunctionExtensions("minInvocationsInclusiveScanNonUniformAMD", 1, &E_GL_AMD_shader_ballot); + symbolTable.setFunctionExtensions("maxInvocationsInclusiveScanNonUniformAMD", 1, &E_GL_AMD_shader_ballot); + symbolTable.setFunctionExtensions("addInvocationsInclusiveScanNonUniformAMD", 1, &E_GL_AMD_shader_ballot); + symbolTable.setFunctionExtensions("minInvocationsExclusiveScanAMD", 1, &E_GL_AMD_shader_ballot); + symbolTable.setFunctionExtensions("maxInvocationsExclusiveScanAMD", 1, &E_GL_AMD_shader_ballot); + symbolTable.setFunctionExtensions("addInvocationsExclusiveScanAMD", 1, &E_GL_AMD_shader_ballot); + symbolTable.setFunctionExtensions("minInvocationsExclusiveScanNonUniformAMD", 1, &E_GL_AMD_shader_ballot); + symbolTable.setFunctionExtensions("maxInvocationsExclusiveScanNonUniformAMD", 1, &E_GL_AMD_shader_ballot); + symbolTable.setFunctionExtensions("addInvocationsExclusiveScanNonUniformAMD", 1, &E_GL_AMD_shader_ballot); + } + + if (profile != EEsProfile) { + symbolTable.setFunctionExtensions("min3", 1, &E_GL_AMD_shader_trinary_minmax); + symbolTable.setFunctionExtensions("max3", 1, &E_GL_AMD_shader_trinary_minmax); + symbolTable.setFunctionExtensions("mid3", 1, &E_GL_AMD_shader_trinary_minmax); + } + + if (profile != EEsProfile) { + symbolTable.setFunctionExtensions("cubeFaceIndexAMD", 1, &E_GL_AMD_gcn_shader); + symbolTable.setFunctionExtensions("cubeFaceCoordAMD", 1, &E_GL_AMD_gcn_shader); + symbolTable.setFunctionExtensions("timeAMD", 1, &E_GL_AMD_gcn_shader); + } + + if (profile != EEsProfile) { + symbolTable.setFunctionExtensions("fragmentMaskFetchAMD", 1, &E_GL_AMD_shader_fragment_mask); + symbolTable.setFunctionExtensions("fragmentFetchAMD", 1, &E_GL_AMD_shader_fragment_mask); + } +#endif + + // Compatibility variables, vertex only + if (spvVersion.spv == 0) { + BuiltInVariable("gl_Color", EbvColor, symbolTable); + BuiltInVariable("gl_SecondaryColor", EbvSecondaryColor, symbolTable); + BuiltInVariable("gl_Normal", EbvNormal, symbolTable); + BuiltInVariable("gl_Vertex", EbvVertex, symbolTable); + BuiltInVariable("gl_MultiTexCoord0", EbvMultiTexCoord0, symbolTable); + BuiltInVariable("gl_MultiTexCoord1", EbvMultiTexCoord1, symbolTable); + BuiltInVariable("gl_MultiTexCoord2", EbvMultiTexCoord2, symbolTable); + BuiltInVariable("gl_MultiTexCoord3", EbvMultiTexCoord3, symbolTable); + BuiltInVariable("gl_MultiTexCoord4", EbvMultiTexCoord4, symbolTable); + BuiltInVariable("gl_MultiTexCoord5", EbvMultiTexCoord5, symbolTable); + BuiltInVariable("gl_MultiTexCoord6", EbvMultiTexCoord6, symbolTable); + BuiltInVariable("gl_MultiTexCoord7", EbvMultiTexCoord7, symbolTable); + BuiltInVariable("gl_FogCoord", EbvFogFragCoord, symbolTable); + } + + if (profile == EEsProfile) { + if (spvVersion.spv == 0) { + symbolTable.setFunctionExtensions("texture2DGradEXT", 1, &E_GL_EXT_shader_texture_lod); + symbolTable.setFunctionExtensions("texture2DProjGradEXT", 1, &E_GL_EXT_shader_texture_lod); + symbolTable.setFunctionExtensions("textureCubeGradEXT", 1, &E_GL_EXT_shader_texture_lod); + if (version == 310) + symbolTable.setFunctionExtensions("textureGatherOffsets", Num_AEP_gpu_shader5, AEP_gpu_shader5); + } + if (version == 310) + symbolTable.setFunctionExtensions("fma", Num_AEP_gpu_shader5, AEP_gpu_shader5); + } + + if (profile == EEsProfile && version < 320) { + symbolTable.setFunctionExtensions("imageAtomicAdd", 1, &E_GL_OES_shader_image_atomic); + symbolTable.setFunctionExtensions("imageAtomicMin", 1, &E_GL_OES_shader_image_atomic); + symbolTable.setFunctionExtensions("imageAtomicMax", 1, &E_GL_OES_shader_image_atomic); + symbolTable.setFunctionExtensions("imageAtomicAnd", 1, &E_GL_OES_shader_image_atomic); + symbolTable.setFunctionExtensions("imageAtomicOr", 1, &E_GL_OES_shader_image_atomic); + symbolTable.setFunctionExtensions("imageAtomicXor", 1, &E_GL_OES_shader_image_atomic); + symbolTable.setFunctionExtensions("imageAtomicExchange", 1, &E_GL_OES_shader_image_atomic); + symbolTable.setFunctionExtensions("imageAtomicCompSwap", 1, &E_GL_OES_shader_image_atomic); + } + + if (spvVersion.vulkan == 0) { + SpecialQualifier("gl_VertexID", EvqVertexId, EbvVertexId, symbolTable); + SpecialQualifier("gl_InstanceID", EvqInstanceId, EbvInstanceId, symbolTable); + } + + if (spvVersion.vulkan >= 100) { + BuiltInVariable("gl_VertexIndex", EbvVertexIndex, symbolTable); + BuiltInVariable("gl_InstanceIndex", EbvInstanceIndex, symbolTable); + } + + if (version >= 300 /* both ES and non-ES */) { + symbolTable.setVariableExtensions("gl_ViewID_OVR", Num_OVR_multiview_EXTs, OVR_multiview_EXTs); + BuiltInVariable("gl_ViewID_OVR", EbvViewIndex, symbolTable); + } + + if (profile == EEsProfile) { + symbolTable.setFunctionExtensions("shadow2DEXT", 1, &E_GL_EXT_shadow_samplers); + symbolTable.setFunctionExtensions("shadow2DProjEXT", 1, &E_GL_EXT_shadow_samplers); + } + + // Fall through + + case EShLangTessControl: + if (profile == EEsProfile && version >= 310) { + BuiltInVariable("gl_BoundingBoxOES", EbvBoundingBox, symbolTable); + if (version < 320) + symbolTable.setVariableExtensions("gl_BoundingBoxOES", Num_AEP_primitive_bounding_box, + AEP_primitive_bounding_box); + } + + // Fall through + + case EShLangTessEvaluation: + case EShLangGeometry: + SpecialQualifier("gl_Position", EvqPosition, EbvPosition, symbolTable); + SpecialQualifier("gl_PointSize", EvqPointSize, EbvPointSize, symbolTable); + SpecialQualifier("gl_ClipVertex", EvqClipVertex, EbvClipVertex, symbolTable); + + BuiltInVariable("gl_in", "gl_Position", EbvPosition, symbolTable); + BuiltInVariable("gl_in", "gl_PointSize", EbvPointSize, symbolTable); + BuiltInVariable("gl_in", "gl_ClipDistance", EbvClipDistance, symbolTable); + BuiltInVariable("gl_in", "gl_CullDistance", EbvCullDistance, symbolTable); + + BuiltInVariable("gl_out", "gl_Position", EbvPosition, symbolTable); + BuiltInVariable("gl_out", "gl_PointSize", EbvPointSize, symbolTable); + BuiltInVariable("gl_out", "gl_ClipDistance", EbvClipDistance, symbolTable); + BuiltInVariable("gl_out", "gl_CullDistance", EbvCullDistance, symbolTable); + + BuiltInVariable("gl_ClipDistance", EbvClipDistance, symbolTable); + BuiltInVariable("gl_CullDistance", EbvCullDistance, symbolTable); + BuiltInVariable("gl_PrimitiveIDIn", EbvPrimitiveId, symbolTable); + BuiltInVariable("gl_PrimitiveID", EbvPrimitiveId, symbolTable); + BuiltInVariable("gl_InvocationID", EbvInvocationId, symbolTable); + BuiltInVariable("gl_Layer", EbvLayer, symbolTable); + BuiltInVariable("gl_ViewportIndex", EbvViewportIndex, symbolTable); + +#ifdef NV_EXTENSIONS + if (language != EShLangGeometry) { + symbolTable.setVariableExtensions("gl_Layer", Num_viewportEXTs, viewportEXTs); + symbolTable.setVariableExtensions("gl_ViewportIndex", Num_viewportEXTs, viewportEXTs); + } +#else + if (language != EShLangGeometry && version >= 410) { + symbolTable.setVariableExtensions("gl_Layer", 1, &E_GL_ARB_shader_viewport_layer_array); + symbolTable.setVariableExtensions("gl_ViewportIndex", 1, &E_GL_ARB_shader_viewport_layer_array); + } +#endif + +#ifdef NV_EXTENSIONS + symbolTable.setVariableExtensions("gl_ViewportMask", 1, &E_GL_NV_viewport_array2); + symbolTable.setVariableExtensions("gl_SecondaryPositionNV", 1, &E_GL_NV_stereo_view_rendering); + symbolTable.setVariableExtensions("gl_SecondaryViewportMaskNV", 1, &E_GL_NV_stereo_view_rendering); + symbolTable.setVariableExtensions("gl_PositionPerViewNV", 1, &E_GL_NVX_multiview_per_view_attributes); + symbolTable.setVariableExtensions("gl_ViewportMaskPerViewNV", 1, &E_GL_NVX_multiview_per_view_attributes); + + BuiltInVariable("gl_ViewportMask", EbvViewportMaskNV, symbolTable); + BuiltInVariable("gl_SecondaryPositionNV", EbvSecondaryPositionNV, symbolTable); + BuiltInVariable("gl_SecondaryViewportMaskNV", EbvSecondaryViewportMaskNV, symbolTable); + BuiltInVariable("gl_PositionPerViewNV", EbvPositionPerViewNV, symbolTable); + BuiltInVariable("gl_ViewportMaskPerViewNV", EbvViewportMaskPerViewNV, symbolTable); + + if (language != EShLangVertex) { + BuiltInVariable("gl_in", "gl_SecondaryPositionNV", EbvSecondaryPositionNV, symbolTable); + BuiltInVariable("gl_in", "gl_PositionPerViewNV", EbvPositionPerViewNV, symbolTable); + } + BuiltInVariable("gl_out", "gl_ViewportMask", EbvViewportMaskNV, symbolTable); + BuiltInVariable("gl_out", "gl_SecondaryPositionNV", EbvSecondaryPositionNV, symbolTable); + BuiltInVariable("gl_out", "gl_SecondaryViewportMaskNV", EbvSecondaryViewportMaskNV, symbolTable); + BuiltInVariable("gl_out", "gl_PositionPerViewNV", EbvPositionPerViewNV, symbolTable); + BuiltInVariable("gl_out", "gl_ViewportMaskPerViewNV", EbvViewportMaskPerViewNV, symbolTable); +#endif + + BuiltInVariable("gl_PatchVerticesIn", EbvPatchVertices, symbolTable); + BuiltInVariable("gl_TessLevelOuter", EbvTessLevelOuter, symbolTable); + BuiltInVariable("gl_TessLevelInner", EbvTessLevelInner, symbolTable); + BuiltInVariable("gl_TessCoord", EbvTessCoord, symbolTable); + + if (version < 410) + symbolTable.setVariableExtensions("gl_ViewportIndex", 1, &E_GL_ARB_viewport_array); + + // Compatibility variables + + BuiltInVariable("gl_in", "gl_ClipVertex", EbvClipVertex, symbolTable); + BuiltInVariable("gl_in", "gl_FrontColor", EbvFrontColor, symbolTable); + BuiltInVariable("gl_in", "gl_BackColor", EbvBackColor, symbolTable); + BuiltInVariable("gl_in", "gl_FrontSecondaryColor", EbvFrontSecondaryColor, symbolTable); + BuiltInVariable("gl_in", "gl_BackSecondaryColor", EbvBackSecondaryColor, symbolTable); + BuiltInVariable("gl_in", "gl_TexCoord", EbvTexCoord, symbolTable); + BuiltInVariable("gl_in", "gl_FogFragCoord", EbvFogFragCoord, symbolTable); + + BuiltInVariable("gl_out", "gl_ClipVertex", EbvClipVertex, symbolTable); + BuiltInVariable("gl_out", "gl_FrontColor", EbvFrontColor, symbolTable); + BuiltInVariable("gl_out", "gl_BackColor", EbvBackColor, symbolTable); + BuiltInVariable("gl_out", "gl_FrontSecondaryColor", EbvFrontSecondaryColor, symbolTable); + BuiltInVariable("gl_out", "gl_BackSecondaryColor", EbvBackSecondaryColor, symbolTable); + BuiltInVariable("gl_out", "gl_TexCoord", EbvTexCoord, symbolTable); + BuiltInVariable("gl_out", "gl_FogFragCoord", EbvFogFragCoord, symbolTable); + + BuiltInVariable("gl_ClipVertex", EbvClipVertex, symbolTable); + BuiltInVariable("gl_FrontColor", EbvFrontColor, symbolTable); + BuiltInVariable("gl_BackColor", EbvBackColor, symbolTable); + BuiltInVariable("gl_FrontSecondaryColor", EbvFrontSecondaryColor, symbolTable); + BuiltInVariable("gl_BackSecondaryColor", EbvBackSecondaryColor, symbolTable); + BuiltInVariable("gl_TexCoord", EbvTexCoord, symbolTable); + BuiltInVariable("gl_FogFragCoord", EbvFogFragCoord, symbolTable); + + // gl_PointSize, when it needs to be tied to an extension, is always a member of a block. + // (Sometimes with an instance name, sometimes anonymous). + // However, the current automatic extension scheme does not work per block member, + // so for now check when parsing. + // + // if (profile == EEsProfile) { + // if (language == EShLangGeometry) + // symbolTable.setVariableExtensions("gl_PointSize", Num_AEP_geometry_point_size, AEP_geometry_point_size); + // else if (language == EShLangTessEvaluation || language == EShLangTessControl) + // symbolTable.setVariableExtensions("gl_PointSize", Num_AEP_tessellation_point_size, AEP_tessellation_point_size); + //} + + if ((profile != EEsProfile && version >= 140) || + (profile == EEsProfile && version >= 310)) { + symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group); + BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable); + symbolTable.setVariableExtensions("gl_ViewIndex", 1, &E_GL_EXT_multiview); + BuiltInVariable("gl_ViewIndex", EbvViewIndex, symbolTable); + } + + break; + + case EShLangFragment: + SpecialQualifier("gl_FrontFacing", EvqFace, EbvFace, symbolTable); + SpecialQualifier("gl_FragCoord", EvqFragCoord, EbvFragCoord, symbolTable); + SpecialQualifier("gl_PointCoord", EvqPointCoord, EbvPointCoord, symbolTable); + if (spvVersion.spv == 0) + SpecialQualifier("gl_FragColor", EvqFragColor, EbvFragColor, symbolTable); + else { + TSymbol* symbol = symbolTable.find("gl_FragColor"); + if (symbol) { + symbol->getWritableType().getQualifier().storage = EvqVaryingOut; + symbol->getWritableType().getQualifier().layoutLocation = 0; + } + } + SpecialQualifier("gl_FragDepth", EvqFragDepth, EbvFragDepth, symbolTable); + SpecialQualifier("gl_FragDepthEXT", EvqFragDepth, EbvFragDepth, symbolTable); + SpecialQualifier("gl_HelperInvocation", EvqVaryingIn, EbvHelperInvocation, symbolTable); + + BuiltInVariable("gl_ClipDistance", EbvClipDistance, symbolTable); + BuiltInVariable("gl_CullDistance", EbvCullDistance, symbolTable); + BuiltInVariable("gl_PrimitiveID", EbvPrimitiveId, symbolTable); + + if (profile != EEsProfile && version >= 140) { + symbolTable.setVariableExtensions("gl_FragStencilRefARB", 1, &E_GL_ARB_shader_stencil_export); + BuiltInVariable("gl_FragStencilRefARB", EbvFragStencilRef, symbolTable); + } + + if ((profile != EEsProfile && version >= 400) || + (profile == EEsProfile && version >= 310)) { + BuiltInVariable("gl_SampleID", EbvSampleId, symbolTable); + BuiltInVariable("gl_SamplePosition", EbvSamplePosition, symbolTable); + BuiltInVariable("gl_SampleMaskIn", EbvSampleMask, symbolTable); + BuiltInVariable("gl_SampleMask", EbvSampleMask, symbolTable); + if (profile == EEsProfile && version < 320) { + symbolTable.setVariableExtensions("gl_SampleID", 1, &E_GL_OES_sample_variables); + symbolTable.setVariableExtensions("gl_SamplePosition", 1, &E_GL_OES_sample_variables); + symbolTable.setVariableExtensions("gl_SampleMaskIn", 1, &E_GL_OES_sample_variables); + symbolTable.setVariableExtensions("gl_SampleMask", 1, &E_GL_OES_sample_variables); + symbolTable.setVariableExtensions("gl_NumSamples", 1, &E_GL_OES_sample_variables); + } + } + + BuiltInVariable("gl_Layer", EbvLayer, symbolTable); + BuiltInVariable("gl_ViewportIndex", EbvViewportIndex, symbolTable); + + // Compatibility variables + + BuiltInVariable("gl_in", "gl_FogFragCoord", EbvFogFragCoord, symbolTable); + BuiltInVariable("gl_in", "gl_TexCoord", EbvTexCoord, symbolTable); + BuiltInVariable("gl_in", "gl_Color", EbvColor, symbolTable); + BuiltInVariable("gl_in", "gl_SecondaryColor", EbvSecondaryColor, symbolTable); + + BuiltInVariable("gl_FogFragCoord", EbvFogFragCoord, symbolTable); + BuiltInVariable("gl_TexCoord", EbvTexCoord, symbolTable); + BuiltInVariable("gl_Color", EbvColor, symbolTable); + BuiltInVariable("gl_SecondaryColor", EbvSecondaryColor, symbolTable); + + // built-in functions + + if (profile == EEsProfile) { + if (spvVersion.spv == 0) { + symbolTable.setFunctionExtensions("texture2DLodEXT", 1, &E_GL_EXT_shader_texture_lod); + symbolTable.setFunctionExtensions("texture2DProjLodEXT", 1, &E_GL_EXT_shader_texture_lod); + symbolTable.setFunctionExtensions("textureCubeLodEXT", 1, &E_GL_EXT_shader_texture_lod); + symbolTable.setFunctionExtensions("texture2DGradEXT", 1, &E_GL_EXT_shader_texture_lod); + symbolTable.setFunctionExtensions("texture2DProjGradEXT", 1, &E_GL_EXT_shader_texture_lod); + symbolTable.setFunctionExtensions("textureCubeGradEXT", 1, &E_GL_EXT_shader_texture_lod); + if (version < 320) + symbolTable.setFunctionExtensions("textureGatherOffsets", Num_AEP_gpu_shader5, AEP_gpu_shader5); + } + if (version == 100) { + symbolTable.setFunctionExtensions("dFdx", 1, &E_GL_OES_standard_derivatives); + symbolTable.setFunctionExtensions("dFdy", 1, &E_GL_OES_standard_derivatives); + symbolTable.setFunctionExtensions("fwidth", 1, &E_GL_OES_standard_derivatives); + } + if (version == 310) { + symbolTable.setFunctionExtensions("fma", Num_AEP_gpu_shader5, AEP_gpu_shader5); + symbolTable.setFunctionExtensions("interpolateAtCentroid", 1, &E_GL_OES_shader_multisample_interpolation); + symbolTable.setFunctionExtensions("interpolateAtSample", 1, &E_GL_OES_shader_multisample_interpolation); + symbolTable.setFunctionExtensions("interpolateAtOffset", 1, &E_GL_OES_shader_multisample_interpolation); + } + } else if (version < 130) { + if (spvVersion.spv == 0) { + symbolTable.setFunctionExtensions("texture1DLod", 1, &E_GL_ARB_shader_texture_lod); + symbolTable.setFunctionExtensions("texture2DLod", 1, &E_GL_ARB_shader_texture_lod); + symbolTable.setFunctionExtensions("texture3DLod", 1, &E_GL_ARB_shader_texture_lod); + symbolTable.setFunctionExtensions("textureCubeLod", 1, &E_GL_ARB_shader_texture_lod); + symbolTable.setFunctionExtensions("texture1DProjLod", 1, &E_GL_ARB_shader_texture_lod); + symbolTable.setFunctionExtensions("texture2DProjLod", 1, &E_GL_ARB_shader_texture_lod); + symbolTable.setFunctionExtensions("texture3DProjLod", 1, &E_GL_ARB_shader_texture_lod); + symbolTable.setFunctionExtensions("shadow1DLod", 1, &E_GL_ARB_shader_texture_lod); + symbolTable.setFunctionExtensions("shadow2DLod", 1, &E_GL_ARB_shader_texture_lod); + symbolTable.setFunctionExtensions("shadow1DProjLod", 1, &E_GL_ARB_shader_texture_lod); + symbolTable.setFunctionExtensions("shadow2DProjLod", 1, &E_GL_ARB_shader_texture_lod); + } + } + + // E_GL_ARB_shader_texture_lod functions usable only with the extension enabled + if (profile != EEsProfile && spvVersion.spv == 0) { + symbolTable.setFunctionExtensions("texture1DGradARB", 1, &E_GL_ARB_shader_texture_lod); + symbolTable.setFunctionExtensions("texture1DProjGradARB", 1, &E_GL_ARB_shader_texture_lod); + symbolTable.setFunctionExtensions("texture2DGradARB", 1, &E_GL_ARB_shader_texture_lod); + symbolTable.setFunctionExtensions("texture2DProjGradARB", 1, &E_GL_ARB_shader_texture_lod); + symbolTable.setFunctionExtensions("texture3DGradARB", 1, &E_GL_ARB_shader_texture_lod); + symbolTable.setFunctionExtensions("texture3DProjGradARB", 1, &E_GL_ARB_shader_texture_lod); + symbolTable.setFunctionExtensions("textureCubeGradARB", 1, &E_GL_ARB_shader_texture_lod); + symbolTable.setFunctionExtensions("shadow1DGradARB", 1, &E_GL_ARB_shader_texture_lod); + symbolTable.setFunctionExtensions("shadow1DProjGradARB", 1, &E_GL_ARB_shader_texture_lod); + symbolTable.setFunctionExtensions("shadow2DGradARB", 1, &E_GL_ARB_shader_texture_lod); + symbolTable.setFunctionExtensions("shadow2DProjGradARB", 1, &E_GL_ARB_shader_texture_lod); + symbolTable.setFunctionExtensions("texture2DRectGradARB", 1, &E_GL_ARB_shader_texture_lod); + symbolTable.setFunctionExtensions("texture2DRectProjGradARB", 1, &E_GL_ARB_shader_texture_lod); + symbolTable.setFunctionExtensions("shadow2DRectGradARB", 1, &E_GL_ARB_shader_texture_lod); + symbolTable.setFunctionExtensions("shadow2DRectProjGradARB", 1, &E_GL_ARB_shader_texture_lod); + } + + // E_GL_EXT_texture_array + if (spvVersion.spv == 0) { + symbolTable.setFunctionExtensions("texture2DArray", 1, &E_GL_EXT_texture_array); + } + if (profile != EEsProfile && spvVersion.spv == 0) { + int nLodExtensions = 2; + const char *lodExtensions[] = {E_GL_EXT_texture_array, E_GL_ARB_shader_texture_lod}; + + if (version >= 130) + nLodExtensions = 1; + + symbolTable.setFunctionExtensions("texture1DArray", 1, &E_GL_EXT_texture_array); + symbolTable.setFunctionExtensions("shadow1DArray", 1, &E_GL_EXT_texture_array); + symbolTable.setFunctionExtensions("shadow2DArray", 1, &E_GL_EXT_texture_array); + + symbolTable.setFunctionExtensions("texture1DArrayLod", nLodExtensions, lodExtensions); + symbolTable.setFunctionExtensions("texture2DArrayLod", nLodExtensions, lodExtensions); + symbolTable.setFunctionExtensions("shadow1DArrayLod", nLodExtensions, lodExtensions); + symbolTable.setFunctionExtensions("shadow2DArrayLod", nLodExtensions, lodExtensions); + } + + // E_GL_ARB_shader_image_load_store + if (profile != EEsProfile && version < 420) + symbolTable.setFunctionExtensions("memoryBarrier", 1, &E_GL_ARB_shader_image_load_store); + // All the image access functions are protected by checks on the type of the first argument. + + // E_GL_ARB_shader_atomic_counters + if (profile != EEsProfile && version < 420) { + symbolTable.setFunctionExtensions("atomicCounterIncrement", 1, &E_GL_ARB_shader_atomic_counters); + symbolTable.setFunctionExtensions("atomicCounterDecrement", 1, &E_GL_ARB_shader_atomic_counters); + symbolTable.setFunctionExtensions("atomicCounter" , 1, &E_GL_ARB_shader_atomic_counters); + } + + // E_GL_ARB_derivative_control + if (profile != EEsProfile && version < 450) { + symbolTable.setFunctionExtensions("dFdxFine", 1, &E_GL_ARB_derivative_control); + symbolTable.setFunctionExtensions("dFdyFine", 1, &E_GL_ARB_derivative_control); + symbolTable.setFunctionExtensions("fwidthFine", 1, &E_GL_ARB_derivative_control); + symbolTable.setFunctionExtensions("dFdxCoarse", 1, &E_GL_ARB_derivative_control); + symbolTable.setFunctionExtensions("dFdyCoarse", 1, &E_GL_ARB_derivative_control); + symbolTable.setFunctionExtensions("fwidthCoarse", 1, &E_GL_ARB_derivative_control); + } + + // E_GL_ARB_sparse_texture2 + if (profile != EEsProfile) + { + symbolTable.setFunctionExtensions("sparseTextureARB", 1, &E_GL_ARB_sparse_texture2); + symbolTable.setFunctionExtensions("sparseTextureLodARB", 1, &E_GL_ARB_sparse_texture2); + symbolTable.setFunctionExtensions("sparseTextureOffsetARB", 1, &E_GL_ARB_sparse_texture2); + symbolTable.setFunctionExtensions("sparseTexelFetchARB", 1, &E_GL_ARB_sparse_texture2); + symbolTable.setFunctionExtensions("sparseTexelFetchOffsetARB", 1, &E_GL_ARB_sparse_texture2); + symbolTable.setFunctionExtensions("sparseTextureLodOffsetARB", 1, &E_GL_ARB_sparse_texture2); + symbolTable.setFunctionExtensions("sparseTextureGradARB", 1, &E_GL_ARB_sparse_texture2); + symbolTable.setFunctionExtensions("sparseTextureGradOffsetARB", 1, &E_GL_ARB_sparse_texture2); + symbolTable.setFunctionExtensions("sparseTextureGatherARB", 1, &E_GL_ARB_sparse_texture2); + symbolTable.setFunctionExtensions("sparseTextureGatherOffsetARB", 1, &E_GL_ARB_sparse_texture2); + symbolTable.setFunctionExtensions("sparseTextureGatherOffsetsARB", 1, &E_GL_ARB_sparse_texture2); + symbolTable.setFunctionExtensions("sparseImageLoadARB", 1, &E_GL_ARB_sparse_texture2); + symbolTable.setFunctionExtensions("sparseTexelsResident", 1, &E_GL_ARB_sparse_texture2); + } + + // E_GL_ARB_sparse_texture_clamp + if (profile != EEsProfile) + { + symbolTable.setFunctionExtensions("sparseTextureClampARB", 1, &E_GL_ARB_sparse_texture_clamp); + symbolTable.setFunctionExtensions("sparseTextureOffsetClampARB", 1, &E_GL_ARB_sparse_texture_clamp); + symbolTable.setFunctionExtensions("sparseTextureGradClampARB", 1, &E_GL_ARB_sparse_texture_clamp); + symbolTable.setFunctionExtensions("sparseTextureGradOffsetClampARB", 1, &E_GL_ARB_sparse_texture_clamp); + symbolTable.setFunctionExtensions("textureClampARB", 1, &E_GL_ARB_sparse_texture_clamp); + symbolTable.setFunctionExtensions("textureOffsetClampARB", 1, &E_GL_ARB_sparse_texture_clamp); + symbolTable.setFunctionExtensions("textureGradClampARB", 1, &E_GL_ARB_sparse_texture_clamp); + symbolTable.setFunctionExtensions("textureGradOffsetClampARB", 1, &E_GL_ARB_sparse_texture_clamp); + } + +#ifdef AMD_EXTENSIONS + // E_GL_AMD_shader_explicit_vertex_parameter + if (profile != EEsProfile) { + symbolTable.setVariableExtensions("gl_BaryCoordNoPerspAMD", 1, &E_GL_AMD_shader_explicit_vertex_parameter); + symbolTable.setVariableExtensions("gl_BaryCoordNoPerspCentroidAMD", 1, &E_GL_AMD_shader_explicit_vertex_parameter); + symbolTable.setVariableExtensions("gl_BaryCoordNoPerspSampleAMD", 1, &E_GL_AMD_shader_explicit_vertex_parameter); + symbolTable.setVariableExtensions("gl_BaryCoordSmoothAMD", 1, &E_GL_AMD_shader_explicit_vertex_parameter); + symbolTable.setVariableExtensions("gl_BaryCoordSmoothCentroidAMD", 1, &E_GL_AMD_shader_explicit_vertex_parameter); + symbolTable.setVariableExtensions("gl_BaryCoordSmoothSampleAMD", 1, &E_GL_AMD_shader_explicit_vertex_parameter); + symbolTable.setVariableExtensions("gl_BaryCoordPullModelAMD", 1, &E_GL_AMD_shader_explicit_vertex_parameter); + + symbolTable.setFunctionExtensions("interpolateAtVertexAMD", 1, &E_GL_AMD_shader_explicit_vertex_parameter); + + BuiltInVariable("gl_BaryCoordNoPerspAMD", EbvBaryCoordNoPersp, symbolTable); + BuiltInVariable("gl_BaryCoordNoPerspCentroidAMD", EbvBaryCoordNoPerspCentroid, symbolTable); + BuiltInVariable("gl_BaryCoordNoPerspSampleAMD", EbvBaryCoordNoPerspSample, symbolTable); + BuiltInVariable("gl_BaryCoordSmoothAMD", EbvBaryCoordSmooth, symbolTable); + BuiltInVariable("gl_BaryCoordSmoothCentroidAMD", EbvBaryCoordSmoothCentroid, symbolTable); + BuiltInVariable("gl_BaryCoordSmoothSampleAMD", EbvBaryCoordSmoothSample, symbolTable); + BuiltInVariable("gl_BaryCoordPullModelAMD", EbvBaryCoordPullModel, symbolTable); + } + + // E_GL_AMD_texture_gather_bias_lod + if (profile != EEsProfile) { + symbolTable.setFunctionExtensions("textureGatherLodAMD", 1, &E_GL_AMD_texture_gather_bias_lod); + symbolTable.setFunctionExtensions("textureGatherLodOffsetAMD", 1, &E_GL_AMD_texture_gather_bias_lod); + symbolTable.setFunctionExtensions("textureGatherLodOffsetsAMD", 1, &E_GL_AMD_texture_gather_bias_lod); + symbolTable.setFunctionExtensions("sparseTextureGatherLodAMD", 1, &E_GL_AMD_texture_gather_bias_lod); + symbolTable.setFunctionExtensions("sparseTextureGatherLodOffsetAMD", 1, &E_GL_AMD_texture_gather_bias_lod); + symbolTable.setFunctionExtensions("sparseTextureGatherLodOffsetsAMD", 1, &E_GL_AMD_texture_gather_bias_lod); + } + + // E_GL_AMD_shader_image_load_store_lod + if (profile != EEsProfile) { + symbolTable.setFunctionExtensions("imageLoadLodAMD", 1, &E_GL_AMD_shader_image_load_store_lod); + symbolTable.setFunctionExtensions("imageStoreLodAMD", 1, &E_GL_AMD_shader_image_load_store_lod); + symbolTable.setFunctionExtensions("sparseImageLoadLodAMD", 1, &E_GL_AMD_shader_image_load_store_lod); + } +#endif + +#ifdef NV_EXTENSIONS + if (profile != EEsProfile && version >= 430) { + symbolTable.setVariableExtensions("gl_FragFullyCoveredNV", 1, &E_GL_NV_conservative_raster_underestimation); + BuiltInVariable("gl_FragFullyCoveredNV", EbvFragFullyCoveredNV, symbolTable); + } +#endif + + symbolTable.setVariableExtensions("gl_FragDepthEXT", 1, &E_GL_EXT_frag_depth); + + if (profile == EEsProfile && version < 320) { + symbolTable.setVariableExtensions("gl_PrimitiveID", Num_AEP_geometry_shader, AEP_geometry_shader); + symbolTable.setVariableExtensions("gl_Layer", Num_AEP_geometry_shader, AEP_geometry_shader); + } + + if (profile == EEsProfile && version < 320) { + symbolTable.setFunctionExtensions("imageAtomicAdd", 1, &E_GL_OES_shader_image_atomic); + symbolTable.setFunctionExtensions("imageAtomicMin", 1, &E_GL_OES_shader_image_atomic); + symbolTable.setFunctionExtensions("imageAtomicMax", 1, &E_GL_OES_shader_image_atomic); + symbolTable.setFunctionExtensions("imageAtomicAnd", 1, &E_GL_OES_shader_image_atomic); + symbolTable.setFunctionExtensions("imageAtomicOr", 1, &E_GL_OES_shader_image_atomic); + symbolTable.setFunctionExtensions("imageAtomicXor", 1, &E_GL_OES_shader_image_atomic); + symbolTable.setFunctionExtensions("imageAtomicExchange", 1, &E_GL_OES_shader_image_atomic); + symbolTable.setFunctionExtensions("imageAtomicCompSwap", 1, &E_GL_OES_shader_image_atomic); + } + + symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group); + BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable); + symbolTable.setVariableExtensions("gl_ViewIndex", 1, &E_GL_EXT_multiview); + BuiltInVariable("gl_ViewIndex", EbvViewIndex, symbolTable); + if (version >= 300 /* both ES and non-ES */) { + symbolTable.setVariableExtensions("gl_ViewID_OVR", Num_OVR_multiview_EXTs, OVR_multiview_EXTs); + BuiltInVariable("gl_ViewID_OVR", EbvViewIndex, symbolTable); + } + + if (profile == EEsProfile) { + symbolTable.setFunctionExtensions("shadow2DEXT", 1, &E_GL_EXT_shadow_samplers); + symbolTable.setFunctionExtensions("shadow2DProjEXT", 1, &E_GL_EXT_shadow_samplers); + } + break; + + case EShLangCompute: + BuiltInVariable("gl_NumWorkGroups", EbvNumWorkGroups, symbolTable); + BuiltInVariable("gl_WorkGroupSize", EbvWorkGroupSize, symbolTable); + BuiltInVariable("gl_WorkGroupID", EbvWorkGroupId, symbolTable); + BuiltInVariable("gl_LocalInvocationID", EbvLocalInvocationId, symbolTable); + BuiltInVariable("gl_GlobalInvocationID", EbvGlobalInvocationId, symbolTable); + BuiltInVariable("gl_LocalInvocationIndex", EbvLocalInvocationIndex, symbolTable); + + if (profile != EEsProfile && version < 430) { + symbolTable.setVariableExtensions("gl_NumWorkGroups", 1, &E_GL_ARB_compute_shader); + symbolTable.setVariableExtensions("gl_WorkGroupSize", 1, &E_GL_ARB_compute_shader); + symbolTable.setVariableExtensions("gl_WorkGroupID", 1, &E_GL_ARB_compute_shader); + symbolTable.setVariableExtensions("gl_LocalInvocationID", 1, &E_GL_ARB_compute_shader); + symbolTable.setVariableExtensions("gl_GlobalInvocationID", 1, &E_GL_ARB_compute_shader); + symbolTable.setVariableExtensions("gl_LocalInvocationIndex", 1, &E_GL_ARB_compute_shader); + + symbolTable.setVariableExtensions("gl_MaxComputeWorkGroupCount", 1, &E_GL_ARB_compute_shader); + symbolTable.setVariableExtensions("gl_MaxComputeWorkGroupSize", 1, &E_GL_ARB_compute_shader); + symbolTable.setVariableExtensions("gl_MaxComputeUniformComponents", 1, &E_GL_ARB_compute_shader); + symbolTable.setVariableExtensions("gl_MaxComputeTextureImageUnits", 1, &E_GL_ARB_compute_shader); + symbolTable.setVariableExtensions("gl_MaxComputeImageUniforms", 1, &E_GL_ARB_compute_shader); + symbolTable.setVariableExtensions("gl_MaxComputeAtomicCounters", 1, &E_GL_ARB_compute_shader); + symbolTable.setVariableExtensions("gl_MaxComputeAtomicCounterBuffers", 1, &E_GL_ARB_compute_shader); + + symbolTable.setFunctionExtensions("barrier", 1, &E_GL_ARB_compute_shader); + symbolTable.setFunctionExtensions("memoryBarrierAtomicCounter", 1, &E_GL_ARB_compute_shader); + symbolTable.setFunctionExtensions("memoryBarrierBuffer", 1, &E_GL_ARB_compute_shader); + symbolTable.setFunctionExtensions("memoryBarrierImage", 1, &E_GL_ARB_compute_shader); + symbolTable.setFunctionExtensions("memoryBarrierShared", 1, &E_GL_ARB_compute_shader); + symbolTable.setFunctionExtensions("groupMemoryBarrier", 1, &E_GL_ARB_compute_shader); + } + + if ((profile != EEsProfile && version >= 140) || + (profile == EEsProfile && version >= 310)) { + symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group); + BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable); + symbolTable.setVariableExtensions("gl_ViewIndex", 1, &E_GL_EXT_multiview); + BuiltInVariable("gl_ViewIndex", EbvViewIndex, symbolTable); + } + + break; + + default: + assert(false && "Language not supported"); + break; + } + + // + // Next, identify which built-ins have a mapping to an operator. + // If PureOperatorBuiltins is false, those that are not identified as such are + // expected to be resolved through a library of functions, versus as + // operations. + // + symbolTable.relateToOperator("not", EOpVectorLogicalNot); + + symbolTable.relateToOperator("matrixCompMult", EOpMul); + // 120 and 150 are correct for both ES and desktop + if (version >= 120) { + symbolTable.relateToOperator("outerProduct", EOpOuterProduct); + symbolTable.relateToOperator("transpose", EOpTranspose); + if (version >= 150) { + symbolTable.relateToOperator("determinant", EOpDeterminant); + symbolTable.relateToOperator("inverse", EOpMatrixInverse); + } + } + + symbolTable.relateToOperator("mod", EOpMod); + symbolTable.relateToOperator("modf", EOpModf); + + symbolTable.relateToOperator("equal", EOpVectorEqual); + symbolTable.relateToOperator("notEqual", EOpVectorNotEqual); + symbolTable.relateToOperator("lessThan", EOpLessThan); + symbolTable.relateToOperator("greaterThan", EOpGreaterThan); + symbolTable.relateToOperator("lessThanEqual", EOpLessThanEqual); + symbolTable.relateToOperator("greaterThanEqual", EOpGreaterThanEqual); + + symbolTable.relateToOperator("radians", EOpRadians); + symbolTable.relateToOperator("degrees", EOpDegrees); + symbolTable.relateToOperator("sin", EOpSin); + symbolTable.relateToOperator("cos", EOpCos); + symbolTable.relateToOperator("tan", EOpTan); + symbolTable.relateToOperator("asin", EOpAsin); + symbolTable.relateToOperator("acos", EOpAcos); + symbolTable.relateToOperator("atan", EOpAtan); + symbolTable.relateToOperator("sinh", EOpSinh); + symbolTable.relateToOperator("cosh", EOpCosh); + symbolTable.relateToOperator("tanh", EOpTanh); + symbolTable.relateToOperator("asinh", EOpAsinh); + symbolTable.relateToOperator("acosh", EOpAcosh); + symbolTable.relateToOperator("atanh", EOpAtanh); + + symbolTable.relateToOperator("pow", EOpPow); + symbolTable.relateToOperator("exp2", EOpExp2); + symbolTable.relateToOperator("log", EOpLog); + symbolTable.relateToOperator("exp", EOpExp); + symbolTable.relateToOperator("log2", EOpLog2); + symbolTable.relateToOperator("sqrt", EOpSqrt); + symbolTable.relateToOperator("inversesqrt", EOpInverseSqrt); + + symbolTable.relateToOperator("abs", EOpAbs); + symbolTable.relateToOperator("sign", EOpSign); + symbolTable.relateToOperator("floor", EOpFloor); + symbolTable.relateToOperator("trunc", EOpTrunc); + symbolTable.relateToOperator("round", EOpRound); + symbolTable.relateToOperator("roundEven", EOpRoundEven); + symbolTable.relateToOperator("ceil", EOpCeil); + symbolTable.relateToOperator("fract", EOpFract); + symbolTable.relateToOperator("min", EOpMin); + symbolTable.relateToOperator("max", EOpMax); + symbolTable.relateToOperator("clamp", EOpClamp); + symbolTable.relateToOperator("mix", EOpMix); + symbolTable.relateToOperator("step", EOpStep); + symbolTable.relateToOperator("smoothstep", EOpSmoothStep); + + symbolTable.relateToOperator("isnan", EOpIsNan); + symbolTable.relateToOperator("isinf", EOpIsInf); + + symbolTable.relateToOperator("floatBitsToInt", EOpFloatBitsToInt); + symbolTable.relateToOperator("floatBitsToUint", EOpFloatBitsToUint); + symbolTable.relateToOperator("intBitsToFloat", EOpIntBitsToFloat); + symbolTable.relateToOperator("uintBitsToFloat", EOpUintBitsToFloat); + symbolTable.relateToOperator("doubleBitsToInt64", EOpDoubleBitsToInt64); + symbolTable.relateToOperator("doubleBitsToUint64", EOpDoubleBitsToUint64); + symbolTable.relateToOperator("int64BitsToDouble", EOpInt64BitsToDouble); + symbolTable.relateToOperator("uint64BitsToDouble", EOpUint64BitsToDouble); +#ifdef AMD_EXTENSIONS + symbolTable.relateToOperator("float16BitsToInt16", EOpFloat16BitsToInt16); + symbolTable.relateToOperator("float16BitsToUint16", EOpFloat16BitsToUint16); + symbolTable.relateToOperator("int16BitsToFloat16", EOpInt16BitsToFloat16); + symbolTable.relateToOperator("uint16BitsToFloat16", EOpUint16BitsToFloat16); +#endif + + symbolTable.relateToOperator("packSnorm2x16", EOpPackSnorm2x16); + symbolTable.relateToOperator("unpackSnorm2x16", EOpUnpackSnorm2x16); + symbolTable.relateToOperator("packUnorm2x16", EOpPackUnorm2x16); + symbolTable.relateToOperator("unpackUnorm2x16", EOpUnpackUnorm2x16); + + symbolTable.relateToOperator("packSnorm4x8", EOpPackSnorm4x8); + symbolTable.relateToOperator("unpackSnorm4x8", EOpUnpackSnorm4x8); + symbolTable.relateToOperator("packUnorm4x8", EOpPackUnorm4x8); + symbolTable.relateToOperator("unpackUnorm4x8", EOpUnpackUnorm4x8); + + symbolTable.relateToOperator("packDouble2x32", EOpPackDouble2x32); + symbolTable.relateToOperator("unpackDouble2x32", EOpUnpackDouble2x32); + + symbolTable.relateToOperator("packHalf2x16", EOpPackHalf2x16); + symbolTable.relateToOperator("unpackHalf2x16", EOpUnpackHalf2x16); + + symbolTable.relateToOperator("packInt2x32", EOpPackInt2x32); + symbolTable.relateToOperator("unpackInt2x32", EOpUnpackInt2x32); + symbolTable.relateToOperator("packUint2x32", EOpPackUint2x32); + symbolTable.relateToOperator("unpackUint2x32", EOpUnpackUint2x32); + +#ifdef AMD_EXTENSIONS + symbolTable.relateToOperator("packInt2x16", EOpPackInt2x16); + symbolTable.relateToOperator("unpackInt2x16", EOpUnpackInt2x16); + symbolTable.relateToOperator("packUint2x16", EOpPackUint2x16); + symbolTable.relateToOperator("unpackUint2x16", EOpUnpackUint2x16); + + symbolTable.relateToOperator("packInt4x16", EOpPackInt4x16); + symbolTable.relateToOperator("unpackInt4x16", EOpUnpackInt4x16); + symbolTable.relateToOperator("packUint4x16", EOpPackUint4x16); + symbolTable.relateToOperator("unpackUint4x16", EOpUnpackUint4x16); + + symbolTable.relateToOperator("packFloat2x16", EOpPackFloat2x16); + symbolTable.relateToOperator("unpackFloat2x16", EOpUnpackFloat2x16); +#endif + + symbolTable.relateToOperator("length", EOpLength); + symbolTable.relateToOperator("distance", EOpDistance); + symbolTable.relateToOperator("dot", EOpDot); + symbolTable.relateToOperator("cross", EOpCross); + symbolTable.relateToOperator("normalize", EOpNormalize); + symbolTable.relateToOperator("faceforward", EOpFaceForward); + symbolTable.relateToOperator("reflect", EOpReflect); + symbolTable.relateToOperator("refract", EOpRefract); + + symbolTable.relateToOperator("any", EOpAny); + symbolTable.relateToOperator("all", EOpAll); + + symbolTable.relateToOperator("barrier", EOpBarrier); + symbolTable.relateToOperator("memoryBarrier", EOpMemoryBarrier); + symbolTable.relateToOperator("memoryBarrierAtomicCounter", EOpMemoryBarrierAtomicCounter); + symbolTable.relateToOperator("memoryBarrierBuffer", EOpMemoryBarrierBuffer); + symbolTable.relateToOperator("memoryBarrierImage", EOpMemoryBarrierImage); + + symbolTable.relateToOperator("atomicAdd", EOpAtomicAdd); + symbolTable.relateToOperator("atomicMin", EOpAtomicMin); + symbolTable.relateToOperator("atomicMax", EOpAtomicMax); + symbolTable.relateToOperator("atomicAnd", EOpAtomicAnd); + symbolTable.relateToOperator("atomicOr", EOpAtomicOr); + symbolTable.relateToOperator("atomicXor", EOpAtomicXor); + symbolTable.relateToOperator("atomicExchange", EOpAtomicExchange); + symbolTable.relateToOperator("atomicCompSwap", EOpAtomicCompSwap); + + symbolTable.relateToOperator("atomicCounterIncrement", EOpAtomicCounterIncrement); + symbolTable.relateToOperator("atomicCounterDecrement", EOpAtomicCounterDecrement); + symbolTable.relateToOperator("atomicCounter", EOpAtomicCounter); + + if (profile != EEsProfile && version >= 460) { + symbolTable.relateToOperator("atomicCounterAdd", EOpAtomicCounterAdd); + symbolTable.relateToOperator("atomicCounterSubtract", EOpAtomicCounterSubtract); + symbolTable.relateToOperator("atomicCounterMin", EOpAtomicCounterMin); + symbolTable.relateToOperator("atomicCounterMax", EOpAtomicCounterMax); + symbolTable.relateToOperator("atomicCounterAnd", EOpAtomicCounterAnd); + symbolTable.relateToOperator("atomicCounterOr", EOpAtomicCounterOr); + symbolTable.relateToOperator("atomicCounterXor", EOpAtomicCounterXor); + symbolTable.relateToOperator("atomicCounterExchange", EOpAtomicCounterExchange); + symbolTable.relateToOperator("atomicCounterCompSwap", EOpAtomicCounterCompSwap); + } + + symbolTable.relateToOperator("fma", EOpFma); + symbolTable.relateToOperator("frexp", EOpFrexp); + symbolTable.relateToOperator("ldexp", EOpLdexp); + symbolTable.relateToOperator("uaddCarry", EOpAddCarry); + symbolTable.relateToOperator("usubBorrow", EOpSubBorrow); + symbolTable.relateToOperator("umulExtended", EOpUMulExtended); + symbolTable.relateToOperator("imulExtended", EOpIMulExtended); + symbolTable.relateToOperator("bitfieldExtract", EOpBitfieldExtract); + symbolTable.relateToOperator("bitfieldInsert", EOpBitfieldInsert); + symbolTable.relateToOperator("bitfieldReverse", EOpBitFieldReverse); + symbolTable.relateToOperator("bitCount", EOpBitCount); + symbolTable.relateToOperator("findLSB", EOpFindLSB); + symbolTable.relateToOperator("findMSB", EOpFindMSB); + + if (PureOperatorBuiltins) { + symbolTable.relateToOperator("imageSize", EOpImageQuerySize); + symbolTable.relateToOperator("imageSamples", EOpImageQuerySamples); + symbolTable.relateToOperator("imageLoad", EOpImageLoad); + symbolTable.relateToOperator("imageStore", EOpImageStore); + symbolTable.relateToOperator("imageAtomicAdd", EOpImageAtomicAdd); + symbolTable.relateToOperator("imageAtomicMin", EOpImageAtomicMin); + symbolTable.relateToOperator("imageAtomicMax", EOpImageAtomicMax); + symbolTable.relateToOperator("imageAtomicAnd", EOpImageAtomicAnd); + symbolTable.relateToOperator("imageAtomicOr", EOpImageAtomicOr); + symbolTable.relateToOperator("imageAtomicXor", EOpImageAtomicXor); + symbolTable.relateToOperator("imageAtomicExchange", EOpImageAtomicExchange); + symbolTable.relateToOperator("imageAtomicCompSwap", EOpImageAtomicCompSwap); + + symbolTable.relateToOperator("subpassLoad", EOpSubpassLoad); + symbolTable.relateToOperator("subpassLoadMS", EOpSubpassLoadMS); + + symbolTable.relateToOperator("textureSize", EOpTextureQuerySize); + symbolTable.relateToOperator("textureQueryLod", EOpTextureQueryLod); + symbolTable.relateToOperator("textureQueryLevels", EOpTextureQueryLevels); + symbolTable.relateToOperator("textureSamples", EOpTextureQuerySamples); + symbolTable.relateToOperator("texture", EOpTexture); + symbolTable.relateToOperator("textureProj", EOpTextureProj); + symbolTable.relateToOperator("textureLod", EOpTextureLod); + symbolTable.relateToOperator("textureOffset", EOpTextureOffset); + symbolTable.relateToOperator("texelFetch", EOpTextureFetch); + symbolTable.relateToOperator("texelFetchOffset", EOpTextureFetchOffset); + symbolTable.relateToOperator("textureProjOffset", EOpTextureProjOffset); + symbolTable.relateToOperator("textureLodOffset", EOpTextureLodOffset); + symbolTable.relateToOperator("textureProjLod", EOpTextureProjLod); + symbolTable.relateToOperator("textureProjLodOffset", EOpTextureProjLodOffset); + symbolTable.relateToOperator("textureGrad", EOpTextureGrad); + symbolTable.relateToOperator("textureGradOffset", EOpTextureGradOffset); + symbolTable.relateToOperator("textureProjGrad", EOpTextureProjGrad); + symbolTable.relateToOperator("textureProjGradOffset", EOpTextureProjGradOffset); + symbolTable.relateToOperator("textureGather", EOpTextureGather); + symbolTable.relateToOperator("textureGatherOffset", EOpTextureGatherOffset); + symbolTable.relateToOperator("textureGatherOffsets", EOpTextureGatherOffsets); + + symbolTable.relateToOperator("noise1", EOpNoise); + symbolTable.relateToOperator("noise2", EOpNoise); + symbolTable.relateToOperator("noise3", EOpNoise); + symbolTable.relateToOperator("noise4", EOpNoise); + + if (spvVersion.spv == 0 && (IncludeLegacy(version, profile, spvVersion) || + (profile == EEsProfile && version == 100))) { + symbolTable.relateToOperator("ftransform", EOpFtransform); + + symbolTable.relateToOperator("texture1D", EOpTexture); + symbolTable.relateToOperator("texture1DGradARB", EOpTextureGrad); + symbolTable.relateToOperator("texture1DProj", EOpTextureProj); + symbolTable.relateToOperator("texture1DProjGradARB", EOpTextureProjGrad); + symbolTable.relateToOperator("texture1DLod", EOpTextureLod); + symbolTable.relateToOperator("texture1DProjLod", EOpTextureProjLod); + + symbolTable.relateToOperator("texture2DRect", EOpTexture); + symbolTable.relateToOperator("texture2DRectProj", EOpTextureProj); + symbolTable.relateToOperator("texture2DRectGradARB", EOpTextureGrad); + symbolTable.relateToOperator("texture2DRectProjGradARB", EOpTextureProjGrad); + symbolTable.relateToOperator("shadow2DRect", EOpTexture); + symbolTable.relateToOperator("shadow2DRectProj", EOpTextureProj); + symbolTable.relateToOperator("shadow2DRectGradARB", EOpTextureGrad); + symbolTable.relateToOperator("shadow2DRectProjGradARB", EOpTextureProjGrad); + + symbolTable.relateToOperator("texture2D", EOpTexture); + symbolTable.relateToOperator("texture2DProj", EOpTextureProj); + symbolTable.relateToOperator("texture2DGradEXT", EOpTextureGrad); + symbolTable.relateToOperator("texture2DGradARB", EOpTextureGrad); + symbolTable.relateToOperator("texture2DProjGradEXT", EOpTextureProjGrad); + symbolTable.relateToOperator("texture2DProjGradARB", EOpTextureProjGrad); + symbolTable.relateToOperator("texture2DLod", EOpTextureLod); + symbolTable.relateToOperator("texture2DLodEXT", EOpTextureLod); + symbolTable.relateToOperator("texture2DProjLod", EOpTextureProjLod); + symbolTable.relateToOperator("texture2DProjLodEXT", EOpTextureProjLod); + + symbolTable.relateToOperator("texture1DArray", EOpTexture); + symbolTable.relateToOperator("texture2DArray", EOpTexture); + symbolTable.relateToOperator("shadow1DArray", EOpTexture); + symbolTable.relateToOperator("shadow2DArray", EOpTexture); + symbolTable.relateToOperator("texture1DArrayLod", EOpTextureLod); + symbolTable.relateToOperator("texture2DArrayLod", EOpTextureLod); + symbolTable.relateToOperator("shadow1DArrayLod", EOpTextureLod); + symbolTable.relateToOperator("shadow2DArrayLod", EOpTextureLod); + + symbolTable.relateToOperator("texture3D", EOpTexture); + symbolTable.relateToOperator("texture3DGradARB", EOpTextureGrad); + symbolTable.relateToOperator("texture3DProj", EOpTextureProj); + symbolTable.relateToOperator("texture3DProjGradARB", EOpTextureProjGrad); + symbolTable.relateToOperator("texture3DLod", EOpTextureLod); + symbolTable.relateToOperator("texture3DProjLod", EOpTextureProjLod); + symbolTable.relateToOperator("textureCube", EOpTexture); + symbolTable.relateToOperator("textureCubeGradEXT", EOpTextureGrad); + symbolTable.relateToOperator("textureCubeGradARB", EOpTextureGrad); + symbolTable.relateToOperator("textureCubeLod", EOpTextureLod); + symbolTable.relateToOperator("textureCubeLodEXT", EOpTextureLod); + symbolTable.relateToOperator("shadow1D", EOpTexture); + symbolTable.relateToOperator("shadow1DGradARB", EOpTextureGrad); + symbolTable.relateToOperator("shadow2D", EOpTexture); + symbolTable.relateToOperator("shadow2DGradARB", EOpTextureGrad); + symbolTable.relateToOperator("shadow1DProj", EOpTextureProj); + symbolTable.relateToOperator("shadow2DProj", EOpTextureProj); + symbolTable.relateToOperator("shadow1DProjGradARB", EOpTextureProjGrad); + symbolTable.relateToOperator("shadow2DProjGradARB", EOpTextureProjGrad); + symbolTable.relateToOperator("shadow1DLod", EOpTextureLod); + symbolTable.relateToOperator("shadow2DLod", EOpTextureLod); + symbolTable.relateToOperator("shadow1DProjLod", EOpTextureProjLod); + symbolTable.relateToOperator("shadow2DProjLod", EOpTextureProjLod); + } + + if (profile != EEsProfile) { + symbolTable.relateToOperator("sparseTextureARB", EOpSparseTexture); + symbolTable.relateToOperator("sparseTextureLodARB", EOpSparseTextureLod); + symbolTable.relateToOperator("sparseTextureOffsetARB", EOpSparseTextureOffset); + symbolTable.relateToOperator("sparseTexelFetchARB", EOpSparseTextureFetch); + symbolTable.relateToOperator("sparseTexelFetchOffsetARB", EOpSparseTextureFetchOffset); + symbolTable.relateToOperator("sparseTextureLodOffsetARB", EOpSparseTextureLodOffset); + symbolTable.relateToOperator("sparseTextureGradARB", EOpSparseTextureGrad); + symbolTable.relateToOperator("sparseTextureGradOffsetARB", EOpSparseTextureGradOffset); + symbolTable.relateToOperator("sparseTextureGatherARB", EOpSparseTextureGather); + symbolTable.relateToOperator("sparseTextureGatherOffsetARB", EOpSparseTextureGatherOffset); + symbolTable.relateToOperator("sparseTextureGatherOffsetsARB", EOpSparseTextureGatherOffsets); + symbolTable.relateToOperator("sparseImageLoadARB", EOpSparseImageLoad); + symbolTable.relateToOperator("sparseTexelsResidentARB", EOpSparseTexelsResident); + + symbolTable.relateToOperator("sparseTextureClampARB", EOpSparseTextureClamp); + symbolTable.relateToOperator("sparseTextureOffsetClampARB", EOpSparseTextureOffsetClamp); + symbolTable.relateToOperator("sparseTextureGradClampARB", EOpSparseTextureGradClamp); + symbolTable.relateToOperator("sparseTextureGradOffsetClampARB", EOpSparseTextureGradOffsetClamp); + symbolTable.relateToOperator("textureClampARB", EOpTextureClamp); + symbolTable.relateToOperator("textureOffsetClampARB", EOpTextureOffsetClamp); + symbolTable.relateToOperator("textureGradClampARB", EOpTextureGradClamp); + symbolTable.relateToOperator("textureGradOffsetClampARB", EOpTextureGradOffsetClamp); + + symbolTable.relateToOperator("ballotARB", EOpBallot); + symbolTable.relateToOperator("readInvocationARB", EOpReadInvocation); + symbolTable.relateToOperator("readFirstInvocationARB", EOpReadFirstInvocation); + + if (version >= 430) { + symbolTable.relateToOperator("anyInvocationARB", EOpAnyInvocation); + symbolTable.relateToOperator("allInvocationsARB", EOpAllInvocations); + symbolTable.relateToOperator("allInvocationsEqualARB", EOpAllInvocationsEqual); + } + if (version >= 460) { + symbolTable.relateToOperator("anyInvocation", EOpAnyInvocation); + symbolTable.relateToOperator("allInvocations", EOpAllInvocations); + symbolTable.relateToOperator("allInvocationsEqual", EOpAllInvocationsEqual); + } +#ifdef AMD_EXTENSIONS + symbolTable.relateToOperator("minInvocationsAMD", EOpMinInvocations); + symbolTable.relateToOperator("maxInvocationsAMD", EOpMaxInvocations); + symbolTable.relateToOperator("addInvocationsAMD", EOpAddInvocations); + symbolTable.relateToOperator("minInvocationsNonUniformAMD", EOpMinInvocationsNonUniform); + symbolTable.relateToOperator("maxInvocationsNonUniformAMD", EOpMaxInvocationsNonUniform); + symbolTable.relateToOperator("addInvocationsNonUniformAMD", EOpAddInvocationsNonUniform); + symbolTable.relateToOperator("minInvocationsInclusiveScanAMD", EOpMinInvocationsInclusiveScan); + symbolTable.relateToOperator("maxInvocationsInclusiveScanAMD", EOpMaxInvocationsInclusiveScan); + symbolTable.relateToOperator("addInvocationsInclusiveScanAMD", EOpAddInvocationsInclusiveScan); + symbolTable.relateToOperator("minInvocationsInclusiveScanNonUniformAMD", EOpMinInvocationsInclusiveScanNonUniform); + symbolTable.relateToOperator("maxInvocationsInclusiveScanNonUniformAMD", EOpMaxInvocationsInclusiveScanNonUniform); + symbolTable.relateToOperator("addInvocationsInclusiveScanNonUniformAMD", EOpAddInvocationsInclusiveScanNonUniform); + symbolTable.relateToOperator("minInvocationsExclusiveScanAMD", EOpMinInvocationsExclusiveScan); + symbolTable.relateToOperator("maxInvocationsExclusiveScanAMD", EOpMaxInvocationsExclusiveScan); + symbolTable.relateToOperator("addInvocationsExclusiveScanAMD", EOpAddInvocationsExclusiveScan); + symbolTable.relateToOperator("minInvocationsExclusiveScanNonUniformAMD", EOpMinInvocationsExclusiveScanNonUniform); + symbolTable.relateToOperator("maxInvocationsExclusiveScanNonUniformAMD", EOpMaxInvocationsExclusiveScanNonUniform); + symbolTable.relateToOperator("addInvocationsExclusiveScanNonUniformAMD", EOpAddInvocationsExclusiveScanNonUniform); + symbolTable.relateToOperator("swizzleInvocationsAMD", EOpSwizzleInvocations); + symbolTable.relateToOperator("swizzleInvocationsMaskedAMD", EOpSwizzleInvocationsMasked); + symbolTable.relateToOperator("writeInvocationAMD", EOpWriteInvocation); + symbolTable.relateToOperator("mbcntAMD", EOpMbcnt); + + symbolTable.relateToOperator("min3", EOpMin3); + symbolTable.relateToOperator("max3", EOpMax3); + symbolTable.relateToOperator("mid3", EOpMid3); + + symbolTable.relateToOperator("cubeFaceIndexAMD", EOpCubeFaceIndex); + symbolTable.relateToOperator("cubeFaceCoordAMD", EOpCubeFaceCoord); + symbolTable.relateToOperator("timeAMD", EOpTime); + + symbolTable.relateToOperator("textureGatherLodAMD", EOpTextureGatherLod); + symbolTable.relateToOperator("textureGatherLodOffsetAMD", EOpTextureGatherLodOffset); + symbolTable.relateToOperator("textureGatherLodOffsetsAMD", EOpTextureGatherLodOffsets); + symbolTable.relateToOperator("sparseTextureGatherLodAMD", EOpSparseTextureGatherLod); + symbolTable.relateToOperator("sparseTextureGatherLodOffsetAMD", EOpSparseTextureGatherLodOffset); + symbolTable.relateToOperator("sparseTextureGatherLodOffsetsAMD", EOpSparseTextureGatherLodOffsets); + + symbolTable.relateToOperator("imageLoadLodAMD", EOpImageLoadLod); + symbolTable.relateToOperator("imageStoreLodAMD", EOpImageStoreLod); + symbolTable.relateToOperator("sparseImageLoadLodAMD", EOpSparseImageLoadLod); + + symbolTable.relateToOperator("fragmentMaskFetchAMD", EOpFragmentMaskFetch); + symbolTable.relateToOperator("fragmentFetchAMD", EOpFragmentFetch); +#endif + } + if (profile == EEsProfile) { + symbolTable.relateToOperator("shadow2DEXT", EOpTexture); + symbolTable.relateToOperator("shadow2DProjEXT", EOpTextureProj); + } + } + + switch(language) { + case EShLangVertex: + break; + + case EShLangTessControl: + case EShLangTessEvaluation: + break; + + case EShLangGeometry: + symbolTable.relateToOperator("EmitStreamVertex", EOpEmitStreamVertex); + symbolTable.relateToOperator("EndStreamPrimitive", EOpEndStreamPrimitive); + symbolTable.relateToOperator("EmitVertex", EOpEmitVertex); + symbolTable.relateToOperator("EndPrimitive", EOpEndPrimitive); + break; + + case EShLangFragment: + symbolTable.relateToOperator("dFdx", EOpDPdx); + symbolTable.relateToOperator("dFdy", EOpDPdy); + symbolTable.relateToOperator("fwidth", EOpFwidth); + if (profile != EEsProfile && version >= 400) { + symbolTable.relateToOperator("dFdxFine", EOpDPdxFine); + symbolTable.relateToOperator("dFdyFine", EOpDPdyFine); + symbolTable.relateToOperator("fwidthFine", EOpFwidthFine); + symbolTable.relateToOperator("dFdxCoarse", EOpDPdxCoarse); + symbolTable.relateToOperator("dFdyCoarse", EOpDPdyCoarse); + symbolTable.relateToOperator("fwidthCoarse", EOpFwidthCoarse); + } + symbolTable.relateToOperator("interpolateAtCentroid", EOpInterpolateAtCentroid); + symbolTable.relateToOperator("interpolateAtSample", EOpInterpolateAtSample); + symbolTable.relateToOperator("interpolateAtOffset", EOpInterpolateAtOffset); + +#ifdef AMD_EXTENSIONS + if (profile != EEsProfile) + symbolTable.relateToOperator("interpolateAtVertexAMD", EOpInterpolateAtVertex); + break; +#endif + + case EShLangCompute: + symbolTable.relateToOperator("memoryBarrierShared", EOpMemoryBarrierShared); + symbolTable.relateToOperator("groupMemoryBarrier", EOpGroupMemoryBarrier); + break; + + default: + assert(false && "Language not supported"); + } +} + +// +// Add context-dependent (resource-specific) built-ins not handled by the above. These +// would be ones that need to be programmatically added because they cannot +// be added by simple text strings. For these, also +// 1) Map built-in functions to operators, for those that will turn into an operation node +// instead of remaining a function call. +// 2) Tag extension-related symbols added to their base version with their extensions, so +// that if an early version has the extension turned off, there is an error reported on use. +// +void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources) +{ + if (profile != EEsProfile && version >= 430 && version < 440) { + symbolTable.setVariableExtensions("gl_MaxTransformFeedbackBuffers", 1, &E_GL_ARB_enhanced_layouts); + symbolTable.setVariableExtensions("gl_MaxTransformFeedbackInterleavedComponents", 1, &E_GL_ARB_enhanced_layouts); + } + if (profile != EEsProfile && version >= 130 && version < 420) { + symbolTable.setVariableExtensions("gl_MinProgramTexelOffset", 1, &E_GL_ARB_shading_language_420pack); + symbolTable.setVariableExtensions("gl_MaxProgramTexelOffset", 1, &E_GL_ARB_shading_language_420pack); + } + if (profile != EEsProfile && version >= 150 && version < 410) + symbolTable.setVariableExtensions("gl_MaxViewports", 1, &E_GL_ARB_viewport_array); + + switch(language) { + case EShLangFragment: + // Set up gl_FragData based on current array size. + if (version == 100 || IncludeLegacy(version, profile, spvVersion) || (! ForwardCompatibility && profile != EEsProfile && version < 420)) { + TPrecisionQualifier pq = profile == EEsProfile ? EpqMedium : EpqNone; + TType fragData(EbtFloat, EvqFragColor, pq, 4); + TArraySizes& arraySizes = *new TArraySizes; + arraySizes.addInnerSize(resources.maxDrawBuffers); + fragData.newArraySizes(arraySizes); + symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"), fragData)); + SpecialQualifier("gl_FragData", EvqFragColor, EbvFragData, symbolTable); + } + break; + + case EShLangTessControl: + case EShLangTessEvaluation: + // Because of the context-dependent array size (gl_MaxPatchVertices), + // these variables were added later than the others and need to be mapped now. + + // standard members + BuiltInVariable("gl_in", "gl_Position", EbvPosition, symbolTable); + BuiltInVariable("gl_in", "gl_PointSize", EbvPointSize, symbolTable); + BuiltInVariable("gl_in", "gl_ClipDistance", EbvClipDistance, symbolTable); + BuiltInVariable("gl_in", "gl_CullDistance", EbvCullDistance, symbolTable); + + // compatibility members + BuiltInVariable("gl_in", "gl_ClipVertex", EbvClipVertex, symbolTable); + BuiltInVariable("gl_in", "gl_FrontColor", EbvFrontColor, symbolTable); + BuiltInVariable("gl_in", "gl_BackColor", EbvBackColor, symbolTable); + BuiltInVariable("gl_in", "gl_FrontSecondaryColor", EbvFrontSecondaryColor, symbolTable); + BuiltInVariable("gl_in", "gl_BackSecondaryColor", EbvBackSecondaryColor, symbolTable); + BuiltInVariable("gl_in", "gl_TexCoord", EbvTexCoord, symbolTable); + BuiltInVariable("gl_in", "gl_FogFragCoord", EbvFogFragCoord, symbolTable); + break; + + default: + break; + } +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/Initialize.h b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/Initialize.h new file mode 100644 index 00000000..6b54c4da --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/Initialize.h @@ -0,0 +1,112 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2013-2016 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef _INITIALIZE_INCLUDED_ +#define _INITIALIZE_INCLUDED_ + +#include "../Include/ResourceLimits.h" +#include "../Include/Common.h" +#include "../Include/ShHandle.h" +#include "SymbolTable.h" +#include "Versions.h" + +namespace glslang { + +// +// This is made to hold parseable strings for almost all the built-in +// functions and variables for one specific combination of version +// and profile. (Some still need to be added programmatically.) +// This is a base class for language-specific derivations, which +// can be used for language independent builtins. +// +// The strings are organized by +// commonBuiltins: intersection of all stages' built-ins, processed just once +// stageBuiltins[]: anything a stage needs that's not in commonBuiltins +// +class TBuiltInParseables { +public: + POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) + TBuiltInParseables(); + virtual ~TBuiltInParseables(); + virtual void initialize(int version, EProfile, const SpvVersion& spvVersion) = 0; + virtual void initialize(const TBuiltInResource& resources, int version, EProfile, const SpvVersion& spvVersion, EShLanguage) = 0; + virtual const TString& getCommonString() const { return commonBuiltins; } + virtual const TString& getStageString(EShLanguage language) const { return stageBuiltins[language]; } + + virtual void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable) = 0; + + virtual void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources) = 0; + +protected: + TString commonBuiltins; + TString stageBuiltins[EShLangCount]; +}; + +// +// This is a GLSL specific derivation of TBuiltInParseables. To present a stable +// interface and match other similar code, it is called TBuiltIns, rather +// than TBuiltInParseablesGlsl. +// +class TBuiltIns : public TBuiltInParseables { +public: + POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) + TBuiltIns(); + virtual ~TBuiltIns(); + void initialize(int version, EProfile, const SpvVersion& spvVersion); + void initialize(const TBuiltInResource& resources, int version, EProfile, const SpvVersion& spvVersion, EShLanguage); + + void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable); + + void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources); + +protected: + void add2ndGenerationSamplingImaging(int version, EProfile profile, const SpvVersion& spvVersion); + void addSubpassSampling(TSampler, const TString& typeName, int version, EProfile profile); + void addQueryFunctions(TSampler, const TString& typeName, int version, EProfile profile); + void addImageFunctions(TSampler, const TString& typeName, int version, EProfile profile); + void addSamplingFunctions(TSampler, const TString& typeName, int version, EProfile profile); + void addGatherFunctions(TSampler, const TString& typeName, int version, EProfile profile); + + // Helpers for making textual representations of the permutations + // of texturing/imaging functions. + const char* postfixes[5]; + const char* prefixes[EbtNumTypes]; + int dimMap[EsdNumDims]; +}; + +} // end namespace glslang + +#endif // _INITIALIZE_INCLUDED_ diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/IntermTraverse.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/IntermTraverse.cpp new file mode 100644 index 00000000..f46010b7 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/IntermTraverse.cpp @@ -0,0 +1,302 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2013 LunarG, Inc. +// Copyright (c) 2002-2010 The ANGLE Project Authors. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#include "../Include/intermediate.h" + +namespace glslang { + +// +// Traverse the intermediate representation tree, and +// call a node type specific function for each node. +// Done recursively through the member function Traverse(). +// Node types can be skipped if their function to call is 0, +// but their subtree will still be traversed. +// Nodes with children can have their whole subtree skipped +// if preVisit is turned on and the type specific function +// returns false. +// +// preVisit, postVisit, and rightToLeft control what order +// nodes are visited in. +// + +// +// Traversal functions for terminals are straightforward.... +// +void TIntermMethod::traverse(TIntermTraverser*) +{ + // Tree should always resolve all methods as a non-method. +} + +void TIntermSymbol::traverse(TIntermTraverser *it) +{ + it->visitSymbol(this); +} + +void TIntermConstantUnion::traverse(TIntermTraverser *it) +{ + it->visitConstantUnion(this); +} + +// +// Traverse a binary node. +// +void TIntermBinary::traverse(TIntermTraverser *it) +{ + bool visit = true; + + // + // visit the node before children if pre-visiting. + // + if (it->preVisit) + visit = it->visitBinary(EvPreVisit, this); + + // + // Visit the children, in the right order. + // + if (visit) { + it->incrementDepth(this); + + if (it->rightToLeft) { + if (right) + right->traverse(it); + + if (it->inVisit) + visit = it->visitBinary(EvInVisit, this); + + if (visit && left) + left->traverse(it); + } else { + if (left) + left->traverse(it); + + if (it->inVisit) + visit = it->visitBinary(EvInVisit, this); + + if (visit && right) + right->traverse(it); + } + + it->decrementDepth(); + } + + // + // Visit the node after the children, if requested and the traversal + // hasn't been canceled yet. + // + if (visit && it->postVisit) + it->visitBinary(EvPostVisit, this); +} + +// +// Traverse a unary node. Same comments in binary node apply here. +// +void TIntermUnary::traverse(TIntermTraverser *it) +{ + bool visit = true; + + if (it->preVisit) + visit = it->visitUnary(EvPreVisit, this); + + if (visit) { + it->incrementDepth(this); + operand->traverse(it); + it->decrementDepth(); + } + + if (visit && it->postVisit) + it->visitUnary(EvPostVisit, this); +} + +// +// Traverse an aggregate node. Same comments in binary node apply here. +// +void TIntermAggregate::traverse(TIntermTraverser *it) +{ + bool visit = true; + + if (it->preVisit) + visit = it->visitAggregate(EvPreVisit, this); + + if (visit) { + it->incrementDepth(this); + + if (it->rightToLeft) { + for (TIntermSequence::reverse_iterator sit = sequence.rbegin(); sit != sequence.rend(); sit++) { + (*sit)->traverse(it); + + if (visit && it->inVisit) { + if (*sit != sequence.front()) + visit = it->visitAggregate(EvInVisit, this); + } + } + } else { + for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++) { + (*sit)->traverse(it); + + if (visit && it->inVisit) { + if (*sit != sequence.back()) + visit = it->visitAggregate(EvInVisit, this); + } + } + } + + it->decrementDepth(); + } + + if (visit && it->postVisit) + it->visitAggregate(EvPostVisit, this); +} + +// +// Traverse a selection node. Same comments in binary node apply here. +// +void TIntermSelection::traverse(TIntermTraverser *it) +{ + bool visit = true; + + if (it->preVisit) + visit = it->visitSelection(EvPreVisit, this); + + if (visit) { + it->incrementDepth(this); + if (it->rightToLeft) { + if (falseBlock) + falseBlock->traverse(it); + if (trueBlock) + trueBlock->traverse(it); + condition->traverse(it); + } else { + condition->traverse(it); + if (trueBlock) + trueBlock->traverse(it); + if (falseBlock) + falseBlock->traverse(it); + } + it->decrementDepth(); + } + + if (visit && it->postVisit) + it->visitSelection(EvPostVisit, this); +} + +// +// Traverse a loop node. Same comments in binary node apply here. +// +void TIntermLoop::traverse(TIntermTraverser *it) +{ + bool visit = true; + + if (it->preVisit) + visit = it->visitLoop(EvPreVisit, this); + + if (visit) { + it->incrementDepth(this); + + if (it->rightToLeft) { + if (terminal) + terminal->traverse(it); + + if (body) + body->traverse(it); + + if (test) + test->traverse(it); + } else { + if (test) + test->traverse(it); + + if (body) + body->traverse(it); + + if (terminal) + terminal->traverse(it); + } + + it->decrementDepth(); + } + + if (visit && it->postVisit) + it->visitLoop(EvPostVisit, this); +} + +// +// Traverse a branch node. Same comments in binary node apply here. +// +void TIntermBranch::traverse(TIntermTraverser *it) +{ + bool visit = true; + + if (it->preVisit) + visit = it->visitBranch(EvPreVisit, this); + + if (visit && expression) { + it->incrementDepth(this); + expression->traverse(it); + it->decrementDepth(); + } + + if (visit && it->postVisit) + it->visitBranch(EvPostVisit, this); +} + +// +// Traverse a switch node. +// +void TIntermSwitch::traverse(TIntermTraverser* it) +{ + bool visit = true; + + if (it->preVisit) + visit = it->visitSwitch(EvPreVisit, this); + + if (visit) { + it->incrementDepth(this); + if (it->rightToLeft) { + body->traverse(it); + condition->traverse(it); + } else { + condition->traverse(it); + body->traverse(it); + } + it->decrementDepth(); + } + + if (visit && it->postVisit) + it->visitSwitch(EvPostVisit, this); +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/Intermediate.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/Intermediate.cpp new file mode 100644 index 00000000..21899abe --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/Intermediate.cpp @@ -0,0 +1,3246 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2012-2015 LunarG, Inc. +// Copyright (C) 2015-2016 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +// +// Build the intermediate representation. +// + +#include "localintermediate.h" +#include "RemoveTree.h" +#include "SymbolTable.h" +#include "propagateNoContraction.h" + +#include +#include + +namespace glslang { + +//////////////////////////////////////////////////////////////////////////// +// +// First set of functions are to help build the intermediate representation. +// These functions are not member functions of the nodes. +// They are called from parser productions. +// +///////////////////////////////////////////////////////////////////////////// + +// +// Add a terminal node for an identifier in an expression. +// +// Returns the added node. +// + +TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, const TConstUnionArray& constArray, + TIntermTyped* constSubtree, const TSourceLoc& loc) +{ + TIntermSymbol* node = new TIntermSymbol(id, name, type); + node->setLoc(loc); + node->setConstArray(constArray); + node->setConstSubtree(constSubtree); + + return node; +} + +TIntermSymbol* TIntermediate::addSymbol(const TIntermSymbol& intermSymbol) +{ + return addSymbol(intermSymbol.getId(), + intermSymbol.getName(), + intermSymbol.getType(), + intermSymbol.getConstArray(), + intermSymbol.getConstSubtree(), + intermSymbol.getLoc()); +} + +TIntermSymbol* TIntermediate::addSymbol(const TVariable& variable) +{ + glslang::TSourceLoc loc; // just a null location + loc.init(); + + return addSymbol(variable, loc); +} + +TIntermSymbol* TIntermediate::addSymbol(const TVariable& variable, const TSourceLoc& loc) +{ + return addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), variable.getConstArray(), variable.getConstSubtree(), loc); +} + +TIntermSymbol* TIntermediate::addSymbol(const TType& type, const TSourceLoc& loc) +{ + TConstUnionArray unionArray; // just a null constant + + return addSymbol(0, "", type, unionArray, nullptr, loc); +} + +// +// Connect two nodes with a new parent that does a binary operation on the nodes. +// +// Returns the added node. +// +// Returns nullptr if the working conversions and promotions could not be found. +// +TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc) +{ + // No operations work on blocks + if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock) + return nullptr; + + // Try converting the children's base types to compatible types. + TIntermTyped* child = addConversion(op, left->getType(), right); + if (child) + right = child; + else { + child = addConversion(op, right->getType(), left); + if (child) + left = child; + else + return nullptr; + } + + // Convert the children's type shape to be compatible. + addBiShapeConversion(op, left, right); + if (left == nullptr || right == nullptr) + return nullptr; + + // + // Need a new node holding things together. Make + // one and promote it to the right type. + // + TIntermBinary* node = addBinaryNode(op, left, right, loc); + if (! promote(node)) + return nullptr; + + node->updatePrecision(); + + // + // If they are both (non-specialization) constants, they must be folded. + // (Unless it's the sequence (comma) operator, but that's handled in addComma().) + // + TIntermConstantUnion *leftTempConstant = node->getLeft()->getAsConstantUnion(); + TIntermConstantUnion *rightTempConstant = node->getRight()->getAsConstantUnion(); + if (leftTempConstant && rightTempConstant) { + TIntermTyped* folded = leftTempConstant->fold(node->getOp(), rightTempConstant); + if (folded) + return folded; + } + + // If can propagate spec-constantness and if the operation is an allowed + // specialization-constant operation, make a spec-constant. + if (specConstantPropagates(*node->getLeft(), *node->getRight()) && isSpecializationOperation(*node)) + node->getWritableType().getQualifier().makeSpecConstant(); + + return node; +} + +// +// Low level: add binary node (no promotions or other argument modifications) +// +TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc) const +{ + // build the node + TIntermBinary* node = new TIntermBinary(op); + if (loc.line == 0) + loc = left->getLoc(); + node->setLoc(loc); + node->setLeft(left); + node->setRight(right); + + return node; +} + +// +// like non-type form, but sets node's type. +// +TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc, const TType& type) const +{ + TIntermBinary* node = addBinaryNode(op, left, right, loc); + node->setType(type); + return node; +} + +// +// Low level: add unary node (no promotions or other argument modifications) +// +TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc loc) const +{ + TIntermUnary* node = new TIntermUnary(op); + if (loc.line == 0) + loc = child->getLoc(); + node->setLoc(loc); + node->setOperand(child); + + return node; +} + +// +// like non-type form, but sets node's type. +// +TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc loc, const TType& type) const +{ + TIntermUnary* node = addUnaryNode(op, child, loc); + node->setType(type); + return node; +} + +// +// Connect two nodes through an assignment. +// +// Returns the added node. +// +// Returns nullptr if the 'right' type could not be converted to match the 'left' type, +// or the resulting operation cannot be properly promoted. +// +TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc) +{ + // No block assignment + if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock) + return nullptr; + + // + // Like adding binary math, except the conversion can only go + // from right to left. + // + + // convert base types, nullptr return means not possible + right = addConversion(op, left->getType(), right); + if (right == nullptr) + return nullptr; + + // convert shape + right = addUniShapeConversion(op, left->getType(), right); + + // build the node + TIntermBinary* node = addBinaryNode(op, left, right, loc); + + if (! promote(node)) + return nullptr; + + node->updatePrecision(); + + return node; +} + +// +// Connect two nodes through an index operator, where the left node is the base +// of an array or struct, and the right node is a direct or indirect offset. +// +// Returns the added node. +// The caller should set the type of the returned node. +// +TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc loc) +{ + // caller should set the type + return addBinaryNode(op, base, index, loc); +} + +// +// Add one node as the parent of another that it operates on. +// +// Returns the added node. +// +TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSourceLoc loc) +{ + if (child == 0) + return nullptr; + + if (child->getType().getBasicType() == EbtBlock) + return nullptr; + + switch (op) { + case EOpLogicalNot: + if (source == EShSourceHlsl) { + break; // HLSL can promote logical not + } + + if (child->getType().getBasicType() != EbtBool || child->getType().isMatrix() || child->getType().isArray() || child->getType().isVector()) { + return nullptr; + } + break; + + case EOpPostIncrement: + case EOpPreIncrement: + case EOpPostDecrement: + case EOpPreDecrement: + case EOpNegative: + if (child->getType().getBasicType() == EbtStruct || child->getType().isArray()) + return nullptr; + default: break; // some compilers want this + } + + // + // Do we need to promote the operand? + // + TBasicType newType = EbtVoid; + switch (op) { + case EOpConstructInt: newType = EbtInt; break; + case EOpConstructUint: newType = EbtUint; break; + case EOpConstructInt64: newType = EbtInt64; break; + case EOpConstructUint64: newType = EbtUint64; break; +#ifdef AMD_EXTENSIONS + case EOpConstructInt16: newType = EbtInt16; break; + case EOpConstructUint16: newType = EbtUint16; break; +#endif + case EOpConstructBool: newType = EbtBool; break; + case EOpConstructFloat: newType = EbtFloat; break; + case EOpConstructDouble: newType = EbtDouble; break; +#ifdef AMD_EXTENSIONS + case EOpConstructFloat16: newType = EbtFloat16; break; +#endif + default: break; // some compilers want this + } + + if (newType != EbtVoid) { + child = addConversion(op, TType(newType, EvqTemporary, child->getVectorSize(), + child->getMatrixCols(), + child->getMatrixRows(), + child->isVector()), + child); + if (child == nullptr) + return nullptr; + } + + // + // For constructors, we are now done, it was all in the conversion. + // TODO: but, did this bypass constant folding? + // + switch (op) { + case EOpConstructInt: + case EOpConstructUint: + case EOpConstructInt64: + case EOpConstructUint64: +#ifdef AMD_EXTENSIONS + case EOpConstructInt16: + case EOpConstructUint16: +#endif + case EOpConstructBool: + case EOpConstructFloat: + case EOpConstructDouble: +#ifdef AMD_EXTENSIONS + case EOpConstructFloat16: +#endif + return child; + default: break; // some compilers want this + } + + // + // Make a new node for the operator. + // + TIntermUnary* node = addUnaryNode(op, child, loc); + + if (! promote(node)) + return nullptr; + + node->updatePrecision(); + + // If it's a (non-specialization) constant, it must be folded. + if (node->getOperand()->getAsConstantUnion()) + return node->getOperand()->getAsConstantUnion()->fold(op, node->getType()); + + // If it's a specialization constant, the result is too, + // if the operation is allowed for specialization constants. + if (node->getOperand()->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*node)) + node->getWritableType().getQualifier().makeSpecConstant(); + + return node; +} + +TIntermTyped* TIntermediate::addBuiltInFunctionCall(const TSourceLoc& loc, TOperator op, bool unary, TIntermNode* childNode, const TType& returnType) +{ + if (unary) { + // + // Treat it like a unary operator. + // addUnaryMath() should get the type correct on its own; + // including constness (which would differ from the prototype). + // + TIntermTyped* child = childNode->getAsTyped(); + if (child == nullptr) + return nullptr; + + if (child->getAsConstantUnion()) { + TIntermTyped* folded = child->getAsConstantUnion()->fold(op, returnType); + if (folded) + return folded; + } + + return addUnaryNode(op, child, child->getLoc(), returnType); + } else { + // setAggregateOperater() calls fold() for constant folding + TIntermTyped* node = setAggregateOperator(childNode, op, returnType, loc); + + return node; + } +} + +// +// This is the safe way to change the operator on an aggregate, as it +// does lots of error checking and fixing. Especially for establishing +// a function call's operation on it's set of parameters. Sequences +// of instructions are also aggregates, but they just directly set +// their operator to EOpSequence. +// +// Returns an aggregate node, which could be the one passed in if +// it was already an aggregate. +// +TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TType& type, TSourceLoc loc) +{ + TIntermAggregate* aggNode; + + // + // Make sure we have an aggregate. If not turn it into one. + // + if (node) { + aggNode = node->getAsAggregate(); + if (aggNode == nullptr || aggNode->getOp() != EOpNull) { + // + // Make an aggregate containing this node. + // + aggNode = new TIntermAggregate(); + aggNode->getSequence().push_back(node); + if (loc.line == 0) + loc = node->getLoc(); + } + } else + aggNode = new TIntermAggregate(); + + // + // Set the operator. + // + aggNode->setOperator(op); + if (loc.line != 0) + aggNode->setLoc(loc); + + aggNode->setType(type); + + return fold(aggNode); +} + +// +// Convert the node's type to the given type, as allowed by the operation involved: 'op'. +// For implicit conversions, 'op' is not the requested conversion, it is the explicit +// operation requiring the implicit conversion. +// +// Returns a node representing the conversion, which could be the same +// node passed in if no conversion was needed. +// +// Generally, this is focused on basic type conversion, not shape conversion. +// See addShapeConversion(). +// +// Return nullptr if a conversion can't be done. +// +TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TIntermTyped* node) const +{ + // + // Does the base type even allow the operation? + // + switch (node->getBasicType()) { + case EbtVoid: + return nullptr; + case EbtAtomicUint: + case EbtSampler: + // opaque types can be passed to functions + if (op == EOpFunction) + break; + + // HLSL can assign samplers directly (no constructor) + if (source == EShSourceHlsl && node->getBasicType() == EbtSampler) + break; + + // samplers can get assigned via a sampler constructor + // (well, not yet, but code in the rest of this function is ready for it) + if (node->getBasicType() == EbtSampler && op == EOpAssign && + node->getAsOperator() != nullptr && node->getAsOperator()->getOp() == EOpConstructTextureSampler) + break; + + // otherwise, opaque types can't even be operated on, let alone converted + return nullptr; + default: + break; + } + + // Otherwise, if types are identical, no problem + if (type == node->getType()) + return node; + + // If one's a structure, then no conversions. + if (type.isStruct() || node->isStruct()) + return nullptr; + + // If one's an array, then no conversions. + if (type.isArray() || node->getType().isArray()) + return nullptr; + + // Note: callers are responsible for other aspects of shape, + // like vector and matrix sizes. + + TBasicType promoteTo; + + switch (op) { + // + // Explicit conversions (unary operations) + // + case EOpConstructBool: + promoteTo = EbtBool; + break; + case EOpConstructFloat: + promoteTo = EbtFloat; + break; + case EOpConstructDouble: + promoteTo = EbtDouble; + break; +#ifdef AMD_EXTENSIONS + case EOpConstructFloat16: + promoteTo = EbtFloat16; + break; +#endif + case EOpConstructInt: + promoteTo = EbtInt; + break; + case EOpConstructUint: + promoteTo = EbtUint; + break; + case EOpConstructInt64: + promoteTo = EbtInt64; + break; + case EOpConstructUint64: + promoteTo = EbtUint64; + break; +#ifdef AMD_EXTENSIONS + case EOpConstructInt16: + promoteTo = EbtInt16; + break; + case EOpConstructUint16: + promoteTo = EbtUint16; + break; +#endif + + // + // List all the binary ops that can implicitly convert one operand to the other's type; + // This implements the 'policy' for implicit type conversion. + // + case EOpLessThan: + case EOpGreaterThan: + case EOpLessThanEqual: + case EOpGreaterThanEqual: + case EOpEqual: + case EOpNotEqual: + + case EOpAdd: + case EOpSub: + case EOpMul: + case EOpDiv: + case EOpMod: + + case EOpVectorTimesScalar: + case EOpVectorTimesMatrix: + case EOpMatrixTimesVector: + case EOpMatrixTimesScalar: + + case EOpAnd: + case EOpInclusiveOr: + case EOpExclusiveOr: + case EOpAndAssign: + case EOpInclusiveOrAssign: + case EOpExclusiveOrAssign: + case EOpLogicalNot: + case EOpLogicalAnd: + case EOpLogicalOr: + case EOpLogicalXor: + + case EOpFunctionCall: + case EOpReturn: + case EOpAssign: + case EOpAddAssign: + case EOpSubAssign: + case EOpMulAssign: + case EOpVectorTimesScalarAssign: + case EOpMatrixTimesScalarAssign: + case EOpDivAssign: + case EOpModAssign: + + case EOpAtan: + case EOpClamp: + case EOpCross: + case EOpDistance: + case EOpDot: + case EOpDst: + case EOpFaceForward: + case EOpFma: + case EOpFrexp: + case EOpLdexp: + case EOpMix: + case EOpLit: + case EOpMax: + case EOpMin: + case EOpModf: + case EOpPow: + case EOpReflect: + case EOpRefract: + case EOpSmoothStep: + case EOpStep: + + case EOpSequence: + case EOpConstructStruct: + + if (type.getBasicType() == node->getType().getBasicType()) + return node; + + if (canImplicitlyPromote(node->getType().getBasicType(), type.getBasicType(), op)) + promoteTo = type.getBasicType(); + else + return nullptr; + + break; + + // Shifts can have mixed types as long as they are integer, without converting. + // It's the left operand's type that determines the resulting type, so no issue + // with assign shift ops either. + case EOpLeftShift: + case EOpRightShift: + case EOpLeftShiftAssign: + case EOpRightShiftAssign: + if ((type.getBasicType() == EbtInt || + type.getBasicType() == EbtUint || +#ifdef AMD_EXTENSIONS + type.getBasicType() == EbtInt16 || + type.getBasicType() == EbtUint16 || +#endif + type.getBasicType() == EbtInt64 || + type.getBasicType() == EbtUint64) && + (node->getType().getBasicType() == EbtInt || + node->getType().getBasicType() == EbtUint || +#ifdef AMD_EXTENSIONS + node->getType().getBasicType() == EbtInt16 || + node->getType().getBasicType() == EbtUint16 || +#endif + node->getType().getBasicType() == EbtInt64 || + node->getType().getBasicType() == EbtUint64)) + + return node; + else if (source == EShSourceHlsl && node->getType().getBasicType() == EbtBool) { + promoteTo = type.getBasicType(); + break; + } else + return nullptr; + + default: + // default is to require a match; all exceptions should have case statements above + + if (type.getBasicType() == node->getType().getBasicType()) + return node; + else + return nullptr; + } + + if (node->getAsConstantUnion()) + return promoteConstantUnion(promoteTo, node->getAsConstantUnion()); + + // + // Add a new newNode for the conversion. + // + TIntermUnary* newNode = nullptr; + + TOperator newOp = EOpNull; + + // This is 'mechanism' here, it does any conversion told. The policy comes + // from the shader or the above code. + switch (promoteTo) { + case EbtDouble: + switch (node->getBasicType()) { + case EbtInt: newOp = EOpConvIntToDouble; break; + case EbtUint: newOp = EOpConvUintToDouble; break; + case EbtBool: newOp = EOpConvBoolToDouble; break; + case EbtFloat: newOp = EOpConvFloatToDouble; break; +#ifdef AMD_EXTENSIONS + case EbtFloat16: newOp = EOpConvFloat16ToDouble; break; +#endif + case EbtInt64: newOp = EOpConvInt64ToDouble; break; + case EbtUint64: newOp = EOpConvUint64ToDouble; break; +#ifdef AMD_EXTENSIONS + case EbtInt16: newOp = EOpConvInt16ToDouble; break; + case EbtUint16: newOp = EOpConvUint16ToDouble; break; +#endif + default: + return nullptr; + } + break; + case EbtFloat: + switch (node->getBasicType()) { + case EbtInt: newOp = EOpConvIntToFloat; break; + case EbtUint: newOp = EOpConvUintToFloat; break; + case EbtBool: newOp = EOpConvBoolToFloat; break; + case EbtDouble: newOp = EOpConvDoubleToFloat; break; +#ifdef AMD_EXTENSIONS + case EbtFloat16: newOp = EOpConvFloat16ToFloat; break; +#endif + case EbtInt64: newOp = EOpConvInt64ToFloat; break; + case EbtUint64: newOp = EOpConvUint64ToFloat; break; +#ifdef AMD_EXTENSIONS + case EbtInt16: newOp = EOpConvInt16ToFloat; break; + case EbtUint16: newOp = EOpConvUint16ToFloat; break; +#endif + default: + return nullptr; + } + break; +#ifdef AMD_EXTENSIONS + case EbtFloat16: + switch (node->getBasicType()) { + case EbtInt: newOp = EOpConvIntToFloat16; break; + case EbtUint: newOp = EOpConvUintToFloat16; break; + case EbtBool: newOp = EOpConvBoolToFloat16; break; + case EbtFloat: newOp = EOpConvFloatToFloat16; break; + case EbtDouble: newOp = EOpConvDoubleToFloat16; break; + case EbtInt64: newOp = EOpConvInt64ToFloat16; break; + case EbtUint64: newOp = EOpConvUint64ToFloat16; break; + case EbtInt16: newOp = EOpConvInt16ToFloat16; break; + case EbtUint16: newOp = EOpConvUint16ToFloat16; break; + default: + return nullptr; + } + break; +#endif + case EbtBool: + switch (node->getBasicType()) { + case EbtInt: newOp = EOpConvIntToBool; break; + case EbtUint: newOp = EOpConvUintToBool; break; + case EbtFloat: newOp = EOpConvFloatToBool; break; + case EbtDouble: newOp = EOpConvDoubleToBool; break; +#ifdef AMD_EXTENSIONS + case EbtFloat16: newOp = EOpConvFloat16ToBool; break; +#endif + case EbtInt64: newOp = EOpConvInt64ToBool; break; + case EbtUint64: newOp = EOpConvUint64ToBool; break; +#ifdef AMD_EXTENSIONS + case EbtInt16: newOp = EOpConvInt16ToBool; break; + case EbtUint16: newOp = EOpConvUint16ToBool; break; +#endif + default: + return nullptr; + } + break; + case EbtInt: + switch (node->getBasicType()) { + case EbtUint: newOp = EOpConvUintToInt; break; + case EbtBool: newOp = EOpConvBoolToInt; break; + case EbtFloat: newOp = EOpConvFloatToInt; break; + case EbtDouble: newOp = EOpConvDoubleToInt; break; +#ifdef AMD_EXTENSIONS + case EbtFloat16: newOp = EOpConvFloat16ToInt; break; +#endif + case EbtInt64: newOp = EOpConvInt64ToInt; break; + case EbtUint64: newOp = EOpConvUint64ToInt; break; +#ifdef AMD_EXTENSIONS + case EbtInt16: newOp = EOpConvInt16ToInt; break; + case EbtUint16: newOp = EOpConvUint16ToInt; break; +#endif + default: + return nullptr; + } + break; + case EbtUint: + switch (node->getBasicType()) { + case EbtInt: newOp = EOpConvIntToUint; break; + case EbtBool: newOp = EOpConvBoolToUint; break; + case EbtFloat: newOp = EOpConvFloatToUint; break; + case EbtDouble: newOp = EOpConvDoubleToUint; break; +#ifdef AMD_EXTENSIONS + case EbtFloat16: newOp = EOpConvFloat16ToUint; break; +#endif + case EbtInt64: newOp = EOpConvInt64ToUint; break; + case EbtUint64: newOp = EOpConvUint64ToUint; break; +#ifdef AMD_EXTENSIONS + case EbtInt16: newOp = EOpConvInt16ToUint; break; + case EbtUint16: newOp = EOpConvUint16ToUint; break; +#endif + default: + return nullptr; + } + break; + case EbtInt64: + switch (node->getBasicType()) { + case EbtInt: newOp = EOpConvIntToInt64; break; + case EbtUint: newOp = EOpConvUintToInt64; break; + case EbtBool: newOp = EOpConvBoolToInt64; break; + case EbtFloat: newOp = EOpConvFloatToInt64; break; + case EbtDouble: newOp = EOpConvDoubleToInt64; break; +#ifdef AMD_EXTENSIONS + case EbtFloat16: newOp = EOpConvFloat16ToInt64; break; +#endif + case EbtUint64: newOp = EOpConvUint64ToInt64; break; +#ifdef AMD_EXTENSIONS + case EbtInt16: newOp = EOpConvInt16ToInt64; break; + case EbtUint16: newOp = EOpConvUint16ToInt64; break; +#endif + default: + return nullptr; + } + break; + case EbtUint64: + switch (node->getBasicType()) { + case EbtInt: newOp = EOpConvIntToUint64; break; + case EbtUint: newOp = EOpConvUintToUint64; break; + case EbtBool: newOp = EOpConvBoolToUint64; break; + case EbtFloat: newOp = EOpConvFloatToUint64; break; + case EbtDouble: newOp = EOpConvDoubleToUint64; break; +#ifdef AMD_EXTENSIONS + case EbtFloat16: newOp = EOpConvFloat16ToUint64; break; +#endif + case EbtInt64: newOp = EOpConvInt64ToUint64; break; +#ifdef AMD_EXTENSIONS + case EbtInt16: newOp = EOpConvInt16ToUint64; break; + case EbtUint16: newOp = EOpConvUint16ToUint64; break; +#endif + default: + return nullptr; + } + break; +#ifdef AMD_EXTENSIONS + case EbtInt16: + switch (node->getBasicType()) { + case EbtInt: newOp = EOpConvIntToInt16; break; + case EbtUint: newOp = EOpConvUintToInt16; break; + case EbtBool: newOp = EOpConvBoolToInt16; break; + case EbtFloat: newOp = EOpConvFloatToInt16; break; + case EbtDouble: newOp = EOpConvDoubleToInt16; break; + case EbtFloat16: newOp = EOpConvFloat16ToInt16; break; + case EbtInt64: newOp = EOpConvInt64ToInt16; break; + case EbtUint64: newOp = EOpConvUint64ToInt16; break; + case EbtUint16: newOp = EOpConvUint16ToInt16; break; + default: + return nullptr; + } + break; + case EbtUint16: + switch (node->getBasicType()) { + case EbtInt: newOp = EOpConvIntToUint16; break; + case EbtUint: newOp = EOpConvUintToUint16; break; + case EbtBool: newOp = EOpConvBoolToUint16; break; + case EbtFloat: newOp = EOpConvFloatToUint16; break; + case EbtDouble: newOp = EOpConvDoubleToUint16; break; + case EbtFloat16: newOp = EOpConvFloat16ToUint16; break; + case EbtInt64: newOp = EOpConvInt64ToUint16; break; + case EbtUint64: newOp = EOpConvUint64ToUint16; break; + case EbtInt16: newOp = EOpConvInt16ToUint16; break; + default: + return nullptr; + } + break; +#endif + default: + return nullptr; + } + + TType newType(promoteTo, EvqTemporary, node->getVectorSize(), node->getMatrixCols(), node->getMatrixRows()); + newNode = addUnaryNode(newOp, node, node->getLoc(), newType); + + // TODO: it seems that some unary folding operations should occur here, but are not + + // Propagate specialization-constant-ness, if allowed + if (node->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*newNode)) + newNode->getWritableType().getQualifier().makeSpecConstant(); + + return newNode; +} + +// Convert the node's shape of type for the given type, as allowed by the +// operation involved: 'op'. This is for situations where there is only one +// direction to consider doing the shape conversion. +// +// This implements policy, it call addShapeConversion() for the mechanism. +// +// Generally, the AST represents allowed GLSL shapes, so this isn't needed +// for GLSL. Bad shapes are caught in conversion or promotion. +// +// Return 'node' if no conversion was done. Promotion handles final shape +// checking. +// +TIntermTyped* TIntermediate::addUniShapeConversion(TOperator op, const TType& type, TIntermTyped* node) +{ + // some source languages don't do this + switch (source) { + case EShSourceHlsl: + break; + case EShSourceGlsl: + default: + return node; + } + + // some operations don't do this + switch (op) { + case EOpFunctionCall: + case EOpReturn: + break; + + case EOpMulAssign: + // want to support vector *= scalar native ops in AST and lower, not smear, similarly for + // matrix *= scalar, etc. + + case EOpAddAssign: + case EOpSubAssign: + case EOpDivAssign: + case EOpAndAssign: + case EOpInclusiveOrAssign: + case EOpExclusiveOrAssign: + case EOpRightShiftAssign: + case EOpLeftShiftAssign: + if (node->getVectorSize() == 1) + return node; + break; + + case EOpAssign: + break; + + case EOpMix: + break; + + default: + return node; + } + + return addShapeConversion(type, node); +} + +// Convert the nodes' shapes to be compatible for the operation 'op'. +// +// This implements policy, it call addShapeConversion() for the mechanism. +// +// Generally, the AST represents allowed GLSL shapes, so this isn't needed +// for GLSL. Bad shapes are caught in conversion or promotion. +// +void TIntermediate::addBiShapeConversion(TOperator op, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode) +{ + // some source languages don't do this + switch (source) { + case EShSourceHlsl: + break; + case EShSourceGlsl: + default: + return; + } + + // some operations don't do this + // 'break' will mean attempt bidirectional conversion + switch (op) { + case EOpMulAssign: + case EOpAssign: + case EOpAddAssign: + case EOpSubAssign: + case EOpDivAssign: + case EOpAndAssign: + case EOpInclusiveOrAssign: + case EOpExclusiveOrAssign: + case EOpRightShiftAssign: + case EOpLeftShiftAssign: + // switch to unidirectional conversion (the lhs can't change) + rhsNode = addUniShapeConversion(op, lhsNode->getType(), rhsNode); + return; + + case EOpAdd: + case EOpSub: + case EOpMul: + case EOpDiv: + // want to support vector * scalar native ops in AST and lower, not smear, similarly for + // matrix * vector, etc. + if (lhsNode->getVectorSize() == 1 || rhsNode->getVectorSize() == 1) + return; + break; + + case EOpRightShift: + case EOpLeftShift: + // can natively support the right operand being a scalar and the left a vector, + // but not the reverse + if (rhsNode->getVectorSize() == 1) + return; + break; + + case EOpLessThan: + case EOpGreaterThan: + case EOpLessThanEqual: + case EOpGreaterThanEqual: + + case EOpEqual: + case EOpNotEqual: + + case EOpLogicalAnd: + case EOpLogicalOr: + case EOpLogicalXor: + + case EOpAnd: + case EOpInclusiveOr: + case EOpExclusiveOr: + + case EOpMix: + break; + + default: + return; + } + + // Do bidirectional conversions + if (lhsNode->getType().isScalarOrVec1() || rhsNode->getType().isScalarOrVec1()) { + if (lhsNode->getType().isScalarOrVec1()) + lhsNode = addShapeConversion(rhsNode->getType(), lhsNode); + else + rhsNode = addShapeConversion(lhsNode->getType(), rhsNode); + } + lhsNode = addShapeConversion(rhsNode->getType(), lhsNode); + rhsNode = addShapeConversion(lhsNode->getType(), rhsNode); +} + +// Convert the node's shape of type for the given type. It's not necessarily +// an error if they are different and not converted, as some operations accept +// mixed types. Promotion will do final shape checking. +// +// If there is a chance of two nodes, with conversions possible in each direction, +// the policy for what to ask for must be in the caller; this will do what is asked. +// +// Return 'node' if no conversion was done. Promotion handles final shape +// checking. +// +TIntermTyped* TIntermediate::addShapeConversion(const TType& type, TIntermTyped* node) +{ + // no conversion needed + if (node->getType() == type) + return node; + + // structures and arrays don't change shape, either to or from + if (node->getType().isStruct() || node->getType().isArray() || + type.isStruct() || type.isArray()) + return node; + + // The new node that handles the conversion + TOperator constructorOp = mapTypeToConstructorOp(type); + + // HLSL has custom semantics for scalar->mat shape conversions. + if (source == EShSourceHlsl) { + if (node->getType().isScalarOrVec1() && type.isMatrix()) { + + // HLSL semantics: the scalar (or vec1) is replicated to every component of the matrix. Left to its + // own devices, the constructor from a scalar would populate the diagonal. This forces replication + // to every matrix element. + + // Note that if the node is complex (e.g, a function call), we don't want to duplicate it here + // repeatedly, so we copy it to a temp, then use the temp. + const int matSize = type.getMatrixRows() * type.getMatrixCols(); + TIntermAggregate* rhsAggregate = new TIntermAggregate(); + + const bool isSimple = (node->getAsSymbolNode() != nullptr) || (node->getAsConstantUnion() != nullptr); + + if (!isSimple) { + assert(0); // TODO: use node replicator service when available. + } + + for (int x=0; xgetSequence().push_back(node); + + return setAggregateOperator(rhsAggregate, constructorOp, type, node->getLoc()); + } + } + + // scalar -> vector or vec1 -> vector or + // vector -> scalar or + // bigger vector -> smaller vector + if ((node->getType().isScalarOrVec1() && type.isVector()) || + (node->getType().isVector() && type.isScalar()) || + (node->isVector() && type.isVector() && node->getVectorSize() > type.getVectorSize())) + return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc()); + + return node; +} + +// +// See if the 'from' type is allowed to be implicitly converted to the +// 'to' type. This is not about vector/array/struct, only about basic type. +// +bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperator op) const +{ + if (profile == EEsProfile || version == 110) + return false; + + if (from == to) + return true; + + // TODO: Move more policies into language-specific handlers. + // Some languages allow more general (or potentially, more specific) conversions under some conditions. + if (source == EShSourceHlsl) { + const bool fromConvertable = (from == EbtFloat || from == EbtDouble || from == EbtInt || from == EbtUint || from == EbtBool); + const bool toConvertable = (to == EbtFloat || to == EbtDouble || to == EbtInt || to == EbtUint || to == EbtBool); + + if (fromConvertable && toConvertable) { + switch (op) { + case EOpAndAssign: // assignments can perform arbitrary conversions + case EOpInclusiveOrAssign: // ... + case EOpExclusiveOrAssign: // ... + case EOpAssign: // ... + case EOpAddAssign: // ... + case EOpSubAssign: // ... + case EOpMulAssign: // ... + case EOpVectorTimesScalarAssign: // ... + case EOpMatrixTimesScalarAssign: // ... + case EOpDivAssign: // ... + case EOpModAssign: // ... + case EOpReturn: // function returns can also perform arbitrary conversions + case EOpFunctionCall: // conversion of a calling parameter + case EOpLogicalNot: + case EOpLogicalAnd: + case EOpLogicalOr: + case EOpLogicalXor: + case EOpConstructStruct: + return true; + default: + break; + } + } + } + + switch (to) { + case EbtDouble: + switch (from) { + case EbtInt: + case EbtUint: + case EbtInt64: + case EbtUint64: +#ifdef AMD_EXTENSIONS + case EbtInt16: + case EbtUint16: +#endif + case EbtFloat: + case EbtDouble: +#ifdef AMD_EXTENSIONS + case EbtFloat16: +#endif + return true; + default: + return false; + } + case EbtFloat: + switch (from) { + case EbtInt: + case EbtUint: +#ifdef AMD_EXTENSIONS + case EbtInt16: + case EbtUint16: +#endif + case EbtFloat: +#ifdef AMD_EXTENSIONS + case EbtFloat16: +#endif + return true; + case EbtBool: + return (source == EShSourceHlsl); + default: + return false; + } + case EbtUint: + switch (from) { + case EbtInt: + return version >= 400 || (source == EShSourceHlsl); + case EbtUint: +#ifdef AMD_EXTENSIONS + case EbtInt16: + case EbtUint16: +#endif + return true; + case EbtBool: + return (source == EShSourceHlsl); + default: + return false; + } + case EbtInt: + switch (from) { + case EbtInt: +#ifdef AMD_EXTENSIONS + case EbtInt16: +#endif + return true; + case EbtBool: + return (source == EShSourceHlsl); + default: + return false; + } + case EbtUint64: + switch (from) { + case EbtInt: + case EbtUint: + case EbtInt64: + case EbtUint64: +#ifdef AMD_EXTENSIONS + case EbtInt16: + case EbtUint16: +#endif + return true; + default: + return false; + } + case EbtInt64: + switch (from) { + case EbtInt: + case EbtInt64: +#ifdef AMD_EXTENSIONS + case EbtInt16: +#endif + return true; + default: + return false; + } +#ifdef AMD_EXTENSIONS + case EbtFloat16: + switch (from) { + case EbtInt16: + case EbtUint16: + case EbtFloat16: + return true; + default: + return false; + } + case EbtUint16: + switch (from) { + case EbtInt16: + case EbtUint16: + return true; + default: + return false; + } +#endif + default: + return false; + } +} + +// +// Given a type, find what operation would fully construct it. +// +TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const +{ + TOperator op = EOpNull; + + switch (type.getBasicType()) { + case EbtStruct: + op = EOpConstructStruct; + break; + case EbtSampler: + if (type.getSampler().combined) + op = EOpConstructTextureSampler; + break; + case EbtFloat: + if (type.isMatrix()) { + switch (type.getMatrixCols()) { + case 2: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructMat2x2; break; + case 3: op = EOpConstructMat2x3; break; + case 4: op = EOpConstructMat2x4; break; + default: break; // some compilers want this + } + break; + case 3: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructMat3x2; break; + case 3: op = EOpConstructMat3x3; break; + case 4: op = EOpConstructMat3x4; break; + default: break; // some compilers want this + } + break; + case 4: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructMat4x2; break; + case 3: op = EOpConstructMat4x3; break; + case 4: op = EOpConstructMat4x4; break; + default: break; // some compilers want this + } + break; + default: break; // some compilers want this + } + } else { + switch(type.getVectorSize()) { + case 1: op = EOpConstructFloat; break; + case 2: op = EOpConstructVec2; break; + case 3: op = EOpConstructVec3; break; + case 4: op = EOpConstructVec4; break; + default: break; // some compilers want this + } + } + break; + case EbtDouble: + if (type.getMatrixCols()) { + switch (type.getMatrixCols()) { + case 2: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructDMat2x2; break; + case 3: op = EOpConstructDMat2x3; break; + case 4: op = EOpConstructDMat2x4; break; + default: break; // some compilers want this + } + break; + case 3: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructDMat3x2; break; + case 3: op = EOpConstructDMat3x3; break; + case 4: op = EOpConstructDMat3x4; break; + default: break; // some compilers want this + } + break; + case 4: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructDMat4x2; break; + case 3: op = EOpConstructDMat4x3; break; + case 4: op = EOpConstructDMat4x4; break; + default: break; // some compilers want this + } + break; + } + } else { + switch(type.getVectorSize()) { + case 1: op = EOpConstructDouble; break; + case 2: op = EOpConstructDVec2; break; + case 3: op = EOpConstructDVec3; break; + case 4: op = EOpConstructDVec4; break; + default: break; // some compilers want this + } + } + break; +#ifdef AMD_EXTENSIONS + case EbtFloat16: + if (type.getMatrixCols()) { + switch (type.getMatrixCols()) { + case 2: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructF16Mat2x2; break; + case 3: op = EOpConstructF16Mat2x3; break; + case 4: op = EOpConstructF16Mat2x4; break; + default: break; // some compilers want this + } + break; + case 3: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructF16Mat3x2; break; + case 3: op = EOpConstructF16Mat3x3; break; + case 4: op = EOpConstructF16Mat3x4; break; + default: break; // some compilers want this + } + break; + case 4: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructF16Mat4x2; break; + case 3: op = EOpConstructF16Mat4x3; break; + case 4: op = EOpConstructF16Mat4x4; break; + default: break; // some compilers want this + } + break; + } + } + else { + switch (type.getVectorSize()) { + case 1: op = EOpConstructFloat16; break; + case 2: op = EOpConstructF16Vec2; break; + case 3: op = EOpConstructF16Vec3; break; + case 4: op = EOpConstructF16Vec4; break; + default: break; // some compilers want this + } + } + break; +#endif + case EbtInt: + if (type.getMatrixCols()) { + switch (type.getMatrixCols()) { + case 2: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructIMat2x2; break; + case 3: op = EOpConstructIMat2x3; break; + case 4: op = EOpConstructIMat2x4; break; + default: break; // some compilers want this + } + break; + case 3: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructIMat3x2; break; + case 3: op = EOpConstructIMat3x3; break; + case 4: op = EOpConstructIMat3x4; break; + default: break; // some compilers want this + } + break; + case 4: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructIMat4x2; break; + case 3: op = EOpConstructIMat4x3; break; + case 4: op = EOpConstructIMat4x4; break; + default: break; // some compilers want this + } + break; + } + } else { + switch(type.getVectorSize()) { + case 1: op = EOpConstructInt; break; + case 2: op = EOpConstructIVec2; break; + case 3: op = EOpConstructIVec3; break; + case 4: op = EOpConstructIVec4; break; + default: break; // some compilers want this + } + } + break; + case EbtUint: + if (type.getMatrixCols()) { + switch (type.getMatrixCols()) { + case 2: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructUMat2x2; break; + case 3: op = EOpConstructUMat2x3; break; + case 4: op = EOpConstructUMat2x4; break; + default: break; // some compilers want this + } + break; + case 3: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructUMat3x2; break; + case 3: op = EOpConstructUMat3x3; break; + case 4: op = EOpConstructUMat3x4; break; + default: break; // some compilers want this + } + break; + case 4: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructUMat4x2; break; + case 3: op = EOpConstructUMat4x3; break; + case 4: op = EOpConstructUMat4x4; break; + default: break; // some compilers want this + } + break; + } + } else { + switch(type.getVectorSize()) { + case 1: op = EOpConstructUint; break; + case 2: op = EOpConstructUVec2; break; + case 3: op = EOpConstructUVec3; break; + case 4: op = EOpConstructUVec4; break; + default: break; // some compilers want this + } + } + break; + case EbtInt64: + switch(type.getVectorSize()) { + case 1: op = EOpConstructInt64; break; + case 2: op = EOpConstructI64Vec2; break; + case 3: op = EOpConstructI64Vec3; break; + case 4: op = EOpConstructI64Vec4; break; + default: break; // some compilers want this + } + break; + case EbtUint64: + switch(type.getVectorSize()) { + case 1: op = EOpConstructUint64; break; + case 2: op = EOpConstructU64Vec2; break; + case 3: op = EOpConstructU64Vec3; break; + case 4: op = EOpConstructU64Vec4; break; + default: break; // some compilers want this + } + break; +#ifdef AMD_EXTENSIONS + case EbtInt16: + switch(type.getVectorSize()) { + case 1: op = EOpConstructInt16; break; + case 2: op = EOpConstructI16Vec2; break; + case 3: op = EOpConstructI16Vec3; break; + case 4: op = EOpConstructI16Vec4; break; + default: break; // some compilers want this + } + break; + case EbtUint16: + switch(type.getVectorSize()) { + case 1: op = EOpConstructUint16; break; + case 2: op = EOpConstructU16Vec2; break; + case 3: op = EOpConstructU16Vec3; break; + case 4: op = EOpConstructU16Vec4; break; + default: break; // some compilers want this + } + break; +#endif + case EbtBool: + if (type.getMatrixCols()) { + switch (type.getMatrixCols()) { + case 2: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructBMat2x2; break; + case 3: op = EOpConstructBMat2x3; break; + case 4: op = EOpConstructBMat2x4; break; + default: break; // some compilers want this + } + break; + case 3: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructBMat3x2; break; + case 3: op = EOpConstructBMat3x3; break; + case 4: op = EOpConstructBMat3x4; break; + default: break; // some compilers want this + } + break; + case 4: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructBMat4x2; break; + case 3: op = EOpConstructBMat4x3; break; + case 4: op = EOpConstructBMat4x4; break; + default: break; // some compilers want this + } + break; + } + } else { + switch(type.getVectorSize()) { + case 1: op = EOpConstructBool; break; + case 2: op = EOpConstructBVec2; break; + case 3: op = EOpConstructBVec3; break; + case 4: op = EOpConstructBVec4; break; + default: break; // some compilers want this + } + } + break; + default: + break; + } + + return op; +} + +// +// Safe way to combine two nodes into an aggregate. Works with null pointers, +// a node that's not a aggregate yet, etc. +// +// Returns the resulting aggregate, unless nullptr was passed in for +// both existing nodes. +// +TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right) +{ + if (left == nullptr && right == nullptr) + return nullptr; + + TIntermAggregate* aggNode = nullptr; + if (left != nullptr) + aggNode = left->getAsAggregate(); + if (aggNode == nullptr || aggNode->getOp() != EOpNull) { + aggNode = new TIntermAggregate; + if (left != nullptr) + aggNode->getSequence().push_back(left); + } + + if (right != nullptr) + aggNode->getSequence().push_back(right); + + return aggNode; +} + +TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc& loc) +{ + TIntermAggregate* aggNode = growAggregate(left, right); + if (aggNode) + aggNode->setLoc(loc); + + return aggNode; +} + +// +// Turn an existing node into an aggregate. +// +// Returns an aggregate, unless nullptr was passed in for the existing node. +// +TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node) +{ + if (node == nullptr) + return nullptr; + + TIntermAggregate* aggNode = new TIntermAggregate; + aggNode->getSequence().push_back(node); + aggNode->setLoc(node->getLoc()); + + return aggNode; +} + +TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, const TSourceLoc& loc) +{ + if (node == nullptr) + return nullptr; + + TIntermAggregate* aggNode = new TIntermAggregate; + aggNode->getSequence().push_back(node); + aggNode->setLoc(loc); + + return aggNode; +} + +// +// Make an aggregate with an empty sequence. +// +TIntermAggregate* TIntermediate::makeAggregate(const TSourceLoc& loc) +{ + TIntermAggregate* aggNode = new TIntermAggregate; + aggNode->setLoc(loc); + + return aggNode; +} + +// +// For "if" test nodes. There are three children; a condition, +// a true path, and a false path. The two paths are in the +// nodePair. +// +// Returns the selection node created. +// +TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc& loc, TSelectionControl control) +{ + // + // Don't prune the false path for compile-time constants; it's needed + // for static access analysis. + // + + TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2); + node->setLoc(loc); + node->setSelectionControl(control); + + return node; +} + +TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc& loc) +{ + // However, the lowest precedence operators of the sequence operator ( , ) and the assignment operators + // ... are not included in the operators that can create a constant expression. + // + // if (left->getType().getQualifier().storage == EvqConst && + // right->getType().getQualifier().storage == EvqConst) { + + // return right; + //} + + TIntermTyped *commaAggregate = growAggregate(left, right, loc); + commaAggregate->getAsAggregate()->setOperator(EOpComma); + commaAggregate->setType(right->getType()); + commaAggregate->getWritableType().getQualifier().makeTemporary(); + + return commaAggregate; +} + +TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type, const TString* name, const TSourceLoc& loc) +{ + TIntermMethod* method = new TIntermMethod(object, type, *name); + method->setLoc(loc); + + return method; +} + +// +// For "?:" test nodes. There are three children; a condition, +// a true path, and a false path. The two paths are specified +// as separate parameters. For vector 'cond', the true and false +// are not paths, but vectors to mix. +// +// Specialization constant operations include +// - The ternary operator ( ? : ) +// +// Returns the selection node created, or nullptr if one could not be. +// +TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc& loc, TSelectionControl control) +{ + // If it's void, go to the if-then-else selection() + if (trueBlock->getBasicType() == EbtVoid && falseBlock->getBasicType() == EbtVoid) { + TIntermNodePair pair = { trueBlock, falseBlock }; + return addSelection(cond, pair, loc, control); + } + + // + // Get compatible types. + // + TIntermTyped* child = addConversion(EOpSequence, trueBlock->getType(), falseBlock); + if (child) + falseBlock = child; + else { + child = addConversion(EOpSequence, falseBlock->getType(), trueBlock); + if (child) + trueBlock = child; + else + return nullptr; + } + + // Handle a vector condition as a mix + if (!cond->getType().isScalarOrVec1()) { + TType targetVectorType(trueBlock->getType().getBasicType(), EvqTemporary, + cond->getType().getVectorSize()); + // smear true/false operands as needed + trueBlock = addUniShapeConversion(EOpMix, targetVectorType, trueBlock); + falseBlock = addUniShapeConversion(EOpMix, targetVectorType, falseBlock); + + // After conversion, types have to match. + if (falseBlock->getType() != trueBlock->getType()) + return nullptr; + + // make the mix operation + TIntermAggregate* mix = makeAggregate(loc); + mix = growAggregate(mix, falseBlock); + mix = growAggregate(mix, trueBlock); + mix = growAggregate(mix, cond); + mix->setType(targetVectorType); + mix->setOp(EOpMix); + + return mix; + } + + // Now have a scalar condition... + + // Convert true and false expressions to matching types + addBiShapeConversion(EOpMix, trueBlock, falseBlock); + + // After conversion, types have to match. + if (falseBlock->getType() != trueBlock->getType()) + return nullptr; + + // Eliminate the selection when the condition is a scalar and all operands are constant. + if (cond->getAsConstantUnion() && trueBlock->getAsConstantUnion() && falseBlock->getAsConstantUnion()) { + if (cond->getAsConstantUnion()->getConstArray()[0].getBConst()) + return trueBlock; + else + return falseBlock; + } + + // + // Make a selection node. + // + TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType()); + node->setLoc(loc); + node->getQualifier().precision = std::max(trueBlock->getQualifier().precision, falseBlock->getQualifier().precision); + + if ((cond->getQualifier().isConstant() && specConstantPropagates(*trueBlock, *falseBlock)) || + (cond->getQualifier().isSpecConstant() && trueBlock->getQualifier().isConstant() && + falseBlock->getQualifier().isConstant())) + node->getQualifier().makeSpecConstant(); + else + node->getQualifier().makeTemporary(); + + return node; +} + +// +// Constant terminal nodes. Has a union that contains bool, float or int constants +// +// Returns the constant union node created. +// + +TIntermConstantUnion* TIntermediate::addConstantUnion(const TConstUnionArray& unionArray, const TType& t, const TSourceLoc& loc, bool literal) const +{ + TIntermConstantUnion* node = new TIntermConstantUnion(unionArray, t); + node->getQualifier().storage = EvqConst; + node->setLoc(loc); + if (literal) + node->setLiteral(); + + return node; +} + +TIntermConstantUnion* TIntermediate::addConstantUnion(int i, const TSourceLoc& loc, bool literal) const +{ + TConstUnionArray unionArray(1); + unionArray[0].setIConst(i); + + return addConstantUnion(unionArray, TType(EbtInt, EvqConst), loc, literal); +} + +TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned int u, const TSourceLoc& loc, bool literal) const +{ + TConstUnionArray unionArray(1); + unionArray[0].setUConst(u); + + return addConstantUnion(unionArray, TType(EbtUint, EvqConst), loc, literal); +} + +TIntermConstantUnion* TIntermediate::addConstantUnion(long long i64, const TSourceLoc& loc, bool literal) const +{ + TConstUnionArray unionArray(1); + unionArray[0].setI64Const(i64); + + return addConstantUnion(unionArray, TType(EbtInt64, EvqConst), loc, literal); +} + +TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned long long u64, const TSourceLoc& loc, bool literal) const +{ + TConstUnionArray unionArray(1); + unionArray[0].setU64Const(u64); + + return addConstantUnion(unionArray, TType(EbtUint64, EvqConst), loc, literal); +} + +#ifdef AMD_EXTENSIONS +TIntermConstantUnion* TIntermediate::addConstantUnion(short i16, const TSourceLoc& loc, bool literal) const +{ + TConstUnionArray unionArray(1); + unionArray[0].setIConst(i16); + + return addConstantUnion(unionArray, TType(EbtInt16, EvqConst), loc, literal); +} + +TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned short u16, const TSourceLoc& loc, bool literal) const +{ + TConstUnionArray unionArray(1); + unionArray[0].setUConst(u16); + + return addConstantUnion(unionArray, TType(EbtUint16, EvqConst), loc, literal); +} +#endif + +TIntermConstantUnion* TIntermediate::addConstantUnion(bool b, const TSourceLoc& loc, bool literal) const +{ + TConstUnionArray unionArray(1); + unionArray[0].setBConst(b); + + return addConstantUnion(unionArray, TType(EbtBool, EvqConst), loc, literal); +} + +TIntermConstantUnion* TIntermediate::addConstantUnion(double d, TBasicType baseType, const TSourceLoc& loc, bool literal) const +{ +#ifdef AMD_EXTENSIONS + assert(baseType == EbtFloat || baseType == EbtDouble || baseType == EbtFloat16); +#else + assert(baseType == EbtFloat || baseType == EbtDouble); +#endif + + TConstUnionArray unionArray(1); + unionArray[0].setDConst(d); + + return addConstantUnion(unionArray, TType(baseType, EvqConst), loc, literal); +} + +TIntermConstantUnion* TIntermediate::addConstantUnion(const TString* s, const TSourceLoc& loc, bool literal) const +{ + TConstUnionArray unionArray(1); + unionArray[0].setSConst(s); + + return addConstantUnion(unionArray, TType(EbtString, EvqConst), loc, literal); +} + +// Put vector swizzle selectors onto the given sequence +void TIntermediate::pushSelector(TIntermSequence& sequence, const TVectorSelector& selector, const TSourceLoc& loc) +{ + TIntermConstantUnion* constIntNode = addConstantUnion(selector, loc); + sequence.push_back(constIntNode); +} + +// Put matrix swizzle selectors onto the given sequence +void TIntermediate::pushSelector(TIntermSequence& sequence, const TMatrixSelector& selector, const TSourceLoc& loc) +{ + TIntermConstantUnion* constIntNode = addConstantUnion(selector.coord1, loc); + sequence.push_back(constIntNode); + constIntNode = addConstantUnion(selector.coord2, loc); + sequence.push_back(constIntNode); +} + +// Make an aggregate node that has a sequence of all selectors. +template TIntermTyped* TIntermediate::addSwizzle(TSwizzleSelectors& selector, const TSourceLoc& loc); +template TIntermTyped* TIntermediate::addSwizzle(TSwizzleSelectors& selector, const TSourceLoc& loc); +template +TIntermTyped* TIntermediate::addSwizzle(TSwizzleSelectors& selector, const TSourceLoc& loc) +{ + TIntermAggregate* node = new TIntermAggregate(EOpSequence); + + node->setLoc(loc); + TIntermSequence &sequenceVector = node->getSequence(); + + for (int i = 0; i < selector.size(); i++) + pushSelector(sequenceVector, selector[i], loc); + + return node; +} + +// +// Follow the left branches down to the root of an l-value +// expression (just "." and []). +// +// Return the base of the l-value (where following indexing quits working). +// Return nullptr if a chain following dereferences cannot be followed. +// +// 'swizzleOkay' says whether or not it is okay to consider a swizzle +// a valid part of the dereference chain. +// +const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay) +{ + do { + const TIntermBinary* binary = node->getAsBinaryNode(); + if (binary == nullptr) + return node; + TOperator op = binary->getOp(); + if (op != EOpIndexDirect && op != EOpIndexIndirect && op != EOpIndexDirectStruct && op != EOpVectorSwizzle && op != EOpMatrixSwizzle) + return nullptr; + if (! swizzleOkay) { + if (op == EOpVectorSwizzle || op == EOpMatrixSwizzle) + return nullptr; + if ((op == EOpIndexDirect || op == EOpIndexIndirect) && + (binary->getLeft()->getType().isVector() || binary->getLeft()->getType().isScalar()) && + ! binary->getLeft()->getType().isArray()) + return nullptr; + } + node = node->getAsBinaryNode()->getLeft(); + } while (true); +} + +// +// Create while and do-while loop nodes. +// +TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc, TLoopControl control) +{ + TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst); + node->setLoc(loc); + node->setLoopControl(control); + + return node; +} + +// +// Create a for-loop sequence. +// +TIntermAggregate* TIntermediate::addForLoop(TIntermNode* body, TIntermNode* initializer, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc, TLoopControl control) +{ + TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst); + node->setLoc(loc); + node->setLoopControl(control); + + // make a sequence of the initializer and statement, but try to reuse the + // aggregate already created for whatever is in the initializer, if there is one + TIntermAggregate* loopSequence = (initializer == nullptr || + initializer->getAsAggregate() == nullptr) ? makeAggregate(initializer, loc) + : initializer->getAsAggregate(); + if (loopSequence != nullptr && loopSequence->getOp() == EOpSequence) + loopSequence->setOp(EOpNull); + loopSequence = growAggregate(loopSequence, node); + loopSequence->setOperator(EOpSequence); + + return loopSequence; +} + +// +// Add branches. +// +TIntermBranch* TIntermediate::addBranch(TOperator branchOp, const TSourceLoc& loc) +{ + return addBranch(branchOp, nullptr, loc); +} + +TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, const TSourceLoc& loc) +{ + TIntermBranch* node = new TIntermBranch(branchOp, expression); + node->setLoc(loc); + + return node; +} + +// +// This is to be executed after the final root is put on top by the parsing +// process. +// +bool TIntermediate::postProcess(TIntermNode* root, EShLanguage /*language*/) +{ + if (root == nullptr) + return true; + + // Finish off the top-level sequence + TIntermAggregate* aggRoot = root->getAsAggregate(); + if (aggRoot && aggRoot->getOp() == EOpNull) + aggRoot->setOperator(EOpSequence); + + // Propagate 'noContraction' label in backward from 'precise' variables. + glslang::PropagateNoContraction(*this); + + switch (textureSamplerTransformMode) { + case EShTexSampTransKeep: + break; + case EShTexSampTransUpgradeTextureRemoveSampler: + performTextureUpgradeAndSamplerRemovalTransformation(root); + break; + } + + return true; +} + +void TIntermediate::addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage language, TSymbolTable& symbolTable) +{ + // Add top-level nodes for declarations that must be checked cross + // compilation unit by a linker, yet might not have been referenced + // by the AST. + // + // Almost entirely, translation of symbols is driven by what's present + // in the AST traversal, not by translating the symbol table. + // + // However, there are some special cases: + // - From the specification: "Special built-in inputs gl_VertexID and + // gl_InstanceID are also considered active vertex attributes." + // - Linker-based type mismatch error reporting needs to see all + // uniforms/ins/outs variables and blocks. + // - ftransform() can make gl_Vertex and gl_ModelViewProjectionMatrix active. + // + + // if (ftransformUsed) { + // TODO: 1.1 lowering functionality: track ftransform() usage + // addSymbolLinkageNode(root, symbolTable, "gl_Vertex"); + // addSymbolLinkageNode(root, symbolTable, "gl_ModelViewProjectionMatrix"); + //} + + if (language == EShLangVertex) { + // the names won't be found in the symbol table unless the versions are right, + // so version logic does not need to be repeated here + addSymbolLinkageNode(linkage, symbolTable, "gl_VertexID"); + addSymbolLinkageNode(linkage, symbolTable, "gl_InstanceID"); + } + + // Add a child to the root node for the linker objects + linkage->setOperator(EOpLinkerObjects); + treeRoot = growAggregate(treeRoot, linkage); +} + +// +// Add the given name or symbol to the list of nodes at the end of the tree used +// for link-time checking and external linkage. +// + +void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable& symbolTable, const TString& name) +{ + TSymbol* symbol = symbolTable.find(name); + if (symbol) + addSymbolLinkageNode(linkage, *symbol->getAsVariable()); +} + +void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol& symbol) +{ + const TVariable* variable = symbol.getAsVariable(); + if (! variable) { + // This must be a member of an anonymous block, and we need to add the whole block + const TAnonMember* anon = symbol.getAsAnonMember(); + variable = &anon->getAnonContainer(); + } + TIntermSymbol* node = addSymbol(*variable); + linkage = growAggregate(linkage, node); +} + +// +// Add a caller->callee relationship to the call graph. +// Assumes the strings are unique per signature. +// +void TIntermediate::addToCallGraph(TInfoSink& /*infoSink*/, const TString& caller, const TString& callee) +{ + // Duplicates are okay, but faster to not keep them, and they come grouped by caller, + // as long as new ones are push on the same end we check on for duplicates + for (TGraph::const_iterator call = callGraph.begin(); call != callGraph.end(); ++call) { + if (call->caller != caller) + break; + if (call->callee == callee) + return; + } + + callGraph.push_front(TCall(caller, callee)); +} + +// +// This deletes the tree. +// +void TIntermediate::removeTree() +{ + if (treeRoot) + RemoveAllTreeNodes(treeRoot); +} + +// +// Implement the part of KHR_vulkan_glsl that lists the set of operations +// that can result in a specialization constant operation. +// +// "5.x Specialization Constant Operations" +// +// Only some operations discussed in this section may be applied to a +// specialization constant and still yield a result that is as +// specialization constant. The operations allowed are listed below. +// When a specialization constant is operated on with one of these +// operators and with another constant or specialization constant, the +// result is implicitly a specialization constant. +// +// - int(), uint(), and bool() constructors for type conversions +// from any of the following types to any of the following types: +// * int +// * uint +// * bool +// - vector versions of the above conversion constructors +// - allowed implicit conversions of the above +// - swizzles (e.g., foo.yx) +// - The following when applied to integer or unsigned integer types: +// * unary negative ( - ) +// * binary operations ( + , - , * , / , % ) +// * shift ( <<, >> ) +// * bitwise operations ( & , | , ^ ) +// - The following when applied to integer or unsigned integer scalar types: +// * comparison ( == , != , > , >= , < , <= ) +// - The following when applied to the Boolean scalar type: +// * not ( ! ) +// * logical operations ( && , || , ^^ ) +// * comparison ( == , != )" +// +// This function just handles binary and unary nodes. Construction +// rules are handled in construction paths that are not covered by the unary +// and binary paths, while required conversions will still show up here +// as unary converters in the from a construction operator. +// +bool TIntermediate::isSpecializationOperation(const TIntermOperator& node) const +{ + // The operations resulting in floating point are quite limited + // (However, some floating-point operations result in bool, like ">", + // so are handled later.) + if (node.getType().isFloatingDomain()) { + switch (node.getOp()) { + case EOpIndexDirect: + case EOpIndexIndirect: + case EOpIndexDirectStruct: + case EOpVectorSwizzle: + case EOpConvFloatToDouble: + case EOpConvDoubleToFloat: +#ifdef AMD_EXTENSIONS + case EOpConvFloat16ToFloat: + case EOpConvFloatToFloat16: + case EOpConvFloat16ToDouble: + case EOpConvDoubleToFloat16: +#endif + return true; + default: + return false; + } + } + + // Check for floating-point arguments + if (const TIntermBinary* bin = node.getAsBinaryNode()) + if (bin->getLeft() ->getType().isFloatingDomain() || + bin->getRight()->getType().isFloatingDomain()) + return false; + + // So, for now, we can assume everything left is non-floating-point... + + // Now check for integer/bool-based operations + switch (node.getOp()) { + + // dereference/swizzle + case EOpIndexDirect: + case EOpIndexIndirect: + case EOpIndexDirectStruct: + case EOpVectorSwizzle: + + // conversion constructors + case EOpConvIntToBool: + case EOpConvUintToBool: + case EOpConvUintToInt: + case EOpConvBoolToInt: + case EOpConvIntToUint: + case EOpConvBoolToUint: + case EOpConvInt64ToBool: + case EOpConvBoolToInt64: + case EOpConvUint64ToBool: + case EOpConvBoolToUint64: + case EOpConvInt64ToInt: + case EOpConvIntToInt64: + case EOpConvUint64ToUint: + case EOpConvUintToUint64: + case EOpConvInt64ToUint64: + case EOpConvUint64ToInt64: + case EOpConvInt64ToUint: + case EOpConvUintToInt64: + case EOpConvUint64ToInt: + case EOpConvIntToUint64: +#ifdef AMD_EXTENSIONS + case EOpConvInt16ToBool: + case EOpConvBoolToInt16: + case EOpConvInt16ToInt: + case EOpConvIntToInt16: + case EOpConvInt16ToUint: + case EOpConvUintToInt16: + case EOpConvInt16ToInt64: + case EOpConvInt64ToInt16: + case EOpConvInt16ToUint64: + case EOpConvUint64ToInt16: + case EOpConvUint16ToBool: + case EOpConvBoolToUint16: + case EOpConvUint16ToInt: + case EOpConvIntToUint16: + case EOpConvUint16ToUint: + case EOpConvUintToUint16: + case EOpConvUint16ToInt64: + case EOpConvInt64ToUint16: + case EOpConvUint16ToUint64: + case EOpConvUint64ToUint16: + case EOpConvInt16ToUint16: + case EOpConvUint16ToInt16: +#endif + + // unary operations + case EOpNegative: + case EOpLogicalNot: + case EOpBitwiseNot: + + // binary operations + case EOpAdd: + case EOpSub: + case EOpMul: + case EOpVectorTimesScalar: + case EOpDiv: + case EOpMod: + case EOpRightShift: + case EOpLeftShift: + case EOpAnd: + case EOpInclusiveOr: + case EOpExclusiveOr: + case EOpLogicalOr: + case EOpLogicalXor: + case EOpLogicalAnd: + case EOpEqual: + case EOpNotEqual: + case EOpLessThan: + case EOpGreaterThan: + case EOpLessThanEqual: + case EOpGreaterThanEqual: + return true; + default: + return false; + } +} + +//////////////////////////////////////////////////////////////// +// +// Member functions of the nodes used for building the tree. +// +//////////////////////////////////////////////////////////////// + +// +// Say whether or not an operation node changes the value of a variable. +// +// Returns true if state is modified. +// +bool TIntermOperator::modifiesState() const +{ + switch (op) { + case EOpPostIncrement: + case EOpPostDecrement: + case EOpPreIncrement: + case EOpPreDecrement: + case EOpAssign: + case EOpAddAssign: + case EOpSubAssign: + case EOpMulAssign: + case EOpVectorTimesMatrixAssign: + case EOpVectorTimesScalarAssign: + case EOpMatrixTimesScalarAssign: + case EOpMatrixTimesMatrixAssign: + case EOpDivAssign: + case EOpModAssign: + case EOpAndAssign: + case EOpInclusiveOrAssign: + case EOpExclusiveOrAssign: + case EOpLeftShiftAssign: + case EOpRightShiftAssign: + return true; + default: + return false; + } +} + +// +// returns true if the operator is for one of the constructors +// +bool TIntermOperator::isConstructor() const +{ + return op > EOpConstructGuardStart && op < EOpConstructGuardEnd; +} + +// +// Make sure the type of an operator is appropriate for its +// combination of operation and operand type. This will invoke +// promoteUnary, promoteBinary, etc as needed. +// +// Returns false if nothing makes sense. +// +bool TIntermediate::promote(TIntermOperator* node) +{ + if (node == nullptr) + return false; + + if (node->getAsUnaryNode()) + return promoteUnary(*node->getAsUnaryNode()); + + if (node->getAsBinaryNode()) + return promoteBinary(*node->getAsBinaryNode()); + + if (node->getAsAggregate()) + return promoteAggregate(*node->getAsAggregate()); + + return false; +} + +// +// See TIntermediate::promote +// +bool TIntermediate::promoteUnary(TIntermUnary& node) +{ + const TOperator op = node.getOp(); + TIntermTyped* operand = node.getOperand(); + + switch (op) { + case EOpLogicalNot: + // Convert operand to a boolean type + if (operand->getBasicType() != EbtBool) { + // Add constructor to boolean type. If that fails, we can't do it, so return false. + TIntermTyped* converted = convertToBasicType(op, EbtBool, operand); + if (converted == nullptr) + return false; + + // Use the result of converting the node to a bool. + node.setOperand(operand = converted); // also updates stack variable + } + break; + case EOpBitwiseNot: + if (operand->getBasicType() != EbtInt && + operand->getBasicType() != EbtUint && +#ifdef AMD_EXTENSIONS + operand->getBasicType() != EbtInt16 && + operand->getBasicType() != EbtUint16 && +#endif + operand->getBasicType() != EbtInt64 && + operand->getBasicType() != EbtUint64) + + return false; + break; + case EOpNegative: + case EOpPostIncrement: + case EOpPostDecrement: + case EOpPreIncrement: + case EOpPreDecrement: + if (operand->getBasicType() != EbtInt && + operand->getBasicType() != EbtUint && + operand->getBasicType() != EbtInt64 && + operand->getBasicType() != EbtUint64 && +#ifdef AMD_EXTENSIONS + operand->getBasicType() != EbtInt16 && + operand->getBasicType() != EbtUint16 && +#endif + operand->getBasicType() != EbtFloat && +#ifdef AMD_EXTENSIONS + operand->getBasicType() != EbtFloat16 && +#endif + operand->getBasicType() != EbtDouble) + + return false; + break; + + default: + if (operand->getBasicType() != EbtFloat) + + return false; + } + + node.setType(operand->getType()); + node.getWritableType().getQualifier().makeTemporary(); + + return true; +} + +void TIntermUnary::updatePrecision() +{ +#ifdef AMD_EXTENSIONS + if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat || getBasicType() == EbtFloat16) { +#else + if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat) { +#endif + if (operand->getQualifier().precision > getQualifier().precision) + getQualifier().precision = operand->getQualifier().precision; + } +} + +// If it is not already, convert this node to the given basic type. +TIntermTyped* TIntermediate::convertToBasicType(TOperator op, TBasicType basicType, TIntermTyped* node) const +{ + if (node == nullptr) + return nullptr; + + // It's already this basic type: nothing needs to be done, so use the node directly. + if (node->getBasicType() == basicType) + return node; + + const TType& type = node->getType(); + const TType newType(basicType, type.getQualifier().storage, + type.getVectorSize(), type.getMatrixCols(), type.getMatrixRows(), type.isVector()); + + // Add constructor to the right vectorness of the right type. If that fails, we can't do it, so return nullptr. + return addConversion(op, newType, node); +} + +// +// See TIntermediate::promote +// +bool TIntermediate::promoteBinary(TIntermBinary& node) +{ + TOperator op = node.getOp(); + TIntermTyped* left = node.getLeft(); + TIntermTyped* right = node.getRight(); + + // Arrays and structures have to be exact matches. + if ((left->isArray() || right->isArray() || left->getBasicType() == EbtStruct || right->getBasicType() == EbtStruct) + && left->getType() != right->getType()) + return false; + + // Base assumption: just make the type the same as the left + // operand. Only deviations from this will be coded. + node.setType(left->getType()); + node.getWritableType().getQualifier().clear(); + + // Composite and opaque types don't having pending operator changes, e.g., + // array, structure, and samplers. Just establish final type and correctness. + if (left->isArray() || left->getBasicType() == EbtStruct || left->getBasicType() == EbtSampler) { + switch (op) { + case EOpEqual: + case EOpNotEqual: + if (left->getBasicType() == EbtSampler) { + // can't compare samplers + return false; + } else { + // Promote to conditional + node.setType(TType(EbtBool)); + } + + return true; + + case EOpAssign: + // Keep type from above + + return true; + + default: + return false; + } + } + + // + // We now have only scalars, vectors, and matrices to worry about. + // + + // HLSL implicitly promotes bool -> int for numeric operations. + // (Implicit conversions to make the operands match each other's types were already done.) + if (getSource() == EShSourceHlsl && + (left->getBasicType() == EbtBool || right->getBasicType() == EbtBool)) { + switch (op) { + case EOpLessThan: + case EOpGreaterThan: + case EOpLessThanEqual: + case EOpGreaterThanEqual: + + case EOpRightShift: + case EOpLeftShift: + + case EOpMod: + + case EOpAnd: + case EOpInclusiveOr: + case EOpExclusiveOr: + + case EOpAdd: + case EOpSub: + case EOpDiv: + case EOpMul: + left = addConversion(op, TType(EbtInt, EvqTemporary, left->getVectorSize()), left); + right = addConversion(op, TType(EbtInt, EvqTemporary, right->getVectorSize()), right); + if (left == nullptr || right == nullptr) + return false; + node.setLeft(left); + node.setRight(right); + + // Update the original base assumption on result type.. + node.setType(left->getType()); + node.getWritableType().getQualifier().clear(); + + break; + + default: + break; + } + } + + // Do general type checks against individual operands (comparing left and right is coming up, checking mixed shapes after that) + switch (op) { + case EOpLessThan: + case EOpGreaterThan: + case EOpLessThanEqual: + case EOpGreaterThanEqual: + // Relational comparisons need numeric types and will promote to scalar Boolean. + if (left->getBasicType() == EbtBool) + return false; + + node.setType(TType(EbtBool, EvqTemporary, left->getVectorSize())); + break; + + case EOpEqual: + case EOpNotEqual: + if (getSource() == EShSourceHlsl) { + const int resultWidth = std::max(left->getVectorSize(), right->getVectorSize()); + + // In HLSL, == or != on vectors means component-wise comparison. + if (resultWidth > 1) { + op = (op == EOpEqual) ? EOpVectorEqual : EOpVectorNotEqual; + node.setOp(op); + } + + node.setType(TType(EbtBool, EvqTemporary, resultWidth)); + } else { + // All the above comparisons result in a bool (but not the vector compares) + node.setType(TType(EbtBool)); + } + break; + + case EOpLogicalAnd: + case EOpLogicalOr: + case EOpLogicalXor: + if (getSource() == EShSourceHlsl) { + TIntermTyped* convertedL = convertToBasicType(op, EbtBool, left); + TIntermTyped* convertedR = convertToBasicType(op, EbtBool, right); + if (convertedL == nullptr || convertedR == nullptr) + return false; + node.setLeft(left = convertedL); // also updates stack variable + node.setRight(right = convertedR); // also updates stack variable + } else { + // logical ops operate only on scalar Booleans and will promote to scalar Boolean. + if (left->getBasicType() != EbtBool || left->isVector() || left->isMatrix()) + return false; + } + + node.setType(TType(EbtBool, EvqTemporary, left->getVectorSize())); + + break; + + case EOpRightShift: + case EOpLeftShift: + case EOpRightShiftAssign: + case EOpLeftShiftAssign: + + case EOpMod: + case EOpModAssign: + + case EOpAnd: + case EOpInclusiveOr: + case EOpExclusiveOr: + case EOpAndAssign: + case EOpInclusiveOrAssign: + case EOpExclusiveOrAssign: + if (getSource() == EShSourceHlsl) + break; + + // Check for integer-only operands. + if ((left->getBasicType() != EbtInt && left->getBasicType() != EbtUint && +#ifdef AMD_EXTENSIONS + left->getBasicType() != EbtInt16 && left->getBasicType() != EbtUint16 && +#endif + left->getBasicType() != EbtInt64 && left->getBasicType() != EbtUint64) || + (right->getBasicType() != EbtInt && right->getBasicType() != EbtUint && +#ifdef AMD_EXTENSIONS + right->getBasicType() != EbtInt16 && right->getBasicType() != EbtUint16 && +#endif + right->getBasicType() != EbtInt64 && right->getBasicType() != EbtUint64)) + return false; + if (left->isMatrix() || right->isMatrix()) + return false; + + break; + + case EOpAdd: + case EOpSub: + case EOpDiv: + case EOpMul: + case EOpAddAssign: + case EOpSubAssign: + case EOpMulAssign: + case EOpDivAssign: + // check for non-Boolean operands + if (left->getBasicType() == EbtBool || right->getBasicType() == EbtBool) + return false; + + default: + break; + } + + // Compare left and right, and finish with the cases where the operand types must match + switch (op) { + case EOpLessThan: + case EOpGreaterThan: + case EOpLessThanEqual: + case EOpGreaterThanEqual: + + case EOpEqual: + case EOpNotEqual: + case EOpVectorEqual: + case EOpVectorNotEqual: + + case EOpLogicalAnd: + case EOpLogicalOr: + case EOpLogicalXor: + return left->getType() == right->getType(); + + case EOpMod: + case EOpModAssign: + + case EOpAnd: + case EOpInclusiveOr: + case EOpExclusiveOr: + case EOpAndAssign: + case EOpInclusiveOrAssign: + case EOpExclusiveOrAssign: + + case EOpAdd: + case EOpSub: + case EOpDiv: + + case EOpAddAssign: + case EOpSubAssign: + case EOpDivAssign: + // Quick out in case the types do match + if (left->getType() == right->getType()) + return true; + + // Fall through + + case EOpMul: + case EOpMulAssign: + // At least the basic type has to match + if (left->getBasicType() != right->getBasicType()) + return false; + + default: + break; + } + + // Finish handling the case, for all ops, where both operands are scalars. + if (left->isScalar() && right->isScalar()) + return true; + + // Finish handling the case, for all ops, where there are two vectors of different sizes + if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize() && right->getVectorSize() > 1) + return false; + + // + // We now have a mix of scalars, vectors, or matrices, for non-relational operations. + // + + // Can these two operands be combined, what is the resulting type? + TBasicType basicType = left->getBasicType(); + switch (op) { + case EOpMul: + if (!left->isMatrix() && right->isMatrix()) { + if (left->isVector()) { + if (left->getVectorSize() != right->getMatrixRows()) + return false; + node.setOp(op = EOpVectorTimesMatrix); + node.setType(TType(basicType, EvqTemporary, right->getMatrixCols())); + } else { + node.setOp(op = EOpMatrixTimesScalar); + node.setType(TType(basicType, EvqTemporary, 0, right->getMatrixCols(), right->getMatrixRows())); + } + } else if (left->isMatrix() && !right->isMatrix()) { + if (right->isVector()) { + if (left->getMatrixCols() != right->getVectorSize()) + return false; + node.setOp(op = EOpMatrixTimesVector); + node.setType(TType(basicType, EvqTemporary, left->getMatrixRows())); + } else { + node.setOp(op = EOpMatrixTimesScalar); + } + } else if (left->isMatrix() && right->isMatrix()) { + if (left->getMatrixCols() != right->getMatrixRows()) + return false; + node.setOp(op = EOpMatrixTimesMatrix); + node.setType(TType(basicType, EvqTemporary, 0, right->getMatrixCols(), left->getMatrixRows())); + } else if (! left->isMatrix() && ! right->isMatrix()) { + if (left->isVector() && right->isVector()) { + ; // leave as component product + } else if (left->isVector() || right->isVector()) { + node.setOp(op = EOpVectorTimesScalar); + if (right->isVector()) + node.setType(TType(basicType, EvqTemporary, right->getVectorSize())); + } + } else { + return false; + } + break; + case EOpMulAssign: + if (! left->isMatrix() && right->isMatrix()) { + if (left->isVector()) { + if (left->getVectorSize() != right->getMatrixRows() || left->getVectorSize() != right->getMatrixCols()) + return false; + node.setOp(op = EOpVectorTimesMatrixAssign); + } else { + return false; + } + } else if (left->isMatrix() && !right->isMatrix()) { + if (right->isVector()) { + return false; + } else { + node.setOp(op = EOpMatrixTimesScalarAssign); + } + } else if (left->isMatrix() && right->isMatrix()) { + if (left->getMatrixCols() != left->getMatrixRows() || left->getMatrixCols() != right->getMatrixCols() || left->getMatrixCols() != right->getMatrixRows()) + return false; + node.setOp(op = EOpMatrixTimesMatrixAssign); + } else if (!left->isMatrix() && !right->isMatrix()) { + if (left->isVector() && right->isVector()) { + // leave as component product + } else if (left->isVector() || right->isVector()) { + if (! left->isVector()) + return false; + node.setOp(op = EOpVectorTimesScalarAssign); + } + } else { + return false; + } + break; + + case EOpRightShift: + case EOpLeftShift: + case EOpRightShiftAssign: + case EOpLeftShiftAssign: + if (right->isVector() && (! left->isVector() || right->getVectorSize() != left->getVectorSize())) + return false; + break; + + case EOpAssign: + if (left->getVectorSize() != right->getVectorSize() || left->getMatrixCols() != right->getMatrixCols() || left->getMatrixRows() != right->getMatrixRows()) + return false; + // fall through + + case EOpAdd: + case EOpSub: + case EOpDiv: + case EOpMod: + case EOpAnd: + case EOpInclusiveOr: + case EOpExclusiveOr: + case EOpAddAssign: + case EOpSubAssign: + case EOpDivAssign: + case EOpModAssign: + case EOpAndAssign: + case EOpInclusiveOrAssign: + case EOpExclusiveOrAssign: + + if ((left->isMatrix() && right->isVector()) || + (left->isVector() && right->isMatrix()) || + left->getBasicType() != right->getBasicType()) + return false; + if (left->isMatrix() && right->isMatrix() && (left->getMatrixCols() != right->getMatrixCols() || left->getMatrixRows() != right->getMatrixRows())) + return false; + if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize()) + return false; + if (right->isVector() || right->isMatrix()) { + node.getWritableType().shallowCopy(right->getType()); + node.getWritableType().getQualifier().makeTemporary(); + } + break; + + default: + return false; + } + + // + // One more check for assignment. + // + switch (op) { + // The resulting type has to match the left operand. + case EOpAssign: + case EOpAddAssign: + case EOpSubAssign: + case EOpMulAssign: + case EOpDivAssign: + case EOpModAssign: + case EOpAndAssign: + case EOpInclusiveOrAssign: + case EOpExclusiveOrAssign: + case EOpLeftShiftAssign: + case EOpRightShiftAssign: + if (node.getType() != left->getType()) + return false; + break; + default: + break; + } + + return true; +} + +// +// See TIntermediate::promote +// +bool TIntermediate::promoteAggregate(TIntermAggregate& node) +{ + TOperator op = node.getOp(); + TIntermSequence& args = node.getSequence(); + const int numArgs = static_cast(args.size()); + + // Presently, only hlsl does intrinsic promotions. + if (getSource() != EShSourceHlsl) + return true; + + // set of opcodes that can be promoted in this manner. + switch (op) { + case EOpAtan: + case EOpClamp: + case EOpCross: + case EOpDistance: + case EOpDot: + case EOpDst: + case EOpFaceForward: + // case EOpFindMSB: TODO: + // case EOpFindLSB: TODO: + case EOpFma: + case EOpMod: + case EOpFrexp: + case EOpLdexp: + case EOpMix: + case EOpLit: + case EOpMax: + case EOpMin: + case EOpModf: + // case EOpGenMul: TODO: + case EOpPow: + case EOpReflect: + case EOpRefract: + // case EOpSinCos: TODO: + case EOpSmoothStep: + case EOpStep: + break; + default: + return true; + } + + // TODO: array and struct behavior + + // Try converting all nodes to the given node's type + TIntermSequence convertedArgs(numArgs, nullptr); + + // Try to convert all types to the nonConvArg type. + for (int nonConvArg = 0; nonConvArg < numArgs; ++nonConvArg) { + // Try converting all args to this arg's type + for (int convArg = 0; convArg < numArgs; ++convArg) { + convertedArgs[convArg] = addConversion(op, args[nonConvArg]->getAsTyped()->getType(), + args[convArg]->getAsTyped()); + } + + // If we successfully converted all the args, use the result. + if (std::all_of(convertedArgs.begin(), convertedArgs.end(), + [](const TIntermNode* node) { return node != nullptr; })) { + + std::swap(args, convertedArgs); + return true; + } + } + + return false; +} + +void TIntermBinary::updatePrecision() +{ +#ifdef AMD_EXTENSIONS + if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat || getBasicType() == EbtFloat16) { +#else + if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat) { +#endif + getQualifier().precision = std::max(right->getQualifier().precision, left->getQualifier().precision); + if (getQualifier().precision != EpqNone) { + left->propagatePrecision(getQualifier().precision); + right->propagatePrecision(getQualifier().precision); + } + } +} + +void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision) +{ +#ifdef AMD_EXTENSIONS + if (getQualifier().precision != EpqNone || (getBasicType() != EbtInt && getBasicType() != EbtUint && getBasicType() != EbtFloat && getBasicType() != EbtFloat16)) +#else + if (getQualifier().precision != EpqNone || (getBasicType() != EbtInt && getBasicType() != EbtUint && getBasicType() != EbtFloat)) +#endif + return; + + getQualifier().precision = newPrecision; + + TIntermBinary* binaryNode = getAsBinaryNode(); + if (binaryNode) { + binaryNode->getLeft()->propagatePrecision(newPrecision); + binaryNode->getRight()->propagatePrecision(newPrecision); + + return; + } + + TIntermUnary* unaryNode = getAsUnaryNode(); + if (unaryNode) { + unaryNode->getOperand()->propagatePrecision(newPrecision); + + return; + } + + TIntermAggregate* aggregateNode = getAsAggregate(); + if (aggregateNode) { + TIntermSequence operands = aggregateNode->getSequence(); + for (unsigned int i = 0; i < operands.size(); ++i) { + TIntermTyped* typedNode = operands[i]->getAsTyped(); + if (! typedNode) + break; + typedNode->propagatePrecision(newPrecision); + } + + return; + } + + TIntermSelection* selectionNode = getAsSelectionNode(); + if (selectionNode) { + TIntermTyped* typedNode = selectionNode->getTrueBlock()->getAsTyped(); + if (typedNode) { + typedNode->propagatePrecision(newPrecision); + typedNode = selectionNode->getFalseBlock()->getAsTyped(); + if (typedNode) + typedNode->propagatePrecision(newPrecision); + } + + return; + } +} + +TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node) const +{ + const TConstUnionArray& rightUnionArray = node->getConstArray(); + int size = node->getType().computeNumComponents(); + + TConstUnionArray leftUnionArray(size); + + for (int i=0; i < size; i++) { + switch (promoteTo) { + case EbtFloat: + switch (node->getType().getBasicType()) { + case EbtInt: + leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getIConst())); + break; + case EbtUint: + leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getUConst())); + break; + case EbtInt64: + leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getI64Const())); + break; + case EbtUint64: + leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getU64Const())); + break; + case EbtBool: + leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getBConst())); + break; + case EbtFloat: + case EbtDouble: +#ifdef AMD_EXTENSIONS + case EbtFloat16: +#endif + leftUnionArray[i] = rightUnionArray[i]; + break; + default: + return node; + } + break; + case EbtDouble: + switch (node->getType().getBasicType()) { + case EbtInt: + leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getIConst())); + break; + case EbtUint: + leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getUConst())); + break; + case EbtInt64: + leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getI64Const())); + break; + case EbtUint64: + leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getU64Const())); + break; + case EbtBool: + leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getBConst())); + break; + case EbtFloat: + case EbtDouble: +#ifdef AMD_EXTENSIONS + case EbtFloat16: +#endif + leftUnionArray[i] = rightUnionArray[i]; + break; + default: + return node; + } + break; +#ifdef AMD_EXTENSIONS + case EbtFloat16: + switch (node->getType().getBasicType()) { + case EbtInt: + leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getIConst())); + break; + case EbtUint: + leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getUConst())); + break; + case EbtInt64: + leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getI64Const())); + break; + case EbtUint64: + leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getU64Const())); + break; + case EbtBool: + leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getBConst())); + break; + case EbtFloat: + case EbtDouble: + case EbtFloat16: + leftUnionArray[i] = rightUnionArray[i]; + break; + default: + return node; + } + break; +#endif + case EbtInt: + switch (node->getType().getBasicType()) { + case EbtInt: + leftUnionArray[i] = rightUnionArray[i]; + break; + case EbtUint: + leftUnionArray[i].setIConst(static_cast(rightUnionArray[i].getUConst())); + break; + case EbtInt64: + leftUnionArray[i].setIConst(static_cast(rightUnionArray[i].getI64Const())); + break; + case EbtUint64: + leftUnionArray[i].setIConst(static_cast(rightUnionArray[i].getU64Const())); + break; + case EbtBool: + leftUnionArray[i].setIConst(static_cast(rightUnionArray[i].getBConst())); + break; + case EbtFloat: + case EbtDouble: +#ifdef AMD_EXTENSIONS + case EbtFloat16: +#endif + leftUnionArray[i].setIConst(static_cast(rightUnionArray[i].getDConst())); + break; + default: + return node; + } + break; + case EbtUint: + switch (node->getType().getBasicType()) { + case EbtInt: + leftUnionArray[i].setUConst(static_cast(rightUnionArray[i].getIConst())); + break; + case EbtUint: + leftUnionArray[i] = rightUnionArray[i]; + break; + case EbtInt64: + leftUnionArray[i].setUConst(static_cast(rightUnionArray[i].getI64Const())); + break; + case EbtUint64: + leftUnionArray[i].setUConst(static_cast(rightUnionArray[i].getU64Const())); + break; + case EbtBool: + leftUnionArray[i].setUConst(static_cast(rightUnionArray[i].getBConst())); + break; + case EbtFloat: + case EbtDouble: +#ifdef AMD_EXTENSIONS + case EbtFloat16: +#endif + leftUnionArray[i].setUConst(static_cast(rightUnionArray[i].getDConst())); + break; + default: + return node; + } + break; + case EbtBool: + switch (node->getType().getBasicType()) { + case EbtInt: + leftUnionArray[i].setBConst(rightUnionArray[i].getIConst() != 0); + break; + case EbtUint: + leftUnionArray[i].setBConst(rightUnionArray[i].getUConst() != 0); + break; + case EbtInt64: + leftUnionArray[i].setBConst(rightUnionArray[i].getI64Const() != 0); + break; + case EbtUint64: + leftUnionArray[i].setBConst(rightUnionArray[i].getU64Const() != 0); + break; + case EbtBool: + leftUnionArray[i] = rightUnionArray[i]; + break; + case EbtFloat: + case EbtDouble: +#ifdef AMD_EXTENSIONS + case EbtFloat16: +#endif + leftUnionArray[i].setBConst(rightUnionArray[i].getDConst() != 0.0); + break; + default: + return node; + } + break; + case EbtInt64: + switch (node->getType().getBasicType()) { + case EbtInt: + leftUnionArray[i].setI64Const(static_cast(rightUnionArray[i].getIConst())); + break; + case EbtUint: + leftUnionArray[i].setI64Const(static_cast(rightUnionArray[i].getUConst())); + break; + case EbtInt64: + leftUnionArray[i] = rightUnionArray[i]; + break; + case EbtUint64: + leftUnionArray[i].setI64Const(static_cast(rightUnionArray[i].getU64Const())); + break; + case EbtBool: + leftUnionArray[i].setI64Const(static_cast(rightUnionArray[i].getBConst())); + break; + case EbtFloat: + case EbtDouble: +#ifdef AMD_EXTENSIONS + case EbtFloat16: +#endif + leftUnionArray[i].setI64Const(static_cast(rightUnionArray[i].getDConst())); + break; + default: + return node; + } + break; + case EbtUint64: + switch (node->getType().getBasicType()) { + case EbtInt: + leftUnionArray[i].setU64Const(static_cast(rightUnionArray[i].getIConst())); + break; + case EbtUint: + leftUnionArray[i].setU64Const(static_cast(rightUnionArray[i].getUConst())); + break; + case EbtInt64: + leftUnionArray[i].setU64Const(static_cast(rightUnionArray[i].getI64Const())); + break; + case EbtUint64: + leftUnionArray[i] = rightUnionArray[i]; + break; + case EbtBool: + leftUnionArray[i].setU64Const(static_cast(rightUnionArray[i].getBConst())); + break; + case EbtFloat: + case EbtDouble: +#ifdef AMD_EXTENSIONS + case EbtFloat16: +#endif + leftUnionArray[i].setU64Const(static_cast(rightUnionArray[i].getDConst())); + break; + default: + return node; + } + break; + default: + return node; + } + } + + const TType& t = node->getType(); + + return addConstantUnion(leftUnionArray, TType(promoteTo, t.getQualifier().storage, t.getVectorSize(), t.getMatrixCols(), t.getMatrixRows()), + node->getLoc()); +} + +void TIntermAggregate::setPragmaTable(const TPragmaTable& pTable) +{ + assert(pragmaTable == nullptr); + pragmaTable = new TPragmaTable; + *pragmaTable = pTable; +} + +// If either node is a specialization constant, while the other is +// a constant (or specialization constant), the result is still +// a specialization constant. +bool TIntermediate::specConstantPropagates(const TIntermTyped& node1, const TIntermTyped& node2) +{ + return (node1.getType().getQualifier().isSpecConstant() && node2.getType().getQualifier().isConstant()) || + (node2.getType().getQualifier().isSpecConstant() && node1.getType().getQualifier().isConstant()); +} + +struct TextureUpgradeAndSamplerRemovalTransform : public TIntermTraverser { + void visitSymbol(TIntermSymbol* symbol) override { + if (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isTexture()) { + symbol->getWritableType().getSampler().combined = true; + } + } + bool visitAggregate(TVisit, TIntermAggregate* ag) override { + using namespace std; + TIntermSequence& seq = ag->getSequence(); + // remove pure sampler variables + TIntermSequence::iterator newEnd = remove_if(seq.begin(), seq.end(), [](TIntermNode* node) { + TIntermSymbol* symbol = node->getAsSymbolNode(); + if (!symbol) + return false; + + return (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isPureSampler()); + }); + seq.erase(newEnd, seq.end()); + // replace constructors with sampler/textures + for_each(seq.begin(), seq.end(), [](TIntermNode*& node) { + TIntermAggregate *constructor = node->getAsAggregate(); + if (constructor && constructor->getOp() == EOpConstructTextureSampler) { + if (!constructor->getSequence().empty()) + node = constructor->getSequence()[0]; + } + }); + return true; + } +}; + +void TIntermediate::performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root) +{ + TextureUpgradeAndSamplerRemovalTransform transform; + root->traverse(&transform); +} + +const char* TIntermediate::getResourceName(TResourceType res) +{ + switch (res) { + case EResSampler: return "shift-sampler-binding"; + case EResTexture: return "shift-texture-binding"; + case EResImage: return "shift-image-binding"; + case EResUbo: return "shift-UBO-binding"; + case EResSsbo: return "shift-ssbo-binding"; + case EResUav: return "shift-uav-binding"; + default: + assert(0); // internal error: should only be called with valid resource types. + return nullptr; + } +} + + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/LiveTraverser.h b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/LiveTraverser.h new file mode 100644 index 00000000..7333bc96 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/LiveTraverser.h @@ -0,0 +1,138 @@ +// +// Copyright (C) 2016 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#pragma once + +#include "../Include/Common.h" +#include "reflection.h" +#include "localintermediate.h" + +#include "gl_types.h" + +#include +#include + +namespace glslang { + +// +// The traverser: mostly pass through, except +// - processing function-call nodes to push live functions onto the stack of functions to process +// - processing selection nodes to trim semantically dead code +// +// This is in the glslang namespace directly so it can be a friend of TReflection. +// This can be derived from to implement reflection database traversers or +// binding mappers: anything that wants to traverse the live subset of the tree. +// + +class TLiveTraverser : public TIntermTraverser { +public: + TLiveTraverser(const TIntermediate& i, bool traverseAll = false, + bool preVisit = true, bool inVisit = false, bool postVisit = false) : + TIntermTraverser(preVisit, inVisit, postVisit), + intermediate(i), traverseAll(traverseAll) + { } + + // + // Given a function name, find its subroot in the tree, and push it onto the stack of + // functions left to process. + // + void pushFunction(const TString& name) + { + TIntermSequence& globals = intermediate.getTreeRoot()->getAsAggregate()->getSequence(); + for (unsigned int f = 0; f < globals.size(); ++f) { + TIntermAggregate* candidate = globals[f]->getAsAggregate(); + if (candidate && candidate->getOp() == EOpFunction && candidate->getName() == name) { + functions.push_back(candidate); + break; + } + } + } + + typedef std::list TFunctionStack; + TFunctionStack functions; + +protected: + // To catch which function calls are not dead, and hence which functions must be visited. + virtual bool visitAggregate(TVisit, TIntermAggregate* node) + { + if (!traverseAll) + if (node->getOp() == EOpFunctionCall) + addFunctionCall(node); + + return true; // traverse this subtree + } + + // To prune semantically dead paths. + virtual bool visitSelection(TVisit /* visit */, TIntermSelection* node) + { + if (traverseAll) + return true; // traverse all code + + TIntermConstantUnion* constant = node->getCondition()->getAsConstantUnion(); + if (constant) { + // cull the path that is dead + if (constant->getConstArray()[0].getBConst() == true && node->getTrueBlock()) + node->getTrueBlock()->traverse(this); + if (constant->getConstArray()[0].getBConst() == false && node->getFalseBlock()) + node->getFalseBlock()->traverse(this); + + return false; // don't traverse any more, we did it all above + } else + return true; // traverse the whole subtree + } + + // Track live functions as well as uniforms, so that we don't visit dead functions + // and only visit each function once. + void addFunctionCall(TIntermAggregate* call) + { + // // just use the map to ensure we process each function at most once + if (liveFunctions.find(call->getName()) == liveFunctions.end()) { + liveFunctions.insert(call->getName()); + pushFunction(call->getName()); + } + } + + const TIntermediate& intermediate; + typedef std::unordered_set TLiveFunctions; + TLiveFunctions liveFunctions; + bool traverseAll; + +private: + // prevent copy & copy construct + TLiveTraverser(TLiveTraverser&); + TLiveTraverser& operator=(TLiveTraverser&); +}; + +} // namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/ParseContextBase.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/ParseContextBase.cpp new file mode 100644 index 00000000..bbc3cac0 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/ParseContextBase.cpp @@ -0,0 +1,612 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2016 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +// Implement the TParseContextBase class. + +#include + +#include "ParseHelper.h" + +extern int yyparse(glslang::TParseContext*); + +namespace glslang { + +// +// Used to output syntax, parsing, and semantic errors. +// + +void TParseContextBase::outputMessage(const TSourceLoc& loc, const char* szReason, + const char* szToken, + const char* szExtraInfoFormat, + TPrefixType prefix, va_list args) +{ + const int maxSize = MaxTokenLength + 200; + char szExtraInfo[maxSize]; + + safe_vsprintf(szExtraInfo, maxSize, szExtraInfoFormat, args); + + infoSink.info.prefix(prefix); + infoSink.info.location(loc); + infoSink.info << "'" << szToken << "' : " << szReason << " " << szExtraInfo << "\n"; + + if (prefix == EPrefixError) { + ++numErrors; + } +} + +void C_DECL TParseContextBase::error(const TSourceLoc& loc, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, ...) +{ + if (messages & EShMsgOnlyPreprocessor) + return; + va_list args; + va_start(args, szExtraInfoFormat); + outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixError, args); + va_end(args); + + if ((messages & EShMsgCascadingErrors) == 0) + currentScanner->setEndOfInput(); +} + +void C_DECL TParseContextBase::warn(const TSourceLoc& loc, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, ...) +{ + if (suppressWarnings()) + return; + va_list args; + va_start(args, szExtraInfoFormat); + outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixWarning, args); + va_end(args); +} + +void C_DECL TParseContextBase::ppError(const TSourceLoc& loc, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, ...) +{ + va_list args; + va_start(args, szExtraInfoFormat); + outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixError, args); + va_end(args); + + if ((messages & EShMsgCascadingErrors) == 0) + currentScanner->setEndOfInput(); +} + +void C_DECL TParseContextBase::ppWarn(const TSourceLoc& loc, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, ...) +{ + va_list args; + va_start(args, szExtraInfoFormat); + outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixWarning, args); + va_end(args); +} + +// +// Both test and if necessary, spit out an error, to see if the node is really +// an l-value that can be operated on this way. +// +// Returns true if there was an error. +// +bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op, TIntermTyped* node) +{ + TIntermBinary* binaryNode = node->getAsBinaryNode(); + + if (binaryNode) { + switch(binaryNode->getOp()) { + case EOpIndexDirect: + case EOpIndexIndirect: // fall through + case EOpIndexDirectStruct: // fall through + case EOpVectorSwizzle: + case EOpMatrixSwizzle: + return lValueErrorCheck(loc, op, binaryNode->getLeft()); + default: + break; + } + error(loc, " l-value required", op, "", ""); + + return true; + } + + const char* symbol = nullptr; + TIntermSymbol* symNode = node->getAsSymbolNode(); + if (symNode != nullptr) + symbol = symNode->getName().c_str(); + + const char* message = nullptr; + switch (node->getQualifier().storage) { + case EvqConst: message = "can't modify a const"; break; + case EvqConstReadOnly: message = "can't modify a const"; break; + case EvqUniform: message = "can't modify a uniform"; break; + case EvqBuffer: + if (node->getQualifier().readonly) + message = "can't modify a readonly buffer"; + break; + + default: + // + // Type that can't be written to? + // + switch (node->getBasicType()) { + case EbtSampler: + message = "can't modify a sampler"; + break; + case EbtAtomicUint: + message = "can't modify an atomic_uint"; + break; + case EbtVoid: + message = "can't modify void"; + break; + default: + break; + } + } + + if (message == nullptr && binaryNode == nullptr && symNode == nullptr) { + error(loc, " l-value required", op, "", ""); + + return true; + } + + // + // Everything else is okay, no error. + // + if (message == nullptr) + return false; + + // + // If we get here, we have an error and a message. + // + if (symNode) + error(loc, " l-value required", op, "\"%s\" (%s)", symbol, message); + else + error(loc, " l-value required", op, "(%s)", message); + + return true; +} + +// Test for and give an error if the node can't be read from. +void TParseContextBase::rValueErrorCheck(const TSourceLoc& loc, const char* op, TIntermTyped* node) +{ + if (! node) + return; + + TIntermBinary* binaryNode = node->getAsBinaryNode(); + if (binaryNode) { + switch(binaryNode->getOp()) { + case EOpIndexDirect: + case EOpIndexIndirect: + case EOpIndexDirectStruct: + case EOpVectorSwizzle: + case EOpMatrixSwizzle: + rValueErrorCheck(loc, op, binaryNode->getLeft()); + default: + break; + } + + return; + } + + TIntermSymbol* symNode = node->getAsSymbolNode(); + if (symNode && symNode->getQualifier().writeonly) + error(loc, "can't read from writeonly object: ", op, symNode->getName().c_str()); +} + +// Add 'symbol' to the list of deferred linkage symbols, which +// are later processed in finish(), at which point the symbol +// must still be valid. +// It is okay if the symbol's type will be subsequently edited; +// the modifications will be tracked. +void TParseContextBase::trackLinkage(TSymbol& symbol) +{ + if (!parsingBuiltins) + linkageSymbols.push_back(&symbol); +} + +// Ensure index is in bounds, correct if necessary. +// Give an error if not. +void TParseContextBase::checkIndex(const TSourceLoc& loc, const TType& type, int& index) +{ + if (index < 0) { + error(loc, "", "[", "index out of range '%d'", index); + index = 0; + } else if (type.isArray()) { + if (type.isExplicitlySizedArray() && index >= type.getOuterArraySize()) { + error(loc, "", "[", "array index out of range '%d'", index); + index = type.getOuterArraySize() - 1; + } + } else if (type.isVector()) { + if (index >= type.getVectorSize()) { + error(loc, "", "[", "vector index out of range '%d'", index); + index = type.getVectorSize() - 1; + } + } else if (type.isMatrix()) { + if (index >= type.getMatrixCols()) { + error(loc, "", "[", "matrix index out of range '%d'", index); + index = type.getMatrixCols() - 1; + } + } +} + +// Make a shared symbol have a non-shared version that can be edited by the current +// compile, such that editing its type will not change the shared version and will +// effect all nodes already sharing it (non-shallow type), +// or adopting its full type after being edited (shallow type). +void TParseContextBase::makeEditable(TSymbol*& symbol) +{ + // copyUp() does a deep copy of the type. + symbol = symbolTable.copyUp(symbol); + + // Save it (deferred, so it can be edited first) in the AST for linker use. + if (symbol) + trackLinkage(*symbol); +} + +// Return a writable version of the variable 'name'. +// +// Return nullptr if 'name' is not found. This should mean +// something is seriously wrong (e.g., compiler asking self for +// built-in that doesn't exist). +TVariable* TParseContextBase::getEditableVariable(const char* name) +{ + bool builtIn; + TSymbol* symbol = symbolTable.find(name, &builtIn); + + assert(symbol != nullptr); + if (symbol == nullptr) + return nullptr; + + if (builtIn) + makeEditable(symbol); + + return symbol->getAsVariable(); +} + +// Select the best matching function for 'call' from 'candidateList'. +// +// Assumptions +// +// There is no exact match, so a selection algorithm needs to run. That is, the +// language-specific handler should check for exact match first, to +// decide what to do, before calling this selector. +// +// Input +// +// * list of candidate signatures to select from +// * the call +// * a predicate function convertible(from, to) that says whether or not type +// 'from' can implicitly convert to type 'to' (it includes the case of what +// the calling language would consider a matching type with no conversion +// needed) +// * a predicate function better(from1, from2, to1, to2) that says whether or +// not a conversion from <-> to2 is considered better than a conversion +// from <-> to1 (both in and out directions need testing, as declared by the +// formal parameter) +// +// Output +// +// * best matching candidate (or none, if no viable candidates found) +// * whether there was a tie for the best match (ambiguous overload selection, +// caller's choice for how to report) +// +const TFunction* TParseContextBase::selectFunction( + const TVector candidateList, + const TFunction& call, + std::function convertible, + std::function better, + /* output */ bool& tie) +{ +// +// Operation +// +// 1. Prune the input list of candidates down to a list of viable candidates, +// where each viable candidate has +// +// * at least as many parameters as there are calling arguments, with any +// remaining parameters being optional or having default values +// * each parameter is true under convertible(A, B), where A is the calling +// type for in and B is the formal type, and in addition, for out B is the +// calling type and A is the formal type +// +// 2. If there are no viable candidates, return with no match. +// +// 3. If there is only one viable candidate, it is the best match. +// +// 4. If there are multiple viable candidates, select the first viable candidate +// as the incumbent. Compare the incumbent to the next viable candidate, and if +// that candidate is better (bullets below), make it the incumbent. Repeat, with +// a linear walk through the viable candidate list. The final incumbent will be +// returned as the best match. A viable candidate is better than the incumbent if +// +// * it has a function argument with a better(...) conversion than the incumbent, +// for all directions needed by in and out +// * the incumbent has no argument with a better(...) conversion then the +// candidate, for either in or out (as needed) +// +// 5. Check for ambiguity by comparing the best match against all other viable +// candidates. If any other viable candidate has a function argument with a +// better(...) conversion than the best candidate (for either in or out +// directions), return that there was a tie for best. +// + + tie = false; + + // 1. prune to viable... + TVector viableCandidates; + for (auto it = candidateList.begin(); it != candidateList.end(); ++it) { + const TFunction& candidate = *(*it); + + // to even be a potential match, number of arguments must be >= the number of + // fixed (non-default) parameters, and <= the total (including parameter with defaults). + if (call.getParamCount() < candidate.getFixedParamCount() || + call.getParamCount() > candidate.getParamCount()) + continue; + + // see if arguments are convertible + bool viable = true; + + // The call can have fewer parameters than the candidate, if some have defaults. + const int paramCount = std::min(call.getParamCount(), candidate.getParamCount()); + for (int param = 0; param < paramCount; ++param) { + if (candidate[param].type->getQualifier().isParamInput()) { + if (! convertible(*call[param].type, *candidate[param].type, candidate.getBuiltInOp(), param)) { + viable = false; + break; + } + } + if (candidate[param].type->getQualifier().isParamOutput()) { + if (! convertible(*candidate[param].type, *call[param].type, candidate.getBuiltInOp(), param)) { + viable = false; + break; + } + } + } + + if (viable) + viableCandidates.push_back(&candidate); + } + + // 2. none viable... + if (viableCandidates.size() == 0) + return nullptr; + + // 3. only one viable... + if (viableCandidates.size() == 1) + return viableCandidates.front(); + + // 4. find best... + const auto betterParam = [&call, &better](const TFunction& can1, const TFunction& can2) -> bool { + // is call -> can2 better than call -> can1 for any parameter + bool hasBetterParam = false; + for (int param = 0; param < call.getParamCount(); ++param) { + if (better(*call[param].type, *can1[param].type, *can2[param].type)) { + hasBetterParam = true; + break; + } + } + return hasBetterParam; + }; + + const auto equivalentParams = [&call, &better](const TFunction& can1, const TFunction& can2) -> bool { + // is call -> can2 equivalent to call -> can1 for all the call parameters? + for (int param = 0; param < call.getParamCount(); ++param) { + if (better(*call[param].type, *can1[param].type, *can2[param].type) || + better(*call[param].type, *can2[param].type, *can1[param].type)) + return false; + } + return true; + }; + + const TFunction* incumbent = viableCandidates.front(); + for (auto it = viableCandidates.begin() + 1; it != viableCandidates.end(); ++it) { + const TFunction& candidate = *(*it); + if (betterParam(*incumbent, candidate) && ! betterParam(candidate, *incumbent)) + incumbent = &candidate; + } + + // 5. ambiguity... + for (auto it = viableCandidates.begin(); it != viableCandidates.end(); ++it) { + if (incumbent == *it) + continue; + const TFunction& candidate = *(*it); + + // In the case of default parameters, it may have an identical initial set, which is + // also ambiguous + if (betterParam(*incumbent, candidate) || equivalentParams(*incumbent, candidate)) + tie = true; + } + + return incumbent; +} + +// +// Look at a '.' field selector string and change it into numerical selectors +// for a vector or scalar. +// +// Always return some form of swizzle, so the result is always usable. +// +void TParseContextBase::parseSwizzleSelector(const TSourceLoc& loc, const TString& compString, int vecSize, + TSwizzleSelectors& selector) +{ + // Too long? + if (compString.size() > MaxSwizzleSelectors) + error(loc, "vector swizzle too long", compString.c_str(), ""); + + // Use this to test that all swizzle characters are from the same swizzle-namespace-set + enum { + exyzw, + ergba, + estpq, + } fieldSet[MaxSwizzleSelectors]; + + // Decode the swizzle string. + int size = std::min(MaxSwizzleSelectors, (int)compString.size()); + for (int i = 0; i < size; ++i) { + switch (compString[i]) { + case 'x': + selector.push_back(0); + fieldSet[i] = exyzw; + break; + case 'r': + selector.push_back(0); + fieldSet[i] = ergba; + break; + case 's': + selector.push_back(0); + fieldSet[i] = estpq; + break; + + case 'y': + selector.push_back(1); + fieldSet[i] = exyzw; + break; + case 'g': + selector.push_back(1); + fieldSet[i] = ergba; + break; + case 't': + selector.push_back(1); + fieldSet[i] = estpq; + break; + + case 'z': + selector.push_back(2); + fieldSet[i] = exyzw; + break; + case 'b': + selector.push_back(2); + fieldSet[i] = ergba; + break; + case 'p': + selector.push_back(2); + fieldSet[i] = estpq; + break; + + case 'w': + selector.push_back(3); + fieldSet[i] = exyzw; + break; + case 'a': + selector.push_back(3); + fieldSet[i] = ergba; + break; + case 'q': + selector.push_back(3); + fieldSet[i] = estpq; + break; + + default: + error(loc, "unknown swizzle selection", compString.c_str(), ""); + break; + } + } + + // Additional error checking. + for (int i = 0; i < selector.size(); ++i) { + if (selector[i] >= vecSize) { + error(loc, "vector swizzle selection out of range", compString.c_str(), ""); + selector.resize(i); + break; + } + + if (i > 0 && fieldSet[i] != fieldSet[i-1]) { + error(loc, "vector swizzle selectors not from the same set", compString.c_str(), ""); + selector.resize(i); + break; + } + } + + // Ensure it is valid. + if (selector.size() == 0) + selector.push_back(0); +} + +// +// Make the passed-in variable information become a member of the +// global uniform block. If this doesn't exist yet, make it. +// +void TParseContextBase::growGlobalUniformBlock(const TSourceLoc& loc, TType& memberType, const TString& memberName, TTypeList* typeList) +{ + // Make the global block, if not yet made. + if (globalUniformBlock == nullptr) { + TQualifier blockQualifier; + blockQualifier.clear(); + blockQualifier.storage = EvqUniform; + TType blockType(new TTypeList, *NewPoolTString(getGlobalUniformBlockName()), blockQualifier); + setUniformBlockDefaults(blockType); + globalUniformBlock = new TVariable(NewPoolTString(""), blockType, true); + firstNewMember = 0; + } + + // Update with binding and set + globalUniformBlock->getWritableType().getQualifier().layoutBinding = globalUniformBinding; + globalUniformBlock->getWritableType().getQualifier().layoutSet = globalUniformSet; + + // Add the requested member as a member to the global block. + TType* type = new TType; + type->shallowCopy(memberType); + type->setFieldName(memberName); + if (typeList) + type->setStruct(typeList); + TTypeLoc typeLoc = {type, loc}; + globalUniformBlock->getType().getWritableStruct()->push_back(typeLoc); + + // Insert into the symbol table. + if (firstNewMember == 0) { + // This is the first request; we need a normal symbol table insert + if (symbolTable.insert(*globalUniformBlock)) + trackLinkage(*globalUniformBlock); + else + error(loc, "failed to insert the global constant buffer", "uniform", ""); + } else { + // This is a follow-on request; we need to amend the first insert + symbolTable.amend(*globalUniformBlock, firstNewMember); + } + + ++firstNewMember; +} + +void TParseContextBase::finish() +{ + if (parsingBuiltins) + return; + + // Transfer the linkage symbols to AST nodes + TIntermAggregate* linkage = new TIntermAggregate; + for (auto i = linkageSymbols.begin(); i != linkageSymbols.end(); ++i) + intermediate.addSymbolLinkageNode(linkage, **i); + intermediate.addSymbolLinkageNodes(linkage, getLanguage(), symbolTable); +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp new file mode 100644 index 00000000..d662be15 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp @@ -0,0 +1,6494 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2012-2015 LunarG, Inc. +// Copyright (C) 2015-2016 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#include "ParseHelper.h" +#include "Scan.h" + +#include "../OSDependent/osinclude.h" +#include + +#include "preprocessor/PpContext.h" + +extern int yyparse(glslang::TParseContext*); + +namespace glslang { + +TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, bool parsingBuiltins, + int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, + TInfoSink& infoSink, bool forwardCompatible, EShMessages messages, + const TString* entryPoint) : + TParseContextBase(symbolTable, interm, parsingBuiltins, version, profile, spvVersion, language, + infoSink, forwardCompatible, messages, entryPoint), + inMain(false), + blockName(nullptr), + limits(resources.limits), + atomicUintOffsets(nullptr), anyIndexLimits(false) +{ + // decide whether precision qualifiers should be ignored or respected + if (profile == EEsProfile || spvVersion.vulkan > 0) { + precisionManager.respectPrecisionQualifiers(); + if (! parsingBuiltins && language == EShLangFragment && profile != EEsProfile && spvVersion.vulkan > 0) + precisionManager.warnAboutDefaults(); + } + + setPrecisionDefaults(); + + globalUniformDefaults.clear(); + globalUniformDefaults.layoutMatrix = ElmColumnMajor; + globalUniformDefaults.layoutPacking = spvVersion.spv != 0 ? ElpStd140 : ElpShared; + + globalBufferDefaults.clear(); + globalBufferDefaults.layoutMatrix = ElmColumnMajor; + globalBufferDefaults.layoutPacking = spvVersion.spv != 0 ? ElpStd430 : ElpShared; + + globalInputDefaults.clear(); + globalOutputDefaults.clear(); + + // "Shaders in the transform + // feedback capturing mode have an initial global default of + // layout(xfb_buffer = 0) out;" + if (language == EShLangVertex || + language == EShLangTessControl || + language == EShLangTessEvaluation || + language == EShLangGeometry) + globalOutputDefaults.layoutXfbBuffer = 0; + + if (language == EShLangGeometry) + globalOutputDefaults.layoutStream = 0; + + if (entryPoint != nullptr && entryPoint->size() > 0 && *entryPoint != "main") + infoSink.info.message(EPrefixError, "Source entry point must be \"main\""); +} + +TParseContext::~TParseContext() +{ + delete [] atomicUintOffsets; +} + +// Set up all default precisions as needed by the current environment. +// Intended just as a TParseContext constructor helper. +void TParseContext::setPrecisionDefaults() +{ + // Set all precision defaults to EpqNone, which is correct for all types + // when not obeying precision qualifiers, and correct for types that don't + // have defaults (thus getting an error on use) when obeying precision + // qualifiers. + + for (int type = 0; type < EbtNumTypes; ++type) + defaultPrecision[type] = EpqNone; + + for (int type = 0; type < maxSamplerIndex; ++type) + defaultSamplerPrecision[type] = EpqNone; + + // replace with real precision defaults for those that have them + if (obeyPrecisionQualifiers()) { + if (profile == EEsProfile) { + // Most don't have defaults, a few default to lowp. + TSampler sampler; + sampler.set(EbtFloat, Esd2D); + defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow; + sampler.set(EbtFloat, EsdCube); + defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow; + sampler.set(EbtFloat, Esd2D); + sampler.external = true; + defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow; + } + + // If we are parsing built-in computational variables/functions, it is meaningful to record + // whether the built-in has no precision qualifier, as that ambiguity + // is used to resolve the precision from the supplied arguments/operands instead. + // So, we don't actually want to replace EpqNone with a default precision for built-ins. + if (! parsingBuiltins) { + if (profile == EEsProfile && language == EShLangFragment) { + defaultPrecision[EbtInt] = EpqMedium; + defaultPrecision[EbtUint] = EpqMedium; + } else { + defaultPrecision[EbtInt] = EpqHigh; + defaultPrecision[EbtUint] = EpqHigh; + defaultPrecision[EbtFloat] = EpqHigh; + } + + if (profile != EEsProfile) { + // Non-ES profile + // All sampler precisions default to highp. + for (int type = 0; type < maxSamplerIndex; ++type) + defaultSamplerPrecision[type] = EpqHigh; + } + } + + defaultPrecision[EbtSampler] = EpqLow; + defaultPrecision[EbtAtomicUint] = EpqHigh; + } +} + +void TParseContext::setLimits(const TBuiltInResource& r) +{ + resources = r; + + anyIndexLimits = ! limits.generalAttributeMatrixVectorIndexing || + ! limits.generalConstantMatrixVectorIndexing || + ! limits.generalSamplerIndexing || + ! limits.generalUniformIndexing || + ! limits.generalVariableIndexing || + ! limits.generalVaryingIndexing; + + intermediate.setLimits(resources); + + // "Each binding point tracks its own current default offset for + // inheritance of subsequent variables using the same binding. The initial state of compilation is that all + // binding points have an offset of 0." + atomicUintOffsets = new int[resources.maxAtomicCounterBindings]; + for (int b = 0; b < resources.maxAtomicCounterBindings; ++b) + atomicUintOffsets[b] = 0; +} + +// +// Parse an array of strings using yyparse, going through the +// preprocessor to tokenize the shader strings, then through +// the GLSL scanner. +// +// Returns true for successful acceptance of the shader, false if any errors. +// +bool TParseContext::parseShaderStrings(TPpContext& ppContext, TInputScanner& input, bool versionWillBeError) +{ + currentScanner = &input; + ppContext.setInput(input, versionWillBeError); + yyparse(this); + + finish(); + + return numErrors == 0; +} + +// This is called from bison when it has a parse (syntax) error +// Note though that to stop cascading errors, we set EOF, which +// will usually cause a syntax error, so be more accurate that +// compilation is terminating. +void TParseContext::parserError(const char* s) +{ + if (! getScanner()->atEndOfInput() || numErrors == 0) + error(getCurrentLoc(), "", "", s, ""); + else + error(getCurrentLoc(), "compilation terminated", "", ""); +} + +void TParseContext::handlePragma(const TSourceLoc& loc, const TVector& tokens) +{ + if (pragmaCallback) + pragmaCallback(loc.line, tokens); + + if (tokens.size() == 0) + return; + + if (tokens[0].compare("optimize") == 0) { + if (tokens.size() != 4) { + error(loc, "optimize pragma syntax is incorrect", "#pragma", ""); + return; + } + + if (tokens[1].compare("(") != 0) { + error(loc, "\"(\" expected after 'optimize' keyword", "#pragma", ""); + return; + } + + if (tokens[2].compare("on") == 0) + contextPragma.optimize = true; + else if (tokens[2].compare("off") == 0) + contextPragma.optimize = false; + else { + error(loc, "\"on\" or \"off\" expected after '(' for 'optimize' pragma", "#pragma", ""); + return; + } + + if (tokens[3].compare(")") != 0) { + error(loc, "\")\" expected to end 'optimize' pragma", "#pragma", ""); + return; + } + } else if (tokens[0].compare("debug") == 0) { + if (tokens.size() != 4) { + error(loc, "debug pragma syntax is incorrect", "#pragma", ""); + return; + } + + if (tokens[1].compare("(") != 0) { + error(loc, "\"(\" expected after 'debug' keyword", "#pragma", ""); + return; + } + + if (tokens[2].compare("on") == 0) + contextPragma.debug = true; + else if (tokens[2].compare("off") == 0) + contextPragma.debug = false; + else { + error(loc, "\"on\" or \"off\" expected after '(' for 'debug' pragma", "#pragma", ""); + return; + } + + if (tokens[3].compare(")") != 0) { + error(loc, "\")\" expected to end 'debug' pragma", "#pragma", ""); + return; + } + } else if (spvVersion.spv > 0 && tokens[0].compare("use_storage_buffer") == 0) { + if (tokens.size() != 1) + error(loc, "extra tokens", "#pragma", ""); + intermediate.setUseStorageBuffer(); + } +} + +// +// Handle seeing a variable identifier in the grammar. +// +TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symbol, const TString* string) +{ + TIntermTyped* node = nullptr; + + // Error check for requiring specific extensions present. + if (symbol && symbol->getNumExtensions()) + requireExtensions(loc, symbol->getNumExtensions(), symbol->getExtensions(), symbol->getName().c_str()); + + if (symbol && symbol->isReadOnly()) { + // All shared things containing an implicitly sized array must be copied up + // on first use, so that all future references will share its array structure, + // so that editing the implicit size will effect all nodes consuming it, + // and so that editing the implicit size won't change the shared one. + // + // If this is a variable or a block, check it and all it contains, but if this + // is a member of an anonymous block, check the whole block, as the whole block + // will need to be copied up if it contains an implicitly-sized array. + if (symbol->getType().containsImplicitlySizedArray() || + (symbol->getAsAnonMember() && + symbol->getAsAnonMember()->getAnonContainer().getType().containsImplicitlySizedArray())) + makeEditable(symbol); + } + + const TVariable* variable; + const TAnonMember* anon = symbol ? symbol->getAsAnonMember() : nullptr; + if (anon) { + // It was a member of an anonymous container. + + // The "getNumExtensions()" mechanism above doesn't yet work for block members + blockMemberExtensionCheck(loc, nullptr, *string); + + // Create a subtree for its dereference. + variable = anon->getAnonContainer().getAsVariable(); + TIntermTyped* container = intermediate.addSymbol(*variable, loc); + TIntermTyped* constNode = intermediate.addConstantUnion(anon->getMemberNumber(), loc); + node = intermediate.addIndex(EOpIndexDirectStruct, container, constNode, loc); + + node->setType(*(*variable->getType().getStruct())[anon->getMemberNumber()].type); + if (node->getType().hiddenMember()) + error(loc, "member of nameless block was not redeclared", string->c_str(), ""); + } else { + // Not a member of an anonymous container. + + // The symbol table search was done in the lexical phase. + // See if it was a variable. + variable = symbol ? symbol->getAsVariable() : nullptr; + if (variable) { + if ((variable->getType().getBasicType() == EbtBlock || + variable->getType().getBasicType() == EbtStruct) && variable->getType().getStruct() == nullptr) { + error(loc, "cannot be used (maybe an instance name is needed)", string->c_str(), ""); + variable = nullptr; + } + } else { + if (symbol) + error(loc, "variable name expected", string->c_str(), ""); + } + + // Recovery, if it wasn't found or was not a variable. + if (! variable) + variable = new TVariable(string, TType(EbtVoid)); + + if (variable->getType().getQualifier().isFrontEndConstant()) + node = intermediate.addConstantUnion(variable->getConstArray(), variable->getType(), loc); + else + node = intermediate.addSymbol(*variable, loc); + } + + if (variable->getType().getQualifier().isIo()) + intermediate.addIoAccessed(*string); + + return node; +} + +// +// Handle seeing a base[index] dereference in the grammar. +// +TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIntermTyped* base, TIntermTyped* index) +{ + TIntermTyped* result = nullptr; + + int indexValue = 0; + if (index->getQualifier().isFrontEndConstant()) + indexValue = index->getAsConstantUnion()->getConstArray()[0].getIConst(); + + variableCheck(base); + if (! base->isArray() && ! base->isMatrix() && ! base->isVector()) { + if (base->getAsSymbolNode()) + error(loc, " left of '[' is not of type array, matrix, or vector ", base->getAsSymbolNode()->getName().c_str(), ""); + else + error(loc, " left of '[' is not of type array, matrix, or vector ", "expression", ""); + } else if (base->getType().getQualifier().isFrontEndConstant() && index->getQualifier().isFrontEndConstant()) { + // both base and index are front-end constants + checkIndex(loc, base->getType(), indexValue); + return intermediate.foldDereference(base, indexValue, loc); + } else { + // at least one of base and index is not a front-end constant variable... + + if (base->getAsSymbolNode() && isIoResizeArray(base->getType())) + handleIoResizeArrayAccess(loc, base); + + if (index->getQualifier().isFrontEndConstant()) { + if (base->getType().isImplicitlySizedArray()) + updateImplicitArraySize(loc, base, indexValue); + else + checkIndex(loc, base->getType(), indexValue); + result = intermediate.addIndex(EOpIndexDirect, base, index, loc); + } else { + if (base->getType().isImplicitlySizedArray()) { + if (base->getAsSymbolNode() && isIoResizeArray(base->getType())) + error(loc, "", "[", "array must be sized by a redeclaration or layout qualifier before being indexed with a variable"); + else + error(loc, "", "[", "array must be redeclared with a size before being indexed with a variable"); + } + if (base->getBasicType() == EbtBlock) { + if (base->getQualifier().storage == EvqBuffer) + requireProfile(base->getLoc(), ~EEsProfile, "variable indexing buffer block array"); + else if (base->getQualifier().storage == EvqUniform) + profileRequires(base->getLoc(), EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5, + "variable indexing uniform block array"); + else { + // input/output blocks either don't exist or can be variable indexed + } + } else if (language == EShLangFragment && base->getQualifier().isPipeOutput()) + requireProfile(base->getLoc(), ~EEsProfile, "variable indexing fragment shader output array"); + else if (base->getBasicType() == EbtSampler && version >= 130) { + const char* explanation = "variable indexing sampler array"; + requireProfile(base->getLoc(), EEsProfile | ECoreProfile | ECompatibilityProfile, explanation); + profileRequires(base->getLoc(), EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5, explanation); + profileRequires(base->getLoc(), ECoreProfile | ECompatibilityProfile, 400, nullptr, explanation); + } + + result = intermediate.addIndex(EOpIndexIndirect, base, index, loc); + } + } + + if (result == nullptr) { + // Insert dummy error-recovery result + result = intermediate.addConstantUnion(0.0, EbtFloat, loc); + } else { + // Insert valid dereferenced result + TType newType(base->getType(), 0); // dereferenced type + if (base->getType().getQualifier().isConstant() && index->getQualifier().isConstant()) { + newType.getQualifier().storage = EvqConst; + // If base or index is a specialization constant, the result should also be a specialization constant. + if (base->getType().getQualifier().isSpecConstant() || index->getQualifier().isSpecConstant()) { + newType.getQualifier().makeSpecConstant(); + } + } else { + newType.getQualifier().makePartialTemporary(); + } + result->setType(newType); + + if (anyIndexLimits) + handleIndexLimits(loc, base, index); + } + + return result; +} + +// for ES 2.0 (version 100) limitations for almost all index operations except vertex-shader uniforms +void TParseContext::handleIndexLimits(const TSourceLoc& /*loc*/, TIntermTyped* base, TIntermTyped* index) +{ + if ((! limits.generalSamplerIndexing && base->getBasicType() == EbtSampler) || + (! limits.generalUniformIndexing && base->getQualifier().isUniformOrBuffer() && language != EShLangVertex) || + (! limits.generalAttributeMatrixVectorIndexing && base->getQualifier().isPipeInput() && language == EShLangVertex && (base->getType().isMatrix() || base->getType().isVector())) || + (! limits.generalConstantMatrixVectorIndexing && base->getAsConstantUnion()) || + (! limits.generalVariableIndexing && ! base->getType().getQualifier().isUniformOrBuffer() && + ! base->getType().getQualifier().isPipeInput() && + ! base->getType().getQualifier().isPipeOutput() && + ! base->getType().getQualifier().isConstant()) || + (! limits.generalVaryingIndexing && (base->getType().getQualifier().isPipeInput() || + base->getType().getQualifier().isPipeOutput()))) { + // it's too early to know what the inductive variables are, save it for post processing + needsIndexLimitationChecking.push_back(index); + } +} + +// Make a shared symbol have a non-shared version that can be edited by the current +// compile, such that editing its type will not change the shared version and will +// effect all nodes sharing it. +void TParseContext::makeEditable(TSymbol*& symbol) +{ + TParseContextBase::makeEditable(symbol); + + // See if it's tied to IO resizing + if (isIoResizeArray(symbol->getType())) + ioArraySymbolResizeList.push_back(symbol); +} + +// Return true if this is a geometry shader input array or tessellation control output array. +bool TParseContext::isIoResizeArray(const TType& type) const +{ + return type.isArray() && + ((language == EShLangGeometry && type.getQualifier().storage == EvqVaryingIn) || + (language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut && ! type.getQualifier().patch)); +} + +// If an array is not isIoResizeArray() but is an io array, make sure it has the right size +void TParseContext::fixIoArraySize(const TSourceLoc& loc, TType& type) +{ + if (! type.isArray() || type.getQualifier().patch || symbolTable.atBuiltInLevel()) + return; + + assert(! isIoResizeArray(type)); + + if (type.getQualifier().storage != EvqVaryingIn || type.getQualifier().patch) + return; + + if (language == EShLangTessControl || language == EShLangTessEvaluation) { + if (type.getOuterArraySize() != resources.maxPatchVertices) { + if (type.isExplicitlySizedArray()) + error(loc, "tessellation input array size must be gl_MaxPatchVertices or implicitly sized", "[]", ""); + type.changeOuterArraySize(resources.maxPatchVertices); + } + } +} + +// Issue any errors if the non-array object is missing arrayness WRT +// shader I/O that has array requirements. +// All arrayness checking is handled in array paths, this is for +void TParseContext::ioArrayCheck(const TSourceLoc& loc, const TType& type, const TString& identifier) +{ + if (! type.isArray() && ! symbolTable.atBuiltInLevel()) { + if (type.getQualifier().isArrayedIo(language) +#ifdef NV_EXTENSIONS + && !type.getQualifier().layoutPassthrough +#endif + ) + error(loc, "type must be an array:", type.getStorageQualifierString(), identifier.c_str()); + } +} + +// Handle a dereference of a geometry shader input array or tessellation control output array. +// See ioArraySymbolResizeList comment in ParseHelper.h. +// +void TParseContext::handleIoResizeArrayAccess(const TSourceLoc& /*loc*/, TIntermTyped* base) +{ + TIntermSymbol* symbolNode = base->getAsSymbolNode(); + assert(symbolNode); + if (! symbolNode) + return; + + // fix array size, if it can be fixed and needs to be fixed (will allow variable indexing) + if (symbolNode->getType().isImplicitlySizedArray()) { + int newSize = getIoArrayImplicitSize(); + if (newSize > 0) + symbolNode->getWritableType().changeOuterArraySize(newSize); + } +} + +// If there has been an input primitive declaration (geometry shader) or an output +// number of vertices declaration(tessellation shader), make sure all input array types +// match it in size. Types come either from nodes in the AST or symbols in the +// symbol table. +// +// Types without an array size will be given one. +// Types already having a size that is wrong will get an error. +// +void TParseContext::checkIoArraysConsistency(const TSourceLoc& loc, bool tailOnly) +{ + int requiredSize = getIoArrayImplicitSize(); + if (requiredSize == 0) + return; + + const char* feature; + if (language == EShLangGeometry) + feature = TQualifier::getGeometryString(intermediate.getInputPrimitive()); + else if (language == EShLangTessControl) + feature = "vertices"; + else + feature = "unknown"; + + if (tailOnly) { + checkIoArrayConsistency(loc, requiredSize, feature, ioArraySymbolResizeList.back()->getWritableType(), ioArraySymbolResizeList.back()->getName()); + return; + } + + for (size_t i = 0; i < ioArraySymbolResizeList.size(); ++i) + checkIoArrayConsistency(loc, requiredSize, feature, ioArraySymbolResizeList[i]->getWritableType(), ioArraySymbolResizeList[i]->getName()); +} + +int TParseContext::getIoArrayImplicitSize() const +{ + if (language == EShLangGeometry) + return TQualifier::mapGeometryToSize(intermediate.getInputPrimitive()); + else if (language == EShLangTessControl) + return intermediate.getVertices() != TQualifier::layoutNotSet ? intermediate.getVertices() : 0; + else + return 0; +} + +void TParseContext::checkIoArrayConsistency(const TSourceLoc& loc, int requiredSize, const char* feature, TType& type, const TString& name) +{ + if (type.isImplicitlySizedArray()) + type.changeOuterArraySize(requiredSize); + else if (type.getOuterArraySize() != requiredSize) { + if (language == EShLangGeometry) + error(loc, "inconsistent input primitive for array size of", feature, name.c_str()); + else if (language == EShLangTessControl) + error(loc, "inconsistent output number of vertices for array size of", feature, name.c_str()); + else + assert(0); + } +} + +// Handle seeing a binary node with a math operation. +// Returns nullptr if not semantically allowed. +TIntermTyped* TParseContext::handleBinaryMath(const TSourceLoc& loc, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right) +{ + rValueErrorCheck(loc, str, left->getAsTyped()); + rValueErrorCheck(loc, str, right->getAsTyped()); + + bool allowed = true; + switch (op) { + // TODO: Bring more source language-specific checks up from intermediate.cpp + // to the specific parse helpers for that source language. + case EOpLessThan: + case EOpGreaterThan: + case EOpLessThanEqual: + case EOpGreaterThanEqual: + if (! left->isScalar() || ! right->isScalar()) + allowed = false; + break; + default: + break; + } + + TIntermTyped* result = nullptr; + if (allowed) + result = intermediate.addBinaryMath(op, left, right, loc); + + if (result == nullptr) + binaryOpError(loc, str, left->getCompleteString(), right->getCompleteString()); + + return result; +} + +// Handle seeing a unary node with a math operation. +TIntermTyped* TParseContext::handleUnaryMath(const TSourceLoc& loc, const char* str, TOperator op, TIntermTyped* childNode) +{ + rValueErrorCheck(loc, str, childNode); + + TIntermTyped* result = intermediate.addUnaryMath(op, childNode, loc); + + if (result) + return result; + else + unaryOpError(loc, str, childNode->getCompleteString()); + + return childNode; +} + +// +// Handle seeing a base.field dereference in the grammar. +// +TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TIntermTyped* base, const TString& field) +{ + variableCheck(base); + + // + // .length() can't be resolved until we later see the function-calling syntax. + // Save away the name in the AST for now. Processing is completed in + // handleLengthMethod(). + // + if (field == "length") { + if (base->isArray()) { + profileRequires(loc, ENoProfile, 120, E_GL_3DL_array_objects, ".length"); + profileRequires(loc, EEsProfile, 300, nullptr, ".length"); + } else if (base->isVector() || base->isMatrix()) { + const char* feature = ".length() on vectors and matrices"; + requireProfile(loc, ~EEsProfile, feature); + profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, feature); + } else { + error(loc, "does not operate on this type:", field.c_str(), base->getType().getCompleteString().c_str()); + + return base; + } + + return intermediate.addMethod(base, TType(EbtInt), &field, loc); + } + + // It's not .length() if we get to here. + + if (base->isArray()) { + error(loc, "cannot apply to an array:", ".", field.c_str()); + + return base; + } + + // It's neither an array nor .length() if we get here, + // leaving swizzles and struct/block dereferences. + + TIntermTyped* result = base; + if ((base->isVector() || base->isScalar()) && + (base->isFloatingDomain() || base->isIntegerDomain() || base->getBasicType() == EbtBool)) { + if (base->isScalar()) { + const char* dotFeature = "scalar swizzle"; + requireProfile(loc, ~EEsProfile, dotFeature); + profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, dotFeature); + } + + TSwizzleSelectors selectors; + parseSwizzleSelector(loc, field, base->getVectorSize(), selectors); + + if (base->isScalar()) { + if (selectors.size() == 1) + return result; + else { + TType type(base->getBasicType(), EvqTemporary, selectors.size()); + // Swizzle operations propagate specialization-constantness + if (base->getQualifier().isSpecConstant()) + type.getQualifier().makeSpecConstant(); + return addConstructor(loc, base, type); + } + } + + if (base->getType().getQualifier().isFrontEndConstant()) + result = intermediate.foldSwizzle(base, selectors, loc); + else { + if (selectors.size() == 1) { + TIntermTyped* index = intermediate.addConstantUnion(selectors[0], loc); + result = intermediate.addIndex(EOpIndexDirect, base, index, loc); + result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision)); + } else { + TIntermTyped* index = intermediate.addSwizzle(selectors, loc); + result = intermediate.addIndex(EOpVectorSwizzle, base, index, loc); + result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision, selectors.size())); + } + // Swizzle operations propagate specialization-constantness + if (base->getType().getQualifier().isSpecConstant()) + result->getWritableType().getQualifier().makeSpecConstant(); + } + } else if (base->getBasicType() == EbtStruct || base->getBasicType() == EbtBlock) { + const TTypeList* fields = base->getType().getStruct(); + bool fieldFound = false; + int member; + for (member = 0; member < (int)fields->size(); ++member) { + if ((*fields)[member].type->getFieldName() == field) { + fieldFound = true; + break; + } + } + if (fieldFound) { + if (base->getType().getQualifier().isFrontEndConstant()) + result = intermediate.foldDereference(base, member, loc); + else { + blockMemberExtensionCheck(loc, base, field); + TIntermTyped* index = intermediate.addConstantUnion(member, loc); + result = intermediate.addIndex(EOpIndexDirectStruct, base, index, loc); + result->setType(*(*fields)[member].type); + } + } else + error(loc, "no such field in structure", field.c_str(), ""); + } else + error(loc, "does not apply to this type:", field.c_str(), base->getType().getCompleteString().c_str()); + + // Propagate noContraction up the dereference chain + if (base->getQualifier().noContraction) + result->getWritableType().getQualifier().noContraction = true; + + return result; +} + +void TParseContext::blockMemberExtensionCheck(const TSourceLoc& loc, const TIntermTyped* /*base*/, const TString& field) +{ + if (profile == EEsProfile && field == "gl_PointSize") { + if (language == EShLangGeometry) + requireExtensions(loc, Num_AEP_geometry_point_size, AEP_geometry_point_size, "gl_PointSize"); + else if (language == EShLangTessControl || language == EShLangTessEvaluation) + requireExtensions(loc, Num_AEP_tessellation_point_size, AEP_tessellation_point_size, "gl_PointSize"); + } +} + +// +// Handle seeing a function declarator in the grammar. This is the precursor +// to recognizing a function prototype or function definition. +// +TFunction* TParseContext::handleFunctionDeclarator(const TSourceLoc& loc, TFunction& function, bool prototype) +{ + // ES can't declare prototypes inside functions + if (! symbolTable.atGlobalLevel()) + requireProfile(loc, ~EEsProfile, "local function declaration"); + + // + // Multiple declarations of the same function name are allowed. + // + // If this is a definition, the definition production code will check for redefinitions + // (we don't know at this point if it's a definition or not). + // + // Redeclarations (full signature match) are allowed. But, return types and parameter qualifiers must also match. + // - except ES 100, which only allows a single prototype + // + // ES 100 does not allow redefining, but does allow overloading of built-in functions. + // ES 300 does not allow redefining or overloading of built-in functions. + // + bool builtIn; + TSymbol* symbol = symbolTable.find(function.getMangledName(), &builtIn); + if (symbol && symbol->getAsFunction() && builtIn) + requireProfile(loc, ~EEsProfile, "redefinition of built-in function"); + const TFunction* prevDec = symbol ? symbol->getAsFunction() : 0; + if (prevDec) { + if (prevDec->isPrototyped() && prototype) + profileRequires(loc, EEsProfile, 300, nullptr, "multiple prototypes for same function"); + if (prevDec->getType() != function.getType()) + error(loc, "overloaded functions must have the same return type", function.getType().getBasicTypeString().c_str(), ""); + for (int i = 0; i < prevDec->getParamCount(); ++i) { + if ((*prevDec)[i].type->getQualifier().storage != function[i].type->getQualifier().storage) + error(loc, "overloaded functions must have the same parameter storage qualifiers for argument", function[i].type->getStorageQualifierString(), "%d", i+1); + + if ((*prevDec)[i].type->getQualifier().precision != function[i].type->getQualifier().precision) + error(loc, "overloaded functions must have the same parameter precision qualifiers for argument", function[i].type->getPrecisionQualifierString(), "%d", i+1); + } + } + + arrayObjectCheck(loc, function.getType(), "array in function return type"); + + if (prototype) { + // All built-in functions are defined, even though they don't have a body. + // Count their prototype as a definition instead. + if (symbolTable.atBuiltInLevel()) + function.setDefined(); + else { + if (prevDec && ! builtIn) + symbol->getAsFunction()->setPrototyped(); // need a writable one, but like having prevDec as a const + function.setPrototyped(); + } + } + + // This insert won't actually insert it if it's a duplicate signature, but it will still check for + // other forms of name collisions. + if (! symbolTable.insert(function)) + error(loc, "function name is redeclaration of existing name", function.getName().c_str(), ""); + + // + // If this is a redeclaration, it could also be a definition, + // in which case, we need to use the parameter names from this one, and not the one that's + // being redeclared. So, pass back this declaration, not the one in the symbol table. + // + return &function; +} + +// +// Handle seeing the function prototype in front of a function definition in the grammar. +// The body is handled after this function returns. +// +TIntermAggregate* TParseContext::handleFunctionDefinition(const TSourceLoc& loc, TFunction& function) +{ + currentCaller = function.getMangledName(); + TSymbol* symbol = symbolTable.find(function.getMangledName()); + TFunction* prevDec = symbol ? symbol->getAsFunction() : nullptr; + + if (! prevDec) + error(loc, "can't find function", function.getName().c_str(), ""); + // Note: 'prevDec' could be 'function' if this is the first time we've seen function + // as it would have just been put in the symbol table. Otherwise, we're looking up + // an earlier occurrence. + + if (prevDec && prevDec->isDefined()) { + // Then this function already has a body. + error(loc, "function already has a body", function.getName().c_str(), ""); + } + if (prevDec && ! prevDec->isDefined()) { + prevDec->setDefined(); + + // Remember the return type for later checking for RETURN statements. + currentFunctionType = &(prevDec->getType()); + } else + currentFunctionType = new TType(EbtVoid); + functionReturnsValue = false; + + // Check for entry point + if (function.getName().compare(intermediate.getEntryPointName().c_str()) == 0) { + intermediate.setEntryPointMangledName(function.getMangledName().c_str()); + intermediate.incrementEntryPointCount(); + inMain = true; + } else + inMain = false; + + // + // Raise error message if main function takes any parameters or returns anything other than void + // + if (inMain) { + if (function.getParamCount() > 0) + error(loc, "function cannot take any parameter(s)", function.getName().c_str(), ""); + if (function.getType().getBasicType() != EbtVoid) + error(loc, "", function.getType().getBasicTypeString().c_str(), "entry point cannot return a value"); + } + + // + // New symbol table scope for body of function plus its arguments + // + symbolTable.push(); + + // + // Insert parameters into the symbol table. + // If the parameter has no name, it's not an error, just don't insert it + // (could be used for unused args). + // + // Also, accumulate the list of parameters into the HIL, so lower level code + // knows where to find parameters. + // + TIntermAggregate* paramNodes = new TIntermAggregate; + for (int i = 0; i < function.getParamCount(); i++) { + TParameter& param = function[i]; + if (param.name != nullptr) { + TVariable *variable = new TVariable(param.name, *param.type); + + // Insert the parameters with name in the symbol table. + if (! symbolTable.insert(*variable)) + error(loc, "redefinition", variable->getName().c_str(), ""); + else { + // Transfer ownership of name pointer to symbol table. + param.name = nullptr; + + // Add the parameter to the HIL + paramNodes = intermediate.growAggregate(paramNodes, + intermediate.addSymbol(*variable, loc), + loc); + } + } else + paramNodes = intermediate.growAggregate(paramNodes, intermediate.addSymbol(*param.type, loc), loc); + } + intermediate.setAggregateOperator(paramNodes, EOpParameters, TType(EbtVoid), loc); + loopNestingLevel = 0; + statementNestingLevel = 0; + controlFlowNestingLevel = 0; + postEntryPointReturn = false; + + return paramNodes; +} + +// +// Handle seeing function call syntax in the grammar, which could be any of +// - .length() method +// - constructor +// - a call to a built-in function mapped to an operator +// - a call to a built-in function that will remain a function call (e.g., texturing) +// - user function +// - subroutine call (not implemented yet) +// +TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction* function, TIntermNode* arguments) +{ + TIntermTyped* result = nullptr; + + if (function->getBuiltInOp() == EOpArrayLength) + result = handleLengthMethod(loc, function, arguments); + else if (function->getBuiltInOp() != EOpNull) { + // + // Then this should be a constructor. + // Don't go through the symbol table for constructors. + // Their parameters will be verified algorithmically. + // + TType type(EbtVoid); // use this to get the type back + if (! constructorError(loc, arguments, *function, function->getBuiltInOp(), type)) { + // + // It's a constructor, of type 'type'. + // + result = addConstructor(loc, arguments, type); + if (result == nullptr) + error(loc, "cannot construct with these arguments", type.getCompleteString().c_str(), ""); + } + } else { + // + // Find it in the symbol table. + // + const TFunction* fnCandidate; + bool builtIn; + fnCandidate = findFunction(loc, *function, builtIn); + if (fnCandidate) { + // This is a declared function that might map to + // - a built-in operator, + // - a built-in function not mapped to an operator, or + // - a user function. + + // Error check for a function requiring specific extensions present. + if (builtIn && fnCandidate->getNumExtensions()) + requireExtensions(loc, fnCandidate->getNumExtensions(), fnCandidate->getExtensions(), fnCandidate->getName().c_str()); + + if (arguments) { + // Make sure qualifications work for these arguments. + TIntermAggregate* aggregate = arguments->getAsAggregate(); + for (int i = 0; i < fnCandidate->getParamCount(); ++i) { + // At this early point there is a slight ambiguity between whether an aggregate 'arguments' + // is the single argument itself or its children are the arguments. Only one argument + // means take 'arguments' itself as the one argument. + TIntermNode* arg = fnCandidate->getParamCount() == 1 ? arguments : (aggregate ? aggregate->getSequence()[i] : arguments); + TQualifier& formalQualifier = (*fnCandidate)[i].type->getQualifier(); + if (formalQualifier.isParamOutput()) { + if (lValueErrorCheck(arguments->getLoc(), "assign", arg->getAsTyped())) + error(arguments->getLoc(), "Non-L-value cannot be passed for 'out' or 'inout' parameters.", "out", ""); + } + TQualifier& argQualifier = arg->getAsTyped()->getQualifier(); + if (argQualifier.isMemory()) { + const char* message = "argument cannot drop memory qualifier when passed to formal parameter"; + if (argQualifier.volatil && ! formalQualifier.volatil) + error(arguments->getLoc(), message, "volatile", ""); + if (argQualifier.coherent && ! formalQualifier.coherent) + error(arguments->getLoc(), message, "coherent", ""); + if (argQualifier.readonly && ! formalQualifier.readonly) + error(arguments->getLoc(), message, "readonly", ""); + if (argQualifier.writeonly && ! formalQualifier.writeonly) + error(arguments->getLoc(), message, "writeonly", ""); + } + // TODO 4.5 functionality: A shader will fail to compile + // if the value passed to the memargument of an atomic memory function does not correspond to a buffer or + // shared variable. It is acceptable to pass an element of an array or a single component of a vector to the + // memargument of an atomic memory function, as long as the underlying array or vector is a buffer or + // shared variable. + } + + // Convert 'in' arguments + addInputArgumentConversions(*fnCandidate, arguments); // arguments may be modified if it's just a single argument node + } + + if (builtIn && fnCandidate->getBuiltInOp() != EOpNull) { + // A function call mapped to a built-in operation. + result = handleBuiltInFunctionCall(loc, *arguments, *fnCandidate); + } else { + // This is a function call not mapped to built-in operator. + // It could still be a built-in function, but only if PureOperatorBuiltins == false. + result = intermediate.setAggregateOperator(arguments, EOpFunctionCall, fnCandidate->getType(), loc); + TIntermAggregate* call = result->getAsAggregate(); + call->setName(fnCandidate->getMangledName()); + + // this is how we know whether the given function is a built-in function or a user-defined function + // if builtIn == false, it's a userDefined -> could be an overloaded built-in function also + // if builtIn == true, it's definitely a built-in function with EOpNull + if (! builtIn) { + call->setUserDefined(); + if (symbolTable.atGlobalLevel()) { + requireProfile(loc, ~EEsProfile, "calling user function from global scope"); + intermediate.addToCallGraph(infoSink, "main(", fnCandidate->getMangledName()); + } else + intermediate.addToCallGraph(infoSink, currentCaller, fnCandidate->getMangledName()); + } + + if (builtIn) + nonOpBuiltInCheck(loc, *fnCandidate, *call); + else + userFunctionCallCheck(loc, *call); + } + + // Convert 'out' arguments. If it was a constant folded built-in, it won't be an aggregate anymore. + // Built-ins with a single argument aren't called with an aggregate, but they also don't have an output. + // Also, build the qualifier list for user function calls, which are always called with an aggregate. + if (result->getAsAggregate()) { + TQualifierList& qualifierList = result->getAsAggregate()->getQualifierList(); + for (int i = 0; i < fnCandidate->getParamCount(); ++i) { + TStorageQualifier qual = (*fnCandidate)[i].type->getQualifier().storage; + qualifierList.push_back(qual); + } + result = addOutputArgumentConversions(*fnCandidate, *result->getAsAggregate()); + } + } + } + + // generic error recovery + // TODO: simplification: localize all the error recoveries that look like this, and taking type into account to reduce cascades + if (result == nullptr) + result = intermediate.addConstantUnion(0.0, EbtFloat, loc); + + return result; +} + +TIntermTyped* TParseContext::handleBuiltInFunctionCall(TSourceLoc loc, TIntermNode& arguments, + const TFunction& function) +{ + checkLocation(loc, function.getBuiltInOp()); + TIntermTyped *result = intermediate.addBuiltInFunctionCall(loc, function.getBuiltInOp(), + function.getParamCount() == 1, + &arguments, function.getType()); + if (obeyPrecisionQualifiers()) + computeBuiltinPrecisions(*result, function); + + if (result == nullptr) { + error(arguments.getLoc(), " wrong operand type", "Internal Error", + "built in unary operator function. Type: %s", + static_cast(&arguments)->getCompleteString().c_str()); + } else if (result->getAsOperator()) + builtInOpCheck(loc, function, *result->getAsOperator()); + + return result; +} + +// "The operation of a built-in function can have a different precision +// qualification than the precision qualification of the resulting value. +// These two precision qualifications are established as follows. +// +// The precision qualification of the operation of a built-in function is +// based on the precision qualification of its input arguments and formal +// parameters: When a formal parameter specifies a precision qualifier, +// that is used, otherwise, the precision qualification of the calling +// argument is used. The highest precision of these will be the precision +// qualification of the operation of the built-in function. Generally, +// this is applied across all arguments to a built-in function, with the +// exceptions being: +// - bitfieldExtract and bitfieldInsert ignore the 'offset' and 'bits' +// arguments. +// - interpolateAt* functions only look at the 'interpolant' argument. +// +// The precision qualification of the result of a built-in function is +// determined in one of the following ways: +// +// - For the texture sampling, image load, and image store functions, +// the precision of the return type matches the precision of the +// sampler type +// +// Otherwise: +// +// - For prototypes that do not specify a resulting precision qualifier, +// the precision will be the same as the precision of the operation. +// +// - For prototypes that do specify a resulting precision qualifier, +// the specified precision qualifier is the precision qualification of +// the result." +// +void TParseContext::computeBuiltinPrecisions(TIntermTyped& node, const TFunction& function) +{ + TPrecisionQualifier operationPrecision = EpqNone; + TPrecisionQualifier resultPrecision = EpqNone; + + TIntermOperator* opNode = node.getAsOperator(); + if (opNode == nullptr) + return; + + if (TIntermUnary* unaryNode = node.getAsUnaryNode()) { + operationPrecision = std::max(function[0].type->getQualifier().precision, + unaryNode->getOperand()->getType().getQualifier().precision); + if (function.getType().getBasicType() != EbtBool) + resultPrecision = function.getType().getQualifier().precision == EpqNone ? + operationPrecision : + function.getType().getQualifier().precision; + } else if (TIntermAggregate* agg = node.getAsAggregate()) { + TIntermSequence& sequence = agg->getSequence(); + unsigned int numArgs = (unsigned int)sequence.size(); + switch (agg->getOp()) { + case EOpBitfieldExtract: + numArgs = 1; + break; + case EOpBitfieldInsert: + numArgs = 2; + break; + case EOpInterpolateAtCentroid: + case EOpInterpolateAtOffset: + case EOpInterpolateAtSample: + numArgs = 1; + break; + default: + break; + } + // find the maximum precision from the arguments and parameters + for (unsigned int arg = 0; arg < numArgs; ++arg) { + operationPrecision = std::max(operationPrecision, sequence[arg]->getAsTyped()->getQualifier().precision); + operationPrecision = std::max(operationPrecision, function[arg].type->getQualifier().precision); + } + // compute the result precision +#ifdef AMD_EXTENSIONS + if (agg->isSampling() || + agg->getOp() == EOpImageLoad || agg->getOp() == EOpImageStore || + agg->getOp() == EOpImageLoadLod || agg->getOp() == EOpImageStoreLod) +#else + if (agg->isSampling() || agg->getOp() == EOpImageLoad || agg->getOp() == EOpImageStore) +#endif + resultPrecision = sequence[0]->getAsTyped()->getQualifier().precision; + else if (function.getType().getBasicType() != EbtBool) + resultPrecision = function.getType().getQualifier().precision == EpqNone ? + operationPrecision : + function.getType().getQualifier().precision; + } + + // Propagate precision through this node and its children. That algorithm stops + // when a precision is found, so start by clearing this subroot precision + opNode->getQualifier().precision = EpqNone; + if (operationPrecision != EpqNone) { + opNode->propagatePrecision(operationPrecision); + opNode->setOperationPrecision(operationPrecision); + } + // Now, set the result precision, which might not match + opNode->getQualifier().precision = resultPrecision; +} + +TIntermNode* TParseContext::handleReturnValue(const TSourceLoc& loc, TIntermTyped* value) +{ + functionReturnsValue = true; + if (currentFunctionType->getBasicType() == EbtVoid) { + error(loc, "void function cannot return a value", "return", ""); + return intermediate.addBranch(EOpReturn, loc); + } else if (*currentFunctionType != value->getType()) { + TIntermTyped* converted = intermediate.addConversion(EOpReturn, *currentFunctionType, value); + if (converted) { + if (*currentFunctionType != converted->getType()) + error(loc, "cannot convert return value to function return type", "return", ""); + if (version < 420) + warn(loc, "type conversion on return values was not explicitly allowed until version 420", "return", ""); + return intermediate.addBranch(EOpReturn, converted, loc); + } else { + error(loc, "type does not match, or is not convertible to, the function's return type", "return", ""); + return intermediate.addBranch(EOpReturn, value, loc); + } + } else + return intermediate.addBranch(EOpReturn, value, loc); +} + +// See if the operation is being done in an illegal location. +void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op) +{ + switch (op) { + case EOpBarrier: + if (language == EShLangTessControl) { + if (controlFlowNestingLevel > 0) + error(loc, "tessellation control barrier() cannot be placed within flow control", "", ""); + if (! inMain) + error(loc, "tessellation control barrier() must be in main()", "", ""); + else if (postEntryPointReturn) + error(loc, "tessellation control barrier() cannot be placed after a return from main()", "", ""); + } + break; + default: + break; + } +} + +// Finish processing object.length(). This started earlier in handleDotDereference(), where +// the ".length" part was recognized and semantically checked, and finished here where the +// function syntax "()" is recognized. +// +// Return resulting tree node. +TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction* function, TIntermNode* intermNode) +{ + int length = 0; + + if (function->getParamCount() > 0) + error(loc, "method does not accept any arguments", function->getName().c_str(), ""); + else { + const TType& type = intermNode->getAsTyped()->getType(); + if (type.isArray()) { + if (type.isRuntimeSizedArray()) { + // Create a unary op and let the back end handle it + return intermediate.addBuiltInFunctionCall(loc, EOpArrayLength, true, intermNode, TType(EbtInt)); + } else if (type.isImplicitlySizedArray()) { + if (intermNode->getAsSymbolNode() && isIoResizeArray(type)) { + // We could be between a layout declaration that gives a built-in io array implicit size and + // a user redeclaration of that array, meaning we have to substitute its implicit size here + // without actually redeclaring the array. (It is an error to use a member before the + // redeclaration, but not an error to use the array name itself.) + const TString& name = intermNode->getAsSymbolNode()->getName(); + if (name == "gl_in" || name == "gl_out") + length = getIoArrayImplicitSize(); + } + if (length == 0) { + if (intermNode->getAsSymbolNode() && isIoResizeArray(type)) + error(loc, "", function->getName().c_str(), "array must first be sized by a redeclaration or layout qualifier"); + else + error(loc, "", function->getName().c_str(), "array must be declared with a size before using this method"); + } + } else if (type.getOuterArrayNode()) { + // If the array's outer size is specified by an intermediate node, it means the array's length + // was specified by a specialization constant. In such a case, we should return the node of the + // specialization constants to represent the length. + return type.getOuterArrayNode(); + } else + length = type.getOuterArraySize(); + } else if (type.isMatrix()) + length = type.getMatrixCols(); + else if (type.isVector()) + length = type.getVectorSize(); + else { + // we should not get here, because earlier semantic checking should have prevented this path + error(loc, ".length()", "unexpected use of .length()", ""); + } + } + + if (length == 0) + length = 1; + + return intermediate.addConstantUnion(length, loc); +} + +// +// Add any needed implicit conversions for function-call arguments to input parameters. +// +void TParseContext::addInputArgumentConversions(const TFunction& function, TIntermNode*& arguments) const +{ + TIntermAggregate* aggregate = arguments->getAsAggregate(); + + // Process each argument's conversion + for (int i = 0; i < function.getParamCount(); ++i) { + // At this early point there is a slight ambiguity between whether an aggregate 'arguments' + // is the single argument itself or its children are the arguments. Only one argument + // means take 'arguments' itself as the one argument. + TIntermTyped* arg = function.getParamCount() == 1 ? arguments->getAsTyped() : (aggregate ? aggregate->getSequence()[i]->getAsTyped() : arguments->getAsTyped()); + if (*function[i].type != arg->getType()) { + if (function[i].type->getQualifier().isParamInput()) { + // In-qualified arguments just need an extra node added above the argument to + // convert to the correct type. + arg = intermediate.addConversion(EOpFunctionCall, *function[i].type, arg); + if (arg) { + if (function.getParamCount() == 1) + arguments = arg; + else { + if (aggregate) + aggregate->getSequence()[i] = arg; + else + arguments = arg; + } + } + } + } + } +} + +// +// Add any needed implicit output conversions for function-call arguments. This +// can require a new tree topology, complicated further by whether the function +// has a return value. +// +// Returns a node of a subtree that evaluates to the return value of the function. +// +TIntermTyped* TParseContext::addOutputArgumentConversions(const TFunction& function, TIntermAggregate& intermNode) const +{ + TIntermSequence& arguments = intermNode.getSequence(); + + // Will there be any output conversions? + bool outputConversions = false; + for (int i = 0; i < function.getParamCount(); ++i) { + if (*function[i].type != arguments[i]->getAsTyped()->getType() && function[i].type->getQualifier().isParamOutput()) { + outputConversions = true; + break; + } + } + + if (! outputConversions) + return &intermNode; + + // Setup for the new tree, if needed: + // + // Output conversions need a different tree topology. + // Out-qualified arguments need a temporary of the correct type, with the call + // followed by an assignment of the temporary to the original argument: + // void: function(arg, ...) -> ( function(tempArg, ...), arg = tempArg, ...) + // ret = function(arg, ...) -> ret = (tempRet = function(tempArg, ...), arg = tempArg, ..., tempRet) + // Where the "tempArg" type needs no conversion as an argument, but will convert on assignment. + TIntermTyped* conversionTree = nullptr; + TVariable* tempRet = nullptr; + if (intermNode.getBasicType() != EbtVoid) { + // do the "tempRet = function(...), " bit from above + tempRet = makeInternalVariable("tempReturn", intermNode.getType()); + TIntermSymbol* tempRetNode = intermediate.addSymbol(*tempRet, intermNode.getLoc()); + conversionTree = intermediate.addAssign(EOpAssign, tempRetNode, &intermNode, intermNode.getLoc()); + } else + conversionTree = &intermNode; + + conversionTree = intermediate.makeAggregate(conversionTree); + + // Process each argument's conversion + for (int i = 0; i < function.getParamCount(); ++i) { + if (*function[i].type != arguments[i]->getAsTyped()->getType()) { + if (function[i].type->getQualifier().isParamOutput()) { + // Out-qualified arguments need to use the topology set up above. + // do the " ...(tempArg, ...), arg = tempArg" bit from above + TVariable* tempArg = makeInternalVariable("tempArg", *function[i].type); + tempArg->getWritableType().getQualifier().makeTemporary(); + TIntermSymbol* tempArgNode = intermediate.addSymbol(*tempArg, intermNode.getLoc()); + TIntermTyped* tempAssign = intermediate.addAssign(EOpAssign, arguments[i]->getAsTyped(), tempArgNode, arguments[i]->getLoc()); + conversionTree = intermediate.growAggregate(conversionTree, tempAssign, arguments[i]->getLoc()); + // replace the argument with another node for the same tempArg variable + arguments[i] = intermediate.addSymbol(*tempArg, intermNode.getLoc()); + } + } + } + + // Finalize the tree topology (see bigger comment above). + if (tempRet) { + // do the "..., tempRet" bit from above + TIntermSymbol* tempRetNode = intermediate.addSymbol(*tempRet, intermNode.getLoc()); + conversionTree = intermediate.growAggregate(conversionTree, tempRetNode, intermNode.getLoc()); + } + conversionTree = intermediate.setAggregateOperator(conversionTree, EOpComma, intermNode.getType(), intermNode.getLoc()); + + return conversionTree; +} + +// +// Do additional checking of built-in function calls that is not caught +// by normal semantic checks on argument type, extension tagging, etc. +// +// Assumes there has been a semantically correct match to a built-in function prototype. +// +void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCandidate, TIntermOperator& callNode) +{ + // Set up convenience accessors to the argument(s). There is almost always + // multiple arguments for the cases below, but when there might be one, + // check the unaryArg first. + const TIntermSequence* argp = nullptr; // confusing to use [] syntax on a pointer, so this is to help get a reference + const TIntermTyped* unaryArg = nullptr; + const TIntermTyped* arg0 = nullptr; + if (callNode.getAsAggregate()) { + argp = &callNode.getAsAggregate()->getSequence(); + if (argp->size() > 0) + arg0 = (*argp)[0]->getAsTyped(); + } else { + assert(callNode.getAsUnaryNode()); + unaryArg = callNode.getAsUnaryNode()->getOperand(); + arg0 = unaryArg; + } + + TString featureString; + const char* feature = nullptr; + switch (callNode.getOp()) { + case EOpTextureGather: + case EOpTextureGatherOffset: + case EOpTextureGatherOffsets: + { + // Figure out which variants are allowed by what extensions, + // and what arguments must be constant for which situations. + + featureString = fnCandidate.getName() + "(...)"; + feature = featureString.c_str(); + profileRequires(loc, EEsProfile, 310, nullptr, feature); + int compArg = -1; // track which argument, if any, is the constant component argument + switch (callNode.getOp()) { + case EOpTextureGather: + // More than two arguments needs gpu_shader5, and rectangular or shadow needs gpu_shader5, + // otherwise, need GL_ARB_texture_gather. + if (fnCandidate.getParamCount() > 2 || fnCandidate[0].type->getSampler().dim == EsdRect || fnCandidate[0].type->getSampler().shadow) { + profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_gpu_shader5, feature); + if (! fnCandidate[0].type->getSampler().shadow) + compArg = 2; + } else + profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_texture_gather, feature); + break; + case EOpTextureGatherOffset: + // GL_ARB_texture_gather is good enough for 2D non-shadow textures with no component argument + if (fnCandidate[0].type->getSampler().dim == Esd2D && ! fnCandidate[0].type->getSampler().shadow && fnCandidate.getParamCount() == 3) + profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_texture_gather, feature); + else + profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_gpu_shader5, feature); + if (! (*argp)[fnCandidate[0].type->getSampler().shadow ? 3 : 2]->getAsConstantUnion()) + profileRequires(loc, EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5, + "non-constant offset argument"); + if (! fnCandidate[0].type->getSampler().shadow) + compArg = 3; + break; + case EOpTextureGatherOffsets: + profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_gpu_shader5, feature); + if (! fnCandidate[0].type->getSampler().shadow) + compArg = 3; + // check for constant offsets + if (! (*argp)[fnCandidate[0].type->getSampler().shadow ? 3 : 2]->getAsConstantUnion()) + error(loc, "must be a compile-time constant:", feature, "offsets argument"); + break; + default: + break; + } + + if (compArg > 0 && compArg < fnCandidate.getParamCount()) { + if ((*argp)[compArg]->getAsConstantUnion()) { + int value = (*argp)[compArg]->getAsConstantUnion()->getConstArray()[0].getIConst(); + if (value < 0 || value > 3) + error(loc, "must be 0, 1, 2, or 3:", feature, "component argument"); + } else + error(loc, "must be a compile-time constant:", feature, "component argument"); + } + +#ifdef AMD_EXTENSIONS + bool bias = false; + if (callNode.getOp() == EOpTextureGather) + bias = fnCandidate.getParamCount() > 3; + else if (callNode.getOp() == EOpTextureGatherOffset || + callNode.getOp() == EOpTextureGatherOffsets) + bias = fnCandidate.getParamCount() > 4; + + if (bias) { + featureString = fnCandidate.getName() + "with bias argument"; + feature = featureString.c_str(); + profileRequires(loc, ~EEsProfile, 450, nullptr, feature); + requireExtensions(loc, 1, &E_GL_AMD_texture_gather_bias_lod, feature); + } +#endif + + break; + } + +#ifdef AMD_EXTENSIONS + case EOpSparseTextureGather: + case EOpSparseTextureGatherOffset: + case EOpSparseTextureGatherOffsets: + { + bool bias = false; + if (callNode.getOp() == EOpSparseTextureGather) + bias = fnCandidate.getParamCount() > 4; + else if (callNode.getOp() == EOpSparseTextureGatherOffset || + callNode.getOp() == EOpSparseTextureGatherOffsets) + bias = fnCandidate.getParamCount() > 5; + + if (bias) { + featureString = fnCandidate.getName() + "with bias argument"; + feature = featureString.c_str(); + profileRequires(loc, ~EEsProfile, 450, nullptr, feature); + requireExtensions(loc, 1, &E_GL_AMD_texture_gather_bias_lod, feature); + } + + break; + } + + case EOpSparseTextureGatherLod: + case EOpSparseTextureGatherLodOffset: + case EOpSparseTextureGatherLodOffsets: + { + requireExtensions(loc, 1, &E_GL_ARB_sparse_texture2, fnCandidate.getName().c_str()); + break; + } +#endif + + case EOpTextureOffset: + case EOpTextureFetchOffset: + case EOpTextureProjOffset: + case EOpTextureLodOffset: + case EOpTextureProjLodOffset: + case EOpTextureGradOffset: + case EOpTextureProjGradOffset: + { + // Handle texture-offset limits checking + // Pick which argument has to hold constant offsets + int arg = -1; + switch (callNode.getOp()) { + case EOpTextureOffset: arg = 2; break; + case EOpTextureFetchOffset: arg = (arg0->getType().getSampler().dim != EsdRect) ? 3 : 2; break; + case EOpTextureProjOffset: arg = 2; break; + case EOpTextureLodOffset: arg = 3; break; + case EOpTextureProjLodOffset: arg = 3; break; + case EOpTextureGradOffset: arg = 4; break; + case EOpTextureProjGradOffset: arg = 4; break; + default: + assert(0); + break; + } + + if (arg > 0) { + if (! (*argp)[arg]->getAsConstantUnion()) + error(loc, "argument must be compile-time constant", "texel offset", ""); + else { + const TType& type = (*argp)[arg]->getAsTyped()->getType(); + for (int c = 0; c < type.getVectorSize(); ++c) { + int offset = (*argp)[arg]->getAsConstantUnion()->getConstArray()[c].getIConst(); + if (offset > resources.maxProgramTexelOffset || offset < resources.minProgramTexelOffset) + error(loc, "value is out of range:", "texel offset", "[gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]"); + } + } + } + + break; + } + + case EOpTextureQuerySamples: + case EOpImageQuerySamples: + // GL_ARB_shader_texture_image_samples + profileRequires(loc, ~EEsProfile, 450, E_GL_ARB_shader_texture_image_samples, "textureSamples and imageSamples"); + break; + + case EOpImageAtomicAdd: + case EOpImageAtomicMin: + case EOpImageAtomicMax: + case EOpImageAtomicAnd: + case EOpImageAtomicOr: + case EOpImageAtomicXor: + case EOpImageAtomicExchange: + case EOpImageAtomicCompSwap: + { + // Make sure the image types have the correct layout() format and correct argument types + const TType& imageType = arg0->getType(); + if (imageType.getSampler().type == EbtInt || imageType.getSampler().type == EbtUint) { + if (imageType.getQualifier().layoutFormat != ElfR32i && imageType.getQualifier().layoutFormat != ElfR32ui) + error(loc, "only supported on image with format r32i or r32ui", fnCandidate.getName().c_str(), ""); + } else { + if (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") != 0) + error(loc, "only supported on integer images", fnCandidate.getName().c_str(), ""); + else if (imageType.getQualifier().layoutFormat != ElfR32f && profile == EEsProfile) + error(loc, "only supported on image with format r32f", fnCandidate.getName().c_str(), ""); + } + + break; + } + +#ifdef NV_EXTENSIONS + case EOpAtomicAdd: + case EOpAtomicMin: + case EOpAtomicMax: + case EOpAtomicAnd: + case EOpAtomicOr: + case EOpAtomicXor: + case EOpAtomicExchange: + case EOpAtomicCompSwap: + { + if (arg0->getType().getBasicType() == EbtInt64 || arg0->getType().getBasicType() == EbtUint64) + requireExtensions(loc, 1, &E_GL_NV_shader_atomic_int64, fnCandidate.getName().c_str()); + + break; + } +#endif + + case EOpInterpolateAtCentroid: + case EOpInterpolateAtSample: + case EOpInterpolateAtOffset: + // Make sure the first argument is an interpolant, or an array element of an interpolant + if (arg0->getType().getQualifier().storage != EvqVaryingIn) { + // It might still be an array element. + // + // We could check more, but the semantics of the first argument are already met; the + // only way to turn an array into a float/vec* is array dereference and swizzle. + // + // ES and desktop 4.3 and earlier: swizzles may not be used + // desktop 4.4 and later: swizzles may be used + bool swizzleOkay = (profile != EEsProfile) && (version >= 440); + const TIntermTyped* base = TIntermediate::findLValueBase(arg0, swizzleOkay); + if (base == nullptr || base->getType().getQualifier().storage != EvqVaryingIn) + error(loc, "first argument must be an interpolant, or interpolant-array element", fnCandidate.getName().c_str(), ""); + } + break; + + case EOpEmitStreamVertex: + case EOpEndStreamPrimitive: + intermediate.setMultiStream(); + break; + + default: + break; + } +} + +extern bool PureOperatorBuiltins; + +// Deprecated! Use PureOperatorBuiltins == true instead, in which case this +// functionality is handled in builtInOpCheck() instead of here. +// +// Do additional checking of built-in function calls that were not mapped +// to built-in operations (e.g., texturing functions). +// +// Assumes there has been a semantically correct match to a built-in function. +// +void TParseContext::nonOpBuiltInCheck(const TSourceLoc& loc, const TFunction& fnCandidate, TIntermAggregate& callNode) +{ + // Further maintenance of this function is deprecated, because the "correct" + // future-oriented design is to not have to do string compares on function names. + + // If PureOperatorBuiltins == true, then all built-ins should be mapped + // to a TOperator, and this function would then never get called. + + assert(PureOperatorBuiltins == false); + + // built-in texturing functions get their return value precision from the precision of the sampler + if (fnCandidate.getType().getQualifier().precision == EpqNone && + fnCandidate.getParamCount() > 0 && fnCandidate[0].type->getBasicType() == EbtSampler) + callNode.getQualifier().precision = callNode.getSequence()[0]->getAsTyped()->getQualifier().precision; + + if (fnCandidate.getName().compare(0, 7, "texture") == 0) { + if (fnCandidate.getName().compare(0, 13, "textureGather") == 0) { + TString featureString = fnCandidate.getName() + "(...)"; + const char* feature = featureString.c_str(); + profileRequires(loc, EEsProfile, 310, nullptr, feature); + + int compArg = -1; // track which argument, if any, is the constant component argument + if (fnCandidate.getName().compare("textureGatherOffset") == 0) { + // GL_ARB_texture_gather is good enough for 2D non-shadow textures with no component argument + if (fnCandidate[0].type->getSampler().dim == Esd2D && ! fnCandidate[0].type->getSampler().shadow && fnCandidate.getParamCount() == 3) + profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_texture_gather, feature); + else + profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_gpu_shader5, feature); + int offsetArg = fnCandidate[0].type->getSampler().shadow ? 3 : 2; + if (! callNode.getSequence()[offsetArg]->getAsConstantUnion()) + profileRequires(loc, EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5, + "non-constant offset argument"); + if (! fnCandidate[0].type->getSampler().shadow) + compArg = 3; + } else if (fnCandidate.getName().compare("textureGatherOffsets") == 0) { + profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_gpu_shader5, feature); + if (! fnCandidate[0].type->getSampler().shadow) + compArg = 3; + // check for constant offsets + int offsetArg = fnCandidate[0].type->getSampler().shadow ? 3 : 2; + if (! callNode.getSequence()[offsetArg]->getAsConstantUnion()) + error(loc, "must be a compile-time constant:", feature, "offsets argument"); + } else if (fnCandidate.getName().compare("textureGather") == 0) { + // More than two arguments needs gpu_shader5, and rectangular or shadow needs gpu_shader5, + // otherwise, need GL_ARB_texture_gather. + if (fnCandidate.getParamCount() > 2 || fnCandidate[0].type->getSampler().dim == EsdRect || fnCandidate[0].type->getSampler().shadow) { + profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_gpu_shader5, feature); + if (! fnCandidate[0].type->getSampler().shadow) + compArg = 2; + } else + profileRequires(loc, ~EEsProfile, 400, E_GL_ARB_texture_gather, feature); + } + + if (compArg > 0 && compArg < fnCandidate.getParamCount()) { + if (callNode.getSequence()[compArg]->getAsConstantUnion()) { + int value = callNode.getSequence()[compArg]->getAsConstantUnion()->getConstArray()[0].getIConst(); + if (value < 0 || value > 3) + error(loc, "must be 0, 1, 2, or 3:", feature, "component argument"); + } else + error(loc, "must be a compile-time constant:", feature, "component argument"); + } + } else { + // this is only for functions not starting "textureGather"... + if (fnCandidate.getName().find("Offset") != TString::npos) { + + // Handle texture-offset limits checking + int arg = -1; + if (fnCandidate.getName().compare("textureOffset") == 0) + arg = 2; + else if (fnCandidate.getName().compare("texelFetchOffset") == 0) + arg = 3; + else if (fnCandidate.getName().compare("textureProjOffset") == 0) + arg = 2; + else if (fnCandidate.getName().compare("textureLodOffset") == 0) + arg = 3; + else if (fnCandidate.getName().compare("textureProjLodOffset") == 0) + arg = 3; + else if (fnCandidate.getName().compare("textureGradOffset") == 0) + arg = 4; + else if (fnCandidate.getName().compare("textureProjGradOffset") == 0) + arg = 4; + + if (arg > 0) { + if (! callNode.getSequence()[arg]->getAsConstantUnion()) + error(loc, "argument must be compile-time constant", "texel offset", ""); + else { + const TType& type = callNode.getSequence()[arg]->getAsTyped()->getType(); + for (int c = 0; c < type.getVectorSize(); ++c) { + int offset = callNode.getSequence()[arg]->getAsConstantUnion()->getConstArray()[c].getIConst(); + if (offset > resources.maxProgramTexelOffset || offset < resources.minProgramTexelOffset) + error(loc, "value is out of range:", "texel offset", "[gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]"); + } + } + } + } + } + } + + // GL_ARB_shader_texture_image_samples + if (fnCandidate.getName().compare(0, 14, "textureSamples") == 0 || fnCandidate.getName().compare(0, 12, "imageSamples") == 0) + profileRequires(loc, ~EEsProfile, 450, E_GL_ARB_shader_texture_image_samples, "textureSamples and imageSamples"); + + if (fnCandidate.getName().compare(0, 11, "imageAtomic") == 0) { + const TType& imageType = callNode.getSequence()[0]->getAsTyped()->getType(); + if (imageType.getSampler().type == EbtInt || imageType.getSampler().type == EbtUint) { + if (imageType.getQualifier().layoutFormat != ElfR32i && imageType.getQualifier().layoutFormat != ElfR32ui) + error(loc, "only supported on image with format r32i or r32ui", fnCandidate.getName().c_str(), ""); + } else { + if (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") != 0) + error(loc, "only supported on integer images", fnCandidate.getName().c_str(), ""); + else if (imageType.getQualifier().layoutFormat != ElfR32f && profile == EEsProfile) + error(loc, "only supported on image with format r32f", fnCandidate.getName().c_str(), ""); + } + } +} + +// +// Do any extra checking for a user function call. +// +void TParseContext::userFunctionCallCheck(const TSourceLoc& loc, TIntermAggregate& callNode) +{ + TIntermSequence& arguments = callNode.getSequence(); + + for (int i = 0; i < (int)arguments.size(); ++i) + samplerConstructorLocationCheck(loc, "call argument", arguments[i]); +} + +// +// Emit an error if this is a sampler constructor +// +void TParseContext::samplerConstructorLocationCheck(const TSourceLoc& loc, const char* token, TIntermNode* node) +{ + if (node->getAsOperator() && node->getAsOperator()->getOp() == EOpConstructTextureSampler) + error(loc, "sampler constructor must appear at point of use", token, ""); +} + +// +// Handle seeing a built-in constructor in a grammar production. +// +TFunction* TParseContext::handleConstructorCall(const TSourceLoc& loc, const TPublicType& publicType) +{ + TType type(publicType); + type.getQualifier().precision = EpqNone; + + if (type.isArray()) { + profileRequires(loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed constructor"); + profileRequires(loc, EEsProfile, 300, nullptr, "arrayed constructor"); + } + + TOperator op = intermediate.mapTypeToConstructorOp(type); + + if (op == EOpNull) { + error(loc, "cannot construct this type", type.getBasicString(), ""); + op = EOpConstructFloat; + TType errorType(EbtFloat); + type.shallowCopy(errorType); + } + + TString empty(""); + + return new TFunction(&empty, type, op); +} + +// Handle seeing a precision qualifier in the grammar. +void TParseContext::handlePrecisionQualifier(const TSourceLoc& /*loc*/, TQualifier& qualifier, TPrecisionQualifier precision) +{ + if (obeyPrecisionQualifiers()) + qualifier.precision = precision; +} + +// Check for messages to give on seeing a precision qualifier used in a +// declaration in the grammar. +void TParseContext::checkPrecisionQualifier(const TSourceLoc& loc, TPrecisionQualifier) +{ + if (precisionManager.shouldWarnAboutDefaults()) { + warn(loc, "all default precisions are highp; use precision statements to quiet warning, e.g.:\n" + " \"precision mediump int; precision highp float;\"", "", ""); + precisionManager.defaultWarningGiven(); + } +} + +// +// Same error message for all places assignments don't work. +// +void TParseContext::assignError(const TSourceLoc& loc, const char* op, TString left, TString right) +{ + error(loc, "", op, "cannot convert from '%s' to '%s'", + right.c_str(), left.c_str()); +} + +// +// Same error message for all places unary operations don't work. +// +void TParseContext::unaryOpError(const TSourceLoc& loc, const char* op, TString operand) +{ + error(loc, " wrong operand type", op, + "no operation '%s' exists that takes an operand of type %s (or there is no acceptable conversion)", + op, operand.c_str()); +} + +// +// Same error message for all binary operations don't work. +// +void TParseContext::binaryOpError(const TSourceLoc& loc, const char* op, TString left, TString right) +{ + error(loc, " wrong operand types:", op, + "no operation '%s' exists that takes a left-hand operand of type '%s' and " + "a right operand of type '%s' (or there is no acceptable conversion)", + op, left.c_str(), right.c_str()); +} + +// +// A basic type of EbtVoid is a key that the name string was seen in the source, but +// it was not found as a variable in the symbol table. If so, give the error +// message and insert a dummy variable in the symbol table to prevent future errors. +// +void TParseContext::variableCheck(TIntermTyped*& nodePtr) +{ + TIntermSymbol* symbol = nodePtr->getAsSymbolNode(); + if (! symbol) + return; + + if (symbol->getType().getBasicType() == EbtVoid) { + const char *extraInfoFormat = ""; + if (spvVersion.vulkan != 0 && symbol->getName() == "gl_VertexID") { + extraInfoFormat = "(Did you mean gl_VertexIndex?)"; + } else if (spvVersion.vulkan != 0 && symbol->getName() == "gl_InstanceID") { + extraInfoFormat = "(Did you mean gl_InstanceIndex?)"; + } + error(symbol->getLoc(), "undeclared identifier", symbol->getName().c_str(), extraInfoFormat); + + // Add to symbol table to prevent future error messages on the same name + if (symbol->getName().size() > 0) { + TVariable* fakeVariable = new TVariable(&symbol->getName(), TType(EbtFloat)); + symbolTable.insert(*fakeVariable); + + // substitute a symbol node for this new variable + nodePtr = intermediate.addSymbol(*fakeVariable, symbol->getLoc()); + } + } else { + switch (symbol->getQualifier().storage) { + case EvqPointCoord: + profileRequires(symbol->getLoc(), ENoProfile, 120, nullptr, "gl_PointCoord"); + break; + default: break; // some compilers want this + } + } +} + +// +// Both test and if necessary, spit out an error, to see if the node is really +// an l-value that can be operated on this way. +// +// Returns true if there was an error. +// +bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TIntermTyped* node) +{ + TIntermBinary* binaryNode = node->getAsBinaryNode(); + + if (binaryNode) { + bool errorReturn = false; + + switch(binaryNode->getOp()) { + case EOpIndexDirect: + case EOpIndexIndirect: + // ... tessellation control shader ... + // If a per-vertex output variable is used as an l-value, it is a + // compile-time or link-time error if the expression indicating the + // vertex index is not the identifier gl_InvocationID. + if (language == EShLangTessControl) { + const TType& leftType = binaryNode->getLeft()->getType(); + if (leftType.getQualifier().storage == EvqVaryingOut && ! leftType.getQualifier().patch && binaryNode->getLeft()->getAsSymbolNode()) { + // we have a per-vertex output + const TIntermSymbol* rightSymbol = binaryNode->getRight()->getAsSymbolNode(); + if (! rightSymbol || rightSymbol->getQualifier().builtIn != EbvInvocationId) + error(loc, "tessellation-control per-vertex output l-value must be indexed with gl_InvocationID", "[]", ""); + } + } + + break; // left node is checked by base class + case EOpIndexDirectStruct: + break; // left node is checked by base class + case EOpVectorSwizzle: + errorReturn = lValueErrorCheck(loc, op, binaryNode->getLeft()); + if (!errorReturn) { + int offset[4] = {0,0,0,0}; + + TIntermTyped* rightNode = binaryNode->getRight(); + TIntermAggregate *aggrNode = rightNode->getAsAggregate(); + + for (TIntermSequence::iterator p = aggrNode->getSequence().begin(); + p != aggrNode->getSequence().end(); p++) { + int value = (*p)->getAsTyped()->getAsConstantUnion()->getConstArray()[0].getIConst(); + offset[value]++; + if (offset[value] > 1) { + error(loc, " l-value of swizzle cannot have duplicate components", op, "", ""); + + return true; + } + } + } + + return errorReturn; + default: + break; + } + + if (errorReturn) { + error(loc, " l-value required", op, "", ""); + return true; + } + } + + // Let the base class check errors + if (TParseContextBase::lValueErrorCheck(loc, op, node)) + return true; + + const char* symbol = nullptr; + TIntermSymbol* symNode = node->getAsSymbolNode(); + if (symNode != nullptr) + symbol = symNode->getName().c_str(); + + const char* message = nullptr; + switch (node->getQualifier().storage) { + case EvqVaryingIn: message = "can't modify shader input"; break; + case EvqInstanceId: message = "can't modify gl_InstanceID"; break; + case EvqVertexId: message = "can't modify gl_VertexID"; break; + case EvqFace: message = "can't modify gl_FrontFace"; break; + case EvqFragCoord: message = "can't modify gl_FragCoord"; break; + case EvqPointCoord: message = "can't modify gl_PointCoord"; break; + case EvqFragDepth: + intermediate.setDepthReplacing(); + // "In addition, it is an error to statically write to gl_FragDepth in the fragment shader." + if (profile == EEsProfile && intermediate.getEarlyFragmentTests()) + message = "can't modify gl_FragDepth if using early_fragment_tests"; + break; + + default: + break; + } + + if (message == nullptr && binaryNode == nullptr && symNode == nullptr) { + error(loc, " l-value required", op, "", ""); + + return true; + } + + // + // Everything else is okay, no error. + // + if (message == nullptr) + return false; + + // + // If we get here, we have an error and a message. + // + if (symNode) + error(loc, " l-value required", op, "\"%s\" (%s)", symbol, message); + else + error(loc, " l-value required", op, "(%s)", message); + + return true; +} + +// Test for and give an error if the node can't be read from. +void TParseContext::rValueErrorCheck(const TSourceLoc& loc, const char* op, TIntermTyped* node) +{ + // Let the base class check errors + TParseContextBase::rValueErrorCheck(loc, op, node); + +#ifdef AMD_EXTENSIONS + TIntermSymbol* symNode = node->getAsSymbolNode(); + if (!(symNode && symNode->getQualifier().writeonly)) // base class checks + if (symNode && symNode->getQualifier().explicitInterp) + error(loc, "can't read from explicitly-interpolated object: ", op, symNode->getName().c_str()); +#endif +} + +// +// Both test, and if necessary spit out an error, to see if the node is really +// a constant. +// +void TParseContext::constantValueCheck(TIntermTyped* node, const char* token) +{ + if (! node->getQualifier().isConstant()) + error(node->getLoc(), "constant expression required", token, ""); +} + +// +// Both test, and if necessary spit out an error, to see if the node is really +// an integer. +// +void TParseContext::integerCheck(const TIntermTyped* node, const char* token) +{ + if ((node->getBasicType() == EbtInt || node->getBasicType() == EbtUint) && node->isScalar()) + return; + + error(node->getLoc(), "scalar integer expression required", token, ""); +} + +// +// Both test, and if necessary spit out an error, to see if we are currently +// globally scoped. +// +void TParseContext::globalCheck(const TSourceLoc& loc, const char* token) +{ + if (! symbolTable.atGlobalLevel()) + error(loc, "not allowed in nested scope", token, ""); +} + +// +// Reserved errors for GLSL. +// +void TParseContext::reservedErrorCheck(const TSourceLoc& loc, const TString& identifier) +{ + // "Identifiers starting with "gl_" are reserved for use by OpenGL, and may not be + // declared in a shader; this results in a compile-time error." + if (! symbolTable.atBuiltInLevel()) { + if (builtInName(identifier)) + error(loc, "identifiers starting with \"gl_\" are reserved", identifier.c_str(), ""); + + // "__" are not supposed to be an error. ES 310 (and desktop) added the clarification: + // "In addition, all identifiers containing two consecutive underscores (__) are + // reserved; using such a name does not itself result in an error, but may result + // in undefined behavior." + // however, before that, ES tests required an error. + if (identifier.find("__") != TString::npos) { + if (profile == EEsProfile && version <= 300) + error(loc, "identifiers containing consecutive underscores (\"__\") are reserved, and an error if version <= 300", identifier.c_str(), ""); + else + warn(loc, "identifiers containing consecutive underscores (\"__\") are reserved", identifier.c_str(), ""); + } + } +} + +// +// Reserved errors for the preprocessor. +// +void TParseContext::reservedPpErrorCheck(const TSourceLoc& loc, const char* identifier, const char* op) +{ + // "__" are not supposed to be an error. ES 310 (and desktop) added the clarification: + // "All macro names containing two consecutive underscores ( __ ) are reserved; + // defining such a name does not itself result in an error, but may result in + // undefined behavior. All macro names prefixed with "GL_" ("GL" followed by a + // single underscore) are also reserved, and defining such a name results in a + // compile-time error." + // however, before that, ES tests required an error. + if (strncmp(identifier, "GL_", 3) == 0) + ppError(loc, "names beginning with \"GL_\" can't be (un)defined:", op, identifier); + else if (strncmp(identifier, "defined", 8) == 0) + ppError(loc, "\"defined\" can't be (un)defined:", op, identifier); + else if (strstr(identifier, "__") != 0) { + if (profile == EEsProfile && version >= 300 && + (strcmp(identifier, "__LINE__") == 0 || + strcmp(identifier, "__FILE__") == 0 || + strcmp(identifier, "__VERSION__") == 0)) + ppError(loc, "predefined names can't be (un)defined:", op, identifier); + else { + if (profile == EEsProfile && version <= 300) + ppError(loc, "names containing consecutive underscores are reserved, and an error if version <= 300:", op, identifier); + else + ppWarn(loc, "names containing consecutive underscores are reserved:", op, identifier); + } + } +} + +// +// See if this version/profile allows use of the line-continuation character '\'. +// +// Returns true if a line continuation should be done. +// +bool TParseContext::lineContinuationCheck(const TSourceLoc& loc, bool endOfComment) +{ + const char* message = "line continuation"; + + bool lineContinuationAllowed = (profile == EEsProfile && version >= 300) || + (profile != EEsProfile && (version >= 420 || extensionTurnedOn(E_GL_ARB_shading_language_420pack))); + + if (endOfComment) { + if (lineContinuationAllowed) + warn(loc, "used at end of comment; the following line is still part of the comment", message, ""); + else + warn(loc, "used at end of comment, but this version does not provide line continuation", message, ""); + + return lineContinuationAllowed; + } + + if (relaxedErrors()) { + if (! lineContinuationAllowed) + warn(loc, "not allowed in this version", message, ""); + return true; + } else { + profileRequires(loc, EEsProfile, 300, nullptr, message); + profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, message); + } + + return lineContinuationAllowed; +} + +bool TParseContext::builtInName(const TString& identifier) +{ + return identifier.compare(0, 3, "gl_") == 0; +} + +// +// Make sure there is enough data and not too many arguments provided to the +// constructor to build something of the type of the constructor. Also returns +// the type of the constructor. +// +// Part of establishing type is establishing specialization-constness. +// We don't yet know "top down" whether type is a specialization constant, +// but a const constructor can becomes a specialization constant if any of +// its children are, subject to KHR_vulkan_glsl rules: +// +// - int(), uint(), and bool() constructors for type conversions +// from any of the following types to any of the following types: +// * int +// * uint +// * bool +// - vector versions of the above conversion constructors +// +// Returns true if there was an error in construction. +// +bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, TFunction& function, TOperator op, TType& type) +{ + type.shallowCopy(function.getType()); + + bool constructingMatrix = false; + switch(op) { + case EOpConstructTextureSampler: + return constructorTextureSamplerError(loc, function); + case EOpConstructMat2x2: + case EOpConstructMat2x3: + case EOpConstructMat2x4: + case EOpConstructMat3x2: + case EOpConstructMat3x3: + case EOpConstructMat3x4: + case EOpConstructMat4x2: + case EOpConstructMat4x3: + case EOpConstructMat4x4: + case EOpConstructDMat2x2: + case EOpConstructDMat2x3: + case EOpConstructDMat2x4: + case EOpConstructDMat3x2: + case EOpConstructDMat3x3: + case EOpConstructDMat3x4: + case EOpConstructDMat4x2: + case EOpConstructDMat4x3: + case EOpConstructDMat4x4: +#ifdef AMD_EXTENSIONS + case EOpConstructF16Mat2x2: + case EOpConstructF16Mat2x3: + case EOpConstructF16Mat2x4: + case EOpConstructF16Mat3x2: + case EOpConstructF16Mat3x3: + case EOpConstructF16Mat3x4: + case EOpConstructF16Mat4x2: + case EOpConstructF16Mat4x3: + case EOpConstructF16Mat4x4: +#endif + constructingMatrix = true; + break; + default: + break; + } + + // + // Walk the arguments for first-pass checks and collection of information. + // + + int size = 0; + bool constType = true; + bool specConstType = false; // value is only valid if constType is true + bool full = false; + bool overFull = false; + bool matrixInMatrix = false; + bool arrayArg = false; + bool floatArgument = false; + for (int arg = 0; arg < function.getParamCount(); ++arg) { + if (function[arg].type->isArray()) { + if (! function[arg].type->isExplicitlySizedArray()) { + // Can't construct from an unsized array. + error(loc, "array argument must be sized", "constructor", ""); + return true; + } + arrayArg = true; + } + if (constructingMatrix && function[arg].type->isMatrix()) + matrixInMatrix = true; + + // 'full' will go to true when enough args have been seen. If we loop + // again, there is an extra argument. + if (full) { + // For vectors and matrices, it's okay to have too many components + // available, but not okay to have unused arguments. + overFull = true; + } + + size += function[arg].type->computeNumComponents(); + if (op != EOpConstructStruct && ! type.isArray() && size >= type.computeNumComponents()) + full = true; + + if (! function[arg].type->getQualifier().isConstant()) + constType = false; + if (function[arg].type->getQualifier().isSpecConstant()) + specConstType = true; + if (function[arg].type->isFloatingDomain()) + floatArgument = true; + } + + // inherit constness from children + if (constType) { + bool makeSpecConst; + // Finish pinning down spec-const semantics + if (specConstType) { + switch (op) { + case EOpConstructInt: + case EOpConstructUint: + case EOpConstructInt64: + case EOpConstructUint64: +#ifdef AMD_EXTENSIONS + case EOpConstructInt16: + case EOpConstructUint16: +#endif + case EOpConstructBool: + case EOpConstructBVec2: + case EOpConstructBVec3: + case EOpConstructBVec4: + case EOpConstructIVec2: + case EOpConstructIVec3: + case EOpConstructIVec4: + case EOpConstructUVec2: + case EOpConstructUVec3: + case EOpConstructUVec4: + case EOpConstructI64Vec2: + case EOpConstructI64Vec3: + case EOpConstructI64Vec4: + case EOpConstructU64Vec2: + case EOpConstructU64Vec3: + case EOpConstructU64Vec4: +#ifdef AMD_EXTENSIONS + case EOpConstructI16Vec2: + case EOpConstructI16Vec3: + case EOpConstructI16Vec4: + case EOpConstructU16Vec2: + case EOpConstructU16Vec3: + case EOpConstructU16Vec4: +#endif + // This was the list of valid ones, if they aren't converting from float + // and aren't making an array. + makeSpecConst = ! floatArgument && ! type.isArray(); + break; + default: + // anything else wasn't white-listed in the spec as a conversion + makeSpecConst = false; + break; + } + } else + makeSpecConst = false; + + if (makeSpecConst) + type.getQualifier().makeSpecConstant(); + else if (specConstType) + type.getQualifier().makeTemporary(); + else + type.getQualifier().storage = EvqConst; + } + + if (type.isArray()) { + if (function.getParamCount() == 0) { + error(loc, "array constructor must have at least one argument", "constructor", ""); + return true; + } + + if (type.isImplicitlySizedArray()) { + // auto adapt the constructor type to the number of arguments + type.changeOuterArraySize(function.getParamCount()); + } else if (type.getOuterArraySize() != function.getParamCount()) { + error(loc, "array constructor needs one argument per array element", "constructor", ""); + return true; + } + + if (type.isArrayOfArrays()) { + // Types have to match, but we're still making the type. + // Finish making the type, and the comparison is done later + // when checking for conversion. + TArraySizes& arraySizes = type.getArraySizes(); + + // At least the dimensionalities have to match. + if (! function[0].type->isArray() || arraySizes.getNumDims() != function[0].type->getArraySizes().getNumDims() + 1) { + error(loc, "array constructor argument not correct type to construct array element", "constructor", ""); + return true; + } + + if (arraySizes.isInnerImplicit()) { + // "Arrays of arrays ..., and the size for any dimension is optional" + // That means we need to adopt (from the first argument) the other array sizes into the type. + for (int d = 1; d < arraySizes.getNumDims(); ++d) { + if (arraySizes.getDimSize(d) == UnsizedArraySize) { + arraySizes.setDimSize(d, function[0].type->getArraySizes().getDimSize(d - 1)); + } + } + } + } + } + + if (arrayArg && op != EOpConstructStruct && ! type.isArrayOfArrays()) { + error(loc, "constructing non-array constituent from array argument", "constructor", ""); + return true; + } + + if (matrixInMatrix && ! type.isArray()) { + profileRequires(loc, ENoProfile, 120, nullptr, "constructing matrix from matrix"); + + // "If a matrix argument is given to a matrix constructor, + // it is a compile-time error to have any other arguments." + if (function.getParamCount() != 1) + error(loc, "matrix constructed from matrix can only have one argument", "constructor", ""); + return false; + } + + if (overFull) { + error(loc, "too many arguments", "constructor", ""); + return true; + } + + if (op == EOpConstructStruct && ! type.isArray() && (int)type.getStruct()->size() != function.getParamCount()) { + error(loc, "Number of constructor parameters does not match the number of structure fields", "constructor", ""); + return true; + } + + if ((op != EOpConstructStruct && size != 1 && size < type.computeNumComponents()) || + (op == EOpConstructStruct && size < type.computeNumComponents())) { + error(loc, "not enough data provided for construction", "constructor", ""); + return true; + } + + TIntermTyped* typed = node->getAsTyped(); + if (typed == nullptr) { + error(loc, "constructor argument does not have a type", "constructor", ""); + return true; + } + if (op != EOpConstructStruct && typed->getBasicType() == EbtSampler) { + error(loc, "cannot convert a sampler", "constructor", ""); + return true; + } + if (op != EOpConstructStruct && typed->getBasicType() == EbtAtomicUint) { + error(loc, "cannot convert an atomic_uint", "constructor", ""); + return true; + } + if (typed->getBasicType() == EbtVoid) { + error(loc, "cannot convert a void", "constructor", ""); + return true; + } + + return false; +} + +// Verify all the correct semantics for constructing a combined texture/sampler. +// Return true if the semantics are incorrect. +bool TParseContext::constructorTextureSamplerError(const TSourceLoc& loc, const TFunction& function) +{ + TString constructorName = function.getType().getBasicTypeString(); // TODO: performance: should not be making copy; interface needs to change + const char* token = constructorName.c_str(); + + // exactly two arguments needed + if (function.getParamCount() != 2) { + error(loc, "sampler-constructor requires two arguments", token, ""); + return true; + } + + // For now, not allowing arrayed constructors, the rest of this function + // is set up to allow them, if this test is removed: + if (function.getType().isArray()) { + error(loc, "sampler-constructor cannot make an array of samplers", token, ""); + return true; + } + + // first argument + // * the constructor's first argument must be a texture type + // * the dimensionality (1D, 2D, 3D, Cube, Rect, Buffer, MS, and Array) + // of the texture type must match that of the constructed sampler type + // (that is, the suffixes of the type of the first argument and the + // type of the constructor will be spelled the same way) + if (function[0].type->getBasicType() != EbtSampler || + ! function[0].type->getSampler().isTexture() || + function[0].type->isArray()) { + error(loc, "sampler-constructor first argument must be a scalar textureXXX type", token, ""); + return true; + } + // simulate the first argument's impact on the result type, so it can be compared with the encapsulated operator!=() + TSampler texture = function.getType().getSampler(); + texture.combined = false; + texture.shadow = false; + if (texture != function[0].type->getSampler()) { + error(loc, "sampler-constructor first argument must match type and dimensionality of constructor type", token, ""); + return true; + } + + // second argument + // * the constructor's second argument must be a scalar of type + // *sampler* or *samplerShadow* + // * the presence or absence of depth comparison (Shadow) must match + // between the constructed sampler type and the type of the second argument + if ( function[1].type->getBasicType() != EbtSampler || + ! function[1].type->getSampler().isPureSampler() || + function[1].type->isArray()) { + error(loc, "sampler-constructor second argument must be a scalar type 'sampler'", token, ""); + return true; + } + if (function.getType().getSampler().shadow != function[1].type->getSampler().shadow) { + error(loc, "sampler-constructor second argument presence of shadow must match constructor presence of shadow", token, ""); + return true; + } + + return false; +} + +// Checks to see if a void variable has been declared and raise an error message for such a case +// +// returns true in case of an error +// +bool TParseContext::voidErrorCheck(const TSourceLoc& loc, const TString& identifier, const TBasicType basicType) +{ + if (basicType == EbtVoid) { + error(loc, "illegal use of type 'void'", identifier.c_str(), ""); + return true; + } + + return false; +} + +// Checks to see if the node (for the expression) contains a scalar boolean expression or not +void TParseContext::boolCheck(const TSourceLoc& loc, const TIntermTyped* type) +{ + if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) + error(loc, "boolean expression expected", "", ""); +} + +// This function checks to see if the node (for the expression) contains a scalar boolean expression or not +void TParseContext::boolCheck(const TSourceLoc& loc, const TPublicType& pType) +{ + if (pType.basicType != EbtBool || pType.arraySizes || pType.matrixCols > 1 || (pType.vectorSize > 1)) + error(loc, "boolean expression expected", "", ""); +} + +void TParseContext::samplerCheck(const TSourceLoc& loc, const TType& type, const TString& identifier, TIntermTyped* /*initializer*/) +{ + // Check that the appropriate extension is enabled if external sampler is used. + // There are two extensions. The correct one must be used based on GLSL version. + if (type.getBasicType() == EbtSampler && type.getSampler().external) { + if (version < 300) { + requireExtensions(loc, 1, &E_GL_OES_EGL_image_external, "samplerExternalOES"); + } else { + requireExtensions(loc, 1, &E_GL_OES_EGL_image_external_essl3, "samplerExternalOES"); + } + } + + if (type.getQualifier().storage == EvqUniform) + return; + + if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtSampler)) + error(loc, "non-uniform struct contains a sampler or image:", type.getBasicTypeString().c_str(), identifier.c_str()); + else if (type.getBasicType() == EbtSampler && type.getQualifier().storage != EvqUniform) { + // non-uniform sampler + // not yet: okay if it has an initializer + // if (! initializer) + error(loc, "sampler/image types can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str()); + } +} + +void TParseContext::atomicUintCheck(const TSourceLoc& loc, const TType& type, const TString& identifier) +{ + if (type.getQualifier().storage == EvqUniform) + return; + + if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtAtomicUint)) + error(loc, "non-uniform struct contains an atomic_uint:", type.getBasicTypeString().c_str(), identifier.c_str()); + else if (type.getBasicType() == EbtAtomicUint && type.getQualifier().storage != EvqUniform) + error(loc, "atomic_uints can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str()); +} + +void TParseContext::transparentOpaqueCheck(const TSourceLoc& loc, const TType& type, const TString& identifier) +{ + if (parsingBuiltins) + return; + + if (type.getQualifier().storage != EvqUniform) + return; + + if (type.containsNonOpaque()) { + // Vulkan doesn't allow transparent uniforms outside of blocks + if (spvVersion.vulkan > 0) + vulkanRemoved(loc, "non-opaque uniforms outside a block"); + // OpenGL wants locations on these (unless they are getting automapped) + if (spvVersion.openGl > 0 && !type.getQualifier().hasLocation() && !intermediate.getAutoMapLocations()) + error(loc, "non-opaque uniform variables need a layout(location=L)", identifier.c_str(), ""); + } +} + +// +// Check/fix just a full qualifier (no variables or types yet, but qualifier is complete) at global level. +// +void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& qualifier) +{ + // move from parameter/unknown qualifiers to pipeline in/out qualifiers + switch (qualifier.storage) { + case EvqIn: + profileRequires(loc, ENoProfile, 130, nullptr, "in for stage inputs"); + profileRequires(loc, EEsProfile, 300, nullptr, "in for stage inputs"); + qualifier.storage = EvqVaryingIn; + break; + case EvqOut: + profileRequires(loc, ENoProfile, 130, nullptr, "out for stage outputs"); + profileRequires(loc, EEsProfile, 300, nullptr, "out for stage outputs"); + qualifier.storage = EvqVaryingOut; + break; + case EvqInOut: + qualifier.storage = EvqVaryingIn; + error(loc, "cannot use 'inout' at global scope", "", ""); + break; + default: + break; + } + + invariantCheck(loc, qualifier); +} + +// +// Check a full qualifier and type (no variable yet) at global level. +// +void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQualifier& qualifier, const TPublicType& publicType) +{ + if (! symbolTable.atGlobalLevel()) + return; + + if (qualifier.isMemory() && ! publicType.isImage() && publicType.qualifier.storage != EvqBuffer) + error(loc, "memory qualifiers cannot be used on this type", "", ""); + + if (qualifier.storage == EvqBuffer && publicType.basicType != EbtBlock) + error(loc, "buffers can be declared only as blocks", "buffer", ""); + + if (qualifier.storage != EvqVaryingIn && qualifier.storage != EvqVaryingOut) + return; + + if (publicType.shaderQualifiers.blendEquation) + error(loc, "can only be applied to a standalone 'out'", "blend equation", ""); + + // now, knowing it is a shader in/out, do all the in/out semantic checks + + if (publicType.basicType == EbtBool && !parsingBuiltins) { + error(loc, "cannot be bool", GetStorageQualifierString(qualifier.storage), ""); + return; + } + + if (publicType.basicType == EbtInt || publicType.basicType == EbtUint || +#ifdef AMD_EXTENSIONS + publicType.basicType == EbtInt16 || publicType.basicType == EbtUint16 || +#endif + publicType.basicType == EbtInt64 || publicType.basicType == EbtUint64 || + publicType.basicType == EbtDouble) + profileRequires(loc, EEsProfile, 300, nullptr, "shader input/output"); + +#ifdef AMD_EXTENSIONS + if (! qualifier.flat && ! qualifier.explicitInterp) { +#else + if (!qualifier.flat) { +#endif + if (publicType.basicType == EbtInt || publicType.basicType == EbtUint || +#ifdef AMD_EXTENSIONS + publicType.basicType == EbtInt16 || publicType.basicType == EbtUint16 || +#endif + publicType.basicType == EbtInt64 || publicType.basicType == EbtUint64 || + publicType.basicType == EbtDouble || + (publicType.userDef && (publicType.userDef->containsBasicType(EbtInt) || + publicType.userDef->containsBasicType(EbtUint) || + publicType.userDef->containsBasicType(EbtInt64) || + publicType.userDef->containsBasicType(EbtUint64) || + publicType.userDef->containsBasicType(EbtDouble)))) { + if (qualifier.storage == EvqVaryingIn && language == EShLangFragment) + error(loc, "must be qualified as flat", TType::getBasicString(publicType.basicType), GetStorageQualifierString(qualifier.storage)); + else if (qualifier.storage == EvqVaryingOut && language == EShLangVertex && version == 300) + error(loc, "must be qualified as flat", TType::getBasicString(publicType.basicType), GetStorageQualifierString(qualifier.storage)); + } + } + + if (qualifier.patch && qualifier.isInterpolation()) + error(loc, "cannot use interpolation qualifiers with patch", "patch", ""); + + if (qualifier.storage == EvqVaryingIn) { + switch (language) { + case EShLangVertex: + if (publicType.basicType == EbtStruct) { + error(loc, "cannot be a structure or array", GetStorageQualifierString(qualifier.storage), ""); + return; + } + if (publicType.arraySizes) { + requireProfile(loc, ~EEsProfile, "vertex input arrays"); + profileRequires(loc, ENoProfile, 150, nullptr, "vertex input arrays"); + } + if (publicType.basicType == EbtDouble) + profileRequires(loc, ~EEsProfile, 410, nullptr, "vertex-shader `double` type input"); + if (qualifier.isAuxiliary() || qualifier.isInterpolation() || qualifier.isMemory() || qualifier.invariant) + error(loc, "vertex input cannot be further qualified", "", ""); + break; + + case EShLangTessControl: + if (qualifier.patch) + error(loc, "can only use on output in tessellation-control shader", "patch", ""); + break; + + case EShLangTessEvaluation: + break; + + case EShLangGeometry: + break; + + case EShLangFragment: + if (publicType.userDef) { + profileRequires(loc, EEsProfile, 300, nullptr, "fragment-shader struct input"); + profileRequires(loc, ~EEsProfile, 150, nullptr, "fragment-shader struct input"); + if (publicType.userDef->containsStructure()) + requireProfile(loc, ~EEsProfile, "fragment-shader struct input containing structure"); + if (publicType.userDef->containsArray()) + requireProfile(loc, ~EEsProfile, "fragment-shader struct input containing an array"); + } + break; + + case EShLangCompute: + if (! symbolTable.atBuiltInLevel()) + error(loc, "global storage input qualifier cannot be used in a compute shader", "in", ""); + break; + + default: + break; + } + } else { + // qualifier.storage == EvqVaryingOut + switch (language) { + case EShLangVertex: + if (publicType.userDef) { + profileRequires(loc, EEsProfile, 300, nullptr, "vertex-shader struct output"); + profileRequires(loc, ~EEsProfile, 150, nullptr, "vertex-shader struct output"); + if (publicType.userDef->containsStructure()) + requireProfile(loc, ~EEsProfile, "vertex-shader struct output containing structure"); + if (publicType.userDef->containsArray()) + requireProfile(loc, ~EEsProfile, "vertex-shader struct output containing an array"); + } + + break; + + case EShLangTessControl: + break; + + case EShLangTessEvaluation: + if (qualifier.patch) + error(loc, "can only use on input in tessellation-evaluation shader", "patch", ""); + break; + + case EShLangGeometry: + break; + + case EShLangFragment: + profileRequires(loc, EEsProfile, 300, nullptr, "fragment shader output"); + if (publicType.basicType == EbtStruct) { + error(loc, "cannot be a structure", GetStorageQualifierString(qualifier.storage), ""); + return; + } + if (publicType.matrixRows > 0) { + error(loc, "cannot be a matrix", GetStorageQualifierString(qualifier.storage), ""); + return; + } + if (qualifier.isAuxiliary()) + error(loc, "can't use auxiliary qualifier on a fragment output", "centroid/sample/patch", ""); + if (qualifier.isInterpolation()) + error(loc, "can't use interpolation qualifier on a fragment output", "flat/smooth/noperspective", ""); + if (publicType.basicType == EbtDouble) + error(loc, "cannot contain a double", GetStorageQualifierString(qualifier.storage), ""); + break; + + case EShLangCompute: + error(loc, "global storage output qualifier cannot be used in a compute shader", "out", ""); + break; + + default: + break; + } + } +} + +// +// Merge characteristics of the 'src' qualifier into the 'dst'. +// If there is duplication, issue error messages, unless 'force' +// is specified, which means to just override default settings. +// +// Also, when force is false, it will be assumed that 'src' follows +// 'dst', for the purpose of error checking order for versions +// that require specific orderings of qualifiers. +// +void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, const TQualifier& src, bool force) +{ + // Multiple auxiliary qualifiers (mostly done later by 'individual qualifiers') + if (src.isAuxiliary() && dst.isAuxiliary()) + error(loc, "can only have one auxiliary qualifier (centroid, patch, and sample)", "", ""); + + // Multiple interpolation qualifiers (mostly done later by 'individual qualifiers') + if (src.isInterpolation() && dst.isInterpolation()) +#ifdef AMD_EXTENSIONS + error(loc, "can only have one interpolation qualifier (flat, smooth, noperspective, __explicitInterpAMD)", "", ""); +#else + error(loc, "can only have one interpolation qualifier (flat, smooth, noperspective)", "", ""); +#endif + + // Ordering + if (! force && ((profile != EEsProfile && version < 420) || + (profile == EEsProfile && version < 310)) + && ! extensionTurnedOn(E_GL_ARB_shading_language_420pack)) { + // non-function parameters + if (src.noContraction && (dst.invariant || dst.isInterpolation() || dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone)) + error(loc, "precise qualifier must appear first", "", ""); + if (src.invariant && (dst.isInterpolation() || dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone)) + error(loc, "invariant qualifier must appear before interpolation, storage, and precision qualifiers ", "", ""); + else if (src.isInterpolation() && (dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone)) + error(loc, "interpolation qualifiers must appear before storage and precision qualifiers", "", ""); + else if (src.isAuxiliary() && (dst.storage != EvqTemporary || dst.precision != EpqNone)) + error(loc, "Auxiliary qualifiers (centroid, patch, and sample) must appear before storage and precision qualifiers", "", ""); + else if (src.storage != EvqTemporary && (dst.precision != EpqNone)) + error(loc, "precision qualifier must appear as last qualifier", "", ""); + + // function parameters + if (src.noContraction && (dst.storage == EvqConst || dst.storage == EvqIn || dst.storage == EvqOut)) + error(loc, "precise qualifier must appear first", "", ""); + if (src.storage == EvqConst && (dst.storage == EvqIn || dst.storage == EvqOut)) + error(loc, "in/out must appear before const", "", ""); + } + + // Storage qualification + if (dst.storage == EvqTemporary || dst.storage == EvqGlobal) + dst.storage = src.storage; + else if ((dst.storage == EvqIn && src.storage == EvqOut) || + (dst.storage == EvqOut && src.storage == EvqIn)) + dst.storage = EvqInOut; + else if ((dst.storage == EvqIn && src.storage == EvqConst) || + (dst.storage == EvqConst && src.storage == EvqIn)) + dst.storage = EvqConstReadOnly; + else if (src.storage != EvqTemporary && + src.storage != EvqGlobal) + error(loc, "too many storage qualifiers", GetStorageQualifierString(src.storage), ""); + + // Precision qualifiers + if (! force && src.precision != EpqNone && dst.precision != EpqNone) + error(loc, "only one precision qualifier allowed", GetPrecisionQualifierString(src.precision), ""); + if (dst.precision == EpqNone || (force && src.precision != EpqNone)) + dst.precision = src.precision; + + // Layout qualifiers + mergeObjectLayoutQualifiers(dst, src, false); + + // individual qualifiers + bool repeated = false; + #define MERGE_SINGLETON(field) repeated |= dst.field && src.field; dst.field |= src.field; + MERGE_SINGLETON(invariant); + MERGE_SINGLETON(noContraction); + MERGE_SINGLETON(centroid); + MERGE_SINGLETON(smooth); + MERGE_SINGLETON(flat); + MERGE_SINGLETON(nopersp); +#ifdef AMD_EXTENSIONS + MERGE_SINGLETON(explicitInterp); +#endif + MERGE_SINGLETON(patch); + MERGE_SINGLETON(sample); + MERGE_SINGLETON(coherent); + MERGE_SINGLETON(volatil); + MERGE_SINGLETON(restrict); + MERGE_SINGLETON(readonly); + MERGE_SINGLETON(writeonly); + MERGE_SINGLETON(specConstant); + + if (repeated) + error(loc, "replicated qualifiers", "", ""); +} + +void TParseContext::setDefaultPrecision(const TSourceLoc& loc, TPublicType& publicType, TPrecisionQualifier qualifier) +{ + TBasicType basicType = publicType.basicType; + + if (basicType == EbtSampler) { + defaultSamplerPrecision[computeSamplerTypeIndex(publicType.sampler)] = qualifier; + + return; // all is well + } + + if (basicType == EbtInt || basicType == EbtFloat) { + if (publicType.isScalar()) { + defaultPrecision[basicType] = qualifier; + if (basicType == EbtInt) { + defaultPrecision[EbtUint] = qualifier; + precisionManager.explicitIntDefaultSeen(); + } else + precisionManager.explicitFloatDefaultSeen(); + + return; // all is well + } + } + + if (basicType == EbtAtomicUint) { + if (qualifier != EpqHigh) + error(loc, "can only apply highp to atomic_uint", "precision", ""); + + return; + } + + error(loc, "cannot apply precision statement to this type; use 'float', 'int' or a sampler type", TType::getBasicString(basicType), ""); +} + +// used to flatten the sampler type space into a single dimension +// correlates with the declaration of defaultSamplerPrecision[] +int TParseContext::computeSamplerTypeIndex(TSampler& sampler) +{ + int arrayIndex = sampler.arrayed ? 1 : 0; + int shadowIndex = sampler.shadow ? 1 : 0; + int externalIndex = sampler.external? 1 : 0; + int imageIndex = sampler.image ? 1 : 0; + int msIndex = sampler.ms ? 1 : 0; + + int flattened = EsdNumDims * (EbtNumTypes * (2 * (2 * (2 * (2 * arrayIndex + msIndex) + imageIndex) + shadowIndex) + + externalIndex) + sampler.type) + sampler.dim; + assert(flattened < maxSamplerIndex); + + return flattened; +} + +TPrecisionQualifier TParseContext::getDefaultPrecision(TPublicType& publicType) +{ + if (publicType.basicType == EbtSampler) + return defaultSamplerPrecision[computeSamplerTypeIndex(publicType.sampler)]; + else + return defaultPrecision[publicType.basicType]; +} + +void TParseContext::precisionQualifierCheck(const TSourceLoc& loc, TBasicType baseType, TQualifier& qualifier) +{ + // Built-in symbols are allowed some ambiguous precisions, to be pinned down + // later by context. + if (! obeyPrecisionQualifiers() || parsingBuiltins) + return; + + if (baseType == EbtAtomicUint && qualifier.precision != EpqNone && qualifier.precision != EpqHigh) + error(loc, "atomic counters can only be highp", "atomic_uint", ""); + + if (baseType == EbtFloat || baseType == EbtUint || baseType == EbtInt || baseType == EbtSampler || baseType == EbtAtomicUint) { + if (qualifier.precision == EpqNone) { + if (relaxedErrors()) + warn(loc, "type requires declaration of default precision qualifier", TType::getBasicString(baseType), "substituting 'mediump'"); + else + error(loc, "type requires declaration of default precision qualifier", TType::getBasicString(baseType), ""); + qualifier.precision = EpqMedium; + defaultPrecision[baseType] = EpqMedium; + } + } else if (qualifier.precision != EpqNone) + error(loc, "type cannot have precision qualifier", TType::getBasicString(baseType), ""); +} + +void TParseContext::parameterTypeCheck(const TSourceLoc& loc, TStorageQualifier qualifier, const TType& type) +{ + if ((qualifier == EvqOut || qualifier == EvqInOut) && type.isOpaque()) + error(loc, "samplers and atomic_uints cannot be output parameters", type.getBasicTypeString().c_str(), ""); +} + +bool TParseContext::containsFieldWithBasicType(const TType& type, TBasicType basicType) +{ + if (type.getBasicType() == basicType) + return true; + + if (type.getBasicType() == EbtStruct) { + const TTypeList& structure = *type.getStruct(); + for (unsigned int i = 0; i < structure.size(); ++i) { + if (containsFieldWithBasicType(*structure[i].type, basicType)) + return true; + } + } + + return false; +} + +// +// Do size checking for an array type's size. +// +void TParseContext::arraySizeCheck(const TSourceLoc& loc, TIntermTyped* expr, TArraySize& sizePair) +{ + bool isConst = false; + sizePair.node = nullptr; + + int size = 1; + + TIntermConstantUnion* constant = expr->getAsConstantUnion(); + if (constant) { + // handle true (non-specialization) constant + size = constant->getConstArray()[0].getIConst(); + isConst = true; + } else { + // see if it's a specialization constant instead + if (expr->getQualifier().isSpecConstant()) { + isConst = true; + sizePair.node = expr; + TIntermSymbol* symbol = expr->getAsSymbolNode(); + if (symbol && symbol->getConstArray().size() > 0) + size = symbol->getConstArray()[0].getIConst(); + } + } + + sizePair.size = size; + + if (! isConst || (expr->getBasicType() != EbtInt && expr->getBasicType() != EbtUint)) { + error(loc, "array size must be a constant integer expression", "", ""); + return; + } + + if (size <= 0) { + error(loc, "array size must be a positive integer", "", ""); + return; + } +} + +// +// See if this qualifier can be an array. +// +// Returns true if there is an error. +// +bool TParseContext::arrayQualifierError(const TSourceLoc& loc, const TQualifier& qualifier) +{ + if (qualifier.storage == EvqConst) { + profileRequires(loc, ENoProfile, 120, E_GL_3DL_array_objects, "const array"); + profileRequires(loc, EEsProfile, 300, nullptr, "const array"); + } + + if (qualifier.storage == EvqVaryingIn && language == EShLangVertex) { + requireProfile(loc, ~EEsProfile, "vertex input arrays"); + profileRequires(loc, ENoProfile, 150, nullptr, "vertex input arrays"); + } + + return false; +} + +// +// See if this qualifier and type combination can be an array. +// Assumes arrayQualifierError() was also called to catch the type-invariant tests. +// +// Returns true if there is an error. +// +bool TParseContext::arrayError(const TSourceLoc& loc, const TType& type) +{ + if (type.getQualifier().storage == EvqVaryingOut && language == EShLangVertex) { + if (type.isArrayOfArrays()) + requireProfile(loc, ~EEsProfile, "vertex-shader array-of-array output"); + else if (type.isStruct()) + requireProfile(loc, ~EEsProfile, "vertex-shader array-of-struct output"); + } + if (type.getQualifier().storage == EvqVaryingIn && language == EShLangFragment) { + if (type.isArrayOfArrays()) + requireProfile(loc, ~EEsProfile, "fragment-shader array-of-array input"); + else if (type.isStruct()) + requireProfile(loc, ~EEsProfile, "fragment-shader array-of-struct input"); + } + if (type.getQualifier().storage == EvqVaryingOut && language == EShLangFragment) { + if (type.isArrayOfArrays()) + requireProfile(loc, ~EEsProfile, "fragment-shader array-of-array output"); + } + + return false; +} + +// +// Require array to be completely sized +// +void TParseContext::arraySizeRequiredCheck(const TSourceLoc& loc, const TArraySizes& arraySizes) +{ + if (arraySizes.isImplicit()) + error(loc, "array size required", "", ""); +} + +void TParseContext::structArrayCheck(const TSourceLoc& /*loc*/, const TType& type) +{ + const TTypeList& structure = *type.getStruct(); + for (int m = 0; m < (int)structure.size(); ++m) { + const TType& member = *structure[m].type; + if (member.isArray()) + arraySizeRequiredCheck(structure[m].loc, *member.getArraySizes()); + } +} + +void TParseContext::arraySizesCheck(const TSourceLoc& loc, const TQualifier& qualifier, TArraySizes* arraySizes, bool initializer, bool lastMember) +{ + assert(arraySizes); + + // always allow special built-in ins/outs sized to topologies + if (parsingBuiltins) + return; + + // always allow an initializer to set any unknown array sizes + if (initializer) + return; + + // No environment allows any non-outer-dimension to be implicitly sized + if (arraySizes->isInnerImplicit()) { + error(loc, "only outermost dimension of an array of arrays can be implicitly sized", "[]", ""); + arraySizes->clearInnerImplicit(); + } + + if (arraySizes->isInnerSpecialization()) + error(loc, "only outermost dimension of an array of arrays can be a specialization constant", "[]", ""); + + // desktop always allows outer-dimension-unsized variable arrays, + if (profile != EEsProfile) + return; + + // for ES, if size isn't coming from an initializer, it has to be explicitly declared now, + // with very few exceptions + + // last member of ssbo block exception: + if (qualifier.storage == EvqBuffer && lastMember) + return; + + // implicitly-sized io exceptions: + switch (language) { + case EShLangGeometry: + if (qualifier.storage == EvqVaryingIn) + if ((profile == EEsProfile && version >= 320) || + extensionsTurnedOn(Num_AEP_geometry_shader, AEP_geometry_shader)) + return; + break; + case EShLangTessControl: + if ( qualifier.storage == EvqVaryingIn || + (qualifier.storage == EvqVaryingOut && ! qualifier.patch)) + if ((profile == EEsProfile && version >= 320) || + extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader)) + return; + break; + case EShLangTessEvaluation: + if ((qualifier.storage == EvqVaryingIn && ! qualifier.patch) || + qualifier.storage == EvqVaryingOut) + if ((profile == EEsProfile && version >= 320) || + extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader)) + return; + break; + default: + break; + } + + arraySizeRequiredCheck(loc, *arraySizes); +} + +void TParseContext::arrayOfArrayVersionCheck(const TSourceLoc& loc) +{ + const char* feature = "arrays of arrays"; + + requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, feature); + profileRequires(loc, EEsProfile, 310, nullptr, feature); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, feature); +} + +void TParseContext::arrayDimCheck(const TSourceLoc& loc, const TArraySizes* sizes1, const TArraySizes* sizes2) +{ + if ((sizes1 && sizes2) || + (sizes1 && sizes1->getNumDims() > 1) || + (sizes2 && sizes2->getNumDims() > 1)) + arrayOfArrayVersionCheck(loc); +} + +void TParseContext::arrayDimCheck(const TSourceLoc& loc, const TType* type, const TArraySizes* sizes2) +{ + // skip checking for multiple dimensions on the type; it was caught earlier + if ((type && type->isArray() && sizes2) || + (sizes2 && sizes2->getNumDims() > 1)) + arrayOfArrayVersionCheck(loc); +} + +// Merge array dimensions listed in 'sizes' onto the type's array dimensions. +// +// From the spec: "vec4[2] a[3]; // size-3 array of size-2 array of vec4" +// +// That means, the 'sizes' go in front of the 'type' as outermost sizes. +// 'type' is the type part of the declaration (to the left) +// 'sizes' is the arrayness tagged on the identifier (to the right) +// +void TParseContext::arrayDimMerge(TType& type, const TArraySizes* sizes) +{ + if (sizes) + type.addArrayOuterSizes(*sizes); +} + +// +// Do all the semantic checking for declaring or redeclaring an array, with and +// without a size, and make the right changes to the symbol table. +// +void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifier, const TType& type, TSymbol*& symbol) +{ + if (symbol == nullptr) { + bool currentScope; + symbol = symbolTable.find(identifier, nullptr, ¤tScope); + + if (symbol && builtInName(identifier) && ! symbolTable.atBuiltInLevel()) { + // bad shader (errors already reported) trying to redeclare a built-in name as an array + symbol = nullptr; + return; + } + if (symbol == nullptr || ! currentScope) { + // + // Successfully process a new definition. + // (Redeclarations have to take place at the same scope; otherwise they are hiding declarations) + // + symbol = new TVariable(&identifier, type); + symbolTable.insert(*symbol); + if (symbolTable.atGlobalLevel()) + trackLinkage(*symbol); + + if (! symbolTable.atBuiltInLevel()) { + if (isIoResizeArray(type)) { + ioArraySymbolResizeList.push_back(symbol); + checkIoArraysConsistency(loc, true); + } else + fixIoArraySize(loc, symbol->getWritableType()); + } + + return; + } + if (symbol->getAsAnonMember()) { + error(loc, "cannot redeclare a user-block member array", identifier.c_str(), ""); + symbol = nullptr; + return; + } + } + + // + // Process a redeclaration. + // + + if (symbol == nullptr) { + error(loc, "array variable name expected", identifier.c_str(), ""); + return; + } + + // redeclareBuiltinVariable() should have already done the copyUp() + TType& existingType = symbol->getWritableType(); + + if (! existingType.isArray()) { + error(loc, "redeclaring non-array as array", identifier.c_str(), ""); + return; + } + + if (! existingType.sameElementType(type)) { + error(loc, "redeclaration of array with a different element type", identifier.c_str(), ""); + return; + } + + if (! existingType.sameInnerArrayness(type)) { + error(loc, "redeclaration of array with a different array dimensions or sizes", identifier.c_str(), ""); + return; + } + + if (existingType.isExplicitlySizedArray()) { + // be more leniant for input arrays to geometry shaders and tessellation control outputs, where the redeclaration is the same size + if (! (isIoResizeArray(type) && existingType.getOuterArraySize() == type.getOuterArraySize())) + error(loc, "redeclaration of array with size", identifier.c_str(), ""); + return; + } + + arrayLimitCheck(loc, identifier, type.getOuterArraySize()); + + existingType.updateArraySizes(type); + + if (isIoResizeArray(type)) + checkIoArraysConsistency(loc); +} + +void TParseContext::updateImplicitArraySize(const TSourceLoc& loc, TIntermNode *node, int index) +{ + // maybe there is nothing to do... + TIntermTyped* typedNode = node->getAsTyped(); + if (typedNode->getType().getImplicitArraySize() > index) + return; + + // something to do... + + // Figure out what symbol to lookup, as we will use its type to edit for the size change, + // as that type will be shared through shallow copies for future references. + TSymbol* symbol = nullptr; + int blockIndex = -1; + const TString* lookupName = nullptr; + if (node->getAsSymbolNode()) + lookupName = &node->getAsSymbolNode()->getName(); + else if (node->getAsBinaryNode()) { + const TIntermBinary* deref = node->getAsBinaryNode(); + // This has to be the result of a block dereference, unless it's bad shader code + // If it's a uniform block, then an error will be issued elsewhere, but + // return early now to avoid crashing later in this function. + if (deref->getLeft()->getBasicType() != EbtBlock || + deref->getLeft()->getType().getQualifier().storage == EvqUniform || + deref->getRight()->getAsConstantUnion() == nullptr) + return; + + const TIntermTyped* left = deref->getLeft(); + const TIntermTyped* right = deref->getRight(); + + if (left->getAsBinaryNode()) { + left = left->getAsBinaryNode()->getLeft(); // Block array access + assert(left->isArray()); + } + + if (! left->getAsSymbolNode()) + return; + + blockIndex = right->getAsConstantUnion()->getConstArray()[0].getIConst(); + + lookupName = &left->getAsSymbolNode()->getName(); + if (IsAnonymous(*lookupName)) + lookupName = &(*left->getType().getStruct())[blockIndex].type->getFieldName(); + } + + // Lookup the symbol, should only fail if shader code is incorrect + symbol = symbolTable.find(*lookupName); + if (symbol == nullptr) + return; + + if (symbol->getAsFunction()) { + error(loc, "array variable name expected", symbol->getName().c_str(), ""); + return; + } + + if (symbol->getType().isStruct() && blockIndex != -1) + (*symbol->getWritableType().getStruct())[blockIndex].type->setImplicitArraySize(index + 1); + else + symbol->getWritableType().setImplicitArraySize(index + 1); +} + +// Returns true if the first argument to the #line directive is the line number for the next line. +// +// Desktop, pre-version 3.30: "After processing this directive +// (including its new-line), the implementation will behave as if it is compiling at line number line+1 and +// source string number source-string-number." +// +// Desktop, version 3.30 and later, and ES: "After processing this directive +// (including its new-line), the implementation will behave as if it is compiling at line number line and +// source string number source-string-number. +bool TParseContext::lineDirectiveShouldSetNextLine() const +{ + return profile == EEsProfile || version >= 330; +} + +// +// Enforce non-initializer type/qualifier rules. +// +void TParseContext::nonInitConstCheck(const TSourceLoc& loc, TString& identifier, TType& type) +{ + // + // Make the qualifier make sense, given that there is not an initializer. + // + if (type.getQualifier().storage == EvqConst || + type.getQualifier().storage == EvqConstReadOnly) { + type.getQualifier().makeTemporary(); + error(loc, "variables with qualifier 'const' must be initialized", identifier.c_str(), ""); + } +} + +// +// See if the identifier is a built-in symbol that can be redeclared, and if so, +// copy the symbol table's read-only built-in variable to the current +// global level, where it can be modified based on the passed in type. +// +// Returns nullptr if no redeclaration took place; meaning a normal declaration still +// needs to occur for it, not necessarily an error. +// +// Returns a redeclared and type-modified variable if a redeclarated occurred. +// +TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TString& identifier, + const TQualifier& qualifier, const TShaderQualifiers& publicType) +{ + if (! builtInName(identifier) || symbolTable.atBuiltInLevel() || ! symbolTable.atGlobalLevel()) + return nullptr; + + bool nonEsRedecls = (profile != EEsProfile && (version >= 130 || identifier == "gl_TexCoord")); + bool esRedecls = (profile == EEsProfile && + (version >= 320 || extensionsTurnedOn(Num_AEP_shader_io_blocks, AEP_shader_io_blocks))); + if (! esRedecls && ! nonEsRedecls) + return nullptr; + + // Special case when using GL_ARB_separate_shader_objects + bool ssoPre150 = false; // means the only reason this variable is redeclared is due to this combination + if (profile != EEsProfile && version <= 140 && extensionTurnedOn(E_GL_ARB_separate_shader_objects)) { + if (identifier == "gl_Position" || + identifier == "gl_PointSize" || + identifier == "gl_ClipVertex" || + identifier == "gl_FogFragCoord") + ssoPre150 = true; + } + + // Potentially redeclaring a built-in variable... + + if (ssoPre150 || + (identifier == "gl_FragDepth" && ((nonEsRedecls && version >= 420) || esRedecls)) || + (identifier == "gl_FragCoord" && ((nonEsRedecls && version >= 150) || esRedecls)) || + identifier == "gl_ClipDistance" || + identifier == "gl_CullDistance" || + identifier == "gl_FrontColor" || + identifier == "gl_BackColor" || + identifier == "gl_FrontSecondaryColor" || + identifier == "gl_BackSecondaryColor" || + identifier == "gl_SecondaryColor" || + (identifier == "gl_Color" && language == EShLangFragment) || +#ifdef NV_EXTENSIONS + identifier == "gl_SampleMask" || + identifier == "gl_Layer" || +#endif + identifier == "gl_TexCoord") { + + // Find the existing symbol, if any. + bool builtIn; + TSymbol* symbol = symbolTable.find(identifier, &builtIn); + + // If the symbol was not found, this must be a version/profile/stage + // that doesn't have it. + if (! symbol) + return nullptr; + + // If it wasn't at a built-in level, then it's already been redeclared; + // that is, this is a redeclaration of a redeclaration; reuse that initial + // redeclaration. Otherwise, make the new one. + if (builtIn) + makeEditable(symbol); + + // Now, modify the type of the copy, as per the type of the current redeclaration. + + TQualifier& symbolQualifier = symbol->getWritableType().getQualifier(); + if (ssoPre150) { + if (intermediate.inIoAccessed(identifier)) + error(loc, "cannot redeclare after use", identifier.c_str(), ""); + if (qualifier.hasLayout()) + error(loc, "cannot apply layout qualifier to", "redeclaration", symbol->getName().c_str()); + if (qualifier.isMemory() || qualifier.isAuxiliary() || (language == EShLangVertex && qualifier.storage != EvqVaryingOut) || + (language == EShLangFragment && qualifier.storage != EvqVaryingIn)) + error(loc, "cannot change storage, memory, or auxiliary qualification of", "redeclaration", symbol->getName().c_str()); + if (! qualifier.smooth) + error(loc, "cannot change interpolation qualification of", "redeclaration", symbol->getName().c_str()); + } else if (identifier == "gl_FrontColor" || + identifier == "gl_BackColor" || + identifier == "gl_FrontSecondaryColor" || + identifier == "gl_BackSecondaryColor" || + identifier == "gl_SecondaryColor" || + identifier == "gl_Color") { + symbolQualifier.flat = qualifier.flat; + symbolQualifier.smooth = qualifier.smooth; + symbolQualifier.nopersp = qualifier.nopersp; + if (qualifier.hasLayout()) + error(loc, "cannot apply layout qualifier to", "redeclaration", symbol->getName().c_str()); + if (qualifier.isMemory() || qualifier.isAuxiliary() || symbol->getType().getQualifier().storage != qualifier.storage) + error(loc, "cannot change storage, memory, or auxiliary qualification of", "redeclaration", symbol->getName().c_str()); + } else if (identifier == "gl_TexCoord" || + identifier == "gl_ClipDistance" || + identifier == "gl_CullDistance") { + if (qualifier.hasLayout() || qualifier.isMemory() || qualifier.isAuxiliary() || + qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat || + symbolQualifier.storage != qualifier.storage) + error(loc, "cannot change qualification of", "redeclaration", symbol->getName().c_str()); + } else if (identifier == "gl_FragCoord") { + if (intermediate.inIoAccessed("gl_FragCoord")) + error(loc, "cannot redeclare after use", "gl_FragCoord", ""); + if (qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat || + qualifier.isMemory() || qualifier.isAuxiliary()) + error(loc, "can only change layout qualification of", "redeclaration", symbol->getName().c_str()); + if (qualifier.storage != EvqVaryingIn) + error(loc, "cannot change input storage qualification of", "redeclaration", symbol->getName().c_str()); + if (! builtIn && (publicType.pixelCenterInteger != intermediate.getPixelCenterInteger() || + publicType.originUpperLeft != intermediate.getOriginUpperLeft())) + error(loc, "cannot redeclare with different qualification:", "redeclaration", symbol->getName().c_str()); + if (publicType.pixelCenterInteger) + intermediate.setPixelCenterInteger(); + if (publicType.originUpperLeft) + intermediate.setOriginUpperLeft(); + } else if (identifier == "gl_FragDepth") { + if (qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat || + qualifier.isMemory() || qualifier.isAuxiliary()) + error(loc, "can only change layout qualification of", "redeclaration", symbol->getName().c_str()); + if (qualifier.storage != EvqVaryingOut) + error(loc, "cannot change output storage qualification of", "redeclaration", symbol->getName().c_str()); + if (publicType.layoutDepth != EldNone) { + if (intermediate.inIoAccessed("gl_FragDepth")) + error(loc, "cannot redeclare after use", "gl_FragDepth", ""); + if (! intermediate.setDepth(publicType.layoutDepth)) + error(loc, "all redeclarations must use the same depth layout on", "redeclaration", symbol->getName().c_str()); + } + } +#ifdef NV_EXTENSIONS + else if (identifier == "gl_SampleMask") { + if (!publicType.layoutOverrideCoverage) { + error(loc, "redeclaration only allowed for override_coverage layout", "redeclaration", symbol->getName().c_str()); + } + intermediate.setLayoutOverrideCoverage(); + } + else if (identifier == "gl_Layer") { + if (!qualifier.layoutViewportRelative && qualifier.layoutSecondaryViewportRelativeOffset == -2048) + error(loc, "redeclaration only allowed for viewport_relative or secondary_view_offset layout", "redeclaration", symbol->getName().c_str()); + symbolQualifier.layoutViewportRelative = qualifier.layoutViewportRelative; + symbolQualifier.layoutSecondaryViewportRelativeOffset = qualifier.layoutSecondaryViewportRelativeOffset; + } +#endif + + // TODO: semantics quality: separate smooth from nothing declared, then use IsInterpolation for several tests above + + return symbol; + } + + return nullptr; +} + +// +// Either redeclare the requested block, or give an error message why it can't be done. +// +// TODO: functionality: explicitly sizing members of redeclared blocks is not giving them an explicit size +void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newTypeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes) +{ + const char* feature = "built-in block redeclaration"; + profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, feature); + profileRequires(loc, ~EEsProfile, 410, E_GL_ARB_separate_shader_objects, feature); + + if (blockName != "gl_PerVertex" && blockName != "gl_PerFragment") { + error(loc, "cannot redeclare block: ", "block declaration", blockName.c_str()); + return; + } + + // Redeclaring a built-in block... + + if (instanceName && ! builtInName(*instanceName)) { + error(loc, "cannot redeclare a built-in block with a user name", instanceName->c_str(), ""); + return; + } + + // Blocks with instance names are easy to find, lookup the instance name, + // Anonymous blocks need to be found via a member. + bool builtIn; + TSymbol* block; + if (instanceName) + block = symbolTable.find(*instanceName, &builtIn); + else + block = symbolTable.find(newTypeList.front().type->getFieldName(), &builtIn); + + // If the block was not found, this must be a version/profile/stage + // that doesn't have it, or the instance name is wrong. + const char* errorName = instanceName ? instanceName->c_str() : newTypeList.front().type->getFieldName().c_str(); + if (! block) { + error(loc, "no declaration found for redeclaration", errorName, ""); + return; + } + // Built-in blocks cannot be redeclared more than once, which if happened, + // we'd be finding the already redeclared one here, rather than the built in. + if (! builtIn) { + error(loc, "can only redeclare a built-in block once, and before any use", blockName.c_str(), ""); + return; + } + + // Copy the block to make a writable version, to insert into the block table after editing. + block = symbolTable.copyUpDeferredInsert(block); + + if (block->getType().getBasicType() != EbtBlock) { + error(loc, "cannot redeclare a non block as a block", errorName, ""); + return; + } + + // Fix XFB stuff up, it applies to the order of the redeclaration, not + // the order of the original members. + if (currentBlockQualifier.storage == EvqVaryingOut && globalOutputDefaults.hasXfbBuffer()) { + currentBlockQualifier.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer; + fixBlockXfbOffsets(currentBlockQualifier, newTypeList); + } + + // Edit and error check the container against the redeclaration + // - remove unused members + // - ensure remaining qualifiers/types match + + TType& type = block->getWritableType(); + +#ifdef NV_EXTENSIONS + // if gl_PerVertex is redeclared for the purpose of passing through "gl_Position" + // for passthrough purpose, the redeclared block should have the same qualifers as + // the current one + if (currentBlockQualifier.layoutPassthrough) { + type.getQualifier().layoutPassthrough = currentBlockQualifier.layoutPassthrough; + type.getQualifier().storage = currentBlockQualifier.storage; + type.getQualifier().layoutStream = currentBlockQualifier.layoutStream; + type.getQualifier().layoutXfbBuffer = currentBlockQualifier.layoutXfbBuffer; + } +#endif + + TTypeList::iterator member = type.getWritableStruct()->begin(); + size_t numOriginalMembersFound = 0; + while (member != type.getStruct()->end()) { + // look for match + bool found = false; + TTypeList::const_iterator newMember; + TSourceLoc memberLoc; + memberLoc.init(); + for (newMember = newTypeList.begin(); newMember != newTypeList.end(); ++newMember) { + if (member->type->getFieldName() == newMember->type->getFieldName()) { + found = true; + memberLoc = newMember->loc; + break; + } + } + + if (found) { + ++numOriginalMembersFound; + // - ensure match between redeclared members' types + // - check for things that can't be changed + // - update things that can be changed + TType& oldType = *member->type; + const TType& newType = *newMember->type; + if (! newType.sameElementType(oldType)) + error(memberLoc, "cannot redeclare block member with a different type", member->type->getFieldName().c_str(), ""); + if (oldType.isArray() != newType.isArray()) + error(memberLoc, "cannot change arrayness of redeclared block member", member->type->getFieldName().c_str(), ""); + else if (! oldType.sameArrayness(newType) && oldType.isExplicitlySizedArray()) + error(memberLoc, "cannot change array size of redeclared block member", member->type->getFieldName().c_str(), ""); + else if (newType.isArray()) + arrayLimitCheck(loc, member->type->getFieldName(), newType.getOuterArraySize()); + if (newType.getQualifier().isMemory()) + error(memberLoc, "cannot add memory qualifier to redeclared block member", member->type->getFieldName().c_str(), ""); + if (newType.getQualifier().hasNonXfbLayout()) + error(memberLoc, "cannot add non-XFB layout to redeclared block member", member->type->getFieldName().c_str(), ""); + if (newType.getQualifier().patch) + error(memberLoc, "cannot add patch to redeclared block member", member->type->getFieldName().c_str(), ""); + if (newType.getQualifier().hasXfbBuffer() && newType.getQualifier().layoutXfbBuffer != currentBlockQualifier.layoutXfbBuffer) + error(memberLoc, "member cannot contradict block (or what block inherited from global)", "xfb_buffer", ""); + oldType.getQualifier().centroid = newType.getQualifier().centroid; + oldType.getQualifier().sample = newType.getQualifier().sample; + oldType.getQualifier().invariant = newType.getQualifier().invariant; + oldType.getQualifier().noContraction = newType.getQualifier().noContraction; + oldType.getQualifier().smooth = newType.getQualifier().smooth; + oldType.getQualifier().flat = newType.getQualifier().flat; + oldType.getQualifier().nopersp = newType.getQualifier().nopersp; + oldType.getQualifier().layoutXfbOffset = newType.getQualifier().layoutXfbOffset; + if (oldType.getQualifier().layoutXfbOffset != TQualifier::layoutXfbBufferEnd) + type.getQualifier().layoutXfbBuffer = currentBlockQualifier.layoutXfbBuffer; + if (oldType.isImplicitlySizedArray() && newType.isExplicitlySizedArray()) + oldType.changeOuterArraySize(newType.getOuterArraySize()); + + // go to next member + ++member; + } else { + // For missing members of anonymous blocks that have been redeclared, + // hide the original (shared) declaration. + // Instance-named blocks can just have the member removed. + if (instanceName) + member = type.getWritableStruct()->erase(member); + else { + member->type->hideMember(); + ++member; + } + } + } + + if (numOriginalMembersFound < newTypeList.size()) + error(loc, "block redeclaration has extra members", blockName.c_str(), ""); + if (type.isArray() != (arraySizes != nullptr)) + error(loc, "cannot change arrayness of redeclared block", blockName.c_str(), ""); + else if (type.isArray()) { + if (type.isExplicitlySizedArray() && arraySizes->getOuterSize() == UnsizedArraySize) + error(loc, "block already declared with size, can't redeclare as implicitly-sized", blockName.c_str(), ""); + else if (type.isExplicitlySizedArray() && type.getArraySizes() != *arraySizes) + error(loc, "cannot change array size of redeclared block", blockName.c_str(), ""); + else if (type.isImplicitlySizedArray() && arraySizes->getOuterSize() != UnsizedArraySize) + type.changeOuterArraySize(arraySizes->getOuterSize()); + } + + symbolTable.insert(*block); + + // Check for general layout qualifier errors + layoutObjectCheck(loc, *block); + + // Tracking for implicit sizing of array + if (isIoResizeArray(block->getType())) { + ioArraySymbolResizeList.push_back(block); + checkIoArraysConsistency(loc, true); + } else if (block->getType().isArray()) + fixIoArraySize(loc, block->getWritableType()); + + // Save it in the AST for linker use. + trackLinkage(*block); +} + +void TParseContext::paramCheckFix(const TSourceLoc& loc, const TStorageQualifier& qualifier, TType& type) +{ + switch (qualifier) { + case EvqConst: + case EvqConstReadOnly: + type.getQualifier().storage = EvqConstReadOnly; + break; + case EvqIn: + case EvqOut: + case EvqInOut: + type.getQualifier().storage = qualifier; + break; + case EvqGlobal: + case EvqTemporary: + type.getQualifier().storage = EvqIn; + break; + default: + type.getQualifier().storage = EvqIn; + error(loc, "storage qualifier not allowed on function parameter", GetStorageQualifierString(qualifier), ""); + break; + } +} + +void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& qualifier, TType& type) +{ + if (qualifier.isMemory()) { + type.getQualifier().volatil = qualifier.volatil; + type.getQualifier().coherent = qualifier.coherent; + type.getQualifier().readonly = qualifier.readonly; + type.getQualifier().writeonly = qualifier.writeonly; + type.getQualifier().restrict = qualifier.restrict; + } + + if (qualifier.isAuxiliary() || + qualifier.isInterpolation()) + error(loc, "cannot use auxiliary or interpolation qualifiers on a function parameter", "", ""); + if (qualifier.hasLayout()) + error(loc, "cannot use layout qualifiers on a function parameter", "", ""); + if (qualifier.invariant) + error(loc, "cannot use invariant qualifier on a function parameter", "", ""); + if (qualifier.noContraction) { + if (qualifier.isParamOutput()) + type.getQualifier().noContraction = true; + else + warn(loc, "qualifier has no effect on non-output parameters", "precise", ""); + } + + paramCheckFix(loc, qualifier.storage, type); +} + +void TParseContext::nestedBlockCheck(const TSourceLoc& loc) +{ + if (structNestingLevel > 0) + error(loc, "cannot nest a block definition inside a structure or block", "", ""); + ++structNestingLevel; +} + +void TParseContext::nestedStructCheck(const TSourceLoc& loc) +{ + if (structNestingLevel > 0) + error(loc, "cannot nest a structure definition inside a structure or block", "", ""); + ++structNestingLevel; +} + +void TParseContext::arrayObjectCheck(const TSourceLoc& loc, const TType& type, const char* op) +{ + // Some versions don't allow comparing arrays or structures containing arrays + if (type.containsArray()) { + profileRequires(loc, ENoProfile, 120, E_GL_3DL_array_objects, op); + profileRequires(loc, EEsProfile, 300, nullptr, op); + } +} + +void TParseContext::opaqueCheck(const TSourceLoc& loc, const TType& type, const char* op) +{ + if (containsFieldWithBasicType(type, EbtSampler)) + error(loc, "can't use with samplers or structs containing samplers", op, ""); +} + +void TParseContext::specializationCheck(const TSourceLoc& loc, const TType& type, const char* op) +{ + if (type.containsSpecializationSize()) + error(loc, "can't use with types containing arrays sized with a specialization constant", op, ""); +} + +void TParseContext::structTypeCheck(const TSourceLoc& /*loc*/, TPublicType& publicType) +{ + const TTypeList& typeList = *publicType.userDef->getStruct(); + + // fix and check for member storage qualifiers and types that don't belong within a structure + for (unsigned int member = 0; member < typeList.size(); ++member) { + TQualifier& memberQualifier = typeList[member].type->getQualifier(); + const TSourceLoc& memberLoc = typeList[member].loc; + if (memberQualifier.isAuxiliary() || + memberQualifier.isInterpolation() || + (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal)) + error(memberLoc, "cannot use storage or interpolation qualifiers on structure members", typeList[member].type->getFieldName().c_str(), ""); + if (memberQualifier.isMemory()) + error(memberLoc, "cannot use memory qualifiers on structure members", typeList[member].type->getFieldName().c_str(), ""); + if (memberQualifier.hasLayout()) { + error(memberLoc, "cannot use layout qualifiers on structure members", typeList[member].type->getFieldName().c_str(), ""); + memberQualifier.clearLayout(); + } + if (memberQualifier.invariant) + error(memberLoc, "cannot use invariant qualifier on structure members", typeList[member].type->getFieldName().c_str(), ""); + } +} + +// +// See if this loop satisfies the limitations for ES 2.0 (version 100) for loops in Appendex A: +// +// "The loop index has type int or float. +// +// "The for statement has the form: +// for ( init-declaration ; condition ; expression ) +// init-declaration has the form: type-specifier identifier = constant-expression +// condition has the form: loop-index relational_operator constant-expression +// where relational_operator is one of: > >= < <= == or != +// expression [sic] has one of the following forms: +// loop-index++ +// loop-index-- +// loop-index += constant-expression +// loop-index -= constant-expression +// +// The body is handled in an AST traversal. +// +void TParseContext::inductiveLoopCheck(const TSourceLoc& loc, TIntermNode* init, TIntermLoop* loop) +{ + // loop index init must exist and be a declaration, which shows up in the AST as an aggregate of size 1 of the declaration + bool badInit = false; + if (! init || ! init->getAsAggregate() || init->getAsAggregate()->getSequence().size() != 1) + badInit = true; + TIntermBinary* binaryInit = 0; + if (! badInit) { + // get the declaration assignment + binaryInit = init->getAsAggregate()->getSequence()[0]->getAsBinaryNode(); + if (! binaryInit) + badInit = true; + } + if (badInit) { + error(loc, "inductive-loop init-declaration requires the form \"type-specifier loop-index = constant-expression\"", "limitations", ""); + return; + } + + // loop index must be type int or float + if (! binaryInit->getType().isScalar() || (binaryInit->getBasicType() != EbtInt && binaryInit->getBasicType() != EbtFloat)) { + error(loc, "inductive loop requires a scalar 'int' or 'float' loop index", "limitations", ""); + return; + } + + // init is the form "loop-index = constant" + if (binaryInit->getOp() != EOpAssign || ! binaryInit->getLeft()->getAsSymbolNode() || ! binaryInit->getRight()->getAsConstantUnion()) { + error(loc, "inductive-loop init-declaration requires the form \"type-specifier loop-index = constant-expression\"", "limitations", ""); + return; + } + + // get the unique id of the loop index + int loopIndex = binaryInit->getLeft()->getAsSymbolNode()->getId(); + inductiveLoopIds.insert(loopIndex); + + // condition's form must be "loop-index relational-operator constant-expression" + bool badCond = ! loop->getTest(); + if (! badCond) { + TIntermBinary* binaryCond = loop->getTest()->getAsBinaryNode(); + badCond = ! binaryCond; + if (! badCond) { + switch (binaryCond->getOp()) { + case EOpGreaterThan: + case EOpGreaterThanEqual: + case EOpLessThan: + case EOpLessThanEqual: + case EOpEqual: + case EOpNotEqual: + break; + default: + badCond = true; + } + } + if (binaryCond && (! binaryCond->getLeft()->getAsSymbolNode() || + binaryCond->getLeft()->getAsSymbolNode()->getId() != loopIndex || + ! binaryCond->getRight()->getAsConstantUnion())) + badCond = true; + } + if (badCond) { + error(loc, "inductive-loop condition requires the form \"loop-index constant-expression\"", "limitations", ""); + return; + } + + // loop-index++ + // loop-index-- + // loop-index += constant-expression + // loop-index -= constant-expression + bool badTerminal = ! loop->getTerminal(); + if (! badTerminal) { + TIntermUnary* unaryTerminal = loop->getTerminal()->getAsUnaryNode(); + TIntermBinary* binaryTerminal = loop->getTerminal()->getAsBinaryNode(); + if (unaryTerminal || binaryTerminal) { + switch(loop->getTerminal()->getAsOperator()->getOp()) { + case EOpPostDecrement: + case EOpPostIncrement: + case EOpAddAssign: + case EOpSubAssign: + break; + default: + badTerminal = true; + } + } else + badTerminal = true; + if (binaryTerminal && (! binaryTerminal->getLeft()->getAsSymbolNode() || + binaryTerminal->getLeft()->getAsSymbolNode()->getId() != loopIndex || + ! binaryTerminal->getRight()->getAsConstantUnion())) + badTerminal = true; + if (unaryTerminal && (! unaryTerminal->getOperand()->getAsSymbolNode() || + unaryTerminal->getOperand()->getAsSymbolNode()->getId() != loopIndex)) + badTerminal = true; + } + if (badTerminal) { + error(loc, "inductive-loop termination requires the form \"loop-index++, loop-index--, loop-index += constant-expression, or loop-index -= constant-expression\"", "limitations", ""); + return; + } + + // the body + inductiveLoopBodyCheck(loop->getBody(), loopIndex, symbolTable); +} + +// Do limit checks for built-in arrays. +void TParseContext::arrayLimitCheck(const TSourceLoc& loc, const TString& identifier, int size) +{ + if (identifier.compare("gl_TexCoord") == 0) + limitCheck(loc, size, "gl_MaxTextureCoords", "gl_TexCoord array size"); + else if (identifier.compare("gl_ClipDistance") == 0) + limitCheck(loc, size, "gl_MaxClipDistances", "gl_ClipDistance array size"); + else if (identifier.compare("gl_CullDistance") == 0) + limitCheck(loc, size, "gl_MaxCullDistances", "gl_CullDistance array size"); +} + +// See if the provided value is less than or equal to the symbol indicated by limit, +// which should be a constant in the symbol table. +void TParseContext::limitCheck(const TSourceLoc& loc, int value, const char* limit, const char* feature) +{ + TSymbol* symbol = symbolTable.find(limit); + assert(symbol->getAsVariable()); + const TConstUnionArray& constArray = symbol->getAsVariable()->getConstArray(); + assert(! constArray.empty()); + if (value > constArray[0].getIConst()) + error(loc, "must be less than or equal to", feature, "%s (%d)", limit, constArray[0].getIConst()); +} + +// +// Do any additional error checking, etc., once we know the parsing is done. +// +void TParseContext::finish() +{ + TParseContextBase::finish(); + + if (parsingBuiltins) + return; + + // Check on array indexes for ES 2.0 (version 100) limitations. + for (size_t i = 0; i < needsIndexLimitationChecking.size(); ++i) + constantIndexExpressionCheck(needsIndexLimitationChecking[i]); + + // Check for stages that are enabled by extension. + // Can't do this at the beginning, it is chicken and egg to add a stage by + // extension. + // Stage-specific features were correctly tested for already, this is just + // about the stage itself. + switch (language) { + case EShLangGeometry: + if (profile == EEsProfile && version == 310) + requireExtensions(getCurrentLoc(), Num_AEP_geometry_shader, AEP_geometry_shader, "geometry shaders"); + break; + case EShLangTessControl: + case EShLangTessEvaluation: + if (profile == EEsProfile && version == 310) + requireExtensions(getCurrentLoc(), Num_AEP_tessellation_shader, AEP_tessellation_shader, "tessellation shaders"); + else if (profile != EEsProfile && version < 400) + requireExtensions(getCurrentLoc(), 1, &E_GL_ARB_tessellation_shader, "tessellation shaders"); + break; + case EShLangCompute: + if (profile != EEsProfile && version < 430) + requireExtensions(getCurrentLoc(), 1, &E_GL_ARB_compute_shader, "compute shaders"); + break; + default: + break; + } +} + +// +// Layout qualifier stuff. +// + +// Put the id's layout qualification into the public type, for qualifiers not having a number set. +// This is before we know any type information for error checking. +void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publicType, TString& id) +{ + std::transform(id.begin(), id.end(), id.begin(), ::tolower); + + if (id == TQualifier::getLayoutMatrixString(ElmColumnMajor)) { + publicType.qualifier.layoutMatrix = ElmColumnMajor; + return; + } + if (id == TQualifier::getLayoutMatrixString(ElmRowMajor)) { + publicType.qualifier.layoutMatrix = ElmRowMajor; + return; + } + if (id == TQualifier::getLayoutPackingString(ElpPacked)) { + if (spvVersion.spv != 0) + spvRemoved(loc, "packed"); + publicType.qualifier.layoutPacking = ElpPacked; + return; + } + if (id == TQualifier::getLayoutPackingString(ElpShared)) { + if (spvVersion.spv != 0) + spvRemoved(loc, "shared"); + publicType.qualifier.layoutPacking = ElpShared; + return; + } + if (id == TQualifier::getLayoutPackingString(ElpStd140)) { + publicType.qualifier.layoutPacking = ElpStd140; + return; + } + if (id == TQualifier::getLayoutPackingString(ElpStd430)) { + requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "std430"); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, "std430"); + profileRequires(loc, EEsProfile, 310, nullptr, "std430"); + publicType.qualifier.layoutPacking = ElpStd430; + return; + } + // TODO: compile-time performance: may need to stop doing linear searches + for (TLayoutFormat format = (TLayoutFormat)(ElfNone + 1); format < ElfCount; format = (TLayoutFormat)(format + 1)) { + if (id == TQualifier::getLayoutFormatString(format)) { + if ((format > ElfEsFloatGuard && format < ElfFloatGuard) || + (format > ElfEsIntGuard && format < ElfIntGuard) || + (format > ElfEsUintGuard && format < ElfCount)) + requireProfile(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, "image load-store format"); + profileRequires(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, 420, E_GL_ARB_shader_image_load_store, "image load store"); + profileRequires(loc, EEsProfile, 310, E_GL_ARB_shader_image_load_store, "image load store"); + publicType.qualifier.layoutFormat = format; + return; + } + } + if (id == "push_constant") { + requireVulkan(loc, "push_constant"); + publicType.qualifier.layoutPushConstant = true; + return; + } + if (language == EShLangGeometry || language == EShLangTessEvaluation) { + if (id == TQualifier::getGeometryString(ElgTriangles)) { + publicType.shaderQualifiers.geometry = ElgTriangles; + return; + } + if (language == EShLangGeometry) { + if (id == TQualifier::getGeometryString(ElgPoints)) { + publicType.shaderQualifiers.geometry = ElgPoints; + return; + } + if (id == TQualifier::getGeometryString(ElgLineStrip)) { + publicType.shaderQualifiers.geometry = ElgLineStrip; + return; + } + if (id == TQualifier::getGeometryString(ElgLines)) { + publicType.shaderQualifiers.geometry = ElgLines; + return; + } + if (id == TQualifier::getGeometryString(ElgLinesAdjacency)) { + publicType.shaderQualifiers.geometry = ElgLinesAdjacency; + return; + } + if (id == TQualifier::getGeometryString(ElgTrianglesAdjacency)) { + publicType.shaderQualifiers.geometry = ElgTrianglesAdjacency; + return; + } + if (id == TQualifier::getGeometryString(ElgTriangleStrip)) { + publicType.shaderQualifiers.geometry = ElgTriangleStrip; + return; + } +#ifdef NV_EXTENSIONS + if (id == "passthrough") { + requireExtensions(loc, 1, &E_SPV_NV_geometry_shader_passthrough, "geometry shader passthrough"); + publicType.qualifier.layoutPassthrough = true; + intermediate.setGeoPassthroughEXT(); + return; + } +#endif + } else { + assert(language == EShLangTessEvaluation); + + // input primitive + if (id == TQualifier::getGeometryString(ElgTriangles)) { + publicType.shaderQualifiers.geometry = ElgTriangles; + return; + } + if (id == TQualifier::getGeometryString(ElgQuads)) { + publicType.shaderQualifiers.geometry = ElgQuads; + return; + } + if (id == TQualifier::getGeometryString(ElgIsolines)) { + publicType.shaderQualifiers.geometry = ElgIsolines; + return; + } + + // vertex spacing + if (id == TQualifier::getVertexSpacingString(EvsEqual)) { + publicType.shaderQualifiers.spacing = EvsEqual; + return; + } + if (id == TQualifier::getVertexSpacingString(EvsFractionalEven)) { + publicType.shaderQualifiers.spacing = EvsFractionalEven; + return; + } + if (id == TQualifier::getVertexSpacingString(EvsFractionalOdd)) { + publicType.shaderQualifiers.spacing = EvsFractionalOdd; + return; + } + + // triangle order + if (id == TQualifier::getVertexOrderString(EvoCw)) { + publicType.shaderQualifiers.order = EvoCw; + return; + } + if (id == TQualifier::getVertexOrderString(EvoCcw)) { + publicType.shaderQualifiers.order = EvoCcw; + return; + } + + // point mode + if (id == "point_mode") { + publicType.shaderQualifiers.pointMode = true; + return; + } + } + } + if (language == EShLangFragment) { + if (id == "origin_upper_left") { + requireProfile(loc, ECoreProfile | ECompatibilityProfile, "origin_upper_left"); + publicType.shaderQualifiers.originUpperLeft = true; + return; + } + if (id == "pixel_center_integer") { + requireProfile(loc, ECoreProfile | ECompatibilityProfile, "pixel_center_integer"); + publicType.shaderQualifiers.pixelCenterInteger = true; + return; + } + if (id == "early_fragment_tests") { + profileRequires(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, 420, E_GL_ARB_shader_image_load_store, "early_fragment_tests"); + profileRequires(loc, EEsProfile, 310, nullptr, "early_fragment_tests"); + publicType.shaderQualifiers.earlyFragmentTests = true; + return; + } + if (id == "post_depth_coverage") { + requireExtensions(loc, Num_post_depth_coverageEXTs, post_depth_coverageEXTs, "post depth coverage"); + if (extensionTurnedOn(E_GL_ARB_post_depth_coverage)) { + publicType.shaderQualifiers.earlyFragmentTests = true; + } + publicType.shaderQualifiers.postDepthCoverage = true; + return; + } + for (TLayoutDepth depth = (TLayoutDepth)(EldNone + 1); depth < EldCount; depth = (TLayoutDepth)(depth+1)) { + if (id == TQualifier::getLayoutDepthString(depth)) { + requireProfile(loc, ECoreProfile | ECompatibilityProfile, "depth layout qualifier"); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 420, nullptr, "depth layout qualifier"); + publicType.shaderQualifiers.layoutDepth = depth; + return; + } + } + if (id.compare(0, 13, "blend_support") == 0) { + bool found = false; + for (TBlendEquationShift be = (TBlendEquationShift)0; be < EBlendCount; be = (TBlendEquationShift)(be + 1)) { + if (id == TQualifier::getBlendEquationString(be)) { + profileRequires(loc, EEsProfile, 320, E_GL_KHR_blend_equation_advanced, "blend equation"); + profileRequires(loc, ~EEsProfile, 0, E_GL_KHR_blend_equation_advanced, "blend equation"); + intermediate.addBlendEquation(be); + publicType.shaderQualifiers.blendEquation = true; + found = true; + break; + } + } + if (! found) + error(loc, "unknown blend equation", "blend_support", ""); + return; + } +#ifdef NV_EXTENSIONS + if (id == "override_coverage") { + requireExtensions(loc, 1, &E_GL_NV_sample_mask_override_coverage, "sample mask override coverage"); + publicType.shaderQualifiers.layoutOverrideCoverage = true; + return; + } + } + if (language == EShLangVertex || + language == EShLangTessControl || + language == EShLangTessEvaluation || + language == EShLangGeometry ) { + if (id == "viewport_relative") { + requireExtensions(loc, 1, &E_GL_NV_viewport_array2, "view port array2"); + publicType.qualifier.layoutViewportRelative = true; + return; + } + } +#else + } +#endif + error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), ""); +} + +// Put the id's layout qualifier value into the public type, for qualifiers having a number set. +// This is before we know any type information for error checking. +void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publicType, TString& id, const TIntermTyped* node) +{ + const char* feature = "layout-id value"; + const char* nonLiteralFeature = "non-literal layout-id value"; + + integerCheck(node, feature); + const TIntermConstantUnion* constUnion = node->getAsConstantUnion(); + int value; + if (constUnion) { + value = constUnion->getConstArray()[0].getIConst(); + if (! constUnion->isLiteral()) { + requireProfile(loc, ECoreProfile | ECompatibilityProfile, nonLiteralFeature); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, nonLiteralFeature); + } + } else { + // grammar should have give out the error message + value = 0; + } + + if (value < 0) { + error(loc, "cannot be negative", feature, ""); + return; + } + + std::transform(id.begin(), id.end(), id.begin(), ::tolower); + + if (id == "offset") { + // "offset" can be for either + // - uniform offsets + // - atomic_uint offsets + const char* feature = "offset"; + if (spvVersion.spv == 0) { + requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, feature); + const char* exts[2] = { E_GL_ARB_enhanced_layouts, E_GL_ARB_shader_atomic_counters }; + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 420, 2, exts, feature); + profileRequires(loc, EEsProfile, 310, nullptr, feature); + } + publicType.qualifier.layoutOffset = value; + return; + } else if (id == "align") { + const char* feature = "uniform buffer-member align"; + if (spvVersion.spv == 0) { + requireProfile(loc, ECoreProfile | ECompatibilityProfile, feature); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, feature); + } + // "The specified alignment must be a power of 2, or a compile-time error results." + if (! IsPow2(value)) + error(loc, "must be a power of 2", "align", ""); + else + publicType.qualifier.layoutAlign = value; + return; + } else if (id == "location") { + profileRequires(loc, EEsProfile, 300, nullptr, "location"); + const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location }; + profileRequires(loc, ~EEsProfile, 330, 2, exts, "location"); + if ((unsigned int)value >= TQualifier::layoutLocationEnd) + error(loc, "location is too large", id.c_str(), ""); + else + publicType.qualifier.layoutLocation = value; + return; + } else if (id == "set") { + if ((unsigned int)value >= TQualifier::layoutSetEnd) + error(loc, "set is too large", id.c_str(), ""); + else + publicType.qualifier.layoutSet = value; + if (value != 0) + requireVulkan(loc, "descriptor set"); + return; + } else if (id == "binding") { + profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, "binding"); + profileRequires(loc, EEsProfile, 310, nullptr, "binding"); + if ((unsigned int)value >= TQualifier::layoutBindingEnd) + error(loc, "binding is too large", id.c_str(), ""); + else + publicType.qualifier.layoutBinding = value; + return; + } else if (id == "component") { + requireProfile(loc, ECoreProfile | ECompatibilityProfile, "component"); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, "component"); + if ((unsigned)value >= TQualifier::layoutComponentEnd) + error(loc, "component is too large", id.c_str(), ""); + else + publicType.qualifier.layoutComponent = value; + return; + } else if (id.compare(0, 4, "xfb_") == 0) { + // "Any shader making any static use (after preprocessing) of any of these + // *xfb_* qualifiers will cause the shader to be in a transform feedback + // capturing mode and hence responsible for describing the transform feedback + // setup." + intermediate.setXfbMode(); + const char* feature = "transform feedback qualifier"; + requireStage(loc, (EShLanguageMask)(EShLangVertexMask | EShLangGeometryMask | EShLangTessControlMask | EShLangTessEvaluationMask), feature); + requireProfile(loc, ECoreProfile | ECompatibilityProfile, feature); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, feature); + if (id == "xfb_buffer") { + // "It is a compile-time error to specify an *xfb_buffer* that is greater than + // the implementation-dependent constant gl_MaxTransformFeedbackBuffers." + if (value >= resources.maxTransformFeedbackBuffers) + error(loc, "buffer is too large:", id.c_str(), "gl_MaxTransformFeedbackBuffers is %d", resources.maxTransformFeedbackBuffers); + if (value >= (int)TQualifier::layoutXfbBufferEnd) + error(loc, "buffer is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbBufferEnd-1); + else + publicType.qualifier.layoutXfbBuffer = value; + return; + } else if (id == "xfb_offset") { + if (value >= (int)TQualifier::layoutXfbOffsetEnd) + error(loc, "offset is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbOffsetEnd-1); + else + publicType.qualifier.layoutXfbOffset = value; + return; + } else if (id == "xfb_stride") { + // "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the + // implementation-dependent constant gl_MaxTransformFeedbackInterleavedComponents." + if (value > 4 * resources.maxTransformFeedbackInterleavedComponents) + error(loc, "1/4 stride is too large:", id.c_str(), "gl_MaxTransformFeedbackInterleavedComponents is %d", resources.maxTransformFeedbackInterleavedComponents); + else if (value >= (int)TQualifier::layoutXfbStrideEnd) + error(loc, "stride is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbStrideEnd-1); + if (value < (int)TQualifier::layoutXfbStrideEnd) + publicType.qualifier.layoutXfbStride = value; + return; + } + } + + if (id == "input_attachment_index") { + requireVulkan(loc, "input_attachment_index"); + if (value >= (int)TQualifier::layoutAttachmentEnd) + error(loc, "attachment index is too large", id.c_str(), ""); + else + publicType.qualifier.layoutAttachment = value; + return; + } + if (id == "constant_id") { + requireSpv(loc, "constant_id"); + if (value >= (int)TQualifier::layoutSpecConstantIdEnd) { + error(loc, "specialization-constant id is too large", id.c_str(), ""); + } else { + publicType.qualifier.layoutSpecConstantId = value; + publicType.qualifier.specConstant = true; + if (! intermediate.addUsedConstantId(value)) + error(loc, "specialization-constant id already used", id.c_str(), ""); + } + return; + } + if (id == "num_views") { + requireExtensions(loc, Num_OVR_multiview_EXTs, OVR_multiview_EXTs, "num_views"); + publicType.shaderQualifiers.numViews = value; + return; + } + +#if NV_EXTENSIONS + if (language == EShLangVertex || + language == EShLangTessControl || + language == EShLangTessEvaluation || + language == EShLangGeometry) { + if (id == "secondary_view_offset") { + requireExtensions(loc, 1, &E_GL_NV_stereo_view_rendering, "stereo view rendering"); + publicType.qualifier.layoutSecondaryViewportRelativeOffset = value; + return; + } + } +#endif + + switch (language) { + case EShLangVertex: + break; + + case EShLangTessControl: + if (id == "vertices") { + if (value == 0) + error(loc, "must be greater than 0", "vertices", ""); + else + publicType.shaderQualifiers.vertices = value; + return; + } + break; + + case EShLangTessEvaluation: + break; + + case EShLangGeometry: + if (id == "invocations") { + profileRequires(loc, ECompatibilityProfile | ECoreProfile, 400, nullptr, "invocations"); + if (value == 0) + error(loc, "must be at least 1", "invocations", ""); + else + publicType.shaderQualifiers.invocations = value; + return; + } + if (id == "max_vertices") { + publicType.shaderQualifiers.vertices = value; + if (value > resources.maxGeometryOutputVertices) + error(loc, "too large, must be less than gl_MaxGeometryOutputVertices", "max_vertices", ""); + return; + } + if (id == "stream") { + requireProfile(loc, ~EEsProfile, "selecting output stream"); + publicType.qualifier.layoutStream = value; + if (value > 0) + intermediate.setMultiStream(); + return; + } + break; + + case EShLangFragment: + if (id == "index") { + requireProfile(loc, ECompatibilityProfile | ECoreProfile, "index layout qualifier on fragment output"); + const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location }; + profileRequires(loc, ECompatibilityProfile | ECoreProfile, 330, 2, exts, "index layout qualifier on fragment output"); + + // "It is also a compile-time error if a fragment shader sets a layout index to less than 0 or greater than 1." + if (value < 0 || value > 1) { + value = 0; + error(loc, "value must be 0 or 1", "index", ""); + } + + publicType.qualifier.layoutIndex = value; + return; + } + break; + + case EShLangCompute: + if (id.compare(0, 11, "local_size_") == 0) { + profileRequires(loc, EEsProfile, 310, 0, "gl_WorkGroupSize"); + profileRequires(loc, ~EEsProfile, 430, E_GL_ARB_compute_shader, "gl_WorkGroupSize"); + if (id.size() == 12 && value == 0) { + error(loc, "must be at least 1", id.c_str(), ""); + return; + } + if (id == "local_size_x") { + publicType.shaderQualifiers.localSize[0] = value; + return; + } + if (id == "local_size_y") { + publicType.shaderQualifiers.localSize[1] = value; + return; + } + if (id == "local_size_z") { + publicType.shaderQualifiers.localSize[2] = value; + return; + } + if (spvVersion.spv != 0) { + if (id == "local_size_x_id") { + publicType.shaderQualifiers.localSizeSpecId[0] = value; + return; + } + if (id == "local_size_y_id") { + publicType.shaderQualifiers.localSizeSpecId[1] = value; + return; + } + if (id == "local_size_z_id") { + publicType.shaderQualifiers.localSizeSpecId[2] = value; + return; + } + } + } + break; + + default: + break; + } + + error(loc, "there is no such layout identifier for this stage taking an assigned value", id.c_str(), ""); +} + +// Merge any layout qualifier information from src into dst, leaving everything else in dst alone +// +// "More than one layout qualifier may appear in a single declaration. +// Additionally, the same layout-qualifier-name can occur multiple times +// within a layout qualifier or across multiple layout qualifiers in the +// same declaration. When the same layout-qualifier-name occurs +// multiple times, in a single declaration, the last occurrence overrides +// the former occurrence(s). Further, if such a layout-qualifier-name +// will effect subsequent declarations or other observable behavior, it +// is only the last occurrence that will have any effect, behaving as if +// the earlier occurrence(s) within the declaration are not present. +// This is also true for overriding layout-qualifier-names, where one +// overrides the other (e.g., row_major vs. column_major); only the last +// occurrence has any effect." +void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifier& src, bool inheritOnly) +{ + if (src.hasMatrix()) + dst.layoutMatrix = src.layoutMatrix; + if (src.hasPacking()) + dst.layoutPacking = src.layoutPacking; + + if (src.hasStream()) + dst.layoutStream = src.layoutStream; + + if (src.hasFormat()) + dst.layoutFormat = src.layoutFormat; + + if (src.hasXfbBuffer()) + dst.layoutXfbBuffer = src.layoutXfbBuffer; + + if (src.hasAlign()) + dst.layoutAlign = src.layoutAlign; + + if (! inheritOnly) { + if (src.hasLocation()) + dst.layoutLocation = src.layoutLocation; + if (src.hasComponent()) + dst.layoutComponent = src.layoutComponent; + if (src.hasIndex()) + dst.layoutIndex = src.layoutIndex; + + if (src.hasOffset()) + dst.layoutOffset = src.layoutOffset; + + if (src.hasSet()) + dst.layoutSet = src.layoutSet; + if (src.layoutBinding != TQualifier::layoutBindingEnd) + dst.layoutBinding = src.layoutBinding; + + if (src.hasXfbStride()) + dst.layoutXfbStride = src.layoutXfbStride; + if (src.hasXfbOffset()) + dst.layoutXfbOffset = src.layoutXfbOffset; + if (src.hasAttachment()) + dst.layoutAttachment = src.layoutAttachment; + if (src.hasSpecConstantId()) + dst.layoutSpecConstantId = src.layoutSpecConstantId; + + if (src.layoutPushConstant) + dst.layoutPushConstant = true; + +#ifdef NV_EXTENSIONS + if (src.layoutPassthrough) + dst.layoutPassthrough = true; + if (src.layoutViewportRelative) + dst.layoutViewportRelative = true; + if (src.layoutSecondaryViewportRelativeOffset != -2048) + dst.layoutSecondaryViewportRelativeOffset = src.layoutSecondaryViewportRelativeOffset; +#endif + } +} + +// Do error layout error checking given a full variable/block declaration. +void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symbol) +{ + const TType& type = symbol.getType(); + const TQualifier& qualifier = type.getQualifier(); + + // first, cross check WRT to just the type + layoutTypeCheck(loc, type); + + // now, any remaining error checking based on the object itself + + if (qualifier.hasAnyLocation()) { + switch (qualifier.storage) { + case EvqUniform: + case EvqBuffer: + if (symbol.getAsVariable() == nullptr) + error(loc, "can only be used on variable declaration", "location", ""); + break; + default: + break; + } + } + + // user-variable location check, which are required for SPIR-V in/out: + // - variables have it directly, + // - blocks have it on each member (already enforced), so check first one + if (spvVersion.spv > 0 && !parsingBuiltins && qualifier.builtIn == EbvNone && + !qualifier.hasLocation() && !intermediate.getAutoMapLocations()) { + + switch (qualifier.storage) { + case EvqVaryingIn: + case EvqVaryingOut: + if (type.getBasicType() != EbtBlock || + (!(*type.getStruct())[0].type->getQualifier().hasLocation() && + (*type.getStruct())[0].type->getQualifier().builtIn == EbvNone)) + error(loc, "SPIR-V requires location for user input/output", "location", ""); + break; + default: + break; + } + } + + // Check packing and matrix + if (qualifier.hasUniformLayout()) { + switch (qualifier.storage) { + case EvqUniform: + case EvqBuffer: + if (type.getBasicType() != EbtBlock) { + if (qualifier.hasMatrix()) + error(loc, "cannot specify matrix layout on a variable declaration", "layout", ""); + if (qualifier.hasPacking()) + error(loc, "cannot specify packing on a variable declaration", "layout", ""); + // "The offset qualifier can only be used on block members of blocks..." + if (qualifier.hasOffset() && type.getBasicType() != EbtAtomicUint) + error(loc, "cannot specify on a variable declaration", "offset", ""); + // "The align qualifier can only be used on blocks or block members..." + if (qualifier.hasAlign()) + error(loc, "cannot specify on a variable declaration", "align", ""); + if (qualifier.layoutPushConstant) + error(loc, "can only specify on a uniform block", "push_constant", ""); + } + break; + default: + // these were already filtered by layoutTypeCheck() (or its callees) + break; + } + } +} + +// "For some blocks declared as arrays, the location can only be applied at the block level: +// When a block is declared as an array where additional locations are needed for each member +// for each block array element, it is a compile-time error to specify locations on the block +// members. That is, when locations would be under specified by applying them on block members, +// they are not allowed on block members. For arrayed interfaces (those generally having an +// extra level of arrayness due to interface expansion), the outer array is stripped before +// applying this rule." +void TParseContext::layoutMemberLocationArrayCheck(const TSourceLoc& loc, bool memberWithLocation, TArraySizes* arraySizes) +{ + if (memberWithLocation && arraySizes != nullptr) { + if (arraySizes->getNumDims() > (currentBlockQualifier.isArrayedIo(language) ? 1 : 0)) + error(loc, "cannot use in a block array where new locations are needed for each block element", + "location", ""); + } +} + +// Do layout error checking with respect to a type. +void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) +{ + const TQualifier& qualifier = type.getQualifier(); + + // first, intra-layout qualifier-only error checking + layoutQualifierCheck(loc, qualifier); + + // now, error checking combining type and qualifier + + if (qualifier.hasAnyLocation()) { + if (qualifier.hasLocation()) { + if (qualifier.storage == EvqVaryingOut && language == EShLangFragment) { + if (qualifier.layoutLocation >= (unsigned int)resources.maxDrawBuffers) + error(loc, "too large for fragment output", "location", ""); + } + } + if (qualifier.hasComponent()) { + // "It is a compile-time error if this sequence of components gets larger than 3." + if (qualifier.layoutComponent + type.getVectorSize() * (type.getBasicType() == EbtDouble ? 2 : 1) > 4) + error(loc, "type overflows the available 4 components", "component", ""); + + // "It is a compile-time error to apply the component qualifier to a matrix, a structure, a block, or an array containing any of these." + if (type.isMatrix() || type.getBasicType() == EbtBlock || type.getBasicType() == EbtStruct) + error(loc, "cannot apply to a matrix, structure, or block", "component", ""); + + // " It is a compile-time error to use component 1 or 3 as the beginning of a double or dvec2." + if (type.getBasicType() == EbtDouble) + if (qualifier.layoutComponent & 1) + error(loc, "doubles cannot start on an odd-numbered component", "component", ""); + } + + switch (qualifier.storage) { + case EvqVaryingIn: + case EvqVaryingOut: + if (type.getBasicType() == EbtBlock) + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, "location qualifier on in/out block"); + break; + case EvqUniform: + case EvqBuffer: + if (type.getBasicType() == EbtBlock) + error(loc, "cannot apply to uniform or buffer block", "location", ""); + break; + default: + error(loc, "can only apply to uniform, buffer, in, or out storage qualifiers", "location", ""); + break; + } + + bool typeCollision; + int repeated = intermediate.addUsedLocation(qualifier, type, typeCollision); + if (repeated >= 0 && ! typeCollision) + error(loc, "overlapping use of location", "location", "%d", repeated); + // "fragment-shader outputs ... if two variables are placed within the same + // location, they must have the same underlying type (floating-point or integer)" + if (typeCollision && language == EShLangFragment && qualifier.isPipeOutput()) + error(loc, "fragment outputs sharing the same location must be the same basic type", "location", "%d", repeated); + } + + if (qualifier.hasXfbOffset() && qualifier.hasXfbBuffer()) { + int repeated = intermediate.addXfbBufferOffset(type); + if (repeated >= 0) + error(loc, "overlapping offsets at", "xfb_offset", "offset %d in buffer %d", repeated, qualifier.layoutXfbBuffer); + + // "The offset must be a multiple of the size of the first component of the first + // qualified variable or block member, or a compile-time error results. Further, if applied to an aggregate + // containing a double, the offset must also be a multiple of 8..." + if (type.containsBasicType(EbtDouble) && ! IsMultipleOfPow2(qualifier.layoutXfbOffset, 8)) + error(loc, "type contains double; xfb_offset must be a multiple of 8", "xfb_offset", ""); +#ifdef AMD_EXTENSIONS + // ..., if applied to an aggregate containing a float16_t, the offset must also be a multiple of 2..." + else if (type.containsBasicType(EbtFloat16) && !IsMultipleOfPow2(qualifier.layoutXfbOffset, 2)) + error(loc, "type contains half float; xfb_offset must be a multiple of 2", "xfb_offset", ""); +#endif + else if (! IsMultipleOfPow2(qualifier.layoutXfbOffset, 4)) + error(loc, "must be a multiple of size of first component", "xfb_offset", ""); + } + + if (qualifier.hasXfbStride() && qualifier.hasXfbBuffer()) { + if (! intermediate.setXfbBufferStride(qualifier.layoutXfbBuffer, qualifier.layoutXfbStride)) + error(loc, "all stride settings must match for xfb buffer", "xfb_stride", "%d", qualifier.layoutXfbBuffer); + } + + if (qualifier.hasBinding()) { + // Binding checking, from the spec: + // + // "If the binding point for any uniform or shader storage block instance is less than zero, or greater than or + // equal to the implementation-dependent maximum number of uniform buffer bindings, a compile-time + // error will occur. When the binding identifier is used with a uniform or shader storage block instanced as + // an array of size N, all elements of the array from binding through binding + N - 1 must be within this + // range." + // + if (! type.isOpaque() && type.getBasicType() != EbtBlock) + error(loc, "requires block, or sampler/image, or atomic-counter type", "binding", ""); + if (type.getBasicType() == EbtSampler) { + int lastBinding = qualifier.layoutBinding; + if (type.isArray()) { + if (type.isImplicitlySizedArray()) { + lastBinding += 1; + warn(loc, "assuming array size of one for compile-time checking of binding numbers for implicitly-sized array", "[]", ""); + } else + lastBinding += type.getCumulativeArraySize(); + } + if (spvVersion.vulkan == 0 && lastBinding >= resources.maxCombinedTextureImageUnits) + error(loc, "sampler binding not less than gl_MaxCombinedTextureImageUnits", "binding", type.isArray() ? "(using array)" : ""); + } + if (type.getBasicType() == EbtAtomicUint) { + if (qualifier.layoutBinding >= (unsigned int)resources.maxAtomicCounterBindings) { + error(loc, "atomic_uint binding is too large; see gl_MaxAtomicCounterBindings", "binding", ""); + return; + } + } + } + + // atomic_uint + if (type.getBasicType() == EbtAtomicUint) { + if (! type.getQualifier().hasBinding()) + error(loc, "layout(binding=X) is required", "atomic_uint", ""); + } + + // "The offset qualifier can only be used on block members of blocks..." + if (qualifier.hasOffset()) { + if (type.getBasicType() == EbtBlock) + error(loc, "only applies to block members, not blocks", "offset", ""); + } + + // Image format + if (qualifier.hasFormat()) { + if (! type.isImage()) + error(loc, "only apply to images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), ""); + else { + if (type.getSampler().type == EbtFloat && qualifier.layoutFormat > ElfFloatGuard) + error(loc, "does not apply to floating point images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), ""); + if (type.getSampler().type == EbtInt && (qualifier.layoutFormat < ElfFloatGuard || qualifier.layoutFormat > ElfIntGuard)) + error(loc, "does not apply to signed integer images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), ""); + if (type.getSampler().type == EbtUint && qualifier.layoutFormat < ElfIntGuard) + error(loc, "does not apply to unsigned integer images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), ""); + + if (profile == EEsProfile) { + // "Except for image variables qualified with the format qualifiers r32f, r32i, and r32ui, image variables must + // specify either memory qualifier readonly or the memory qualifier writeonly." + if (! (qualifier.layoutFormat == ElfR32f || qualifier.layoutFormat == ElfR32i || qualifier.layoutFormat == ElfR32ui)) { + if (! qualifier.readonly && ! qualifier.writeonly) + error(loc, "format requires readonly or writeonly memory qualifier", TQualifier::getLayoutFormatString(qualifier.layoutFormat), ""); + } + } + } + } else if (type.isImage() && ! qualifier.writeonly) { + const char *explanation = "image variables not declared 'writeonly' and without a format layout qualifier"; + requireProfile(loc, ECoreProfile | ECompatibilityProfile, explanation); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 0, E_GL_EXT_shader_image_load_formatted, explanation); + } + + if (qualifier.layoutPushConstant && type.getBasicType() != EbtBlock) + error(loc, "can only be used with a block", "push_constant", ""); + + // input attachment + if (type.isSubpass()) { + if (! qualifier.hasAttachment()) + error(loc, "requires an input_attachment_index layout qualifier", "subpass", ""); + } else { + if (qualifier.hasAttachment()) + error(loc, "can only be used with a subpass", "input_attachment_index", ""); + } + + // specialization-constant id + if (qualifier.hasSpecConstantId()) { + if (type.getQualifier().storage != EvqConst) + error(loc, "can only be applied to 'const'-qualified scalar", "constant_id", ""); + if (! type.isScalar()) + error(loc, "can only be applied to a scalar", "constant_id", ""); + switch (type.getBasicType()) + { + case EbtInt: + case EbtUint: + case EbtInt64: + case EbtUint64: +#ifdef AMD_EXTENSIONS + case EbtInt16: + case EbtUint16: +#endif + case EbtBool: + case EbtFloat: + case EbtDouble: +#ifdef AMD_EXTENSIONS + case EbtFloat16: +#endif + break; + default: + error(loc, "cannot be applied to this type", "constant_id", ""); + break; + } + } +} + +// Do layout error checking that can be done within a layout qualifier proper, not needing to know +// if there are blocks, atomic counters, variables, etc. +void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier& qualifier) +{ + if (qualifier.storage == EvqShared && qualifier.hasLayout()) + error(loc, "cannot apply layout qualifiers to a shared variable", "shared", ""); + + // "It is a compile-time error to use *component* without also specifying the location qualifier (order does not matter)." + if (qualifier.hasComponent() && ! qualifier.hasLocation()) + error(loc, "must specify 'location' to use 'component'", "component", ""); + + if (qualifier.hasAnyLocation()) { + + // "As with input layout qualifiers, all shaders except compute shaders + // allow *location* layout qualifiers on output variable declarations, + // output block declarations, and output block member declarations." + + switch (qualifier.storage) { + case EvqVaryingIn: + { + const char* feature = "location qualifier on input"; + if (profile == EEsProfile && version < 310) + requireStage(loc, EShLangVertex, feature); + else + requireStage(loc, (EShLanguageMask)~EShLangComputeMask, feature); + if (language == EShLangVertex) { + const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location }; + profileRequires(loc, ~EEsProfile, 330, 2, exts, feature); + profileRequires(loc, EEsProfile, 300, nullptr, feature); + } else { + profileRequires(loc, ~EEsProfile, 410, E_GL_ARB_separate_shader_objects, feature); + profileRequires(loc, EEsProfile, 310, nullptr, feature); + } + break; + } + case EvqVaryingOut: + { + const char* feature = "location qualifier on output"; + if (profile == EEsProfile && version < 310) + requireStage(loc, EShLangFragment, feature); + else + requireStage(loc, (EShLanguageMask)~EShLangComputeMask, feature); + if (language == EShLangFragment) { + const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location }; + profileRequires(loc, ~EEsProfile, 330, 2, exts, feature); + profileRequires(loc, EEsProfile, 300, nullptr, feature); + } else { + profileRequires(loc, ~EEsProfile, 410, E_GL_ARB_separate_shader_objects, feature); + profileRequires(loc, EEsProfile, 310, nullptr, feature); + } + break; + } + case EvqUniform: + case EvqBuffer: + { + const char* feature = "location qualifier on uniform or buffer"; + requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, feature); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, feature); + profileRequires(loc, EEsProfile, 310, nullptr, feature); + break; + } + default: + break; + } + if (qualifier.hasIndex()) { + if (qualifier.storage != EvqVaryingOut) + error(loc, "can only be used on an output", "index", ""); + if (! qualifier.hasLocation()) + error(loc, "can only be used with an explicit location", "index", ""); + } + } + + if (qualifier.hasBinding()) { + if (! qualifier.isUniformOrBuffer()) + error(loc, "requires uniform or buffer storage qualifier", "binding", ""); + } + if (qualifier.hasStream()) { + if (qualifier.storage != EvqVaryingOut) + error(loc, "can only be used on an output", "stream", ""); + } + if (qualifier.hasXfb()) { + if (qualifier.storage != EvqVaryingOut) + error(loc, "can only be used on an output", "xfb layout qualifier", ""); + } + if (qualifier.hasUniformLayout()) { + if (! qualifier.isUniformOrBuffer()) { + if (qualifier.hasMatrix() || qualifier.hasPacking()) + error(loc, "matrix or packing qualifiers can only be used on a uniform or buffer", "layout", ""); + if (qualifier.hasOffset() || qualifier.hasAlign()) + error(loc, "offset/align can only be used on a uniform or buffer", "layout", ""); + } + } + if (qualifier.layoutPushConstant) { + if (qualifier.storage != EvqUniform) + error(loc, "can only be used with a uniform", "push_constant", ""); + if (qualifier.hasSet()) + error(loc, "cannot be used with push_constant", "set", ""); + } +} + +// For places that can't have shader-level layout qualifiers +void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQualifiers& shaderQualifiers) +{ + const char* message = "can only apply to a standalone qualifier"; + + if (shaderQualifiers.geometry != ElgNone) + error(loc, message, TQualifier::getGeometryString(shaderQualifiers.geometry), ""); + if (shaderQualifiers.spacing != EvsNone) + error(loc, message, TQualifier::getVertexSpacingString(shaderQualifiers.spacing), ""); + if (shaderQualifiers.order != EvoNone) + error(loc, message, TQualifier::getVertexOrderString(shaderQualifiers.order), ""); + if (shaderQualifiers.pointMode) + error(loc, message, "point_mode", ""); + if (shaderQualifiers.invocations != TQualifier::layoutNotSet) + error(loc, message, "invocations", ""); + if (shaderQualifiers.earlyFragmentTests) + error(loc, message, "early_fragment_tests", ""); + if (shaderQualifiers.postDepthCoverage) + error(loc, message, "post_depth_coverage", ""); + for (int i = 0; i < 3; ++i) { + if (shaderQualifiers.localSize[i] > 1) + error(loc, message, "local_size", ""); + if (shaderQualifiers.localSizeSpecId[i] != TQualifier::layoutNotSet) + error(loc, message, "local_size id", ""); + } + if (shaderQualifiers.vertices != TQualifier::layoutNotSet) { + if (language == EShLangGeometry) + error(loc, message, "max_vertices", ""); + else if (language == EShLangTessControl) + error(loc, message, "vertices", ""); + else + assert(0); + } + if (shaderQualifiers.blendEquation) + error(loc, message, "blend equation", ""); + if (shaderQualifiers.numViews != TQualifier::layoutNotSet) + error(loc, message, "num_views", ""); +} + +// Correct and/or advance an object's offset layout qualifier. +void TParseContext::fixOffset(const TSourceLoc& loc, TSymbol& symbol) +{ + const TQualifier& qualifier = symbol.getType().getQualifier(); + if (symbol.getType().getBasicType() == EbtAtomicUint) { + if (qualifier.hasBinding() && (int)qualifier.layoutBinding < resources.maxAtomicCounterBindings) { + + // Set the offset + int offset; + if (qualifier.hasOffset()) + offset = qualifier.layoutOffset; + else + offset = atomicUintOffsets[qualifier.layoutBinding]; + symbol.getWritableType().getQualifier().layoutOffset = offset; + + // Check for overlap + int numOffsets = 4; + if (symbol.getType().isArray()) { + if (symbol.getType().isExplicitlySizedArray() && ! symbol.getType().getArraySizes()->isInnerImplicit()) + numOffsets *= symbol.getType().getCumulativeArraySize(); + else { + // "It is a compile-time error to declare an unsized array of atomic_uint." + error(loc, "array must be explicitly sized", "atomic_uint", ""); + } + } + int repeated = intermediate.addUsedOffsets(qualifier.layoutBinding, offset, numOffsets); + if (repeated >= 0) + error(loc, "atomic counters sharing the same offset:", "offset", "%d", repeated); + + // Bump the default offset + atomicUintOffsets[qualifier.layoutBinding] = offset + numOffsets; + } + } +} + +// +// Look up a function name in the symbol table, and make sure it is a function. +// +// Return the function symbol if found, otherwise nullptr. +// +const TFunction* TParseContext::findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn) +{ + const TFunction* function = nullptr; + + if (symbolTable.isFunctionNameVariable(call.getName())) { + error(loc, "can't use function syntax on variable", call.getName().c_str(), ""); + return nullptr; + } + + if (profile == EEsProfile || version < 120) + function = findFunctionExact(loc, call, builtIn); + else if (version < 400) + function = findFunction120(loc, call, builtIn); + else + function = findFunction400(loc, call, builtIn); + + return function; +} + +// Function finding algorithm for ES and desktop 110. +const TFunction* TParseContext::findFunctionExact(const TSourceLoc& loc, const TFunction& call, bool& builtIn) +{ + TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn); + if (symbol == nullptr) { + error(loc, "no matching overloaded function found", call.getName().c_str(), ""); + + return nullptr; + } + + return symbol->getAsFunction(); +} + +// Function finding algorithm for desktop versions 120 through 330. +const TFunction* TParseContext::findFunction120(const TSourceLoc& loc, const TFunction& call, bool& builtIn) +{ + // first, look for an exact match + TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn); + if (symbol) + return symbol->getAsFunction(); + + // exact match not found, look through a list of overloaded functions of the same name + + // "If no exact match is found, then [implicit conversions] will be applied to find a match. Mismatched types + // on input parameters (in or inout or default) must have a conversion from the calling argument type to the + // formal parameter type. Mismatched types on output parameters (out or inout) must have a conversion + // from the formal parameter type to the calling argument type. When argument conversions are used to find + // a match, it is a semantic error if there are multiple ways to apply these conversions to make the call match + // more than one function." + + const TFunction* candidate = nullptr; + TVector candidateList; + symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn); + + for (auto it = candidateList.begin(); it != candidateList.end(); ++it) { + const TFunction& function = *(*it); + + // to even be a potential match, number of arguments has to match + if (call.getParamCount() != function.getParamCount()) + continue; + + bool possibleMatch = true; + for (int i = 0; i < function.getParamCount(); ++i) { + // same types is easy + if (*function[i].type == *call[i].type) + continue; + + // We have a mismatch in type, see if it is implicitly convertible + + if (function[i].type->isArray() || call[i].type->isArray() || + ! function[i].type->sameElementShape(*call[i].type)) + possibleMatch = false; + else { + // do direction-specific checks for conversion of basic type + if (function[i].type->getQualifier().isParamInput()) { + if (! intermediate.canImplicitlyPromote(call[i].type->getBasicType(), function[i].type->getBasicType())) + possibleMatch = false; + } + if (function[i].type->getQualifier().isParamOutput()) { + if (! intermediate.canImplicitlyPromote(function[i].type->getBasicType(), call[i].type->getBasicType())) + possibleMatch = false; + } + } + if (! possibleMatch) + break; + } + if (possibleMatch) { + if (candidate) { + // our second match, meaning ambiguity + error(loc, "ambiguous function signature match: multiple signatures match under implicit type conversion", call.getName().c_str(), ""); + } else + candidate = &function; + } + } + + if (candidate == nullptr) + error(loc, "no matching overloaded function found", call.getName().c_str(), ""); + + return candidate; +} + +// Function finding algorithm for desktop version 400 and above. +// +// "When function calls are resolved, an exact type match for all the arguments +// is sought. If an exact match is found, all other functions are ignored, and +// the exact match is used. If no exact match is found, then the implicit +// conversions in section 4.1.10 Implicit Conversions will be applied to find +// a match. Mismatched types on input parameters (in or inout or default) must +// have a conversion from the calling argument type to the formal parameter type. +// Mismatched types on output parameters (out or inout) must have a conversion +// from the formal parameter type to the calling argument type. +// +// "If implicit conversions can be used to find more than one matching function, +// a single best-matching function is sought. To determine a best match, the +// conversions between calling argument and formal parameter types are compared +// for each function argument and pair of matching functions. After these +// comparisons are performed, each pair of matching functions are compared. +// A function declaration A is considered a better match than function +// declaration B if +// +// * for at least one function argument, the conversion for that argument in A +// is better than the corresponding conversion in B; and +// * there is no function argument for which the conversion in B is better than +// the corresponding conversion in A. +// +// "If a single function declaration is considered a better match than every +// other matching function declaration, it will be used. Otherwise, a +// compile-time semantic error for an ambiguous overloaded function call occurs. +// +// "To determine whether the conversion for a single argument in one match is +// better than that for another match, the following rules are applied, in order: +// +// 1. An exact match is better than a match involving any implicit conversion. +// 2. A match involving an implicit conversion from float to double is better +// than a match involving any other implicit conversion. +// 3. A match involving an implicit conversion from either int or uint to float +// is better than a match involving an implicit conversion from either int +// or uint to double. +// +// "If none of the rules above apply to a particular pair of conversions, neither +// conversion is considered better than the other." +// +const TFunction* TParseContext::findFunction400(const TSourceLoc& loc, const TFunction& call, bool& builtIn) +{ + // first, look for an exact match + TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn); + if (symbol) + return symbol->getAsFunction(); + + // no exact match, use the generic selector, parameterized by the GLSL rules + + // create list of candidates to send + TVector candidateList; + symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn); + + // can 'from' convert to 'to'? + const auto convertible = [this](const TType& from, const TType& to, TOperator, int) -> bool { + if (from == to) + return true; + if (from.isArray() || to.isArray() || ! from.sameElementShape(to)) + return false; + return intermediate.canImplicitlyPromote(from.getBasicType(), to.getBasicType()); + }; + + // Is 'to2' a better conversion than 'to1'? + // Ties should not be considered as better. + // Assumes 'convertible' already said true. + const auto better = [](const TType& from, const TType& to1, const TType& to2) -> bool { + // 1. exact match + if (from == to2) + return from != to1; + if (from == to1) + return false; + + // 2. float -> double is better + if (from.getBasicType() == EbtFloat) { + if (to2.getBasicType() == EbtDouble && to1.getBasicType() != EbtDouble) + return true; + } + + // 3. -> float is better than -> double + return to2.getBasicType() == EbtFloat && to1.getBasicType() == EbtDouble; + }; + + // for ambiguity reporting + bool tie = false; + + // send to the generic selector + const TFunction* bestMatch = selectFunction(candidateList, call, convertible, better, tie); + + if (bestMatch == nullptr) + error(loc, "no matching overloaded function found", call.getName().c_str(), ""); + else if (tie) + error(loc, "ambiguous best function under implicit type conversion", call.getName().c_str(), ""); + + return bestMatch; +} + +// When a declaration includes a type, but not a variable name, it can be +// to establish defaults. +void TParseContext::declareTypeDefaults(const TSourceLoc& loc, const TPublicType& publicType) +{ + if (publicType.basicType == EbtAtomicUint && publicType.qualifier.hasBinding() && publicType.qualifier.hasOffset()) { + if (publicType.qualifier.layoutBinding >= (unsigned int)resources.maxAtomicCounterBindings) { + error(loc, "atomic_uint binding is too large", "binding", ""); + return; + } + atomicUintOffsets[publicType.qualifier.layoutBinding] = publicType.qualifier.layoutOffset; + return; + } + + if (publicType.qualifier.hasLayout()) + warn(loc, "useless application of layout qualifier", "layout", ""); +} + +// +// Do everything necessary to handle a variable (non-block) declaration. +// Either redeclaring a variable, or making a new one, updating the symbol +// table, and all error checking. +// +// Returns a subtree node that computes an initializer, if needed. +// Returns nullptr if there is no code to execute for initialization. +// +// 'publicType' is the type part of the declaration (to the left) +// 'arraySizes' is the arrayness tagged on the identifier (to the right) +// +TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& identifier, const TPublicType& publicType, TArraySizes* arraySizes, TIntermTyped* initializer) +{ + TType type(publicType); // shallow copy; 'type' shares the arrayness and structure definition with 'publicType' + if (type.isImplicitlySizedArray()) { + // Because "int[] a = int[2](...), b = int[3](...)" makes two arrays a and b + // of different sizes, for this case sharing the shallow copy of arrayness + // with the publicType oversubscribes it, so get a deep copy of the arrayness. + type.newArraySizes(*publicType.arraySizes); + } + + if (voidErrorCheck(loc, identifier, type.getBasicType())) + return nullptr; + + if (initializer) + rValueErrorCheck(loc, "initializer", initializer); + else + nonInitConstCheck(loc, identifier, type); + + samplerCheck(loc, type, identifier, initializer); + atomicUintCheck(loc, type, identifier); + transparentOpaqueCheck(loc, type, identifier); + + if (identifier != "gl_FragCoord" && (publicType.shaderQualifiers.originUpperLeft || publicType.shaderQualifiers.pixelCenterInteger)) + error(loc, "can only apply origin_upper_left and pixel_center_origin to gl_FragCoord", "layout qualifier", ""); + if (identifier != "gl_FragDepth" && publicType.shaderQualifiers.layoutDepth != EldNone) + error(loc, "can only apply depth layout to gl_FragDepth", "layout qualifier", ""); + + // Check for redeclaration of built-ins and/or attempting to declare a reserved name + TSymbol* symbol = redeclareBuiltinVariable(loc, identifier, type.getQualifier(), publicType.shaderQualifiers); + if (symbol == nullptr) + reservedErrorCheck(loc, identifier); + + inheritGlobalDefaults(type.getQualifier()); + + // Declare the variable + if (arraySizes || type.isArray()) { + // Arrayness is potentially coming both from the type and from the + // variable: "int[] a[];" or just one or the other. + // Merge it all to the type, so all arrayness is part of the type. + arrayDimCheck(loc, &type, arraySizes); + arrayDimMerge(type, arraySizes); + + // Check that implicit sizing is only where allowed. + arraySizesCheck(loc, type.getQualifier(), &type.getArraySizes(), initializer != nullptr, false); + + if (! arrayQualifierError(loc, type.getQualifier()) && ! arrayError(loc, type)) + declareArray(loc, identifier, type, symbol); + + if (initializer) { + profileRequires(loc, ENoProfile, 120, E_GL_3DL_array_objects, "initializer"); + profileRequires(loc, EEsProfile, 300, nullptr, "initializer"); + } + } else { + // non-array case + if (symbol == nullptr) + symbol = declareNonArray(loc, identifier, type); + else if (type != symbol->getType()) + error(loc, "cannot change the type of", "redeclaration", symbol->getName().c_str()); + } + + if (symbol == nullptr) + return nullptr; + + // Deal with initializer + TIntermNode* initNode = nullptr; + if (symbol != nullptr && initializer) { + TVariable* variable = symbol->getAsVariable(); + if (! variable) { + error(loc, "initializer requires a variable, not a member", identifier.c_str(), ""); + return nullptr; + } + initNode = executeInitializer(loc, initializer, variable); + } + + // look for errors in layout qualifier use + layoutObjectCheck(loc, *symbol); + + // fix up + fixOffset(loc, *symbol); + + return initNode; +} + +// Pick up global defaults from the provide global defaults into dst. +void TParseContext::inheritGlobalDefaults(TQualifier& dst) const +{ + if (dst.storage == EvqVaryingOut) { + if (! dst.hasStream() && language == EShLangGeometry) + dst.layoutStream = globalOutputDefaults.layoutStream; + if (! dst.hasXfbBuffer()) + dst.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer; + } +} + +// +// Make an internal-only variable whose name is for debug purposes only +// and won't be searched for. Callers will only use the return value to use +// the variable, not the name to look it up. It is okay if the name +// is the same as other names; there won't be any conflict. +// +TVariable* TParseContext::makeInternalVariable(const char* name, const TType& type) const +{ + TString* nameString = NewPoolTString(name); + TVariable* variable = new TVariable(nameString, type); + symbolTable.makeInternalVariable(*variable); + + return variable; +} + +// +// Declare a non-array variable, the main point being there is no redeclaration +// for resizing allowed. +// +// Return the successfully declared variable. +// +TVariable* TParseContext::declareNonArray(const TSourceLoc& loc, const TString& identifier, const TType& type) +{ + // make a new variable + TVariable* variable = new TVariable(&identifier, type); + + ioArrayCheck(loc, type, identifier); + + // add variable to symbol table + if (symbolTable.insert(*variable)) { + if (symbolTable.atGlobalLevel()) + trackLinkage(*variable); + return variable; + } + + error(loc, "redefinition", variable->getName().c_str(), ""); + return nullptr; +} + +// +// Handle all types of initializers from the grammar. +// +// Returning nullptr just means there is no code to execute to handle the +// initializer, which will, for example, be the case for constant initializers. +// +TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyped* initializer, TVariable* variable) +{ + // + // Identifier must be of type constant, a global, or a temporary, and + // starting at version 120, desktop allows uniforms to have initializers. + // + TStorageQualifier qualifier = variable->getType().getQualifier().storage; + if (! (qualifier == EvqTemporary || qualifier == EvqGlobal || qualifier == EvqConst || + (qualifier == EvqUniform && profile != EEsProfile && version >= 120))) { + error(loc, " cannot initialize this type of qualifier ", variable->getType().getStorageQualifierString(), ""); + return nullptr; + } + arrayObjectCheck(loc, variable->getType(), "array initializer"); + + // + // If the initializer was from braces { ... }, we convert the whole subtree to a + // constructor-style subtree, allowing the rest of the code to operate + // identically for both kinds of initializers. + // + // Type can't be deduced from the initializer list, so a skeletal type to + // follow has to be passed in. Constness and specialization-constness + // should be deduced bottom up, not dictated by the skeletal type. + // + TType skeletalType; + skeletalType.shallowCopy(variable->getType()); + skeletalType.getQualifier().makeTemporary(); + initializer = convertInitializerList(loc, skeletalType, initializer); + if (! initializer) { + // error recovery; don't leave const without constant values + if (qualifier == EvqConst) + variable->getWritableType().getQualifier().makeTemporary(); + return nullptr; + } + + // Fix outer arrayness if variable is unsized, getting size from the initializer + if (initializer->getType().isExplicitlySizedArray() && + variable->getType().isImplicitlySizedArray()) + variable->getWritableType().changeOuterArraySize(initializer->getType().getOuterArraySize()); + + // Inner arrayness can also get set by an initializer + if (initializer->getType().isArrayOfArrays() && variable->getType().isArrayOfArrays() && + initializer->getType().getArraySizes()->getNumDims() == + variable->getType().getArraySizes()->getNumDims()) { + // adopt unsized sizes from the initializer's sizes + for (int d = 1; d < variable->getType().getArraySizes()->getNumDims(); ++d) { + if (variable->getType().getArraySizes()->getDimSize(d) == UnsizedArraySize) + variable->getWritableType().getArraySizes().setDimSize(d, initializer->getType().getArraySizes()->getDimSize(d)); + } + } + + // Uniforms require a compile-time constant initializer + if (qualifier == EvqUniform && ! initializer->getType().getQualifier().isFrontEndConstant()) { + error(loc, "uniform initializers must be constant", "=", "'%s'", variable->getType().getCompleteString().c_str()); + variable->getWritableType().getQualifier().makeTemporary(); + return nullptr; + } + // Global consts require a constant initializer (specialization constant is okay) + if (qualifier == EvqConst && symbolTable.atGlobalLevel() && ! initializer->getType().getQualifier().isConstant()) { + error(loc, "global const initializers must be constant", "=", "'%s'", variable->getType().getCompleteString().c_str()); + variable->getWritableType().getQualifier().makeTemporary(); + return nullptr; + } + + // Const variables require a constant initializer, depending on version + if (qualifier == EvqConst) { + if (! initializer->getType().getQualifier().isConstant()) { + const char* initFeature = "non-constant initializer"; + requireProfile(loc, ~EEsProfile, initFeature); + profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature); + variable->getWritableType().getQualifier().storage = EvqConstReadOnly; + qualifier = EvqConstReadOnly; + } + } else { + // Non-const global variables in ES need a const initializer. + // + // "In declarations of global variables with no storage qualifier or with a const + // qualifier any initializer must be a constant expression." + if (symbolTable.atGlobalLevel() && ! initializer->getType().getQualifier().isConstant()) { + const char* initFeature = "non-constant global initializer (needs GL_EXT_shader_non_constant_global_initializers)"; + if (profile == EEsProfile) { + if (relaxedErrors() && ! extensionTurnedOn(E_GL_EXT_shader_non_constant_global_initializers)) + warn(loc, "not allowed in this version", initFeature, ""); + else + profileRequires(loc, EEsProfile, 0, E_GL_EXT_shader_non_constant_global_initializers, initFeature); + } + } + } + + if (qualifier == EvqConst || qualifier == EvqUniform) { + // Compile-time tagging of the variable with its constant value... + + initializer = intermediate.addConversion(EOpAssign, variable->getType(), initializer); + if (! initializer || ! initializer->getType().getQualifier().isConstant() || variable->getType() != initializer->getType()) { + error(loc, "non-matching or non-convertible constant type for const initializer", + variable->getType().getStorageQualifierString(), ""); + variable->getWritableType().getQualifier().makeTemporary(); + return nullptr; + } + + // We either have a folded constant in getAsConstantUnion, or we have to use + // the initializer's subtree in the AST to represent the computation of a + // specialization constant. + assert(initializer->getAsConstantUnion() || initializer->getType().getQualifier().isSpecConstant()); + if (initializer->getAsConstantUnion()) + variable->setConstArray(initializer->getAsConstantUnion()->getConstArray()); + else { + // It's a specialization constant. + variable->getWritableType().getQualifier().makeSpecConstant(); + + // Keep the subtree that computes the specialization constant with the variable. + // Later, a symbol node will adopt the subtree from the variable. + variable->setConstSubtree(initializer); + } + } else { + // normal assigning of a value to a variable... + specializationCheck(loc, initializer->getType(), "initializer"); + TIntermSymbol* intermSymbol = intermediate.addSymbol(*variable, loc); + TIntermTyped* initNode = intermediate.addAssign(EOpAssign, intermSymbol, initializer, loc); + if (! initNode) + assignError(loc, "=", intermSymbol->getCompleteString(), initializer->getCompleteString()); + + return initNode; + } + + return nullptr; +} + +// +// Reprocess any initializer-list (the "{ ... }" syntax) parts of the +// initializer. +// +// Need to hierarchically assign correct types and implicit +// conversions. Will do this mimicking the same process used for +// creating a constructor-style initializer, ensuring we get the +// same form. However, it has to in parallel walk the 'type' +// passed in, as type cannot be deduced from an initializer list. +// +TIntermTyped* TParseContext::convertInitializerList(const TSourceLoc& loc, const TType& type, TIntermTyped* initializer) +{ + // Will operate recursively. Once a subtree is found that is constructor style, + // everything below it is already good: Only the "top part" of the initializer + // can be an initializer list, where "top part" can extend for several (or all) levels. + + // see if we have bottomed out in the tree within the initializer-list part + TIntermAggregate* initList = initializer->getAsAggregate(); + if (! initList || initList->getOp() != EOpNull) + return initializer; + + // Of the initializer-list set of nodes, need to process bottom up, + // so recurse deep, then process on the way up. + + // Go down the tree here... + if (type.isArray()) { + // The type's array might be unsized, which could be okay, so base sizes on the size of the aggregate. + // Later on, initializer execution code will deal with array size logic. + TType arrayType; + arrayType.shallowCopy(type); // sharing struct stuff is fine + arrayType.newArraySizes(*type.getArraySizes()); // but get a fresh copy of the array information, to edit below + + // edit array sizes to fill in unsized dimensions + arrayType.changeOuterArraySize((int)initList->getSequence().size()); + TIntermTyped* firstInit = initList->getSequence()[0]->getAsTyped(); + if (arrayType.isArrayOfArrays() && firstInit->getType().isArray() && + arrayType.getArraySizes().getNumDims() == firstInit->getType().getArraySizes()->getNumDims() + 1) { + for (int d = 1; d < arrayType.getArraySizes().getNumDims(); ++d) { + if (arrayType.getArraySizes().getDimSize(d) == UnsizedArraySize) + arrayType.getArraySizes().setDimSize(d, firstInit->getType().getArraySizes()->getDimSize(d - 1)); + } + } + + TType elementType(arrayType, 0); // dereferenced type + for (size_t i = 0; i < initList->getSequence().size(); ++i) { + initList->getSequence()[i] = convertInitializerList(loc, elementType, initList->getSequence()[i]->getAsTyped()); + if (initList->getSequence()[i] == nullptr) + return nullptr; + } + + return addConstructor(loc, initList, arrayType); + } else if (type.isStruct()) { + if (type.getStruct()->size() != initList->getSequence().size()) { + error(loc, "wrong number of structure members", "initializer list", ""); + return nullptr; + } + for (size_t i = 0; i < type.getStruct()->size(); ++i) { + initList->getSequence()[i] = convertInitializerList(loc, *(*type.getStruct())[i].type, initList->getSequence()[i]->getAsTyped()); + if (initList->getSequence()[i] == nullptr) + return nullptr; + } + } else if (type.isMatrix()) { + if (type.getMatrixCols() != (int)initList->getSequence().size()) { + error(loc, "wrong number of matrix columns:", "initializer list", type.getCompleteString().c_str()); + return nullptr; + } + TType vectorType(type, 0); // dereferenced type + for (int i = 0; i < type.getMatrixCols(); ++i) { + initList->getSequence()[i] = convertInitializerList(loc, vectorType, initList->getSequence()[i]->getAsTyped()); + if (initList->getSequence()[i] == nullptr) + return nullptr; + } + } else if (type.isVector()) { + if (type.getVectorSize() != (int)initList->getSequence().size()) { + error(loc, "wrong vector size (or rows in a matrix column):", "initializer list", type.getCompleteString().c_str()); + return nullptr; + } + } else { + error(loc, "unexpected initializer-list type:", "initializer list", type.getCompleteString().c_str()); + return nullptr; + } + + // Now that the subtree is processed, process this node as if the + // initializer list is a set of arguments to a constructor. + TIntermNode* emulatedConstructorArguments; + if (initList->getSequence().size() == 1) + emulatedConstructorArguments = initList->getSequence()[0]; + else + emulatedConstructorArguments = initList; + return addConstructor(loc, emulatedConstructorArguments, type); +} + +// +// Test for the correctness of the parameters passed to various constructor functions +// and also convert them to the right data type, if allowed and required. +// +// 'node' is what to construct from. +// 'type' is what type to construct. +// +// Returns nullptr for an error or the constructed node (aggregate or typed) for no error. +// +TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode* node, const TType& type) +{ + if (node == nullptr || node->getAsTyped() == nullptr) + return nullptr; + rValueErrorCheck(loc, "constructor", node->getAsTyped()); + + TIntermAggregate* aggrNode = node->getAsAggregate(); + TOperator op = intermediate.mapTypeToConstructorOp(type); + + // Combined texture-sampler constructors are completely semantic checked + // in constructorTextureSamplerError() + if (op == EOpConstructTextureSampler) + return intermediate.setAggregateOperator(aggrNode, op, type, loc); + + TTypeList::const_iterator memberTypes; + if (op == EOpConstructStruct) + memberTypes = type.getStruct()->begin(); + + TType elementType; + if (type.isArray()) { + TType dereferenced(type, 0); + elementType.shallowCopy(dereferenced); + } else + elementType.shallowCopy(type); + + bool singleArg; + if (aggrNode) { + if (aggrNode->getOp() != EOpNull) + singleArg = true; + else + singleArg = false; + } else + singleArg = true; + + TIntermTyped *newNode; + if (singleArg) { + // If structure constructor or array constructor is being called + // for only one parameter inside the structure, we need to call constructAggregate function once. + if (type.isArray()) + newNode = constructAggregate(node, elementType, 1, node->getLoc()); + else if (op == EOpConstructStruct) + newNode = constructAggregate(node, *(*memberTypes).type, 1, node->getLoc()); + else + newNode = constructBuiltIn(type, op, node->getAsTyped(), node->getLoc(), false); + + if (newNode && (type.isArray() || op == EOpConstructStruct)) + newNode = intermediate.setAggregateOperator(newNode, EOpConstructStruct, type, loc); + + return newNode; + } + + // + // Handle list of arguments. + // + TIntermSequence &sequenceVector = aggrNode->getSequence(); // Stores the information about the parameter to the constructor + // if the structure constructor contains more than one parameter, then construct + // each parameter + + int paramCount = 0; // keeps track of the constructor parameter number being checked + + // for each parameter to the constructor call, check to see if the right type is passed or convert them + // to the right type if possible (and allowed). + // for structure constructors, just check if the right type is passed, no conversion is allowed. + for (TIntermSequence::iterator p = sequenceVector.begin(); + p != sequenceVector.end(); p++, paramCount++) { + if (type.isArray()) + newNode = constructAggregate(*p, elementType, paramCount+1, node->getLoc()); + else if (op == EOpConstructStruct) + newNode = constructAggregate(*p, *(memberTypes[paramCount]).type, paramCount+1, node->getLoc()); + else + newNode = constructBuiltIn(type, op, (*p)->getAsTyped(), node->getLoc(), true); + + if (newNode) + *p = newNode; + else + return nullptr; + } + + return intermediate.setAggregateOperator(aggrNode, op, type, loc); +} + +// Function for constructor implementation. Calls addUnaryMath with appropriate EOp value +// for the parameter to the constructor (passed to this function). Essentially, it converts +// the parameter types correctly. If a constructor expects an int (like ivec2) and is passed a +// float, then float is converted to int. +// +// Returns nullptr for an error or the constructed node. +// +TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, TIntermTyped* node, const TSourceLoc& loc, bool subset) +{ + TIntermTyped* newNode; + TOperator basicOp; + + // + // First, convert types as needed. + // + switch (op) { + case EOpConstructVec2: + case EOpConstructVec3: + case EOpConstructVec4: + case EOpConstructMat2x2: + case EOpConstructMat2x3: + case EOpConstructMat2x4: + case EOpConstructMat3x2: + case EOpConstructMat3x3: + case EOpConstructMat3x4: + case EOpConstructMat4x2: + case EOpConstructMat4x3: + case EOpConstructMat4x4: + case EOpConstructFloat: + basicOp = EOpConstructFloat; + break; + + case EOpConstructDVec2: + case EOpConstructDVec3: + case EOpConstructDVec4: + case EOpConstructDMat2x2: + case EOpConstructDMat2x3: + case EOpConstructDMat2x4: + case EOpConstructDMat3x2: + case EOpConstructDMat3x3: + case EOpConstructDMat3x4: + case EOpConstructDMat4x2: + case EOpConstructDMat4x3: + case EOpConstructDMat4x4: + case EOpConstructDouble: + basicOp = EOpConstructDouble; + break; + +#ifdef AMD_EXTENSIONS + case EOpConstructF16Vec2: + case EOpConstructF16Vec3: + case EOpConstructF16Vec4: + case EOpConstructF16Mat2x2: + case EOpConstructF16Mat2x3: + case EOpConstructF16Mat2x4: + case EOpConstructF16Mat3x2: + case EOpConstructF16Mat3x3: + case EOpConstructF16Mat3x4: + case EOpConstructF16Mat4x2: + case EOpConstructF16Mat4x3: + case EOpConstructF16Mat4x4: + case EOpConstructFloat16: + basicOp = EOpConstructFloat16; + break; +#endif + + case EOpConstructIVec2: + case EOpConstructIVec3: + case EOpConstructIVec4: + case EOpConstructInt: + basicOp = EOpConstructInt; + break; + + case EOpConstructUVec2: + case EOpConstructUVec3: + case EOpConstructUVec4: + case EOpConstructUint: + basicOp = EOpConstructUint; + break; + + case EOpConstructI64Vec2: + case EOpConstructI64Vec3: + case EOpConstructI64Vec4: + case EOpConstructInt64: + basicOp = EOpConstructInt64; + break; + + case EOpConstructU64Vec2: + case EOpConstructU64Vec3: + case EOpConstructU64Vec4: + case EOpConstructUint64: + basicOp = EOpConstructUint64; + break; + +#ifdef AMD_EXTENSIONS + case EOpConstructI16Vec2: + case EOpConstructI16Vec3: + case EOpConstructI16Vec4: + case EOpConstructInt16: + basicOp = EOpConstructInt16; + break; + + case EOpConstructU16Vec2: + case EOpConstructU16Vec3: + case EOpConstructU16Vec4: + case EOpConstructUint16: + basicOp = EOpConstructUint16; + break; +#endif + + case EOpConstructBVec2: + case EOpConstructBVec3: + case EOpConstructBVec4: + case EOpConstructBool: + basicOp = EOpConstructBool; + break; + + default: + error(loc, "unsupported construction", "", ""); + + return nullptr; + } + newNode = intermediate.addUnaryMath(basicOp, node, node->getLoc()); + if (newNode == nullptr) { + error(loc, "can't convert", "constructor", ""); + return nullptr; + } + + // + // Now, if there still isn't an operation to do the construction, and we need one, add one. + // + + // Otherwise, skip out early. + if (subset || (newNode != node && newNode->getType() == type)) + return newNode; + + // setAggregateOperator will insert a new node for the constructor, as needed. + return intermediate.setAggregateOperator(newNode, op, type, loc); +} + +// This function tests for the type of the parameters to the structure or array constructor. Raises +// an error message if the expected type does not match the parameter passed to the constructor. +// +// Returns nullptr for an error or the input node itself if the expected and the given parameter types match. +// +TIntermTyped* TParseContext::constructAggregate(TIntermNode* node, const TType& type, int paramCount, const TSourceLoc& loc) +{ + TIntermTyped* converted = intermediate.addConversion(EOpConstructStruct, type, node->getAsTyped()); + if (! converted || converted->getType() != type) { + error(loc, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount, + node->getAsTyped()->getType().getCompleteString().c_str(), type.getCompleteString().c_str()); + + return nullptr; + } + + return converted; +} + +// +// Do everything needed to add an interface block. +// +void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, const TString* instanceName, TArraySizes* arraySizes) +{ + blockStageIoCheck(loc, currentBlockQualifier); + blockQualifierCheck(loc, currentBlockQualifier, instanceName != nullptr); + if (arraySizes) { + arraySizesCheck(loc, currentBlockQualifier, arraySizes, false, false); + arrayDimCheck(loc, arraySizes, 0); + if (arraySizes->getNumDims() > 1) + requireProfile(loc, ~EEsProfile, "array-of-array of block"); + } + + // fix and check for member storage qualifiers and types that don't belong within a block + for (unsigned int member = 0; member < typeList.size(); ++member) { + TType& memberType = *typeList[member].type; + TQualifier& memberQualifier = memberType.getQualifier(); + const TSourceLoc& memberLoc = typeList[member].loc; + globalQualifierFixCheck(memberLoc, memberQualifier); + if (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal && memberQualifier.storage != currentBlockQualifier.storage) + error(memberLoc, "member storage qualifier cannot contradict block storage qualifier", memberType.getFieldName().c_str(), ""); + memberQualifier.storage = currentBlockQualifier.storage; + if ((currentBlockQualifier.storage == EvqUniform || currentBlockQualifier.storage == EvqBuffer) && (memberQualifier.isInterpolation() || memberQualifier.isAuxiliary())) + error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), ""); + if (memberType.isArray()) + arraySizesCheck(memberLoc, currentBlockQualifier, &memberType.getArraySizes(), false, member == typeList.size() - 1); + if (memberQualifier.hasOffset()) { + if (spvVersion.spv == 0) { + requireProfile(memberLoc, ~EEsProfile, "offset on block member"); + profileRequires(memberLoc, ~EEsProfile, 440, E_GL_ARB_enhanced_layouts, "offset on block member"); + } + } + + if (memberType.containsOpaque()) + error(memberLoc, "member of block cannot be or contain a sampler, image, or atomic_uint type", typeList[member].type->getFieldName().c_str(), ""); + } + + // This might be a redeclaration of a built-in block. If so, redeclareBuiltinBlock() will + // do all the rest. + if (! symbolTable.atBuiltInLevel() && builtInName(*blockName)) { + redeclareBuiltinBlock(loc, typeList, *blockName, instanceName, arraySizes); + return; + } + + // Not a redeclaration of a built-in; check that all names are user names. + reservedErrorCheck(loc, *blockName); + if (instanceName) + reservedErrorCheck(loc, *instanceName); + for (unsigned int member = 0; member < typeList.size(); ++member) + reservedErrorCheck(typeList[member].loc, typeList[member].type->getFieldName()); + + // Make default block qualification, and adjust the member qualifications + + TQualifier defaultQualification; + switch (currentBlockQualifier.storage) { + case EvqUniform: defaultQualification = globalUniformDefaults; break; + case EvqBuffer: defaultQualification = globalBufferDefaults; break; + case EvqVaryingIn: defaultQualification = globalInputDefaults; break; + case EvqVaryingOut: defaultQualification = globalOutputDefaults; break; + default: defaultQualification.clear(); break; + } + + // Special case for "push_constant uniform", which has a default of std430, + // contrary to normal uniform defaults, and can't have a default tracked for it. + if (currentBlockQualifier.layoutPushConstant && !currentBlockQualifier.hasPacking()) + currentBlockQualifier.layoutPacking = ElpStd430; + + // fix and check for member layout qualifiers + + mergeObjectLayoutQualifiers(defaultQualification, currentBlockQualifier, true); + + // "The align qualifier can only be used on blocks or block members, and only for blocks declared with std140 or std430 layouts." + if (currentBlockQualifier.hasAlign()) { + if (defaultQualification.layoutPacking != ElpStd140 && defaultQualification.layoutPacking != ElpStd430) { + error(loc, "can only be used with std140 or std430 layout packing", "align", ""); + defaultQualification.layoutAlign = -1; + } + } + + bool memberWithLocation = false; + bool memberWithoutLocation = false; + for (unsigned int member = 0; member < typeList.size(); ++member) { + TQualifier& memberQualifier = typeList[member].type->getQualifier(); + const TSourceLoc& memberLoc = typeList[member].loc; + if (memberQualifier.hasStream()) { + if (defaultQualification.layoutStream != memberQualifier.layoutStream) + error(memberLoc, "member cannot contradict block", "stream", ""); + } + + // "This includes a block's inheritance of the + // current global default buffer, a block member's inheritance of the block's + // buffer, and the requirement that any *xfb_buffer* declared on a block + // member must match the buffer inherited from the block." + if (memberQualifier.hasXfbBuffer()) { + if (defaultQualification.layoutXfbBuffer != memberQualifier.layoutXfbBuffer) + error(memberLoc, "member cannot contradict block (or what block inherited from global)", "xfb_buffer", ""); + } + + if (memberQualifier.hasPacking()) + error(memberLoc, "member of block cannot have a packing layout qualifier", typeList[member].type->getFieldName().c_str(), ""); + if (memberQualifier.hasLocation()) { + const char* feature = "location on block member"; + switch (currentBlockQualifier.storage) { + case EvqVaryingIn: + case EvqVaryingOut: + requireProfile(memberLoc, ECoreProfile | ECompatibilityProfile | EEsProfile, feature); + profileRequires(memberLoc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, feature); + profileRequires(memberLoc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, feature); + memberWithLocation = true; + break; + default: + error(memberLoc, "can only use in an in/out block", feature, ""); + break; + } + } else + memberWithoutLocation = true; + + // "The offset qualifier can only be used on block members of blocks declared with std140 or std430 layouts." + // "The align qualifier can only be used on blocks or block members, and only for blocks declared with std140 or std430 layouts." + if (memberQualifier.hasAlign() || memberQualifier.hasOffset()) { + if (defaultQualification.layoutPacking != ElpStd140 && defaultQualification.layoutPacking != ElpStd430) + error(memberLoc, "can only be used with std140 or std430 layout packing", "offset/align", ""); + } + + TQualifier newMemberQualification = defaultQualification; + mergeQualifiers(memberLoc, newMemberQualification, memberQualifier, false); + memberQualifier = newMemberQualification; + } + + layoutMemberLocationArrayCheck(loc, memberWithLocation, arraySizes); + + // Process the members + fixBlockLocations(loc, currentBlockQualifier, typeList, memberWithLocation, memberWithoutLocation); + fixBlockXfbOffsets(currentBlockQualifier, typeList); + fixBlockUniformOffsets(currentBlockQualifier, typeList); + for (unsigned int member = 0; member < typeList.size(); ++member) + layoutTypeCheck(typeList[member].loc, *typeList[member].type); + + // reverse merge, so that currentBlockQualifier now has all layout information + // (can't use defaultQualification directly, it's missing other non-layout-default-class qualifiers) + mergeObjectLayoutQualifiers(currentBlockQualifier, defaultQualification, true); + + // + // Build and add the interface block as a new type named 'blockName' + // + + TType blockType(&typeList, *blockName, currentBlockQualifier); + if (arraySizes) + blockType.newArraySizes(*arraySizes); + else + ioArrayCheck(loc, blockType, instanceName ? *instanceName : *blockName); + + // + // Don't make a user-defined type out of block name; that will cause an error + // if the same block name gets reused in a different interface. + // + // "Block names have no other use within a shader + // beyond interface matching; it is a compile-time error to use a block name at global scope for anything + // other than as a block name (e.g., use of a block name for a global variable name or function name is + // currently reserved)." + // + // Use the symbol table to prevent normal reuse of the block's name, as a variable entry, + // whose type is EbtBlock, but without all the structure; that will come from the type + // the instances point to. + // + TType blockNameType(EbtBlock, blockType.getQualifier().storage); + TVariable* blockNameVar = new TVariable(blockName, blockNameType); + if (! symbolTable.insert(*blockNameVar)) { + TSymbol* existingName = symbolTable.find(*blockName); + if (existingName->getType().getBasicType() == EbtBlock) { + if (existingName->getType().getQualifier().storage == blockType.getQualifier().storage) { + error(loc, "Cannot reuse block name within the same interface:", blockName->c_str(), blockType.getStorageQualifierString()); + return; + } + } else { + error(loc, "block name cannot redefine a non-block name", blockName->c_str(), ""); + return; + } + } + + // Add the variable, as anonymous or named instanceName. + // Make an anonymous variable if no name was provided. + if (! instanceName) + instanceName = NewPoolTString(""); + + TVariable& variable = *new TVariable(instanceName, blockType); + if (! symbolTable.insert(variable)) { + if (*instanceName == "") + error(loc, "nameless block contains a member that already has a name at global scope", blockName->c_str(), ""); + else + error(loc, "block instance name redefinition", variable.getName().c_str(), ""); + + return; + } + + // Check for general layout qualifier errors + layoutObjectCheck(loc, variable); + + // fix up + if (isIoResizeArray(blockType)) { + ioArraySymbolResizeList.push_back(&variable); + checkIoArraysConsistency(loc, true); + } else + fixIoArraySize(loc, variable.getWritableType()); + + // Save it in the AST for linker use. + trackLinkage(variable); +} + +// Do all block-declaration checking regarding the combination of in/out/uniform/buffer +// with a particular stage. +void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& qualifier) +{ + switch (qualifier.storage) { + case EvqUniform: + profileRequires(loc, EEsProfile, 300, nullptr, "uniform block"); + profileRequires(loc, ENoProfile, 140, nullptr, "uniform block"); + if (currentBlockQualifier.layoutPacking == ElpStd430 && ! currentBlockQualifier.layoutPushConstant) + error(loc, "requires the 'buffer' storage qualifier", "std430", ""); + break; + case EvqBuffer: + requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "buffer block"); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, "buffer block"); + profileRequires(loc, EEsProfile, 310, nullptr, "buffer block"); + break; + case EvqVaryingIn: + profileRequires(loc, ~EEsProfile, 150, E_GL_ARB_separate_shader_objects, "input block"); + // It is a compile-time error to have an input block in a vertex shader or an output block in a fragment shader + // "Compute shaders do not permit user-defined input variables..." + requireStage(loc, (EShLanguageMask)(EShLangTessControlMask|EShLangTessEvaluationMask|EShLangGeometryMask|EShLangFragmentMask), "input block"); + if (language == EShLangFragment) + profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "fragment input block"); + break; + case EvqVaryingOut: + profileRequires(loc, ~EEsProfile, 150, E_GL_ARB_separate_shader_objects, "output block"); + requireStage(loc, (EShLanguageMask)(EShLangVertexMask|EShLangTessControlMask|EShLangTessEvaluationMask|EShLangGeometryMask), "output block"); + // ES 310 can have a block before shader_io is turned on, so skip this test for built-ins + if (language == EShLangVertex && ! parsingBuiltins) + profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "vertex output block"); + break; + default: + error(loc, "only uniform, buffer, in, or out blocks are supported", blockName->c_str(), ""); + break; + } +} + +// Do all block-declaration checking regarding its qualifiers. +void TParseContext::blockQualifierCheck(const TSourceLoc& loc, const TQualifier& qualifier, bool /*instanceName*/) +{ + // The 4.5 specification says: + // + // interface-block : + // layout-qualifieropt interface-qualifier block-name { member-list } instance-nameopt ; + // + // interface-qualifier : + // in + // out + // patch in + // patch out + // uniform + // buffer + // + // Note however memory qualifiers aren't included, yet the specification also says + // + // "...memory qualifiers may also be used in the declaration of shader storage blocks..." + + if (qualifier.isInterpolation()) + error(loc, "cannot use interpolation qualifiers on an interface block", "flat/smooth/noperspective", ""); + if (qualifier.centroid) + error(loc, "cannot use centroid qualifier on an interface block", "centroid", ""); + if (qualifier.sample) + error(loc, "cannot use sample qualifier on an interface block", "sample", ""); + if (qualifier.invariant) + error(loc, "cannot use invariant qualifier on an interface block", "invariant", ""); + if (qualifier.layoutPushConstant) + intermediate.addPushConstantCount(); +} + +// +// "For a block, this process applies to the entire block, or until the first member +// is reached that has a location layout qualifier. When a block member is declared with a location +// qualifier, its location comes from that qualifier: The member's location qualifier overrides the block-level +// declaration. Subsequent members are again assigned consecutive locations, based on the newest location, +// until the next member declared with a location qualifier. The values used for locations do not have to be +// declared in increasing order." +void TParseContext::fixBlockLocations(const TSourceLoc& loc, TQualifier& qualifier, TTypeList& typeList, bool memberWithLocation, bool memberWithoutLocation) +{ + // "If a block has no block-level location layout qualifier, it is required that either all or none of its members + // have a location layout qualifier, or a compile-time error results." + if (! qualifier.hasLocation() && memberWithLocation && memberWithoutLocation) + error(loc, "either the block needs a location, or all members need a location, or no members have a location", "location", ""); + else { + if (memberWithLocation) { + // remove any block-level location and make it per *every* member + int nextLocation = 0; // by the rule above, initial value is not relevant + if (qualifier.hasAnyLocation()) { + nextLocation = qualifier.layoutLocation; + qualifier.layoutLocation = TQualifier::layoutLocationEnd; + if (qualifier.hasComponent()) { + // "It is a compile-time error to apply the *component* qualifier to a ... block" + error(loc, "cannot apply to a block", "component", ""); + } + if (qualifier.hasIndex()) { + error(loc, "cannot apply to a block", "index", ""); + } + } + for (unsigned int member = 0; member < typeList.size(); ++member) { + TQualifier& memberQualifier = typeList[member].type->getQualifier(); + const TSourceLoc& memberLoc = typeList[member].loc; + if (! memberQualifier.hasLocation()) { + if (nextLocation >= (int)TQualifier::layoutLocationEnd) + error(memberLoc, "location is too large", "location", ""); + memberQualifier.layoutLocation = nextLocation; + memberQualifier.layoutComponent = TQualifier::layoutComponentEnd; + } + nextLocation = memberQualifier.layoutLocation + intermediate.computeTypeLocationSize(*typeList[member].type); + } + } + } +} + +void TParseContext::fixBlockXfbOffsets(TQualifier& qualifier, TTypeList& typeList) +{ + // "If a block is qualified with xfb_offset, all its + // members are assigned transform feedback buffer offsets. If a block is not qualified with xfb_offset, any + // members of that block not qualified with an xfb_offset will not be assigned transform feedback buffer + // offsets." + + if (! qualifier.hasXfbBuffer() || ! qualifier.hasXfbOffset()) + return; + + int nextOffset = qualifier.layoutXfbOffset; + for (unsigned int member = 0; member < typeList.size(); ++member) { + TQualifier& memberQualifier = typeList[member].type->getQualifier(); + bool containsDouble = false; + int memberSize = intermediate.computeTypeXfbSize(*typeList[member].type, containsDouble); + // see if we need to auto-assign an offset to this member + if (! memberQualifier.hasXfbOffset()) { + // "if applied to an aggregate containing a double, the offset must also be a multiple of 8" + if (containsDouble) + RoundToPow2(nextOffset, 8); + memberQualifier.layoutXfbOffset = nextOffset; + } else + nextOffset = memberQualifier.layoutXfbOffset; + nextOffset += memberSize; + } + + // The above gave all block members an offset, so we can take it off the block now, + // which will avoid double counting the offset usage. + qualifier.layoutXfbOffset = TQualifier::layoutXfbOffsetEnd; +} + +// Calculate and save the offset of each block member, using the recursively +// defined block offset rules and the user-provided offset and align. +// +// Also, compute and save the total size of the block. For the block's size, arrayness +// is not taken into account, as each element is backed by a separate buffer. +// +void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typeList) +{ + if (! qualifier.isUniformOrBuffer()) + return; + if (qualifier.layoutPacking != ElpStd140 && qualifier.layoutPacking != ElpStd430) + return; + + int offset = 0; + int memberSize; + for (unsigned int member = 0; member < typeList.size(); ++member) { + TQualifier& memberQualifier = typeList[member].type->getQualifier(); + const TSourceLoc& memberLoc = typeList[member].loc; + + // "When align is applied to an array, it effects only the start of the array, not the array's internal stride." + + // modify just the children's view of matrix layout, if there is one for this member + TLayoutMatrix subMatrixLayout = typeList[member].type->getQualifier().layoutMatrix; + int dummyStride; + int memberAlignment = intermediate.getBaseAlignment(*typeList[member].type, memberSize, dummyStride, qualifier.layoutPacking == ElpStd140, + subMatrixLayout != ElmNone ? subMatrixLayout == ElmRowMajor : qualifier.layoutMatrix == ElmRowMajor); + if (memberQualifier.hasOffset()) { + // "The specified offset must be a multiple + // of the base alignment of the type of the block member it qualifies, or a compile-time error results." + if (! IsMultipleOfPow2(memberQualifier.layoutOffset, memberAlignment)) + error(memberLoc, "must be a multiple of the member's alignment", "offset", ""); + + // GLSL: "It is a compile-time error to specify an offset that is smaller than the offset of the previous + // member in the block or that lies within the previous member of the block" + if (spvVersion.spv == 0) { + if (memberQualifier.layoutOffset < offset) + error(memberLoc, "cannot lie in previous members", "offset", ""); + + // "The offset qualifier forces the qualified member to start at or after the specified + // integral-constant expression, which will be its byte offset from the beginning of the buffer. + // "The actual offset of a member is computed as + // follows: If offset was declared, start with that offset, otherwise start with the next available offset." + offset = std::max(offset, memberQualifier.layoutOffset); + } else { + // TODO: Vulkan: "It is a compile-time error to have any offset, explicit or assigned, + // that lies within another member of the block." + + offset = memberQualifier.layoutOffset; + } + } + + // "The actual alignment of a member will be the greater of the specified align alignment and the standard + // (e.g., std140) base alignment for the member's type." + if (memberQualifier.hasAlign()) + memberAlignment = std::max(memberAlignment, memberQualifier.layoutAlign); + + // "If the resulting offset is not a multiple of the actual alignment, + // increase it to the first offset that is a multiple of + // the actual alignment." + RoundToPow2(offset, memberAlignment); + typeList[member].type->getQualifier().layoutOffset = offset; + offset += memberSize; + } +} + +// For an identifier that is already declared, add more qualification to it. +void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qualifier, const TString& identifier) +{ + TSymbol* symbol = symbolTable.find(identifier); + if (! symbol) { + error(loc, "identifier not previously declared", identifier.c_str(), ""); + return; + } + if (symbol->getAsFunction()) { + error(loc, "cannot re-qualify a function name", identifier.c_str(), ""); + return; + } + + if (qualifier.isAuxiliary() || + qualifier.isMemory() || + qualifier.isInterpolation() || + qualifier.hasLayout() || + qualifier.storage != EvqTemporary || + qualifier.precision != EpqNone) { + error(loc, "cannot add storage, auxiliary, memory, interpolation, layout, or precision qualifier to an existing variable", identifier.c_str(), ""); + return; + } + + // For read-only built-ins, add a new symbol for holding the modified qualifier. + // This will bring up an entire block, if a block type has to be modified (e.g., gl_Position inside a block) + if (symbol->isReadOnly()) + symbol = symbolTable.copyUp(symbol); + + if (qualifier.invariant) { + if (intermediate.inIoAccessed(identifier)) + error(loc, "cannot change qualification after use", "invariant", ""); + symbol->getWritableType().getQualifier().invariant = true; + invariantCheck(loc, symbol->getType().getQualifier()); + } else if (qualifier.noContraction) { + if (intermediate.inIoAccessed(identifier)) + error(loc, "cannot change qualification after use", "precise", ""); + symbol->getWritableType().getQualifier().noContraction = true; + } else if (qualifier.specConstant) { + symbol->getWritableType().getQualifier().makeSpecConstant(); + if (qualifier.hasSpecConstantId()) + symbol->getWritableType().getQualifier().layoutSpecConstantId = qualifier.layoutSpecConstantId; + } else + warn(loc, "unknown requalification", "", ""); +} + +void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qualifier, TIdentifierList& identifiers) +{ + for (unsigned int i = 0; i < identifiers.size(); ++i) + addQualifierToExisting(loc, qualifier, *identifiers[i]); +} + +// Make sure 'invariant' isn't being applied to a non-allowed object. +void TParseContext::invariantCheck(const TSourceLoc& loc, const TQualifier& qualifier) +{ + if (! qualifier.invariant) + return; + + bool pipeOut = qualifier.isPipeOutput(); + bool pipeIn = qualifier.isPipeInput(); + if (version >= 300 || (profile != EEsProfile && version >= 420)) { + if (! pipeOut) + error(loc, "can only apply to an output", "invariant", ""); + } else { + if ((language == EShLangVertex && pipeIn) || (! pipeOut && ! pipeIn)) + error(loc, "can only apply to an output, or to an input in a non-vertex stage\n", "invariant", ""); + } +} + +// +// Updating default qualifier for the case of a declaration with just a qualifier, +// no type, block, or identifier. +// +void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, const TPublicType& publicType) +{ + if (publicType.shaderQualifiers.vertices != TQualifier::layoutNotSet) { + assert(language == EShLangTessControl || language == EShLangGeometry); + const char* id = (language == EShLangTessControl) ? "vertices" : "max_vertices"; + + if (publicType.qualifier.storage != EvqVaryingOut) + error(loc, "can only apply to 'out'", id, ""); + if (! intermediate.setVertices(publicType.shaderQualifiers.vertices)) + error(loc, "cannot change previously set layout value", id, ""); + + if (language == EShLangTessControl) + checkIoArraysConsistency(loc); + } + if (publicType.shaderQualifiers.invocations != TQualifier::layoutNotSet) { + if (publicType.qualifier.storage != EvqVaryingIn) + error(loc, "can only apply to 'in'", "invocations", ""); + if (! intermediate.setInvocations(publicType.shaderQualifiers.invocations)) + error(loc, "cannot change previously set layout value", "invocations", ""); + } + if (publicType.shaderQualifiers.geometry != ElgNone) { + if (publicType.qualifier.storage == EvqVaryingIn) { + switch (publicType.shaderQualifiers.geometry) { + case ElgPoints: + case ElgLines: + case ElgLinesAdjacency: + case ElgTriangles: + case ElgTrianglesAdjacency: + case ElgQuads: + case ElgIsolines: + if (intermediate.setInputPrimitive(publicType.shaderQualifiers.geometry)) { + if (language == EShLangGeometry) + checkIoArraysConsistency(loc); + } else + error(loc, "cannot change previously set input primitive", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), ""); + break; + default: + error(loc, "cannot apply to input", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), ""); + } + } else if (publicType.qualifier.storage == EvqVaryingOut) { + switch (publicType.shaderQualifiers.geometry) { + case ElgPoints: + case ElgLineStrip: + case ElgTriangleStrip: + if (! intermediate.setOutputPrimitive(publicType.shaderQualifiers.geometry)) + error(loc, "cannot change previously set output primitive", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), ""); + break; + default: + error(loc, "cannot apply to 'out'", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), ""); + } + } else + error(loc, "cannot apply to:", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), GetStorageQualifierString(publicType.qualifier.storage)); + } + if (publicType.shaderQualifiers.spacing != EvsNone) { + if (publicType.qualifier.storage == EvqVaryingIn) { + if (! intermediate.setVertexSpacing(publicType.shaderQualifiers.spacing)) + error(loc, "cannot change previously set vertex spacing", TQualifier::getVertexSpacingString(publicType.shaderQualifiers.spacing), ""); + } else + error(loc, "can only apply to 'in'", TQualifier::getVertexSpacingString(publicType.shaderQualifiers.spacing), ""); + } + if (publicType.shaderQualifiers.order != EvoNone) { + if (publicType.qualifier.storage == EvqVaryingIn) { + if (! intermediate.setVertexOrder(publicType.shaderQualifiers.order)) + error(loc, "cannot change previously set vertex order", TQualifier::getVertexOrderString(publicType.shaderQualifiers.order), ""); + } else + error(loc, "can only apply to 'in'", TQualifier::getVertexOrderString(publicType.shaderQualifiers.order), ""); + } + if (publicType.shaderQualifiers.pointMode) { + if (publicType.qualifier.storage == EvqVaryingIn) + intermediate.setPointMode(); + else + error(loc, "can only apply to 'in'", "point_mode", ""); + } + for (int i = 0; i < 3; ++i) { + if (publicType.shaderQualifiers.localSize[i] > 1) { + if (publicType.qualifier.storage == EvqVaryingIn) { + if (! intermediate.setLocalSize(i, publicType.shaderQualifiers.localSize[i])) + error(loc, "cannot change previously set size", "local_size", ""); + else { + int max = 0; + switch (i) { + case 0: max = resources.maxComputeWorkGroupSizeX; break; + case 1: max = resources.maxComputeWorkGroupSizeY; break; + case 2: max = resources.maxComputeWorkGroupSizeZ; break; + default: break; + } + if (intermediate.getLocalSize(i) > (unsigned int)max) + error(loc, "too large; see gl_MaxComputeWorkGroupSize", "local_size", ""); + + // Fix the existing constant gl_WorkGroupSize with this new information. + TVariable* workGroupSize = getEditableVariable("gl_WorkGroupSize"); + if (workGroupSize != nullptr) + workGroupSize->getWritableConstArray()[i].setUConst(intermediate.getLocalSize(i)); + } + } else + error(loc, "can only apply to 'in'", "local_size", ""); + } + if (publicType.shaderQualifiers.localSizeSpecId[i] != TQualifier::layoutNotSet) { + if (publicType.qualifier.storage == EvqVaryingIn) { + if (! intermediate.setLocalSizeSpecId(i, publicType.shaderQualifiers.localSizeSpecId[i])) + error(loc, "cannot change previously set size", "local_size", ""); + } else + error(loc, "can only apply to 'in'", "local_size id", ""); + // Set the workgroup built-in variable as a specialization constant + TVariable* workGroupSize = getEditableVariable("gl_WorkGroupSize"); + if (workGroupSize != nullptr) + workGroupSize->getWritableType().getQualifier().specConstant = true; + } + } + if (publicType.shaderQualifiers.earlyFragmentTests) { + if (publicType.qualifier.storage == EvqVaryingIn) + intermediate.setEarlyFragmentTests(); + else + error(loc, "can only apply to 'in'", "early_fragment_tests", ""); + } + if (publicType.shaderQualifiers.postDepthCoverage) { + if (publicType.qualifier.storage == EvqVaryingIn) + intermediate.setPostDepthCoverage(); + else + error(loc, "can only apply to 'in'", "post_coverage_coverage", ""); + } + if (publicType.shaderQualifiers.blendEquation) { + if (publicType.qualifier.storage != EvqVaryingOut) + error(loc, "can only apply to 'out'", "blend equation", ""); + } + + const TQualifier& qualifier = publicType.qualifier; + + if (qualifier.isAuxiliary() || + qualifier.isMemory() || + qualifier.isInterpolation() || + qualifier.precision != EpqNone) + error(loc, "cannot use auxiliary, memory, interpolation, or precision qualifier in a default qualifier declaration (declaration with no type)", "qualifier", ""); + // "The offset qualifier can only be used on block members of blocks..." + // "The align qualifier can only be used on blocks or block members..." + if (qualifier.hasOffset() || + qualifier.hasAlign()) + error(loc, "cannot use offset or align qualifiers in a default qualifier declaration (declaration with no type)", "layout qualifier", ""); + + layoutQualifierCheck(loc, qualifier); + + switch (qualifier.storage) { + case EvqUniform: + if (qualifier.hasMatrix()) + globalUniformDefaults.layoutMatrix = qualifier.layoutMatrix; + if (qualifier.hasPacking()) + globalUniformDefaults.layoutPacking = qualifier.layoutPacking; + break; + case EvqBuffer: + if (qualifier.hasMatrix()) + globalBufferDefaults.layoutMatrix = qualifier.layoutMatrix; + if (qualifier.hasPacking()) + globalBufferDefaults.layoutPacking = qualifier.layoutPacking; + break; + case EvqVaryingIn: + break; + case EvqVaryingOut: + if (qualifier.hasStream()) + globalOutputDefaults.layoutStream = qualifier.layoutStream; + if (qualifier.hasXfbBuffer()) + globalOutputDefaults.layoutXfbBuffer = qualifier.layoutXfbBuffer; + if (globalOutputDefaults.hasXfbBuffer() && qualifier.hasXfbStride()) { + if (! intermediate.setXfbBufferStride(globalOutputDefaults.layoutXfbBuffer, qualifier.layoutXfbStride)) + error(loc, "all stride settings must match for xfb buffer", "xfb_stride", "%d", qualifier.layoutXfbBuffer); + } + break; + default: + error(loc, "default qualifier requires 'uniform', 'buffer', 'in', or 'out' storage qualification", "", ""); + return; + } + + if (qualifier.hasBinding()) + error(loc, "cannot declare a default, include a type or full declaration", "binding", ""); + if (qualifier.hasAnyLocation()) + error(loc, "cannot declare a default, use a full declaration", "location/component/index", ""); + if (qualifier.hasXfbOffset()) + error(loc, "cannot declare a default, use a full declaration", "xfb_offset", ""); + if (qualifier.layoutPushConstant) + error(loc, "cannot declare a default, can only be used on a block", "push_constant", ""); + if (qualifier.hasSpecConstantId()) + error(loc, "cannot declare a default, can only be used on a scalar", "constant_id", ""); +} + +// +// Take the sequence of statements that has been built up since the last case/default, +// put it on the list of top-level nodes for the current (inner-most) switch statement, +// and follow that by the case/default we are on now. (See switch topology comment on +// TIntermSwitch.) +// +void TParseContext::wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode) +{ + TIntermSequence* switchSequence = switchSequenceStack.back(); + + if (statements) { + if (switchSequence->size() == 0) + error(statements->getLoc(), "cannot have statements before first case/default label", "switch", ""); + statements->setOperator(EOpSequence); + switchSequence->push_back(statements); + } + if (branchNode) { + // check all previous cases for the same label (or both are 'default') + for (unsigned int s = 0; s < switchSequence->size(); ++s) { + TIntermBranch* prevBranch = (*switchSequence)[s]->getAsBranchNode(); + if (prevBranch) { + TIntermTyped* prevExpression = prevBranch->getExpression(); + TIntermTyped* newExpression = branchNode->getAsBranchNode()->getExpression(); + if (prevExpression == nullptr && newExpression == nullptr) + error(branchNode->getLoc(), "duplicate label", "default", ""); + else if (prevExpression != nullptr && + newExpression != nullptr && + prevExpression->getAsConstantUnion() && + newExpression->getAsConstantUnion() && + prevExpression->getAsConstantUnion()->getConstArray()[0].getIConst() == + newExpression->getAsConstantUnion()->getConstArray()[0].getIConst()) + error(branchNode->getLoc(), "duplicated value", "case", ""); + } + } + switchSequence->push_back(branchNode); + } +} + +// +// Turn the top-level node sequence built up of wrapupSwitchSubsequence9) +// into a switch node. +// +TIntermNode* TParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expression, TIntermAggregate* lastStatements) +{ + profileRequires(loc, EEsProfile, 300, nullptr, "switch statements"); + profileRequires(loc, ENoProfile, 130, nullptr, "switch statements"); + + wrapupSwitchSubsequence(lastStatements, nullptr); + + if (expression == nullptr || + (expression->getBasicType() != EbtInt && expression->getBasicType() != EbtUint) || + expression->getType().isArray() || expression->getType().isMatrix() || expression->getType().isVector()) + error(loc, "condition must be a scalar integer expression", "switch", ""); + + // If there is nothing to do, drop the switch but still execute the expression + TIntermSequence* switchSequence = switchSequenceStack.back(); + if (switchSequence->size() == 0) + return expression; + + if (lastStatements == nullptr) { + // This was originally an ERRROR, because early versions of the specification said + // "it is an error to have no statement between a label and the end of the switch statement." + // The specifications were updated to remove this (being ill-defined what a "statement" was), + // so, this became a warning. However, 3.0 tests still check for the error. + if (profile == EEsProfile && version <= 300 && ! relaxedErrors()) + error(loc, "last case/default label not followed by statements", "switch", ""); + else + warn(loc, "last case/default label not followed by statements", "switch", ""); + + // emulate a break for error recovery + lastStatements = intermediate.makeAggregate(intermediate.addBranch(EOpBreak, loc)); + lastStatements->setOperator(EOpSequence); + switchSequence->push_back(lastStatements); + } + + TIntermAggregate* body = new TIntermAggregate(EOpSequence); + body->getSequence() = *switchSequenceStack.back(); + body->setLoc(loc); + + TIntermSwitch* switchNode = new TIntermSwitch(expression, body); + switchNode->setLoc(loc); + + return switchNode; +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h new file mode 100644 index 00000000..0d929789 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h @@ -0,0 +1,490 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2012-2013 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +// +// This header defines a two-level parse-helper hierarchy, derived from +// TParseVersions: +// - TParseContextBase: sharable across multiple parsers +// - TParseContext: GLSL specific helper +// + +#ifndef _PARSER_HELPER_INCLUDED_ +#define _PARSER_HELPER_INCLUDED_ + +#include "parseVersions.h" +#include "../Include/ShHandle.h" +#include "SymbolTable.h" +#include "localintermediate.h" +#include "Scan.h" +#include +#include + +namespace glslang { + +struct TPragma { + TPragma(bool o, bool d) : optimize(o), debug(d) { } + bool optimize; + bool debug; + TPragmaTable pragmaTable; +}; + +class TScanContext; +class TPpContext; + +typedef std::set TIdSetType; + +// +// Sharable code (as well as what's in TParseVersions) across +// parse helpers. +// +class TParseContextBase : public TParseVersions { +public: + TParseContextBase(TSymbolTable& symbolTable, TIntermediate& interm, bool parsingBuiltins, int version, + EProfile profile, const SpvVersion& spvVersion, EShLanguage language, + TInfoSink& infoSink, bool forwardCompatible, EShMessages messages, + const TString* entryPoint = nullptr) + : TParseVersions(interm, version, profile, spvVersion, language, infoSink, forwardCompatible, messages), + scopeMangler("::"), + symbolTable(symbolTable), + statementNestingLevel(0), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0), + postEntryPointReturn(false), + contextPragma(true, false), + parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr), + limits(resources.limits), + globalUniformBlock(nullptr), + globalUniformBinding(TQualifier::layoutBindingEnd), + globalUniformSet(TQualifier::layoutSetEnd) + { + if (entryPoint != nullptr) + sourceEntryPointName = *entryPoint; + } + virtual ~TParseContextBase() { } + + virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, ...); + virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, ...); + virtual void C_DECL ppError(const TSourceLoc&, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, ...); + virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, ...); + + virtual void setLimits(const TBuiltInResource&) = 0; + + void checkIndex(const TSourceLoc&, const TType&, int& index); + + EShLanguage getLanguage() const { return language; } + void setScanContext(TScanContext* c) { scanContext = c; } + TScanContext* getScanContext() const { return scanContext; } + void setPpContext(TPpContext* c) { ppContext = c; } + TPpContext* getPpContext() const { return ppContext; } + + virtual void setLineCallback(const std::function& func) { lineCallback = func; } + virtual void setExtensionCallback(const std::function& func) { extensionCallback = func; } + virtual void setVersionCallback(const std::function& func) { versionCallback = func; } + virtual void setPragmaCallback(const std::function&)>& func) { pragmaCallback = func; } + virtual void setErrorCallback(const std::function& func) { errorCallback = func; } + + virtual void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op) = 0; + virtual bool lineContinuationCheck(const TSourceLoc&, bool endOfComment) = 0; + virtual bool lineDirectiveShouldSetNextLine() const = 0; + virtual void handlePragma(const TSourceLoc&, const TVector&) = 0; + + virtual bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false) = 0; + + virtual void notifyVersion(int line, int version, const char* type_string) + { + if (versionCallback) + versionCallback(line, version, type_string); + } + virtual void notifyErrorDirective(int line, const char* error_message) + { + if (errorCallback) + errorCallback(line, error_message); + } + virtual void notifyLineDirective(int curLineNo, int newLineNo, bool hasSource, int sourceNum, const char* sourceName) + { + if (lineCallback) + lineCallback(curLineNo, newLineNo, hasSource, sourceNum, sourceName); + } + virtual void notifyExtensionDirective(int line, const char* extension, const char* behavior) + { + if (extensionCallback) + extensionCallback(line, extension, behavior); + } + + // Manage the global uniform block (default uniforms in GLSL, $Global in HLSL) + virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr); + + // Potentially rename shader entry point function + void renameShaderFunction(TString*& name) const + { + // Replace the entry point name given in the shader with the real entry point name, + // if there is a substitution. + if (name != nullptr && *name == sourceEntryPointName && intermediate.getEntryPointName().size() > 0) + name = NewPoolTString(intermediate.getEntryPointName().c_str()); + } + + virtual bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*); + virtual void rValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*); + + const char* const scopeMangler; + + // Basic parsing state, easily accessible to the grammar + + TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile + int statementNestingLevel; // 0 if outside all flow control or compound statements + int loopNestingLevel; // 0 if outside all loops + int structNestingLevel; // 0 if outside blocks and structures + int controlFlowNestingLevel; // 0 if outside all flow control + const TType* currentFunctionType; // the return type of the function that's currently being parsed + bool functionReturnsValue; // true if a non-void function has a return + // if inside a function, true if the function is the entry point and this is after a return statement + bool postEntryPointReturn; + // case, node, case, case, node, ...; ensure only one node between cases; stack of them for nesting + TList switchSequenceStack; + // the statementNestingLevel the current switch statement is at, which must match the level of its case statements + TList switchLevel; + struct TPragma contextPragma; + +protected: + TParseContextBase(TParseContextBase&); + TParseContextBase& operator=(TParseContextBase&); + + const bool parsingBuiltins; // true if parsing built-in symbols/functions + TVector linkageSymbols; // these need to be transferred to 'linkage', after all editing is done + TScanContext* scanContext; + TPpContext* ppContext; + TBuiltInResource resources; + TLimits& limits; + TString sourceEntryPointName; + + // These, if set, will be called when a line, pragma ... is preprocessed. + // They will be called with any parameters to the original directive. + std::function lineCallback; + std::function&)> pragmaCallback; + std::function versionCallback; + std::function extensionCallback; + std::function errorCallback; + + // see implementation for detail + const TFunction* selectFunction(const TVector, const TFunction&, + std::function, + std::function, + /* output */ bool& tie); + + virtual void parseSwizzleSelector(const TSourceLoc&, const TString&, int size, + TSwizzleSelectors&); + + // Manage the global uniform block (default uniforms in GLSL, $Global in HLSL) + TVariable* globalUniformBlock; // the actual block, inserted into the symbol table + unsigned int globalUniformBinding; // the block's binding number + unsigned int globalUniformSet; // the block's set number + int firstNewMember; // the index of the first member not yet inserted into the symbol table + // override this to set the language-specific name + virtual const char* getGlobalUniformBlockName() const { return ""; } + virtual void setUniformBlockDefaults(TType&) const { } + virtual void finalizeGlobalUniformBlockLayout(TVariable&) { } + virtual void outputMessage(const TSourceLoc&, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, TPrefixType prefix, + va_list args); + virtual void trackLinkage(TSymbol& symbol); + virtual void makeEditable(TSymbol*&); + virtual TVariable* getEditableVariable(const char* name); + virtual void finish(); +}; + +// +// Manage the state for when to respect precision qualifiers and when to warn about +// the defaults being different than might be expected. +// +class TPrecisionManager { +public: + TPrecisionManager() : obey(false), warn(false), explicitIntDefault(false), explicitFloatDefault(false){ } + virtual ~TPrecisionManager() {} + + void respectPrecisionQualifiers() { obey = true; } + bool respectingPrecisionQualifiers() const { return obey; } + bool shouldWarnAboutDefaults() const { return warn; } + void defaultWarningGiven() { warn = false; } + void warnAboutDefaults() { warn = true; } + void explicitIntDefaultSeen() + { + explicitIntDefault = true; + if (explicitFloatDefault) + warn = false; + } + void explicitFloatDefaultSeen() + { + explicitFloatDefault = true; + if (explicitIntDefault) + warn = false; + } + +protected: + bool obey; // respect precision qualifiers + bool warn; // need to give a warning about the defaults + bool explicitIntDefault; // user set the default for int/uint + bool explicitFloatDefault; // user set the default for float +}; + +// +// GLSL-specific parse helper. Should have GLSL in the name, but that's +// too big of a change for comparing branches at the moment, and perhaps +// impacts downstream consumers as well. +// +class TParseContext : public TParseContextBase { +public: + TParseContext(TSymbolTable&, TIntermediate&, bool parsingBuiltins, int version, EProfile, const SpvVersion& spvVersion, EShLanguage, TInfoSink&, + bool forwardCompatible = false, EShMessages messages = EShMsgDefault, + const TString* entryPoint = nullptr); + virtual ~TParseContext(); + + bool obeyPrecisionQualifiers() const { return precisionManager.respectingPrecisionQualifiers(); }; + void setPrecisionDefaults(); + + void setLimits(const TBuiltInResource&) override; + bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false) override; + void parserError(const char* s); // for bison's yyerror + + void reservedErrorCheck(const TSourceLoc&, const TString&); + void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op) override; + bool lineContinuationCheck(const TSourceLoc&, bool endOfComment) override; + bool lineDirectiveShouldSetNextLine() const override; + bool builtInName(const TString&); + + void handlePragma(const TSourceLoc&, const TVector&) override; + TIntermTyped* handleVariable(const TSourceLoc&, TSymbol* symbol, const TString* string); + TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index); + void handleIndexLimits(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index); + + void makeEditable(TSymbol*&) override; + bool isIoResizeArray(const TType&) const; + void fixIoArraySize(const TSourceLoc&, TType&); + void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier); + void handleIoResizeArrayAccess(const TSourceLoc&, TIntermTyped* base); + void checkIoArraysConsistency(const TSourceLoc&, bool tailOnly = false); + int getIoArrayImplicitSize() const; + void checkIoArrayConsistency(const TSourceLoc&, int requiredSize, const char* feature, TType&, const TString&); + + TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right); + TIntermTyped* handleUnaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* childNode); + TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field); + void blockMemberExtensionCheck(const TSourceLoc&, const TIntermTyped* base, const TString& field); + TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype); + TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&); + TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*); + TIntermTyped* handleBuiltInFunctionCall(TSourceLoc, TIntermNode& arguments, const TFunction& function); + void computeBuiltinPrecisions(TIntermTyped&, const TFunction&); + TIntermNode* handleReturnValue(const TSourceLoc&, TIntermTyped*); + void checkLocation(const TSourceLoc&, TOperator); + TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*); + void addInputArgumentConversions(const TFunction&, TIntermNode*&) const; + TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const; + void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&); + void nonOpBuiltInCheck(const TSourceLoc&, const TFunction&, TIntermAggregate&); + void userFunctionCallCheck(const TSourceLoc&, TIntermAggregate&); + void samplerConstructorLocationCheck(const TSourceLoc&, const char* token, TIntermNode*); + TFunction* handleConstructorCall(const TSourceLoc&, const TPublicType&); + void handlePrecisionQualifier(const TSourceLoc&, TQualifier&, TPrecisionQualifier); + void checkPrecisionQualifier(const TSourceLoc&, TPrecisionQualifier); + + void assignError(const TSourceLoc&, const char* op, TString left, TString right); + void unaryOpError(const TSourceLoc&, const char* op, TString operand); + void binaryOpError(const TSourceLoc&, const char* op, TString left, TString right); + void variableCheck(TIntermTyped*& nodePtr); + bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*) override; + void rValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*) override; + void constantValueCheck(TIntermTyped* node, const char* token); + void integerCheck(const TIntermTyped* node, const char* token); + void globalCheck(const TSourceLoc&, const char* token); + bool constructorError(const TSourceLoc&, TIntermNode*, TFunction&, TOperator, TType&); + bool constructorTextureSamplerError(const TSourceLoc&, const TFunction&); + void arraySizeCheck(const TSourceLoc&, TIntermTyped* expr, TArraySize&); + bool arrayQualifierError(const TSourceLoc&, const TQualifier&); + bool arrayError(const TSourceLoc&, const TType&); + void arraySizeRequiredCheck(const TSourceLoc&, const TArraySizes&); + void structArrayCheck(const TSourceLoc&, const TType& structure); + void arraySizesCheck(const TSourceLoc&, const TQualifier&, TArraySizes*, bool initializer, bool lastMember); + void arrayOfArrayVersionCheck(const TSourceLoc&); + void arrayDimCheck(const TSourceLoc&, const TArraySizes* sizes1, const TArraySizes* sizes2); + void arrayDimCheck(const TSourceLoc&, const TType*, const TArraySizes*); + void arrayDimMerge(TType& type, const TArraySizes* sizes); + bool voidErrorCheck(const TSourceLoc&, const TString&, TBasicType); + void boolCheck(const TSourceLoc&, const TIntermTyped*); + void boolCheck(const TSourceLoc&, const TPublicType&); + void samplerCheck(const TSourceLoc&, const TType&, const TString& identifier, TIntermTyped* initializer); + void atomicUintCheck(const TSourceLoc&, const TType&, const TString& identifier); + void transparentOpaqueCheck(const TSourceLoc&, const TType&, const TString& identifier); + void globalQualifierFixCheck(const TSourceLoc&, TQualifier&); + void globalQualifierTypeCheck(const TSourceLoc&, const TQualifier&, const TPublicType&); + bool structQualifierErrorCheck(const TSourceLoc&, const TPublicType& pType); + void mergeQualifiers(const TSourceLoc&, TQualifier& dst, const TQualifier& src, bool force); + void setDefaultPrecision(const TSourceLoc&, TPublicType&, TPrecisionQualifier); + int computeSamplerTypeIndex(TSampler&); + TPrecisionQualifier getDefaultPrecision(TPublicType&); + void precisionQualifierCheck(const TSourceLoc&, TBasicType, TQualifier&); + void parameterTypeCheck(const TSourceLoc&, TStorageQualifier qualifier, const TType& type); + bool containsFieldWithBasicType(const TType& type ,TBasicType basicType); + TSymbol* redeclareBuiltinVariable(const TSourceLoc&, const TString&, const TQualifier&, const TShaderQualifiers&); + void redeclareBuiltinBlock(const TSourceLoc&, TTypeList& typeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes); + void paramCheckFix(const TSourceLoc&, const TStorageQualifier&, TType& type); + void paramCheckFix(const TSourceLoc&, const TQualifier&, TType& type); + void nestedBlockCheck(const TSourceLoc&); + void nestedStructCheck(const TSourceLoc&); + void arrayObjectCheck(const TSourceLoc&, const TType&, const char* op); + void opaqueCheck(const TSourceLoc&, const TType&, const char* op); + void specializationCheck(const TSourceLoc&, const TType&, const char* op); + void structTypeCheck(const TSourceLoc&, TPublicType&); + void inductiveLoopCheck(const TSourceLoc&, TIntermNode* init, TIntermLoop* loop); + void arrayLimitCheck(const TSourceLoc&, const TString&, int size); + void limitCheck(const TSourceLoc&, int value, const char* limit, const char* feature); + + void inductiveLoopBodyCheck(TIntermNode*, int loopIndexId, TSymbolTable&); + void constantIndexExpressionCheck(TIntermNode*); + + void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&); + void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&, const TIntermTyped*); + void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly); + void layoutObjectCheck(const TSourceLoc&, const TSymbol&); + void layoutMemberLocationArrayCheck(const TSourceLoc&, bool memberWithLocation, TArraySizes* arraySizes); + void layoutTypeCheck(const TSourceLoc&, const TType&); + void layoutQualifierCheck(const TSourceLoc&, const TQualifier&); + void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&); + void fixOffset(const TSourceLoc&, TSymbol&); + + const TFunction* findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn); + const TFunction* findFunctionExact(const TSourceLoc& loc, const TFunction& call, bool& builtIn); + const TFunction* findFunction120(const TSourceLoc& loc, const TFunction& call, bool& builtIn); + const TFunction* findFunction400(const TSourceLoc& loc, const TFunction& call, bool& builtIn); + void declareTypeDefaults(const TSourceLoc&, const TPublicType&); + TIntermNode* declareVariable(const TSourceLoc&, TString& identifier, const TPublicType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0); + TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&); + TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&); + TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset); + void declareBlock(const TSourceLoc&, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0); + void blockStageIoCheck(const TSourceLoc&, const TQualifier&); + void blockQualifierCheck(const TSourceLoc&, const TQualifier&, bool instanceName); + void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation); + void fixBlockXfbOffsets(TQualifier&, TTypeList&); + void fixBlockUniformOffsets(TQualifier&, TTypeList&); + void addQualifierToExisting(const TSourceLoc&, TQualifier, const TString& identifier); + void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&); + void invariantCheck(const TSourceLoc&, const TQualifier&); + void updateStandaloneQualifierDefaults(const TSourceLoc&, const TPublicType&); + void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode); + TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body); + + void updateImplicitArraySize(const TSourceLoc&, TIntermNode*, int index); + +protected: + void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type); + void inheritGlobalDefaults(TQualifier& dst) const; + TVariable* makeInternalVariable(const char* name, const TType&) const; + TVariable* declareNonArray(const TSourceLoc&, const TString& identifier, const TType&); + void declareArray(const TSourceLoc&, const TString& identifier, const TType&, TSymbol*&); + TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable); + TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer); + void finish() override; + +public: + // + // Generally, bison productions, the scanner, and the PP need read/write access to these; just give them direct access + // + + // Current state of parsing + bool inMain; // if inside a function, true if the function is main + const TString* blockName; + TQualifier currentBlockQualifier; + TPrecisionQualifier defaultPrecision[EbtNumTypes]; + TBuiltInResource resources; + TLimits& limits; + +protected: + TParseContext(TParseContext&); + TParseContext& operator=(TParseContext&); + + static const int maxSamplerIndex = EsdNumDims * (EbtNumTypes * (2 * 2 * 2 * 2 * 2)); // see computeSamplerTypeIndex() + TPrecisionQualifier defaultSamplerPrecision[maxSamplerIndex]; + TPrecisionManager precisionManager; + TQualifier globalBufferDefaults; + TQualifier globalUniformDefaults; + TQualifier globalInputDefaults; + TQualifier globalOutputDefaults; + int* atomicUintOffsets; // to become an array of the right size to hold an offset per binding point + TString currentCaller; // name of last function body entered (not valid when at global scope) + TIdSetType inductiveLoopIds; + bool anyIndexLimits; + TVector needsIndexLimitationChecking; + + // + // Geometry shader input arrays: + // - array sizing is based on input primitive and/or explicit size + // + // Tessellation control output arrays: + // - array sizing is based on output layout(vertices=...) and/or explicit size + // + // Both: + // - array sizing is retroactive + // - built-in block redeclarations interact with this + // + // Design: + // - use a per-context "resize-list", a list of symbols whose array sizes + // can be fixed + // + // - the resize-list starts empty at beginning of user-shader compilation, it does + // not have built-ins in it + // + // - on built-in array use: copyUp() symbol and add it to the resize-list + // + // - on user array declaration: add it to the resize-list + // + // - on block redeclaration: copyUp() symbol and add it to the resize-list + // * note, that appropriately gives an error if redeclaring a block that + // was already used and hence already copied-up + // + // - on seeing a layout declaration that sizes the array, fix everything in the + // resize-list, giving errors for mismatch + // + // - on seeing an array size declaration, give errors on mismatch between it and previous + // array-sizing declarations + // + TVector ioArraySymbolResizeList; +}; + +} // end namespace glslang + +#endif // _PARSER_HELPER_INCLUDED_ diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/PoolAlloc.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/PoolAlloc.cpp new file mode 100644 index 00000000..84c40f4e --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/PoolAlloc.cpp @@ -0,0 +1,315 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#include "../Include/Common.h" +#include "../Include/PoolAlloc.h" + +#include "../Include/InitializeGlobals.h" +#include "../OSDependent/osinclude.h" + +namespace glslang { + +// Process-wide TLS index +OS_TLSIndex PoolIndex; + +// Return the thread-specific current pool. +TPoolAllocator& GetThreadPoolAllocator() +{ + return *static_cast(OS_GetTLSValue(PoolIndex)); +} + +// Set the thread-specific current pool. +void SetThreadPoolAllocator(TPoolAllocator* poolAllocator) +{ + OS_SetTLSValue(PoolIndex, poolAllocator); +} + +// Process-wide set up of the TLS pool storage. +bool InitializePoolIndex() +{ + // Allocate a TLS index. + if ((PoolIndex = OS_AllocTLSIndex()) == OS_INVALID_TLS_INDEX) + return false; + + return true; +} + +// +// Implement the functionality of the TPoolAllocator class, which +// is documented in PoolAlloc.h. +// +TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) : + pageSize(growthIncrement), + alignment(allocationAlignment), + freeList(nullptr), + inUseList(nullptr), + numCalls(0) +{ + // + // Don't allow page sizes we know are smaller than all common + // OS page sizes. + // + if (pageSize < 4*1024) + pageSize = 4*1024; + + // + // A large currentPageOffset indicates a new page needs to + // be obtained to allocate memory. + // + currentPageOffset = pageSize; + + // + // Adjust alignment to be at least pointer aligned and + // power of 2. + // + size_t minAlign = sizeof(void*); + alignment &= ~(minAlign - 1); + if (alignment < minAlign) + alignment = minAlign; + size_t a = 1; + while (a < alignment) + a <<= 1; + alignment = a; + alignmentMask = a - 1; + + // + // Align header skip + // + headerSkip = minAlign; + if (headerSkip < sizeof(tHeader)) { + headerSkip = (sizeof(tHeader) + alignmentMask) & ~alignmentMask; + } + + push(); +} + +TPoolAllocator::~TPoolAllocator() +{ + while (inUseList) { + tHeader* next = inUseList->nextPage; + inUseList->~tHeader(); + delete [] reinterpret_cast(inUseList); + inUseList = next; + } + + // + // Always delete the free list memory - it can't be being + // (correctly) referenced, whether the pool allocator was + // global or not. We should not check the guard blocks + // here, because we did it already when the block was + // placed into the free list. + // + while (freeList) { + tHeader* next = freeList->nextPage; + delete [] reinterpret_cast(freeList); + freeList = next; + } +} + +const unsigned char TAllocation::guardBlockBeginVal = 0xfb; +const unsigned char TAllocation::guardBlockEndVal = 0xfe; +const unsigned char TAllocation::userDataFill = 0xcd; + +# ifdef GUARD_BLOCKS + const size_t TAllocation::guardBlockSize = 16; +# else + const size_t TAllocation::guardBlockSize = 0; +# endif + +// +// Check a single guard block for damage +// +#ifdef GUARD_BLOCKS +void TAllocation::checkGuardBlock(unsigned char* blockMem, unsigned char val, const char* locText) const +#else +void TAllocation::checkGuardBlock(unsigned char*, unsigned char, const char*) const +#endif +{ +#ifdef GUARD_BLOCKS + for (size_t x = 0; x < guardBlockSize; x++) { + if (blockMem[x] != val) { + const int maxSize = 80; + char assertMsg[maxSize]; + + // We don't print the assert message. It's here just to be helpful. + snprintf(assertMsg, maxSize, "PoolAlloc: Damage %s %zu byte allocation at 0x%p\n", + locText, size, data()); + assert(0 && "PoolAlloc: Damage in guard block"); + } + } +#else + assert(guardBlockSize == 0); +#endif +} + +void TPoolAllocator::push() +{ + tAllocState state = { currentPageOffset, inUseList }; + + stack.push_back(state); + + // + // Indicate there is no current page to allocate from. + // + currentPageOffset = pageSize; +} + +// +// Do a mass-deallocation of all the individual allocations +// that have occurred since the last push(), or since the +// last pop(), or since the object's creation. +// +// The deallocated pages are saved for future allocations. +// +void TPoolAllocator::pop() +{ + if (stack.size() < 1) + return; + + tHeader* page = stack.back().page; + currentPageOffset = stack.back().offset; + + while (inUseList != page) { + tHeader* nextInUse = inUseList->nextPage; + size_t pageCount = inUseList->pageCount; + + // This technically ends the lifetime of the header as C++ object, + // but we will still control the memory and reuse it. + inUseList->~tHeader(); // currently, just a debug allocation checker + + if (pageCount > 1) { + delete [] reinterpret_cast(inUseList); + } else { + inUseList->nextPage = freeList; + freeList = inUseList; + } + inUseList = nextInUse; + } + + stack.pop_back(); +} + +// +// Do a mass-deallocation of all the individual allocations +// that have occurred. +// +void TPoolAllocator::popAll() +{ + while (stack.size() > 0) + pop(); +} + +void* TPoolAllocator::allocate(size_t numBytes) +{ + // If we are using guard blocks, all allocations are bracketed by + // them: [guardblock][allocation][guardblock]. numBytes is how + // much memory the caller asked for. allocationSize is the total + // size including guard blocks. In release build, + // guardBlockSize=0 and this all gets optimized away. + size_t allocationSize = TAllocation::allocationSize(numBytes); + + // + // Just keep some interesting statistics. + // + ++numCalls; + totalBytes += numBytes; + + // + // Do the allocation, most likely case first, for efficiency. + // This step could be moved to be inline sometime. + // + if (currentPageOffset + allocationSize <= pageSize) { + // + // Safe to allocate from currentPageOffset. + // + unsigned char* memory = reinterpret_cast(inUseList) + currentPageOffset; + currentPageOffset += allocationSize; + currentPageOffset = (currentPageOffset + alignmentMask) & ~alignmentMask; + + return initializeAllocation(inUseList, memory, numBytes); + } + + if (allocationSize + headerSkip > pageSize) { + // + // Do a multi-page allocation. Don't mix these with the others. + // The OS is efficient and allocating and free-ing multiple pages. + // + size_t numBytesToAlloc = allocationSize + headerSkip; + tHeader* memory = reinterpret_cast(::new char[numBytesToAlloc]); + if (memory == 0) + return 0; + + // Use placement-new to initialize header + new(memory) tHeader(inUseList, (numBytesToAlloc + pageSize - 1) / pageSize); + inUseList = memory; + + currentPageOffset = pageSize; // make next allocation come from a new page + + // No guard blocks for multi-page allocations (yet) + return reinterpret_cast(reinterpret_cast(memory) + headerSkip); + } + + // + // Need a simple page to allocate from. + // + tHeader* memory; + if (freeList) { + memory = freeList; + freeList = freeList->nextPage; + } else { + memory = reinterpret_cast(::new char[pageSize]); + if (memory == 0) + return 0; + } + + // Use placement-new to initialize header + new(memory) tHeader(inUseList, 1); + inUseList = memory; + + unsigned char* ret = reinterpret_cast(inUseList) + headerSkip; + currentPageOffset = (headerSkip + allocationSize + alignmentMask) & ~alignmentMask; + + return initializeAllocation(inUseList, ret, numBytes); +} + +// +// Check all allocations in a list for damage by calling check on each. +// +void TAllocation::checkAllocList() const +{ + for (const TAllocation* alloc = this; alloc != 0; alloc = alloc->prevAlloc) + alloc->check(); +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/RemoveTree.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/RemoveTree.cpp new file mode 100644 index 00000000..1d33bfd2 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/RemoveTree.cpp @@ -0,0 +1,118 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2013 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#include "../Include/intermediate.h" +#include "RemoveTree.h" + +namespace glslang { + +// +// Code to recursively delete the intermediate tree. +// +struct TRemoveTraverser : TIntermTraverser { + TRemoveTraverser() : TIntermTraverser(false, false, true, false) {} + + virtual void visitSymbol(TIntermSymbol* node) + { + delete node; + } + + virtual bool visitBinary(TVisit /* visit*/ , TIntermBinary* node) + { + delete node; + + return true; + } + + virtual bool visitUnary(TVisit /* visit */, TIntermUnary* node) + { + delete node; + + return true; + } + + virtual bool visitAggregate(TVisit /* visit*/ , TIntermAggregate* node) + { + delete node; + + return true; + } + + virtual bool visitSelection(TVisit /* visit*/ , TIntermSelection* node) + { + delete node; + + return true; + } + + virtual bool visitSwitch(TVisit /* visit*/ , TIntermSwitch* node) + { + delete node; + + return true; + } + + virtual void visitConstantUnion(TIntermConstantUnion* node) + { + delete node; + } + + virtual bool visitLoop(TVisit /* visit*/ , TIntermLoop* node) + { + delete node; + + return true; + } + + virtual bool visitBranch(TVisit /* visit*/ , TIntermBranch* node) + { + delete node; + + return true; + } +}; + +// +// Entry point. +// +void RemoveAllTreeNodes(TIntermNode* root) +{ + TRemoveTraverser it; + + root->traverse(&it); +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/RemoveTree.h b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/RemoveTree.h new file mode 100644 index 00000000..1ed01562 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/RemoveTree.h @@ -0,0 +1,41 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#pragma once + +namespace glslang { + +void RemoveAllTreeNodes(TIntermNode*); + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/Scan.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/Scan.cpp new file mode 100644 index 00000000..df15a166 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/Scan.cpp @@ -0,0 +1,1460 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2013 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +// +// GLSL scanning, leveraging the scanning done by the preprocessor. +// + +#include +#include +#include + +#include "../Include/Types.h" +#include "SymbolTable.h" +#include "ParseHelper.h" +#include "glslang_tab.cpp.h" +#include "ScanContext.h" +#include "Scan.h" + +// preprocessor includes +#include "preprocessor/PpContext.h" +#include "preprocessor/PpTokens.h" + +// Required to avoid missing prototype warnings for some compilers +int yylex(YYSTYPE*, glslang::TParseContext&); + +namespace glslang { + +// read past any white space +void TInputScanner::consumeWhiteSpace(bool& foundNonSpaceTab) +{ + int c = peek(); // don't accidentally consume anything other than whitespace + while (c == ' ' || c == '\t' || c == '\r' || c == '\n') { + if (c == '\r' || c == '\n') + foundNonSpaceTab = true; + get(); + c = peek(); + } +} + +// return true if a comment was actually consumed +bool TInputScanner::consumeComment() +{ + if (peek() != '/') + return false; + + get(); // consume the '/' + int c = peek(); + if (c == '/') { + + // a '//' style comment + get(); // consume the second '/' + c = get(); + do { + while (c != EndOfInput && c != '\\' && c != '\r' && c != '\n') + c = get(); + + if (c == EndOfInput || c == '\r' || c == '\n') { + while (c == '\r' || c == '\n') + c = get(); + + // we reached the end of the comment + break; + } else { + // it's a '\', so we need to keep going, after skipping what's escaped + + // read the skipped character + c = get(); + + // if it's a two-character newline, skip both characters + if (c == '\r' && peek() == '\n') + get(); + c = get(); + } + } while (true); + + // put back the last non-comment character + if (c != EndOfInput) + unget(); + + return true; + } else if (c == '*') { + + // a '/*' style comment + get(); // consume the '*' + c = get(); + do { + while (c != EndOfInput && c != '*') + c = get(); + if (c == '*') { + c = get(); + if (c == '/') + break; // end of comment + // not end of comment + } else // end of input + break; + } while (true); + + return true; + } else { + // it's not a comment, put the '/' back + unget(); + + return false; + } +} + +// skip whitespace, then skip a comment, rinse, repeat +void TInputScanner::consumeWhitespaceComment(bool& foundNonSpaceTab) +{ + do { + consumeWhiteSpace(foundNonSpaceTab); + + // if not starting a comment now, then done + int c = peek(); + if (c != '/' || c == EndOfInput) + return; + + // skip potential comment + foundNonSpaceTab = true; + if (! consumeComment()) + return; + + } while (true); +} + +// Returns true if there was non-white space (e.g., a comment, newline) before the #version +// or no #version was found; otherwise, returns false. There is no error case, it always +// succeeds, but will leave version == 0 if no #version was found. +// +// Sets notFirstToken based on whether tokens (beyond white space and comments) +// appeared before the #version. +// +// N.B. does not attempt to leave input in any particular known state. The assumption +// is that scanning will start anew, following the rules for the chosen version/profile, +// and with a corresponding parsing context. +// +bool TInputScanner::scanVersion(int& version, EProfile& profile, bool& notFirstToken) +{ + // This function doesn't have to get all the semantics correct, + // just find the #version if there is a correct one present. + // The preprocessor will have the responsibility of getting all the semantics right. + + bool versionNotFirst = false; // means not first WRT comments and white space, nothing more + notFirstToken = false; // means not first WRT to real tokens + version = 0; // means not found + profile = ENoProfile; + + bool foundNonSpaceTab = false; + bool lookingInMiddle = false; + int c; + do { + if (lookingInMiddle) { + notFirstToken = true; + // make forward progress by finishing off the current line plus extra new lines + if (peek() == '\n' || peek() == '\r') { + while (peek() == '\n' || peek() == '\r') + get(); + } else + do { + c = get(); + } while (c != EndOfInput && c != '\n' && c != '\r'); + while (peek() == '\n' || peek() == '\r') + get(); + if (peek() == EndOfInput) + return true; + } + lookingInMiddle = true; + + // Nominal start, skipping the desktop allowed comments and white space, but tracking if + // something else was found for ES: + consumeWhitespaceComment(foundNonSpaceTab); + if (foundNonSpaceTab) + versionNotFirst = true; + + // "#" + if (get() != '#') { + versionNotFirst = true; + continue; + } + + // whitespace + do { + c = get(); + } while (c == ' ' || c == '\t'); + + // "version" + if ( c != 'v' || + get() != 'e' || + get() != 'r' || + get() != 's' || + get() != 'i' || + get() != 'o' || + get() != 'n') { + versionNotFirst = true; + continue; + } + + // whitespace + do { + c = get(); + } while (c == ' ' || c == '\t'); + + // version number + while (c >= '0' && c <= '9') { + version = 10 * version + (c - '0'); + c = get(); + } + if (version == 0) { + versionNotFirst = true; + continue; + } + + // whitespace + while (c == ' ' || c == '\t') + c = get(); + + // profile + const int maxProfileLength = 13; // not including any 0 + char profileString[maxProfileLength]; + int profileLength; + for (profileLength = 0; profileLength < maxProfileLength; ++profileLength) { + if (c == EndOfInput || c == ' ' || c == '\t' || c == '\n' || c == '\r') + break; + profileString[profileLength] = (char)c; + c = get(); + } + if (c != EndOfInput && c != ' ' && c != '\t' && c != '\n' && c != '\r') { + versionNotFirst = true; + continue; + } + + if (profileLength == 2 && strncmp(profileString, "es", profileLength) == 0) + profile = EEsProfile; + else if (profileLength == 4 && strncmp(profileString, "core", profileLength) == 0) + profile = ECoreProfile; + else if (profileLength == 13 && strncmp(profileString, "compatibility", profileLength) == 0) + profile = ECompatibilityProfile; + + return versionNotFirst; + } while (true); +} + +// Fill this in when doing glslang-level scanning, to hand back to the parser. +class TParserToken { +public: + explicit TParserToken(YYSTYPE& b) : sType(b) { } + + YYSTYPE& sType; +protected: + TParserToken(TParserToken&); + TParserToken& operator=(TParserToken&); +}; + +} // end namespace glslang + +// This is the function the glslang parser (i.e., bison) calls to get its next token +int yylex(YYSTYPE* glslangTokenDesc, glslang::TParseContext& parseContext) +{ + glslang::TParserToken token(*glslangTokenDesc); + + return parseContext.getScanContext()->tokenize(parseContext.getPpContext(), token); +} + +namespace { + +struct str_eq +{ + bool operator()(const char* lhs, const char* rhs) const + { + return strcmp(lhs, rhs) == 0; + } +}; + +struct str_hash +{ + size_t operator()(const char* str) const + { + // djb2 + unsigned long hash = 5381; + int c; + + while ((c = *str++) != 0) + hash = ((hash << 5) + hash) + c; + + return hash; + } +}; + +// A single global usable by all threads, by all versions, by all languages. +// After a single process-level initialization, this is read only and thread safe +std::unordered_map* KeywordMap = nullptr; +std::unordered_set* ReservedSet = nullptr; + +}; + +namespace glslang { + +void TScanContext::fillInKeywordMap() +{ + if (KeywordMap != nullptr) { + // this is really an error, as this should called only once per process + // but, the only risk is if two threads called simultaneously + return; + } + KeywordMap = new std::unordered_map; + + (*KeywordMap)["const"] = CONST; + (*KeywordMap)["uniform"] = UNIFORM; + (*KeywordMap)["in"] = IN; + (*KeywordMap)["out"] = OUT; + (*KeywordMap)["inout"] = INOUT; + (*KeywordMap)["struct"] = STRUCT; + (*KeywordMap)["break"] = BREAK; + (*KeywordMap)["continue"] = CONTINUE; + (*KeywordMap)["do"] = DO; + (*KeywordMap)["for"] = FOR; + (*KeywordMap)["while"] = WHILE; + (*KeywordMap)["switch"] = SWITCH; + (*KeywordMap)["case"] = CASE; + (*KeywordMap)["default"] = DEFAULT; + (*KeywordMap)["if"] = IF; + (*KeywordMap)["else"] = ELSE; + (*KeywordMap)["discard"] = DISCARD; + (*KeywordMap)["return"] = RETURN; + (*KeywordMap)["void"] = VOID; + (*KeywordMap)["bool"] = BOOL; + (*KeywordMap)["float"] = FLOAT; + (*KeywordMap)["int"] = INT; + (*KeywordMap)["bvec2"] = BVEC2; + (*KeywordMap)["bvec3"] = BVEC3; + (*KeywordMap)["bvec4"] = BVEC4; + (*KeywordMap)["vec2"] = VEC2; + (*KeywordMap)["vec3"] = VEC3; + (*KeywordMap)["vec4"] = VEC4; + (*KeywordMap)["ivec2"] = IVEC2; + (*KeywordMap)["ivec3"] = IVEC3; + (*KeywordMap)["ivec4"] = IVEC4; + (*KeywordMap)["mat2"] = MAT2; + (*KeywordMap)["mat3"] = MAT3; + (*KeywordMap)["mat4"] = MAT4; + (*KeywordMap)["true"] = BOOLCONSTANT; + (*KeywordMap)["false"] = BOOLCONSTANT; + (*KeywordMap)["attribute"] = ATTRIBUTE; + (*KeywordMap)["varying"] = VARYING; + (*KeywordMap)["buffer"] = BUFFER; + (*KeywordMap)["coherent"] = COHERENT; + (*KeywordMap)["restrict"] = RESTRICT; + (*KeywordMap)["readonly"] = READONLY; + (*KeywordMap)["writeonly"] = WRITEONLY; + (*KeywordMap)["atomic_uint"] = ATOMIC_UINT; + (*KeywordMap)["volatile"] = VOLATILE; + (*KeywordMap)["layout"] = LAYOUT; + (*KeywordMap)["shared"] = SHARED; + (*KeywordMap)["patch"] = PATCH; + (*KeywordMap)["sample"] = SAMPLE; + (*KeywordMap)["subroutine"] = SUBROUTINE; + (*KeywordMap)["highp"] = HIGH_PRECISION; + (*KeywordMap)["mediump"] = MEDIUM_PRECISION; + (*KeywordMap)["lowp"] = LOW_PRECISION; + (*KeywordMap)["precision"] = PRECISION; + (*KeywordMap)["mat2x2"] = MAT2X2; + (*KeywordMap)["mat2x3"] = MAT2X3; + (*KeywordMap)["mat2x4"] = MAT2X4; + (*KeywordMap)["mat3x2"] = MAT3X2; + (*KeywordMap)["mat3x3"] = MAT3X3; + (*KeywordMap)["mat3x4"] = MAT3X4; + (*KeywordMap)["mat4x2"] = MAT4X2; + (*KeywordMap)["mat4x3"] = MAT4X3; + (*KeywordMap)["mat4x4"] = MAT4X4; + (*KeywordMap)["dmat2"] = DMAT2; + (*KeywordMap)["dmat3"] = DMAT3; + (*KeywordMap)["dmat4"] = DMAT4; + (*KeywordMap)["dmat2x2"] = DMAT2X2; + (*KeywordMap)["dmat2x3"] = DMAT2X3; + (*KeywordMap)["dmat2x4"] = DMAT2X4; + (*KeywordMap)["dmat3x2"] = DMAT3X2; + (*KeywordMap)["dmat3x3"] = DMAT3X3; + (*KeywordMap)["dmat3x4"] = DMAT3X4; + (*KeywordMap)["dmat4x2"] = DMAT4X2; + (*KeywordMap)["dmat4x3"] = DMAT4X3; + (*KeywordMap)["dmat4x4"] = DMAT4X4; + (*KeywordMap)["image1D"] = IMAGE1D; + (*KeywordMap)["iimage1D"] = IIMAGE1D; + (*KeywordMap)["uimage1D"] = UIMAGE1D; + (*KeywordMap)["image2D"] = IMAGE2D; + (*KeywordMap)["iimage2D"] = IIMAGE2D; + (*KeywordMap)["uimage2D"] = UIMAGE2D; + (*KeywordMap)["image3D"] = IMAGE3D; + (*KeywordMap)["iimage3D"] = IIMAGE3D; + (*KeywordMap)["uimage3D"] = UIMAGE3D; + (*KeywordMap)["image2DRect"] = IMAGE2DRECT; + (*KeywordMap)["iimage2DRect"] = IIMAGE2DRECT; + (*KeywordMap)["uimage2DRect"] = UIMAGE2DRECT; + (*KeywordMap)["imageCube"] = IMAGECUBE; + (*KeywordMap)["iimageCube"] = IIMAGECUBE; + (*KeywordMap)["uimageCube"] = UIMAGECUBE; + (*KeywordMap)["imageBuffer"] = IMAGEBUFFER; + (*KeywordMap)["iimageBuffer"] = IIMAGEBUFFER; + (*KeywordMap)["uimageBuffer"] = UIMAGEBUFFER; + (*KeywordMap)["image1DArray"] = IMAGE1DARRAY; + (*KeywordMap)["iimage1DArray"] = IIMAGE1DARRAY; + (*KeywordMap)["uimage1DArray"] = UIMAGE1DARRAY; + (*KeywordMap)["image2DArray"] = IMAGE2DARRAY; + (*KeywordMap)["iimage2DArray"] = IIMAGE2DARRAY; + (*KeywordMap)["uimage2DArray"] = UIMAGE2DARRAY; + (*KeywordMap)["imageCubeArray"] = IMAGECUBEARRAY; + (*KeywordMap)["iimageCubeArray"] = IIMAGECUBEARRAY; + (*KeywordMap)["uimageCubeArray"] = UIMAGECUBEARRAY; + (*KeywordMap)["image2DMS"] = IMAGE2DMS; + (*KeywordMap)["iimage2DMS"] = IIMAGE2DMS; + (*KeywordMap)["uimage2DMS"] = UIMAGE2DMS; + (*KeywordMap)["image2DMSArray"] = IMAGE2DMSARRAY; + (*KeywordMap)["iimage2DMSArray"] = IIMAGE2DMSARRAY; + (*KeywordMap)["uimage2DMSArray"] = UIMAGE2DMSARRAY; + (*KeywordMap)["double"] = DOUBLE; + (*KeywordMap)["dvec2"] = DVEC2; + (*KeywordMap)["dvec3"] = DVEC3; + (*KeywordMap)["dvec4"] = DVEC4; + (*KeywordMap)["uint"] = UINT; + (*KeywordMap)["uvec2"] = UVEC2; + (*KeywordMap)["uvec3"] = UVEC3; + (*KeywordMap)["uvec4"] = UVEC4; + + (*KeywordMap)["int64_t"] = INT64_T; + (*KeywordMap)["uint64_t"] = UINT64_T; + (*KeywordMap)["i64vec2"] = I64VEC2; + (*KeywordMap)["i64vec3"] = I64VEC3; + (*KeywordMap)["i64vec4"] = I64VEC4; + (*KeywordMap)["u64vec2"] = U64VEC2; + (*KeywordMap)["u64vec3"] = U64VEC3; + (*KeywordMap)["u64vec4"] = U64VEC4; + +#ifdef AMD_EXTENSIONS + (*KeywordMap)["int16_t"] = INT16_T; + (*KeywordMap)["uint16_t"] = UINT16_T; + (*KeywordMap)["i16vec2"] = I16VEC2; + (*KeywordMap)["i16vec3"] = I16VEC3; + (*KeywordMap)["i16vec4"] = I16VEC4; + (*KeywordMap)["u16vec2"] = U16VEC2; + (*KeywordMap)["u16vec3"] = U16VEC3; + (*KeywordMap)["u16vec4"] = U16VEC4; + + (*KeywordMap)["float16_t"] = FLOAT16_T; + (*KeywordMap)["f16vec2"] = F16VEC2; + (*KeywordMap)["f16vec3"] = F16VEC3; + (*KeywordMap)["f16vec4"] = F16VEC4; + (*KeywordMap)["f16mat2"] = F16MAT2; + (*KeywordMap)["f16mat3"] = F16MAT3; + (*KeywordMap)["f16mat4"] = F16MAT4; + (*KeywordMap)["f16mat2x2"] = F16MAT2X2; + (*KeywordMap)["f16mat2x3"] = F16MAT2X3; + (*KeywordMap)["f16mat2x4"] = F16MAT2X4; + (*KeywordMap)["f16mat3x2"] = F16MAT3X2; + (*KeywordMap)["f16mat3x3"] = F16MAT3X3; + (*KeywordMap)["f16mat3x4"] = F16MAT3X4; + (*KeywordMap)["f16mat4x2"] = F16MAT4X2; + (*KeywordMap)["f16mat4x3"] = F16MAT4X3; + (*KeywordMap)["f16mat4x4"] = F16MAT4X4; +#endif + + (*KeywordMap)["sampler2D"] = SAMPLER2D; + (*KeywordMap)["samplerCube"] = SAMPLERCUBE; + (*KeywordMap)["samplerCubeArray"] = SAMPLERCUBEARRAY; + (*KeywordMap)["samplerCubeArrayShadow"] = SAMPLERCUBEARRAYSHADOW; + (*KeywordMap)["isamplerCubeArray"] = ISAMPLERCUBEARRAY; + (*KeywordMap)["usamplerCubeArray"] = USAMPLERCUBEARRAY; + (*KeywordMap)["sampler1DArrayShadow"] = SAMPLER1DARRAYSHADOW; + (*KeywordMap)["isampler1DArray"] = ISAMPLER1DARRAY; + (*KeywordMap)["usampler1D"] = USAMPLER1D; + (*KeywordMap)["isampler1D"] = ISAMPLER1D; + (*KeywordMap)["usampler1DArray"] = USAMPLER1DARRAY; + (*KeywordMap)["samplerBuffer"] = SAMPLERBUFFER; + (*KeywordMap)["samplerCubeShadow"] = SAMPLERCUBESHADOW; + (*KeywordMap)["sampler2DArray"] = SAMPLER2DARRAY; + (*KeywordMap)["sampler2DArrayShadow"] = SAMPLER2DARRAYSHADOW; + (*KeywordMap)["isampler2D"] = ISAMPLER2D; + (*KeywordMap)["isampler3D"] = ISAMPLER3D; + (*KeywordMap)["isamplerCube"] = ISAMPLERCUBE; + (*KeywordMap)["isampler2DArray"] = ISAMPLER2DARRAY; + (*KeywordMap)["usampler2D"] = USAMPLER2D; + (*KeywordMap)["usampler3D"] = USAMPLER3D; + (*KeywordMap)["usamplerCube"] = USAMPLERCUBE; + (*KeywordMap)["usampler2DArray"] = USAMPLER2DARRAY; + (*KeywordMap)["isampler2DRect"] = ISAMPLER2DRECT; + (*KeywordMap)["usampler2DRect"] = USAMPLER2DRECT; + (*KeywordMap)["isamplerBuffer"] = ISAMPLERBUFFER; + (*KeywordMap)["usamplerBuffer"] = USAMPLERBUFFER; + (*KeywordMap)["sampler2DMS"] = SAMPLER2DMS; + (*KeywordMap)["isampler2DMS"] = ISAMPLER2DMS; + (*KeywordMap)["usampler2DMS"] = USAMPLER2DMS; + (*KeywordMap)["sampler2DMSArray"] = SAMPLER2DMSARRAY; + (*KeywordMap)["isampler2DMSArray"] = ISAMPLER2DMSARRAY; + (*KeywordMap)["usampler2DMSArray"] = USAMPLER2DMSARRAY; + (*KeywordMap)["sampler1D"] = SAMPLER1D; + (*KeywordMap)["sampler1DShadow"] = SAMPLER1DSHADOW; + (*KeywordMap)["sampler3D"] = SAMPLER3D; + (*KeywordMap)["sampler2DShadow"] = SAMPLER2DSHADOW; + (*KeywordMap)["sampler2DRect"] = SAMPLER2DRECT; + (*KeywordMap)["sampler2DRectShadow"] = SAMPLER2DRECTSHADOW; + (*KeywordMap)["sampler1DArray"] = SAMPLER1DARRAY; + + (*KeywordMap)["samplerExternalOES"] = SAMPLEREXTERNALOES; // GL_OES_EGL_image_external + + (*KeywordMap)["sampler"] = SAMPLER; + (*KeywordMap)["samplerShadow"] = SAMPLERSHADOW; + + (*KeywordMap)["texture2D"] = TEXTURE2D; + (*KeywordMap)["textureCube"] = TEXTURECUBE; + (*KeywordMap)["textureCubeArray"] = TEXTURECUBEARRAY; + (*KeywordMap)["itextureCubeArray"] = ITEXTURECUBEARRAY; + (*KeywordMap)["utextureCubeArray"] = UTEXTURECUBEARRAY; + (*KeywordMap)["itexture1DArray"] = ITEXTURE1DARRAY; + (*KeywordMap)["utexture1D"] = UTEXTURE1D; + (*KeywordMap)["itexture1D"] = ITEXTURE1D; + (*KeywordMap)["utexture1DArray"] = UTEXTURE1DARRAY; + (*KeywordMap)["textureBuffer"] = TEXTUREBUFFER; + (*KeywordMap)["texture2DArray"] = TEXTURE2DARRAY; + (*KeywordMap)["itexture2D"] = ITEXTURE2D; + (*KeywordMap)["itexture3D"] = ITEXTURE3D; + (*KeywordMap)["itextureCube"] = ITEXTURECUBE; + (*KeywordMap)["itexture2DArray"] = ITEXTURE2DARRAY; + (*KeywordMap)["utexture2D"] = UTEXTURE2D; + (*KeywordMap)["utexture3D"] = UTEXTURE3D; + (*KeywordMap)["utextureCube"] = UTEXTURECUBE; + (*KeywordMap)["utexture2DArray"] = UTEXTURE2DARRAY; + (*KeywordMap)["itexture2DRect"] = ITEXTURE2DRECT; + (*KeywordMap)["utexture2DRect"] = UTEXTURE2DRECT; + (*KeywordMap)["itextureBuffer"] = ITEXTUREBUFFER; + (*KeywordMap)["utextureBuffer"] = UTEXTUREBUFFER; + (*KeywordMap)["texture2DMS"] = TEXTURE2DMS; + (*KeywordMap)["itexture2DMS"] = ITEXTURE2DMS; + (*KeywordMap)["utexture2DMS"] = UTEXTURE2DMS; + (*KeywordMap)["texture2DMSArray"] = TEXTURE2DMSARRAY; + (*KeywordMap)["itexture2DMSArray"] = ITEXTURE2DMSARRAY; + (*KeywordMap)["utexture2DMSArray"] = UTEXTURE2DMSARRAY; + (*KeywordMap)["texture1D"] = TEXTURE1D; + (*KeywordMap)["texture3D"] = TEXTURE3D; + (*KeywordMap)["texture2DRect"] = TEXTURE2DRECT; + (*KeywordMap)["texture1DArray"] = TEXTURE1DARRAY; + + (*KeywordMap)["subpassInput"] = SUBPASSINPUT; + (*KeywordMap)["subpassInputMS"] = SUBPASSINPUTMS; + (*KeywordMap)["isubpassInput"] = ISUBPASSINPUT; + (*KeywordMap)["isubpassInputMS"] = ISUBPASSINPUTMS; + (*KeywordMap)["usubpassInput"] = USUBPASSINPUT; + (*KeywordMap)["usubpassInputMS"] = USUBPASSINPUTMS; + + (*KeywordMap)["noperspective"] = NOPERSPECTIVE; + (*KeywordMap)["smooth"] = SMOOTH; + (*KeywordMap)["flat"] = FLAT; +#ifdef AMD_EXTENSIONS + (*KeywordMap)["__explicitInterpAMD"] = __EXPLICITINTERPAMD; +#endif + (*KeywordMap)["centroid"] = CENTROID; + (*KeywordMap)["precise"] = PRECISE; + (*KeywordMap)["invariant"] = INVARIANT; + (*KeywordMap)["packed"] = PACKED; + (*KeywordMap)["resource"] = RESOURCE; + (*KeywordMap)["superp"] = SUPERP; + + ReservedSet = new std::unordered_set; + + ReservedSet->insert("common"); + ReservedSet->insert("partition"); + ReservedSet->insert("active"); + ReservedSet->insert("asm"); + ReservedSet->insert("class"); + ReservedSet->insert("union"); + ReservedSet->insert("enum"); + ReservedSet->insert("typedef"); + ReservedSet->insert("template"); + ReservedSet->insert("this"); + ReservedSet->insert("goto"); + ReservedSet->insert("inline"); + ReservedSet->insert("noinline"); + ReservedSet->insert("public"); + ReservedSet->insert("static"); + ReservedSet->insert("extern"); + ReservedSet->insert("external"); + ReservedSet->insert("interface"); + ReservedSet->insert("long"); + ReservedSet->insert("short"); + ReservedSet->insert("half"); + ReservedSet->insert("fixed"); + ReservedSet->insert("unsigned"); + ReservedSet->insert("input"); + ReservedSet->insert("output"); + ReservedSet->insert("hvec2"); + ReservedSet->insert("hvec3"); + ReservedSet->insert("hvec4"); + ReservedSet->insert("fvec2"); + ReservedSet->insert("fvec3"); + ReservedSet->insert("fvec4"); + ReservedSet->insert("sampler3DRect"); + ReservedSet->insert("filter"); + ReservedSet->insert("sizeof"); + ReservedSet->insert("cast"); + ReservedSet->insert("namespace"); + ReservedSet->insert("using"); +} + +void TScanContext::deleteKeywordMap() +{ + delete KeywordMap; + KeywordMap = nullptr; + delete ReservedSet; + ReservedSet = nullptr; +} + +// Called by yylex to get the next token. +// Returning 0 implies end of input. +int TScanContext::tokenize(TPpContext* pp, TParserToken& token) +{ + do { + parserToken = &token; + TPpToken ppToken; + int token = pp->tokenize(ppToken); + if (token == EndOfInput) + return 0; + + tokenText = ppToken.name; + loc = ppToken.loc; + parserToken->sType.lex.loc = loc; + switch (token) { + case ';': afterType = false; return SEMICOLON; + case ',': afterType = false; return COMMA; + case ':': return COLON; + case '=': afterType = false; return EQUAL; + case '(': afterType = false; return LEFT_PAREN; + case ')': afterType = false; return RIGHT_PAREN; + case '.': field = true; return DOT; + case '!': return BANG; + case '-': return DASH; + case '~': return TILDE; + case '+': return PLUS; + case '*': return STAR; + case '/': return SLASH; + case '%': return PERCENT; + case '<': return LEFT_ANGLE; + case '>': return RIGHT_ANGLE; + case '|': return VERTICAL_BAR; + case '^': return CARET; + case '&': return AMPERSAND; + case '?': return QUESTION; + case '[': return LEFT_BRACKET; + case ']': return RIGHT_BRACKET; + case '{': return LEFT_BRACE; + case '}': return RIGHT_BRACE; + case '\\': + parseContext.error(loc, "illegal use of escape character", "\\", ""); + break; + + case PPAtomAddAssign: return ADD_ASSIGN; + case PPAtomSubAssign: return SUB_ASSIGN; + case PPAtomMulAssign: return MUL_ASSIGN; + case PPAtomDivAssign: return DIV_ASSIGN; + case PPAtomModAssign: return MOD_ASSIGN; + + case PpAtomRight: return RIGHT_OP; + case PpAtomLeft: return LEFT_OP; + + case PpAtomRightAssign: return RIGHT_ASSIGN; + case PpAtomLeftAssign: return LEFT_ASSIGN; + case PpAtomAndAssign: return AND_ASSIGN; + case PpAtomOrAssign: return OR_ASSIGN; + case PpAtomXorAssign: return XOR_ASSIGN; + + case PpAtomAnd: return AND_OP; + case PpAtomOr: return OR_OP; + case PpAtomXor: return XOR_OP; + + case PpAtomEQ: return EQ_OP; + case PpAtomGE: return GE_OP; + case PpAtomNE: return NE_OP; + case PpAtomLE: return LE_OP; + + case PpAtomDecrement: return DEC_OP; + case PpAtomIncrement: return INC_OP; + + case PpAtomColonColon: + parseContext.error(loc, "not supported", "::", ""); + break; + + case PpAtomConstInt: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT; + case PpAtomConstUint: parserToken->sType.lex.i = ppToken.ival; return UINTCONSTANT; + case PpAtomConstInt64: parserToken->sType.lex.i64 = ppToken.i64val; return INT64CONSTANT; + case PpAtomConstUint64: parserToken->sType.lex.i64 = ppToken.i64val; return UINT64CONSTANT; +#ifdef AMD_EXTENSIONS + case PpAtomConstInt16: parserToken->sType.lex.i = ppToken.ival; return INT16CONSTANT; + case PpAtomConstUint16: parserToken->sType.lex.i = ppToken.ival; return UINT16CONSTANT; +#endif + case PpAtomConstFloat: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT; + case PpAtomConstDouble: parserToken->sType.lex.d = ppToken.dval; return DOUBLECONSTANT; +#ifdef AMD_EXTENSIONS + case PpAtomConstFloat16: parserToken->sType.lex.d = ppToken.dval; return FLOAT16CONSTANT; +#endif + case PpAtomIdentifier: + { + int token = tokenizeIdentifier(); + field = false; + return token; + } + + case EndOfInput: return 0; + + default: + char buf[2]; + buf[0] = (char)token; + buf[1] = 0; + parseContext.error(loc, "unexpected token", buf, ""); + break; + } + } while (true); +} + +int TScanContext::tokenizeIdentifier() +{ + if (ReservedSet->find(tokenText) != ReservedSet->end()) + return reservedWord(); + + auto it = KeywordMap->find(tokenText); + if (it == KeywordMap->end()) { + // Should have an identifier of some sort + return identifierOrType(); + } + keyword = it->second; + + switch (keyword) { + case CONST: + case UNIFORM: + case IN: + case OUT: + case INOUT: + case STRUCT: + case BREAK: + case CONTINUE: + case DO: + case FOR: + case WHILE: + case IF: + case ELSE: + case DISCARD: + case RETURN: + case CASE: + return keyword; + + case SWITCH: + case DEFAULT: + if ((parseContext.profile == EEsProfile && parseContext.version < 300) || + (parseContext.profile != EEsProfile && parseContext.version < 130)) + reservedWord(); + return keyword; + + case VOID: + case BOOL: + case FLOAT: + case INT: + case BVEC2: + case BVEC3: + case BVEC4: + case VEC2: + case VEC3: + case VEC4: + case IVEC2: + case IVEC3: + case IVEC4: + case MAT2: + case MAT3: + case MAT4: + case SAMPLER2D: + case SAMPLERCUBE: + afterType = true; + return keyword; + + case BOOLCONSTANT: + if (strcmp("true", tokenText) == 0) + parserToken->sType.lex.b = true; + else + parserToken->sType.lex.b = false; + return keyword; + + case ATTRIBUTE: + case VARYING: + if (parseContext.profile == EEsProfile && parseContext.version >= 300) + reservedWord(); + return keyword; + + case BUFFER: + if ((parseContext.profile == EEsProfile && parseContext.version < 310) || + (parseContext.profile != EEsProfile && parseContext.version < 430)) + return identifierOrType(); + return keyword; + + case ATOMIC_UINT: + if ((parseContext.profile == EEsProfile && parseContext.version >= 310) || + parseContext.extensionTurnedOn(E_GL_ARB_shader_atomic_counters)) + return keyword; + return es30ReservedFromGLSL(420); + + case COHERENT: + case RESTRICT: + case READONLY: + case WRITEONLY: + if (parseContext.profile == EEsProfile && parseContext.version >= 310) + return keyword; + return es30ReservedFromGLSL(parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store) ? 130 : 420); + + case VOLATILE: + if (parseContext.profile == EEsProfile && parseContext.version >= 310) + return keyword; + if (! parseContext.symbolTable.atBuiltInLevel() && (parseContext.profile == EEsProfile || (parseContext.version < 420 && ! parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store)))) + reservedWord(); + return keyword; + + case LAYOUT: + { + const int numLayoutExts = 2; + const char* layoutExts[numLayoutExts] = { E_GL_ARB_shading_language_420pack, + E_GL_ARB_explicit_attrib_location }; + if ((parseContext.profile == EEsProfile && parseContext.version < 300) || + (parseContext.profile != EEsProfile && parseContext.version < 140 && + ! parseContext.extensionsTurnedOn(numLayoutExts, layoutExts))) + return identifierOrType(); + return keyword; + } + case SHARED: + if ((parseContext.profile == EEsProfile && parseContext.version < 300) || + (parseContext.profile != EEsProfile && parseContext.version < 140)) + return identifierOrType(); + return keyword; + + case PATCH: + if (parseContext.symbolTable.atBuiltInLevel() || + (parseContext.profile == EEsProfile && + (parseContext.version >= 320 || + parseContext.extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader))) || + (parseContext.profile != EEsProfile && parseContext.extensionTurnedOn(E_GL_ARB_tessellation_shader))) + return keyword; + + return es30ReservedFromGLSL(400); + + case SAMPLE: + if ((parseContext.profile == EEsProfile && parseContext.version >= 320) || + parseContext.extensionsTurnedOn(1, &E_GL_OES_shader_multisample_interpolation)) + return keyword; + return es30ReservedFromGLSL(400); + + case SUBROUTINE: + return es30ReservedFromGLSL(400); + + case HIGH_PRECISION: + case MEDIUM_PRECISION: + case LOW_PRECISION: + case PRECISION: + return precisionKeyword(); + + case MAT2X2: + case MAT2X3: + case MAT2X4: + case MAT3X2: + case MAT3X3: + case MAT3X4: + case MAT4X2: + case MAT4X3: + case MAT4X4: + return matNxM(); + + case DMAT2: + case DMAT3: + case DMAT4: + case DMAT2X2: + case DMAT2X3: + case DMAT2X4: + case DMAT3X2: + case DMAT3X3: + case DMAT3X4: + case DMAT4X2: + case DMAT4X3: + case DMAT4X4: + return dMat(); + + case IMAGE1D: + case IIMAGE1D: + case UIMAGE1D: + case IMAGE1DARRAY: + case IIMAGE1DARRAY: + case UIMAGE1DARRAY: + case IMAGE2DRECT: + case IIMAGE2DRECT: + case UIMAGE2DRECT: + afterType = true; + return firstGenerationImage(false); + + case IMAGEBUFFER: + case IIMAGEBUFFER: + case UIMAGEBUFFER: + afterType = true; + if ((parseContext.profile == EEsProfile && parseContext.version >= 320) || + parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer)) + return keyword; + return firstGenerationImage(false); + + case IMAGE2D: + case IIMAGE2D: + case UIMAGE2D: + case IMAGE3D: + case IIMAGE3D: + case UIMAGE3D: + case IMAGECUBE: + case IIMAGECUBE: + case UIMAGECUBE: + case IMAGE2DARRAY: + case IIMAGE2DARRAY: + case UIMAGE2DARRAY: + afterType = true; + return firstGenerationImage(true); + + case IMAGECUBEARRAY: + case IIMAGECUBEARRAY: + case UIMAGECUBEARRAY: + afterType = true; + if ((parseContext.profile == EEsProfile && parseContext.version >= 320) || + parseContext.extensionsTurnedOn(Num_AEP_texture_cube_map_array, AEP_texture_cube_map_array)) + return keyword; + return secondGenerationImage(); + + case IMAGE2DMS: + case IIMAGE2DMS: + case UIMAGE2DMS: + case IMAGE2DMSARRAY: + case IIMAGE2DMSARRAY: + case UIMAGE2DMSARRAY: + afterType = true; + return secondGenerationImage(); + + case DOUBLE: + case DVEC2: + case DVEC3: + case DVEC4: + afterType = true; + if (parseContext.profile == EEsProfile || parseContext.version < 400) + reservedWord(); + return keyword; + + case INT64_T: + case UINT64_T: + case I64VEC2: + case I64VEC3: + case I64VEC4: + case U64VEC2: + case U64VEC3: + case U64VEC4: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel() || + (parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_int64) && + parseContext.profile != EEsProfile && parseContext.version >= 450)) + return keyword; + return identifierOrType(); + +#ifdef AMD_EXTENSIONS + case INT16_T: + case UINT16_T: + case I16VEC2: + case I16VEC3: + case I16VEC4: + case U16VEC2: + case U16VEC3: + case U16VEC4: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel() || + (parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_int16) && + parseContext.profile != EEsProfile && parseContext.version >= 450)) + return keyword; + return identifierOrType(); + + case FLOAT16_T: + case F16VEC2: + case F16VEC3: + case F16VEC4: + case F16MAT2: + case F16MAT3: + case F16MAT4: + case F16MAT2X2: + case F16MAT2X3: + case F16MAT2X4: + case F16MAT3X2: + case F16MAT3X3: + case F16MAT3X4: + case F16MAT4X2: + case F16MAT4X3: + case F16MAT4X4: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel() || + (parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float) && + parseContext.profile != EEsProfile && parseContext.version >= 450)) + return keyword; + return identifierOrType(); +#endif + + case SAMPLERCUBEARRAY: + case SAMPLERCUBEARRAYSHADOW: + case ISAMPLERCUBEARRAY: + case USAMPLERCUBEARRAY: + afterType = true; + if ((parseContext.profile == EEsProfile && parseContext.version >= 320) || + parseContext.extensionsTurnedOn(Num_AEP_texture_cube_map_array, AEP_texture_cube_map_array)) + return keyword; + if (parseContext.profile == EEsProfile || (parseContext.version < 400 && ! parseContext.extensionTurnedOn(E_GL_ARB_texture_cube_map_array))) + reservedWord(); + return keyword; + + case ISAMPLER1D: + case ISAMPLER1DARRAY: + case USAMPLER1D: + case USAMPLER1DARRAY: + afterType = true; + return es30ReservedFromGLSL(130); + + case UINT: + case UVEC2: + case UVEC3: + case UVEC4: + case SAMPLERCUBESHADOW: + case ISAMPLER2D: + case ISAMPLER3D: + case ISAMPLERCUBE: + case ISAMPLER2DARRAY: + case USAMPLER2D: + case USAMPLER3D: + case USAMPLERCUBE: + case USAMPLER2DARRAY: + afterType = true; + return nonreservedKeyword(300, 130); + + case ISAMPLER2DRECT: + case USAMPLER2DRECT: + afterType = true; + return es30ReservedFromGLSL(140); + + case SAMPLERBUFFER: + afterType = true; + if ((parseContext.profile == EEsProfile && parseContext.version >= 320) || + parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer)) + return keyword; + return es30ReservedFromGLSL(130); + + case ISAMPLERBUFFER: + case USAMPLERBUFFER: + afterType = true; + if ((parseContext.profile == EEsProfile && parseContext.version >= 320) || + parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer)) + return keyword; + return es30ReservedFromGLSL(140); + + case SAMPLER2DMS: + case ISAMPLER2DMS: + case USAMPLER2DMS: + afterType = true; + if (parseContext.profile == EEsProfile && parseContext.version >= 310) + return keyword; + return es30ReservedFromGLSL(150); + + case SAMPLER2DMSARRAY: + case ISAMPLER2DMSARRAY: + case USAMPLER2DMSARRAY: + afterType = true; + if ((parseContext.profile == EEsProfile && parseContext.version >= 320) || + parseContext.extensionsTurnedOn(1, &E_GL_OES_texture_storage_multisample_2d_array)) + return keyword; + return es30ReservedFromGLSL(150); + + case SAMPLER1D: + case SAMPLER1DSHADOW: + afterType = true; + if (parseContext.profile == EEsProfile) + reservedWord(); + return keyword; + + case SAMPLER3D: + afterType = true; + if (parseContext.profile == EEsProfile && parseContext.version < 300) { + if (! parseContext.extensionTurnedOn(E_GL_OES_texture_3D)) + reservedWord(); + } + return keyword; + + case SAMPLER2DSHADOW: + afterType = true; + if (parseContext.profile == EEsProfile && parseContext.version < 300) { + if (!parseContext.extensionTurnedOn(E_GL_EXT_shadow_samplers)) + reservedWord(); + } + return keyword; + + case SAMPLER1DARRAY: + case SAMPLER1DARRAYSHADOW: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel()) + return keyword; + else if (parseContext.profile == EEsProfile) { + if (parseContext.version >= 300) + reservedWord(); + else + return identifierOrType(); + } else if (parseContext.version < 130 && !parseContext.extensionTurnedOn(E_GL_EXT_texture_array)) { + if (parseContext.forwardCompatible) + parseContext.warn(loc, "using future keyword", tokenText, ""); + + return identifierOrType(); + } + return keyword; + + case SAMPLER2DARRAY: + case SAMPLER2DARRAYSHADOW: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel()) + return keyword; + else if (parseContext.version < 130 && ((parseContext.profile == EEsProfile && keyword != SAMPLER2DARRAY) || !parseContext.extensionTurnedOn(E_GL_EXT_texture_array))) { + if (parseContext.forwardCompatible) + parseContext.warn(loc, "using future keyword", tokenText, ""); + + return identifierOrType(); + } + return keyword; + + case SAMPLER2DRECT: + case SAMPLER2DRECTSHADOW: + afterType = true; + if (parseContext.profile == EEsProfile) + reservedWord(); + else if (parseContext.version < 140 && ! parseContext.symbolTable.atBuiltInLevel() && ! parseContext.extensionTurnedOn(E_GL_ARB_texture_rectangle)) { + if (parseContext.relaxedErrors()) + parseContext.requireExtensions(loc, 1, &E_GL_ARB_texture_rectangle, "texture-rectangle sampler keyword"); + else + reservedWord(); + } + return keyword; + + case SAMPLEREXTERNALOES: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel() || + parseContext.extensionTurnedOn(E_GL_OES_EGL_image_external) || + parseContext.extensionTurnedOn(E_GL_OES_EGL_image_external_essl3)) + return keyword; + return identifierOrType(); + + case TEXTURE2D: + case TEXTURECUBE: + case TEXTURECUBEARRAY: + case ITEXTURECUBEARRAY: + case UTEXTURECUBEARRAY: + case ITEXTURE1DARRAY: + case UTEXTURE1D: + case ITEXTURE1D: + case UTEXTURE1DARRAY: + case TEXTUREBUFFER: + case TEXTURE2DARRAY: + case ITEXTURE2D: + case ITEXTURE3D: + case ITEXTURECUBE: + case ITEXTURE2DARRAY: + case UTEXTURE2D: + case UTEXTURE3D: + case UTEXTURECUBE: + case UTEXTURE2DARRAY: + case ITEXTURE2DRECT: + case UTEXTURE2DRECT: + case ITEXTUREBUFFER: + case UTEXTUREBUFFER: + case TEXTURE2DMS: + case ITEXTURE2DMS: + case UTEXTURE2DMS: + case TEXTURE2DMSARRAY: + case ITEXTURE2DMSARRAY: + case UTEXTURE2DMSARRAY: + case TEXTURE1D: + case TEXTURE3D: + case TEXTURE2DRECT: + case TEXTURE1DARRAY: + case SAMPLER: + case SAMPLERSHADOW: + if (parseContext.spvVersion.vulkan >= 100) + return keyword; + else + return identifierOrType(); + + case SUBPASSINPUT: + case SUBPASSINPUTMS: + case ISUBPASSINPUT: + case ISUBPASSINPUTMS: + case USUBPASSINPUT: + case USUBPASSINPUTMS: + if (parseContext.spvVersion.vulkan >= 100) + return keyword; + else + return identifierOrType(); + + case NOPERSPECTIVE: + return es30ReservedFromGLSL(130); + + case SMOOTH: + if ((parseContext.profile == EEsProfile && parseContext.version < 300) || + (parseContext.profile != EEsProfile && parseContext.version < 130)) + return identifierOrType(); + return keyword; + +#ifdef AMD_EXTENSIONS + case __EXPLICITINTERPAMD: + if (parseContext.profile != EEsProfile && parseContext.version >= 450 && + parseContext.extensionTurnedOn(E_GL_AMD_shader_explicit_vertex_parameter)) + return keyword; + return identifierOrType(); +#endif + + case FLAT: + if (parseContext.profile == EEsProfile && parseContext.version < 300) + reservedWord(); + else if (parseContext.profile != EEsProfile && parseContext.version < 130) + return identifierOrType(); + return keyword; + + case CENTROID: + if (parseContext.version < 120) + return identifierOrType(); + return keyword; + + case PRECISE: + if ((parseContext.profile == EEsProfile && + (parseContext.version >= 320 || parseContext.extensionsTurnedOn(Num_AEP_gpu_shader5, AEP_gpu_shader5))) || + (parseContext.profile != EEsProfile && parseContext.version >= 400)) + return keyword; + if (parseContext.profile == EEsProfile && parseContext.version == 310) { + reservedWord(); + return keyword; + } + return identifierOrType(); + + case INVARIANT: + if (parseContext.profile != EEsProfile && parseContext.version < 120) + return identifierOrType(); + return keyword; + + case PACKED: + if ((parseContext.profile == EEsProfile && parseContext.version < 300) || + (parseContext.profile != EEsProfile && parseContext.version < 330)) + return reservedWord(); + return identifierOrType(); + + case RESOURCE: + { + bool reserved = (parseContext.profile == EEsProfile && parseContext.version >= 300) || + (parseContext.profile != EEsProfile && parseContext.version >= 420); + return identifierOrReserved(reserved); + } + case SUPERP: + { + bool reserved = parseContext.profile == EEsProfile || parseContext.version >= 130; + return identifierOrReserved(reserved); + } + + default: + parseContext.infoSink.info.message(EPrefixInternalError, "Unknown glslang keyword", loc); + return 0; + } +} + +int TScanContext::identifierOrType() +{ + parserToken->sType.lex.string = NewPoolTString(tokenText); + if (field) + return IDENTIFIER; + + parserToken->sType.lex.symbol = parseContext.symbolTable.find(*parserToken->sType.lex.string); + if (afterType == false && parserToken->sType.lex.symbol) { + if (const TVariable* variable = parserToken->sType.lex.symbol->getAsVariable()) { + if (variable->isUserType()) { + afterType = true; + + return TYPE_NAME; + } + } + } + + return IDENTIFIER; +} + +// Give an error for use of a reserved symbol. +// However, allow built-in declarations to use reserved words, to allow +// extension support before the extension is enabled. +int TScanContext::reservedWord() +{ + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.error(loc, "Reserved word.", tokenText, "", ""); + + return 0; +} + +int TScanContext::identifierOrReserved(bool reserved) +{ + if (reserved) { + reservedWord(); + + return 0; + } + + if (parseContext.forwardCompatible) + parseContext.warn(loc, "using future reserved keyword", tokenText, ""); + + return identifierOrType(); +} + +// For keywords that suddenly showed up on non-ES (not previously reserved) +// but then got reserved by ES 3.0. +int TScanContext::es30ReservedFromGLSL(int version) +{ + if (parseContext.symbolTable.atBuiltInLevel()) + return keyword; + + if ((parseContext.profile == EEsProfile && parseContext.version < 300) || + (parseContext.profile != EEsProfile && parseContext.version < version)) { + if (parseContext.forwardCompatible) + parseContext.warn(loc, "future reserved word in ES 300 and keyword in GLSL", tokenText, ""); + + return identifierOrType(); + } else if (parseContext.profile == EEsProfile && parseContext.version >= 300) + reservedWord(); + + return keyword; +} + +// For a keyword that was never reserved, until it suddenly +// showed up, both in an es version and a non-ES version. +int TScanContext::nonreservedKeyword(int esVersion, int nonEsVersion) +{ + if ((parseContext.profile == EEsProfile && parseContext.version < esVersion) || + (parseContext.profile != EEsProfile && parseContext.version < nonEsVersion)) { + if (parseContext.forwardCompatible) + parseContext.warn(loc, "using future keyword", tokenText, ""); + + return identifierOrType(); + } + + return keyword; +} + +int TScanContext::precisionKeyword() +{ + if (parseContext.profile == EEsProfile || parseContext.version >= 130) + return keyword; + + if (parseContext.forwardCompatible) + parseContext.warn(loc, "using ES precision qualifier keyword", tokenText, ""); + + return identifierOrType(); +} + +int TScanContext::matNxM() +{ + afterType = true; + + if (parseContext.version > 110) + return keyword; + + if (parseContext.forwardCompatible) + parseContext.warn(loc, "using future non-square matrix type keyword", tokenText, ""); + + return identifierOrType(); +} + +int TScanContext::dMat() +{ + afterType = true; + + if (parseContext.profile == EEsProfile && parseContext.version >= 300) { + reservedWord(); + + return keyword; + } + + if (parseContext.profile != EEsProfile && parseContext.version >= 400) + return keyword; + + if (parseContext.forwardCompatible) + parseContext.warn(loc, "using future type keyword", tokenText, ""); + + return identifierOrType(); +} + +int TScanContext::firstGenerationImage(bool inEs310) +{ + if (parseContext.symbolTable.atBuiltInLevel() || + (parseContext.profile != EEsProfile && (parseContext.version >= 420 || parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store))) || + (inEs310 && parseContext.profile == EEsProfile && parseContext.version >= 310)) + return keyword; + + if ((parseContext.profile == EEsProfile && parseContext.version >= 300) || + (parseContext.profile != EEsProfile && parseContext.version >= 130)) { + reservedWord(); + + return keyword; + } + + if (parseContext.forwardCompatible) + parseContext.warn(loc, "using future type keyword", tokenText, ""); + + return identifierOrType(); +} + +int TScanContext::secondGenerationImage() +{ + if (parseContext.profile == EEsProfile && parseContext.version >= 310) { + reservedWord(); + return keyword; + } + + if (parseContext.symbolTable.atBuiltInLevel() || + (parseContext.profile != EEsProfile && + (parseContext.version >= 420 || parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store)))) + return keyword; + + if (parseContext.forwardCompatible) + parseContext.warn(loc, "using future type keyword", tokenText, ""); + + return identifierOrType(); +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/Scan.h b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/Scan.h new file mode 100644 index 00000000..2c26c2ef --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/Scan.h @@ -0,0 +1,274 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2013 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +#ifndef _GLSLANG_SCAN_INCLUDED_ +#define _GLSLANG_SCAN_INCLUDED_ + +#include "Versions.h" + +namespace glslang { + +// Use a global end-of-input character, so no translation is needed across +// layers of encapsulation. Characters are all 8 bit, and positive, so there is +// no aliasing of character 255 onto -1, for example. +const int EndOfInput = -1; + +// +// A character scanner that seamlessly, on read-only strings, reads across an +// array of strings without assuming null termination. +// +class TInputScanner { +public: + TInputScanner(int n, const char* const s[], size_t L[], const char* const* names = nullptr, + int b = 0, int f = 0, bool single = false) : + numSources(n), + // up to this point, common usage is "char*", but now we need positive 8-bit characters + sources(reinterpret_cast(s)), + lengths(L), currentSource(0), currentChar(0), stringBias(b), finale(f), singleLogical(single), + endOfFileReached(false) + { + loc = new TSourceLoc[numSources]; + for (int i = 0; i < numSources; ++i) { + loc[i].init(i - stringBias); + } + if (names != nullptr) { + for (int i = 0; i < numSources; ++i) + loc[i].name = names[i]; + } + loc[currentSource].line = 1; + logicalSourceLoc.init(1); + logicalSourceLoc.name = loc[0].name; + } + + virtual ~TInputScanner() + { + delete [] loc; + } + + // retrieve the next character and advance one character + int get() + { + int ret = peek(); + if (ret == EndOfInput) + return ret; + ++loc[currentSource].column; + ++logicalSourceLoc.column; + if (ret == '\n') { + ++loc[currentSource].line; + ++logicalSourceLoc.line; + logicalSourceLoc.column = 0; + loc[currentSource].column = 0; + } + advance(); + + return ret; + } + + // retrieve the next character, no advance + int peek() + { + if (currentSource >= numSources) { + endOfFileReached = true; + return EndOfInput; + } + // Make sure we do not read off the end of a string. + // N.B. Sources can have a length of 0. + int sourceToRead = currentSource; + size_t charToRead = currentChar; + while(charToRead >= lengths[sourceToRead]) { + charToRead = 0; + sourceToRead += 1; + if (sourceToRead >= numSources) { + return EndOfInput; + } + } + + // Here, we care about making negative valued characters positive + return sources[sourceToRead][charToRead]; + } + + // go back one character + void unget() + { + // Do not roll back once we've reached the end of the file. + if (endOfFileReached) + return; + + if (currentChar > 0) { + --currentChar; + --loc[currentSource].column; + --logicalSourceLoc.column; + if (loc[currentSource].column < 0) { + // We've moved back past a new line. Find the + // previous newline (or start of the file) to compute + // the column count on the now current line. + size_t chIndex = currentChar; + while (chIndex > 0) { + if (sources[currentSource][chIndex] == '\n') { + break; + } + --chIndex; + } + logicalSourceLoc.column = (int)(currentChar - chIndex); + loc[currentSource].column = (int)(currentChar - chIndex); + } + } else { + do { + --currentSource; + } while (currentSource > 0 && lengths[currentSource] == 0); + if (lengths[currentSource] == 0) { + // set to 0 if we've backed up to the start of an empty string + currentChar = 0; + } else + currentChar = lengths[currentSource] - 1; + } + if (peek() == '\n') { + --loc[currentSource].line; + --logicalSourceLoc.line; + } + } + + // for #line override + void setLine(int newLine) + { + logicalSourceLoc.line = newLine; + loc[getLastValidSourceIndex()].line = newLine; + } + + // for #line override in filename based parsing + void setFile(const char* filename) + { + logicalSourceLoc.name = filename; + loc[getLastValidSourceIndex()].name = filename; + } + + void setFile(const char* filename, int i) + { + if (i == getLastValidSourceIndex()) { + logicalSourceLoc.name = filename; + } + loc[i].name = filename; + } + + void setString(int newString) + { + logicalSourceLoc.string = newString; + loc[getLastValidSourceIndex()].string = newString; + logicalSourceLoc.name = nullptr; + loc[getLastValidSourceIndex()].name = nullptr; + } + + // for #include content indentation + void setColumn(int col) + { + logicalSourceLoc.column = col; + loc[getLastValidSourceIndex()].column = col; + } + + void setEndOfInput() + { + endOfFileReached = true; + currentSource = numSources; + } + + bool atEndOfInput() const { return endOfFileReached; } + + const TSourceLoc& getSourceLoc() const + { + if (singleLogical) { + return logicalSourceLoc; + } else { + return loc[std::max(0, std::min(currentSource, numSources - finale - 1))]; + } + } + // Returns the index (starting from 0) of the most recent valid source string we are reading from. + int getLastValidSourceIndex() const { return std::min(currentSource, numSources - 1); } + + void consumeWhiteSpace(bool& foundNonSpaceTab); + bool consumeComment(); + void consumeWhitespaceComment(bool& foundNonSpaceTab); + bool scanVersion(int& version, EProfile& profile, bool& notFirstToken); + +protected: + + // advance one character + void advance() + { + ++currentChar; + if (currentChar >= lengths[currentSource]) { + ++currentSource; + if (currentSource < numSources) { + loc[currentSource].string = loc[currentSource - 1].string + 1; + loc[currentSource].line = 1; + loc[currentSource].column = 0; + } + while (currentSource < numSources && lengths[currentSource] == 0) { + ++currentSource; + if (currentSource < numSources) { + loc[currentSource].string = loc[currentSource - 1].string + 1; + loc[currentSource].line = 1; + loc[currentSource].column = 0; + } + } + currentChar = 0; + } + } + + int numSources; // number of strings in source + const unsigned char* const *sources; // array of strings; must be converted to positive values on use, to avoid aliasing with -1 as EndOfInput + const size_t *lengths; // length of each string + int currentSource; + size_t currentChar; + + // This is for reporting what string/line an error occurred on, and can be overridden by #line. + // It remembers the last state of each source string as it is left for the next one, so unget() + // can restore that state. + TSourceLoc* loc; // an array + + int stringBias; // the first string that is the user's string number 0 + int finale; // number of internal strings after user's last string + + TSourceLoc logicalSourceLoc; + bool singleLogical; // treats the strings as a single logical string. + // locations will be reported from the first string. + + // Set to true once peek() returns EndOfFile, so that we won't roll back + // once we've reached EndOfFile. + bool endOfFileReached; +}; + +} // end namespace glslang + +#endif // _GLSLANG_SCAN_INCLUDED_ diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/ScanContext.h b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/ScanContext.h new file mode 100644 index 00000000..608ae067 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/ScanContext.h @@ -0,0 +1,88 @@ +// +// Copyright (C) 2013 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +// +// This holds context specific to the GLSL scanner, which +// sits between the preprocessor scanner and parser. +// + +#pragma once + +#include "ParseHelper.h" + +namespace glslang { + +class TPpContext; +class TPpToken; +class TParserToken; + +class TScanContext { +public: + explicit TScanContext(TParseContextBase& pc) : parseContext(pc), afterType(false), field(false) { } + virtual ~TScanContext() { } + + static void fillInKeywordMap(); + static void deleteKeywordMap(); + + int tokenize(TPpContext*, TParserToken&); + +protected: + TScanContext(TScanContext&); + TScanContext& operator=(TScanContext&); + + int tokenizeIdentifier(); + int identifierOrType(); + int reservedWord(); + int identifierOrReserved(bool reserved); + int es30ReservedFromGLSL(int version); + int nonreservedKeyword(int esVersion, int nonEsVersion); + int precisionKeyword(); + int matNxM(); + int dMat(); + int firstGenerationImage(bool inEs310); + int secondGenerationImage(); + + TParseContextBase& parseContext; + bool afterType; // true if we've recognized a type, so can only be looking for an identifier + bool field; // true if we're on a field, right after a '.' + TSourceLoc loc; + TParserToken* parserToken; + TPpToken* ppToken; + + const char* tokenText; + int keyword; +}; + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp new file mode 100644 index 00000000..c92d0239 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp @@ -0,0 +1,1943 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2013-2016 LunarG, Inc. +// Copyright (C) 2015-2017 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +// +// Implement the top-level of interface to the compiler/linker, +// as defined in ShaderLang.h +// This is the platform independent interface between an OGL driver +// and the shading language compiler/linker. +// +#include +#include +#include +#include +#include "SymbolTable.h" +#include "ParseHelper.h" +#include "Scan.h" +#include "ScanContext.h" + +#ifdef ENABLE_HLSL +#include "../../hlsl/hlslParseHelper.h" +#include "../../hlsl/hlslParseables.h" +#include "../../hlsl/hlslScanContext.h" +#endif + +#include "../Include/ShHandle.h" +#include "../../OGLCompilersDLL/InitializeDll.h" + +#include "preprocessor/PpContext.h" + +#define SH_EXPORTING +#include "../Public/ShaderLang.h" +#include "reflection.h" +#include "iomapper.h" +#include "Initialize.h" + +namespace { // anonymous namespace for file-local functions and symbols + +// Total number of successful initializers of glslang: a refcount +// Shared global; access should be protected by a global mutex/critical section. +int NumberOfClients = 0; + +using namespace glslang; + +// Create a language specific version of parseables. +TBuiltInParseables* CreateBuiltInParseables(TInfoSink& infoSink, EShSource source) +{ + switch (source) { + case EShSourceGlsl: return new TBuiltIns(); // GLSL builtIns +#ifdef ENABLE_HLSL + case EShSourceHlsl: return new TBuiltInParseablesHlsl(); // HLSL intrinsics +#endif + + default: + infoSink.info.message(EPrefixInternalError, "Unable to determine source language"); + return nullptr; + } +} + +// Create a language specific version of a parse context. +TParseContextBase* CreateParseContext(TSymbolTable& symbolTable, TIntermediate& intermediate, + int version, EProfile profile, EShSource source, + EShLanguage language, TInfoSink& infoSink, + SpvVersion spvVersion, bool forwardCompatible, EShMessages messages, + bool parsingBuiltIns, std::string sourceEntryPointName = "") +{ + switch (source) { + case EShSourceGlsl: { + if (sourceEntryPointName.size() == 0) + intermediate.setEntryPointName("main"); + TString entryPoint = sourceEntryPointName.c_str(); + return new TParseContext(symbolTable, intermediate, parsingBuiltIns, version, profile, spvVersion, + language, infoSink, forwardCompatible, messages, &entryPoint); + } +#ifdef ENABLE_HLSL + case EShSourceHlsl: + return new HlslParseContext(symbolTable, intermediate, parsingBuiltIns, version, profile, spvVersion, + language, infoSink, sourceEntryPointName.c_str(), forwardCompatible, messages); +#endif + default: + infoSink.info.message(EPrefixInternalError, "Unable to determine source language"); + return nullptr; + } +} + +// Local mapping functions for making arrays of symbol tables.... + +const int VersionCount = 17; // index range in MapVersionToIndex + +int MapVersionToIndex(int version) +{ + int index = 0; + + switch (version) { + case 100: index = 0; break; + case 110: index = 1; break; + case 120: index = 2; break; + case 130: index = 3; break; + case 140: index = 4; break; + case 150: index = 5; break; + case 300: index = 6; break; + case 330: index = 7; break; + case 400: index = 8; break; + case 410: index = 9; break; + case 420: index = 10; break; + case 430: index = 11; break; + case 440: index = 12; break; + case 310: index = 13; break; + case 450: index = 14; break; + case 500: index = 0; break; // HLSL + case 320: index = 15; break; + case 460: index = 16; break; + default: assert(0); break; + } + + assert(index < VersionCount); + + return index; +} + +const int SpvVersionCount = 3; // index range in MapSpvVersionToIndex + +int MapSpvVersionToIndex(const SpvVersion& spvVersion) +{ + int index = 0; + + if (spvVersion.openGl > 0) + index = 1; + else if (spvVersion.vulkan > 0) + index = 2; + + assert(index < SpvVersionCount); + + return index; +} + +const int ProfileCount = 4; // index range in MapProfileToIndex + +int MapProfileToIndex(EProfile profile) +{ + int index = 0; + + switch (profile) { + case ENoProfile: index = 0; break; + case ECoreProfile: index = 1; break; + case ECompatibilityProfile: index = 2; break; + case EEsProfile: index = 3; break; + default: break; + } + + assert(index < ProfileCount); + + return index; +} + +const int SourceCount = 2; + +int MapSourceToIndex(EShSource source) +{ + int index = 0; + + switch (source) { + case EShSourceGlsl: index = 0; break; + case EShSourceHlsl: index = 1; break; + default: break; + } + + assert(index < SourceCount); + + return index; +} + +// only one of these needed for non-ES; ES needs 2 for different precision defaults of built-ins +enum EPrecisionClass { + EPcGeneral, + EPcFragment, + EPcCount +}; + +// A process-global symbol table per version per profile for built-ins common +// to multiple stages (languages), and a process-global symbol table per version +// per profile per stage for built-ins unique to each stage. They will be sparsely +// populated, so they will only be generated as needed. +// +// Each has a different set of built-ins, and we want to preserve that from +// compile to compile. +// +TSymbolTable* CommonSymbolTable[VersionCount][SpvVersionCount][ProfileCount][SourceCount][EPcCount] = {}; +TSymbolTable* SharedSymbolTables[VersionCount][SpvVersionCount][ProfileCount][SourceCount][EShLangCount] = {}; + +TPoolAllocator* PerProcessGPA = nullptr; + +// +// Parse and add to the given symbol table the content of the given shader string. +// +bool InitializeSymbolTable(const TString& builtIns, int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, + EShSource source, TInfoSink& infoSink, TSymbolTable& symbolTable) +{ + TIntermediate intermediate(language, version, profile); + + intermediate.setSource(source); + + std::unique_ptr parseContext(CreateParseContext(symbolTable, intermediate, version, profile, source, + language, infoSink, spvVersion, true, EShMsgDefault, + true)); + + TShader::ForbidIncluder includer; + TPpContext ppContext(*parseContext, "", includer); + TScanContext scanContext(*parseContext); + parseContext->setScanContext(&scanContext); + parseContext->setPpContext(&ppContext); + + // + // Push the symbol table to give it an initial scope. This + // push should not have a corresponding pop, so that built-ins + // are preserved, and the test for an empty table fails. + // + + symbolTable.push(); + + const char* builtInShaders[2]; + size_t builtInLengths[2]; + builtInShaders[0] = builtIns.c_str(); + builtInLengths[0] = builtIns.size(); + + if (builtInLengths[0] == 0) + return true; + + TInputScanner input(1, builtInShaders, builtInLengths); + if (! parseContext->parseShaderStrings(ppContext, input) != 0) { + infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins"); + printf("Unable to parse built-ins\n%s\n", infoSink.info.c_str()); + printf("%s\n", builtInShaders[0]); + + return false; + } + + return true; +} + +int CommonIndex(EProfile profile, EShLanguage language) +{ + return (profile == EEsProfile && language == EShLangFragment) ? EPcFragment : EPcGeneral; +} + +// +// To initialize per-stage shared tables, with the common table already complete. +// +void InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int version, EProfile profile, const SpvVersion& spvVersion, + EShLanguage language, EShSource source, TInfoSink& infoSink, TSymbolTable** commonTable, + TSymbolTable** symbolTables) +{ + (*symbolTables[language]).adoptLevels(*commonTable[CommonIndex(profile, language)]); + InitializeSymbolTable(builtInParseables.getStageString(language), version, profile, spvVersion, language, source, + infoSink, *symbolTables[language]); + builtInParseables.identifyBuiltIns(version, profile, spvVersion, language, *symbolTables[language]); + if (profile == EEsProfile && version >= 300) + (*symbolTables[language]).setNoBuiltInRedeclarations(); + if (version == 110) + (*symbolTables[language]).setSeparateNameSpaces(); +} + +// +// Initialize the full set of shareable symbol tables; +// The common (cross-stage) and those shareable per-stage. +// +bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TSymbolTable** symbolTables, int version, EProfile profile, const SpvVersion& spvVersion, EShSource source) +{ + std::unique_ptr builtInParseables(CreateBuiltInParseables(infoSink, source)); + + if (builtInParseables == nullptr) + return false; + + builtInParseables->initialize(version, profile, spvVersion); + + // do the common tables + InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, EShLangVertex, source, + infoSink, *commonTable[EPcGeneral]); + if (profile == EEsProfile) + InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, EShLangFragment, source, + infoSink, *commonTable[EPcFragment]); + + // do the per-stage tables + + // always have vertex and fragment + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangVertex, source, + infoSink, commonTable, symbolTables); + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangFragment, source, + infoSink, commonTable, symbolTables); + + // check for tessellation + if ((profile != EEsProfile && version >= 150) || + (profile == EEsProfile && version >= 310)) { + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTessControl, source, + infoSink, commonTable, symbolTables); + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTessEvaluation, source, + infoSink, commonTable, symbolTables); + } + + // check for geometry + if ((profile != EEsProfile && version >= 150) || + (profile == EEsProfile && version >= 310)) + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangGeometry, source, + infoSink, commonTable, symbolTables); + + // check for compute + if ((profile != EEsProfile && version >= 420) || + (profile == EEsProfile && version >= 310)) + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCompute, source, + infoSink, commonTable, symbolTables); + + return true; +} + +bool AddContextSpecificSymbols(const TBuiltInResource* resources, TInfoSink& infoSink, TSymbolTable& symbolTable, int version, + EProfile profile, const SpvVersion& spvVersion, EShLanguage language, EShSource source) +{ + std::unique_ptr builtInParseables(CreateBuiltInParseables(infoSink, source)); + + if (builtInParseables == nullptr) + return false; + + builtInParseables->initialize(*resources, version, profile, spvVersion, language); + InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, language, source, infoSink, symbolTable); + builtInParseables->identifyBuiltIns(version, profile, spvVersion, language, symbolTable, *resources); + + return true; +} + +// +// To do this on the fly, we want to leave the current state of our thread's +// pool allocator intact, so: +// - Switch to a new pool for parsing the built-ins +// - Do the parsing, which builds the symbol table, using the new pool +// - Switch to the process-global pool to save a copy of the resulting symbol table +// - Free up the new pool used to parse the built-ins +// - Switch back to the original thread's pool +// +// This only gets done the first time any thread needs a particular symbol table +// (lazy evaluation). +// +void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& spvVersion, EShSource source) +{ + TInfoSink infoSink; + + // Make sure only one thread tries to do this at a time + glslang::GetGlobalLock(); + + // See if it's already been done for this version/profile combination + int versionIndex = MapVersionToIndex(version); + int spvVersionIndex = MapSpvVersionToIndex(spvVersion); + int profileIndex = MapProfileToIndex(profile); + int sourceIndex = MapSourceToIndex(source); + if (CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][sourceIndex][EPcGeneral]) { + glslang::ReleaseGlobalLock(); + + return; + } + + // Switch to a new pool + TPoolAllocator& previousAllocator = GetThreadPoolAllocator(); + TPoolAllocator* builtInPoolAllocator = new TPoolAllocator; + SetThreadPoolAllocator(builtInPoolAllocator); + + // Dynamically allocate the local symbol tables so we can control when they are deallocated WRT when the pool is popped. + TSymbolTable* commonTable[EPcCount]; + TSymbolTable* stageTables[EShLangCount]; + for (int precClass = 0; precClass < EPcCount; ++precClass) + commonTable[precClass] = new TSymbolTable; + for (int stage = 0; stage < EShLangCount; ++stage) + stageTables[stage] = new TSymbolTable; + + // Generate the local symbol tables using the new pool + InitializeSymbolTables(infoSink, commonTable, stageTables, version, profile, spvVersion, source); + + // Switch to the process-global pool + SetThreadPoolAllocator(PerProcessGPA); + + // Copy the local symbol tables from the new pool to the global tables using the process-global pool + for (int precClass = 0; precClass < EPcCount; ++precClass) { + if (! commonTable[precClass]->isEmpty()) { + CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][sourceIndex][precClass] = new TSymbolTable; + CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][sourceIndex][precClass]->copyTable(*commonTable[precClass]); + CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][sourceIndex][precClass]->readOnly(); + } + } + for (int stage = 0; stage < EShLangCount; ++stage) { + if (! stageTables[stage]->isEmpty()) { + SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][sourceIndex][stage] = new TSymbolTable; + SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][sourceIndex][stage]->adoptLevels(*CommonSymbolTable + [versionIndex][spvVersionIndex][profileIndex][sourceIndex][CommonIndex(profile, (EShLanguage)stage)]); + SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][sourceIndex][stage]->copyTable(*stageTables[stage]); + SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][sourceIndex][stage]->readOnly(); + } + } + + // Clean up the local tables before deleting the pool they used. + for (int precClass = 0; precClass < EPcCount; ++precClass) + delete commonTable[precClass]; + for (int stage = 0; stage < EShLangCount; ++stage) + delete stageTables[stage]; + + delete builtInPoolAllocator; + SetThreadPoolAllocator(&previousAllocator); + + glslang::ReleaseGlobalLock(); +} + +// Return true if the shader was correctly specified for version/profile/stage. +bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNotFirst, int defaultVersion, + EShSource source, int& version, EProfile& profile, const SpvVersion& spvVersion) +{ + const int FirstProfileVersion = 150; + bool correct = true; + + if (source == EShSourceHlsl) { + version = 500; // shader model; currently a characteristic of glslang, not the input + profile = ECoreProfile; // allow doubles in prototype parsing + return correct; + } + + // Get a version... + if (version == 0) { + version = defaultVersion; + // infoSink.info.message(EPrefixWarning, "#version: statement missing; use #version on first line of shader"); + } + + // Get a good profile... + if (profile == ENoProfile) { + if (version == 300 || version == 310 || version == 320) { + correct = false; + infoSink.info.message(EPrefixError, "#version: versions 300, 310, and 320 require specifying the 'es' profile"); + profile = EEsProfile; + } else if (version == 100) + profile = EEsProfile; + else if (version >= FirstProfileVersion) + profile = ECoreProfile; + else + profile = ENoProfile; + } else { + // a profile was provided... + if (version < 150) { + correct = false; + infoSink.info.message(EPrefixError, "#version: versions before 150 do not allow a profile token"); + if (version == 100) + profile = EEsProfile; + else + profile = ENoProfile; + } else if (version == 300 || version == 310 || version == 320) { + if (profile != EEsProfile) { + correct = false; + infoSink.info.message(EPrefixError, "#version: versions 300, 310, and 320 support only the es profile"); + } + profile = EEsProfile; + } else { + if (profile == EEsProfile) { + correct = false; + infoSink.info.message(EPrefixError, "#version: only version 300, 310, and 320 support the es profile"); + if (version >= FirstProfileVersion) + profile = ECoreProfile; + else + profile = ENoProfile; + } + // else: typical desktop case... e.g., "#version 410 core" + } + } + + // Fix version... + switch (version) { + // ES versions + case 100: break; + case 300: break; + case 310: break; + case 320: break; + + // desktop versions + case 110: break; + case 120: break; + case 130: break; + case 140: break; + case 150: break; + case 330: break; + case 400: break; + case 410: break; + case 420: break; + case 430: break; + case 440: break; + case 450: break; + case 460: break; + + // unknown version + default: + correct = false; + infoSink.info.message(EPrefixError, "version not supported"); + if (profile == EEsProfile) + version = 310; + else { + version = 450; + profile = ECoreProfile; + } + break; + } + + // Correct for stage type... + switch (stage) { + case EShLangGeometry: + if ((profile == EEsProfile && version < 310) || + (profile != EEsProfile && version < 150)) { + correct = false; + infoSink.info.message(EPrefixError, "#version: geometry shaders require es profile with version 310 or non-es profile with version 150 or above"); + version = (profile == EEsProfile) ? 310 : 150; + if (profile == EEsProfile || profile == ENoProfile) + profile = ECoreProfile; + } + break; + case EShLangTessControl: + case EShLangTessEvaluation: + if ((profile == EEsProfile && version < 310) || + (profile != EEsProfile && version < 150)) { + correct = false; + infoSink.info.message(EPrefixError, "#version: tessellation shaders require es profile with version 310 or non-es profile with version 150 or above"); + version = (profile == EEsProfile) ? 310 : 400; // 150 supports the extension, correction is to 400 which does not + if (profile == EEsProfile || profile == ENoProfile) + profile = ECoreProfile; + } + break; + case EShLangCompute: + if ((profile == EEsProfile && version < 310) || + (profile != EEsProfile && version < 420)) { + correct = false; + infoSink.info.message(EPrefixError, "#version: compute shaders require es profile with version 310 or above, or non-es profile with version 420 or above"); + version = profile == EEsProfile ? 310 : 420; + } + break; + default: + break; + } + + if (profile == EEsProfile && version >= 300 && versionNotFirst) { + correct = false; + infoSink.info.message(EPrefixError, "#version: statement must appear first in es-profile shader; before comments or newlines"); + } + + // Check for SPIR-V compatibility + if (spvVersion.spv != 0) { + switch (profile) { + case EEsProfile: + if (spvVersion.vulkan >= 100 && version < 310) { + correct = false; + infoSink.info.message(EPrefixError, "#version: ES shaders for Vulkan SPIR-V require version 310 or higher"); + version = 310; + } + if (spvVersion.openGl >= 100) { + correct = false; + infoSink.info.message(EPrefixError, "#version: ES shaders for OpenGL SPIR-V are not supported"); + version = 310; + } + break; + case ECompatibilityProfile: + infoSink.info.message(EPrefixError, "#version: compilation for SPIR-V does not support the compatibility profile"); + break; + default: + if (spvVersion.vulkan >= 100 && version < 140) { + correct = false; + infoSink.info.message(EPrefixError, "#version: Desktop shaders for Vulkan SPIR-V require version 140 or higher"); + version = 140; + } + if (spvVersion.openGl >= 100 && version < 330) { + correct = false; + infoSink.info.message(EPrefixError, "#version: Desktop shaders for OpenGL SPIR-V require version 330 or higher"); + version = 330; + } + break; + } + } + + return correct; +} + +// There are multiple paths in for setting environment stuff. +// TEnvironment takes precedence, for what it sets, so sort all this out. +// Ideally, the internal code could be made to use TEnvironment, but for +// now, translate it to the historically used parameters. +void TranslateEnvironment(const TEnvironment* environment, EShMessages& messages, EShSource& source, + EShLanguage& stage, SpvVersion& spvVersion) +{ + // Set up environmental defaults, first ignoring 'environment'. + if (messages & EShMsgSpvRules) + spvVersion.spv = 0x00010000; + if (messages & EShMsgVulkanRules) { + spvVersion.vulkan = 100; + spvVersion.vulkanGlsl = 100; + } else if (spvVersion.spv != 0) + spvVersion.openGl = 100; + + // Now, override, based on any content set in 'environment'. + // 'environment' must be cleared to ESh*None settings when items + // are not being set. + if (environment != nullptr) { + // input language + if (environment->input.languageFamily != EShSourceNone) { + stage = environment->input.stage; + switch (environment->input.dialect) { + case EShClientNone: + break; + case EShClientVulkan: + spvVersion.vulkanGlsl = environment->input.dialectVersion; + break; + case EShClientOpenGL: + spvVersion.openGl = environment->input.dialectVersion; + break; + } + switch (environment->input.languageFamily) { + case EShSourceNone: + break; + case EShSourceGlsl: + source = EShSourceGlsl; + messages = static_cast(messages & ~EShMsgReadHlsl); + break; + case EShSourceHlsl: + source = EShSourceHlsl; + messages = static_cast(messages | EShMsgReadHlsl); + break; + } + } + + // client + switch (environment->client.client) { + case EShClientVulkan: + spvVersion.vulkan = environment->client.version; + break; + default: + break; + } + + // generated code + switch (environment->target.language) { + case EshTargetSpv: + spvVersion.spv = environment->target.version; + break; + default: + break; + } + } +} + +// Most processes are recorded when set in the intermediate representation, +// These are the few that are not. +void RecordProcesses(TIntermediate& intermediate, EShMessages messages, const std::string& sourceEntryPointName) +{ + if ((messages & EShMsgRelaxedErrors) != 0) + intermediate.addProcess("relaxed-errors"); + if ((messages & EShMsgSuppressWarnings) != 0) + intermediate.addProcess("suppress-warnings"); + if ((messages & EShMsgKeepUncalled) != 0) + intermediate.addProcess("keep-uncalled"); + if (sourceEntryPointName.size() > 0) { + intermediate.addProcess("source-entrypoint"); + intermediate.addProcessArgument(sourceEntryPointName); + } +} + +// This is the common setup and cleanup code for PreprocessDeferred and +// CompileDeferred. +// It takes any callable with a signature of +// bool (TParseContextBase& parseContext, TPpContext& ppContext, +// TInputScanner& input, bool versionWillBeError, +// TSymbolTable& , TIntermediate& , +// EShOptimizationLevel , EShMessages ); +// Which returns false if a failure was detected and true otherwise. +// +template +bool ProcessDeferred( + TCompiler* compiler, + const char* const shaderStrings[], + const int numStrings, + const int* inputLengths, + const char* const stringNames[], + const char* customPreamble, + const EShOptimizationLevel optLevel, + const TBuiltInResource* resources, + int defaultVersion, // use 100 for ES environment, 110 for desktop; this is the GLSL version, not SPIR-V or Vulkan + EProfile defaultProfile, + // set version/profile to defaultVersion/defaultProfile regardless of the #version + // directive in the source code + bool forceDefaultVersionAndProfile, + bool forwardCompatible, // give errors for use of deprecated features + EShMessages messages, // warnings/errors/AST; things to print out + TIntermediate& intermediate, // returned tree, etc. + ProcessingContext& processingContext, + bool requireNonempty, + TShader::Includer& includer, + const std::string sourceEntryPointName = "", + const TEnvironment* environment = nullptr) // optional way of fully setting all versions, overriding the above +{ + // This must be undone (.pop()) by the caller, after it finishes consuming the created tree. + GetThreadPoolAllocator().push(); + + if (numStrings == 0) + return true; + + // Move to length-based strings, rather than null-terminated strings. + // Also, add strings to include the preamble and to ensure the shader is not null, + // which lets the grammar accept what was a null (post preprocessing) shader. + // + // Shader will look like + // string 0: system preamble + // string 1: custom preamble + // string 2...numStrings+1: user's shader + // string numStrings+2: "int;" + const int numPre = 2; + const int numPost = requireNonempty? 1 : 0; + const int numTotal = numPre + numStrings + numPost; + size_t* lengths = new size_t[numTotal]; + const char** strings = new const char*[numTotal]; + const char** names = new const char*[numTotal]; + for (int s = 0; s < numStrings; ++s) { + strings[s + numPre] = shaderStrings[s]; + if (inputLengths == nullptr || inputLengths[s] < 0) + lengths[s + numPre] = strlen(shaderStrings[s]); + else + lengths[s + numPre] = inputLengths[s]; + } + if (stringNames != nullptr) { + for (int s = 0; s < numStrings; ++s) + names[s + numPre] = stringNames[s]; + } else { + for (int s = 0; s < numStrings; ++s) + names[s + numPre] = nullptr; + } + + // Get all the stages, languages, clients, and other environment + // stuff sorted out. + EShSource source = (messages & EShMsgReadHlsl) != 0 ? EShSourceHlsl : EShSourceGlsl; + SpvVersion spvVersion; + EShLanguage stage = compiler->getLanguage(); + TranslateEnvironment(environment, messages, source, stage, spvVersion); + + // First, without using the preprocessor or parser, find the #version, so we know what + // symbol tables, processing rules, etc. to set up. This does not need the extra strings + // outlined above, just the user shader, after the system and user preambles. + glslang::TInputScanner userInput(numStrings, &strings[numPre], &lengths[numPre]); + int version = 0; + EProfile profile = ENoProfile; + bool versionNotFirstToken = false; + bool versionNotFirst = (source == EShSourceHlsl) + ? true + : userInput.scanVersion(version, profile, versionNotFirstToken); + bool versionNotFound = version == 0; + if (forceDefaultVersionAndProfile && source == EShSourceGlsl) { + if (! (messages & EShMsgSuppressWarnings) && ! versionNotFound && + (version != defaultVersion || profile != defaultProfile)) { + compiler->infoSink.info << "Warning, (version, profile) forced to be (" + << defaultVersion << ", " << ProfileName(defaultProfile) + << "), while in source code it is (" + << version << ", " << ProfileName(profile) << ")\n"; + } + + if (versionNotFound) { + versionNotFirstToken = false; + versionNotFirst = false; + versionNotFound = false; + } + version = defaultVersion; + profile = defaultProfile; + } + + bool goodVersion = DeduceVersionProfile(compiler->infoSink, stage, + versionNotFirst, defaultVersion, source, version, profile, spvVersion); + bool versionWillBeError = (versionNotFound || (profile == EEsProfile && version >= 300 && versionNotFirst)); + bool warnVersionNotFirst = false; + if (! versionWillBeError && versionNotFirstToken) { + if (messages & EShMsgRelaxedErrors) + warnVersionNotFirst = true; + else + versionWillBeError = true; + } + + intermediate.setSource(source); + intermediate.setVersion(version); + intermediate.setProfile(profile); + intermediate.setSpv(spvVersion); + RecordProcesses(intermediate, messages, sourceEntryPointName); + if (spvVersion.vulkan >= 100) + intermediate.setOriginUpperLeft(); + if ((messages & EShMsgHlslOffsets) || source == EShSourceHlsl) + intermediate.setHlslOffsets(); + if (messages & EShMsgDebugInfo) { + intermediate.setSourceFile(names[numPre]); + for (int s = 0; s < numStrings; ++s) + intermediate.addSourceText(strings[numPre + s]); + } + SetupBuiltinSymbolTable(version, profile, spvVersion, source); + + TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)] + [MapSpvVersionToIndex(spvVersion)] + [MapProfileToIndex(profile)] + [MapSourceToIndex(source)] + [stage]; + + // Dynamically allocate the symbol table so we can control when it is deallocated WRT the pool. + TSymbolTable* symbolTableMemory = new TSymbolTable; + TSymbolTable& symbolTable = *symbolTableMemory; + if (cachedTable) + symbolTable.adoptLevels(*cachedTable); + + // Add built-in symbols that are potentially context dependent; + // they get popped again further down. + if (! AddContextSpecificSymbols(resources, compiler->infoSink, symbolTable, version, profile, spvVersion, + stage, source)) + return false; + + // + // Now we can process the full shader under proper symbols and rules. + // + + TParseContextBase* parseContext = CreateParseContext(symbolTable, intermediate, version, profile, source, + stage, compiler->infoSink, + spvVersion, forwardCompatible, messages, false, sourceEntryPointName); + + TPpContext ppContext(*parseContext, names[numPre] ? names[numPre] : "", includer); + + // only GLSL (bison triggered, really) needs an externally set scan context + glslang::TScanContext scanContext(*parseContext); + if (source == EShSourceGlsl) + parseContext->setScanContext(&scanContext); + + parseContext->setPpContext(&ppContext); + parseContext->setLimits(*resources); + if (! goodVersion) + parseContext->addError(); + if (warnVersionNotFirst) { + TSourceLoc loc; + loc.init(); + parseContext->warn(loc, "Illegal to have non-comment, non-whitespace tokens before #version", "#version", ""); + } + + parseContext->initializeExtensionBehavior(); + + // Fill in the strings as outlined above. + std::string preamble; + parseContext->getPreamble(preamble); + strings[0] = preamble.c_str(); + lengths[0] = strlen(strings[0]); + names[0] = nullptr; + strings[1] = customPreamble; + lengths[1] = strlen(strings[1]); + names[1] = nullptr; + assert(2 == numPre); + if (requireNonempty) { + const int postIndex = numStrings + numPre; + strings[postIndex] = "\n int;"; + lengths[postIndex] = strlen(strings[numStrings + numPre]); + names[postIndex] = nullptr; + } + TInputScanner fullInput(numStrings + numPre + numPost, strings, lengths, names, numPre, numPost); + + // Push a new symbol allocation scope that will get used for the shader's globals. + symbolTable.push(); + + bool success = processingContext(*parseContext, ppContext, fullInput, + versionWillBeError, symbolTable, + intermediate, optLevel, messages); + + // Clean up the symbol table. The AST is self-sufficient now. + delete symbolTableMemory; + + delete parseContext; + delete [] lengths; + delete [] strings; + delete [] names; + + return success; +} + +// Responsible for keeping track of the most recent source string and line in +// the preprocessor and outputting newlines appropriately if the source string +// or line changes. +class SourceLineSynchronizer { +public: + SourceLineSynchronizer(const std::function& lastSourceIndex, + std::stringstream* output) + : getLastSourceIndex(lastSourceIndex), output(output), lastSource(-1), lastLine(0) {} +// SourceLineSynchronizer(const SourceLineSynchronizer&) = delete; +// SourceLineSynchronizer& operator=(const SourceLineSynchronizer&) = delete; + + // Sets the internally tracked source string index to that of the most + // recently read token. If we switched to a new source string, returns + // true and inserts a newline. Otherwise, returns false and outputs nothing. + bool syncToMostRecentString() { + if (getLastSourceIndex() != lastSource) { + // After switching to a new source string, we need to reset lastLine + // because line number resets every time a new source string is + // used. We also need to output a newline to separate the output + // from the previous source string (if there is one). + if (lastSource != -1 || lastLine != 0) + *output << std::endl; + lastSource = getLastSourceIndex(); + lastLine = -1; + return true; + } + return false; + } + + // Calls syncToMostRecentString() and then sets the internally tracked line + // number to tokenLine. If we switched to a new line, returns true and inserts + // newlines appropriately. Otherwise, returns false and outputs nothing. + bool syncToLine(int tokenLine) { + syncToMostRecentString(); + const bool newLineStarted = lastLine < tokenLine; + for (; lastLine < tokenLine; ++lastLine) { + if (lastLine > 0) *output << std::endl; + } + return newLineStarted; + } + + // Sets the internally tracked line number to newLineNum. + void setLineNum(int newLineNum) { lastLine = newLineNum; } + +private: + SourceLineSynchronizer& operator=(const SourceLineSynchronizer&); + + // A function for getting the index of the last valid source string we've + // read tokens from. + const std::function getLastSourceIndex; + // output stream for newlines. + std::stringstream* output; + // lastSource is the source string index (starting from 0) of the last token + // processed. It is tracked in order for newlines to be inserted when a new + // source string starts. -1 means we haven't started processing any source + // string. + int lastSource; + // lastLine is the line number (starting from 1) of the last token processed. + // It is tracked in order for newlines to be inserted when a token appears + // on a new line. 0 means we haven't started processing any line in the + // current source string. + int lastLine; +}; + +// DoPreprocessing is a valid ProcessingContext template argument, +// which only performs the preprocessing step of compilation. +// It places the result in the "string" argument to its constructor. +struct DoPreprocessing { + explicit DoPreprocessing(std::string* string): outputString(string) {} + bool operator()(TParseContextBase& parseContext, TPpContext& ppContext, + TInputScanner& input, bool versionWillBeError, + TSymbolTable&, TIntermediate&, + EShOptimizationLevel, EShMessages) + { + // This is a list of tokens that do not require a space before or after. + static const std::string unNeededSpaceTokens = ";()[]"; + static const std::string noSpaceBeforeTokens = ","; + glslang::TPpToken ppToken; + + parseContext.setScanner(&input); + ppContext.setInput(input, versionWillBeError); + + std::stringstream outputStream; + SourceLineSynchronizer lineSync( + std::bind(&TInputScanner::getLastValidSourceIndex, &input), &outputStream); + + parseContext.setExtensionCallback([&lineSync, &outputStream]( + int line, const char* extension, const char* behavior) { + lineSync.syncToLine(line); + outputStream << "#extension " << extension << " : " << behavior; + }); + + parseContext.setLineCallback([&lineSync, &outputStream, &parseContext]( + int curLineNum, int newLineNum, bool hasSource, int sourceNum, const char* sourceName) { + // SourceNum is the number of the source-string that is being parsed. + lineSync.syncToLine(curLineNum); + outputStream << "#line " << newLineNum; + if (hasSource) { + outputStream << " "; + if (sourceName != nullptr) { + outputStream << "\"" << sourceName << "\""; + } else { + outputStream << sourceNum; + } + } + if (parseContext.lineDirectiveShouldSetNextLine()) { + // newLineNum is the new line number for the line following the #line + // directive. So the new line number for the current line is + newLineNum -= 1; + } + outputStream << std::endl; + // And we are at the next line of the #line directive now. + lineSync.setLineNum(newLineNum + 1); + }); + + parseContext.setVersionCallback( + [&lineSync, &outputStream](int line, int version, const char* str) { + lineSync.syncToLine(line); + outputStream << "#version " << version; + if (str) { + outputStream << " " << str; + } + }); + + parseContext.setPragmaCallback([&lineSync, &outputStream]( + int line, const glslang::TVector& ops) { + lineSync.syncToLine(line); + outputStream << "#pragma "; + for(size_t i = 0; i < ops.size(); ++i) { + outputStream << ops[i]; + } + }); + + parseContext.setErrorCallback([&lineSync, &outputStream]( + int line, const char* errorMessage) { + lineSync.syncToLine(line); + outputStream << "#error " << errorMessage; + }); + + int lastToken = EndOfInput; // lastToken records the last token processed. + do { + int token = ppContext.tokenize(ppToken); + if (token == EndOfInput) + break; + + bool isNewString = lineSync.syncToMostRecentString(); + bool isNewLine = lineSync.syncToLine(ppToken.loc.line); + + if (isNewLine) { + // Don't emit whitespace onto empty lines. + // Copy any whitespace characters at the start of a line + // from the input to the output. + outputStream << std::string(ppToken.loc.column - 1, ' '); + } + + // Output a space in between tokens, but not at the start of a line, + // and also not around special tokens. This helps with readability + // and consistency. + if (!isNewString && !isNewLine && lastToken != EndOfInput && + (unNeededSpaceTokens.find((char)token) == std::string::npos) && + (unNeededSpaceTokens.find((char)lastToken) == std::string::npos) && + (noSpaceBeforeTokens.find((char)token) == std::string::npos)) { + outputStream << " "; + } + lastToken = token; + outputStream << ppToken.name; + } while (true); + outputStream << std::endl; + *outputString = outputStream.str(); + + bool success = true; + if (parseContext.getNumErrors() > 0) { + success = false; + parseContext.infoSink.info.prefix(EPrefixError); + parseContext.infoSink.info << parseContext.getNumErrors() << " compilation errors. No code generated.\n\n"; + } + return success; + } + std::string* outputString; +}; + +// DoFullParse is a valid ProcessingConext template argument for fully +// parsing the shader. It populates the "intermediate" with the AST. +struct DoFullParse{ + bool operator()(TParseContextBase& parseContext, TPpContext& ppContext, + TInputScanner& fullInput, bool versionWillBeError, + TSymbolTable&, TIntermediate& intermediate, + EShOptimizationLevel optLevel, EShMessages messages) + { + bool success = true; + // Parse the full shader. + if (! parseContext.parseShaderStrings(ppContext, fullInput, versionWillBeError)) + success = false; + + if (success && intermediate.getTreeRoot()) { + if (optLevel == EShOptNoGeneration) + parseContext.infoSink.info.message(EPrefixNone, "No errors. No code generation or linking was requested."); + else + success = intermediate.postProcess(intermediate.getTreeRoot(), parseContext.getLanguage()); + } else if (! success) { + parseContext.infoSink.info.prefix(EPrefixError); + parseContext.infoSink.info << parseContext.getNumErrors() << " compilation errors. No code generated.\n\n"; + } + + if (messages & EShMsgAST) + intermediate.output(parseContext.infoSink, true); + + return success; + } +}; + +// Take a single compilation unit, and run the preprocessor on it. +// Return: True if there were no issues found in preprocessing, +// False if during preprocessing any unknown version, pragmas or +// extensions were found. +bool PreprocessDeferred( + TCompiler* compiler, + const char* const shaderStrings[], + const int numStrings, + const int* inputLengths, + const char* const stringNames[], + const char* preamble, + const EShOptimizationLevel optLevel, + const TBuiltInResource* resources, + int defaultVersion, // use 100 for ES environment, 110 for desktop + EProfile defaultProfile, + bool forceDefaultVersionAndProfile, + bool forwardCompatible, // give errors for use of deprecated features + EShMessages messages, // warnings/errors/AST; things to print out + TShader::Includer& includer, + TIntermediate& intermediate, // returned tree, etc. + std::string* outputString) +{ + DoPreprocessing parser(outputString); + return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames, + preamble, optLevel, resources, defaultVersion, + defaultProfile, forceDefaultVersionAndProfile, + forwardCompatible, messages, intermediate, parser, + false, includer); +} + +// +// do a partial compile on the given strings for a single compilation unit +// for a potential deferred link into a single stage (and deferred full compile of that +// stage through machine-dependent compilation). +// +// all preprocessing, parsing, semantic checks, etc. for a single compilation unit +// are done here. +// +// return: the tree and other information is filled into the intermediate argument, +// and true is returned by the function for success. +// +bool CompileDeferred( + TCompiler* compiler, + const char* const shaderStrings[], + const int numStrings, + const int* inputLengths, + const char* const stringNames[], + const char* preamble, + const EShOptimizationLevel optLevel, + const TBuiltInResource* resources, + int defaultVersion, // use 100 for ES environment, 110 for desktop + EProfile defaultProfile, + bool forceDefaultVersionAndProfile, + bool forwardCompatible, // give errors for use of deprecated features + EShMessages messages, // warnings/errors/AST; things to print out + TIntermediate& intermediate,// returned tree, etc. + TShader::Includer& includer, + const std::string sourceEntryPointName = "", + TEnvironment* environment = nullptr) +{ + DoFullParse parser; + return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames, + preamble, optLevel, resources, defaultVersion, + defaultProfile, forceDefaultVersionAndProfile, + forwardCompatible, messages, intermediate, parser, + true, includer, sourceEntryPointName, environment); +} + +} // end anonymous namespace for local functions + +// +// ShInitialize() should be called exactly once per process, not per thread. +// +int ShInitialize() +{ + glslang::InitGlobalLock(); + + if (! InitProcess()) + return 0; + + glslang::GetGlobalLock(); + ++NumberOfClients; + glslang::ReleaseGlobalLock(); + + if (PerProcessGPA == nullptr) + PerProcessGPA = new TPoolAllocator(); + + glslang::TScanContext::fillInKeywordMap(); +#ifdef ENABLE_HLSL + glslang::HlslScanContext::fillInKeywordMap(); +#endif + + return 1; +} + +// +// Driver calls these to create and destroy compiler/linker +// objects. +// + +ShHandle ShConstructCompiler(const EShLanguage language, int debugOptions) +{ + if (!InitThread()) + return 0; + + TShHandleBase* base = static_cast(ConstructCompiler(language, debugOptions)); + + return reinterpret_cast(base); +} + +ShHandle ShConstructLinker(const EShExecutable executable, int debugOptions) +{ + if (!InitThread()) + return 0; + + TShHandleBase* base = static_cast(ConstructLinker(executable, debugOptions)); + + return reinterpret_cast(base); +} + +ShHandle ShConstructUniformMap() +{ + if (!InitThread()) + return 0; + + TShHandleBase* base = static_cast(ConstructUniformMap()); + + return reinterpret_cast(base); +} + +void ShDestruct(ShHandle handle) +{ + if (handle == 0) + return; + + TShHandleBase* base = static_cast(handle); + + if (base->getAsCompiler()) + DeleteCompiler(base->getAsCompiler()); + else if (base->getAsLinker()) + DeleteLinker(base->getAsLinker()); + else if (base->getAsUniformMap()) + DeleteUniformMap(base->getAsUniformMap()); +} + +// +// Cleanup symbol tables +// +int __fastcall ShFinalize() +{ + glslang::GetGlobalLock(); + --NumberOfClients; + assert(NumberOfClients >= 0); + bool finalize = NumberOfClients == 0; + glslang::ReleaseGlobalLock(); + if (! finalize) + return 1; + + for (int version = 0; version < VersionCount; ++version) { + for (int spvVersion = 0; spvVersion < SpvVersionCount; ++spvVersion) { + for (int p = 0; p < ProfileCount; ++p) { + for (int source = 0; source < SourceCount; ++source) { + for (int stage = 0; stage < EShLangCount; ++stage) { + delete SharedSymbolTables[version][spvVersion][p][source][stage]; + SharedSymbolTables[version][spvVersion][p][source][stage] = 0; + } + } + } + } + } + + for (int version = 0; version < VersionCount; ++version) { + for (int spvVersion = 0; spvVersion < SpvVersionCount; ++spvVersion) { + for (int p = 0; p < ProfileCount; ++p) { + for (int source = 0; source < SourceCount; ++source) { + for (int pc = 0; pc < EPcCount; ++pc) { + delete CommonSymbolTable[version][spvVersion][p][source][pc]; + CommonSymbolTable[version][spvVersion][p][source][pc] = 0; + } + } + } + } + } + + if (PerProcessGPA != nullptr) { + delete PerProcessGPA; + PerProcessGPA = nullptr; + } + + glslang::TScanContext::deleteKeywordMap(); +#ifdef ENABLE_HLSL + glslang::HlslScanContext::deleteKeywordMap(); +#endif + + return 1; +} + +// +// Do a full compile on the given strings for a single compilation unit +// forming a complete stage. The result of the machine dependent compilation +// is left in the provided compile object. +// +// Return: The return value is really boolean, indicating +// success (1) or failure (0). +// +int ShCompile( + const ShHandle handle, + const char* const shaderStrings[], + const int numStrings, + const int* inputLengths, + const EShOptimizationLevel optLevel, + const TBuiltInResource* resources, + int /*debugOptions*/, + int defaultVersion, // use 100 for ES environment, 110 for desktop + bool forwardCompatible, // give errors for use of deprecated features + EShMessages messages // warnings/errors/AST; things to print out + ) +{ + // Map the generic handle to the C++ object + if (handle == 0) + return 0; + + TShHandleBase* base = reinterpret_cast(handle); + TCompiler* compiler = base->getAsCompiler(); + if (compiler == 0) + return 0; + + SetThreadPoolAllocator(compiler->getPool()); + + compiler->infoSink.info.erase(); + compiler->infoSink.debug.erase(); + + TIntermediate intermediate(compiler->getLanguage()); + TShader::ForbidIncluder includer; + bool success = CompileDeferred(compiler, shaderStrings, numStrings, inputLengths, nullptr, + "", optLevel, resources, defaultVersion, ENoProfile, false, + forwardCompatible, messages, intermediate, includer); + + // + // Call the machine dependent compiler + // + if (success && intermediate.getTreeRoot() && optLevel != EShOptNoGeneration) + success = compiler->compile(intermediate.getTreeRoot(), intermediate.getVersion(), intermediate.getProfile()); + + intermediate.removeTree(); + + // Throw away all the temporary memory used by the compilation process. + // The push was done in the CompileDeferred() call above. + GetThreadPoolAllocator().pop(); + + return success ? 1 : 0; +} + +// +// Link the given compile objects. +// +// Return: The return value of is really boolean, indicating +// success or failure. +// +int ShLinkExt( + const ShHandle linkHandle, + const ShHandle compHandles[], + const int numHandles) +{ + if (linkHandle == 0 || numHandles == 0) + return 0; + + THandleList cObjects; + + for (int i = 0; i < numHandles; ++i) { + if (compHandles[i] == 0) + return 0; + TShHandleBase* base = reinterpret_cast(compHandles[i]); + if (base->getAsLinker()) { + cObjects.push_back(base->getAsLinker()); + } + if (base->getAsCompiler()) + cObjects.push_back(base->getAsCompiler()); + + if (cObjects[i] == 0) + return 0; + } + + TShHandleBase* base = reinterpret_cast(linkHandle); + TLinker* linker = static_cast(base->getAsLinker()); + + SetThreadPoolAllocator(linker->getPool()); + + if (linker == 0) + return 0; + + linker->infoSink.info.erase(); + + for (int i = 0; i < numHandles; ++i) { + if (cObjects[i]->getAsCompiler()) { + if (! cObjects[i]->getAsCompiler()->linkable()) { + linker->infoSink.info.message(EPrefixError, "Not all shaders have valid object code."); + return 0; + } + } + } + + bool ret = linker->link(cObjects); + + return ret ? 1 : 0; +} + +// +// ShSetEncrpytionMethod is a place-holder for specifying +// how source code is encrypted. +// +void ShSetEncryptionMethod(ShHandle handle) +{ + if (handle == 0) + return; +} + +// +// Return any compiler/linker/uniformmap log of messages for the application. +// +const char* ShGetInfoLog(const ShHandle handle) +{ + if (handle == 0) + return 0; + + TShHandleBase* base = static_cast(handle); + TInfoSink* infoSink; + + if (base->getAsCompiler()) + infoSink = &(base->getAsCompiler()->getInfoSink()); + else if (base->getAsLinker()) + infoSink = &(base->getAsLinker()->getInfoSink()); + else + return 0; + + infoSink->info << infoSink->debug.c_str(); + return infoSink->info.c_str(); +} + +// +// Return the resulting binary code from the link process. Structure +// is machine dependent. +// +const void* ShGetExecutable(const ShHandle handle) +{ + if (handle == 0) + return 0; + + TShHandleBase* base = reinterpret_cast(handle); + + TLinker* linker = static_cast(base->getAsLinker()); + if (linker == 0) + return 0; + + return linker->getObjectCode(); +} + +// +// Let the linker know where the application said it's attributes are bound. +// The linker does not use these values, they are remapped by the ICD or +// hardware. It just needs them to know what's aliased. +// +// Return: The return value of is really boolean, indicating +// success or failure. +// +int ShSetVirtualAttributeBindings(const ShHandle handle, const ShBindingTable* table) +{ + if (handle == 0) + return 0; + + TShHandleBase* base = reinterpret_cast(handle); + TLinker* linker = static_cast(base->getAsLinker()); + + if (linker == 0) + return 0; + + linker->setAppAttributeBindings(table); + + return 1; +} + +// +// Let the linker know where the predefined attributes have to live. +// +int ShSetFixedAttributeBindings(const ShHandle handle, const ShBindingTable* table) +{ + if (handle == 0) + return 0; + + TShHandleBase* base = reinterpret_cast(handle); + TLinker* linker = static_cast(base->getAsLinker()); + + if (linker == 0) + return 0; + + linker->setFixedAttributeBindings(table); + return 1; +} + +// +// Some attribute locations are off-limits to the linker... +// +int ShExcludeAttributes(const ShHandle handle, int *attributes, int count) +{ + if (handle == 0) + return 0; + + TShHandleBase* base = reinterpret_cast(handle); + TLinker* linker = static_cast(base->getAsLinker()); + if (linker == 0) + return 0; + + linker->setExcludedAttributes(attributes, count); + + return 1; +} + +// +// Return the index for OpenGL to use for knowing where a uniform lives. +// +// Return: The return value of is really boolean, indicating +// success or failure. +// +int ShGetUniformLocation(const ShHandle handle, const char* name) +{ + if (handle == 0) + return -1; + + TShHandleBase* base = reinterpret_cast(handle); + TUniformMap* uniformMap= base->getAsUniformMap(); + if (uniformMap == 0) + return -1; + + return uniformMap->getLocation(name); +} + +//////////////////////////////////////////////////////////////////////////////////////////// +// +// Deferred-Lowering C++ Interface +// ----------------------------------- +// +// Below is a new alternate C++ interface that might potentially replace the above +// opaque handle-based interface. +// +// See more detailed comment in ShaderLang.h +// + +namespace glslang { + +#include "../Include/revision.h" + +const char* GetEsslVersionString() +{ + return "OpenGL ES GLSL 3.20 glslang Khronos." GLSLANG_REVISION " " GLSLANG_DATE; +} + +const char* GetGlslVersionString() +{ + return "4.60 glslang Khronos." GLSLANG_REVISION " " GLSLANG_DATE; +} + +int GetKhronosToolId() +{ + return 8; +} + +bool InitializeProcess() +{ + return ShInitialize() != 0; +} + +void FinalizeProcess() +{ + ShFinalize(); +} + +class TDeferredCompiler : public TCompiler { +public: + TDeferredCompiler(EShLanguage s, TInfoSink& i) : TCompiler(s, i) { } + virtual bool compile(TIntermNode*, int = 0, EProfile = ENoProfile) { return true; } +}; + +TShader::TShader(EShLanguage s) + : stage(s), lengths(nullptr), stringNames(nullptr), preamble("") +{ + pool = new TPoolAllocator; + infoSink = new TInfoSink; + compiler = new TDeferredCompiler(stage, *infoSink); + intermediate = new TIntermediate(s); + + // clear environment (avoid constructors in them for use in a C interface) + environment.input.languageFamily = EShSourceNone; + environment.input.dialect = EShClientNone; + environment.client.client = EShClientNone; + environment.target.language = EShTargetNone; +} + +TShader::~TShader() +{ + delete infoSink; + delete compiler; + delete intermediate; + delete pool; +} + +void TShader::setStrings(const char* const* s, int n) +{ + strings = s; + numStrings = n; + lengths = nullptr; +} + +void TShader::setStringsWithLengths(const char* const* s, const int* l, int n) +{ + strings = s; + numStrings = n; + lengths = l; +} + +void TShader::setStringsWithLengthsAndNames( + const char* const* s, const int* l, const char* const* names, int n) +{ + strings = s; + numStrings = n; + lengths = l; + stringNames = names; +} + +void TShader::setEntryPoint(const char* entryPoint) +{ + intermediate->setEntryPointName(entryPoint); +} + +void TShader::setSourceEntryPoint(const char* name) +{ + sourceEntryPointName = name; +} + +void TShader::addProcesses(const std::vector& p) +{ + intermediate->addProcesses(p); +} + +// Set binding base for given resource type +void TShader::setShiftBinding(TResourceType res, unsigned int base) { + intermediate->setShiftBinding(res, base); +} + +// Set binding base for given resource type for a given binding set. +void TShader::setShiftBindingForSet(TResourceType res, unsigned int base, unsigned int set) { + intermediate->setShiftBindingForSet(res, base, set); +} + +// Set binding base for sampler types +void TShader::setShiftSamplerBinding(unsigned int base) { setShiftBinding(EResSampler, base); } +// Set binding base for texture types (SRV) +void TShader::setShiftTextureBinding(unsigned int base) { setShiftBinding(EResTexture, base); } +// Set binding base for image types +void TShader::setShiftImageBinding(unsigned int base) { setShiftBinding(EResImage, base); } +// Set binding base for uniform buffer objects (CBV) +void TShader::setShiftUboBinding(unsigned int base) { setShiftBinding(EResUbo, base); } +// Synonym for setShiftUboBinding, to match HLSL language. +void TShader::setShiftCbufferBinding(unsigned int base) { setShiftBinding(EResUbo, base); } +// Set binding base for UAV (unordered access view) +void TShader::setShiftUavBinding(unsigned int base) { setShiftBinding(EResUav, base); } +// Set binding base for SSBOs +void TShader::setShiftSsboBinding(unsigned int base) { setShiftBinding(EResSsbo, base); } +// Enables binding automapping using TIoMapper +void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); } +// Enables position.Y output negation in vertex shader +void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); } +// Fragile: currently within one stage: simple auto-assignment of location +void TShader::setAutoMapLocations(bool map) { intermediate->setAutoMapLocations(map); } +// See comment above TDefaultHlslIoMapper in iomapper.cpp: +void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); } +void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); } +void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); } +void TShader::setResourceSetBinding(const std::vector& base) { intermediate->setResourceSetBinding(base); } +void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { intermediate->setTextureSamplerTransformMode(mode); } + +// +// Turn the shader strings into a parse tree in the TIntermediate. +// +// Returns true for success. +// +bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile, + bool forwardCompatible, EShMessages messages, Includer& includer) +{ + if (! InitThread()) + return false; + SetThreadPoolAllocator(pool); + + if (! preamble) + preamble = ""; + + return CompileDeferred(compiler, strings, numStrings, lengths, stringNames, + preamble, EShOptNone, builtInResources, defaultVersion, + defaultProfile, forceDefaultVersionAndProfile, + forwardCompatible, messages, *intermediate, includer, sourceEntryPointName, + &environment); +} + +// Fill in a string with the result of preprocessing ShaderStrings +// Returns true if all extensions, pragmas and version strings were valid. +bool TShader::preprocess(const TBuiltInResource* builtInResources, + int defaultVersion, EProfile defaultProfile, + bool forceDefaultVersionAndProfile, + bool forwardCompatible, EShMessages message, + std::string* output_string, + Includer& includer) +{ + if (! InitThread()) + return false; + SetThreadPoolAllocator(pool); + + if (! preamble) + preamble = ""; + + return PreprocessDeferred(compiler, strings, numStrings, lengths, stringNames, preamble, + EShOptNone, builtInResources, defaultVersion, + defaultProfile, forceDefaultVersionAndProfile, + forwardCompatible, message, includer, *intermediate, output_string); +} + +const char* TShader::getInfoLog() +{ + return infoSink->info.c_str(); +} + +const char* TShader::getInfoDebugLog() +{ + return infoSink->debug.c_str(); +} + +TProgram::TProgram() : reflection(0), ioMapper(nullptr), linked(false) +{ + pool = new TPoolAllocator; + infoSink = new TInfoSink; + for (int s = 0; s < EShLangCount; ++s) { + intermediate[s] = 0; + newedIntermediate[s] = false; + } +} + +TProgram::~TProgram() +{ + delete ioMapper; + delete infoSink; + delete reflection; + + for (int s = 0; s < EShLangCount; ++s) + if (newedIntermediate[s]) + delete intermediate[s]; + + delete pool; +} + +// +// Merge the compilation units within each stage into a single TIntermediate. +// All starting compilation units need to be the result of calling TShader::parse(). +// +// Return true for success. +// +bool TProgram::link(EShMessages messages) +{ + if (linked) + return false; + linked = true; + + bool error = false; + + SetThreadPoolAllocator(pool); + + for (int s = 0; s < EShLangCount; ++s) { + if (! linkStage((EShLanguage)s, messages)) + error = true; + } + + // TODO: Link: cross-stage error checking + + return ! error; +} + +// +// Merge the compilation units within the given stage into a single TIntermediate. +// +// Return true for success. +// +bool TProgram::linkStage(EShLanguage stage, EShMessages messages) +{ + if (stages[stage].size() == 0) + return true; + + int numEsShaders = 0, numNonEsShaders = 0; + for (auto it = stages[stage].begin(); it != stages[stage].end(); ++it) { + if ((*it)->intermediate->getProfile() == EEsProfile) { + numEsShaders++; + } else { + numNonEsShaders++; + } + } + + if (numEsShaders > 0 && numNonEsShaders > 0) { + infoSink->info.message(EPrefixError, "Cannot mix ES profile with non-ES profile shaders"); + return false; + } else if (numEsShaders > 1) { + infoSink->info.message(EPrefixError, "Cannot attach multiple ES shaders of the same type to a single program"); + return false; + } + + // + // Be efficient for the common single compilation unit per stage case, + // reusing it's TIntermediate instead of merging into a new one. + // + TIntermediate *firstIntermediate = stages[stage].front()->intermediate; + if (stages[stage].size() == 1) + intermediate[stage] = firstIntermediate; + else { + intermediate[stage] = new TIntermediate(stage, + firstIntermediate->getVersion(), + firstIntermediate->getProfile()); + + + // The new TIntermediate must use the same origin as the original TIntermediates. + // Otherwise linking will fail due to different coordinate systems. + if (firstIntermediate->getOriginUpperLeft()) { + intermediate[stage]->setOriginUpperLeft(); + } + intermediate[stage]->setSpv(firstIntermediate->getSpv()); + + newedIntermediate[stage] = true; + } + + if (messages & EShMsgAST) + infoSink->info << "\nLinked " << StageName(stage) << " stage:\n\n"; + + if (stages[stage].size() > 1) { + std::list::const_iterator it; + for (it = stages[stage].begin(); it != stages[stage].end(); ++it) + intermediate[stage]->merge(*infoSink, *(*it)->intermediate); + } + + intermediate[stage]->finalCheck(*infoSink, (messages & EShMsgKeepUncalled) != 0); + + if (messages & EShMsgAST) + intermediate[stage]->output(*infoSink, true); + + return intermediate[stage]->getNumErrors() == 0; +} + +const char* TProgram::getInfoLog() +{ + return infoSink->info.c_str(); +} + +const char* TProgram::getInfoDebugLog() +{ + return infoSink->debug.c_str(); +} + +// +// Reflection implementation. +// + +bool TProgram::buildReflection() +{ + if (! linked || reflection) + return false; + + reflection = new TReflection; + + for (int s = 0; s < EShLangCount; ++s) { + if (intermediate[s]) { + if (! reflection->addStage((EShLanguage)s, *intermediate[s])) + return false; + } + } + + return true; +} + +int TProgram::getNumLiveUniformVariables() const { return reflection->getNumUniforms(); } +int TProgram::getNumLiveUniformBlocks() const { return reflection->getNumUniformBlocks(); } +const char* TProgram::getUniformName(int index) const { return reflection->getUniform(index).name.c_str(); } +const char* TProgram::getUniformBlockName(int index) const { return reflection->getUniformBlock(index).name.c_str(); } +int TProgram::getUniformBlockSize(int index) const { return reflection->getUniformBlock(index).size; } +int TProgram::getUniformIndex(const char* name) const { return reflection->getIndex(name); } +int TProgram::getUniformBinding(int index) const { return reflection->getUniform(index).getBinding(); } +int TProgram::getUniformBlockIndex(int index) const { return reflection->getUniform(index).index; } +int TProgram::getUniformBlockCounterIndex(int index) const { return reflection->getUniformBlock(index).counterIndex; } +int TProgram::getUniformType(int index) const { return reflection->getUniform(index).glDefineType; } +int TProgram::getUniformBufferOffset(int index) const { return reflection->getUniform(index).offset; } +int TProgram::getUniformArraySize(int index) const { return reflection->getUniform(index).size; } +int TProgram::getNumLiveAttributes() const { return reflection->getNumAttributes(); } +const char* TProgram::getAttributeName(int index) const { return reflection->getAttribute(index).name.c_str(); } +int TProgram::getAttributeType(int index) const { return reflection->getAttribute(index).glDefineType; } +const TType* TProgram::getAttributeTType(int index) const { return reflection->getAttribute(index).getType(); } +const TType* TProgram::getUniformTType(int index) const { return reflection->getUniform(index).getType(); } +const TType* TProgram::getUniformBlockTType(int index) const { return reflection->getUniformBlock(index).getType(); } +unsigned TProgram::getLocalSize(int dim) const { return reflection->getLocalSize(dim); } + +void TProgram::dumpReflection() { reflection->dump(); } + +// +// I/O mapping implementation. +// +bool TProgram::mapIO(TIoMapResolver* resolver) +{ + if (! linked || ioMapper) + return false; + + ioMapper = new TIoMapper; + + for (int s = 0; s < EShLangCount; ++s) { + if (intermediate[s]) { + if (! ioMapper->addStage((EShLanguage)s, *intermediate[s], *infoSink, resolver)) + return false; + } + } + + return true; +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.cpp new file mode 100644 index 00000000..233033e7 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.cpp @@ -0,0 +1,383 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2012-2013 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +// +// Symbol table for parsing. Most functionality and main ideas +// are documented in the header file. +// + +#include "SymbolTable.h" + +namespace glslang { + +// +// TType helper function needs a place to live. +// + +// +// Recursively generate mangled names. +// +void TType::buildMangledName(TString& mangledName) const +{ + if (isMatrix()) + mangledName += 'm'; + else if (isVector()) + mangledName += 'v'; + + switch (basicType) { + case EbtFloat: mangledName += 'f'; break; + case EbtDouble: mangledName += 'd'; break; +#ifdef AMD_EXTENSIONS + case EbtFloat16: mangledName += "f16"; break; +#endif + case EbtInt: mangledName += 'i'; break; + case EbtUint: mangledName += 'u'; break; + case EbtInt64: mangledName += "i64"; break; + case EbtUint64: mangledName += "u64"; break; +#ifdef AMD_EXTENSIONS + case EbtInt16: mangledName += "i16"; break; + case EbtUint16: mangledName += "u16"; break; +#endif + case EbtBool: mangledName += 'b'; break; + case EbtAtomicUint: mangledName += "au"; break; + case EbtSampler: + switch (sampler.type) { + case EbtInt: mangledName += "i"; break; + case EbtUint: mangledName += "u"; break; + default: break; // some compilers want this + } + if (sampler.image) + mangledName += "I"; // a normal image + else if (sampler.sampler) + mangledName += "p"; // a "pure" sampler + else if (!sampler.combined) + mangledName += "t"; // a "pure" texture + else + mangledName += "s"; // traditional combined sampler + if (sampler.arrayed) + mangledName += "A"; + if (sampler.shadow) + mangledName += "S"; + if (sampler.external) + mangledName += "E"; + switch (sampler.dim) { + case Esd1D: mangledName += "1"; break; + case Esd2D: mangledName += "2"; break; + case Esd3D: mangledName += "3"; break; + case EsdCube: mangledName += "C"; break; + case EsdRect: mangledName += "R2"; break; + case EsdBuffer: mangledName += "B"; break; + case EsdSubpass: mangledName += "P"; break; + default: break; // some compilers want this + } + + if (sampler.hasReturnStruct()) { + // Name mangle for sampler return struct uses struct table index. + mangledName += "-tx-struct"; + + char text[16]; // plenty enough space for the small integers. + snprintf(text, sizeof(text), "%d-", sampler.structReturnIndex); + mangledName += text; + } else { + switch (sampler.getVectorSize()) { + case 1: mangledName += "1"; break; + case 2: mangledName += "2"; break; + case 3: mangledName += "3"; break; + case 4: break; // default to prior name mangle behavior + } + } + + if (sampler.ms) + mangledName += "M"; + break; + case EbtStruct: + case EbtBlock: + if (basicType == EbtStruct) + mangledName += "struct-"; + else + mangledName += "block-"; + if (typeName) + mangledName += *typeName; + for (unsigned int i = 0; i < structure->size(); ++i) { + mangledName += '-'; + (*structure)[i].type->buildMangledName(mangledName); + } + default: + break; + } + + if (getVectorSize() > 0) + mangledName += static_cast('0' + getVectorSize()); + else { + mangledName += static_cast('0' + getMatrixCols()); + mangledName += static_cast('0' + getMatrixRows()); + } + + if (arraySizes) { + const int maxSize = 11; + char buf[maxSize]; + for (int i = 0; i < arraySizes->getNumDims(); ++i) { + if (arraySizes->getDimNode(i)) { + if (arraySizes->getDimNode(i)->getAsSymbolNode()) + snprintf(buf, maxSize, "s%d", arraySizes->getDimNode(i)->getAsSymbolNode()->getId()); + else + snprintf(buf, maxSize, "s%p", arraySizes->getDimNode(i)); + } else + snprintf(buf, maxSize, "%d", arraySizes->getDimSize(i)); + mangledName += '['; + mangledName += buf; + mangledName += ']'; + } + } +} + +// +// Dump functions. +// + +void TVariable::dump(TInfoSink& infoSink) const +{ + infoSink.debug << getName().c_str() << ": " << type.getStorageQualifierString() << " " << type.getBasicTypeString(); + if (type.isArray()) { + infoSink.debug << "[0]"; + } + infoSink.debug << "\n"; +} + +void TFunction::dump(TInfoSink& infoSink) const +{ + infoSink.debug << getName().c_str() << ": " << returnType.getBasicTypeString() << " " << getMangledName().c_str() << "\n"; +} + +void TAnonMember::dump(TInfoSink& TInfoSink) const +{ + TInfoSink.debug << "anonymous member " << getMemberNumber() << " of " << getAnonContainer().getName().c_str() << "\n"; +} + +void TSymbolTableLevel::dump(TInfoSink &infoSink) const +{ + tLevel::const_iterator it; + for (it = level.begin(); it != level.end(); ++it) + (*it).second->dump(infoSink); +} + +void TSymbolTable::dump(TInfoSink &infoSink) const +{ + for (int level = currentLevel(); level >= 0; --level) { + infoSink.debug << "LEVEL " << level << "\n"; + table[level]->dump(infoSink); + } +} + +// +// Functions have buried pointers to delete. +// +TFunction::~TFunction() +{ + for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i) + delete (*i).type; +} + +// +// Symbol table levels are a map of pointers to symbols that have to be deleted. +// +TSymbolTableLevel::~TSymbolTableLevel() +{ + for (tLevel::iterator it = level.begin(); it != level.end(); ++it) + delete (*it).second; + + delete [] defaultPrecision; +} + +// +// Change all function entries in the table with the non-mangled name +// to be related to the provided built-in operation. +// +void TSymbolTableLevel::relateToOperator(const char* name, TOperator op) +{ + tLevel::const_iterator candidate = level.lower_bound(name); + while (candidate != level.end()) { + const TString& candidateName = (*candidate).first; + TString::size_type parenAt = candidateName.find_first_of('('); + if (parenAt != candidateName.npos && candidateName.compare(0, parenAt, name) == 0) { + TFunction* function = (*candidate).second->getAsFunction(); + function->relateToOperator(op); + } else + break; + ++candidate; + } +} + +// Make all function overloads of the given name require an extension(s). +// Should only be used for a version/profile that actually needs the extension(s). +void TSymbolTableLevel::setFunctionExtensions(const char* name, int num, const char* const extensions[]) +{ + tLevel::const_iterator candidate = level.lower_bound(name); + while (candidate != level.end()) { + const TString& candidateName = (*candidate).first; + TString::size_type parenAt = candidateName.find_first_of('('); + if (parenAt != candidateName.npos && candidateName.compare(0, parenAt, name) == 0) { + TSymbol* symbol = candidate->second; + symbol->setExtensions(num, extensions); + } else + break; + ++candidate; + } +} + +// +// Make all symbols in this table level read only. +// +void TSymbolTableLevel::readOnly() +{ + for (tLevel::iterator it = level.begin(); it != level.end(); ++it) + (*it).second->makeReadOnly(); +} + +// +// Copy a symbol, but the copy is writable; call readOnly() afterward if that's not desired. +// +TSymbol::TSymbol(const TSymbol& copyOf) +{ + name = NewPoolTString(copyOf.name->c_str()); + uniqueId = copyOf.uniqueId; + writable = true; +} + +TVariable::TVariable(const TVariable& copyOf) : TSymbol(copyOf) +{ + type.deepCopy(copyOf.type); + userType = copyOf.userType; + numExtensions = 0; + extensions = 0; + if (copyOf.numExtensions != 0) + setExtensions(copyOf.numExtensions, copyOf.extensions); + + if (! copyOf.constArray.empty()) { + assert(! copyOf.type.isStruct()); + TConstUnionArray newArray(copyOf.constArray, 0, copyOf.constArray.size()); + constArray = newArray; + } + + // don't support specialization-constant subtrees in cloned tables + constSubtree = nullptr; +} + +TVariable* TVariable::clone() const +{ + TVariable *variable = new TVariable(*this); + + return variable; +} + +TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf) +{ + for (unsigned int i = 0; i < copyOf.parameters.size(); ++i) { + TParameter param; + parameters.push_back(param); + parameters.back().copyParam(copyOf.parameters[i]); + } + + numExtensions = 0; + extensions = 0; + if (copyOf.extensions != 0) + setExtensions(copyOf.numExtensions, copyOf.extensions); + returnType.deepCopy(copyOf.returnType); + mangledName = copyOf.mangledName; + op = copyOf.op; + defined = copyOf.defined; + prototyped = copyOf.prototyped; + implicitThis = copyOf.implicitThis; + illegalImplicitThis = copyOf.illegalImplicitThis; + defaultParamCount = copyOf.defaultParamCount; +} + +TFunction* TFunction::clone() const +{ + TFunction *function = new TFunction(*this); + + return function; +} + +TAnonMember* TAnonMember::clone() const +{ + // Anonymous members of a given block should be cloned at a higher level, + // where they can all be assured to still end up pointing to a single + // copy of the original container. + assert(0); + + return 0; +} + +TSymbolTableLevel* TSymbolTableLevel::clone() const +{ + TSymbolTableLevel *symTableLevel = new TSymbolTableLevel(); + symTableLevel->anonId = anonId; + symTableLevel->thisLevel = thisLevel; + std::vector containerCopied(anonId, false); + tLevel::const_iterator iter; + for (iter = level.begin(); iter != level.end(); ++iter) { + const TAnonMember* anon = iter->second->getAsAnonMember(); + if (anon) { + // Insert all the anonymous members of this same container at once, + // avoid inserting the other members in the future, once this has been done, + // allowing them to all be part of the same new container. + if (! containerCopied[anon->getAnonId()]) { + TVariable* container = anon->getAnonContainer().clone(); + container->changeName(NewPoolTString("")); + // insert the whole container + symTableLevel->insert(*container, false); + containerCopied[anon->getAnonId()] = true; + } + } else + symTableLevel->insert(*iter->second->clone(), false); + } + + return symTableLevel; +} + +void TSymbolTable::copyTable(const TSymbolTable& copyOf) +{ + assert(adoptedLevels == copyOf.adoptedLevels); + + uniqueId = copyOf.uniqueId; + noBuiltInRedeclarations = copyOf.noBuiltInRedeclarations; + separateNameSpaces = copyOf.separateNameSpaces; + for (unsigned int i = copyOf.adoptedLevels; i < copyOf.table.size(); ++i) + table.push_back(copyOf.table[i]->clone()); +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.h b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.h new file mode 100644 index 00000000..f928b7ae --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.h @@ -0,0 +1,825 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2013 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef _SYMBOL_TABLE_INCLUDED_ +#define _SYMBOL_TABLE_INCLUDED_ + +// +// Symbol table for parsing. Has these design characteristics: +// +// * Same symbol table can be used to compile many shaders, to preserve +// effort of creating and loading with the large numbers of built-in +// symbols. +// +// --> This requires a copy mechanism, so initial pools used to create +// the shared information can be popped. Done through "clone" +// methods. +// +// * Name mangling will be used to give each function a unique name +// so that symbol table lookups are never ambiguous. This allows +// a simpler symbol table structure. +// +// * Pushing and popping of scope, so symbol table will really be a stack +// of symbol tables. Searched from the top, with new inserts going into +// the top. +// +// * Constants: Compile time constant symbols will keep their values +// in the symbol table. The parser can substitute constants at parse +// time, including doing constant folding and constant propagation. +// +// * No temporaries: Temporaries made from operations (+, --, .xy, etc.) +// are tracked in the intermediate representation, not the symbol table. +// + +#include "../Include/Common.h" +#include "../Include/intermediate.h" +#include "../Include/InfoSink.h" + +namespace glslang { + +// +// Symbol base class. (Can build functions or variables out of these...) +// + +class TVariable; +class TFunction; +class TAnonMember; + +class TSymbol { +public: + POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) + explicit TSymbol(const TString *n) : name(n), numExtensions(0), extensions(0), writable(true) { } + virtual TSymbol* clone() const = 0; + virtual ~TSymbol() { } // rely on all symbol owned memory coming from the pool + + virtual const TString& getName() const { return *name; } + virtual void changeName(const TString* newName) { name = newName; } + virtual void addPrefix(const char* prefix) + { + TString newName(prefix); + newName.append(*name); + changeName(NewPoolTString(newName.c_str())); + } + virtual const TString& getMangledName() const { return getName(); } + virtual TFunction* getAsFunction() { return 0; } + virtual const TFunction* getAsFunction() const { return 0; } + virtual TVariable* getAsVariable() { return 0; } + virtual const TVariable* getAsVariable() const { return 0; } + virtual const TAnonMember* getAsAnonMember() const { return 0; } + virtual const TType& getType() const = 0; + virtual TType& getWritableType() = 0; + virtual void setUniqueId(int id) { uniqueId = id; } + virtual int getUniqueId() const { return uniqueId; } + virtual void setExtensions(int num, const char* const exts[]) + { + assert(extensions == 0); + assert(num > 0); + numExtensions = num; + extensions = NewPoolObject(exts[0], num); + for (int e = 0; e < num; ++e) + extensions[e] = exts[e]; + } + virtual int getNumExtensions() const { return numExtensions; } + virtual const char** getExtensions() const { return extensions; } + virtual void dump(TInfoSink &infoSink) const = 0; + + virtual bool isReadOnly() const { return ! writable; } + virtual void makeReadOnly() { writable = false; } + +protected: + explicit TSymbol(const TSymbol&); + TSymbol& operator=(const TSymbol&); + + const TString *name; + unsigned int uniqueId; // For cross-scope comparing during code generation + + // For tracking what extensions must be present + // (don't use if correct version/profile is present). + int numExtensions; + const char** extensions; // an array of pointers to existing constant char strings + + // + // N.B.: Non-const functions that will be generally used should assert on this, + // to avoid overwriting shared symbol-table information. + // + bool writable; +}; + +// +// Variable class, meaning a symbol that's not a function. +// +// There could be a separate class hierarchy for Constant variables; +// Only one of int, bool, or float, (or none) is correct for +// any particular use, but it's easy to do this way, and doesn't +// seem worth having separate classes, and "getConst" can't simply return +// different values for different types polymorphically, so this is +// just simple and pragmatic. +// +class TVariable : public TSymbol { +public: + TVariable(const TString *name, const TType& t, bool uT = false ) + : TSymbol(name), + userType(uT), + constSubtree(nullptr), + anonId(-1) { type.shallowCopy(t); } + virtual TVariable* clone() const; + virtual ~TVariable() { } + + virtual TVariable* getAsVariable() { return this; } + virtual const TVariable* getAsVariable() const { return this; } + virtual const TType& getType() const { return type; } + virtual TType& getWritableType() { assert(writable); return type; } + virtual bool isUserType() const { return userType; } + virtual const TConstUnionArray& getConstArray() const { return constArray; } + virtual TConstUnionArray& getWritableConstArray() { assert(writable); return constArray; } + virtual void setConstArray(const TConstUnionArray& array) { constArray = array; } + virtual void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; } + virtual TIntermTyped* getConstSubtree() const { return constSubtree; } + virtual void setAnonId(int i) { anonId = i; } + virtual int getAnonId() const { return anonId; } + + virtual void dump(TInfoSink &infoSink) const; + +protected: + explicit TVariable(const TVariable&); + TVariable& operator=(const TVariable&); + + TType type; + bool userType; + // we are assuming that Pool Allocator will free the memory allocated to unionArray + // when this object is destroyed + + // TODO: these two should be a union + // A variable could be a compile-time constant, or a specialization + // constant, or neither, but never both. + TConstUnionArray constArray; // for compile-time constant value + TIntermTyped* constSubtree; // for specialization constant computation + int anonId; // the ID used for anonymous blocks: TODO: see if uniqueId could serve a dual purpose +}; + +// +// The function sub-class of symbols and the parser will need to +// share this definition of a function parameter. +// +struct TParameter { + TString *name; + TType* type; + TIntermTyped* defaultValue; + void copyParam(const TParameter& param) + { + if (param.name) + name = NewPoolTString(param.name->c_str()); + else + name = 0; + type = param.type->clone(); + defaultValue = param.defaultValue; + } + TBuiltInVariable getDeclaredBuiltIn() const { return type->getQualifier().declaredBuiltIn; } +}; + +// +// The function sub-class of a symbol. +// +class TFunction : public TSymbol { +public: + explicit TFunction(TOperator o) : + TSymbol(0), + op(o), + defined(false), prototyped(false), implicitThis(false), illegalImplicitThis(false), defaultParamCount(0) { } + TFunction(const TString *name, const TType& retType, TOperator tOp = EOpNull) : + TSymbol(name), + mangledName(*name + '('), + op(tOp), + defined(false), prototyped(false), implicitThis(false), illegalImplicitThis(false), defaultParamCount(0) + { + returnType.shallowCopy(retType); + declaredBuiltIn = retType.getQualifier().builtIn; + } + virtual TFunction* clone() const override; + virtual ~TFunction(); + + virtual TFunction* getAsFunction() override { return this; } + virtual const TFunction* getAsFunction() const override { return this; } + + // Install 'p' as the (non-'this') last parameter. + // Non-'this' parameters are reflected in both the list of parameters and the + // mangled name. + virtual void addParameter(TParameter& p) + { + assert(writable); + parameters.push_back(p); + p.type->appendMangledName(mangledName); + + if (p.defaultValue != nullptr) + defaultParamCount++; + } + + // Install 'this' as the first parameter. + // 'this' is reflected in the list of parameters, but not the mangled name. + virtual void addThisParameter(TType& type, const char* name) + { + TParameter p = { NewPoolTString(name), new TType, nullptr }; + p.type->shallowCopy(type); + parameters.insert(parameters.begin(), p); + } + + virtual void addPrefix(const char* prefix) override + { + TSymbol::addPrefix(prefix); + mangledName.insert(0, prefix); + } + + virtual void removePrefix(const TString& prefix) + { + assert(mangledName.compare(0, prefix.size(), prefix) == 0); + mangledName.erase(0, prefix.size()); + } + + virtual const TString& getMangledName() const override { return mangledName; } + virtual const TType& getType() const override { return returnType; } + virtual TBuiltInVariable getDeclaredBuiltInType() const { return declaredBuiltIn; } + virtual TType& getWritableType() override { return returnType; } + virtual void relateToOperator(TOperator o) { assert(writable); op = o; } + virtual TOperator getBuiltInOp() const { return op; } + virtual void setDefined() { assert(writable); defined = true; } + virtual bool isDefined() const { return defined; } + virtual void setPrototyped() { assert(writable); prototyped = true; } + virtual bool isPrototyped() const { return prototyped; } + virtual void setImplicitThis() { assert(writable); implicitThis = true; } + virtual bool hasImplicitThis() const { return implicitThis; } + virtual void setIllegalImplicitThis() { assert(writable); illegalImplicitThis = true; } + virtual bool hasIllegalImplicitThis() const { return illegalImplicitThis; } + + // Return total number of parameters + virtual int getParamCount() const { return static_cast(parameters.size()); } + // Return number of parameters with default values. + virtual int getDefaultParamCount() const { return defaultParamCount; } + // Return number of fixed parameters (without default values) + virtual int getFixedParamCount() const { return getParamCount() - getDefaultParamCount(); } + + virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; } + virtual const TParameter& operator[](int i) const { return parameters[i]; } + + virtual void dump(TInfoSink &infoSink) const override; + +protected: + explicit TFunction(const TFunction&); + TFunction& operator=(const TFunction&); + + typedef TVector TParamList; + TParamList parameters; + TType returnType; + TBuiltInVariable declaredBuiltIn; + + TString mangledName; + TOperator op; + bool defined; + bool prototyped; + bool implicitThis; // True if this function is allowed to see all members of 'this' + bool illegalImplicitThis; // True if this function is not supposed to have access to dynamic members of 'this', + // even if it finds member variables in the symbol table. + // This is important for a static member function that has member variables in scope, + // but is not allowed to use them, or see hidden symbols instead. + int defaultParamCount; +}; + +// +// Members of anonymous blocks are a kind of TSymbol. They are not hidden in +// the symbol table behind a container; rather they are visible and point to +// their anonymous container. (The anonymous container is found through the +// member, not the other way around.) +// +class TAnonMember : public TSymbol { +public: + TAnonMember(const TString* n, unsigned int m, const TVariable& a, int an) : TSymbol(n), anonContainer(a), memberNumber(m), anonId(an) { } + virtual TAnonMember* clone() const; + virtual ~TAnonMember() { } + + virtual const TAnonMember* getAsAnonMember() const { return this; } + virtual const TVariable& getAnonContainer() const { return anonContainer; } + virtual unsigned int getMemberNumber() const { return memberNumber; } + + virtual const TType& getType() const + { + const TTypeList& types = *anonContainer.getType().getStruct(); + return *types[memberNumber].type; + } + + virtual TType& getWritableType() + { + assert(writable); + const TTypeList& types = *anonContainer.getType().getStruct(); + return *types[memberNumber].type; + } + + virtual int getAnonId() const { return anonId; } + virtual void dump(TInfoSink &infoSink) const; + +protected: + explicit TAnonMember(const TAnonMember&); + TAnonMember& operator=(const TAnonMember&); + + const TVariable& anonContainer; + unsigned int memberNumber; + int anonId; +}; + +class TSymbolTableLevel { +public: + POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) + TSymbolTableLevel() : defaultPrecision(0), anonId(0), thisLevel(false) { } + ~TSymbolTableLevel(); + + bool insert(TSymbol& symbol, bool separateNameSpaces) + { + // + // returning true means symbol was added to the table with no semantic errors + // + const TString& name = symbol.getName(); + if (name == "") { + symbol.getAsVariable()->setAnonId(anonId++); + // An empty name means an anonymous container, exposing its members to the external scope. + // Give it a name and insert its members in the symbol table, pointing to the container. + char buf[20]; + snprintf(buf, 20, "%s%d", AnonymousPrefix, symbol.getAsVariable()->getAnonId()); + symbol.changeName(NewPoolTString(buf)); + + return insertAnonymousMembers(symbol, 0); + } else { + // Check for redefinition errors: + // - STL itself will tell us if there is a direct name collision, with name mangling, at this level + // - additionally, check for function-redefining-variable name collisions + const TString& insertName = symbol.getMangledName(); + if (symbol.getAsFunction()) { + // make sure there isn't a variable of this name + if (! separateNameSpaces && level.find(name) != level.end()) + return false; + + // insert, and whatever happens is okay + level.insert(tLevelPair(insertName, &symbol)); + + return true; + } else + return level.insert(tLevelPair(insertName, &symbol)).second; + } + } + + // Add more members to an already inserted aggregate object + bool amend(TSymbol& symbol, int firstNewMember) + { + // See insert() for comments on basic explanation of insert. + // This operates similarly, but more simply. + // Only supporting amend of anonymous blocks so far. + if (IsAnonymous(symbol.getName())) + return insertAnonymousMembers(symbol, firstNewMember); + else + return false; + } + + bool insertAnonymousMembers(TSymbol& symbol, int firstMember) + { + const TTypeList& types = *symbol.getAsVariable()->getType().getStruct(); + for (unsigned int m = firstMember; m < types.size(); ++m) { + TAnonMember* member = new TAnonMember(&types[m].type->getFieldName(), m, *symbol.getAsVariable(), symbol.getAsVariable()->getAnonId()); + if (! level.insert(tLevelPair(member->getMangledName(), member)).second) + return false; + } + + return true; + } + + TSymbol* find(const TString& name) const + { + tLevel::const_iterator it = level.find(name); + if (it == level.end()) + return 0; + else + return (*it).second; + } + + void findFunctionNameList(const TString& name, TVector& list) + { + size_t parenAt = name.find_first_of('('); + TString base(name, 0, parenAt + 1); + + tLevel::const_iterator begin = level.lower_bound(base); + base[parenAt] = ')'; // assume ')' is lexically after '(' + tLevel::const_iterator end = level.upper_bound(base); + for (tLevel::const_iterator it = begin; it != end; ++it) + list.push_back(it->second->getAsFunction()); + } + + // See if there is already a function in the table having the given non-function-style name. + bool hasFunctionName(const TString& name) const + { + tLevel::const_iterator candidate = level.lower_bound(name); + if (candidate != level.end()) { + const TString& candidateName = (*candidate).first; + TString::size_type parenAt = candidateName.find_first_of('('); + if (parenAt != candidateName.npos && candidateName.compare(0, parenAt, name) == 0) + + return true; + } + + return false; + } + + // See if there is a variable at this level having the given non-function-style name. + // Return true if name is found, and set variable to true if the name was a variable. + bool findFunctionVariableName(const TString& name, bool& variable) const + { + tLevel::const_iterator candidate = level.lower_bound(name); + if (candidate != level.end()) { + const TString& candidateName = (*candidate).first; + TString::size_type parenAt = candidateName.find_first_of('('); + if (parenAt == candidateName.npos) { + // not a mangled name + if (candidateName == name) { + // found a variable name match + variable = true; + return true; + } + } else { + // a mangled name + if (candidateName.compare(0, parenAt, name) == 0) { + // found a function name match + variable = false; + return true; + } + } + } + + return false; + } + + // Use this to do a lazy 'push' of precision defaults the first time + // a precision statement is seen in a new scope. Leave it at 0 for + // when no push was needed. Thus, it is not the current defaults, + // it is what to restore the defaults to when popping a level. + void setPreviousDefaultPrecisions(const TPrecisionQualifier *p) + { + // can call multiple times at one scope, will only latch on first call, + // as we're tracking the previous scope's values, not the current values + if (defaultPrecision != 0) + return; + + defaultPrecision = new TPrecisionQualifier[EbtNumTypes]; + for (int t = 0; t < EbtNumTypes; ++t) + defaultPrecision[t] = p[t]; + } + + void getPreviousDefaultPrecisions(TPrecisionQualifier *p) + { + // can be called for table level pops that didn't set the + // defaults + if (defaultPrecision == 0 || p == 0) + return; + + for (int t = 0; t < EbtNumTypes; ++t) + p[t] = defaultPrecision[t]; + } + + void relateToOperator(const char* name, TOperator op); + void setFunctionExtensions(const char* name, int num, const char* const extensions[]); + void dump(TInfoSink &infoSink) const; + TSymbolTableLevel* clone() const; + void readOnly(); + + void setThisLevel() { thisLevel = true; } + bool isThisLevel() const { return thisLevel; } + +protected: + explicit TSymbolTableLevel(TSymbolTableLevel&); + TSymbolTableLevel& operator=(TSymbolTableLevel&); + + typedef std::map, pool_allocator > > tLevel; + typedef const tLevel::value_type tLevelPair; + typedef std::pair tInsertResult; + + tLevel level; // named mappings + TPrecisionQualifier *defaultPrecision; + int anonId; + bool thisLevel; // True if this level of the symbol table is a structure scope containing member function + // that are supposed to see anonymous access to member variables. +}; + +class TSymbolTable { +public: + TSymbolTable() : uniqueId(0), noBuiltInRedeclarations(false), separateNameSpaces(false), adoptedLevels(0) + { + // + // This symbol table cannot be used until push() is called. + // + } + ~TSymbolTable() + { + // this can be called explicitly; safest to code it so it can be called multiple times + + // don't deallocate levels passed in from elsewhere + while (table.size() > adoptedLevels) + pop(0); + } + + void adoptLevels(TSymbolTable& symTable) + { + for (unsigned int level = 0; level < symTable.table.size(); ++level) { + table.push_back(symTable.table[level]); + ++adoptedLevels; + } + uniqueId = symTable.uniqueId; + noBuiltInRedeclarations = symTable.noBuiltInRedeclarations; + separateNameSpaces = symTable.separateNameSpaces; + } + + // + // While level adopting is generic, the methods below enact a the following + // convention for levels: + // 0: common built-ins shared across all stages, all compiles, only one copy for all symbol tables + // 1: per-stage built-ins, shared across all compiles, but a different copy per stage + // 2: built-ins specific to a compile, like resources that are context-dependent, or redeclared built-ins + // 3: user-shader globals + // +protected: + static const int globalLevel = 3; + bool isSharedLevel(int level) { return level <= 1; } // exclude all per-compile levels + bool isBuiltInLevel(int level) { return level <= 2; } // exclude user globals + bool isGlobalLevel(int level) { return level <= globalLevel; } // include user globals +public: + bool isEmpty() { return table.size() == 0; } + bool atBuiltInLevel() { return isBuiltInLevel(currentLevel()); } + bool atGlobalLevel() { return isGlobalLevel(currentLevel()); } + + void setNoBuiltInRedeclarations() { noBuiltInRedeclarations = true; } + void setSeparateNameSpaces() { separateNameSpaces = true; } + + void push() + { + table.push_back(new TSymbolTableLevel); + } + + // Make a new symbol-table level to represent the scope introduced by a structure + // containing member functions, such that the member functions can find anonymous + // references to member variables. + // + // 'thisSymbol' should have a name of "" to trigger anonymous structure-member + // symbol finds. + void pushThis(TSymbol& thisSymbol) + { + assert(thisSymbol.getName().size() == 0); + table.push_back(new TSymbolTableLevel); + table.back()->setThisLevel(); + insert(thisSymbol); + } + + void pop(TPrecisionQualifier *p) + { + table[currentLevel()]->getPreviousDefaultPrecisions(p); + delete table.back(); + table.pop_back(); + } + + // + // Insert a visible symbol into the symbol table so it can + // be found later by name. + // + // Returns false if the was a name collision. + // + bool insert(TSymbol& symbol) + { + symbol.setUniqueId(++uniqueId); + + // make sure there isn't a function of this variable name + if (! separateNameSpaces && ! symbol.getAsFunction() && table[currentLevel()]->hasFunctionName(symbol.getName())) + return false; + + // check for not overloading or redefining a built-in function + if (noBuiltInRedeclarations) { + if (atGlobalLevel() && currentLevel() > 0) { + if (table[0]->hasFunctionName(symbol.getName())) + return false; + if (currentLevel() > 1 && table[1]->hasFunctionName(symbol.getName())) + return false; + } + } + + return table[currentLevel()]->insert(symbol, separateNameSpaces); + } + + // Add more members to an already inserted aggregate object + bool amend(TSymbol& symbol, int firstNewMember) + { + // See insert() for comments on basic explanation of insert. + // This operates similarly, but more simply. + return table[currentLevel()]->amend(symbol, firstNewMember); + } + + // + // To allocate an internal temporary, which will need to be uniquely + // identified by the consumer of the AST, but never need to + // found by doing a symbol table search by name, hence allowed an + // arbitrary name in the symbol with no worry of collision. + // + void makeInternalVariable(TSymbol& symbol) + { + symbol.setUniqueId(++uniqueId); + } + + // + // Copy a variable or anonymous member's structure from a shared level so that + // it can be added (soon after return) to the symbol table where it can be + // modified without impacting other users of the shared table. + // + TSymbol* copyUpDeferredInsert(TSymbol* shared) + { + if (shared->getAsVariable()) { + TSymbol* copy = shared->clone(); + copy->setUniqueId(shared->getUniqueId()); + return copy; + } else { + const TAnonMember* anon = shared->getAsAnonMember(); + assert(anon); + TVariable* container = anon->getAnonContainer().clone(); + container->changeName(NewPoolTString("")); + container->setUniqueId(anon->getAnonContainer().getUniqueId()); + return container; + } + } + + TSymbol* copyUp(TSymbol* shared) + { + TSymbol* copy = copyUpDeferredInsert(shared); + table[globalLevel]->insert(*copy, separateNameSpaces); + if (shared->getAsVariable()) + return copy; + else { + // return the copy of the anonymous member + return table[globalLevel]->find(shared->getName()); + } + } + + // Normal find of a symbol, that can optionally say whether the symbol was found + // at a built-in level or the current top-scope level. + TSymbol* find(const TString& name, bool* builtIn = 0, bool* currentScope = 0, int* thisDepthP = 0) + { + int level = currentLevel(); + TSymbol* symbol; + int thisDepth = 0; + do { + if (table[level]->isThisLevel()) + ++thisDepth; + symbol = table[level]->find(name); + --level; + } while (symbol == nullptr && level >= 0); + level++; + if (builtIn) + *builtIn = isBuiltInLevel(level); + if (currentScope) + *currentScope = isGlobalLevel(currentLevel()) || level == currentLevel(); // consider shared levels as "current scope" WRT user globals + if (thisDepthP != nullptr) { + if (! table[level]->isThisLevel()) + thisDepth = 0; + *thisDepthP = thisDepth; + } + + return symbol; + } + + // Find of a symbol that returns how many layers deep of nested + // structures-with-member-functions ('this' scopes) deep the symbol was + // found in. + TSymbol* find(const TString& name, int& thisDepth) + { + int level = currentLevel(); + TSymbol* symbol; + thisDepth = 0; + do { + if (table[level]->isThisLevel()) + ++thisDepth; + symbol = table[level]->find(name); + --level; + } while (symbol == 0 && level >= 0); + + if (! table[level + 1]->isThisLevel()) + thisDepth = 0; + + return symbol; + } + + bool isFunctionNameVariable(const TString& name) const + { + if (separateNameSpaces) + return false; + + int level = currentLevel(); + do { + bool variable; + bool found = table[level]->findFunctionVariableName(name, variable); + if (found) + return variable; + --level; + } while (level >= 0); + + return false; + } + + void findFunctionNameList(const TString& name, TVector& list, bool& builtIn) + { + // For user levels, return the set found in the first scope with a match + builtIn = false; + int level = currentLevel(); + do { + table[level]->findFunctionNameList(name, list); + --level; + } while (list.empty() && level >= globalLevel); + + if (! list.empty()) + return; + + // Gather across all built-in levels; they don't hide each other + builtIn = true; + do { + table[level]->findFunctionNameList(name, list); + --level; + } while (level >= 0); + } + + void relateToOperator(const char* name, TOperator op) + { + for (unsigned int level = 0; level < table.size(); ++level) + table[level]->relateToOperator(name, op); + } + + void setFunctionExtensions(const char* name, int num, const char* const extensions[]) + { + for (unsigned int level = 0; level < table.size(); ++level) + table[level]->setFunctionExtensions(name, num, extensions); + } + + void setVariableExtensions(const char* name, int num, const char* const extensions[]) + { + TSymbol* symbol = find(TString(name)); + if (symbol) + symbol->setExtensions(num, extensions); + } + + int getMaxSymbolId() { return uniqueId; } + void dump(TInfoSink &infoSink) const; + void copyTable(const TSymbolTable& copyOf); + + void setPreviousDefaultPrecisions(TPrecisionQualifier *p) { table[currentLevel()]->setPreviousDefaultPrecisions(p); } + + void readOnly() + { + for (unsigned int level = 0; level < table.size(); ++level) + table[level]->readOnly(); + } + +protected: + TSymbolTable(TSymbolTable&); + TSymbolTable& operator=(TSymbolTableLevel&); + + int currentLevel() const { return static_cast(table.size()) - 1; } + + std::vector table; + int uniqueId; // for unique identification in code generation + bool noBuiltInRedeclarations; + bool separateNameSpaces; + unsigned int adoptedLevels; +}; + +} // end namespace glslang + +#endif // _SYMBOL_TABLE_INCLUDED_ diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/Versions.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/Versions.cpp new file mode 100644 index 00000000..a8757ad3 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/Versions.cpp @@ -0,0 +1,808 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2012-2013 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +// +// Help manage multiple profiles, versions, extensions etc. +// +// These don't return error codes, as the presumption is parsing will +// always continue as if the tested feature were enabled, and thus there +// is no error recovery needed. +// + +// +// HOW TO add a feature enabled by an extension. +// +// To add a new hypothetical "Feature F" to the front end, where an extension +// "XXX_extension_X" can be used to enable the feature, do the following. +// +// OVERVIEW: Specific features are what are error-checked for, not +// extensions: A specific Feature F might be enabled by an extension, or a +// particular version in a particular profile, or a stage, or combinations, etc. +// +// The basic mechanism is to use the following to "declare" all the things that +// enable/disable Feature F, in a code path that implements Feature F: +// +// requireProfile() +// profileRequires() +// requireStage() +// checkDeprecated() +// requireNotRemoved() +// requireExtensions() +// +// Typically, only the first two calls are needed. They go into a code path that +// implements Feature F, and will log the proper error/warning messages. Parsing +// will then always continue as if the tested feature was enabled. +// +// There is typically no if-testing or conditional parsing, just insertion of the calls above. +// However, if symbols specific to the extension are added (step 5), they will +// only be added under tests that the minimum version and profile are present. +// +// 1) Add a symbol name for the extension string at the bottom of Versions.h: +// +// const char* const XXX_extension_X = "XXX_extension_X"; +// +// 2) Add extension initialization to TParseVersions::initializeExtensionBehavior(), +// the first function below: +// +// extensionBehavior[XXX_extension_X] = EBhDisable; +// +// 3) Add any preprocessor directives etc. in the next function, TParseVersions::getPreamble(): +// +// "#define XXX_extension_X 1\n" +// +// The new-line is important, as that ends preprocess tokens. +// +// 4) Insert a profile check in the feature's path (unless all profiles support the feature, +// for some version level). That is, call requireProfile() to constrain the profiles, e.g.: +// +// // ... in a path specific to Feature F... +// requireProfile(loc, +// ECoreProfile | ECompatibilityProfile, +// "Feature F"); +// +// 5) For each profile that supports the feature, insert version/extension checks: +// +// The mostly likely scenario is that Feature F can only be used with a +// particular profile if XXX_extension_X is present or the version is +// high enough that the core specification already incorporated it. +// +// // following the requireProfile() call... +// profileRequires(loc, +// ECoreProfile | ECompatibilityProfile, +// 420, // 0 if no version incorporated the feature into the core spec. +// XXX_extension_X, // can be a list of extensions that all add the feature +// "Feature F Description"); +// +// This allows the feature if either A) one of the extensions is enabled or +// B) the version is high enough. If no version yet incorporates the feature +// into core, pass in 0. +// +// This can be called multiple times, if different profiles support the +// feature starting at different version numbers or with different +// extensions. +// +// This must be called for each profile allowed by the initial call to requireProfile(). +// +// Profiles are all masks, which can be "or"-ed together. +// +// ENoProfile +// ECoreProfile +// ECompatibilityProfile +// EEsProfile +// +// The ENoProfile profile is only for desktop, before profiles showed up in version 150; +// All other #version with no profile default to either es or core, and so have profiles. +// +// You can select all but a particular profile using ~. The following basically means "desktop": +// +// ~EEsProfile +// +// 6) If built-in symbols are added by the extension, add them in Initialize.cpp: Their use +// will be automatically error checked against the extensions enabled at that moment. +// see the comment at the top of Initialize.cpp for where to put them. Establish them at +// the earliest release that supports the extension. Then, tag them with the +// set of extensions that both enable them and are necessary, given the version of the symbol +// table. (There is a different symbol table for each version.) +// + +#include "parseVersions.h" +#include "localintermediate.h" + +namespace glslang { + +// +// Initialize all extensions, almost always to 'disable', as once their features +// are incorporated into a core version, their features are supported through allowing that +// core version, not through a pseudo-enablement of the extension. +// +void TParseVersions::initializeExtensionBehavior() +{ + extensionBehavior[E_GL_OES_texture_3D] = EBhDisable; + extensionBehavior[E_GL_OES_standard_derivatives] = EBhDisable; + extensionBehavior[E_GL_EXT_frag_depth] = EBhDisable; + extensionBehavior[E_GL_OES_EGL_image_external] = EBhDisable; + extensionBehavior[E_GL_OES_EGL_image_external_essl3] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_texture_lod] = EBhDisable; + extensionBehavior[E_GL_EXT_texture_array] = EBhDisable; + extensionBehavior[E_GL_EXT_shadow_samplers] = EBhDisable; + extensionBehavior[E_GL_ARB_texture_rectangle] = EBhDisable; + extensionBehavior[E_GL_3DL_array_objects] = EBhDisable; + extensionBehavior[E_GL_ARB_shading_language_420pack] = EBhDisable; + extensionBehavior[E_GL_ARB_texture_gather] = EBhDisable; + extensionBehavior[E_GL_ARB_gpu_shader5] = EBhDisablePartial; + extensionBehavior[E_GL_ARB_separate_shader_objects] = EBhDisable; + extensionBehavior[E_GL_ARB_compute_shader] = EBhDisable; + extensionBehavior[E_GL_ARB_tessellation_shader] = EBhDisable; + extensionBehavior[E_GL_ARB_enhanced_layouts] = EBhDisable; + extensionBehavior[E_GL_ARB_texture_cube_map_array] = EBhDisable; + extensionBehavior[E_GL_ARB_shader_texture_lod] = EBhDisable; + extensionBehavior[E_GL_ARB_explicit_attrib_location] = EBhDisable; + extensionBehavior[E_GL_ARB_shader_image_load_store] = EBhDisable; + extensionBehavior[E_GL_ARB_shader_atomic_counters] = EBhDisable; + extensionBehavior[E_GL_ARB_shader_draw_parameters] = EBhDisable; + extensionBehavior[E_GL_ARB_shader_group_vote] = EBhDisable; + extensionBehavior[E_GL_ARB_derivative_control] = EBhDisable; + extensionBehavior[E_GL_ARB_shader_texture_image_samples] = EBhDisable; + extensionBehavior[E_GL_ARB_viewport_array] = EBhDisable; + extensionBehavior[E_GL_ARB_gpu_shader_int64] = EBhDisable; + extensionBehavior[E_GL_ARB_shader_ballot] = EBhDisable; + extensionBehavior[E_GL_ARB_sparse_texture2] = EBhDisable; + extensionBehavior[E_GL_ARB_sparse_texture_clamp] = EBhDisable; + extensionBehavior[E_GL_ARB_shader_stencil_export] = EBhDisable; +// extensionBehavior[E_GL_ARB_cull_distance] = EBhDisable; // present for 4.5, but need extension control over block members + extensionBehavior[E_GL_ARB_post_depth_coverage] = EBhDisable; + extensionBehavior[E_GL_ARB_shader_viewport_layer_array] = EBhDisable; + + extensionBehavior[E_GL_EXT_shader_non_constant_global_initializers] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_image_load_formatted] = EBhDisable; + extensionBehavior[E_GL_EXT_post_depth_coverage] = EBhDisable; + + // #line and #include + extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable; + extensionBehavior[E_GL_GOOGLE_include_directive] = EBhDisable; + +#ifdef AMD_EXTENSIONS + extensionBehavior[E_GL_AMD_shader_ballot] = EBhDisable; + extensionBehavior[E_GL_AMD_shader_trinary_minmax] = EBhDisable; + extensionBehavior[E_GL_AMD_shader_explicit_vertex_parameter] = EBhDisable; + extensionBehavior[E_GL_AMD_gcn_shader] = EBhDisable; + extensionBehavior[E_GL_AMD_gpu_shader_half_float] = EBhDisable; + extensionBehavior[E_GL_AMD_texture_gather_bias_lod] = EBhDisable; + extensionBehavior[E_GL_AMD_gpu_shader_int16] = EBhDisable; + extensionBehavior[E_GL_AMD_shader_image_load_store_lod] = EBhDisable; + extensionBehavior[E_GL_AMD_shader_fragment_mask] = EBhDisable; +#endif + +#ifdef NV_EXTENSIONS + extensionBehavior[E_GL_NV_sample_mask_override_coverage] = EBhDisable; + extensionBehavior[E_SPV_NV_geometry_shader_passthrough] = EBhDisable; + extensionBehavior[E_GL_NV_viewport_array2] = EBhDisable; + extensionBehavior[E_GL_NV_stereo_view_rendering] = EBhDisable; + extensionBehavior[E_GL_NVX_multiview_per_view_attributes] = EBhDisable; + extensionBehavior[E_GL_NV_shader_atomic_int64] = EBhDisable; + extensionBehavior[E_GL_NV_conservative_raster_underestimation] = EBhDisable; +#endif + + // AEP + extensionBehavior[E_GL_ANDROID_extension_pack_es31a] = EBhDisable; + extensionBehavior[E_GL_KHR_blend_equation_advanced] = EBhDisable; + extensionBehavior[E_GL_OES_sample_variables] = EBhDisable; + extensionBehavior[E_GL_OES_shader_image_atomic] = EBhDisable; + extensionBehavior[E_GL_OES_shader_multisample_interpolation] = EBhDisable; + extensionBehavior[E_GL_OES_texture_storage_multisample_2d_array] = EBhDisable; + extensionBehavior[E_GL_EXT_geometry_shader] = EBhDisable; + extensionBehavior[E_GL_EXT_geometry_point_size] = EBhDisable; + extensionBehavior[E_GL_EXT_gpu_shader5] = EBhDisable; + extensionBehavior[E_GL_EXT_primitive_bounding_box] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_io_blocks] = EBhDisable; + extensionBehavior[E_GL_EXT_tessellation_shader] = EBhDisable; + extensionBehavior[E_GL_EXT_tessellation_point_size] = EBhDisable; + extensionBehavior[E_GL_EXT_texture_buffer] = EBhDisable; + extensionBehavior[E_GL_EXT_texture_cube_map_array] = EBhDisable; + + // OES matching AEP + extensionBehavior[E_GL_OES_geometry_shader] = EBhDisable; + extensionBehavior[E_GL_OES_geometry_point_size] = EBhDisable; + extensionBehavior[E_GL_OES_gpu_shader5] = EBhDisable; + extensionBehavior[E_GL_OES_primitive_bounding_box] = EBhDisable; + extensionBehavior[E_GL_OES_shader_io_blocks] = EBhDisable; + extensionBehavior[E_GL_OES_tessellation_shader] = EBhDisable; + extensionBehavior[E_GL_OES_tessellation_point_size] = EBhDisable; + extensionBehavior[E_GL_OES_texture_buffer] = EBhDisable; + extensionBehavior[E_GL_OES_texture_cube_map_array] = EBhDisable; + + // EXT extensions + extensionBehavior[E_GL_EXT_device_group] = EBhDisable; + extensionBehavior[E_GL_EXT_multiview] = EBhDisable; + + // OVR extensions + extensionBehavior[E_GL_OVR_multiview] = EBhDisable; + extensionBehavior[E_GL_OVR_multiview2] = EBhDisable; +} + +// Get code that is not part of a shared symbol table, is specific to this shader, +// or needed by the preprocessor (which does not use a shared symbol table). +void TParseVersions::getPreamble(std::string& preamble) +{ + if (profile == EEsProfile) { + preamble = + "#define GL_ES 1\n" + "#define GL_FRAGMENT_PRECISION_HIGH 1\n" + "#define GL_EXT_texture_array 1\n" + "#define GL_OES_texture_3D 1\n" + "#define GL_OES_standard_derivatives 1\n" + "#define GL_EXT_frag_depth 1\n" + "#define GL_OES_EGL_image_external 1\n" + "#define GL_OES_EGL_image_external_essl3 1\n" + "#define GL_EXT_shader_texture_lod 1\n" + "#define GL_EXT_shadow_samplers 1\n" + + // AEP + "#define GL_ANDROID_extension_pack_es31a 1\n" + "#define GL_KHR_blend_equation_advanced 1\n" + "#define GL_OES_sample_variables 1\n" + "#define GL_OES_shader_image_atomic 1\n" + "#define GL_OES_shader_multisample_interpolation 1\n" + "#define GL_OES_texture_storage_multisample_2d_array 1\n" + "#define GL_EXT_geometry_shader 1\n" + "#define GL_EXT_geometry_point_size 1\n" + "#define GL_EXT_gpu_shader5 1\n" + "#define GL_EXT_primitive_bounding_box 1\n" + "#define GL_EXT_shader_io_blocks 1\n" + "#define GL_EXT_tessellation_shader 1\n" + "#define GL_EXT_tessellation_point_size 1\n" + "#define GL_EXT_texture_buffer 1\n" + "#define GL_EXT_texture_cube_map_array 1\n" + + // OES matching AEP + "#define GL_OES_geometry_shader 1\n" + "#define GL_OES_geometry_point_size 1\n" + "#define GL_OES_gpu_shader5 1\n" + "#define GL_OES_primitive_bounding_box 1\n" + "#define GL_OES_shader_io_blocks 1\n" + "#define GL_OES_tessellation_shader 1\n" + "#define GL_OES_tessellation_point_size 1\n" + "#define GL_OES_texture_buffer 1\n" + "#define GL_OES_texture_cube_map_array 1\n" + "#define GL_EXT_shader_non_constant_global_initializers 1\n" + ; + } else { + preamble = + "#define GL_FRAGMENT_PRECISION_HIGH 1\n" + "#define GL_EXT_texture_array 1\n" + "#define GL_ARB_texture_rectangle 1\n" + "#define GL_ARB_shading_language_420pack 1\n" + "#define GL_ARB_texture_gather 1\n" + "#define GL_ARB_gpu_shader5 1\n" + "#define GL_ARB_separate_shader_objects 1\n" + "#define GL_ARB_compute_shader 1\n" + "#define GL_ARB_tessellation_shader 1\n" + "#define GL_ARB_enhanced_layouts 1\n" + "#define GL_ARB_texture_cube_map_array 1\n" + "#define GL_ARB_shader_texture_lod 1\n" + "#define GL_ARB_explicit_attrib_location 1\n" + "#define GL_ARB_shader_image_load_store 1\n" + "#define GL_ARB_shader_atomic_counters 1\n" + "#define GL_ARB_shader_draw_parameters 1\n" + "#define GL_ARB_shader_group_vote 1\n" + "#define GL_ARB_derivative_control 1\n" + "#define GL_ARB_shader_texture_image_samples 1\n" + "#define GL_ARB_viewport_array 1\n" + "#define GL_ARB_gpu_shader_int64 1\n" + "#define GL_ARB_shader_ballot 1\n" + "#define GL_ARB_sparse_texture2 1\n" + "#define GL_ARB_sparse_texture_clamp 1\n" + "#define GL_ARB_shader_stencil_export 1\n" +// "#define GL_ARB_cull_distance 1\n" // present for 4.5, but need extension control over block members + "#define GL_ARB_post_depth_coverage 1\n" + "#define GL_EXT_shader_non_constant_global_initializers 1\n" + "#define GL_EXT_shader_image_load_formatted 1\n" + "#define GL_EXT_post_depth_coverage 1\n" + +#ifdef AMD_EXTENSIONS + "#define GL_AMD_shader_ballot 1\n" + "#define GL_AMD_shader_trinary_minmax 1\n" + "#define GL_AMD_shader_explicit_vertex_parameter 1\n" + "#define GL_AMD_gcn_shader 1\n" + "#define GL_AMD_gpu_shader_half_float 1\n" + "#define GL_AMD_texture_gather_bias_lod 1\n" + "#define GL_AMD_gpu_shader_int16 1\n" + "#define GL_AMD_shader_image_load_store_lod 1\n" + "#define GL_AMD_shader_fragment_mask 1\n" +#endif + +#ifdef NV_EXTENSIONS + "#define GL_NV_sample_mask_override_coverage 1\n" + "#define GL_NV_geometry_shader_passthrough 1\n" + "#define GL_NV_viewport_array2 1\n" + "#define GL_NV_shader_atomic_int64 1\n" + "#define GL_NV_conservative_raster_underestimation 1\n" +#endif + ; + + if (version >= 150) { + // define GL_core_profile and GL_compatibility_profile + preamble += "#define GL_core_profile 1\n"; + + if (profile == ECompatibilityProfile) + preamble += "#define GL_compatibility_profile 1\n"; + } + } + + if ((profile != EEsProfile && version >= 140) || + (profile == EEsProfile && version >= 310)) { + preamble += + "#define GL_EXT_device_group 1\n" + "#define GL_EXT_multiview 1\n" + ; + } + + if (version >= 300 /* both ES and non-ES */) { + preamble += + "#define GL_OVR_multiview 1\n" + "#define GL_OVR_multiview2 1\n" + ; + } + + // #line and #include + preamble += + "#define GL_GOOGLE_cpp_style_line_directive 1\n" + "#define GL_GOOGLE_include_directive 1\n" + ; + + // #define VULKAN XXXX + const int numberBufSize = 12; + char numberBuf[numberBufSize]; + if (spvVersion.vulkanGlsl > 0) { + preamble += "#define VULKAN "; + snprintf(numberBuf, numberBufSize, "%d", spvVersion.vulkanGlsl); + preamble += numberBuf; + preamble += "\n"; + } + // #define GL_SPIRV XXXX + if (spvVersion.openGl > 0) { + preamble += "#define GL_SPIRV "; + snprintf(numberBuf, numberBufSize, "%d", spvVersion.openGl); + preamble += numberBuf; + preamble += "\n"; + } + +} + +// +// When to use requireProfile(): +// +// Use if only some profiles support a feature. However, if within a profile the feature +// is version or extension specific, follow this call with calls to profileRequires(). +// +// Operation: If the current profile is not one of the profileMask, +// give an error message. +// +void TParseVersions::requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc) +{ + if (! (profile & profileMask)) + error(loc, "not supported with this profile:", featureDesc, ProfileName(profile)); +} + +// +// Map from stage enum to externally readable text name. +// +const char* StageName(EShLanguage stage) +{ + switch(stage) { + case EShLangVertex: return "vertex"; + case EShLangTessControl: return "tessellation control"; + case EShLangTessEvaluation: return "tessellation evaluation"; + case EShLangGeometry: return "geometry"; + case EShLangFragment: return "fragment"; + case EShLangCompute: return "compute"; + default: return "unknown stage"; + } +} + +// +// When to use profileRequires(): +// +// If a set of profiles have the same requirements for what version or extensions +// are needed to support a feature. +// +// It must be called for each profile that needs protection. Use requireProfile() first +// to reduce that set of profiles. +// +// Operation: Will issue warnings/errors based on the current profile, version, and extension +// behaviors. It only checks extensions when the current profile is one of the profileMask. +// +// A minVersion of 0 means no version of the profileMask support this in core, +// the extension must be present. +// + +// entry point that takes multiple extensions +void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions, const char* const extensions[], const char* featureDesc) +{ + if (profile & profileMask) { + bool okay = false; + if (minVersion > 0 && version >= minVersion) + okay = true; + for (int i = 0; i < numExtensions; ++i) { + switch (getExtensionBehavior(extensions[i])) { + case EBhWarn: + infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc); + // fall through + case EBhRequire: + case EBhEnable: + okay = true; + break; + default: break; // some compilers want this + } + } + + if (! okay) + error(loc, "not supported for this version or the enabled extensions", featureDesc, ""); + } +} + +// entry point for the above that takes a single extension +void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, const char* extension, const char* featureDesc) +{ + profileRequires(loc, profileMask, minVersion, extension ? 1 : 0, &extension, featureDesc); +} + +// +// When to use requireStage() +// +// If only some stages support a feature. +// +// Operation: If the current stage is not present, give an error message. +// +void TParseVersions::requireStage(const TSourceLoc& loc, EShLanguageMask languageMask, const char* featureDesc) +{ + if (((1 << language) & languageMask) == 0) + error(loc, "not supported in this stage:", featureDesc, StageName(language)); +} + +// If only one stage supports a feature, this can be called. But, all supporting stages +// must be specified with one call. +void TParseVersions::requireStage(const TSourceLoc& loc, EShLanguage stage, const char* featureDesc) +{ + requireStage(loc, static_cast(1 << stage), featureDesc); +} + +// +// Within a set of profiles, see if a feature is deprecated and give an error or warning based on whether +// a future compatibility context is being use. +// +void TParseVersions::checkDeprecated(const TSourceLoc& loc, int profileMask, int depVersion, const char* featureDesc) +{ + if (profile & profileMask) { + if (version >= depVersion) { + if (forwardCompatible) + error(loc, "deprecated, may be removed in future release", featureDesc, ""); + else if (! suppressWarnings()) + infoSink.info.message(EPrefixWarning, (TString(featureDesc) + " deprecated in version " + + String(depVersion) + "; may be removed in future release").c_str(), loc); + } + } +} + +// +// Within a set of profiles, see if a feature has now been removed and if so, give an error. +// The version argument is the first version no longer having the feature. +// +void TParseVersions::requireNotRemoved(const TSourceLoc& loc, int profileMask, int removedVersion, const char* featureDesc) +{ + if (profile & profileMask) { + if (version >= removedVersion) { + const int maxSize = 60; + char buf[maxSize]; + snprintf(buf, maxSize, "%s profile; removed in version %d", ProfileName(profile), removedVersion); + error(loc, "no longer supported in", featureDesc, buf); + } + } +} + +void TParseVersions::unimplemented(const TSourceLoc& loc, const char* featureDesc) +{ + error(loc, "feature not yet implemented", featureDesc, ""); +} + +// Returns true if at least one of the extensions in the extensions parameter is requested. Otherwise, returns false. +// Warns appropriately if the requested behavior of an extension is "warn". +bool TParseVersions::checkExtensionsRequested(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc) +{ + // First, see if any of the extensions are enabled + for (int i = 0; i < numExtensions; ++i) { + TExtensionBehavior behavior = getExtensionBehavior(extensions[i]); + if (behavior == EBhEnable || behavior == EBhRequire) + return true; + } + + // See if any extensions want to give a warning on use; give warnings for all such extensions + bool warned = false; + for (int i = 0; i < numExtensions; ++i) { + TExtensionBehavior behavior = getExtensionBehavior(extensions[i]); + if (behavior == EBhDisable && relaxedErrors()) { + infoSink.info.message(EPrefixWarning, "The following extension must be enabled to use this feature:", loc); + behavior = EBhWarn; + } + if (behavior == EBhWarn) { + infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc); + warned = true; + } + } + if (warned) + return true; + return false; +} + +// +// Use when there are no profile/version to check, it's just an error if one of the +// extensions is not present. +// +void TParseVersions::requireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc) +{ + if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc)) return; + + // If we get this far, give errors explaining what extensions are needed + if (numExtensions == 1) + error(loc, "required extension not requested:", featureDesc, extensions[0]); + else { + error(loc, "required extension not requested:", featureDesc, "Possible extensions include:"); + for (int i = 0; i < numExtensions; ++i) + infoSink.info.message(EPrefixNone, extensions[i]); + } +} + +// +// Use by preprocessor when there are no profile/version to check, it's just an error if one of the +// extensions is not present. +// +void TParseVersions::ppRequireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc) +{ + if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc)) return; + + // If we get this far, give errors explaining what extensions are needed + if (numExtensions == 1) + ppError(loc, "required extension not requested:", featureDesc, extensions[0]); + else { + ppError(loc, "required extension not requested:", featureDesc, "Possible extensions include:"); + for (int i = 0; i < numExtensions; ++i) + infoSink.info.message(EPrefixNone, extensions[i]); + } +} + +TExtensionBehavior TParseVersions::getExtensionBehavior(const char* extension) +{ + auto iter = extensionBehavior.find(TString(extension)); + if (iter == extensionBehavior.end()) + return EBhMissing; + else + return iter->second; +} + +// Returns true if the given extension is set to enable, require, or warn. +bool TParseVersions::extensionTurnedOn(const char* const extension) +{ + switch (getExtensionBehavior(extension)) { + case EBhEnable: + case EBhRequire: + case EBhWarn: + return true; + default: + break; + } + return false; +} +// See if any of the extensions are set to enable, require, or warn. +bool TParseVersions::extensionsTurnedOn(int numExtensions, const char* const extensions[]) +{ + for (int i = 0; i < numExtensions; ++i) { + if (extensionTurnedOn(extensions[i])) return true; + } + return false; +} + +// +// Change the current state of an extension's behavior. +// +void TParseVersions::updateExtensionBehavior(int line, const char* extension, const char* behaviorString) +{ + // Translate from text string of extension's behavior to an enum. + TExtensionBehavior behavior = EBhDisable; + if (! strcmp("require", behaviorString)) + behavior = EBhRequire; + else if (! strcmp("enable", behaviorString)) + behavior = EBhEnable; + else if (! strcmp("disable", behaviorString)) + behavior = EBhDisable; + else if (! strcmp("warn", behaviorString)) + behavior = EBhWarn; + else { + error(getCurrentLoc(), "behavior not supported:", "#extension", behaviorString); + return; + } + + // update the requested extension + updateExtensionBehavior(extension, behavior); + + // see if need to propagate to implicitly modified things + if (strcmp(extension, "GL_ANDROID_extension_pack_es31a") == 0) { + // to everything in AEP + updateExtensionBehavior(line, "GL_KHR_blend_equation_advanced", behaviorString); + updateExtensionBehavior(line, "GL_OES_sample_variables", behaviorString); + updateExtensionBehavior(line, "GL_OES_shader_image_atomic", behaviorString); + updateExtensionBehavior(line, "GL_OES_shader_multisample_interpolation", behaviorString); + updateExtensionBehavior(line, "GL_OES_texture_storage_multisample_2d_array", behaviorString); + updateExtensionBehavior(line, "GL_EXT_geometry_shader", behaviorString); + updateExtensionBehavior(line, "GL_EXT_gpu_shader5", behaviorString); + updateExtensionBehavior(line, "GL_EXT_primitive_bounding_box", behaviorString); + updateExtensionBehavior(line, "GL_EXT_shader_io_blocks", behaviorString); + updateExtensionBehavior(line, "GL_EXT_tessellation_shader", behaviorString); + updateExtensionBehavior(line, "GL_EXT_texture_buffer", behaviorString); + updateExtensionBehavior(line, "GL_EXT_texture_cube_map_array", behaviorString); + } + // geometry to io_blocks + else if (strcmp(extension, "GL_EXT_geometry_shader") == 0) + updateExtensionBehavior(line, "GL_EXT_shader_io_blocks", behaviorString); + else if (strcmp(extension, "GL_OES_geometry_shader") == 0) + updateExtensionBehavior(line, "GL_OES_shader_io_blocks", behaviorString); + // tessellation to io_blocks + else if (strcmp(extension, "GL_EXT_tessellation_shader") == 0) + updateExtensionBehavior(line, "GL_EXT_shader_io_blocks", behaviorString); + else if (strcmp(extension, "GL_OES_tessellation_shader") == 0) + updateExtensionBehavior(line, "GL_OES_shader_io_blocks", behaviorString); + else if (strcmp(extension, "GL_GOOGLE_include_directive") == 0) + updateExtensionBehavior(line, "GL_GOOGLE_cpp_style_line_directive", behaviorString); +} + +void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBehavior behavior) +{ + // Update the current behavior + if (strcmp(extension, "all") == 0) { + // special case for the 'all' extension; apply it to every extension present + if (behavior == EBhRequire || behavior == EBhEnable) { + error(getCurrentLoc(), "extension 'all' cannot have 'require' or 'enable' behavior", "#extension", ""); + return; + } else { + for (auto iter = extensionBehavior.begin(); iter != extensionBehavior.end(); ++iter) + iter->second = behavior; + } + } else { + // Do the update for this single extension + auto iter = extensionBehavior.find(TString(extension)); + if (iter == extensionBehavior.end()) { + switch (behavior) { + case EBhRequire: + error(getCurrentLoc(), "extension not supported:", "#extension", extension); + break; + case EBhEnable: + case EBhWarn: + case EBhDisable: + warn(getCurrentLoc(), "extension not supported:", "#extension", extension); + break; + default: + assert(0 && "unexpected behavior"); + } + + return; + } else { + if (iter->second == EBhDisablePartial) + warn(getCurrentLoc(), "extension is only partially supported:", "#extension", extension); + if (behavior == EBhEnable || behavior == EBhRequire) + intermediate.addRequestedExtension(extension); + iter->second = behavior; + } + } +} + +// Call for any operation needing full GLSL integer data-type support. +void TParseVersions::fullIntegerCheck(const TSourceLoc& loc, const char* op) +{ + profileRequires(loc, ENoProfile, 130, nullptr, op); + profileRequires(loc, EEsProfile, 300, nullptr, op); +} + +// Call for any operation needing GLSL double data-type support. +void TParseVersions::doubleCheck(const TSourceLoc& loc, const char* op) +{ + requireProfile(loc, ECoreProfile | ECompatibilityProfile, op); + profileRequires(loc, ECoreProfile, 400, nullptr, op); + profileRequires(loc, ECompatibilityProfile, 400, nullptr, op); +} + +#ifdef AMD_EXTENSIONS +// Call for any operation needing GLSL 16-bit integer data-type support. +void TParseVersions::int16Check(const TSourceLoc& loc, const char* op, bool builtIn) +{ + if (! builtIn) { + requireExtensions(loc, 1, &E_GL_AMD_gpu_shader_int16, "shader int16"); + requireProfile(loc, ECoreProfile | ECompatibilityProfile, op); + profileRequires(loc, ECoreProfile, 450, nullptr, op); + profileRequires(loc, ECompatibilityProfile, 450, nullptr, op); + } +} + +// Call for any operation needing GLSL float16 data-type support. +void TParseVersions::float16Check(const TSourceLoc& loc, const char* op, bool builtIn) +{ + if (! builtIn) { + requireExtensions(loc, 1, &E_GL_AMD_gpu_shader_half_float, "shader half float"); + requireProfile(loc, ECoreProfile | ECompatibilityProfile, op); + profileRequires(loc, ECoreProfile, 450, nullptr, op); + profileRequires(loc, ECompatibilityProfile, 450, nullptr, op); + } +} +#endif + +// Call for any operation needing GLSL 64-bit integer data-type support. +void TParseVersions::int64Check(const TSourceLoc& loc, const char* op, bool builtIn) +{ + if (! builtIn) { + requireExtensions(loc, 1, &E_GL_ARB_gpu_shader_int64, "shader int64"); + requireProfile(loc, ECoreProfile | ECompatibilityProfile, op); + profileRequires(loc, ECoreProfile, 450, nullptr, op); + profileRequires(loc, ECompatibilityProfile, 450, nullptr, op); + } +} + +// Call for any operation removed because SPIR-V is in use. +void TParseVersions::spvRemoved(const TSourceLoc& loc, const char* op) +{ + if (spvVersion.spv != 0) + error(loc, "not allowed when generating SPIR-V", op, ""); +} + +// Call for any operation removed because Vulkan SPIR-V is being generated. +void TParseVersions::vulkanRemoved(const TSourceLoc& loc, const char* op) +{ + if (spvVersion.vulkan >= 100) + error(loc, "not allowed when using GLSL for Vulkan", op, ""); +} + +// Call for any operation that requires Vulkan. +void TParseVersions::requireVulkan(const TSourceLoc& loc, const char* op) +{ + if (spvVersion.vulkan == 0) + error(loc, "only allowed when using GLSL for Vulkan", op, ""); +} + +// Call for any operation that requires SPIR-V. +void TParseVersions::requireSpv(const TSourceLoc& loc, const char* op) +{ + if (spvVersion.spv == 0) + error(loc, "only allowed when generating SPIR-V", op, ""); +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/Versions.h b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/Versions.h new file mode 100644 index 00000000..193aabc5 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/Versions.h @@ -0,0 +1,254 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2012-2013 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +#ifndef _VERSIONS_INCLUDED_ +#define _VERSIONS_INCLUDED_ + +// +// Help manage multiple profiles, versions, extensions etc. +// + +// +// Profiles are set up for masking operations, so queries can be done on multiple +// profiles at the same time. +// +// Don't maintain an ordinal set of enums (0,1,2,3...) to avoid all possible +// defects from mixing the two different forms. +// +typedef enum { + EBadProfile = 0, + ENoProfile = (1 << 0), // only for desktop, before profiles showed up + ECoreProfile = (1 << 1), + ECompatibilityProfile = (1 << 2), + EEsProfile = (1 << 3) +} EProfile; + +namespace glslang { + +// +// Map from profile enum to externally readable text name. +// +inline const char* ProfileName(EProfile profile) +{ + switch (profile) { + case ENoProfile: return "none"; + case ECoreProfile: return "core"; + case ECompatibilityProfile: return "compatibility"; + case EEsProfile: return "es"; + default: return "unknown profile"; + } +} + +// +// What source rules, validation rules, target language, etc. are needed +// desired for SPIR-V? +// +// 0 means a target or rule set is not enabled (ignore rules from that entity). +// Non-0 means to apply semantic rules arising from that version of its rule set. +// The union of all requested rule sets will be applied. +// +struct SpvVersion { + SpvVersion() : spv(0), vulkanGlsl(0), vulkan(0), openGl(0) {} + unsigned int spv; // the version of SPIR-V to target, as defined by "word 1" of the SPIR-V binary header + int vulkanGlsl; // the version of GLSL semantics for Vulkan, from GL_KHR_vulkan_glsl, for "#define VULKAN XXX" + int vulkan; // the version of Vulkan, for which SPIR-V execution environment rules to use (100 means 1.0) + int openGl; // the version of GLSL semantics for OpenGL, from GL_ARB_gl_spirv, for "#define GL_SPIRV XXX" +}; + +// +// The behaviors from the GLSL "#extension extension_name : behavior" +// +typedef enum { + EBhMissing = 0, + EBhRequire, + EBhEnable, + EBhWarn, + EBhDisable, + EBhDisablePartial // use as initial state of an extension that is only partially implemented +} TExtensionBehavior; + +// +// Symbolic names for extensions. Strings may be directly used when calling the +// functions, but better to have the compiler do spelling checks. +// +const char* const E_GL_OES_texture_3D = "GL_OES_texture_3D"; +const char* const E_GL_OES_standard_derivatives = "GL_OES_standard_derivatives"; +const char* const E_GL_EXT_frag_depth = "GL_EXT_frag_depth"; +const char* const E_GL_OES_EGL_image_external = "GL_OES_EGL_image_external"; +const char* const E_GL_OES_EGL_image_external_essl3 = "GL_OES_EGL_image_external_essl3"; +const char* const E_GL_EXT_shader_texture_lod = "GL_EXT_shader_texture_lod"; +const char* const E_GL_EXT_shadow_samplers = "GL_EXT_shadow_samplers"; + +const char* const E_GL_EXT_texture_array = "GL_EXT_texture_array"; +const char* const E_GL_ARB_texture_rectangle = "GL_ARB_texture_rectangle"; +const char* const E_GL_3DL_array_objects = "GL_3DL_array_objects"; +const char* const E_GL_ARB_shading_language_420pack = "GL_ARB_shading_language_420pack"; +const char* const E_GL_ARB_texture_gather = "GL_ARB_texture_gather"; +const char* const E_GL_ARB_gpu_shader5 = "GL_ARB_gpu_shader5"; +const char* const E_GL_ARB_separate_shader_objects = "GL_ARB_separate_shader_objects"; +const char* const E_GL_ARB_compute_shader = "GL_ARB_compute_shader"; +const char* const E_GL_ARB_tessellation_shader = "GL_ARB_tessellation_shader"; +const char* const E_GL_ARB_enhanced_layouts = "GL_ARB_enhanced_layouts"; +const char* const E_GL_ARB_texture_cube_map_array = "GL_ARB_texture_cube_map_array"; +const char* const E_GL_ARB_shader_texture_lod = "GL_ARB_shader_texture_lod"; +const char* const E_GL_ARB_explicit_attrib_location = "GL_ARB_explicit_attrib_location"; +const char* const E_GL_ARB_shader_image_load_store = "GL_ARB_shader_image_load_store"; +const char* const E_GL_ARB_shader_atomic_counters = "GL_ARB_shader_atomic_counters"; +const char* const E_GL_ARB_shader_draw_parameters = "GL_ARB_shader_draw_parameters"; +const char* const E_GL_ARB_shader_group_vote = "GL_ARB_shader_group_vote"; +const char* const E_GL_ARB_derivative_control = "GL_ARB_derivative_control"; +const char* const E_GL_ARB_shader_texture_image_samples = "GL_ARB_shader_texture_image_samples"; +const char* const E_GL_ARB_viewport_array = "GL_ARB_viewport_array"; +const char* const E_GL_ARB_gpu_shader_int64 = "GL_ARB_gpu_shader_int64"; +const char* const E_GL_ARB_shader_ballot = "GL_ARB_shader_ballot"; +const char* const E_GL_ARB_sparse_texture2 = "GL_ARB_sparse_texture2"; +const char* const E_GL_ARB_sparse_texture_clamp = "GL_ARB_sparse_texture_clamp"; +const char* const E_GL_ARB_shader_stencil_export = "GL_ARB_shader_stencil_export"; +// const char* const E_GL_ARB_cull_distance = "GL_ARB_cull_distance"; // present for 4.5, but need extension control over block members +const char* const E_GL_ARB_post_depth_coverage = "GL_ARB_post_depth_coverage"; +const char* const E_GL_ARB_shader_viewport_layer_array = "GL_ARB_shader_viewport_layer_array"; + +const char* const E_GL_EXT_shader_non_constant_global_initializers = "GL_EXT_shader_non_constant_global_initializers"; +const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_load_formatted"; + +// EXT extensions +const char* const E_GL_EXT_device_group = "GL_EXT_device_group"; +const char* const E_GL_EXT_multiview = "GL_EXT_multiview"; +const char* const E_GL_EXT_post_depth_coverage = "GL_EXT_post_depth_coverage"; + +// Arrays of extensions for the above viewportEXTs duplications + +const char* const post_depth_coverageEXTs[] = { E_GL_ARB_post_depth_coverage, E_GL_EXT_post_depth_coverage }; +const int Num_post_depth_coverageEXTs = sizeof(post_depth_coverageEXTs) / sizeof(post_depth_coverageEXTs[0]); + +// OVR extensions +const char* const E_GL_OVR_multiview = "GL_OVR_multiview"; +const char* const E_GL_OVR_multiview2 = "GL_OVR_multiview2"; + +const char* const OVR_multiview_EXTs[] = { E_GL_OVR_multiview, E_GL_OVR_multiview2 }; +const int Num_OVR_multiview_EXTs = sizeof(OVR_multiview_EXTs) / sizeof(OVR_multiview_EXTs[0]); + +// #line and #include +const char* const E_GL_GOOGLE_cpp_style_line_directive = "GL_GOOGLE_cpp_style_line_directive"; +const char* const E_GL_GOOGLE_include_directive = "GL_GOOGLE_include_directive"; + +#ifdef AMD_EXTENSIONS +const char* const E_GL_AMD_shader_ballot = "GL_AMD_shader_ballot"; +const char* const E_GL_AMD_shader_trinary_minmax = "GL_AMD_shader_trinary_minmax"; +const char* const E_GL_AMD_shader_explicit_vertex_parameter = "GL_AMD_shader_explicit_vertex_parameter"; +const char* const E_GL_AMD_gcn_shader = "GL_AMD_gcn_shader"; +const char* const E_GL_AMD_gpu_shader_half_float = "GL_AMD_gpu_shader_half_float"; +const char* const E_GL_AMD_texture_gather_bias_lod = "GL_AMD_texture_gather_bias_lod"; +const char* const E_GL_AMD_gpu_shader_int16 = "GL_AMD_gpu_shader_int16"; +const char* const E_GL_AMD_shader_image_load_store_lod = "GL_AMD_shader_image_load_store_lod"; +const char* const E_GL_AMD_shader_fragment_mask = "GL_AMD_shader_fragment_mask"; +#endif + +#ifdef NV_EXTENSIONS + +const char* const E_GL_NV_sample_mask_override_coverage = "GL_NV_sample_mask_override_coverage"; +const char* const E_SPV_NV_geometry_shader_passthrough = "GL_NV_geometry_shader_passthrough"; +const char* const E_GL_NV_viewport_array2 = "GL_NV_viewport_array2"; +const char* const E_GL_NV_stereo_view_rendering = "GL_NV_stereo_view_rendering"; +const char* const E_GL_NVX_multiview_per_view_attributes = "GL_NVX_multiview_per_view_attributes"; +const char* const E_GL_NV_shader_atomic_int64 = "GL_NV_shader_atomic_int64"; +const char* const E_GL_NV_conservative_raster_underestimation = "GL_NV_conservative_raster_underestimation"; + +// Arrays of extensions for the above viewportEXTs duplications + +const char* const viewportEXTs[] = { E_GL_ARB_shader_viewport_layer_array, E_GL_NV_viewport_array2 }; +const int Num_viewportEXTs = sizeof(viewportEXTs) / sizeof(viewportEXTs[0]); +#endif + +// AEP +const char* const E_GL_ANDROID_extension_pack_es31a = "GL_ANDROID_extension_pack_es31a"; +const char* const E_GL_KHR_blend_equation_advanced = "GL_KHR_blend_equation_advanced"; +const char* const E_GL_OES_sample_variables = "GL_OES_sample_variables"; +const char* const E_GL_OES_shader_image_atomic = "GL_OES_shader_image_atomic"; +const char* const E_GL_OES_shader_multisample_interpolation = "GL_OES_shader_multisample_interpolation"; +const char* const E_GL_OES_texture_storage_multisample_2d_array = "GL_OES_texture_storage_multisample_2d_array"; +const char* const E_GL_EXT_geometry_shader = "GL_EXT_geometry_shader"; +const char* const E_GL_EXT_geometry_point_size = "GL_EXT_geometry_point_size"; +const char* const E_GL_EXT_gpu_shader5 = "GL_EXT_gpu_shader5"; +const char* const E_GL_EXT_primitive_bounding_box = "GL_EXT_primitive_bounding_box"; +const char* const E_GL_EXT_shader_io_blocks = "GL_EXT_shader_io_blocks"; +const char* const E_GL_EXT_tessellation_shader = "GL_EXT_tessellation_shader"; +const char* const E_GL_EXT_tessellation_point_size = "GL_EXT_tessellation_point_size"; +const char* const E_GL_EXT_texture_buffer = "GL_EXT_texture_buffer"; +const char* const E_GL_EXT_texture_cube_map_array = "GL_EXT_texture_cube_map_array"; + +// OES matching AEP +const char* const E_GL_OES_geometry_shader = "GL_OES_geometry_shader"; +const char* const E_GL_OES_geometry_point_size = "GL_OES_geometry_point_size"; +const char* const E_GL_OES_gpu_shader5 = "GL_OES_gpu_shader5"; +const char* const E_GL_OES_primitive_bounding_box = "GL_OES_primitive_bounding_box"; +const char* const E_GL_OES_shader_io_blocks = "GL_OES_shader_io_blocks"; +const char* const E_GL_OES_tessellation_shader = "GL_OES_tessellation_shader"; +const char* const E_GL_OES_tessellation_point_size = "GL_OES_tessellation_point_size"; +const char* const E_GL_OES_texture_buffer = "GL_OES_texture_buffer"; +const char* const E_GL_OES_texture_cube_map_array = "GL_OES_texture_cube_map_array"; + +// Arrays of extensions for the above AEP duplications + +const char* const AEP_geometry_shader[] = { E_GL_EXT_geometry_shader, E_GL_OES_geometry_shader }; +const int Num_AEP_geometry_shader = sizeof(AEP_geometry_shader)/sizeof(AEP_geometry_shader[0]); + +const char* const AEP_geometry_point_size[] = { E_GL_EXT_geometry_point_size, E_GL_OES_geometry_point_size }; +const int Num_AEP_geometry_point_size = sizeof(AEP_geometry_point_size)/sizeof(AEP_geometry_point_size[0]); + +const char* const AEP_gpu_shader5[] = { E_GL_EXT_gpu_shader5, E_GL_OES_gpu_shader5 }; +const int Num_AEP_gpu_shader5 = sizeof(AEP_gpu_shader5)/sizeof(AEP_gpu_shader5[0]); + +const char* const AEP_primitive_bounding_box[] = { E_GL_EXT_primitive_bounding_box, E_GL_OES_primitive_bounding_box }; +const int Num_AEP_primitive_bounding_box = sizeof(AEP_primitive_bounding_box)/sizeof(AEP_primitive_bounding_box[0]); + +const char* const AEP_shader_io_blocks[] = { E_GL_EXT_shader_io_blocks, E_GL_OES_shader_io_blocks }; +const int Num_AEP_shader_io_blocks = sizeof(AEP_shader_io_blocks)/sizeof(AEP_shader_io_blocks[0]); + +const char* const AEP_tessellation_shader[] = { E_GL_EXT_tessellation_shader, E_GL_OES_tessellation_shader }; +const int Num_AEP_tessellation_shader = sizeof(AEP_tessellation_shader)/sizeof(AEP_tessellation_shader[0]); + +const char* const AEP_tessellation_point_size[] = { E_GL_EXT_tessellation_point_size, E_GL_OES_tessellation_point_size }; +const int Num_AEP_tessellation_point_size = sizeof(AEP_tessellation_point_size)/sizeof(AEP_tessellation_point_size[0]); + +const char* const AEP_texture_buffer[] = { E_GL_EXT_texture_buffer, E_GL_OES_texture_buffer }; +const int Num_AEP_texture_buffer = sizeof(AEP_texture_buffer)/sizeof(AEP_texture_buffer[0]); + +const char* const AEP_texture_cube_map_array[] = { E_GL_EXT_texture_cube_map_array, E_GL_OES_texture_cube_map_array }; +const int Num_AEP_texture_cube_map_array = sizeof(AEP_texture_cube_map_array)/sizeof(AEP_texture_cube_map_array[0]); + +} // end namespace glslang + +#endif // _VERSIONS_INCLUDED_ diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/gl_types.h b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/gl_types.h new file mode 100644 index 00000000..ae00ae57 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/gl_types.h @@ -0,0 +1,180 @@ +/* +** Copyright (c) 2013 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +#pragma once + +#define GL_FLOAT 0x1406 +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 + +#define GL_DOUBLE 0x140A +#define GL_DOUBLE_VEC2 0x8FFC +#define GL_DOUBLE_VEC3 0x8FFD +#define GL_DOUBLE_VEC4 0x8FFE + +#define GL_INT 0x1404 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 + +#define GL_UNSIGNED_INT 0x1405 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 + +#define GL_INT64_ARB 0x140E +#define GL_INT64_VEC2_ARB 0x8FE9 +#define GL_INT64_VEC3_ARB 0x8FEA +#define GL_INT64_VEC4_ARB 0x8FEB + +#define GL_UNSIGNED_INT64_ARB 0x140F +#define GL_UNSIGNED_INT64_VEC2_ARB 0x8FE5 +#define GL_UNSIGNED_INT64_VEC3_ARB 0x8FE6 +#define GL_UNSIGNED_INT64_VEC4_ARB 0x8FE7 + +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 + +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A + +#define GL_DOUBLE_MAT2 0x8F46 +#define GL_DOUBLE_MAT3 0x8F47 +#define GL_DOUBLE_MAT4 0x8F48 +#define GL_DOUBLE_MAT2x3 0x8F49 +#define GL_DOUBLE_MAT2x4 0x8F4A +#define GL_DOUBLE_MAT3x2 0x8F4B +#define GL_DOUBLE_MAT3x4 0x8F4C +#define GL_DOUBLE_MAT4x2 0x8F4D +#define GL_DOUBLE_MAT4x3 0x8F4E + +#ifdef AMD_EXTENSIONS +// Those constants are borrowed from extension NV_gpu_shader5 +#define GL_FLOAT16_NV 0x8FF8 +#define GL_FLOAT16_VEC2_NV 0x8FF9 +#define GL_FLOAT16_VEC3_NV 0x8FFA +#define GL_FLOAT16_VEC4_NV 0x8FFB + +#define GL_FLOAT16_MAT2_AMD 0x91C5 +#define GL_FLOAT16_MAT3_AMD 0x91C6 +#define GL_FLOAT16_MAT4_AMD 0x91C7 +#define GL_FLOAT16_MAT2x3_AMD 0x91C8 +#define GL_FLOAT16_MAT2x4_AMD 0x91C9 +#define GL_FLOAT16_MAT3x2_AMD 0x91CA +#define GL_FLOAT16_MAT3x4_AMD 0x91CB +#define GL_FLOAT16_MAT4x2_AMD 0x91CC +#define GL_FLOAT16_MAT4x3_AMD 0x91CD +#endif + +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_BUFFER 0x8DC2 +#define GL_SAMPLER_1D_ARRAY 0x8DC0 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_SAMPLER_2D_RECT 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D +#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D + +#define GL_INT_SAMPLER_1D 0x8DC9 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_INT_SAMPLER_2D_RECT 0x8DCD +#define GL_INT_SAMPLER_BUFFER 0x8DD0 +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E + +#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A + +#define GL_IMAGE_1D 0x904C +#define GL_IMAGE_2D 0x904D +#define GL_IMAGE_3D 0x904E +#define GL_IMAGE_2D_RECT 0x904F +#define GL_IMAGE_CUBE 0x9050 +#define GL_IMAGE_BUFFER 0x9051 +#define GL_IMAGE_1D_ARRAY 0x9052 +#define GL_IMAGE_2D_ARRAY 0x9053 +#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 +#define GL_IMAGE_2D_MULTISAMPLE 0x9055 +#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056 +#define GL_INT_IMAGE_1D 0x9057 +#define GL_INT_IMAGE_2D 0x9058 +#define GL_INT_IMAGE_3D 0x9059 +#define GL_INT_IMAGE_2D_RECT 0x905A +#define GL_INT_IMAGE_CUBE 0x905B +#define GL_INT_IMAGE_BUFFER 0x905C +#define GL_INT_IMAGE_1D_ARRAY 0x905D +#define GL_INT_IMAGE_2D_ARRAY 0x905E +#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F +#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060 +#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061 +#define GL_UNSIGNED_INT_IMAGE_1D 0x9062 +#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#define GL_UNSIGNED_INT_IMAGE_3D 0x9064 +#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065 +#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 +#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 +#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C + +#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp new file mode 100644 index 00000000..72415681 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp @@ -0,0 +1,8213 @@ +/* A Bison parser, made by GNU Bison 3.0. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "3.0" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 1 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + + + +/* Copy the first part of user declarations. */ +#line 41 "MachineIndependent/glslang.y" /* yacc.c:339 */ + + +/* Based on: +ANSI C Yacc grammar + +In 1985, Jeff Lee published his Yacc grammar (which is accompanied by a +matching Lex specification) for the April 30, 1985 draft version of the +ANSI C standard. Tom Stockfisch reposted it to net.sources in 1987; that +original, as mentioned in the answer to question 17.25 of the comp.lang.c +FAQ, can be ftp'ed from ftp.uu.net, file usenet/net.sources/ansi.c.grammar.Z. + +I intend to keep this version as close to the current C Standard grammar as +possible; please let me know if you discover discrepancies. + +Jutta Degener, 1995 +*/ + +#include "SymbolTable.h" +#include "ParseHelper.h" +#include "../Public/ShaderLang.h" + +using namespace glslang; + + +#line 91 "MachineIndependent/glslang_tab.cpp" /* yacc.c:339 */ + +# ifndef YY_NULL +# if defined __cplusplus && 201103L <= __cplusplus +# define YY_NULL nullptr +# else +# define YY_NULL 0 +# endif +# endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 1 +#endif + +/* In a future release of Bison, this section will be replaced + by #include "glslang_tab.cpp.h". */ +#ifndef YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED +# define YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 1 +#endif +#if YYDEBUG +extern int yydebug; +#endif + +/* Token type. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + ATTRIBUTE = 258, + VARYING = 259, + CONST = 260, + BOOL = 261, + FLOAT = 262, + DOUBLE = 263, + INT = 264, + UINT = 265, + INT64_T = 266, + UINT64_T = 267, + INT16_T = 268, + UINT16_T = 269, + FLOAT16_T = 270, + BREAK = 271, + CONTINUE = 272, + DO = 273, + ELSE = 274, + FOR = 275, + IF = 276, + DISCARD = 277, + RETURN = 278, + SWITCH = 279, + CASE = 280, + DEFAULT = 281, + SUBROUTINE = 282, + BVEC2 = 283, + BVEC3 = 284, + BVEC4 = 285, + IVEC2 = 286, + IVEC3 = 287, + IVEC4 = 288, + I64VEC2 = 289, + I64VEC3 = 290, + I64VEC4 = 291, + UVEC2 = 292, + UVEC3 = 293, + UVEC4 = 294, + U64VEC2 = 295, + U64VEC3 = 296, + U64VEC4 = 297, + VEC2 = 298, + VEC3 = 299, + VEC4 = 300, + MAT2 = 301, + MAT3 = 302, + MAT4 = 303, + CENTROID = 304, + IN = 305, + OUT = 306, + INOUT = 307, + UNIFORM = 308, + PATCH = 309, + SAMPLE = 310, + BUFFER = 311, + SHARED = 312, + COHERENT = 313, + VOLATILE = 314, + RESTRICT = 315, + READONLY = 316, + WRITEONLY = 317, + DVEC2 = 318, + DVEC3 = 319, + DVEC4 = 320, + DMAT2 = 321, + DMAT3 = 322, + DMAT4 = 323, + F16VEC2 = 324, + F16VEC3 = 325, + F16VEC4 = 326, + F16MAT2 = 327, + F16MAT3 = 328, + F16MAT4 = 329, + I16VEC2 = 330, + I16VEC3 = 331, + I16VEC4 = 332, + U16VEC2 = 333, + U16VEC3 = 334, + U16VEC4 = 335, + NOPERSPECTIVE = 336, + FLAT = 337, + SMOOTH = 338, + LAYOUT = 339, + __EXPLICITINTERPAMD = 340, + MAT2X2 = 341, + MAT2X3 = 342, + MAT2X4 = 343, + MAT3X2 = 344, + MAT3X3 = 345, + MAT3X4 = 346, + MAT4X2 = 347, + MAT4X3 = 348, + MAT4X4 = 349, + DMAT2X2 = 350, + DMAT2X3 = 351, + DMAT2X4 = 352, + DMAT3X2 = 353, + DMAT3X3 = 354, + DMAT3X4 = 355, + DMAT4X2 = 356, + DMAT4X3 = 357, + DMAT4X4 = 358, + F16MAT2X2 = 359, + F16MAT2X3 = 360, + F16MAT2X4 = 361, + F16MAT3X2 = 362, + F16MAT3X3 = 363, + F16MAT3X4 = 364, + F16MAT4X2 = 365, + F16MAT4X3 = 366, + F16MAT4X4 = 367, + ATOMIC_UINT = 368, + SAMPLER1D = 369, + SAMPLER2D = 370, + SAMPLER3D = 371, + SAMPLERCUBE = 372, + SAMPLER1DSHADOW = 373, + SAMPLER2DSHADOW = 374, + SAMPLERCUBESHADOW = 375, + SAMPLER1DARRAY = 376, + SAMPLER2DARRAY = 377, + SAMPLER1DARRAYSHADOW = 378, + SAMPLER2DARRAYSHADOW = 379, + ISAMPLER1D = 380, + ISAMPLER2D = 381, + ISAMPLER3D = 382, + ISAMPLERCUBE = 383, + ISAMPLER1DARRAY = 384, + ISAMPLER2DARRAY = 385, + USAMPLER1D = 386, + USAMPLER2D = 387, + USAMPLER3D = 388, + USAMPLERCUBE = 389, + USAMPLER1DARRAY = 390, + USAMPLER2DARRAY = 391, + SAMPLER2DRECT = 392, + SAMPLER2DRECTSHADOW = 393, + ISAMPLER2DRECT = 394, + USAMPLER2DRECT = 395, + SAMPLERBUFFER = 396, + ISAMPLERBUFFER = 397, + USAMPLERBUFFER = 398, + SAMPLERCUBEARRAY = 399, + SAMPLERCUBEARRAYSHADOW = 400, + ISAMPLERCUBEARRAY = 401, + USAMPLERCUBEARRAY = 402, + SAMPLER2DMS = 403, + ISAMPLER2DMS = 404, + USAMPLER2DMS = 405, + SAMPLER2DMSARRAY = 406, + ISAMPLER2DMSARRAY = 407, + USAMPLER2DMSARRAY = 408, + SAMPLEREXTERNALOES = 409, + SAMPLER = 410, + SAMPLERSHADOW = 411, + TEXTURE1D = 412, + TEXTURE2D = 413, + TEXTURE3D = 414, + TEXTURECUBE = 415, + TEXTURE1DARRAY = 416, + TEXTURE2DARRAY = 417, + ITEXTURE1D = 418, + ITEXTURE2D = 419, + ITEXTURE3D = 420, + ITEXTURECUBE = 421, + ITEXTURE1DARRAY = 422, + ITEXTURE2DARRAY = 423, + UTEXTURE1D = 424, + UTEXTURE2D = 425, + UTEXTURE3D = 426, + UTEXTURECUBE = 427, + UTEXTURE1DARRAY = 428, + UTEXTURE2DARRAY = 429, + TEXTURE2DRECT = 430, + ITEXTURE2DRECT = 431, + UTEXTURE2DRECT = 432, + TEXTUREBUFFER = 433, + ITEXTUREBUFFER = 434, + UTEXTUREBUFFER = 435, + TEXTURECUBEARRAY = 436, + ITEXTURECUBEARRAY = 437, + UTEXTURECUBEARRAY = 438, + TEXTURE2DMS = 439, + ITEXTURE2DMS = 440, + UTEXTURE2DMS = 441, + TEXTURE2DMSARRAY = 442, + ITEXTURE2DMSARRAY = 443, + UTEXTURE2DMSARRAY = 444, + SUBPASSINPUT = 445, + SUBPASSINPUTMS = 446, + ISUBPASSINPUT = 447, + ISUBPASSINPUTMS = 448, + USUBPASSINPUT = 449, + USUBPASSINPUTMS = 450, + IMAGE1D = 451, + IIMAGE1D = 452, + UIMAGE1D = 453, + IMAGE2D = 454, + IIMAGE2D = 455, + UIMAGE2D = 456, + IMAGE3D = 457, + IIMAGE3D = 458, + UIMAGE3D = 459, + IMAGE2DRECT = 460, + IIMAGE2DRECT = 461, + UIMAGE2DRECT = 462, + IMAGECUBE = 463, + IIMAGECUBE = 464, + UIMAGECUBE = 465, + IMAGEBUFFER = 466, + IIMAGEBUFFER = 467, + UIMAGEBUFFER = 468, + IMAGE1DARRAY = 469, + IIMAGE1DARRAY = 470, + UIMAGE1DARRAY = 471, + IMAGE2DARRAY = 472, + IIMAGE2DARRAY = 473, + UIMAGE2DARRAY = 474, + IMAGECUBEARRAY = 475, + IIMAGECUBEARRAY = 476, + UIMAGECUBEARRAY = 477, + IMAGE2DMS = 478, + IIMAGE2DMS = 479, + UIMAGE2DMS = 480, + IMAGE2DMSARRAY = 481, + IIMAGE2DMSARRAY = 482, + UIMAGE2DMSARRAY = 483, + STRUCT = 484, + VOID = 485, + WHILE = 486, + IDENTIFIER = 487, + TYPE_NAME = 488, + FLOATCONSTANT = 489, + DOUBLECONSTANT = 490, + INTCONSTANT = 491, + UINTCONSTANT = 492, + INT64CONSTANT = 493, + UINT64CONSTANT = 494, + INT16CONSTANT = 495, + UINT16CONSTANT = 496, + BOOLCONSTANT = 497, + FLOAT16CONSTANT = 498, + LEFT_OP = 499, + RIGHT_OP = 500, + INC_OP = 501, + DEC_OP = 502, + LE_OP = 503, + GE_OP = 504, + EQ_OP = 505, + NE_OP = 506, + AND_OP = 507, + OR_OP = 508, + XOR_OP = 509, + MUL_ASSIGN = 510, + DIV_ASSIGN = 511, + ADD_ASSIGN = 512, + MOD_ASSIGN = 513, + LEFT_ASSIGN = 514, + RIGHT_ASSIGN = 515, + AND_ASSIGN = 516, + XOR_ASSIGN = 517, + OR_ASSIGN = 518, + SUB_ASSIGN = 519, + LEFT_PAREN = 520, + RIGHT_PAREN = 521, + LEFT_BRACKET = 522, + RIGHT_BRACKET = 523, + LEFT_BRACE = 524, + RIGHT_BRACE = 525, + DOT = 526, + COMMA = 527, + COLON = 528, + EQUAL = 529, + SEMICOLON = 530, + BANG = 531, + DASH = 532, + TILDE = 533, + PLUS = 534, + STAR = 535, + SLASH = 536, + PERCENT = 537, + LEFT_ANGLE = 538, + RIGHT_ANGLE = 539, + VERTICAL_BAR = 540, + CARET = 541, + AMPERSAND = 542, + QUESTION = 543, + INVARIANT = 544, + PRECISE = 545, + HIGH_PRECISION = 546, + MEDIUM_PRECISION = 547, + LOW_PRECISION = 548, + PRECISION = 549, + PACKED = 550, + RESOURCE = 551, + SUPERP = 552 + }; +#endif + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE YYSTYPE; +union YYSTYPE +{ +#line 68 "MachineIndependent/glslang.y" /* yacc.c:355 */ + + struct { + glslang::TSourceLoc loc; + union { + glslang::TString *string; + int i; + unsigned int u; + long long i64; + unsigned long long u64; + bool b; + double d; + }; + glslang::TSymbol* symbol; + } lex; + struct { + glslang::TSourceLoc loc; + glslang::TOperator op; + union { + TIntermNode* intermNode; + glslang::TIntermNodePair nodePair; + glslang::TIntermTyped* intermTypedNode; + }; + union { + glslang::TPublicType type; + glslang::TFunction* function; + glslang::TParameter param; + glslang::TTypeLoc typeLine; + glslang::TTypeList* typeList; + glslang::TArraySizes* arraySizes; + glslang::TIdentifierList* identifierList; + }; + } interm; + +#line 463 "MachineIndependent/glslang_tab.cpp" /* yacc.c:355 */ +}; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + + +int yyparse (glslang::TParseContext* pParseContext); + +#endif /* !YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED */ + +/* Copy the second part of user declarations. */ +#line 102 "MachineIndependent/glslang.y" /* yacc.c:358 */ + + +/* windows only pragma */ +#ifdef _MSC_VER + #pragma warning(disable : 4065) + #pragma warning(disable : 4127) + #pragma warning(disable : 4244) +#endif + +#define parseContext (*pParseContext) +#define yyerror(context, msg) context->parserError(msg) + +extern int yylex(YYSTYPE*, TParseContext&); + + +#line 492 "MachineIndependent/glslang_tab.cpp" /* yacc.c:358 */ + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#else +typedef signed char yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +# endif +# endif +# ifndef YY_ +# define YY_(Msgid) Msgid +# endif +#endif + +#ifndef __attribute__ +/* This feature is available in gcc versions 2.5 and later. */ +# if (! defined __GNUC__ || __GNUC__ < 2 \ + || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)) +# define __attribute__(Spec) /* empty */ +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(E) ((void) (E)) +#else +# define YYUSE(E) /* empty */ +#endif + +#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else +# define YY_INITIAL_VALUE(Value) Value +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +# include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's 'empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (0) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 274 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 6614 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 298 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 100 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 450 +/* YYNSTATES -- Number of states. */ +#define YYNSTATES 582 + +/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned + by yylex, with out-of-bounds checking. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 552 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, without out-of-bounds checking. */ +static const yytype_uint16 yytranslate[] = +{ + 0, 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, 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, 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, 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, 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, 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, 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, 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, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297 +}; + +#if YYDEBUG + /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 253, 253, 259, 262, 265, 269, 273, 277, 283, + 289, 292, 296, 302, 305, 313, 316, 319, 322, 325, + 330, 338, 345, 352, 358, 362, 369, 372, 378, 385, + 395, 403, 408, 438, 444, 448, 452, 472, 473, 474, + 475, 481, 482, 487, 492, 501, 502, 507, 515, 516, + 522, 531, 532, 537, 542, 547, 555, 556, 564, 575, + 576, 585, 586, 595, 596, 605, 606, 614, 615, 623, + 624, 632, 633, 633, 651, 652, 667, 671, 675, 679, + 684, 688, 692, 696, 700, 704, 708, 715, 718, 729, + 736, 741, 746, 754, 758, 762, 766, 771, 776, 785, + 785, 796, 800, 807, 814, 817, 824, 832, 852, 875, + 890, 913, 924, 934, 944, 954, 963, 966, 970, 974, + 979, 987, 992, 997, 1002, 1007, 1016, 1027, 1054, 1063, + 1070, 1077, 1084, 1096, 1102, 1105, 1112, 1116, 1120, 1128, + 1137, 1140, 1151, 1154, 1157, 1161, 1165, 1169, 1176, 1180, + 1192, 1206, 1211, 1217, 1223, 1230, 1236, 1241, 1246, 1251, + 1259, 1263, 1267, 1271, 1275, 1279, 1285, 1294, 1297, 1305, + 1309, 1318, 1323, 1331, 1335, 1345, 1349, 1353, 1358, 1365, + 1369, 1374, 1379, 1384, 1391, 1398, 1402, 1407, 1412, 1417, + 1423, 1429, 1435, 1443, 1451, 1459, 1464, 1469, 1474, 1479, + 1484, 1489, 1495, 1501, 1507, 1515, 1523, 1531, 1537, 1543, + 1549, 1555, 1561, 1567, 1575, 1583, 1591, 1596, 1601, 1606, + 1611, 1616, 1621, 1626, 1631, 1636, 1641, 1646, 1651, 1657, + 1663, 1669, 1675, 1681, 1687, 1693, 1699, 1705, 1711, 1717, + 1723, 1731, 1739, 1747, 1755, 1763, 1771, 1779, 1787, 1795, + 1803, 1811, 1819, 1824, 1829, 1834, 1839, 1844, 1849, 1854, + 1859, 1864, 1869, 1874, 1879, 1884, 1889, 1894, 1899, 1904, + 1909, 1914, 1919, 1924, 1929, 1934, 1939, 1944, 1949, 1954, + 1959, 1964, 1969, 1974, 1979, 1984, 1989, 1994, 1999, 2004, + 2009, 2014, 2019, 2024, 2029, 2034, 2039, 2044, 2049, 2054, + 2059, 2064, 2069, 2074, 2079, 2084, 2089, 2094, 2099, 2104, + 2109, 2114, 2119, 2124, 2129, 2134, 2139, 2144, 2149, 2154, + 2159, 2164, 2169, 2174, 2179, 2184, 2189, 2194, 2199, 2204, + 2209, 2214, 2219, 2224, 2229, 2234, 2239, 2244, 2249, 2254, + 2259, 2264, 2269, 2274, 2279, 2284, 2289, 2294, 2299, 2304, + 2309, 2314, 2319, 2324, 2329, 2334, 2339, 2344, 2349, 2354, + 2359, 2364, 2370, 2376, 2382, 2388, 2394, 2400, 2406, 2411, + 2427, 2432, 2437, 2445, 2445, 2456, 2456, 2466, 2469, 2482, + 2500, 2524, 2528, 2534, 2539, 2550, 2553, 2559, 2568, 2571, + 2577, 2581, 2582, 2588, 2589, 2590, 2591, 2592, 2593, 2594, + 2598, 2599, 2603, 2599, 2615, 2616, 2620, 2620, 2627, 2627, + 2641, 2644, 2652, 2660, 2671, 2672, 2676, 2683, 2687, 2695, + 2699, 2712, 2712, 2732, 2735, 2741, 2753, 2765, 2765, 2780, + 2780, 2796, 2796, 2817, 2820, 2826, 2829, 2835, 2839, 2846, + 2851, 2856, 2863, 2866, 2875, 2879, 2888, 2891, 2894, 2902, + 2902 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || 1 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "ATTRIBUTE", "VARYING", "CONST", "BOOL", + "FLOAT", "DOUBLE", "INT", "UINT", "INT64_T", "UINT64_T", "INT16_T", + "UINT16_T", "FLOAT16_T", "BREAK", "CONTINUE", "DO", "ELSE", "FOR", "IF", + "DISCARD", "RETURN", "SWITCH", "CASE", "DEFAULT", "SUBROUTINE", "BVEC2", + "BVEC3", "BVEC4", "IVEC2", "IVEC3", "IVEC4", "I64VEC2", "I64VEC3", + "I64VEC4", "UVEC2", "UVEC3", "UVEC4", "U64VEC2", "U64VEC3", "U64VEC4", + "VEC2", "VEC3", "VEC4", "MAT2", "MAT3", "MAT4", "CENTROID", "IN", "OUT", + "INOUT", "UNIFORM", "PATCH", "SAMPLE", "BUFFER", "SHARED", "COHERENT", + "VOLATILE", "RESTRICT", "READONLY", "WRITEONLY", "DVEC2", "DVEC3", + "DVEC4", "DMAT2", "DMAT3", "DMAT4", "F16VEC2", "F16VEC3", "F16VEC4", + "F16MAT2", "F16MAT3", "F16MAT4", "I16VEC2", "I16VEC3", "I16VEC4", + "U16VEC2", "U16VEC3", "U16VEC4", "NOPERSPECTIVE", "FLAT", "SMOOTH", + "LAYOUT", "__EXPLICITINTERPAMD", "MAT2X2", "MAT2X3", "MAT2X4", "MAT3X2", + "MAT3X3", "MAT3X4", "MAT4X2", "MAT4X3", "MAT4X4", "DMAT2X2", "DMAT2X3", + "DMAT2X4", "DMAT3X2", "DMAT3X3", "DMAT3X4", "DMAT4X2", "DMAT4X3", + "DMAT4X4", "F16MAT2X2", "F16MAT2X3", "F16MAT2X4", "F16MAT3X2", + "F16MAT3X3", "F16MAT3X4", "F16MAT4X2", "F16MAT4X3", "F16MAT4X4", + "ATOMIC_UINT", "SAMPLER1D", "SAMPLER2D", "SAMPLER3D", "SAMPLERCUBE", + "SAMPLER1DSHADOW", "SAMPLER2DSHADOW", "SAMPLERCUBESHADOW", + "SAMPLER1DARRAY", "SAMPLER2DARRAY", "SAMPLER1DARRAYSHADOW", + "SAMPLER2DARRAYSHADOW", "ISAMPLER1D", "ISAMPLER2D", "ISAMPLER3D", + "ISAMPLERCUBE", "ISAMPLER1DARRAY", "ISAMPLER2DARRAY", "USAMPLER1D", + "USAMPLER2D", "USAMPLER3D", "USAMPLERCUBE", "USAMPLER1DARRAY", + "USAMPLER2DARRAY", "SAMPLER2DRECT", "SAMPLER2DRECTSHADOW", + "ISAMPLER2DRECT", "USAMPLER2DRECT", "SAMPLERBUFFER", "ISAMPLERBUFFER", + "USAMPLERBUFFER", "SAMPLERCUBEARRAY", "SAMPLERCUBEARRAYSHADOW", + "ISAMPLERCUBEARRAY", "USAMPLERCUBEARRAY", "SAMPLER2DMS", "ISAMPLER2DMS", + "USAMPLER2DMS", "SAMPLER2DMSARRAY", "ISAMPLER2DMSARRAY", + "USAMPLER2DMSARRAY", "SAMPLEREXTERNALOES", "SAMPLER", "SAMPLERSHADOW", + "TEXTURE1D", "TEXTURE2D", "TEXTURE3D", "TEXTURECUBE", "TEXTURE1DARRAY", + "TEXTURE2DARRAY", "ITEXTURE1D", "ITEXTURE2D", "ITEXTURE3D", + "ITEXTURECUBE", "ITEXTURE1DARRAY", "ITEXTURE2DARRAY", "UTEXTURE1D", + "UTEXTURE2D", "UTEXTURE3D", "UTEXTURECUBE", "UTEXTURE1DARRAY", + "UTEXTURE2DARRAY", "TEXTURE2DRECT", "ITEXTURE2DRECT", "UTEXTURE2DRECT", + "TEXTUREBUFFER", "ITEXTUREBUFFER", "UTEXTUREBUFFER", "TEXTURECUBEARRAY", + "ITEXTURECUBEARRAY", "UTEXTURECUBEARRAY", "TEXTURE2DMS", "ITEXTURE2DMS", + "UTEXTURE2DMS", "TEXTURE2DMSARRAY", "ITEXTURE2DMSARRAY", + "UTEXTURE2DMSARRAY", "SUBPASSINPUT", "SUBPASSINPUTMS", "ISUBPASSINPUT", + "ISUBPASSINPUTMS", "USUBPASSINPUT", "USUBPASSINPUTMS", "IMAGE1D", + "IIMAGE1D", "UIMAGE1D", "IMAGE2D", "IIMAGE2D", "UIMAGE2D", "IMAGE3D", + "IIMAGE3D", "UIMAGE3D", "IMAGE2DRECT", "IIMAGE2DRECT", "UIMAGE2DRECT", + "IMAGECUBE", "IIMAGECUBE", "UIMAGECUBE", "IMAGEBUFFER", "IIMAGEBUFFER", + "UIMAGEBUFFER", "IMAGE1DARRAY", "IIMAGE1DARRAY", "UIMAGE1DARRAY", + "IMAGE2DARRAY", "IIMAGE2DARRAY", "UIMAGE2DARRAY", "IMAGECUBEARRAY", + "IIMAGECUBEARRAY", "UIMAGECUBEARRAY", "IMAGE2DMS", "IIMAGE2DMS", + "UIMAGE2DMS", "IMAGE2DMSARRAY", "IIMAGE2DMSARRAY", "UIMAGE2DMSARRAY", + "STRUCT", "VOID", "WHILE", "IDENTIFIER", "TYPE_NAME", "FLOATCONSTANT", + "DOUBLECONSTANT", "INTCONSTANT", "UINTCONSTANT", "INT64CONSTANT", + "UINT64CONSTANT", "INT16CONSTANT", "UINT16CONSTANT", "BOOLCONSTANT", + "FLOAT16CONSTANT", "LEFT_OP", "RIGHT_OP", "INC_OP", "DEC_OP", "LE_OP", + "GE_OP", "EQ_OP", "NE_OP", "AND_OP", "OR_OP", "XOR_OP", "MUL_ASSIGN", + "DIV_ASSIGN", "ADD_ASSIGN", "MOD_ASSIGN", "LEFT_ASSIGN", "RIGHT_ASSIGN", + "AND_ASSIGN", "XOR_ASSIGN", "OR_ASSIGN", "SUB_ASSIGN", "LEFT_PAREN", + "RIGHT_PAREN", "LEFT_BRACKET", "RIGHT_BRACKET", "LEFT_BRACE", + "RIGHT_BRACE", "DOT", "COMMA", "COLON", "EQUAL", "SEMICOLON", "BANG", + "DASH", "TILDE", "PLUS", "STAR", "SLASH", "PERCENT", "LEFT_ANGLE", + "RIGHT_ANGLE", "VERTICAL_BAR", "CARET", "AMPERSAND", "QUESTION", + "INVARIANT", "PRECISE", "HIGH_PRECISION", "MEDIUM_PRECISION", + "LOW_PRECISION", "PRECISION", "PACKED", "RESOURCE", "SUPERP", "$accept", + "variable_identifier", "primary_expression", "postfix_expression", + "integer_expression", "function_call", "function_call_or_method", + "function_call_generic", "function_call_header_no_parameters", + "function_call_header_with_parameters", "function_call_header", + "function_identifier", "unary_expression", "unary_operator", + "multiplicative_expression", "additive_expression", "shift_expression", + "relational_expression", "equality_expression", "and_expression", + "exclusive_or_expression", "inclusive_or_expression", + "logical_and_expression", "logical_xor_expression", + "logical_or_expression", "conditional_expression", "$@1", + "assignment_expression", "assignment_operator", "expression", + "constant_expression", "declaration", "block_structure", "$@2", + "identifier_list", "function_prototype", "function_declarator", + "function_header_with_parameters", "function_header", + "parameter_declarator", "parameter_declaration", + "parameter_type_specifier", "init_declarator_list", "single_declaration", + "fully_specified_type", "invariant_qualifier", "interpolation_qualifier", + "layout_qualifier", "layout_qualifier_id_list", "layout_qualifier_id", + "precise_qualifier", "type_qualifier", "single_type_qualifier", + "storage_qualifier", "type_name_list", "type_specifier", + "array_specifier", "type_specifier_nonarray", "precision_qualifier", + "struct_specifier", "$@3", "$@4", "struct_declaration_list", + "struct_declaration", "struct_declarator_list", "struct_declarator", + "initializer", "initializer_list", "declaration_statement", "statement", + "simple_statement", "compound_statement", "$@5", "$@6", + "statement_no_new_scope", "statement_scoped", "$@7", "$@8", + "compound_statement_no_new_scope", "statement_list", + "expression_statement", "selection_statement", + "selection_rest_statement", "condition", "switch_statement", "$@9", + "switch_statement_list", "case_label", "iteration_statement", "$@10", + "$@11", "$@12", "for_init_statement", "conditionopt", + "for_rest_statement", "jump_statement", "translation_unit", + "external_declaration", "function_definition", "$@13", YY_NULL +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[NUM] -- (External) token number corresponding to the + (internal) symbol number NUM (which must be that of a token). */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, + 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, + 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, + 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, + 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, + 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, + 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, + 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, + 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, + 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, + 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, + 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, + 545, 546, 547, 548, 549, 550, 551, 552 +}; +# endif + +#define YYPACT_NINF -525 + +#define yypact_value_is_default(Yystate) \ + (!!((Yystate) == (-525))) + +#define YYTABLE_NINF -407 + +#define yytable_value_is_error(Yytable_value) \ + 0 + + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +static const yytype_int16 yypact[] = +{ + 2619, -525, -525, -525, -525, -525, -525, -525, -525, -525, + -525, -525, -525, -525, -243, -525, -525, -525, -525, -525, + -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, + -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, + -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, + -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, + -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, + -525, -228, -525, -525, -525, -525, -525, -525, -525, -525, + -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, + -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, + -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, + -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, + -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, + -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, + -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, + -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, + -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, + -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, + -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, + -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, + -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, + -525, -525, -525, -525, -525, -525, -215, -525, -525, -525, + -525, -525, -525, -525, -525, -157, -525, -216, -218, -205, + -141, 4260, -165, -525, -94, -525, -525, -525, -525, 3183, + -525, -525, -525, -117, -525, -525, 575, -525, -525, -80, + -48, -114, -525, 6381, -242, -525, -525, -113, -525, 4260, + -525, -525, -525, 4260, -75, -74, -525, -235, -190, -525, + -525, -525, 4765, -108, -525, -525, -525, -186, -525, -112, + -178, -525, -525, 4260, -115, -525, -226, 867, -525, -525, + -525, -525, -117, -229, -525, 5039, -224, -525, -71, -525, + -158, -525, -525, -525, -525, -525, -525, -525, -525, -525, + -525, -525, 5861, 5861, 5861, -525, -525, -525, -525, -525, + -525, -525, -223, -525, -525, -525, -102, -177, 6121, -100, + -525, 5861, -204, -171, -132, -221, -199, -124, -120, -111, + -84, -83, -233, -98, -525, 5313, -525, -60, 5861, -525, + -48, 4260, 4260, -59, 3456, -525, -525, -525, -99, -97, + -525, -90, -88, -96, 5587, -85, 5861, -92, -79, -81, + -525, -525, -191, -525, -525, -153, -525, -218, -78, -525, + -525, -525, -525, 1159, -525, -525, -525, -525, -525, -525, + -108, 5039, -193, 5039, -525, -525, 5039, 4260, -525, -47, + -525, -525, -525, -176, -525, -525, 5861, -42, -525, -525, + 5861, -73, -525, -525, -525, 5861, 5861, 5861, 5861, 5861, + 5861, 5861, 5861, 5861, 5861, 5861, 5861, 5861, 5861, 5861, + 5861, 5861, 5861, 5861, -525, -525, -525, -76, -525, -525, + -525, -525, 3724, -59, -117, -152, -525, -525, -525, -525, + -525, 1451, -525, 5861, -525, -525, -143, 5861, -180, -525, + -525, -525, 1451, -525, -525, -525, -525, -525, -525, -525, + -525, -525, -525, -525, 5861, 5861, -525, -525, -525, -525, + 5039, -525, -133, -525, 3992, -525, -525, -72, -77, -525, + -525, -525, -525, -525, -204, -204, -171, -171, -132, -132, + -132, -132, -221, -221, -199, -124, -120, -111, -84, -83, + 5861, -525, -525, -142, -108, -59, -525, -37, 2327, -175, + -525, -163, -525, 2892, 1451, -525, -525, -525, -525, 4491, + -525, -525, -129, -525, -525, -68, -525, -525, 2892, -70, + -525, -77, -32, 4260, -63, -66, -525, -525, 5861, 5861, + -525, -69, -61, 188, -58, 2035, -525, -56, -57, 1743, + -525, -525, -161, 5861, 1743, -70, -525, -525, 1451, 5039, + -525, -525, -525, -67, -77, -525, -525, 1451, -54, -525, + -525, -525 +}; + + /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ +static const yytype_uint16 yydefact[] = +{ + 0, 149, 150, 148, 185, 176, 177, 179, 180, 181, + 182, 183, 184, 178, 165, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 207, 208, 209, 210, 211, 212, + 186, 187, 188, 216, 217, 218, 154, 152, 153, 151, + 157, 155, 156, 158, 159, 160, 161, 162, 163, 164, + 189, 190, 191, 228, 229, 230, 192, 193, 194, 240, + 241, 242, 204, 205, 206, 213, 214, 215, 131, 130, + 129, 0, 132, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 231, 232, 233, 234, 235, 236, 237, 238, + 239, 243, 244, 245, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, + 262, 263, 266, 267, 268, 269, 270, 271, 273, 274, + 275, 276, 277, 278, 280, 281, 282, 283, 284, 285, + 286, 264, 265, 272, 279, 287, 288, 289, 290, 291, + 292, 361, 293, 294, 295, 296, 297, 298, 299, 300, + 302, 303, 304, 305, 306, 307, 309, 310, 311, 312, + 313, 314, 316, 317, 318, 319, 320, 321, 301, 308, + 315, 322, 323, 324, 325, 326, 327, 362, 363, 364, + 365, 366, 367, 328, 329, 330, 331, 332, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 0, 175, 369, 448, + 128, 139, 370, 371, 372, 0, 447, 0, 449, 0, + 105, 104, 0, 116, 121, 146, 145, 143, 147, 0, + 140, 142, 126, 169, 144, 368, 0, 444, 446, 0, + 0, 0, 375, 0, 0, 93, 90, 0, 103, 0, + 112, 106, 114, 0, 115, 0, 91, 122, 0, 96, + 141, 127, 0, 170, 1, 445, 167, 0, 138, 136, + 0, 134, 373, 0, 0, 94, 0, 0, 450, 107, + 111, 113, 109, 117, 108, 0, 123, 99, 0, 97, + 0, 2, 10, 11, 4, 5, 6, 7, 8, 9, + 13, 12, 0, 0, 0, 171, 39, 38, 40, 37, + 3, 15, 33, 17, 22, 23, 0, 0, 27, 0, + 41, 0, 45, 48, 51, 56, 59, 61, 63, 65, + 67, 69, 71, 0, 31, 0, 166, 0, 0, 133, + 0, 0, 0, 0, 0, 377, 92, 95, 0, 0, + 429, 0, 0, 0, 0, 0, 0, 0, 0, 401, + 410, 414, 41, 74, 87, 0, 390, 0, 126, 393, + 412, 392, 391, 0, 394, 395, 396, 397, 398, 399, + 110, 0, 118, 0, 385, 125, 0, 0, 101, 0, + 98, 34, 35, 0, 19, 20, 0, 0, 25, 24, + 0, 175, 28, 30, 36, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 72, 172, 173, 0, 168, 89, + 137, 135, 0, 0, 383, 0, 381, 376, 378, 440, + 439, 0, 431, 0, 443, 441, 0, 0, 0, 426, + 427, 400, 0, 77, 78, 80, 79, 82, 83, 84, + 85, 86, 81, 76, 0, 0, 415, 411, 413, 120, + 0, 388, 0, 124, 0, 102, 14, 0, 21, 18, + 29, 42, 43, 44, 47, 46, 49, 50, 54, 55, + 52, 53, 57, 58, 60, 62, 64, 66, 68, 70, + 0, 174, 374, 0, 384, 0, 379, 0, 0, 0, + 442, 0, 425, 0, 402, 75, 88, 119, 386, 0, + 100, 16, 0, 380, 382, 0, 434, 433, 436, 408, + 421, 419, 0, 0, 0, 0, 387, 389, 0, 0, + 435, 0, 0, 418, 0, 0, 416, 0, 0, 0, + 403, 73, 0, 437, 0, 408, 407, 409, 423, 0, + 405, 428, 404, 0, 438, 432, 417, 424, 0, 420, + 430, 422 +}; + + /* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = +{ + -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, + -525, -525, -103, -525, -278, -274, -297, -273, -214, -211, + -210, -212, -209, -208, -525, -261, -525, -292, -525, -308, + -525, 4, -525, -525, -525, 5, -525, -525, -525, -41, + -38, -39, -525, -525, -504, -525, -525, -525, -525, -123, + -525, -230, -237, -525, -525, 0, -246, -525, 1, -525, + -525, -525, -337, -342, -207, -286, -378, -525, -285, -376, + -524, -322, -525, -525, -330, -327, -525, -525, -22, -452, + -275, -525, -525, -298, -525, -525, -525, -525, -525, -525, + -525, -525, -525, -525, -525, -525, -525, -2, -525, -525 +}; + + /* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int16 yydefgoto[] = +{ + -1, 320, 321, 322, 487, 323, 324, 325, 326, 327, + 328, 329, 372, 331, 332, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 373, 510, 374, 474, 375, + 440, 376, 227, 397, 300, 377, 229, 230, 231, 260, + 261, 262, 232, 233, 234, 235, 236, 237, 280, 281, + 238, 239, 240, 241, 277, 344, 273, 243, 244, 245, + 351, 283, 354, 355, 445, 446, 395, 482, 379, 380, + 381, 382, 462, 545, 571, 553, 554, 555, 572, 383, + 384, 385, 556, 544, 386, 557, 578, 387, 388, 523, + 451, 518, 538, 551, 552, 389, 246, 247, 248, 257 +}; + + /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ +static const yytype_int16 yytable[] = +{ + 242, 263, 270, 394, 226, 228, 403, 478, 286, 278, + 524, 343, 448, 479, 442, 481, 254, 251, 483, 542, + 433, 296, 249, 404, 405, 272, 270, 422, 423, 263, + 294, 567, 272, 285, 542, 570, 412, 250, 272, 295, + 570, 345, -32, 345, 406, 391, 390, 392, 407, 357, + 396, 426, 427, 352, 252, 434, 456, 256, 458, 255, + 484, 258, 424, 425, 463, 464, 465, 466, 467, 468, + 469, 470, 471, 472, 345, 517, 415, 416, 417, 297, + 346, 480, 298, 473, 437, 299, 347, 439, 349, 409, + 486, 539, 475, 522, 350, 410, 475, 475, 488, 394, + 448, 394, 527, 540, 394, 573, 418, 265, 419, 475, + 266, 475, 420, 421, 399, 270, 577, 400, 490, 475, + 515, 352, 476, 516, 352, 498, 499, 500, 501, 475, + 515, 259, 520, 533, 222, 223, 224, 528, 267, 529, + 494, 495, 448, 475, 548, 519, 496, 497, 478, 521, + 272, 547, 276, 502, 503, 282, 287, 292, 293, 345, + 356, 398, 348, 428, 408, 413, 429, 352, 431, 330, + 435, 432, 438, 444, 430, 452, 449, 453, 450, 454, + 457, 459, 525, 526, 279, 485, 460, -31, 394, 461, + 489, 579, 511, -26, 535, 475, 531, 549, 514, -406, + 558, 478, 532, 559, 560, 564, 563, 565, 580, 401, + 402, 369, 352, 568, 504, 541, 581, 569, 505, 507, + 506, 289, 290, 508, 291, 509, 253, 441, 414, 534, + 541, 264, 566, 536, 575, 288, 513, 394, 576, 271, + 550, 562, 330, 537, 275, 330, 242, 0, 0, 0, + 226, 228, 0, 284, 352, 574, 561, 0, 0, 264, + 0, 0, 0, 264, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 394, 0, 0, + 0, 0, 0, 353, 0, 0, 0, 378, 0, 0, + 0, 0, 0, 543, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 270, 0, 543, 0, + 0, 0, 491, 492, 493, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 353, 443, 0, 353, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 378, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 353, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 353, 0, 0, 0, 0, 0, 0, 0, + 0, 378, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 378, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 353, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 378, 0, + 0, 0, 0, 378, 378, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 378, 0, + 0, 0, 0, 271, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 378, 0, 0, 0, 378, + 0, 0, 0, 0, 378, 0, 0, 0, 378, 0, + 0, 0, 0, 0, 0, 274, 0, 378, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, 217, 0, 0, 218, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 219, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 220, 221, 222, 223, 224, 225, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 358, 359, 360, 0, 361, 362, 363, + 364, 365, 366, 367, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 368, 301, + 218, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 0, 0, 312, 313, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 314, 0, 0, 0, 369, 370, 0, 0, + 0, 0, 371, 316, 317, 318, 319, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 220, 221, 222, 223, + 224, 225, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 358, 359, 360, 0, 361, + 362, 363, 364, 365, 366, 367, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, + 368, 301, 218, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 0, 0, 312, 313, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 314, 0, 0, 0, 369, 477, + 0, 0, 0, 0, 371, 316, 317, 318, 319, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 220, 221, + 222, 223, 224, 225, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 358, 359, 360, + 0, 361, 362, 363, 364, 365, 366, 367, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, + 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, + 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, + 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 368, 301, 218, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 0, 0, 312, 313, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 0, 0, 0, + 369, 0, 0, 0, 0, 0, 371, 316, 317, 318, + 319, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 220, 221, 222, 223, 224, 225, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 358, + 359, 360, 0, 361, 362, 363, 364, 365, 366, 367, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, + 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, + 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, + 214, 215, 216, 217, 368, 301, 218, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 0, 0, 312, + 313, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 314, 0, + 0, 0, 287, 0, 0, 0, 0, 0, 371, 316, + 317, 318, 319, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 220, 221, 222, 223, 224, 225, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 358, 359, 360, 0, 361, 362, 363, 364, 365, + 366, 367, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, 217, 368, 301, 218, 302, + 303, 304, 305, 306, 307, 308, 309, 310, 311, 0, + 0, 312, 313, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 314, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 371, 316, 317, 318, 319, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 220, 221, 222, 223, 224, 225, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 0, 301, + 218, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 0, 0, 312, 313, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 314, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 371, 316, 317, 318, 319, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 220, 221, 222, 223, + 224, 225, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, + 0, 0, 218, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 219, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 220, 221, + 222, 223, 224, 225, 0, 0, 0, 0, 0, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 0, 301, 218, 302, 303, 304, 305, + 306, 307, 308, 309, 310, 311, 0, 0, 312, 313, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 314, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 316, 317, + 318, 319, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 220, 221, 222, 223, 224, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, + 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, + 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, + 214, 215, 216, 217, 0, 268, 218, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 269, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 220, 221, 222, 223, 224, 0, 0, 0, + 0, 0, 0, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, + 211, 212, 213, 214, 215, 216, 217, 0, 0, 218, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 447, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 0, 0, 0, 0, 0, 220, 221, 222, 223, 224, + 0, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, 0, 0, 218, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 512, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, + 0, 0, 0, 220, 221, 222, 223, 224, 0, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 0, 0, 218, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 530, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, + 0, 220, 221, 222, 223, 224, 0, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 0, 0, 218, 0, 0, 0, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, + 221, 222, 223, 224, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 0, 0, 0, 0, 0, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, + 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, + 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, + 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 0, 301, 218, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 0, 0, 312, 313, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 0, 0, 0, + 393, 546, 0, 0, 0, 0, 0, 316, 317, 318, + 319, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 0, 0, 0, 0, + 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, 217, 0, 301, 218, 302, + 303, 304, 305, 306, 307, 308, 309, 310, 311, 0, + 0, 312, 313, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 314, 0, 0, 315, 0, 0, 0, 0, 0, 0, + 0, 316, 317, 318, 319, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 0, 0, 0, 0, 0, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, + 0, 301, 218, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 0, 0, 312, 313, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 314, 0, 0, 0, 393, 0, + 0, 0, 0, 0, 0, 316, 317, 318, 319, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 0, 0, 0, 0, 0, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, + 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, + 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, + 214, 215, 216, 217, 0, 301, 218, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 0, 0, 312, + 313, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 314, 0, + 0, 436, 0, 0, 0, 0, 0, 0, 0, 316, + 317, 318, 319, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 0, 0, + 0, 0, 0, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 0, 301, + 218, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 0, 0, 312, 313, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 314, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 455, 316, 317, 318, 319, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 0, 0, 0, 0, 0, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, + 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, + 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, + 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 0, 301, 218, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 0, 0, 312, 313, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 316, 317, 318, + 319, 0, 0, 0, 0, 0, 0, 0, 0, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 0, 0, 0, 0, 0, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, + 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, + 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, + 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, + 216, 411, 0, 301, 218, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 0, 0, 312, 313, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 316, 317, 318, + 319, 0, 0, 0, 0, 0, 0, 0, 0, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 0, 0, 0, 0, 0, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, + 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, + 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, + 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 0, 0, 218 +}; + +static const yytype_int16 yycheck[] = +{ + 0, 231, 239, 295, 0, 0, 314, 383, 254, 57, + 462, 272, 354, 391, 351, 393, 232, 232, 396, 523, + 253, 267, 265, 246, 247, 267, 263, 248, 249, 259, + 265, 555, 267, 275, 538, 559, 328, 265, 267, 274, + 564, 267, 265, 267, 267, 274, 292, 293, 271, 275, + 274, 250, 251, 283, 269, 288, 364, 275, 366, 275, + 397, 266, 283, 284, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 267, 451, 280, 281, 282, 269, + 266, 274, 272, 274, 345, 275, 272, 348, 266, 266, + 266, 266, 272, 273, 272, 272, 272, 272, 406, 391, + 442, 393, 480, 266, 396, 266, 277, 272, 279, 272, + 275, 272, 244, 245, 272, 352, 568, 275, 410, 272, + 272, 351, 275, 275, 354, 422, 423, 424, 425, 272, + 272, 272, 275, 275, 291, 292, 293, 270, 232, 272, + 418, 419, 484, 272, 273, 453, 420, 421, 524, 457, + 267, 529, 232, 426, 427, 269, 269, 232, 232, 267, + 275, 232, 274, 287, 266, 265, 286, 397, 252, 272, + 268, 254, 232, 232, 285, 265, 275, 265, 275, 275, + 265, 273, 474, 475, 232, 232, 265, 265, 480, 270, + 232, 569, 268, 266, 231, 272, 268, 265, 444, 269, + 232, 577, 510, 266, 270, 266, 275, 19, 275, 312, + 313, 269, 442, 269, 428, 523, 270, 274, 429, 431, + 430, 259, 263, 432, 263, 433, 225, 350, 331, 515, + 538, 231, 554, 518, 564, 257, 443, 529, 565, 239, + 538, 549, 345, 518, 246, 348, 246, -1, -1, -1, + 246, 246, -1, 253, 484, 563, 548, -1, -1, 259, + -1, -1, -1, 263, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 569, -1, -1, + -1, -1, -1, 283, -1, -1, -1, 287, -1, -1, + -1, -1, -1, 523, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 543, -1, 538, -1, + -1, -1, 415, 416, 417, 418, 419, 420, 421, 422, + 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, + 433, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 351, 352, -1, 354, -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, 383, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 397, -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, 442, -1, -1, -1, -1, -1, -1, -1, + -1, 451, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 462, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 484, -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, 518, -1, + -1, -1, -1, 523, 524, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 538, -1, + -1, -1, -1, 543, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 555, -1, -1, -1, 559, + -1, -1, -1, -1, 564, -1, -1, -1, 568, -1, + -1, -1, -1, -1, -1, 0, -1, 577, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, -1, -1, 233, -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, + 275, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 289, 290, 291, 292, 293, 294, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, -1, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 243, -1, -1, 246, 247, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 265, -1, -1, -1, 269, 270, -1, -1, + -1, -1, 275, 276, 277, 278, 279, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 289, 290, 291, 292, + 293, 294, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, -1, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, + 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, + 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, -1, -1, 246, 247, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 265, -1, -1, -1, 269, 270, + -1, -1, -1, -1, 275, 276, 277, 278, 279, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 289, 290, + 291, 292, 293, 294, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + -1, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, -1, -1, 246, 247, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 265, -1, -1, -1, + 269, -1, -1, -1, -1, -1, 275, 276, 277, 278, + 279, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 289, 290, 291, 292, 293, 294, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, -1, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, -1, -1, 246, + 247, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 265, -1, + -1, -1, 269, -1, -1, -1, -1, -1, 275, 276, + 277, 278, 279, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 289, 290, 291, 292, 293, 294, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, -1, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, -1, + -1, 246, 247, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 265, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 275, 276, 277, 278, 279, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 289, 290, 291, 292, 293, 294, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 229, 230, -1, 232, + 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 243, -1, -1, 246, 247, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 265, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 275, 276, 277, 278, 279, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 289, 290, 291, 292, + 293, 294, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, + 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, + -1, -1, 233, -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, 275, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 289, 290, + 291, 292, 293, 294, -1, -1, -1, -1, -1, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, -1, 232, 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, 243, -1, -1, 246, 247, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 265, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 276, 277, + 278, 279, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 289, 290, 291, 292, 293, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, -1, 232, 233, -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, 275, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 289, 290, 291, 292, 293, -1, -1, -1, + -1, -1, -1, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, + 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, + 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, + 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, -1, -1, 233, + -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, 270, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + -1, -1, -1, -1, -1, 289, 290, 291, 292, 293, + -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, + 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, + 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, + 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 228, 229, 230, -1, -1, 233, -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, 270, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, + -1, -1, -1, 289, 290, 291, 292, 293, -1, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, -1, -1, 233, -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, 270, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, + -1, 289, 290, 291, 292, 293, -1, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, + 230, -1, -1, 233, -1, -1, -1, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 289, + 290, 291, 292, 293, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, -1, -1, -1, -1, -1, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, -1, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, -1, -1, 246, 247, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 265, -1, -1, -1, + 269, 270, -1, -1, -1, -1, -1, 276, 277, 278, + 279, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, -1, -1, -1, -1, + -1, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, -1, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, -1, + -1, 246, 247, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 265, -1, -1, 268, -1, -1, -1, -1, -1, -1, + -1, 276, 277, 278, 279, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + -1, -1, -1, -1, -1, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, + 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, + -1, 232, 233, 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, -1, -1, 246, 247, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 265, -1, -1, -1, 269, -1, + -1, -1, -1, -1, -1, 276, 277, 278, 279, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, -1, -1, -1, -1, -1, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, -1, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, -1, -1, 246, + 247, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 265, -1, + -1, 268, -1, -1, -1, -1, -1, -1, -1, 276, + 277, 278, 279, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, -1, -1, + -1, -1, -1, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 229, 230, -1, 232, + 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 243, -1, -1, 246, 247, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 265, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 275, 276, 277, 278, 279, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, -1, -1, -1, -1, -1, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, -1, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, -1, -1, 246, 247, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 265, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 276, 277, 278, + 279, -1, -1, -1, -1, -1, -1, -1, -1, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, -1, -1, -1, -1, -1, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, -1, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, -1, -1, 246, 247, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 265, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 276, 277, 278, + 279, -1, -1, -1, -1, -1, -1, -1, -1, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, -1, -1, -1, -1, -1, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, -1, -1, 233 +}; + + /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint16 yystos[] = +{ + 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 229, 230, 233, 275, + 289, 290, 291, 292, 293, 294, 329, 330, 333, 334, + 335, 336, 340, 341, 342, 343, 344, 345, 348, 349, + 350, 351, 353, 355, 356, 357, 394, 395, 396, 265, + 265, 232, 269, 356, 232, 275, 275, 397, 266, 272, + 337, 338, 339, 349, 353, 272, 275, 232, 232, 275, + 350, 353, 267, 354, 0, 395, 232, 352, 57, 232, + 346, 347, 269, 359, 353, 275, 354, 269, 376, 338, + 337, 339, 232, 232, 265, 274, 354, 269, 272, 275, + 332, 232, 234, 235, 236, 237, 238, 239, 240, 241, + 242, 243, 246, 247, 265, 268, 276, 277, 278, 279, + 299, 300, 301, 303, 304, 305, 306, 307, 308, 309, + 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, + 320, 321, 322, 323, 353, 267, 266, 272, 274, 266, + 272, 358, 349, 353, 360, 361, 275, 275, 16, 17, + 18, 20, 21, 22, 23, 24, 25, 26, 231, 269, + 270, 275, 310, 323, 325, 327, 329, 333, 353, 366, + 367, 368, 369, 377, 378, 379, 382, 385, 386, 393, + 354, 274, 354, 269, 325, 364, 274, 331, 232, 272, + 275, 310, 310, 327, 246, 247, 267, 271, 266, 266, + 272, 230, 325, 265, 310, 280, 281, 282, 277, 279, + 244, 245, 248, 249, 283, 284, 250, 251, 287, 286, + 285, 252, 254, 253, 288, 268, 268, 323, 232, 323, + 328, 347, 360, 353, 232, 362, 363, 270, 361, 275, + 275, 388, 265, 265, 275, 275, 327, 265, 327, 273, + 265, 270, 370, 255, 256, 257, 258, 259, 260, 261, + 262, 263, 264, 274, 326, 272, 275, 270, 367, 364, + 274, 364, 365, 364, 360, 232, 266, 302, 327, 232, + 325, 310, 310, 310, 312, 312, 313, 313, 314, 314, + 314, 314, 315, 315, 316, 317, 318, 319, 320, 321, + 324, 268, 270, 362, 354, 272, 275, 367, 389, 327, + 275, 327, 273, 387, 377, 325, 325, 364, 270, 272, + 270, 268, 327, 275, 363, 231, 366, 378, 390, 266, + 266, 327, 342, 349, 381, 371, 270, 364, 273, 265, + 381, 391, 392, 373, 374, 375, 380, 383, 232, 266, + 270, 325, 327, 275, 266, 19, 369, 368, 269, 274, + 368, 372, 376, 266, 327, 372, 373, 377, 384, 364, + 275, 270 +}; + + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint16 yyr1[] = +{ + 0, 298, 299, 300, 300, 300, 300, 300, 300, 300, + 300, 300, 300, 300, 300, 301, 301, 301, 301, 301, + 301, 302, 303, 304, 305, 305, 306, 306, 307, 307, + 308, 309, 309, 310, 310, 310, 310, 311, 311, 311, + 311, 312, 312, 312, 312, 313, 313, 313, 314, 314, + 314, 315, 315, 315, 315, 315, 316, 316, 316, 317, + 317, 318, 318, 319, 319, 320, 320, 321, 321, 322, + 322, 323, 324, 323, 325, 325, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 327, 327, 328, + 329, 329, 329, 329, 329, 329, 329, 329, 329, 331, + 330, 332, 332, 333, 334, 334, 335, 335, 336, 337, + 337, 338, 338, 338, 338, 339, 340, 340, 340, 340, + 340, 341, 341, 341, 341, 341, 342, 342, 343, 344, + 344, 344, 344, 345, 346, 346, 347, 347, 347, 348, + 349, 349, 350, 350, 350, 350, 350, 350, 351, 351, + 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, + 351, 351, 351, 351, 351, 351, 351, 352, 352, 353, + 353, 354, 354, 354, 354, 355, 355, 355, 355, 355, + 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, + 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, + 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, + 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, + 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, + 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, + 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, + 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, + 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, + 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, + 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, + 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, + 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, + 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, + 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, + 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, + 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, + 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, + 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, + 356, 356, 356, 358, 357, 359, 357, 360, 360, 361, + 361, 362, 362, 363, 363, 364, 364, 364, 365, 365, + 366, 367, 367, 368, 368, 368, 368, 368, 368, 368, + 369, 370, 371, 369, 372, 372, 374, 373, 375, 373, + 376, 376, 377, 377, 378, 378, 379, 380, 380, 381, + 381, 383, 382, 384, 384, 385, 385, 387, 386, 388, + 386, 389, 386, 390, 390, 391, 391, 392, 392, 393, + 393, 393, 393, 393, 394, 394, 395, 395, 395, 397, + 396 +}; + + /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 1, 4, 1, 3, 2, + 2, 1, 1, 1, 2, 2, 2, 1, 2, 3, + 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, + 1, 1, 3, 3, 3, 1, 3, 3, 1, 3, + 3, 1, 3, 3, 3, 3, 1, 3, 3, 1, + 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, + 3, 1, 0, 6, 1, 3, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, + 2, 2, 4, 2, 3, 4, 2, 3, 4, 0, + 6, 2, 3, 2, 1, 1, 2, 3, 3, 2, + 3, 2, 1, 2, 1, 1, 1, 3, 4, 6, + 5, 1, 2, 3, 5, 4, 1, 2, 1, 1, + 1, 1, 1, 4, 1, 3, 1, 3, 1, 1, + 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 4, 1, 3, 1, + 2, 2, 3, 3, 4, 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, 1, 1, 1, + 1, 1, 1, 0, 6, 0, 5, 1, 2, 3, + 4, 1, 3, 1, 2, 1, 3, 4, 1, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 0, 0, 5, 1, 1, 0, 2, 0, 2, + 2, 3, 1, 2, 1, 2, 5, 3, 1, 1, + 4, 0, 8, 0, 1, 3, 2, 0, 6, 0, + 8, 0, 7, 1, 1, 1, 0, 2, 3, 2, + 2, 2, 3, 2, 1, 2, 1, 1, 1, 0, + 3 +}; + + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (pParseContext, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (0) + +/* Error token number */ +#define YYTERROR 1 +#define YYERRCODE 256 + + + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +/* This macro is provided for backward compatibility. */ +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value, pParseContext); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + + +/*----------------------------------------. +| Print this symbol's value on YYOUTPUT. | +`----------------------------------------*/ + +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, glslang::TParseContext* pParseContext) +{ + FILE *yyo = yyoutput; + YYUSE (yyo); + YYUSE (pParseContext); + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + YYUSE (yytype); +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, glslang::TParseContext* pParseContext) +{ + YYFPRINTF (yyoutput, "%s %s (", + yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep, pParseContext); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +static void +yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, glslang::TParseContext* pParseContext) +{ + unsigned long int yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, + yystos[yyssp[yyi + 1 - yynrhs]], + &(yyvsp[(yyi + 1) - (yynrhs)]) + , pParseContext); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, Rule, pParseContext); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +yystrlen (const char *yystr) +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +yystpcpy (char *yydest, const char *yysrc) +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULL; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + { + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + } + } + } + + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + { + YYSIZE_T yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, glslang::TParseContext* pParseContext) +{ + YYUSE (yyvaluep); + YYUSE (pParseContext); + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YYUSE (yytype); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + + + +/*----------. +| yyparse. | +`----------*/ + +int +yyparse (glslang::TParseContext* pParseContext) +{ +/* The lookahead symbol. */ +int yychar; + + +/* The semantic value of the lookahead symbol. */ +/* Default value used for initialization, for pacifying older GCCs + or non-GCC compilers. */ +YY_INITIAL_VALUE (static YYSTYPE yyval_default;) +YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + /* Number of syntax errors so far. */ + int yynerrs; + + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + 'yyss': related to states. + 'yyvs': related to semantic values. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = yylex (&yylval, parseContext); + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + '$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +#line 253 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleVariable((yyvsp[0].lex).loc, (yyvsp[0].lex).symbol, (yyvsp[0].lex).string); + } +#line 3344 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 3: +#line 259 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); + } +#line 3352 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 4: +#line 262 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); + } +#line 3360 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 5: +#line 265 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); + } +#line 3369 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 6: +#line 269 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i64, (yyvsp[0].lex).loc, true); + } +#line 3378 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 7: +#line 273 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u64, (yyvsp[0].lex).loc, true); + } +#line 3387 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 8: +#line 277 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.int16Check((yyvsp[0].lex).loc, "16-bit integer literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((short)(yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); +#endif + } +#line 3398 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 9: +#line 283 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.int16Check((yyvsp[0].lex).loc, "16-bit unsigned integer literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((unsigned short)(yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); +#endif + } +#line 3409 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 10: +#line 289 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat, (yyvsp[0].lex).loc, true); + } +#line 3417 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 11: +#line 292 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.doubleCheck((yyvsp[0].lex).loc, "double literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtDouble, (yyvsp[0].lex).loc, true); + } +#line 3426 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 12: +#line 296 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16Check((yyvsp[0].lex).loc, "half float literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat16, (yyvsp[0].lex).loc, true); +#endif + } +#line 3437 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 13: +#line 302 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).b, (yyvsp[0].lex).loc, true); + } +#line 3445 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 14: +#line 305 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = (yyvsp[-1].interm.intermTypedNode); + if ((yyval.interm.intermTypedNode)->getAsConstantUnion()) + (yyval.interm.intermTypedNode)->getAsConstantUnion()->setExpression(); + } +#line 3455 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 15: +#line 313 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); + } +#line 3463 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 16: +#line 316 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleBracketDereference((yyvsp[-2].lex).loc, (yyvsp[-3].interm.intermTypedNode), (yyvsp[-1].interm.intermTypedNode)); + } +#line 3471 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 17: +#line 319 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); + } +#line 3479 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 18: +#line 322 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleDotDereference((yyvsp[0].lex).loc, (yyvsp[-2].interm.intermTypedNode), *(yyvsp[0].lex).string); + } +#line 3487 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 19: +#line 325 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.variableCheck((yyvsp[-1].interm.intermTypedNode)); + parseContext.lValueErrorCheck((yyvsp[0].lex).loc, "++", (yyvsp[-1].interm.intermTypedNode)); + (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[0].lex).loc, "++", EOpPostIncrement, (yyvsp[-1].interm.intermTypedNode)); + } +#line 3497 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 20: +#line 330 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.variableCheck((yyvsp[-1].interm.intermTypedNode)); + parseContext.lValueErrorCheck((yyvsp[0].lex).loc, "--", (yyvsp[-1].interm.intermTypedNode)); + (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[0].lex).loc, "--", EOpPostDecrement, (yyvsp[-1].interm.intermTypedNode)); + } +#line 3507 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 21: +#line 338 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.integerCheck((yyvsp[0].interm.intermTypedNode), "[]"); + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); + } +#line 3516 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 22: +#line 345 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleFunctionCall((yyvsp[0].interm).loc, (yyvsp[0].interm).function, (yyvsp[0].interm).intermNode); + delete (yyvsp[0].interm).function; + } +#line 3525 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 23: +#line 352 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[0].interm); + } +#line 3533 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 24: +#line 358 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[-1].interm); + (yyval.interm).loc = (yyvsp[0].lex).loc; + } +#line 3542 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 25: +#line 362 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[-1].interm); + (yyval.interm).loc = (yyvsp[0].lex).loc; + } +#line 3551 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 26: +#line 369 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[-1].interm); + } +#line 3559 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 27: +#line 372 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[0].interm); + } +#line 3567 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 28: +#line 378 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + TParameter param = { 0, new TType }; + param.type->shallowCopy((yyvsp[0].interm.intermTypedNode)->getType()); + (yyvsp[-1].interm).function->addParameter(param); + (yyval.interm).function = (yyvsp[-1].interm).function; + (yyval.interm).intermNode = (yyvsp[0].interm.intermTypedNode); + } +#line 3579 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 29: +#line 385 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + TParameter param = { 0, new TType }; + param.type->shallowCopy((yyvsp[0].interm.intermTypedNode)->getType()); + (yyvsp[-2].interm).function->addParameter(param); + (yyval.interm).function = (yyvsp[-2].interm).function; + (yyval.interm).intermNode = parseContext.intermediate.growAggregate((yyvsp[-2].interm).intermNode, (yyvsp[0].interm.intermTypedNode), (yyvsp[-1].lex).loc); + } +#line 3591 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 30: +#line 395 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[-1].interm); + } +#line 3599 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 31: +#line 403 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + // Constructor + (yyval.interm).intermNode = 0; + (yyval.interm).function = parseContext.handleConstructorCall((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type)); + } +#line 3609 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 32: +#line 408 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + // + // Should be a method or subroutine call, but we haven't recognized the arguments yet. + // + (yyval.interm).function = 0; + (yyval.interm).intermNode = 0; + + TIntermMethod* method = (yyvsp[0].interm.intermTypedNode)->getAsMethodNode(); + if (method) { + (yyval.interm).function = new TFunction(&method->getMethodName(), TType(EbtInt), EOpArrayLength); + (yyval.interm).intermNode = method->getObject(); + } else { + TIntermSymbol* symbol = (yyvsp[0].interm.intermTypedNode)->getAsSymbolNode(); + if (symbol) { + parseContext.reservedErrorCheck(symbol->getLoc(), symbol->getName()); + TFunction *function = new TFunction(&symbol->getName(), TType(EbtVoid)); + (yyval.interm).function = function; + } else + parseContext.error((yyvsp[0].interm.intermTypedNode)->getLoc(), "function call, method, or subroutine call expected", "", ""); + } + + if ((yyval.interm).function == 0) { + // error recover + TString empty(""); + (yyval.interm).function = new TFunction(&empty, TType(EbtVoid), EOpNull); + } + } +#line 3641 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 33: +#line 438 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.variableCheck((yyvsp[0].interm.intermTypedNode)); + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); + if (TIntermMethod* method = (yyvsp[0].interm.intermTypedNode)->getAsMethodNode()) + parseContext.error((yyvsp[0].interm.intermTypedNode)->getLoc(), "incomplete method syntax", method->getMethodName().c_str(), ""); + } +#line 3652 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 34: +#line 444 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.lValueErrorCheck((yyvsp[-1].lex).loc, "++", (yyvsp[0].interm.intermTypedNode)); + (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[-1].lex).loc, "++", EOpPreIncrement, (yyvsp[0].interm.intermTypedNode)); + } +#line 3661 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 35: +#line 448 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.lValueErrorCheck((yyvsp[-1].lex).loc, "--", (yyvsp[0].interm.intermTypedNode)); + (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[-1].lex).loc, "--", EOpPreDecrement, (yyvsp[0].interm.intermTypedNode)); + } +#line 3670 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 36: +#line 452 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + if ((yyvsp[-1].interm).op != EOpNull) { + char errorOp[2] = {0, 0}; + switch((yyvsp[-1].interm).op) { + case EOpNegative: errorOp[0] = '-'; break; + case EOpLogicalNot: errorOp[0] = '!'; break; + case EOpBitwiseNot: errorOp[0] = '~'; break; + default: break; // some compilers want this + } + (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[-1].interm).loc, errorOp, (yyvsp[-1].interm).op, (yyvsp[0].interm.intermTypedNode)); + } else { + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); + if ((yyval.interm.intermTypedNode)->getAsConstantUnion()) + (yyval.interm.intermTypedNode)->getAsConstantUnion()->setExpression(); + } + } +#line 3691 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 37: +#line 472 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpNull; } +#line 3697 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 38: +#line 473 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpNegative; } +#line 3703 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 39: +#line 474 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpLogicalNot; } +#line 3709 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 40: +#line 475 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpBitwiseNot; + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise not"); } +#line 3716 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 41: +#line 481 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 3722 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 42: +#line 482 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "*", EOpMul, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + } +#line 3732 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 43: +#line 487 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "/", EOpDiv, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + } +#line 3742 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 44: +#line 492 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "%"); + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "%", EOpMod, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + } +#line 3753 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 45: +#line 501 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 3759 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 46: +#line 502 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "+", EOpAdd, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + } +#line 3769 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 47: +#line 507 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "-", EOpSub, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + } +#line 3779 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 48: +#line 515 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 3785 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 49: +#line 516 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bit shift left"); + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "<<", EOpLeftShift, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + } +#line 3796 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 50: +#line 522 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bit shift right"); + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, ">>", EOpRightShift, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + } +#line 3807 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 51: +#line 531 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 3813 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 52: +#line 532 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "<", EOpLessThan, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); + } +#line 3823 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 53: +#line 537 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, ">", EOpGreaterThan, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); + } +#line 3833 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 54: +#line 542 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "<=", EOpLessThanEqual, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); + } +#line 3843 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 55: +#line 547 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, ">=", EOpGreaterThanEqual, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); + } +#line 3853 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 56: +#line 555 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 3859 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 57: +#line 556 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.arrayObjectCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "array comparison"); + parseContext.opaqueCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "=="); + parseContext.specializationCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "=="); + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "==", EOpEqual, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); + } +#line 3872 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 58: +#line 564 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.arrayObjectCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "array comparison"); + parseContext.opaqueCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "!="); + parseContext.specializationCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "!="); + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "!=", EOpNotEqual, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); + } +#line 3885 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 59: +#line 575 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 3891 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 60: +#line 576 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bitwise and"); + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "&", EOpAnd, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + } +#line 3902 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 61: +#line 585 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 3908 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 62: +#line 586 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bitwise exclusive or"); + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "^", EOpExclusiveOr, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + } +#line 3919 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 63: +#line 595 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 3925 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 64: +#line 596 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bitwise inclusive or"); + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "|", EOpInclusiveOr, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + } +#line 3936 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 65: +#line 605 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 3942 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 66: +#line 606 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "&&", EOpLogicalAnd, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); + } +#line 3952 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 67: +#line 614 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 3958 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 68: +#line 615 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "^^", EOpLogicalXor, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); + } +#line 3968 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 69: +#line 623 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 3974 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 70: +#line 624 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "||", EOpLogicalOr, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); + } +#line 3984 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 71: +#line 632 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 3990 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 72: +#line 633 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + ++parseContext.controlFlowNestingLevel; + } +#line 3998 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 73: +#line 636 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + --parseContext.controlFlowNestingLevel; + parseContext.boolCheck((yyvsp[-4].lex).loc, (yyvsp[-5].interm.intermTypedNode)); + parseContext.rValueErrorCheck((yyvsp[-4].lex).loc, "?", (yyvsp[-5].interm.intermTypedNode)); + parseContext.rValueErrorCheck((yyvsp[-1].lex).loc, ":", (yyvsp[-2].interm.intermTypedNode)); + parseContext.rValueErrorCheck((yyvsp[-1].lex).loc, ":", (yyvsp[0].interm.intermTypedNode)); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addSelection((yyvsp[-5].interm.intermTypedNode), (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yyvsp[-4].lex).loc); + if ((yyval.interm.intermTypedNode) == 0) { + parseContext.binaryOpError((yyvsp[-4].lex).loc, ":", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(), (yyvsp[0].interm.intermTypedNode)->getCompleteString()); + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); + } + } +#line 4015 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 74: +#line 651 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4021 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 75: +#line 652 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.arrayObjectCheck((yyvsp[-1].interm).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "array assignment"); + parseContext.opaqueCheck((yyvsp[-1].interm).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "="); + parseContext.specializationCheck((yyvsp[-1].interm).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "="); + parseContext.lValueErrorCheck((yyvsp[-1].interm).loc, "assign", (yyvsp[-2].interm.intermTypedNode)); + parseContext.rValueErrorCheck((yyvsp[-1].interm).loc, "assign", (yyvsp[0].interm.intermTypedNode)); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addAssign((yyvsp[-1].interm).op, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yyvsp[-1].interm).loc); + if ((yyval.interm.intermTypedNode) == 0) { + parseContext.assignError((yyvsp[-1].interm).loc, "assign", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(), (yyvsp[0].interm.intermTypedNode)->getCompleteString()); + (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + } + } +#line 4038 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 76: +#line 667 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm).loc = (yyvsp[0].lex).loc; + (yyval.interm).op = EOpAssign; + } +#line 4047 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 77: +#line 671 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm).loc = (yyvsp[0].lex).loc; + (yyval.interm).op = EOpMulAssign; + } +#line 4056 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 78: +#line 675 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm).loc = (yyvsp[0].lex).loc; + (yyval.interm).op = EOpDivAssign; + } +#line 4065 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 79: +#line 679 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "%="); + (yyval.interm).loc = (yyvsp[0].lex).loc; + (yyval.interm).op = EOpModAssign; + } +#line 4075 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 80: +#line 684 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm).loc = (yyvsp[0].lex).loc; + (yyval.interm).op = EOpAddAssign; + } +#line 4084 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 81: +#line 688 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm).loc = (yyvsp[0].lex).loc; + (yyval.interm).op = EOpSubAssign; + } +#line 4093 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 82: +#line 692 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bit-shift left assign"); + (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpLeftShiftAssign; + } +#line 4102 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 83: +#line 696 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bit-shift right assign"); + (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpRightShiftAssign; + } +#line 4111 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 84: +#line 700 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise-and assign"); + (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpAndAssign; + } +#line 4120 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 85: +#line 704 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise-xor assign"); + (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpExclusiveOrAssign; + } +#line 4129 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 86: +#line 708 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise-or assign"); + (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpInclusiveOrAssign; + } +#line 4138 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 87: +#line 715 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); + } +#line 4146 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 88: +#line 718 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.samplerConstructorLocationCheck((yyvsp[-1].lex).loc, ",", (yyvsp[0].interm.intermTypedNode)); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addComma((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yyvsp[-1].lex).loc); + if ((yyval.interm.intermTypedNode) == 0) { + parseContext.binaryOpError((yyvsp[-1].lex).loc, ",", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(), (yyvsp[0].interm.intermTypedNode)->getCompleteString()); + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); + } + } +#line 4159 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 89: +#line 729 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.constantValueCheck((yyvsp[0].interm.intermTypedNode), ""); + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); + } +#line 4168 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 90: +#line 736 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.handleFunctionDeclarator((yyvsp[-1].interm).loc, *(yyvsp[-1].interm).function, true /* prototype */); + (yyval.interm.intermNode) = 0; + // TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature + } +#line 4178 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 91: +#line 741 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + if ((yyvsp[-1].interm).intermNode && (yyvsp[-1].interm).intermNode->getAsAggregate()) + (yyvsp[-1].interm).intermNode->getAsAggregate()->setOperator(EOpSequence); + (yyval.interm.intermNode) = (yyvsp[-1].interm).intermNode; + } +#line 4188 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 92: +#line 746 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.profileRequires((yyvsp[-3].lex).loc, ENoProfile, 130, 0, "precision statement"); + + // lazy setting of the previous scope's defaults, has effect only the first time it is called in a particular scope + parseContext.symbolTable.setPreviousDefaultPrecisions(&parseContext.defaultPrecision[0]); + parseContext.setDefaultPrecision((yyvsp[-3].lex).loc, (yyvsp[-1].interm.type), (yyvsp[-2].interm.type).qualifier.precision); + (yyval.interm.intermNode) = 0; + } +#line 4201 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 93: +#line 754 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.declareBlock((yyvsp[-1].interm).loc, *(yyvsp[-1].interm).typeList); + (yyval.interm.intermNode) = 0; + } +#line 4210 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 94: +#line 758 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.declareBlock((yyvsp[-2].interm).loc, *(yyvsp[-2].interm).typeList, (yyvsp[-1].lex).string); + (yyval.interm.intermNode) = 0; + } +#line 4219 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 95: +#line 762 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.declareBlock((yyvsp[-3].interm).loc, *(yyvsp[-3].interm).typeList, (yyvsp[-2].lex).string, (yyvsp[-1].interm).arraySizes); + (yyval.interm.intermNode) = 0; + } +#line 4228 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 96: +#line 766 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.globalQualifierFixCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier); + parseContext.updateStandaloneQualifierDefaults((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type)); + (yyval.interm.intermNode) = 0; + } +#line 4238 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 97: +#line 771 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.checkNoShaderLayouts((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).shaderQualifiers); + parseContext.addQualifierToExisting((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).qualifier, *(yyvsp[-1].lex).string); + (yyval.interm.intermNode) = 0; + } +#line 4248 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 98: +#line 776 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.checkNoShaderLayouts((yyvsp[-3].interm.type).loc, (yyvsp[-3].interm.type).shaderQualifiers); + (yyvsp[-1].interm.identifierList)->push_back((yyvsp[-2].lex).string); + parseContext.addQualifierToExisting((yyvsp[-3].interm.type).loc, (yyvsp[-3].interm.type).qualifier, *(yyvsp[-1].interm.identifierList)); + (yyval.interm.intermNode) = 0; + } +#line 4259 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 99: +#line 785 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { parseContext.nestedBlockCheck((yyvsp[-2].interm.type).loc); } +#line 4265 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 100: +#line 785 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + --parseContext.structNestingLevel; + parseContext.blockName = (yyvsp[-4].lex).string; + parseContext.globalQualifierFixCheck((yyvsp[-5].interm.type).loc, (yyvsp[-5].interm.type).qualifier); + parseContext.checkNoShaderLayouts((yyvsp[-5].interm.type).loc, (yyvsp[-5].interm.type).shaderQualifiers); + parseContext.currentBlockQualifier = (yyvsp[-5].interm.type).qualifier; + (yyval.interm).loc = (yyvsp[-5].interm.type).loc; + (yyval.interm).typeList = (yyvsp[-1].interm.typeList); + } +#line 4279 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 101: +#line 796 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.identifierList) = new TIdentifierList; + (yyval.interm.identifierList)->push_back((yyvsp[0].lex).string); + } +#line 4288 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 102: +#line 800 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.identifierList) = (yyvsp[-2].interm.identifierList); + (yyval.interm.identifierList)->push_back((yyvsp[0].lex).string); + } +#line 4297 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 103: +#line 807 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm).function = (yyvsp[-1].interm.function); + (yyval.interm).loc = (yyvsp[0].lex).loc; + } +#line 4306 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 104: +#line 814 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.function) = (yyvsp[0].interm.function); + } +#line 4314 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 105: +#line 817 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.function) = (yyvsp[0].interm.function); + } +#line 4322 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 106: +#line 824 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + // Add the parameter + (yyval.interm.function) = (yyvsp[-1].interm.function); + if ((yyvsp[0].interm).param.type->getBasicType() != EbtVoid) + (yyvsp[-1].interm.function)->addParameter((yyvsp[0].interm).param); + else + delete (yyvsp[0].interm).param.type; + } +#line 4335 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 107: +#line 832 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + // + // Only first parameter of one-parameter functions can be void + // The check for named parameters not being void is done in parameter_declarator + // + if ((yyvsp[0].interm).param.type->getBasicType() == EbtVoid) { + // + // This parameter > first is void + // + parseContext.error((yyvsp[-1].lex).loc, "cannot be an argument type except for '(void)'", "void", ""); + delete (yyvsp[0].interm).param.type; + } else { + // Add the parameter + (yyval.interm.function) = (yyvsp[-2].interm.function); + (yyvsp[-2].interm.function)->addParameter((yyvsp[0].interm).param); + } + } +#line 4357 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 108: +#line 852 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + if ((yyvsp[-2].interm.type).qualifier.storage != EvqGlobal && (yyvsp[-2].interm.type).qualifier.storage != EvqTemporary) { + parseContext.error((yyvsp[-1].lex).loc, "no qualifiers allowed for function return", + GetStorageQualifierString((yyvsp[-2].interm.type).qualifier.storage), ""); + } + if ((yyvsp[-2].interm.type).arraySizes) + parseContext.arraySizeRequiredCheck((yyvsp[-2].interm.type).loc, *(yyvsp[-2].interm.type).arraySizes); + + // Add the function as a prototype after parsing it (we do not support recursion) + TFunction *function; + TType type((yyvsp[-2].interm.type)); + + // Potentially rename shader entry point function. No-op most of the time. + parseContext.renameShaderFunction((yyvsp[-1].lex).string); + + // Make the function + function = new TFunction((yyvsp[-1].lex).string, type); + (yyval.interm.function) = function; + } +#line 4381 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 109: +#line 875 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + if ((yyvsp[-1].interm.type).arraySizes) { + parseContext.profileRequires((yyvsp[-1].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); + parseContext.profileRequires((yyvsp[-1].interm.type).loc, EEsProfile, 300, 0, "arrayed type"); + parseContext.arraySizeRequiredCheck((yyvsp[-1].interm.type).loc, *(yyvsp[-1].interm.type).arraySizes); + } + if ((yyvsp[-1].interm.type).basicType == EbtVoid) { + parseContext.error((yyvsp[0].lex).loc, "illegal use of type 'void'", (yyvsp[0].lex).string->c_str(), ""); + } + parseContext.reservedErrorCheck((yyvsp[0].lex).loc, *(yyvsp[0].lex).string); + + TParameter param = {(yyvsp[0].lex).string, new TType((yyvsp[-1].interm.type))}; + (yyval.interm).loc = (yyvsp[0].lex).loc; + (yyval.interm).param = param; + } +#line 4401 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 110: +#line 890 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + if ((yyvsp[-2].interm.type).arraySizes) { + parseContext.profileRequires((yyvsp[-2].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); + parseContext.profileRequires((yyvsp[-2].interm.type).loc, EEsProfile, 300, 0, "arrayed type"); + parseContext.arraySizeRequiredCheck((yyvsp[-2].interm.type).loc, *(yyvsp[-2].interm.type).arraySizes); + } + parseContext.arrayDimCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.type).arraySizes, (yyvsp[0].interm).arraySizes); + + parseContext.arraySizeRequiredCheck((yyvsp[0].interm).loc, *(yyvsp[0].interm).arraySizes); + parseContext.reservedErrorCheck((yyvsp[-1].lex).loc, *(yyvsp[-1].lex).string); + + (yyvsp[-2].interm.type).arraySizes = (yyvsp[0].interm).arraySizes; + + TParameter param = { (yyvsp[-1].lex).string, new TType((yyvsp[-2].interm.type))}; + (yyval.interm).loc = (yyvsp[-1].lex).loc; + (yyval.interm).param = param; + } +#line 4423 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 111: +#line 913 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[0].interm); + if ((yyvsp[-1].interm.type).qualifier.precision != EpqNone) + (yyval.interm).param.type->getQualifier().precision = (yyvsp[-1].interm.type).qualifier.precision; + parseContext.precisionQualifierCheck((yyval.interm).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier()); + + parseContext.checkNoShaderLayouts((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).shaderQualifiers); + parseContext.parameterTypeCheck((yyvsp[0].interm).loc, (yyvsp[-1].interm.type).qualifier.storage, *(yyval.interm).param.type); + parseContext.paramCheckFix((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, *(yyval.interm).param.type); + + } +#line 4439 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 112: +#line 924 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[0].interm); + + parseContext.parameterTypeCheck((yyvsp[0].interm).loc, EvqIn, *(yyvsp[0].interm).param.type); + parseContext.paramCheckFix((yyvsp[0].interm).loc, EvqTemporary, *(yyval.interm).param.type); + parseContext.precisionQualifierCheck((yyval.interm).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier()); + } +#line 4451 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 113: +#line 934 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[0].interm); + if ((yyvsp[-1].interm.type).qualifier.precision != EpqNone) + (yyval.interm).param.type->getQualifier().precision = (yyvsp[-1].interm.type).qualifier.precision; + parseContext.precisionQualifierCheck((yyvsp[-1].interm.type).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier()); + + parseContext.checkNoShaderLayouts((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).shaderQualifiers); + parseContext.parameterTypeCheck((yyvsp[0].interm).loc, (yyvsp[-1].interm.type).qualifier.storage, *(yyval.interm).param.type); + parseContext.paramCheckFix((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, *(yyval.interm).param.type); + } +#line 4466 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 114: +#line 944 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[0].interm); + + parseContext.parameterTypeCheck((yyvsp[0].interm).loc, EvqIn, *(yyvsp[0].interm).param.type); + parseContext.paramCheckFix((yyvsp[0].interm).loc, EvqTemporary, *(yyval.interm).param.type); + parseContext.precisionQualifierCheck((yyval.interm).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier()); + } +#line 4478 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 115: +#line 954 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + TParameter param = { 0, new TType((yyvsp[0].interm.type)) }; + (yyval.interm).param = param; + if ((yyvsp[0].interm.type).arraySizes) + parseContext.arraySizeRequiredCheck((yyvsp[0].interm.type).loc, *(yyvsp[0].interm.type).arraySizes); + } +#line 4489 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 116: +#line 963 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[0].interm); + } +#line 4497 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 117: +#line 966 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[-2].interm); + parseContext.declareVariable((yyvsp[0].lex).loc, *(yyvsp[0].lex).string, (yyvsp[-2].interm).type); + } +#line 4506 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 118: +#line 970 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[-3].interm); + parseContext.declareVariable((yyvsp[-1].lex).loc, *(yyvsp[-1].lex).string, (yyvsp[-3].interm).type, (yyvsp[0].interm).arraySizes); + } +#line 4515 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 119: +#line 974 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm).type = (yyvsp[-5].interm).type; + TIntermNode* initNode = parseContext.declareVariable((yyvsp[-3].lex).loc, *(yyvsp[-3].lex).string, (yyvsp[-5].interm).type, (yyvsp[-2].interm).arraySizes, (yyvsp[0].interm.intermTypedNode)); + (yyval.interm).intermNode = parseContext.intermediate.growAggregate((yyvsp[-5].interm).intermNode, initNode, (yyvsp[-1].lex).loc); + } +#line 4525 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 120: +#line 979 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm).type = (yyvsp[-4].interm).type; + TIntermNode* initNode = parseContext.declareVariable((yyvsp[-2].lex).loc, *(yyvsp[-2].lex).string, (yyvsp[-4].interm).type, 0, (yyvsp[0].interm.intermTypedNode)); + (yyval.interm).intermNode = parseContext.intermediate.growAggregate((yyvsp[-4].interm).intermNode, initNode, (yyvsp[-1].lex).loc); + } +#line 4535 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 121: +#line 987 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm).type = (yyvsp[0].interm.type); + (yyval.interm).intermNode = 0; + parseContext.declareTypeDefaults((yyval.interm).loc, (yyval.interm).type); + } +#line 4545 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 122: +#line 992 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm).type = (yyvsp[-1].interm.type); + (yyval.interm).intermNode = 0; + parseContext.declareVariable((yyvsp[0].lex).loc, *(yyvsp[0].lex).string, (yyvsp[-1].interm.type)); + } +#line 4555 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 123: +#line 997 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm).type = (yyvsp[-2].interm.type); + (yyval.interm).intermNode = 0; + parseContext.declareVariable((yyvsp[-1].lex).loc, *(yyvsp[-1].lex).string, (yyvsp[-2].interm.type), (yyvsp[0].interm).arraySizes); + } +#line 4565 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 124: +#line 1002 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm).type = (yyvsp[-4].interm.type); + TIntermNode* initNode = parseContext.declareVariable((yyvsp[-3].lex).loc, *(yyvsp[-3].lex).string, (yyvsp[-4].interm.type), (yyvsp[-2].interm).arraySizes, (yyvsp[0].interm.intermTypedNode)); + (yyval.interm).intermNode = parseContext.intermediate.growAggregate(0, initNode, (yyvsp[-1].lex).loc); + } +#line 4575 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 125: +#line 1007 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm).type = (yyvsp[-3].interm.type); + TIntermNode* initNode = parseContext.declareVariable((yyvsp[-2].lex).loc, *(yyvsp[-2].lex).string, (yyvsp[-3].interm.type), 0, (yyvsp[0].interm.intermTypedNode)); + (yyval.interm).intermNode = parseContext.intermediate.growAggregate(0, initNode, (yyvsp[-1].lex).loc); + } +#line 4585 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 126: +#line 1016 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type) = (yyvsp[0].interm.type); + + parseContext.globalQualifierTypeCheck((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type).qualifier, (yyval.interm.type)); + if ((yyvsp[0].interm.type).arraySizes) { + parseContext.profileRequires((yyvsp[0].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); + parseContext.profileRequires((yyvsp[0].interm.type).loc, EEsProfile, 300, 0, "arrayed type"); + } + + parseContext.precisionQualifierCheck((yyval.interm.type).loc, (yyval.interm.type).basicType, (yyval.interm.type).qualifier); + } +#line 4601 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 127: +#line 1027 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.globalQualifierFixCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier); + parseContext.globalQualifierTypeCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, (yyvsp[0].interm.type)); + + if ((yyvsp[0].interm.type).arraySizes) { + parseContext.profileRequires((yyvsp[0].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); + parseContext.profileRequires((yyvsp[0].interm.type).loc, EEsProfile, 300, 0, "arrayed type"); + } + + if ((yyvsp[0].interm.type).arraySizes && parseContext.arrayQualifierError((yyvsp[0].interm.type).loc, (yyvsp[-1].interm.type).qualifier)) + (yyvsp[0].interm.type).arraySizes = 0; + + parseContext.checkNoShaderLayouts((yyvsp[0].interm.type).loc, (yyvsp[-1].interm.type).shaderQualifiers); + (yyvsp[0].interm.type).shaderQualifiers.merge((yyvsp[-1].interm.type).shaderQualifiers); + parseContext.mergeQualifiers((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type).qualifier, (yyvsp[-1].interm.type).qualifier, true); + parseContext.precisionQualifierCheck((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type).basicType, (yyvsp[0].interm.type).qualifier); + + (yyval.interm.type) = (yyvsp[0].interm.type); + + if (! (yyval.interm.type).qualifier.isInterpolation() && + ((parseContext.language == EShLangVertex && (yyval.interm.type).qualifier.storage == EvqVaryingOut) || + (parseContext.language == EShLangFragment && (yyval.interm.type).qualifier.storage == EvqVaryingIn))) + (yyval.interm.type).qualifier.smooth = true; + } +#line 4630 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 128: +#line 1054 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.globalCheck((yyvsp[0].lex).loc, "invariant"); + parseContext.profileRequires((yyval.interm.type).loc, ENoProfile, 120, 0, "invariant"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.invariant = true; + } +#line 4641 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 129: +#line 1063 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.globalCheck((yyvsp[0].lex).loc, "smooth"); + parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "smooth"); + parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 300, 0, "smooth"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.smooth = true; + } +#line 4653 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 130: +#line 1070 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.globalCheck((yyvsp[0].lex).loc, "flat"); + parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "flat"); + parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 300, 0, "flat"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.flat = true; + } +#line 4665 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 131: +#line 1077 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.globalCheck((yyvsp[0].lex).loc, "noperspective"); + parseContext.requireProfile((yyvsp[0].lex).loc, ~EEsProfile, "noperspective"); + parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "noperspective"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.nopersp = true; + } +#line 4677 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 132: +#line 1084 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.globalCheck((yyvsp[0].lex).loc, "__explicitInterpAMD"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 450, E_GL_AMD_shader_explicit_vertex_parameter, "explicit interpolation"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECompatibilityProfile, 450, E_GL_AMD_shader_explicit_vertex_parameter, "explicit interpolation"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.explicitInterp = true; +#endif + } +#line 4691 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 133: +#line 1096 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type) = (yyvsp[-1].interm.type); + } +#line 4699 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 134: +#line 1102 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 4707 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 135: +#line 1105 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type) = (yyvsp[-2].interm.type); + (yyval.interm.type).shaderQualifiers.merge((yyvsp[0].interm.type).shaderQualifiers); + parseContext.mergeObjectLayoutQualifiers((yyval.interm.type).qualifier, (yyvsp[0].interm.type).qualifier, false); + } +#line 4717 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 136: +#line 1112 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc); + parseContext.setLayoutQualifier((yyvsp[0].lex).loc, (yyval.interm.type), *(yyvsp[0].lex).string); + } +#line 4726 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 137: +#line 1116 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[-2].lex).loc); + parseContext.setLayoutQualifier((yyvsp[-2].lex).loc, (yyval.interm.type), *(yyvsp[-2].lex).string, (yyvsp[0].interm.intermTypedNode)); + } +#line 4735 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 138: +#line 1120 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { // because "shared" is both an identifier and a keyword + (yyval.interm.type).init((yyvsp[0].lex).loc); + TString strShared("shared"); + parseContext.setLayoutQualifier((yyvsp[0].lex).loc, (yyval.interm.type), strShared); + } +#line 4745 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 139: +#line 1128 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.profileRequires((yyval.interm.type).loc, ECoreProfile | ECompatibilityProfile, 400, E_GL_ARB_gpu_shader5, "precise"); + parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5, "precise"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.noContraction = true; + } +#line 4756 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 140: +#line 1137 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 4764 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 141: +#line 1140 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type) = (yyvsp[-1].interm.type); + if ((yyval.interm.type).basicType == EbtVoid) + (yyval.interm.type).basicType = (yyvsp[0].interm.type).basicType; + + (yyval.interm.type).shaderQualifiers.merge((yyvsp[0].interm.type).shaderQualifiers); + parseContext.mergeQualifiers((yyval.interm.type).loc, (yyval.interm.type).qualifier, (yyvsp[0].interm.type).qualifier, false); + } +#line 4777 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 142: +#line 1151 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 4785 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 143: +#line 1154 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 4793 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 144: +#line 1157 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.checkPrecisionQualifier((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type).qualifier.precision); + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 4802 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 145: +#line 1161 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + // allow inheritance of storage qualifier from block declaration + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 4811 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 146: +#line 1165 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + // allow inheritance of storage qualifier from block declaration + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 4820 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 147: +#line 1169 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + // allow inheritance of storage qualifier from block declaration + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 4829 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 148: +#line 1176 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqConst; // will later turn into EvqConstReadOnly, if the initializer is not constant + } +#line 4838 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 149: +#line 1180 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireStage((yyvsp[0].lex).loc, EShLangVertex, "attribute"); + parseContext.checkDeprecated((yyvsp[0].lex).loc, ECoreProfile, 130, "attribute"); + parseContext.checkDeprecated((yyvsp[0].lex).loc, ENoProfile, 130, "attribute"); + parseContext.requireNotRemoved((yyvsp[0].lex).loc, ECoreProfile, 420, "attribute"); + parseContext.requireNotRemoved((yyvsp[0].lex).loc, EEsProfile, 300, "attribute"); + + parseContext.globalCheck((yyvsp[0].lex).loc, "attribute"); + + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqVaryingIn; + } +#line 4855 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 150: +#line 1192 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.checkDeprecated((yyvsp[0].lex).loc, ENoProfile, 130, "varying"); + parseContext.checkDeprecated((yyvsp[0].lex).loc, ECoreProfile, 130, "varying"); + parseContext.requireNotRemoved((yyvsp[0].lex).loc, ECoreProfile, 420, "varying"); + parseContext.requireNotRemoved((yyvsp[0].lex).loc, EEsProfile, 300, "varying"); + + parseContext.globalCheck((yyvsp[0].lex).loc, "varying"); + + (yyval.interm.type).init((yyvsp[0].lex).loc); + if (parseContext.language == EShLangVertex) + (yyval.interm.type).qualifier.storage = EvqVaryingOut; + else + (yyval.interm.type).qualifier.storage = EvqVaryingIn; + } +#line 4874 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 151: +#line 1206 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.globalCheck((yyvsp[0].lex).loc, "inout"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqInOut; + } +#line 4884 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 152: +#line 1211 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.globalCheck((yyvsp[0].lex).loc, "in"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + // whether this is a parameter "in" or a pipeline "in" will get sorted out a bit later + (yyval.interm.type).qualifier.storage = EvqIn; + } +#line 4895 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 153: +#line 1217 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.globalCheck((yyvsp[0].lex).loc, "out"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + // whether this is a parameter "out" or a pipeline "out" will get sorted out a bit later + (yyval.interm.type).qualifier.storage = EvqOut; + } +#line 4906 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 154: +#line 1223 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 120, 0, "centroid"); + parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 300, 0, "centroid"); + parseContext.globalCheck((yyvsp[0].lex).loc, "centroid"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.centroid = true; + } +#line 4918 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 155: +#line 1230 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.globalCheck((yyvsp[0].lex).loc, "patch"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangTessControlMask | EShLangTessEvaluationMask), "patch"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.patch = true; + } +#line 4929 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 156: +#line 1236 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.globalCheck((yyvsp[0].lex).loc, "sample"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.sample = true; + } +#line 4939 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 157: +#line 1241 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.globalCheck((yyvsp[0].lex).loc, "uniform"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqUniform; + } +#line 4949 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 158: +#line 1246 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.globalCheck((yyvsp[0].lex).loc, "buffer"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqBuffer; + } +#line 4959 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 159: +#line 1251 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.globalCheck((yyvsp[0].lex).loc, "shared"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared"); + parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 310, 0, "shared"); + parseContext.requireStage((yyvsp[0].lex).loc, EShLangCompute, "shared"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqShared; + } +#line 4972 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 160: +#line 1259 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.coherent = true; + } +#line 4981 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 161: +#line 1263 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.volatil = true; + } +#line 4990 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 162: +#line 1267 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.restrict = true; + } +#line 4999 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 163: +#line 1271 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.readonly = true; + } +#line 5008 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 164: +#line 1275 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.writeonly = true; + } +#line 5017 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 165: +#line 1279 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.spvRemoved((yyvsp[0].lex).loc, "subroutine"); + parseContext.globalCheck((yyvsp[0].lex).loc, "subroutine"); + parseContext.unimplemented((yyvsp[0].lex).loc, "subroutine"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + } +#line 5028 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 166: +#line 1285 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.spvRemoved((yyvsp[-3].lex).loc, "subroutine"); + parseContext.globalCheck((yyvsp[-3].lex).loc, "subroutine"); + parseContext.unimplemented((yyvsp[-3].lex).loc, "subroutine"); + (yyval.interm.type).init((yyvsp[-3].lex).loc); + } +#line 5039 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 167: +#line 1294 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + // TODO + } +#line 5047 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 168: +#line 1297 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + // TODO: 4.0 semantics: subroutines + // 1) make sure each identifier is a type declared earlier with SUBROUTINE + // 2) save all of the identifiers for future comparison with the declared function + } +#line 5057 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 169: +#line 1305 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type) = (yyvsp[0].interm.type); + (yyval.interm.type).qualifier.precision = parseContext.getDefaultPrecision((yyval.interm.type)); + } +#line 5066 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 170: +#line 1309 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.arrayDimCheck((yyvsp[0].interm).loc, (yyvsp[0].interm).arraySizes, 0); + (yyval.interm.type) = (yyvsp[-1].interm.type); + (yyval.interm.type).qualifier.precision = parseContext.getDefaultPrecision((yyval.interm.type)); + (yyval.interm.type).arraySizes = (yyvsp[0].interm).arraySizes; + } +#line 5077 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 171: +#line 1318 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm).loc = (yyvsp[-1].lex).loc; + (yyval.interm).arraySizes = new TArraySizes; + (yyval.interm).arraySizes->addInnerSize(); + } +#line 5087 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 172: +#line 1323 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm).loc = (yyvsp[-2].lex).loc; + (yyval.interm).arraySizes = new TArraySizes; + + TArraySize size; + parseContext.arraySizeCheck((yyvsp[-1].interm.intermTypedNode)->getLoc(), (yyvsp[-1].interm.intermTypedNode), size); + (yyval.interm).arraySizes->addInnerSize(size); + } +#line 5100 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 173: +#line 1331 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[-2].interm); + (yyval.interm).arraySizes->addInnerSize(); + } +#line 5109 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 174: +#line 1335 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[-3].interm); + + TArraySize size; + parseContext.arraySizeCheck((yyvsp[-1].interm.intermTypedNode)->getLoc(), (yyvsp[-1].interm.intermTypedNode), size); + (yyval.interm).arraySizes->addInnerSize(size); + } +#line 5121 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 175: +#line 1345 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtVoid; + } +#line 5130 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 176: +#line 1349 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + } +#line 5139 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 177: +#line 1353 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.doubleCheck((yyvsp[0].lex).loc, "double"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + } +#line 5149 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 178: +#line 1358 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16Check((yyvsp[0].lex).loc, "half float", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; +#endif + } +#line 5161 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 179: +#line 1365 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt; + } +#line 5170 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 180: +#line 1369 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint; + } +#line 5180 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 181: +#line 1374 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt64; + } +#line 5190 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 182: +#line 1379 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint64; + } +#line 5200 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 183: +#line 1384 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.int16Check((yyvsp[0].lex).loc, "16-bit integer", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt16; +#endif + } +#line 5212 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 184: +#line 1391 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.int16Check((yyvsp[0].lex).loc, "16-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint16; +#endif + } +#line 5224 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 185: +#line 1398 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtBool; + } +#line 5233 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 186: +#line 1402 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setVector(2); + } +#line 5243 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 187: +#line 1407 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setVector(3); + } +#line 5253 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 188: +#line 1412 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setVector(4); + } +#line 5263 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 189: +#line 1417 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.doubleCheck((yyvsp[0].lex).loc, "double vector"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setVector(2); + } +#line 5274 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 190: +#line 1423 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.doubleCheck((yyvsp[0].lex).loc, "double vector"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setVector(3); + } +#line 5285 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 191: +#line 1429 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.doubleCheck((yyvsp[0].lex).loc, "double vector"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setVector(4); + } +#line 5296 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 192: +#line 1435 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16Check((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setVector(2); +#endif + } +#line 5309 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 193: +#line 1443 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16Check((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setVector(3); +#endif + } +#line 5322 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 194: +#line 1451 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16Check((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setVector(4); +#endif + } +#line 5335 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 195: +#line 1459 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtBool; + (yyval.interm.type).setVector(2); + } +#line 5345 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 196: +#line 1464 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtBool; + (yyval.interm.type).setVector(3); + } +#line 5355 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 197: +#line 1469 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtBool; + (yyval.interm.type).setVector(4); + } +#line 5365 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 198: +#line 1474 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt; + (yyval.interm.type).setVector(2); + } +#line 5375 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 199: +#line 1479 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt; + (yyval.interm.type).setVector(3); + } +#line 5385 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 200: +#line 1484 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt; + (yyval.interm.type).setVector(4); + } +#line 5395 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 201: +#line 1489 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt64; + (yyval.interm.type).setVector(2); + } +#line 5406 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 202: +#line 1495 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt64; + (yyval.interm.type).setVector(3); + } +#line 5417 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 203: +#line 1501 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt64; + (yyval.interm.type).setVector(4); + } +#line 5428 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 204: +#line 1507 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.int16Check((yyvsp[0].lex).loc, "16-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt16; + (yyval.interm.type).setVector(2); +#endif + } +#line 5441 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 205: +#line 1515 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.int16Check((yyvsp[0].lex).loc, "16-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt16; + (yyval.interm.type).setVector(3); +#endif + } +#line 5454 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 206: +#line 1523 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.int16Check((yyvsp[0].lex).loc, "16-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt16; + (yyval.interm.type).setVector(4); +#endif + } +#line 5467 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 207: +#line 1531 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer vector"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint; + (yyval.interm.type).setVector(2); + } +#line 5478 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 208: +#line 1537 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer vector"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint; + (yyval.interm.type).setVector(3); + } +#line 5489 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 209: +#line 1543 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer vector"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint; + (yyval.interm.type).setVector(4); + } +#line 5500 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 210: +#line 1549 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint64; + (yyval.interm.type).setVector(2); + } +#line 5511 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 211: +#line 1555 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint64; + (yyval.interm.type).setVector(3); + } +#line 5522 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 212: +#line 1561 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint64; + (yyval.interm.type).setVector(4); + } +#line 5533 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 213: +#line 1567 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.int16Check((yyvsp[0].lex).loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint16; + (yyval.interm.type).setVector(2); +#endif + } +#line 5546 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 214: +#line 1575 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.int16Check((yyvsp[0].lex).loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint16; + (yyval.interm.type).setVector(3); +#endif + } +#line 5559 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 215: +#line 1583 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.int16Check((yyvsp[0].lex).loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint16; + (yyval.interm.type).setVector(4); +#endif + } +#line 5572 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 216: +#line 1591 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(2, 2); + } +#line 5582 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 217: +#line 1596 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(3, 3); + } +#line 5592 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 218: +#line 1601 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(4, 4); + } +#line 5602 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 219: +#line 1606 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(2, 2); + } +#line 5612 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 220: +#line 1611 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(2, 3); + } +#line 5622 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 221: +#line 1616 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(2, 4); + } +#line 5632 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 222: +#line 1621 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(3, 2); + } +#line 5642 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 223: +#line 1626 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(3, 3); + } +#line 5652 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 224: +#line 1631 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(3, 4); + } +#line 5662 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 225: +#line 1636 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(4, 2); + } +#line 5672 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 226: +#line 1641 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(4, 3); + } +#line 5682 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 227: +#line 1646 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(4, 4); + } +#line 5692 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 228: +#line 1651 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(2, 2); + } +#line 5703 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 229: +#line 1657 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(3, 3); + } +#line 5714 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 230: +#line 1663 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(4, 4); + } +#line 5725 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 231: +#line 1669 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(2, 2); + } +#line 5736 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 232: +#line 1675 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(2, 3); + } +#line 5747 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 233: +#line 1681 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(2, 4); + } +#line 5758 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 234: +#line 1687 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(3, 2); + } +#line 5769 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 235: +#line 1693 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(3, 3); + } +#line 5780 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 236: +#line 1699 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(3, 4); + } +#line 5791 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 237: +#line 1705 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(4, 2); + } +#line 5802 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 238: +#line 1711 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(4, 3); + } +#line 5813 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 239: +#line 1717 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(4, 4); + } +#line 5824 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 240: +#line 1723 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(2, 2); +#endif + } +#line 5837 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 241: +#line 1731 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(3, 3); +#endif + } +#line 5850 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 242: +#line 1739 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(4, 4); +#endif + } +#line 5863 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 243: +#line 1747 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(2, 2); +#endif + } +#line 5876 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 244: +#line 1755 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(2, 3); +#endif + } +#line 5889 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 245: +#line 1763 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(2, 4); +#endif + } +#line 5902 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 246: +#line 1771 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(3, 2); +#endif + } +#line 5915 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 247: +#line 1779 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(3, 3); +#endif + } +#line 5928 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 248: +#line 1787 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(3, 4); +#endif + } +#line 5941 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 249: +#line 1795 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(4, 2); +#endif + } +#line 5954 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 250: +#line 1803 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(4, 3); +#endif + } +#line 5967 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 251: +#line 1811 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(4, 4); +#endif + } +#line 5980 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 252: +#line 1819 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.vulkanRemoved((yyvsp[0].lex).loc, "atomic counter types"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtAtomicUint; + } +#line 5990 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 253: +#line 1824 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd1D); + } +#line 6000 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 254: +#line 1829 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd2D); + } +#line 6010 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 255: +#line 1834 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd3D); + } +#line 6020 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 256: +#line 1839 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, EsdCube); + } +#line 6030 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 257: +#line 1844 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd1D, false, true); + } +#line 6040 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 258: +#line 1849 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd2D, false, true); + } +#line 6050 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 259: +#line 1854 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, EsdCube, false, true); + } +#line 6060 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 260: +#line 1859 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd1D, true); + } +#line 6070 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 261: +#line 1864 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd2D, true); + } +#line 6080 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 262: +#line 1869 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd1D, true, true); + } +#line 6090 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 263: +#line 1874 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd2D, true, true); + } +#line 6100 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 264: +#line 1879 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, EsdCube, true); + } +#line 6110 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 265: +#line 1884 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, EsdCube, true, true); + } +#line 6120 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 266: +#line 1889 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtInt, Esd1D); + } +#line 6130 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 267: +#line 1894 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtInt, Esd2D); + } +#line 6140 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 268: +#line 1899 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtInt, Esd3D); + } +#line 6150 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 269: +#line 1904 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtInt, EsdCube); + } +#line 6160 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 270: +#line 1909 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtInt, Esd1D, true); + } +#line 6170 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 271: +#line 1914 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtInt, Esd2D, true); + } +#line 6180 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 272: +#line 1919 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtInt, EsdCube, true); + } +#line 6190 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 273: +#line 1924 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtUint, Esd1D); + } +#line 6200 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 274: +#line 1929 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtUint, Esd2D); + } +#line 6210 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 275: +#line 1934 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtUint, Esd3D); + } +#line 6220 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 276: +#line 1939 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtUint, EsdCube); + } +#line 6230 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 277: +#line 1944 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtUint, Esd1D, true); + } +#line 6240 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 278: +#line 1949 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtUint, Esd2D, true); + } +#line 6250 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 279: +#line 1954 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtUint, EsdCube, true); + } +#line 6260 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 280: +#line 1959 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, EsdRect); + } +#line 6270 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 281: +#line 1964 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, EsdRect, false, true); + } +#line 6280 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 282: +#line 1969 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtInt, EsdRect); + } +#line 6290 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 283: +#line 1974 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtUint, EsdRect); + } +#line 6300 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 284: +#line 1979 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, EsdBuffer); + } +#line 6310 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 285: +#line 1984 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtInt, EsdBuffer); + } +#line 6320 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 286: +#line 1989 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtUint, EsdBuffer); + } +#line 6330 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 287: +#line 1994 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd2D, false, false, true); + } +#line 6340 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 288: +#line 1999 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtInt, Esd2D, false, false, true); + } +#line 6350 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 289: +#line 2004 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtUint, Esd2D, false, false, true); + } +#line 6360 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 290: +#line 2009 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd2D, true, false, true); + } +#line 6370 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 291: +#line 2014 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtInt, Esd2D, true, false, true); + } +#line 6380 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 292: +#line 2019 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtUint, Esd2D, true, false, true); + } +#line 6390 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 293: +#line 2024 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setPureSampler(false); + } +#line 6400 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 294: +#line 2029 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setPureSampler(true); + } +#line 6410 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 295: +#line 2034 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat, Esd1D); + } +#line 6420 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 296: +#line 2039 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D); + } +#line 6430 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 297: +#line 2044 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat, Esd3D); + } +#line 6440 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 298: +#line 2049 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat, EsdCube); + } +#line 6450 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 299: +#line 2054 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat, Esd1D, true); + } +#line 6460 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 300: +#line 2059 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D, true); + } +#line 6470 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 301: +#line 2064 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat, EsdCube, true); + } +#line 6480 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 302: +#line 2069 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtInt, Esd1D); + } +#line 6490 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 303: +#line 2074 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D); + } +#line 6500 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 304: +#line 2079 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtInt, Esd3D); + } +#line 6510 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 305: +#line 2084 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtInt, EsdCube); + } +#line 6520 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 306: +#line 2089 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtInt, Esd1D, true); + } +#line 6530 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 307: +#line 2094 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D, true); + } +#line 6540 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 308: +#line 2099 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtInt, EsdCube, true); + } +#line 6550 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 309: +#line 2104 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtUint, Esd1D); + } +#line 6560 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 310: +#line 2109 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D); + } +#line 6570 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 311: +#line 2114 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtUint, Esd3D); + } +#line 6580 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 312: +#line 2119 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtUint, EsdCube); + } +#line 6590 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 313: +#line 2124 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtUint, Esd1D, true); + } +#line 6600 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 314: +#line 2129 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D, true); + } +#line 6610 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 315: +#line 2134 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtUint, EsdCube, true); + } +#line 6620 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 316: +#line 2139 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat, EsdRect); + } +#line 6630 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 317: +#line 2144 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtInt, EsdRect); + } +#line 6640 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 318: +#line 2149 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtUint, EsdRect); + } +#line 6650 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 319: +#line 2154 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat, EsdBuffer); + } +#line 6660 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 320: +#line 2159 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtInt, EsdBuffer); + } +#line 6670 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 321: +#line 2164 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtUint, EsdBuffer); + } +#line 6680 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 322: +#line 2169 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D, false, false, true); + } +#line 6690 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 323: +#line 2174 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D, false, false, true); + } +#line 6700 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 324: +#line 2179 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D, false, false, true); + } +#line 6710 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 325: +#line 2184 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D, true, false, true); + } +#line 6720 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 326: +#line 2189 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D, true, false, true); + } +#line 6730 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 327: +#line 2194 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D, true, false, true); + } +#line 6740 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 328: +#line 2199 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtFloat, Esd1D); + } +#line 6750 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 329: +#line 2204 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtInt, Esd1D); + } +#line 6760 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 330: +#line 2209 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtUint, Esd1D); + } +#line 6770 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 331: +#line 2214 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtFloat, Esd2D); + } +#line 6780 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 332: +#line 2219 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtInt, Esd2D); + } +#line 6790 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 333: +#line 2224 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtUint, Esd2D); + } +#line 6800 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 334: +#line 2229 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtFloat, Esd3D); + } +#line 6810 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 335: +#line 2234 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtInt, Esd3D); + } +#line 6820 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 336: +#line 2239 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtUint, Esd3D); + } +#line 6830 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 337: +#line 2244 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtFloat, EsdRect); + } +#line 6840 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 338: +#line 2249 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtInt, EsdRect); + } +#line 6850 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 339: +#line 2254 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtUint, EsdRect); + } +#line 6860 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 340: +#line 2259 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtFloat, EsdCube); + } +#line 6870 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 341: +#line 2264 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtInt, EsdCube); + } +#line 6880 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 342: +#line 2269 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtUint, EsdCube); + } +#line 6890 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 343: +#line 2274 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtFloat, EsdBuffer); + } +#line 6900 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 344: +#line 2279 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtInt, EsdBuffer); + } +#line 6910 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 345: +#line 2284 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtUint, EsdBuffer); + } +#line 6920 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 346: +#line 2289 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtFloat, Esd1D, true); + } +#line 6930 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 347: +#line 2294 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtInt, Esd1D, true); + } +#line 6940 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 348: +#line 2299 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtUint, Esd1D, true); + } +#line 6950 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 349: +#line 2304 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtFloat, Esd2D, true); + } +#line 6960 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 350: +#line 2309 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtInt, Esd2D, true); + } +#line 6970 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 351: +#line 2314 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtUint, Esd2D, true); + } +#line 6980 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 352: +#line 2319 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtFloat, EsdCube, true); + } +#line 6990 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 353: +#line 2324 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtInt, EsdCube, true); + } +#line 7000 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 354: +#line 2329 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtUint, EsdCube, true); + } +#line 7010 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 355: +#line 2334 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtFloat, Esd2D, false, false, true); + } +#line 7020 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 356: +#line 2339 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtInt, Esd2D, false, false, true); + } +#line 7030 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 357: +#line 2344 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtUint, Esd2D, false, false, true); + } +#line 7040 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 358: +#line 2349 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtFloat, Esd2D, true, false, true); + } +#line 7050 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 359: +#line 2354 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtInt, Esd2D, true, false, true); + } +#line 7060 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 360: +#line 2359 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtUint, Esd2D, true, false, true); + } +#line 7070 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 361: +#line 2364 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { // GL_OES_EGL_image_external + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd2D); + (yyval.interm.type).sampler.external = true; + } +#line 7081 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 362: +#line 2370 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setSubpass(EbtFloat); + } +#line 7092 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 363: +#line 2376 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setSubpass(EbtFloat, true); + } +#line 7103 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 364: +#line 2382 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setSubpass(EbtInt); + } +#line 7114 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 365: +#line 2388 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setSubpass(EbtInt, true); + } +#line 7125 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 366: +#line 2394 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setSubpass(EbtUint); + } +#line 7136 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 367: +#line 2400 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setSubpass(EbtUint, true); + } +#line 7147 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 368: +#line 2406 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type) = (yyvsp[0].interm.type); + (yyval.interm.type).qualifier.storage = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + parseContext.structTypeCheck((yyval.interm.type).loc, (yyval.interm.type)); + } +#line 7157 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 369: +#line 2411 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + // + // This is for user defined type names. The lexical phase looked up the + // type. + // + if (const TVariable* variable = ((yyvsp[0].lex).symbol)->getAsVariable()) { + const TType& structure = variable->getType(); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtStruct; + (yyval.interm.type).userDef = &structure; + } else + parseContext.error((yyvsp[0].lex).loc, "expected type name", (yyvsp[0].lex).string->c_str(), ""); + } +#line 7175 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 370: +#line 2427 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "highp precision qualifier"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + parseContext.handlePrecisionQualifier((yyvsp[0].lex).loc, (yyval.interm.type).qualifier, EpqHigh); + } +#line 7185 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 371: +#line 2432 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "mediump precision qualifier"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + parseContext.handlePrecisionQualifier((yyvsp[0].lex).loc, (yyval.interm.type).qualifier, EpqMedium); + } +#line 7195 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 372: +#line 2437 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "lowp precision qualifier"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + parseContext.handlePrecisionQualifier((yyvsp[0].lex).loc, (yyval.interm.type).qualifier, EpqLow); + } +#line 7205 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 373: +#line 2445 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { parseContext.nestedStructCheck((yyvsp[-2].lex).loc); } +#line 7211 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 374: +#line 2445 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + TType* structure = new TType((yyvsp[-1].interm.typeList), *(yyvsp[-4].lex).string); + parseContext.structArrayCheck((yyvsp[-4].lex).loc, *structure); + TVariable* userTypeDef = new TVariable((yyvsp[-4].lex).string, *structure, true); + if (! parseContext.symbolTable.insert(*userTypeDef)) + parseContext.error((yyvsp[-4].lex).loc, "redefinition", (yyvsp[-4].lex).string->c_str(), "struct"); + (yyval.interm.type).init((yyvsp[-5].lex).loc); + (yyval.interm.type).basicType = EbtStruct; + (yyval.interm.type).userDef = structure; + --parseContext.structNestingLevel; + } +#line 7227 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 375: +#line 2456 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { parseContext.nestedStructCheck((yyvsp[-1].lex).loc); } +#line 7233 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 376: +#line 2456 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + TType* structure = new TType((yyvsp[-1].interm.typeList), TString("")); + (yyval.interm.type).init((yyvsp[-4].lex).loc); + (yyval.interm.type).basicType = EbtStruct; + (yyval.interm.type).userDef = structure; + --parseContext.structNestingLevel; + } +#line 7245 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 377: +#line 2466 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.typeList) = (yyvsp[0].interm.typeList); + } +#line 7253 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 378: +#line 2469 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.typeList) = (yyvsp[-1].interm.typeList); + for (unsigned int i = 0; i < (yyvsp[0].interm.typeList)->size(); ++i) { + for (unsigned int j = 0; j < (yyval.interm.typeList)->size(); ++j) { + if ((*(yyval.interm.typeList))[j].type->getFieldName() == (*(yyvsp[0].interm.typeList))[i].type->getFieldName()) + parseContext.error((*(yyvsp[0].interm.typeList))[i].loc, "duplicate member name:", "", (*(yyvsp[0].interm.typeList))[i].type->getFieldName().c_str()); + } + (yyval.interm.typeList)->push_back((*(yyvsp[0].interm.typeList))[i]); + } + } +#line 7268 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 379: +#line 2482 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + if ((yyvsp[-2].interm.type).arraySizes) { + parseContext.profileRequires((yyvsp[-2].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); + parseContext.profileRequires((yyvsp[-2].interm.type).loc, EEsProfile, 300, 0, "arrayed type"); + if (parseContext.profile == EEsProfile) + parseContext.arraySizeRequiredCheck((yyvsp[-2].interm.type).loc, *(yyvsp[-2].interm.type).arraySizes); + } + + (yyval.interm.typeList) = (yyvsp[-1].interm.typeList); + + parseContext.voidErrorCheck((yyvsp[-2].interm.type).loc, (*(yyvsp[-1].interm.typeList))[0].type->getFieldName(), (yyvsp[-2].interm.type).basicType); + parseContext.precisionQualifierCheck((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).basicType, (yyvsp[-2].interm.type).qualifier); + + for (unsigned int i = 0; i < (yyval.interm.typeList)->size(); ++i) { + parseContext.arrayDimCheck((yyvsp[-2].interm.type).loc, (*(yyval.interm.typeList))[i].type, (yyvsp[-2].interm.type).arraySizes); + (*(yyval.interm.typeList))[i].type->mergeType((yyvsp[-2].interm.type)); + } + } +#line 7291 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 380: +#line 2500 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.globalQualifierFixCheck((yyvsp[-3].interm.type).loc, (yyvsp[-3].interm.type).qualifier); + if ((yyvsp[-2].interm.type).arraySizes) { + parseContext.profileRequires((yyvsp[-2].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); + parseContext.profileRequires((yyvsp[-2].interm.type).loc, EEsProfile, 300, 0, "arrayed type"); + if (parseContext.profile == EEsProfile) + parseContext.arraySizeRequiredCheck((yyvsp[-2].interm.type).loc, *(yyvsp[-2].interm.type).arraySizes); + } + + (yyval.interm.typeList) = (yyvsp[-1].interm.typeList); + + parseContext.checkNoShaderLayouts((yyvsp[-3].interm.type).loc, (yyvsp[-3].interm.type).shaderQualifiers); + parseContext.voidErrorCheck((yyvsp[-2].interm.type).loc, (*(yyvsp[-1].interm.typeList))[0].type->getFieldName(), (yyvsp[-2].interm.type).basicType); + parseContext.mergeQualifiers((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).qualifier, (yyvsp[-3].interm.type).qualifier, true); + parseContext.precisionQualifierCheck((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).basicType, (yyvsp[-2].interm.type).qualifier); + + for (unsigned int i = 0; i < (yyval.interm.typeList)->size(); ++i) { + parseContext.arrayDimCheck((yyvsp[-3].interm.type).loc, (*(yyval.interm.typeList))[i].type, (yyvsp[-2].interm.type).arraySizes); + (*(yyval.interm.typeList))[i].type->mergeType((yyvsp[-2].interm.type)); + } + } +#line 7317 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 381: +#line 2524 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.typeList) = new TTypeList; + (yyval.interm.typeList)->push_back((yyvsp[0].interm.typeLine)); + } +#line 7326 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 382: +#line 2528 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.typeList)->push_back((yyvsp[0].interm.typeLine)); + } +#line 7334 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 383: +#line 2534 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.typeLine).type = new TType(EbtVoid); + (yyval.interm.typeLine).loc = (yyvsp[0].lex).loc; + (yyval.interm.typeLine).type->setFieldName(*(yyvsp[0].lex).string); + } +#line 7344 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 384: +#line 2539 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.arrayDimCheck((yyvsp[-1].lex).loc, (yyvsp[0].interm).arraySizes, 0); + + (yyval.interm.typeLine).type = new TType(EbtVoid); + (yyval.interm.typeLine).loc = (yyvsp[-1].lex).loc; + (yyval.interm.typeLine).type->setFieldName(*(yyvsp[-1].lex).string); + (yyval.interm.typeLine).type->newArraySizes(*(yyvsp[0].interm).arraySizes); + } +#line 7357 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 385: +#line 2550 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); + } +#line 7365 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 386: +#line 2553 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + const char* initFeature = "{ } style initializers"; + parseContext.requireProfile((yyvsp[-2].lex).loc, ~EEsProfile, initFeature); + parseContext.profileRequires((yyvsp[-2].lex).loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature); + (yyval.interm.intermTypedNode) = (yyvsp[-1].interm.intermTypedNode); + } +#line 7376 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 387: +#line 2559 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + const char* initFeature = "{ } style initializers"; + parseContext.requireProfile((yyvsp[-3].lex).loc, ~EEsProfile, initFeature); + parseContext.profileRequires((yyvsp[-3].lex).loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature); + (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + } +#line 7387 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 388: +#line 2568 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.intermediate.growAggregate(0, (yyvsp[0].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)->getLoc()); + } +#line 7395 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 389: +#line 2571 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + } +#line 7403 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 390: +#line 2577 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 7409 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 391: +#line 2581 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 7415 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 392: +#line 2582 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 7421 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 393: +#line 2588 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 7427 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 394: +#line 2589 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 7433 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 395: +#line 2590 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 7439 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 396: +#line 2591 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 7445 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 397: +#line 2592 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 7451 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 398: +#line 2593 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 7457 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 399: +#line 2594 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 7463 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 400: +#line 2598 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = 0; } +#line 7469 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 401: +#line 2599 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.symbolTable.push(); + ++parseContext.statementNestingLevel; + } +#line 7478 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 402: +#line 2603 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); + --parseContext.statementNestingLevel; + } +#line 7487 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 403: +#line 2607 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + if ((yyvsp[-2].interm.intermNode) && (yyvsp[-2].interm.intermNode)->getAsAggregate()) + (yyvsp[-2].interm.intermNode)->getAsAggregate()->setOperator(EOpSequence); + (yyval.interm.intermNode) = (yyvsp[-2].interm.intermNode); + } +#line 7497 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 404: +#line 2615 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 7503 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 405: +#line 2616 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 7509 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 406: +#line 2620 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + ++parseContext.controlFlowNestingLevel; + } +#line 7517 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 407: +#line 2623 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + --parseContext.controlFlowNestingLevel; + (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); + } +#line 7526 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 408: +#line 2627 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.symbolTable.push(); + ++parseContext.statementNestingLevel; + ++parseContext.controlFlowNestingLevel; + } +#line 7536 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 409: +#line 2632 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); + --parseContext.statementNestingLevel; + --parseContext.controlFlowNestingLevel; + (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); + } +#line 7547 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 410: +#line 2641 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermNode) = 0; + } +#line 7555 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 411: +#line 2644 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + if ((yyvsp[-1].interm.intermNode) && (yyvsp[-1].interm.intermNode)->getAsAggregate()) + (yyvsp[-1].interm.intermNode)->getAsAggregate()->setOperator(EOpSequence); + (yyval.interm.intermNode) = (yyvsp[-1].interm.intermNode); + } +#line 7565 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 412: +#line 2652 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[0].interm.intermNode)); + if ((yyvsp[0].interm.intermNode) && (yyvsp[0].interm.intermNode)->getAsBranchNode() && ((yyvsp[0].interm.intermNode)->getAsBranchNode()->getFlowOp() == EOpCase || + (yyvsp[0].interm.intermNode)->getAsBranchNode()->getFlowOp() == EOpDefault)) { + parseContext.wrapupSwitchSubsequence(0, (yyvsp[0].interm.intermNode)); + (yyval.interm.intermNode) = 0; // start a fresh subsequence for what's after this case + } + } +#line 7578 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 413: +#line 2660 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + if ((yyvsp[0].interm.intermNode) && (yyvsp[0].interm.intermNode)->getAsBranchNode() && ((yyvsp[0].interm.intermNode)->getAsBranchNode()->getFlowOp() == EOpCase || + (yyvsp[0].interm.intermNode)->getAsBranchNode()->getFlowOp() == EOpDefault)) { + parseContext.wrapupSwitchSubsequence((yyvsp[-1].interm.intermNode) ? (yyvsp[-1].interm.intermNode)->getAsAggregate() : 0, (yyvsp[0].interm.intermNode)); + (yyval.interm.intermNode) = 0; // start a fresh subsequence for what's after this case + } else + (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-1].interm.intermNode), (yyvsp[0].interm.intermNode)); + } +#line 7591 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 414: +#line 2671 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = 0; } +#line 7597 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 415: +#line 2672 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = static_cast((yyvsp[-1].interm.intermTypedNode)); } +#line 7603 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 416: +#line 2676 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.boolCheck((yyvsp[-4].lex).loc, (yyvsp[-2].interm.intermTypedNode)); + (yyval.interm.intermNode) = parseContext.intermediate.addSelection((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.nodePair), (yyvsp[-4].lex).loc); + } +#line 7612 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 417: +#line 2683 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermNode); + (yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermNode); + } +#line 7621 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 418: +#line 2687 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.nodePair).node1 = (yyvsp[0].interm.intermNode); + (yyval.interm.nodePair).node2 = 0; + } +#line 7630 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 419: +#line 2695 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); + parseContext.boolCheck((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode)); + } +#line 7639 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 420: +#line 2699 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.boolCheck((yyvsp[-2].lex).loc, (yyvsp[-3].interm.type)); + + TType type((yyvsp[-3].interm.type)); + TIntermNode* initNode = parseContext.declareVariable((yyvsp[-2].lex).loc, *(yyvsp[-2].lex).string, (yyvsp[-3].interm.type), 0, (yyvsp[0].interm.intermTypedNode)); + if (initNode) + (yyval.interm.intermTypedNode) = initNode->getAsTyped(); + else + (yyval.interm.intermTypedNode) = 0; + } +#line 7654 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 421: +#line 2712 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + // start new switch sequence on the switch stack + ++parseContext.controlFlowNestingLevel; + ++parseContext.statementNestingLevel; + parseContext.switchSequenceStack.push_back(new TIntermSequence); + parseContext.switchLevel.push_back(parseContext.statementNestingLevel); + parseContext.symbolTable.push(); + } +#line 7667 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 422: +#line 2720 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermNode) = parseContext.addSwitch((yyvsp[-7].lex).loc, (yyvsp[-5].interm.intermTypedNode), (yyvsp[-1].interm.intermNode) ? (yyvsp[-1].interm.intermNode)->getAsAggregate() : 0); + delete parseContext.switchSequenceStack.back(); + parseContext.switchSequenceStack.pop_back(); + parseContext.switchLevel.pop_back(); + parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); + --parseContext.statementNestingLevel; + --parseContext.controlFlowNestingLevel; + } +#line 7681 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 423: +#line 2732 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermNode) = 0; + } +#line 7689 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 424: +#line 2735 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); + } +#line 7697 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 425: +#line 2741 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermNode) = 0; + if (parseContext.switchLevel.size() == 0) + parseContext.error((yyvsp[-2].lex).loc, "cannot appear outside switch statement", "case", ""); + else if (parseContext.switchLevel.back() != parseContext.statementNestingLevel) + parseContext.error((yyvsp[-2].lex).loc, "cannot be nested inside control flow", "case", ""); + else { + parseContext.constantValueCheck((yyvsp[-1].interm.intermTypedNode), "case"); + parseContext.integerCheck((yyvsp[-1].interm.intermTypedNode), "case"); + (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpCase, (yyvsp[-1].interm.intermTypedNode), (yyvsp[-2].lex).loc); + } + } +#line 7714 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 426: +#line 2753 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermNode) = 0; + if (parseContext.switchLevel.size() == 0) + parseContext.error((yyvsp[-1].lex).loc, "cannot appear outside switch statement", "default", ""); + else if (parseContext.switchLevel.back() != parseContext.statementNestingLevel) + parseContext.error((yyvsp[-1].lex).loc, "cannot be nested inside control flow", "default", ""); + else + (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpDefault, (yyvsp[-1].lex).loc); + } +#line 7728 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 427: +#line 2765 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + if (! parseContext.limits.whileLoops) + parseContext.error((yyvsp[-1].lex).loc, "while loops not available", "limitation", ""); + parseContext.symbolTable.push(); + ++parseContext.loopNestingLevel; + ++parseContext.statementNestingLevel; + ++parseContext.controlFlowNestingLevel; + } +#line 7741 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 428: +#line 2773 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); + (yyval.interm.intermNode) = parseContext.intermediate.addLoop((yyvsp[0].interm.intermNode), (yyvsp[-2].interm.intermTypedNode), 0, true, (yyvsp[-5].lex).loc); + --parseContext.loopNestingLevel; + --parseContext.statementNestingLevel; + --parseContext.controlFlowNestingLevel; + } +#line 7753 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 429: +#line 2780 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + ++parseContext.loopNestingLevel; + ++parseContext.statementNestingLevel; + ++parseContext.controlFlowNestingLevel; + } +#line 7763 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 430: +#line 2785 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + if (! parseContext.limits.whileLoops) + parseContext.error((yyvsp[-7].lex).loc, "do-while loops not available", "limitation", ""); + + parseContext.boolCheck((yyvsp[0].lex).loc, (yyvsp[-2].interm.intermTypedNode)); + + (yyval.interm.intermNode) = parseContext.intermediate.addLoop((yyvsp[-5].interm.intermNode), (yyvsp[-2].interm.intermTypedNode), 0, false, (yyvsp[-4].lex).loc); + --parseContext.loopNestingLevel; + --parseContext.statementNestingLevel; + --parseContext.controlFlowNestingLevel; + } +#line 7779 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 431: +#line 2796 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.symbolTable.push(); + ++parseContext.loopNestingLevel; + ++parseContext.statementNestingLevel; + ++parseContext.controlFlowNestingLevel; + } +#line 7790 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 432: +#line 2802 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); + (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[-3].interm.intermNode), (yyvsp[-5].lex).loc); + TIntermLoop* forLoop = parseContext.intermediate.addLoop((yyvsp[0].interm.intermNode), reinterpret_cast((yyvsp[-2].interm.nodePair).node1), reinterpret_cast((yyvsp[-2].interm.nodePair).node2), true, (yyvsp[-6].lex).loc); + if (! parseContext.limits.nonInductiveForLoops) + parseContext.inductiveLoopCheck((yyvsp[-6].lex).loc, (yyvsp[-3].interm.intermNode), forLoop); + (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyval.interm.intermNode), forLoop, (yyvsp[-6].lex).loc); + (yyval.interm.intermNode)->getAsAggregate()->setOperator(EOpSequence); + --parseContext.loopNestingLevel; + --parseContext.statementNestingLevel; + --parseContext.controlFlowNestingLevel; + } +#line 7807 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 433: +#line 2817 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); + } +#line 7815 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 434: +#line 2820 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); + } +#line 7823 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 435: +#line 2826 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); + } +#line 7831 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 436: +#line 2829 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = 0; + } +#line 7839 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 437: +#line 2835 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.nodePair).node1 = (yyvsp[-1].interm.intermTypedNode); + (yyval.interm.nodePair).node2 = 0; + } +#line 7848 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 438: +#line 2839 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermTypedNode); + (yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermTypedNode); + } +#line 7857 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 439: +#line 2846 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + if (parseContext.loopNestingLevel <= 0) + parseContext.error((yyvsp[-1].lex).loc, "continue statement only allowed in loops", "", ""); + (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpContinue, (yyvsp[-1].lex).loc); + } +#line 7867 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 440: +#line 2851 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + if (parseContext.loopNestingLevel + parseContext.switchSequenceStack.size() <= 0) + parseContext.error((yyvsp[-1].lex).loc, "break statement only allowed in switch and loops", "", ""); + (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpBreak, (yyvsp[-1].lex).loc); + } +#line 7877 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 441: +#line 2856 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpReturn, (yyvsp[-1].lex).loc); + if (parseContext.currentFunctionType->getBasicType() != EbtVoid) + parseContext.error((yyvsp[-1].lex).loc, "non-void function must return a value", "return", ""); + if (parseContext.inMain) + parseContext.postEntryPointReturn = true; + } +#line 7889 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 442: +#line 2863 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermNode) = parseContext.handleReturnValue((yyvsp[-2].lex).loc, (yyvsp[-1].interm.intermTypedNode)); + } +#line 7897 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 443: +#line 2866 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireStage((yyvsp[-1].lex).loc, EShLangFragment, "discard"); + (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpKill, (yyvsp[-1].lex).loc); + } +#line 7906 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 444: +#line 2875 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); + parseContext.intermediate.setTreeRoot((yyval.interm.intermNode)); + } +#line 7915 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 445: +#line 2879 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + if ((yyvsp[0].interm.intermNode) != nullptr) { + (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-1].interm.intermNode), (yyvsp[0].interm.intermNode)); + parseContext.intermediate.setTreeRoot((yyval.interm.intermNode)); + } + } +#line 7926 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 446: +#line 2888 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); + } +#line 7934 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 447: +#line 2891 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); + } +#line 7942 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 448: +#line 2894 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireProfile((yyvsp[0].lex).loc, ~EEsProfile, "extraneous semicolon"); + parseContext.profileRequires((yyvsp[0].lex).loc, ~EEsProfile, 460, nullptr, "extraneous semicolon"); + (yyval.interm.intermNode) = nullptr; + } +#line 7952 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 449: +#line 2902 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyvsp[0].interm).function = parseContext.handleFunctionDeclarator((yyvsp[0].interm).loc, *(yyvsp[0].interm).function, false /* not prototype */); + (yyvsp[0].interm).intermNode = parseContext.handleFunctionDefinition((yyvsp[0].interm).loc, *(yyvsp[0].interm).function); + } +#line 7961 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 450: +#line 2906 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + // May be best done as post process phase on intermediate code + if (parseContext.currentFunctionType->getBasicType() != EbtVoid && ! parseContext.functionReturnsValue) + parseContext.error((yyvsp[-2].interm).loc, "function does not return a value:", "", (yyvsp[-2].interm).function->getName().c_str()); + parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); + (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm).intermNode, (yyvsp[0].interm.intermNode)); + parseContext.intermediate.setAggregateOperator((yyval.interm.intermNode), EOpFunction, (yyvsp[-2].interm).function->getType(), (yyvsp[-2].interm).loc); + (yyval.interm.intermNode)->getAsAggregate()->setName((yyvsp[-2].interm).function->getMangledName().c_str()); + + // store the pragma information for debug and optimize and other vendor specific + // information. This information can be queried from the parse tree + (yyval.interm.intermNode)->getAsAggregate()->setOptimize(parseContext.contextPragma.optimize); + (yyval.interm.intermNode)->getAsAggregate()->setDebug(parseContext.contextPragma.debug); + (yyval.interm.intermNode)->getAsAggregate()->setPragmaTable(parseContext.contextPragma.pragmaTable); + } +#line 7981 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + +#line 7985 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now 'shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*--------------------------------------. +| yyerrlab -- here on detecting error. | +`--------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (pParseContext, YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (pParseContext, yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval, pParseContext); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule whose action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp, pParseContext); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined yyoverflow || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (pParseContext, YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval, pParseContext); + } + /* Do not reclaim the symbols of the rule whose action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp, pParseContext); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + return yyresult; +} +#line 2923 "MachineIndependent/glslang.y" /* yacc.c:1906 */ + diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp.h b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp.h new file mode 100644 index 00000000..b2e00632 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp.h @@ -0,0 +1,395 @@ +/* A Bison parser, made by GNU Bison 3.0. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +#ifndef YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED +# define YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 1 +#endif +#if YYDEBUG +extern int yydebug; +#endif + +/* Token type. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + ATTRIBUTE = 258, + VARYING = 259, + CONST = 260, + BOOL = 261, + FLOAT = 262, + DOUBLE = 263, + INT = 264, + UINT = 265, + INT64_T = 266, + UINT64_T = 267, + INT16_T = 268, + UINT16_T = 269, + FLOAT16_T = 270, + BREAK = 271, + CONTINUE = 272, + DO = 273, + ELSE = 274, + FOR = 275, + IF = 276, + DISCARD = 277, + RETURN = 278, + SWITCH = 279, + CASE = 280, + DEFAULT = 281, + SUBROUTINE = 282, + BVEC2 = 283, + BVEC3 = 284, + BVEC4 = 285, + IVEC2 = 286, + IVEC3 = 287, + IVEC4 = 288, + I64VEC2 = 289, + I64VEC3 = 290, + I64VEC4 = 291, + UVEC2 = 292, + UVEC3 = 293, + UVEC4 = 294, + U64VEC2 = 295, + U64VEC3 = 296, + U64VEC4 = 297, + VEC2 = 298, + VEC3 = 299, + VEC4 = 300, + MAT2 = 301, + MAT3 = 302, + MAT4 = 303, + CENTROID = 304, + IN = 305, + OUT = 306, + INOUT = 307, + UNIFORM = 308, + PATCH = 309, + SAMPLE = 310, + BUFFER = 311, + SHARED = 312, + COHERENT = 313, + VOLATILE = 314, + RESTRICT = 315, + READONLY = 316, + WRITEONLY = 317, + DVEC2 = 318, + DVEC3 = 319, + DVEC4 = 320, + DMAT2 = 321, + DMAT3 = 322, + DMAT4 = 323, + F16VEC2 = 324, + F16VEC3 = 325, + F16VEC4 = 326, + F16MAT2 = 327, + F16MAT3 = 328, + F16MAT4 = 329, + I16VEC2 = 330, + I16VEC3 = 331, + I16VEC4 = 332, + U16VEC2 = 333, + U16VEC3 = 334, + U16VEC4 = 335, + NOPERSPECTIVE = 336, + FLAT = 337, + SMOOTH = 338, + LAYOUT = 339, + __EXPLICITINTERPAMD = 340, + MAT2X2 = 341, + MAT2X3 = 342, + MAT2X4 = 343, + MAT3X2 = 344, + MAT3X3 = 345, + MAT3X4 = 346, + MAT4X2 = 347, + MAT4X3 = 348, + MAT4X4 = 349, + DMAT2X2 = 350, + DMAT2X3 = 351, + DMAT2X4 = 352, + DMAT3X2 = 353, + DMAT3X3 = 354, + DMAT3X4 = 355, + DMAT4X2 = 356, + DMAT4X3 = 357, + DMAT4X4 = 358, + F16MAT2X2 = 359, + F16MAT2X3 = 360, + F16MAT2X4 = 361, + F16MAT3X2 = 362, + F16MAT3X3 = 363, + F16MAT3X4 = 364, + F16MAT4X2 = 365, + F16MAT4X3 = 366, + F16MAT4X4 = 367, + ATOMIC_UINT = 368, + SAMPLER1D = 369, + SAMPLER2D = 370, + SAMPLER3D = 371, + SAMPLERCUBE = 372, + SAMPLER1DSHADOW = 373, + SAMPLER2DSHADOW = 374, + SAMPLERCUBESHADOW = 375, + SAMPLER1DARRAY = 376, + SAMPLER2DARRAY = 377, + SAMPLER1DARRAYSHADOW = 378, + SAMPLER2DARRAYSHADOW = 379, + ISAMPLER1D = 380, + ISAMPLER2D = 381, + ISAMPLER3D = 382, + ISAMPLERCUBE = 383, + ISAMPLER1DARRAY = 384, + ISAMPLER2DARRAY = 385, + USAMPLER1D = 386, + USAMPLER2D = 387, + USAMPLER3D = 388, + USAMPLERCUBE = 389, + USAMPLER1DARRAY = 390, + USAMPLER2DARRAY = 391, + SAMPLER2DRECT = 392, + SAMPLER2DRECTSHADOW = 393, + ISAMPLER2DRECT = 394, + USAMPLER2DRECT = 395, + SAMPLERBUFFER = 396, + ISAMPLERBUFFER = 397, + USAMPLERBUFFER = 398, + SAMPLERCUBEARRAY = 399, + SAMPLERCUBEARRAYSHADOW = 400, + ISAMPLERCUBEARRAY = 401, + USAMPLERCUBEARRAY = 402, + SAMPLER2DMS = 403, + ISAMPLER2DMS = 404, + USAMPLER2DMS = 405, + SAMPLER2DMSARRAY = 406, + ISAMPLER2DMSARRAY = 407, + USAMPLER2DMSARRAY = 408, + SAMPLEREXTERNALOES = 409, + SAMPLER = 410, + SAMPLERSHADOW = 411, + TEXTURE1D = 412, + TEXTURE2D = 413, + TEXTURE3D = 414, + TEXTURECUBE = 415, + TEXTURE1DARRAY = 416, + TEXTURE2DARRAY = 417, + ITEXTURE1D = 418, + ITEXTURE2D = 419, + ITEXTURE3D = 420, + ITEXTURECUBE = 421, + ITEXTURE1DARRAY = 422, + ITEXTURE2DARRAY = 423, + UTEXTURE1D = 424, + UTEXTURE2D = 425, + UTEXTURE3D = 426, + UTEXTURECUBE = 427, + UTEXTURE1DARRAY = 428, + UTEXTURE2DARRAY = 429, + TEXTURE2DRECT = 430, + ITEXTURE2DRECT = 431, + UTEXTURE2DRECT = 432, + TEXTUREBUFFER = 433, + ITEXTUREBUFFER = 434, + UTEXTUREBUFFER = 435, + TEXTURECUBEARRAY = 436, + ITEXTURECUBEARRAY = 437, + UTEXTURECUBEARRAY = 438, + TEXTURE2DMS = 439, + ITEXTURE2DMS = 440, + UTEXTURE2DMS = 441, + TEXTURE2DMSARRAY = 442, + ITEXTURE2DMSARRAY = 443, + UTEXTURE2DMSARRAY = 444, + SUBPASSINPUT = 445, + SUBPASSINPUTMS = 446, + ISUBPASSINPUT = 447, + ISUBPASSINPUTMS = 448, + USUBPASSINPUT = 449, + USUBPASSINPUTMS = 450, + IMAGE1D = 451, + IIMAGE1D = 452, + UIMAGE1D = 453, + IMAGE2D = 454, + IIMAGE2D = 455, + UIMAGE2D = 456, + IMAGE3D = 457, + IIMAGE3D = 458, + UIMAGE3D = 459, + IMAGE2DRECT = 460, + IIMAGE2DRECT = 461, + UIMAGE2DRECT = 462, + IMAGECUBE = 463, + IIMAGECUBE = 464, + UIMAGECUBE = 465, + IMAGEBUFFER = 466, + IIMAGEBUFFER = 467, + UIMAGEBUFFER = 468, + IMAGE1DARRAY = 469, + IIMAGE1DARRAY = 470, + UIMAGE1DARRAY = 471, + IMAGE2DARRAY = 472, + IIMAGE2DARRAY = 473, + UIMAGE2DARRAY = 474, + IMAGECUBEARRAY = 475, + IIMAGECUBEARRAY = 476, + UIMAGECUBEARRAY = 477, + IMAGE2DMS = 478, + IIMAGE2DMS = 479, + UIMAGE2DMS = 480, + IMAGE2DMSARRAY = 481, + IIMAGE2DMSARRAY = 482, + UIMAGE2DMSARRAY = 483, + STRUCT = 484, + VOID = 485, + WHILE = 486, + IDENTIFIER = 487, + TYPE_NAME = 488, + FLOATCONSTANT = 489, + DOUBLECONSTANT = 490, + INTCONSTANT = 491, + UINTCONSTANT = 492, + INT64CONSTANT = 493, + UINT64CONSTANT = 494, + INT16CONSTANT = 495, + UINT16CONSTANT = 496, + BOOLCONSTANT = 497, + FLOAT16CONSTANT = 498, + LEFT_OP = 499, + RIGHT_OP = 500, + INC_OP = 501, + DEC_OP = 502, + LE_OP = 503, + GE_OP = 504, + EQ_OP = 505, + NE_OP = 506, + AND_OP = 507, + OR_OP = 508, + XOR_OP = 509, + MUL_ASSIGN = 510, + DIV_ASSIGN = 511, + ADD_ASSIGN = 512, + MOD_ASSIGN = 513, + LEFT_ASSIGN = 514, + RIGHT_ASSIGN = 515, + AND_ASSIGN = 516, + XOR_ASSIGN = 517, + OR_ASSIGN = 518, + SUB_ASSIGN = 519, + LEFT_PAREN = 520, + RIGHT_PAREN = 521, + LEFT_BRACKET = 522, + RIGHT_BRACKET = 523, + LEFT_BRACE = 524, + RIGHT_BRACE = 525, + DOT = 526, + COMMA = 527, + COLON = 528, + EQUAL = 529, + SEMICOLON = 530, + BANG = 531, + DASH = 532, + TILDE = 533, + PLUS = 534, + STAR = 535, + SLASH = 536, + PERCENT = 537, + LEFT_ANGLE = 538, + RIGHT_ANGLE = 539, + VERTICAL_BAR = 540, + CARET = 541, + AMPERSAND = 542, + QUESTION = 543, + INVARIANT = 544, + PRECISE = 545, + HIGH_PRECISION = 546, + MEDIUM_PRECISION = 547, + LOW_PRECISION = 548, + PRECISION = 549, + PACKED = 550, + RESOURCE = 551, + SUPERP = 552 + }; +#endif + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE YYSTYPE; +union YYSTYPE +{ +#line 68 "MachineIndependent/glslang.y" /* yacc.c:1909 */ + + struct { + glslang::TSourceLoc loc; + union { + glslang::TString *string; + int i; + unsigned int u; + long long i64; + unsigned long long u64; + bool b; + double d; + }; + glslang::TSymbol* symbol; + } lex; + struct { + glslang::TSourceLoc loc; + glslang::TOperator op; + union { + TIntermNode* intermNode; + glslang::TIntermNodePair nodePair; + glslang::TIntermTyped* intermTypedNode; + }; + union { + glslang::TPublicType type; + glslang::TFunction* function; + glslang::TParameter param; + glslang::TTypeLoc typeLine; + glslang::TTypeList* typeList; + glslang::TArraySizes* arraySizes; + glslang::TIdentifierList* identifierList; + }; + } interm; + +#line 386 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */ +}; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + + +int yyparse (glslang::TParseContext* pParseContext); + +#endif /* !YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED */ diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/intermOut.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/intermOut.cpp new file mode 100644 index 00000000..dd2cdc89 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/intermOut.cpp @@ -0,0 +1,1155 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2012-2016 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#include "localintermediate.h" +#include "../Include/InfoSink.h" + +#ifdef _MSC_VER +#include +#else +#include +#endif + +namespace { + +bool IsInfinity(double x) { +#ifdef _MSC_VER + switch (_fpclass(x)) { + case _FPCLASS_NINF: + case _FPCLASS_PINF: + return true; + default: + return false; + } +#else + return std::isinf(x); +#endif +} + +bool IsNan(double x) { +#ifdef _MSC_VER + switch (_fpclass(x)) { + case _FPCLASS_SNAN: + case _FPCLASS_QNAN: + return true; + default: + return false; + } +#else + return std::isnan(x); +#endif +} + +} + +namespace glslang { + +// +// Two purposes: +// 1. Show an example of how to iterate tree. Functions can +// also directly call Traverse() on children themselves to +// have finer grained control over the process than shown here. +// See the last function for how to get started. +// 2. Print out a text based description of the tree. +// + +// +// Use this class to carry along data from node to node in +// the traversal +// +class TOutputTraverser : public TIntermTraverser { +public: + TOutputTraverser(TInfoSink& i) : infoSink(i) { } + + virtual bool visitBinary(TVisit, TIntermBinary* node); + virtual bool visitUnary(TVisit, TIntermUnary* node); + virtual bool visitAggregate(TVisit, TIntermAggregate* node); + virtual bool visitSelection(TVisit, TIntermSelection* node); + virtual void visitConstantUnion(TIntermConstantUnion* node); + virtual void visitSymbol(TIntermSymbol* node); + virtual bool visitLoop(TVisit, TIntermLoop* node); + virtual bool visitBranch(TVisit, TIntermBranch* node); + virtual bool visitSwitch(TVisit, TIntermSwitch* node); + + TInfoSink& infoSink; +protected: + TOutputTraverser(TOutputTraverser&); + TOutputTraverser& operator=(TOutputTraverser&); +}; + +// +// Helper functions for printing, not part of traversing. +// + +static void OutputTreeText(TInfoSink& infoSink, const TIntermNode* node, const int depth) +{ + int i; + + infoSink.debug << node->getLoc().string << ":"; + if (node->getLoc().line) + infoSink.debug << node->getLoc().line; + else + infoSink.debug << "? "; + + for (i = 0; i < depth; ++i) + infoSink.debug << " "; +} + +// +// The rest of the file are the traversal functions. The last one +// is the one that starts the traversal. +// +// Return true from interior nodes to have the external traversal +// continue on to children. If you process children yourself, +// return false. +// + +bool TOutputTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node) +{ + TInfoSink& out = infoSink; + + OutputTreeText(out, node, depth); + + switch (node->getOp()) { + case EOpAssign: out.debug << "move second child to first child"; break; + case EOpAddAssign: out.debug << "add second child into first child"; break; + case EOpSubAssign: out.debug << "subtract second child into first child"; break; + case EOpMulAssign: out.debug << "multiply second child into first child"; break; + case EOpVectorTimesMatrixAssign: out.debug << "matrix mult second child into first child"; break; + case EOpVectorTimesScalarAssign: out.debug << "vector scale second child into first child"; break; + case EOpMatrixTimesScalarAssign: out.debug << "matrix scale second child into first child"; break; + case EOpMatrixTimesMatrixAssign: out.debug << "matrix mult second child into first child"; break; + case EOpDivAssign: out.debug << "divide second child into first child"; break; + case EOpModAssign: out.debug << "mod second child into first child"; break; + case EOpAndAssign: out.debug << "and second child into first child"; break; + case EOpInclusiveOrAssign: out.debug << "or second child into first child"; break; + case EOpExclusiveOrAssign: out.debug << "exclusive or second child into first child"; break; + case EOpLeftShiftAssign: out.debug << "left shift second child into first child"; break; + case EOpRightShiftAssign: out.debug << "right shift second child into first child"; break; + + case EOpIndexDirect: out.debug << "direct index"; break; + case EOpIndexIndirect: out.debug << "indirect index"; break; + case EOpIndexDirectStruct: + out.debug << (*node->getLeft()->getType().getStruct())[node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst()].type->getFieldName(); + out.debug << ": direct index for structure"; break; + case EOpVectorSwizzle: out.debug << "vector swizzle"; break; + case EOpMatrixSwizzle: out.debug << "matrix swizzle"; break; + + case EOpAdd: out.debug << "add"; break; + case EOpSub: out.debug << "subtract"; break; + case EOpMul: out.debug << "component-wise multiply"; break; + case EOpDiv: out.debug << "divide"; break; + case EOpMod: out.debug << "mod"; break; + case EOpRightShift: out.debug << "right-shift"; break; + case EOpLeftShift: out.debug << "left-shift"; break; + case EOpAnd: out.debug << "bitwise and"; break; + case EOpInclusiveOr: out.debug << "inclusive-or"; break; + case EOpExclusiveOr: out.debug << "exclusive-or"; break; + case EOpEqual: out.debug << "Compare Equal"; break; + case EOpNotEqual: out.debug << "Compare Not Equal"; break; + case EOpLessThan: out.debug << "Compare Less Than"; break; + case EOpGreaterThan: out.debug << "Compare Greater Than"; break; + case EOpLessThanEqual: out.debug << "Compare Less Than or Equal"; break; + case EOpGreaterThanEqual: out.debug << "Compare Greater Than or Equal"; break; + case EOpVectorEqual: out.debug << "Equal"; break; + case EOpVectorNotEqual: out.debug << "NotEqual"; break; + + case EOpVectorTimesScalar: out.debug << "vector-scale"; break; + case EOpVectorTimesMatrix: out.debug << "vector-times-matrix"; break; + case EOpMatrixTimesVector: out.debug << "matrix-times-vector"; break; + case EOpMatrixTimesScalar: out.debug << "matrix-scale"; break; + case EOpMatrixTimesMatrix: out.debug << "matrix-multiply"; break; + + case EOpLogicalOr: out.debug << "logical-or"; break; + case EOpLogicalXor: out.debug << "logical-xor"; break; + case EOpLogicalAnd: out.debug << "logical-and"; break; + + default: out.debug << ""; + } + + out.debug << " (" << node->getCompleteString() << ")"; + + out.debug << "\n"; + + return true; +} + +bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node) +{ + TInfoSink& out = infoSink; + + OutputTreeText(out, node, depth); + + switch (node->getOp()) { + case EOpNegative: out.debug << "Negate value"; break; + case EOpVectorLogicalNot: + case EOpLogicalNot: out.debug << "Negate conditional"; break; + case EOpBitwiseNot: out.debug << "Bitwise not"; break; + + case EOpPostIncrement: out.debug << "Post-Increment"; break; + case EOpPostDecrement: out.debug << "Post-Decrement"; break; + case EOpPreIncrement: out.debug << "Pre-Increment"; break; + case EOpPreDecrement: out.debug << "Pre-Decrement"; break; + + case EOpConvIntToBool: out.debug << "Convert int to bool"; break; + case EOpConvUintToBool: out.debug << "Convert uint to bool"; break; + case EOpConvFloatToBool: out.debug << "Convert float to bool"; break; + case EOpConvDoubleToBool: out.debug << "Convert double to bool"; break; + case EOpConvInt64ToBool: out.debug << "Convert int64 to bool"; break; + case EOpConvUint64ToBool: out.debug << "Convert uint64 to bool"; break; + case EOpConvIntToFloat: out.debug << "Convert int to float"; break; + case EOpConvUintToFloat: out.debug << "Convert uint to float"; break; + case EOpConvDoubleToFloat: out.debug << "Convert double to float"; break; + case EOpConvInt64ToFloat: out.debug << "Convert int64 to float"; break; + case EOpConvUint64ToFloat: out.debug << "Convert uint64 to float"; break; + case EOpConvBoolToFloat: out.debug << "Convert bool to float"; break; + case EOpConvUintToInt: out.debug << "Convert uint to int"; break; + case EOpConvFloatToInt: out.debug << "Convert float to int"; break; + case EOpConvDoubleToInt: out.debug << "Convert double to int"; break; + case EOpConvBoolToInt: out.debug << "Convert bool to int"; break; + case EOpConvInt64ToInt: out.debug << "Convert int64 to int"; break; + case EOpConvUint64ToInt: out.debug << "Convert uint64 to int"; break; + case EOpConvIntToUint: out.debug << "Convert int to uint"; break; + case EOpConvFloatToUint: out.debug << "Convert float to uint"; break; + case EOpConvDoubleToUint: out.debug << "Convert double to uint"; break; + case EOpConvBoolToUint: out.debug << "Convert bool to uint"; break; + case EOpConvInt64ToUint: out.debug << "Convert int64 to uint"; break; + case EOpConvUint64ToUint: out.debug << "Convert uint64 to uint"; break; + case EOpConvIntToDouble: out.debug << "Convert int to double"; break; + case EOpConvUintToDouble: out.debug << "Convert uint to double"; break; + case EOpConvFloatToDouble: out.debug << "Convert float to double"; break; + case EOpConvBoolToDouble: out.debug << "Convert bool to double"; break; + case EOpConvInt64ToDouble: out.debug << "Convert int64 to double"; break; + case EOpConvUint64ToDouble: out.debug << "Convert uint64 to double"; break; + case EOpConvBoolToInt64: out.debug << "Convert bool to int64"; break; + case EOpConvIntToInt64: out.debug << "Convert int to int64"; break; + case EOpConvUintToInt64: out.debug << "Convert uint to int64"; break; + case EOpConvFloatToInt64: out.debug << "Convert float to int64"; break; + case EOpConvDoubleToInt64: out.debug << "Convert double to int64"; break; + case EOpConvUint64ToInt64: out.debug << "Convert uint64 to int64"; break; + case EOpConvBoolToUint64: out.debug << "Convert bool to uint64"; break; + case EOpConvIntToUint64: out.debug << "Convert int to uint64"; break; + case EOpConvUintToUint64: out.debug << "Convert uint to uint64"; break; + case EOpConvFloatToUint64: out.debug << "Convert float to uint64"; break; + case EOpConvDoubleToUint64: out.debug << "Convert double to uint64"; break; + case EOpConvInt64ToUint64: out.debug << "Convert uint64 to uint64"; break; + + case EOpRadians: out.debug << "radians"; break; + case EOpDegrees: out.debug << "degrees"; break; + case EOpSin: out.debug << "sine"; break; + case EOpCos: out.debug << "cosine"; break; + case EOpTan: out.debug << "tangent"; break; + case EOpAsin: out.debug << "arc sine"; break; + case EOpAcos: out.debug << "arc cosine"; break; + case EOpAtan: out.debug << "arc tangent"; break; + case EOpSinh: out.debug << "hyp. sine"; break; + case EOpCosh: out.debug << "hyp. cosine"; break; + case EOpTanh: out.debug << "hyp. tangent"; break; + case EOpAsinh: out.debug << "arc hyp. sine"; break; + case EOpAcosh: out.debug << "arc hyp. cosine"; break; + case EOpAtanh: out.debug << "arc hyp. tangent"; break; + + case EOpExp: out.debug << "exp"; break; + case EOpLog: out.debug << "log"; break; + case EOpExp2: out.debug << "exp2"; break; + case EOpLog2: out.debug << "log2"; break; + case EOpSqrt: out.debug << "sqrt"; break; + case EOpInverseSqrt: out.debug << "inverse sqrt"; break; + + case EOpAbs: out.debug << "Absolute value"; break; + case EOpSign: out.debug << "Sign"; break; + case EOpFloor: out.debug << "Floor"; break; + case EOpTrunc: out.debug << "trunc"; break; + case EOpRound: out.debug << "round"; break; + case EOpRoundEven: out.debug << "roundEven"; break; + case EOpCeil: out.debug << "Ceiling"; break; + case EOpFract: out.debug << "Fraction"; break; + + case EOpIsNan: out.debug << "isnan"; break; + case EOpIsInf: out.debug << "isinf"; break; + + case EOpFloatBitsToInt: out.debug << "floatBitsToInt"; break; + case EOpFloatBitsToUint:out.debug << "floatBitsToUint"; break; + case EOpIntBitsToFloat: out.debug << "intBitsToFloat"; break; + case EOpUintBitsToFloat:out.debug << "uintBitsToFloat"; break; + case EOpDoubleBitsToInt64: out.debug << "doubleBitsToInt64"; break; + case EOpDoubleBitsToUint64: out.debug << "doubleBitsToUint64"; break; + case EOpInt64BitsToDouble: out.debug << "int64BitsToDouble"; break; + case EOpUint64BitsToDouble: out.debug << "uint64BitsToDouble"; break; +#ifdef AMD_EXTENSIONS + case EOpFloat16BitsToInt16: out.debug << "float16BitsToInt16"; break; + case EOpFloat16BitsToUint16: out.debug << "float16BitsToUint16"; break; + case EOpInt16BitsToFloat16: out.debug << "int16BitsToFloat16"; break; + case EOpUint16BitsToFloat16: out.debug << "uint16BitsToFloat16"; break; +#endif + + case EOpPackSnorm2x16: out.debug << "packSnorm2x16"; break; + case EOpUnpackSnorm2x16:out.debug << "unpackSnorm2x16"; break; + case EOpPackUnorm2x16: out.debug << "packUnorm2x16"; break; + case EOpUnpackUnorm2x16:out.debug << "unpackUnorm2x16"; break; + case EOpPackHalf2x16: out.debug << "packHalf2x16"; break; + case EOpUnpackHalf2x16: out.debug << "unpackHalf2x16"; break; + + case EOpPackSnorm4x8: out.debug << "PackSnorm4x8"; break; + case EOpUnpackSnorm4x8: out.debug << "UnpackSnorm4x8"; break; + case EOpPackUnorm4x8: out.debug << "PackUnorm4x8"; break; + case EOpUnpackUnorm4x8: out.debug << "UnpackUnorm4x8"; break; + case EOpPackDouble2x32: out.debug << "PackDouble2x32"; break; + case EOpUnpackDouble2x32: out.debug << "UnpackDouble2x32"; break; + + case EOpPackInt2x32: out.debug << "packInt2x32"; break; + case EOpUnpackInt2x32: out.debug << "unpackInt2x32"; break; + case EOpPackUint2x32: out.debug << "packUint2x32"; break; + case EOpUnpackUint2x32: out.debug << "unpackUint2x32"; break; + +#ifdef AMD_EXTENSIONS + case EOpPackInt2x16: out.debug << "packInt2x16"; break; + case EOpUnpackInt2x16: out.debug << "unpackInt2x16"; break; + case EOpPackUint2x16: out.debug << "packUint2x16"; break; + case EOpUnpackUint2x16: out.debug << "unpackUint2x16"; break; + + case EOpPackInt4x16: out.debug << "packInt4x16"; break; + case EOpUnpackInt4x16: out.debug << "unpackInt4x16"; break; + case EOpPackUint4x16: out.debug << "packUint4x16"; break; + case EOpUnpackUint4x16: out.debug << "unpackUint4x16"; break; + + case EOpPackFloat2x16: out.debug << "packFloat2x16"; break; + case EOpUnpackFloat2x16: out.debug << "unpackFloat2x16"; break; +#endif + + case EOpLength: out.debug << "length"; break; + case EOpNormalize: out.debug << "normalize"; break; + case EOpDPdx: out.debug << "dPdx"; break; + case EOpDPdy: out.debug << "dPdy"; break; + case EOpFwidth: out.debug << "fwidth"; break; + case EOpDPdxFine: out.debug << "dPdxFine"; break; + case EOpDPdyFine: out.debug << "dPdyFine"; break; + case EOpFwidthFine: out.debug << "fwidthFine"; break; + case EOpDPdxCoarse: out.debug << "dPdxCoarse"; break; + case EOpDPdyCoarse: out.debug << "dPdyCoarse"; break; + case EOpFwidthCoarse: out.debug << "fwidthCoarse"; break; + + case EOpInterpolateAtCentroid: out.debug << "interpolateAtCentroid"; break; + + case EOpDeterminant: out.debug << "determinant"; break; + case EOpMatrixInverse: out.debug << "inverse"; break; + case EOpTranspose: out.debug << "transpose"; break; + + case EOpAny: out.debug << "any"; break; + case EOpAll: out.debug << "all"; break; + + case EOpArrayLength: out.debug << "array length"; break; + + case EOpEmitStreamVertex: out.debug << "EmitStreamVertex"; break; + case EOpEndStreamPrimitive: out.debug << "EndStreamPrimitive"; break; + + case EOpAtomicCounterIncrement: out.debug << "AtomicCounterIncrement";break; + case EOpAtomicCounterDecrement: out.debug << "AtomicCounterDecrement";break; + case EOpAtomicCounter: out.debug << "AtomicCounter"; break; + + case EOpTextureQuerySize: out.debug << "textureSize"; break; + case EOpTextureQueryLod: out.debug << "textureQueryLod"; break; + case EOpTextureQueryLevels: out.debug << "textureQueryLevels"; break; + case EOpTextureQuerySamples: out.debug << "textureSamples"; break; + case EOpImageQuerySize: out.debug << "imageQuerySize"; break; + case EOpImageQuerySamples: out.debug << "imageQuerySamples"; break; + case EOpImageLoad: out.debug << "imageLoad"; break; + + case EOpBitFieldReverse: out.debug << "bitFieldReverse"; break; + case EOpBitCount: out.debug << "bitCount"; break; + case EOpFindLSB: out.debug << "findLSB"; break; + case EOpFindMSB: out.debug << "findMSB"; break; + + case EOpNoise: out.debug << "noise"; break; + + case EOpBallot: out.debug << "ballot"; break; + case EOpReadFirstInvocation: out.debug << "readFirstInvocation"; break; + + case EOpAnyInvocation: out.debug << "anyInvocation"; break; + case EOpAllInvocations: out.debug << "allInvocations"; break; + case EOpAllInvocationsEqual: out.debug << "allInvocationsEqual"; break; + + case EOpClip: out.debug << "clip"; break; + case EOpIsFinite: out.debug << "isfinite"; break; + case EOpLog10: out.debug << "log10"; break; + case EOpRcp: out.debug << "rcp"; break; + case EOpSaturate: out.debug << "saturate"; break; + + case EOpSparseTexelsResident: out.debug << "sparseTexelsResident"; break; + +#ifdef AMD_EXTENSIONS + case EOpMinInvocations: out.debug << "minInvocations"; break; + case EOpMaxInvocations: out.debug << "maxInvocations"; break; + case EOpAddInvocations: out.debug << "addInvocations"; break; + case EOpMinInvocationsNonUniform: out.debug << "minInvocationsNonUniform"; break; + case EOpMaxInvocationsNonUniform: out.debug << "maxInvocationsNonUniform"; break; + case EOpAddInvocationsNonUniform: out.debug << "addInvocationsNonUniform"; break; + + case EOpMinInvocationsInclusiveScan: out.debug << "minInvocationsInclusiveScan"; break; + case EOpMaxInvocationsInclusiveScan: out.debug << "maxInvocationsInclusiveScan"; break; + case EOpAddInvocationsInclusiveScan: out.debug << "addInvocationsInclusiveScan"; break; + case EOpMinInvocationsInclusiveScanNonUniform: out.debug << "minInvocationsInclusiveScanNonUniform"; break; + case EOpMaxInvocationsInclusiveScanNonUniform: out.debug << "maxInvocationsInclusiveScanNonUniform"; break; + case EOpAddInvocationsInclusiveScanNonUniform: out.debug << "addInvocationsInclusiveScanNonUniform"; break; + + case EOpMinInvocationsExclusiveScan: out.debug << "minInvocationsExclusiveScan"; break; + case EOpMaxInvocationsExclusiveScan: out.debug << "maxInvocationsExclusiveScan"; break; + case EOpAddInvocationsExclusiveScan: out.debug << "addInvocationsExclusiveScan"; break; + case EOpMinInvocationsExclusiveScanNonUniform: out.debug << "minInvocationsExclusiveScanNonUniform"; break; + case EOpMaxInvocationsExclusiveScanNonUniform: out.debug << "maxInvocationsExclusiveScanNonUniform"; break; + case EOpAddInvocationsExclusiveScanNonUniform: out.debug << "addInvocationsExclusiveScanNonUniform"; break; + + case EOpMbcnt: out.debug << "mbcnt"; break; + + case EOpCubeFaceIndex: out.debug << "cubeFaceIndex"; break; + case EOpCubeFaceCoord: out.debug << "cubeFaceCoord"; break; + + case EOpFragmentMaskFetch: out.debug << "fragmentMaskFetchAMD"; break; + case EOpFragmentFetch: out.debug << "fragmentFetchAMD"; break; + + case EOpConvBoolToFloat16: out.debug << "Convert bool to float16"; break; + case EOpConvIntToFloat16: out.debug << "Convert int to float16"; break; + case EOpConvUintToFloat16: out.debug << "Convert uint to float16"; break; + case EOpConvFloatToFloat16: out.debug << "Convert float to float16"; break; + case EOpConvDoubleToFloat16: out.debug << "Convert double to float16"; break; + case EOpConvInt64ToFloat16: out.debug << "Convert int64 to float16"; break; + case EOpConvUint64ToFloat16: out.debug << "Convert uint64 to float16"; break; + case EOpConvFloat16ToBool: out.debug << "Convert float16 to bool"; break; + case EOpConvFloat16ToInt: out.debug << "Convert float16 to int"; break; + case EOpConvFloat16ToUint: out.debug << "Convert float16 to uint"; break; + case EOpConvFloat16ToFloat: out.debug << "Convert float16 to float"; break; + case EOpConvFloat16ToDouble: out.debug << "Convert float16 to double"; break; + case EOpConvFloat16ToInt64: out.debug << "Convert float16 to int64"; break; + case EOpConvFloat16ToUint64: out.debug << "Convert float16 to uint64"; break; + + case EOpConvBoolToInt16: out.debug << "Convert bool to int16"; break; + case EOpConvIntToInt16: out.debug << "Convert int to int16"; break; + case EOpConvUintToInt16: out.debug << "Convert uint to int16"; break; + case EOpConvFloatToInt16: out.debug << "Convert float to int16"; break; + case EOpConvDoubleToInt16: out.debug << "Convert double to int16"; break; + case EOpConvFloat16ToInt16: out.debug << "Convert float16 to int16"; break; + case EOpConvInt64ToInt16: out.debug << "Convert int64 to int16"; break; + case EOpConvUint64ToInt16: out.debug << "Convert uint64 to int16"; break; + case EOpConvUint16ToInt16: out.debug << "Convert uint16 to int16"; break; + case EOpConvInt16ToBool: out.debug << "Convert int16 to bool"; break; + case EOpConvInt16ToInt: out.debug << "Convert int16 to int"; break; + case EOpConvInt16ToUint: out.debug << "Convert int16 to uint"; break; + case EOpConvInt16ToFloat: out.debug << "Convert int16 to float"; break; + case EOpConvInt16ToDouble: out.debug << "Convert int16 to double"; break; + case EOpConvInt16ToFloat16: out.debug << "Convert int16 to float16"; break; + case EOpConvInt16ToInt64: out.debug << "Convert int16 to int64"; break; + case EOpConvInt16ToUint64: out.debug << "Convert int16 to uint64"; break; + + case EOpConvBoolToUint16: out.debug << "Convert bool to uint16"; break; + case EOpConvIntToUint16: out.debug << "Convert int to uint16"; break; + case EOpConvUintToUint16: out.debug << "Convert uint to uint16"; break; + case EOpConvFloatToUint16: out.debug << "Convert float to uint16"; break; + case EOpConvDoubleToUint16: out.debug << "Convert double to uint16"; break; + case EOpConvFloat16ToUint16: out.debug << "Convert float16 to uint16"; break; + case EOpConvInt64ToUint16: out.debug << "Convert int64 to uint16"; break; + case EOpConvUint64ToUint16: out.debug << "Convert uint64 to uint16"; break; + case EOpConvInt16ToUint16: out.debug << "Convert int16 to uint16"; break; + case EOpConvUint16ToBool: out.debug << "Convert uint16 to bool"; break; + case EOpConvUint16ToInt: out.debug << "Convert uint16 to int"; break; + case EOpConvUint16ToUint: out.debug << "Convert uint16 to uint"; break; + case EOpConvUint16ToFloat: out.debug << "Convert uint16 to float"; break; + case EOpConvUint16ToDouble: out.debug << "Convert uint16 to double"; break; + case EOpConvUint16ToFloat16: out.debug << "Convert uint16 to float16"; break; + case EOpConvUint16ToInt64: out.debug << "Convert uint16 to int64"; break; + case EOpConvUint16ToUint64: out.debug << "Convert uint16 to uint64"; break; +#endif + + case EOpSubpassLoad: out.debug << "subpassLoad"; break; + case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break; + + default: out.debug.message(EPrefixError, "Bad unary op"); + } + + out.debug << " (" << node->getCompleteString() << ")"; + + out.debug << "\n"; + + return true; +} + +bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node) +{ + TInfoSink& out = infoSink; + + if (node->getOp() == EOpNull) { + out.debug.message(EPrefixError, "node is still EOpNull!"); + return true; + } + + OutputTreeText(out, node, depth); + + switch (node->getOp()) { + case EOpSequence: out.debug << "Sequence\n"; return true; + case EOpLinkerObjects: out.debug << "Linker Objects\n"; return true; + case EOpComma: out.debug << "Comma"; break; + case EOpFunction: out.debug << "Function Definition: " << node->getName(); break; + case EOpFunctionCall: out.debug << "Function Call: " << node->getName(); break; + case EOpParameters: out.debug << "Function Parameters: "; break; + + case EOpConstructFloat: out.debug << "Construct float"; break; + case EOpConstructDouble:out.debug << "Construct double"; break; + + case EOpConstructVec2: out.debug << "Construct vec2"; break; + case EOpConstructVec3: out.debug << "Construct vec3"; break; + case EOpConstructVec4: out.debug << "Construct vec4"; break; + case EOpConstructDVec2: out.debug << "Construct dvec2"; break; + case EOpConstructDVec3: out.debug << "Construct dvec3"; break; + case EOpConstructDVec4: out.debug << "Construct dvec4"; break; + case EOpConstructBool: out.debug << "Construct bool"; break; + case EOpConstructBVec2: out.debug << "Construct bvec2"; break; + case EOpConstructBVec3: out.debug << "Construct bvec3"; break; + case EOpConstructBVec4: out.debug << "Construct bvec4"; break; + case EOpConstructInt: out.debug << "Construct int"; break; + case EOpConstructIVec2: out.debug << "Construct ivec2"; break; + case EOpConstructIVec3: out.debug << "Construct ivec3"; break; + case EOpConstructIVec4: out.debug << "Construct ivec4"; break; + case EOpConstructUint: out.debug << "Construct uint"; break; + case EOpConstructUVec2: out.debug << "Construct uvec2"; break; + case EOpConstructUVec3: out.debug << "Construct uvec3"; break; + case EOpConstructUVec4: out.debug << "Construct uvec4"; break; + case EOpConstructInt64: out.debug << "Construct int64_t"; break; + case EOpConstructI64Vec2: out.debug << "Construct i64vec2"; break; + case EOpConstructI64Vec3: out.debug << "Construct i64vec3"; break; + case EOpConstructI64Vec4: out.debug << "Construct i64vec4"; break; + case EOpConstructUint64: out.debug << "Construct uint64_t"; break; + case EOpConstructU64Vec2: out.debug << "Construct u64vec2"; break; + case EOpConstructU64Vec3: out.debug << "Construct u64vec3"; break; + case EOpConstructU64Vec4: out.debug << "Construct u64vec4"; break; +#ifdef AMD_EXTENSIONS + case EOpConstructInt16: out.debug << "Construct int16_t"; break; + case EOpConstructI16Vec2: out.debug << "Construct i16vec2"; break; + case EOpConstructI16Vec3: out.debug << "Construct i16vec3"; break; + case EOpConstructI16Vec4: out.debug << "Construct i16vec4"; break; + case EOpConstructUint16: out.debug << "Construct uint16_t"; break; + case EOpConstructU16Vec2: out.debug << "Construct u16vec2"; break; + case EOpConstructU16Vec3: out.debug << "Construct u16vec3"; break; + case EOpConstructU16Vec4: out.debug << "Construct u16vec4"; break; +#endif + case EOpConstructMat2x2: out.debug << "Construct mat2"; break; + case EOpConstructMat2x3: out.debug << "Construct mat2x3"; break; + case EOpConstructMat2x4: out.debug << "Construct mat2x4"; break; + case EOpConstructMat3x2: out.debug << "Construct mat3x2"; break; + case EOpConstructMat3x3: out.debug << "Construct mat3"; break; + case EOpConstructMat3x4: out.debug << "Construct mat3x4"; break; + case EOpConstructMat4x2: out.debug << "Construct mat4x2"; break; + case EOpConstructMat4x3: out.debug << "Construct mat4x3"; break; + case EOpConstructMat4x4: out.debug << "Construct mat4"; break; + case EOpConstructDMat2x2: out.debug << "Construct dmat2"; break; + case EOpConstructDMat2x3: out.debug << "Construct dmat2x3"; break; + case EOpConstructDMat2x4: out.debug << "Construct dmat2x4"; break; + case EOpConstructDMat3x2: out.debug << "Construct dmat3x2"; break; + case EOpConstructDMat3x3: out.debug << "Construct dmat3"; break; + case EOpConstructDMat3x4: out.debug << "Construct dmat3x4"; break; + case EOpConstructDMat4x2: out.debug << "Construct dmat4x2"; break; + case EOpConstructDMat4x3: out.debug << "Construct dmat4x3"; break; + case EOpConstructDMat4x4: out.debug << "Construct dmat4"; break; + case EOpConstructIMat2x2: out.debug << "Construct imat2"; break; + case EOpConstructIMat2x3: out.debug << "Construct imat2x3"; break; + case EOpConstructIMat2x4: out.debug << "Construct imat2x4"; break; + case EOpConstructIMat3x2: out.debug << "Construct imat3x2"; break; + case EOpConstructIMat3x3: out.debug << "Construct imat3"; break; + case EOpConstructIMat3x4: out.debug << "Construct imat3x4"; break; + case EOpConstructIMat4x2: out.debug << "Construct imat4x2"; break; + case EOpConstructIMat4x3: out.debug << "Construct imat4x3"; break; + case EOpConstructIMat4x4: out.debug << "Construct imat4"; break; + case EOpConstructUMat2x2: out.debug << "Construct umat2"; break; + case EOpConstructUMat2x3: out.debug << "Construct umat2x3"; break; + case EOpConstructUMat2x4: out.debug << "Construct umat2x4"; break; + case EOpConstructUMat3x2: out.debug << "Construct umat3x2"; break; + case EOpConstructUMat3x3: out.debug << "Construct umat3"; break; + case EOpConstructUMat3x4: out.debug << "Construct umat3x4"; break; + case EOpConstructUMat4x2: out.debug << "Construct umat4x2"; break; + case EOpConstructUMat4x3: out.debug << "Construct umat4x3"; break; + case EOpConstructUMat4x4: out.debug << "Construct umat4"; break; + case EOpConstructBMat2x2: out.debug << "Construct bmat2"; break; + case EOpConstructBMat2x3: out.debug << "Construct bmat2x3"; break; + case EOpConstructBMat2x4: out.debug << "Construct bmat2x4"; break; + case EOpConstructBMat3x2: out.debug << "Construct bmat3x2"; break; + case EOpConstructBMat3x3: out.debug << "Construct bmat3"; break; + case EOpConstructBMat3x4: out.debug << "Construct bmat3x4"; break; + case EOpConstructBMat4x2: out.debug << "Construct bmat4x2"; break; + case EOpConstructBMat4x3: out.debug << "Construct bmat4x3"; break; + case EOpConstructBMat4x4: out.debug << "Construct bmat4"; break; +#ifdef AMD_EXTENSIONS + case EOpConstructFloat16: out.debug << "Construct float16_t"; break; + case EOpConstructF16Vec2: out.debug << "Construct f16vec2"; break; + case EOpConstructF16Vec3: out.debug << "Construct f16vec3"; break; + case EOpConstructF16Vec4: out.debug << "Construct f16vec4"; break; + case EOpConstructF16Mat2x2: out.debug << "Construct f16mat2"; break; + case EOpConstructF16Mat2x3: out.debug << "Construct f16mat2x3"; break; + case EOpConstructF16Mat2x4: out.debug << "Construct f16mat2x4"; break; + case EOpConstructF16Mat3x2: out.debug << "Construct f16mat3x2"; break; + case EOpConstructF16Mat3x3: out.debug << "Construct f16mat3"; break; + case EOpConstructF16Mat3x4: out.debug << "Construct f16mat3x4"; break; + case EOpConstructF16Mat4x2: out.debug << "Construct f16mat4x2"; break; + case EOpConstructF16Mat4x3: out.debug << "Construct f16mat4x3"; break; + case EOpConstructF16Mat4x4: out.debug << "Construct f16mat4"; break; +#endif + case EOpConstructStruct: out.debug << "Construct structure"; break; + case EOpConstructTextureSampler: out.debug << "Construct combined texture-sampler"; break; + + case EOpLessThan: out.debug << "Compare Less Than"; break; + case EOpGreaterThan: out.debug << "Compare Greater Than"; break; + case EOpLessThanEqual: out.debug << "Compare Less Than or Equal"; break; + case EOpGreaterThanEqual: out.debug << "Compare Greater Than or Equal"; break; + case EOpVectorEqual: out.debug << "Equal"; break; + case EOpVectorNotEqual: out.debug << "NotEqual"; break; + + case EOpMod: out.debug << "mod"; break; + case EOpModf: out.debug << "modf"; break; + case EOpPow: out.debug << "pow"; break; + + case EOpAtan: out.debug << "arc tangent"; break; + + case EOpMin: out.debug << "min"; break; + case EOpMax: out.debug << "max"; break; + case EOpClamp: out.debug << "clamp"; break; + case EOpMix: out.debug << "mix"; break; + case EOpStep: out.debug << "step"; break; + case EOpSmoothStep: out.debug << "smoothstep"; break; + + case EOpDistance: out.debug << "distance"; break; + case EOpDot: out.debug << "dot-product"; break; + case EOpCross: out.debug << "cross-product"; break; + case EOpFaceForward: out.debug << "face-forward"; break; + case EOpReflect: out.debug << "reflect"; break; + case EOpRefract: out.debug << "refract"; break; + case EOpMul: out.debug << "component-wise multiply"; break; + case EOpOuterProduct: out.debug << "outer product"; break; + + case EOpEmitVertex: out.debug << "EmitVertex"; break; + case EOpEndPrimitive: out.debug << "EndPrimitive"; break; + + case EOpBarrier: out.debug << "Barrier"; break; + case EOpMemoryBarrier: out.debug << "MemoryBarrier"; break; + case EOpMemoryBarrierAtomicCounter: out.debug << "MemoryBarrierAtomicCounter"; break; + case EOpMemoryBarrierBuffer: out.debug << "MemoryBarrierBuffer"; break; + case EOpMemoryBarrierImage: out.debug << "MemoryBarrierImage"; break; + case EOpMemoryBarrierShared: out.debug << "MemoryBarrierShared"; break; + case EOpGroupMemoryBarrier: out.debug << "GroupMemoryBarrier"; break; + + case EOpReadInvocation: out.debug << "readInvocation"; break; + +#ifdef AMD_EXTENSIONS + case EOpSwizzleInvocations: out.debug << "swizzleInvocations"; break; + case EOpSwizzleInvocationsMasked: out.debug << "swizzleInvocationsMasked"; break; + case EOpWriteInvocation: out.debug << "writeInvocation"; break; + + case EOpMin3: out.debug << "min3"; break; + case EOpMax3: out.debug << "max3"; break; + case EOpMid3: out.debug << "mid3"; break; + + case EOpTime: out.debug << "time"; break; +#endif + + case EOpAtomicAdd: out.debug << "AtomicAdd"; break; + case EOpAtomicMin: out.debug << "AtomicMin"; break; + case EOpAtomicMax: out.debug << "AtomicMax"; break; + case EOpAtomicAnd: out.debug << "AtomicAnd"; break; + case EOpAtomicOr: out.debug << "AtomicOr"; break; + case EOpAtomicXor: out.debug << "AtomicXor"; break; + case EOpAtomicExchange: out.debug << "AtomicExchange"; break; + case EOpAtomicCompSwap: out.debug << "AtomicCompSwap"; break; + + case EOpAtomicCounterAdd: out.debug << "AtomicCounterAdd"; break; + case EOpAtomicCounterSubtract: out.debug << "AtomicCounterSubtract"; break; + case EOpAtomicCounterMin: out.debug << "AtomicCounterMin"; break; + case EOpAtomicCounterMax: out.debug << "AtomicCounterMax"; break; + case EOpAtomicCounterAnd: out.debug << "AtomicCounterAnd"; break; + case EOpAtomicCounterOr: out.debug << "AtomicCounterOr"; break; + case EOpAtomicCounterXor: out.debug << "AtomicCounterXor"; break; + case EOpAtomicCounterExchange: out.debug << "AtomicCounterExchange"; break; + case EOpAtomicCounterCompSwap: out.debug << "AtomicCounterCompSwap"; break; + + case EOpImageQuerySize: out.debug << "imageQuerySize"; break; + case EOpImageQuerySamples: out.debug << "imageQuerySamples"; break; + case EOpImageLoad: out.debug << "imageLoad"; break; + case EOpImageStore: out.debug << "imageStore"; break; + case EOpImageAtomicAdd: out.debug << "imageAtomicAdd"; break; + case EOpImageAtomicMin: out.debug << "imageAtomicMin"; break; + case EOpImageAtomicMax: out.debug << "imageAtomicMax"; break; + case EOpImageAtomicAnd: out.debug << "imageAtomicAnd"; break; + case EOpImageAtomicOr: out.debug << "imageAtomicOr"; break; + case EOpImageAtomicXor: out.debug << "imageAtomicXor"; break; + case EOpImageAtomicExchange: out.debug << "imageAtomicExchange"; break; + case EOpImageAtomicCompSwap: out.debug << "imageAtomicCompSwap"; break; +#ifdef AMD_EXTENSIONS + case EOpImageLoadLod: out.debug << "imageLoadLod"; break; + case EOpImageStoreLod: out.debug << "imageStoreLod"; break; +#endif + + case EOpTextureQuerySize: out.debug << "textureSize"; break; + case EOpTextureQueryLod: out.debug << "textureQueryLod"; break; + case EOpTextureQueryLevels: out.debug << "textureQueryLevels"; break; + case EOpTextureQuerySamples: out.debug << "textureSamples"; break; + case EOpTexture: out.debug << "texture"; break; + case EOpTextureProj: out.debug << "textureProj"; break; + case EOpTextureLod: out.debug << "textureLod"; break; + case EOpTextureOffset: out.debug << "textureOffset"; break; + case EOpTextureFetch: out.debug << "textureFetch"; break; + case EOpTextureFetchOffset: out.debug << "textureFetchOffset"; break; + case EOpTextureProjOffset: out.debug << "textureProjOffset"; break; + case EOpTextureLodOffset: out.debug << "textureLodOffset"; break; + case EOpTextureProjLod: out.debug << "textureProjLod"; break; + case EOpTextureProjLodOffset: out.debug << "textureProjLodOffset"; break; + case EOpTextureGrad: out.debug << "textureGrad"; break; + case EOpTextureGradOffset: out.debug << "textureGradOffset"; break; + case EOpTextureProjGrad: out.debug << "textureProjGrad"; break; + case EOpTextureProjGradOffset: out.debug << "textureProjGradOffset"; break; + case EOpTextureGather: out.debug << "textureGather"; break; + case EOpTextureGatherOffset: out.debug << "textureGatherOffset"; break; + case EOpTextureGatherOffsets: out.debug << "textureGatherOffsets"; break; + case EOpTextureClamp: out.debug << "textureClamp"; break; + case EOpTextureOffsetClamp: out.debug << "textureOffsetClamp"; break; + case EOpTextureGradClamp: out.debug << "textureGradClamp"; break; + case EOpTextureGradOffsetClamp: out.debug << "textureGradOffsetClamp"; break; +#ifdef AMD_EXTENSIONS + case EOpTextureGatherLod: out.debug << "textureGatherLod"; break; + case EOpTextureGatherLodOffset: out.debug << "textureGatherLodOffset"; break; + case EOpTextureGatherLodOffsets: out.debug << "textureGatherLodOffsets"; break; +#endif + + case EOpSparseTexture: out.debug << "sparseTexture"; break; + case EOpSparseTextureOffset: out.debug << "sparseTextureOffset"; break; + case EOpSparseTextureLod: out.debug << "sparseTextureLod"; break; + case EOpSparseTextureLodOffset: out.debug << "sparseTextureLodOffset"; break; + case EOpSparseTextureFetch: out.debug << "sparseTexelFetch"; break; + case EOpSparseTextureFetchOffset: out.debug << "sparseTexelFetchOffset"; break; + case EOpSparseTextureGrad: out.debug << "sparseTextureGrad"; break; + case EOpSparseTextureGradOffset: out.debug << "sparseTextureGradOffset"; break; + case EOpSparseTextureGather: out.debug << "sparseTextureGather"; break; + case EOpSparseTextureGatherOffset: out.debug << "sparseTextureGatherOffset"; break; + case EOpSparseTextureGatherOffsets: out.debug << "sparseTextureGatherOffsets"; break; + case EOpSparseImageLoad: out.debug << "sparseImageLoad"; break; + case EOpSparseTextureClamp: out.debug << "sparseTextureClamp"; break; + case EOpSparseTextureOffsetClamp: out.debug << "sparseTextureOffsetClamp"; break; + case EOpSparseTextureGradClamp: out.debug << "sparseTextureGradClamp"; break; + case EOpSparseTextureGradOffsetClamp: out.debug << "sparseTextureGradOffsetClam"; break; +#ifdef AMD_EXTENSIONS + case EOpSparseTextureGatherLod: out.debug << "sparseTextureGatherLod"; break; + case EOpSparseTextureGatherLodOffset: out.debug << "sparseTextureGatherLodOffset"; break; + case EOpSparseTextureGatherLodOffsets: out.debug << "sparseTextureGatherLodOffsets"; break; + case EOpSparseImageLoadLod: out.debug << "sparseImageLoadLod"; break; +#endif + + case EOpAddCarry: out.debug << "addCarry"; break; + case EOpSubBorrow: out.debug << "subBorrow"; break; + case EOpUMulExtended: out.debug << "uMulExtended"; break; + case EOpIMulExtended: out.debug << "iMulExtended"; break; + case EOpBitfieldExtract: out.debug << "bitfieldExtract"; break; + case EOpBitfieldInsert: out.debug << "bitfieldInsert"; break; + + case EOpFma: out.debug << "fma"; break; + case EOpFrexp: out.debug << "frexp"; break; + case EOpLdexp: out.debug << "ldexp"; break; + + case EOpInterpolateAtSample: out.debug << "interpolateAtSample"; break; + case EOpInterpolateAtOffset: out.debug << "interpolateAtOffset"; break; +#ifdef AMD_EXTENSIONS + case EOpInterpolateAtVertex: out.debug << "interpolateAtVertex"; break; +#endif + + case EOpSinCos: out.debug << "sincos"; break; + case EOpGenMul: out.debug << "mul"; break; + + case EOpAllMemoryBarrierWithGroupSync: out.debug << "AllMemoryBarrierWithGroupSync"; break; + case EOpDeviceMemoryBarrier: out.debug << "DeviceMemoryBarrier"; break; + case EOpDeviceMemoryBarrierWithGroupSync: out.debug << "DeviceMemoryBarrierWithGroupSync"; break; + case EOpWorkgroupMemoryBarrier: out.debug << "WorkgroupMemoryBarrier"; break; + case EOpWorkgroupMemoryBarrierWithGroupSync: out.debug << "WorkgroupMemoryBarrierWithGroupSync"; break; + + case EOpSubpassLoad: out.debug << "subpassLoad"; break; + case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break; + + default: out.debug.message(EPrefixError, "Bad aggregation op"); + } + + if (node->getOp() != EOpSequence && node->getOp() != EOpParameters) + out.debug << " (" << node->getCompleteString() << ")"; + + out.debug << "\n"; + + return true; +} + +bool TOutputTraverser::visitSelection(TVisit /* visit */, TIntermSelection* node) +{ + TInfoSink& out = infoSink; + + OutputTreeText(out, node, depth); + + out.debug << "Test condition and select"; + out.debug << " (" << node->getCompleteString() << ")\n"; + + ++depth; + + OutputTreeText(out, node, depth); + out.debug << "Condition\n"; + node->getCondition()->traverse(this); + + OutputTreeText(out, node, depth); + if (node->getTrueBlock()) { + out.debug << "true case\n"; + node->getTrueBlock()->traverse(this); + } else + out.debug << "true case is null\n"; + + if (node->getFalseBlock()) { + OutputTreeText(out, node, depth); + out.debug << "false case\n"; + node->getFalseBlock()->traverse(this); + } + + --depth; + + return false; +} + +static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const TConstUnionArray& constUnion, int depth) +{ + int size = node->getType().computeNumComponents(); + + for (int i = 0; i < size; i++) { + OutputTreeText(out, node, depth); + switch (constUnion[i].getType()) { + case EbtBool: + if (constUnion[i].getBConst()) + out.debug << "true"; + else + out.debug << "false"; + + out.debug << " (" << "const bool" << ")"; + + out.debug << "\n"; + break; + case EbtFloat: + case EbtDouble: +#ifdef AMD_EXTENSIONS + case EbtFloat16: +#endif + { + const double value = constUnion[i].getDConst(); + // Print infinities and NaNs in a portable way. + if (IsInfinity(value)) { + if (value < 0) + out.debug << "-1.#INF\n"; + else + out.debug << "+1.#INF\n"; + } else if (IsNan(value)) + out.debug << "1.#IND\n"; + else { + const int maxSize = 300; + char buf[maxSize]; + snprintf(buf, maxSize, "%f", value); + + out.debug << buf << "\n"; + } + } + break; + case EbtInt: + { + const int maxSize = 300; + char buf[maxSize]; + snprintf(buf, maxSize, "%d (%s)", constUnion[i].getIConst(), "const int"); + + out.debug << buf << "\n"; + } + break; + case EbtUint: + { + const int maxSize = 300; + char buf[maxSize]; + snprintf(buf, maxSize, "%u (%s)", constUnion[i].getUConst(), "const uint"); + + out.debug << buf << "\n"; + } + break; + case EbtInt64: + { + const int maxSize = 300; + char buf[maxSize]; + snprintf(buf, maxSize, "%lld (%s)", constUnion[i].getI64Const(), "const int64_t"); + + out.debug << buf << "\n"; + } + break; + case EbtUint64: + { + const int maxSize = 300; + char buf[maxSize]; + snprintf(buf, maxSize, "%llu (%s)", constUnion[i].getU64Const(), "const uint64_t"); + + out.debug << buf << "\n"; + } + break; +#ifdef AMD_EXTENSIONS + case EbtInt16: + { + const int maxSize = 300; + char buf[maxSize]; + snprintf(buf, maxSize, "%d (%s)", constUnion[i].getIConst(), "const int16_t"); + + out.debug << buf << "\n"; + } + break; + case EbtUint16: + { + const int maxSize = 300; + char buf[maxSize]; + snprintf(buf, maxSize, "%u (%s)", constUnion[i].getUConst(), "const uint16_t"); + + out.debug << buf << "\n"; + } + break; +#endif + default: + out.info.message(EPrefixInternalError, "Unknown constant", node->getLoc()); + break; + } + } +} + +void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node) +{ + OutputTreeText(infoSink, node, depth); + infoSink.debug << "Constant:\n"; + + OutputConstantUnion(infoSink, node, node->getConstArray(), depth + 1); +} + +void TOutputTraverser::visitSymbol(TIntermSymbol* node) +{ + OutputTreeText(infoSink, node, depth); + + infoSink.debug << "'" << node->getName() << "' (" << node->getCompleteString() << ")\n"; + + if (! node->getConstArray().empty()) + OutputConstantUnion(infoSink, node, node->getConstArray(), depth + 1); + else if (node->getConstSubtree()) { + incrementDepth(node); + node->getConstSubtree()->traverse(this); + decrementDepth(); + } +} + +bool TOutputTraverser::visitLoop(TVisit /* visit */, TIntermLoop* node) +{ + TInfoSink& out = infoSink; + + OutputTreeText(out, node, depth); + + out.debug << "Loop with condition "; + if (! node->testFirst()) + out.debug << "not "; + out.debug << "tested first\n"; + + ++depth; + + OutputTreeText(infoSink, node, depth); + if (node->getTest()) { + out.debug << "Loop Condition\n"; + node->getTest()->traverse(this); + } else + out.debug << "No loop condition\n"; + + OutputTreeText(infoSink, node, depth); + if (node->getBody()) { + out.debug << "Loop Body\n"; + node->getBody()->traverse(this); + } else + out.debug << "No loop body\n"; + + if (node->getTerminal()) { + OutputTreeText(infoSink, node, depth); + out.debug << "Loop Terminal Expression\n"; + node->getTerminal()->traverse(this); + } + + --depth; + + return false; +} + +bool TOutputTraverser::visitBranch(TVisit /* visit*/, TIntermBranch* node) +{ + TInfoSink& out = infoSink; + + OutputTreeText(out, node, depth); + + switch (node->getFlowOp()) { + case EOpKill: out.debug << "Branch: Kill"; break; + case EOpBreak: out.debug << "Branch: Break"; break; + case EOpContinue: out.debug << "Branch: Continue"; break; + case EOpReturn: out.debug << "Branch: Return"; break; + case EOpCase: out.debug << "case: "; break; + case EOpDefault: out.debug << "default: "; break; + default: out.debug << "Branch: Unknown Branch"; break; + } + + if (node->getExpression()) { + out.debug << " with expression\n"; + ++depth; + node->getExpression()->traverse(this); + --depth; + } else + out.debug << "\n"; + + return false; +} + +bool TOutputTraverser::visitSwitch(TVisit /* visit */, TIntermSwitch* node) +{ + TInfoSink& out = infoSink; + + OutputTreeText(out, node, depth); + out.debug << "switch\n"; + + OutputTreeText(out, node, depth); + out.debug << "condition\n"; + ++depth; + node->getCondition()->traverse(this); + + --depth; + OutputTreeText(out, node, depth); + out.debug << "body\n"; + ++depth; + node->getBody()->traverse(this); + + --depth; + + return false; +} + +// +// This function is the one to call externally to start the traversal. +// Individual functions can be initialized to 0 to skip processing of that +// type of node. It's children will still be processed. +// +void TIntermediate::output(TInfoSink& infoSink, bool tree) +{ + infoSink.debug << "Shader version: " << version << "\n"; + if (requestedExtensions.size() > 0) { + for (auto extIt = requestedExtensions.begin(); extIt != requestedExtensions.end(); ++extIt) + infoSink.debug << "Requested " << *extIt << "\n"; + } + + if (xfbMode) + infoSink.debug << "in xfb mode\n"; + + switch (language) { + case EShLangVertex: + break; + + case EShLangTessControl: + infoSink.debug << "vertices = " << vertices << "\n"; + + if (inputPrimitive != ElgNone) + infoSink.debug << "input primitive = " << TQualifier::getGeometryString(inputPrimitive) << "\n"; + if (vertexSpacing != EvsNone) + infoSink.debug << "vertex spacing = " << TQualifier::getVertexSpacingString(vertexSpacing) << "\n"; + if (vertexOrder != EvoNone) + infoSink.debug << "triangle order = " << TQualifier::getVertexOrderString(vertexOrder) << "\n"; + break; + + case EShLangTessEvaluation: + infoSink.debug << "input primitive = " << TQualifier::getGeometryString(inputPrimitive) << "\n"; + infoSink.debug << "vertex spacing = " << TQualifier::getVertexSpacingString(vertexSpacing) << "\n"; + infoSink.debug << "triangle order = " << TQualifier::getVertexOrderString(vertexOrder) << "\n"; + if (pointMode) + infoSink.debug << "using point mode\n"; + break; + + case EShLangGeometry: + infoSink.debug << "invocations = " << invocations << "\n"; + infoSink.debug << "max_vertices = " << vertices << "\n"; + infoSink.debug << "input primitive = " << TQualifier::getGeometryString(inputPrimitive) << "\n"; + infoSink.debug << "output primitive = " << TQualifier::getGeometryString(outputPrimitive) << "\n"; + break; + + case EShLangFragment: + if (pixelCenterInteger) + infoSink.debug << "gl_FragCoord pixel center is integer\n"; + if (originUpperLeft) + infoSink.debug << "gl_FragCoord origin is upper left\n"; + if (earlyFragmentTests) + infoSink.debug << "using early_fragment_tests\n"; + if (postDepthCoverage) + infoSink.debug << "using post_depth_coverage\n"; + if (depthLayout != EldNone) + infoSink.debug << "using " << TQualifier::getLayoutDepthString(depthLayout) << "\n"; + if (blendEquations != 0) { + infoSink.debug << "using"; + // blendEquations is a mask, decode it + for (TBlendEquationShift be = (TBlendEquationShift)0; be < EBlendCount; be = (TBlendEquationShift)(be + 1)) { + if (blendEquations & (1 << be)) + infoSink.debug << " " << TQualifier::getBlendEquationString(be); + } + infoSink.debug << "\n"; + } + break; + + case EShLangCompute: + infoSink.debug << "local_size = (" << localSize[0] << ", " << localSize[1] << ", " << localSize[2] << ")\n"; + { + if (localSizeSpecId[0] != TQualifier::layoutNotSet || + localSizeSpecId[1] != TQualifier::layoutNotSet || + localSizeSpecId[2] != TQualifier::layoutNotSet) { + infoSink.debug << "local_size ids = (" << + localSizeSpecId[0] << ", " << + localSizeSpecId[1] << ", " << + localSizeSpecId[2] << ")\n"; + } + } + break; + + default: + break; + } + + if (treeRoot == 0 || ! tree) + return; + + TOutputTraverser it(infoSink); + + treeRoot->traverse(&it); +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/iomapper.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/iomapper.cpp new file mode 100644 index 00000000..a7d9d91d --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/iomapper.cpp @@ -0,0 +1,778 @@ +// +// Copyright (C) 2016-2017 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#include "../Include/Common.h" +#include "../Include/InfoSink.h" +#include "iomapper.h" +#include "LiveTraverser.h" +#include "localintermediate.h" + +#include "gl_types.h" + +#include +#include + +// +// Map IO bindings. +// +// High-level algorithm for one stage: +// +// 1. Traverse all code (live+dead) to find the explicitly provided bindings. +// +// 2. Traverse (just) the live code to determine which non-provided bindings +// require auto-numbering. We do not auto-number dead ones. +// +// 3. Traverse all the code to apply the bindings: +// a. explicitly given bindings are offset according to their type +// b. implicit live bindings are auto-numbered into the holes, using +// any open binding slot. +// c. implicit dead bindings are left un-bound. +// + + +namespace glslang { + +struct TVarEntryInfo +{ + int id; + TIntermSymbol* symbol; + bool live; + int newBinding; + int newSet; + int newLocation; + int newComponent; + int newIndex; + + struct TOrderById + { + inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) + { + return l.id < r.id; + } + }; + + struct TOrderByPriority + { + // ordering: + // 1) has both binding and set + // 2) has binding but no set + // 3) has no binding but set + // 4) has no binding and no set + inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) + { + const TQualifier& lq = l.symbol->getQualifier(); + const TQualifier& rq = r.symbol->getQualifier(); + + // simple rules: + // has binding gives 2 points + // has set gives 1 point + // who has the most points is more important. + int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0); + int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0); + + if (lPoints == rPoints) + return l.id < r.id; + return lPoints > rPoints; + } + }; +}; + + + +typedef std::vector TVarLiveMap; + +class TVarGatherTraverser : public TLiveTraverser +{ +public: + TVarGatherTraverser(const TIntermediate& i, bool traverseDeadCode, TVarLiveMap& inList, TVarLiveMap& outList, TVarLiveMap& uniformList) + : TLiveTraverser(i, traverseDeadCode, true, true, false) + , inputList(inList) + , outputList(outList) + , uniformList(uniformList) + { + } + + + virtual void visitSymbol(TIntermSymbol* base) + { + TVarLiveMap* target = nullptr; + if (base->getQualifier().storage == EvqVaryingIn) + target = &inputList; + else if (base->getQualifier().storage == EvqVaryingOut) + target = &outputList; + else if (base->getQualifier().isUniformOrBuffer()) + target = &uniformList; + + if (target) { + TVarEntryInfo ent = { base->getId(), base, !traverseAll }; + TVarLiveMap::iterator at = std::lower_bound(target->begin(), target->end(), ent, TVarEntryInfo::TOrderById()); + if (at != target->end() && at->id == ent.id) + at->live = at->live || !traverseAll; // update live state + else + target->insert(at, ent); + } + } + +private: + TVarLiveMap& inputList; + TVarLiveMap& outputList; + TVarLiveMap& uniformList; +}; + +class TVarSetTraverser : public TLiveTraverser +{ +public: + TVarSetTraverser(const TIntermediate& i, const TVarLiveMap& inList, const TVarLiveMap& outList, const TVarLiveMap& uniformList) + : TLiveTraverser(i, true, true, true, false) + , inputList(inList) + , outputList(outList) + , uniformList(uniformList) + { + } + + + virtual void visitSymbol(TIntermSymbol* base) + { + const TVarLiveMap* source; + if (base->getQualifier().storage == EvqVaryingIn) + source = &inputList; + else if (base->getQualifier().storage == EvqVaryingOut) + source = &outputList; + else if (base->getQualifier().isUniformOrBuffer()) + source = &uniformList; + else + return; + + TVarEntryInfo ent = { base->getId() }; + TVarLiveMap::const_iterator at = std::lower_bound(source->begin(), source->end(), ent, TVarEntryInfo::TOrderById()); + if (at == source->end()) + return; + + if (at->id != ent.id) + return; + + if (at->newBinding != -1) + base->getWritableType().getQualifier().layoutBinding = at->newBinding; + if (at->newSet != -1) + base->getWritableType().getQualifier().layoutSet = at->newSet; + if (at->newLocation != -1) + base->getWritableType().getQualifier().layoutLocation = at->newLocation; + if (at->newComponent != -1) + base->getWritableType().getQualifier().layoutComponent = at->newComponent; + if (at->newIndex != -1) + base->getWritableType().getQualifier().layoutIndex = at->newIndex; + } + + private: + const TVarLiveMap& inputList; + const TVarLiveMap& outputList; + const TVarLiveMap& uniformList; +}; + +struct TNotifyUniformAdaptor +{ + EShLanguage stage; + TIoMapResolver& resolver; + inline TNotifyUniformAdaptor(EShLanguage s, TIoMapResolver& r) + : stage(s) + , resolver(r) + { + } + inline void operator()(TVarEntryInfo& ent) + { + resolver.notifyBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live); + } +private: + TNotifyUniformAdaptor& operator=(TNotifyUniformAdaptor&); +}; + +struct TNotifyInOutAdaptor +{ + EShLanguage stage; + TIoMapResolver& resolver; + inline TNotifyInOutAdaptor(EShLanguage s, TIoMapResolver& r) + : stage(s) + , resolver(r) + { + } + inline void operator()(TVarEntryInfo& ent) + { + resolver.notifyInOut(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live); + } +private: + TNotifyInOutAdaptor& operator=(TNotifyInOutAdaptor&); +}; + +struct TResolverUniformAdaptor +{ + TResolverUniformAdaptor(EShLanguage s, TIoMapResolver& r, TInfoSink& i, bool& e, TIntermediate& interm) + : stage(s) + , resolver(r) + , infoSink(i) + , error(e) + , intermediate(interm) + { + } + + inline void operator()(TVarEntryInfo& ent) + { + ent.newLocation = -1; + ent.newComponent = -1; + ent.newBinding = -1; + ent.newSet = -1; + ent.newIndex = -1; + const bool isValid = resolver.validateBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), + ent.live); + if (isValid) { + ent.newBinding = resolver.resolveBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), + ent.live); + ent.newSet = resolver.resolveSet(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live); + ent.newLocation = resolver.resolveUniformLocation(stage, ent.symbol->getName().c_str(), + ent.symbol->getType(), ent.live); + + if (ent.newBinding != -1) { + if (ent.newBinding >= int(TQualifier::layoutBindingEnd)) { + TString err = "mapped binding out of range: " + ent.symbol->getName(); + + infoSink.info.message(EPrefixInternalError, err.c_str()); + error = true; + } + } + if (ent.newSet != -1) { + if (ent.newSet >= int(TQualifier::layoutSetEnd)) { + TString err = "mapped set out of range: " + ent.symbol->getName(); + + infoSink.info.message(EPrefixInternalError, err.c_str()); + error = true; + } + } + } else { + TString errorMsg = "Invalid binding: " + ent.symbol->getName(); + infoSink.info.message(EPrefixInternalError, errorMsg.c_str()); + error = true; + } + } + + EShLanguage stage; + TIoMapResolver& resolver; + TInfoSink& infoSink; + bool& error; + TIntermediate& intermediate; + +private: + TResolverUniformAdaptor& operator=(TResolverUniformAdaptor&); +}; + +struct TResolverInOutAdaptor +{ + TResolverInOutAdaptor(EShLanguage s, TIoMapResolver& r, TInfoSink& i, bool& e, TIntermediate& interm) + : stage(s) + , resolver(r) + , infoSink(i) + , error(e) + , intermediate(interm) + { + } + + inline void operator()(TVarEntryInfo& ent) + { + ent.newLocation = -1; + ent.newComponent = -1; + ent.newBinding = -1; + ent.newSet = -1; + ent.newIndex = -1; + const bool isValid = resolver.validateInOut(stage, + ent.symbol->getName().c_str(), + ent.symbol->getType(), + ent.live); + if (isValid) { + ent.newLocation = resolver.resolveInOutLocation(stage, + ent.symbol->getName().c_str(), + ent.symbol->getType(), + ent.live); + ent.newComponent = resolver.resolveInOutComponent(stage, + ent.symbol->getName().c_str(), + ent.symbol->getType(), + ent.live); + ent.newIndex = resolver.resolveInOutIndex(stage, + ent.symbol->getName().c_str(), + ent.symbol->getType(), + ent.live); + } else { + TString errorMsg = "Invalid shader In/Out variable semantic: "; + errorMsg += ent.symbol->getType().getQualifier().semanticName; + infoSink.info.message(EPrefixInternalError, errorMsg.c_str()); + error = true; + } + } + + EShLanguage stage; + TIoMapResolver& resolver; + TInfoSink& infoSink; + bool& error; + TIntermediate& intermediate; + +private: + TResolverInOutAdaptor& operator=(TResolverInOutAdaptor&); +}; + +// Base class for shared TIoMapResolver services, used by several derivations. +struct TDefaultIoResolverBase : public glslang::TIoMapResolver +{ + TDefaultIoResolverBase(const TIntermediate &intermediate) : + intermediate(intermediate), + nextUniformLocation(0) + { } + + int getBaseBinding(TResourceType res, unsigned int set) const { + return selectBaseBinding(intermediate.getShiftBinding(res), + intermediate.getShiftBindingForSet(res, set)); + } + + const std::vector& getResourceSetBinding() const { return intermediate.getResourceSetBinding(); } + + bool doAutoBindingMapping() const { return intermediate.getAutoMapBindings(); } + bool doAutoLocationMapping() const { return intermediate.getAutoMapLocations(); } + + typedef std::vector TSlotSet; + typedef std::unordered_map TSlotSetMap; + TSlotSetMap slots; + + TSlotSet::iterator findSlot(int set, int slot) + { + return std::lower_bound(slots[set].begin(), slots[set].end(), slot); + } + + bool checkEmpty(int set, int slot) + { + TSlotSet::iterator at = findSlot(set, slot); + return !(at != slots[set].end() && *at == slot); + } + + int reserveSlot(int set, int slot) + { + TSlotSet::iterator at = findSlot(set, slot); + + // tolerate aliasing, by not double-recording aliases + // (policy about appropriateness of the alias is higher up) + if (at == slots[set].end() || *at != slot) + slots[set].insert(at, slot); + + return slot; + } + + int getFreeSlot(int set, int base) + { + TSlotSet::iterator at = findSlot(set, base); + if (at == slots[set].end()) + return reserveSlot(set, base); + + // look in locksteps, if they not match, then there is a free slot + for (; at != slots[set].end(); ++at, ++base) + if (*at != base) + break; + return reserveSlot(set, base); + } + + virtual bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override = 0; + + virtual int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override = 0; + + int resolveSet(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override + { + if (type.getQualifier().hasSet()) + return type.getQualifier().layoutSet; + + // If a command line or API option requested a single descriptor set, use that (if not overrided by spaceN) + if (getResourceSetBinding().size() == 1) + return atoi(getResourceSetBinding()[0].c_str()); + + return 0; + } + int resolveUniformLocation(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override + { + // kick out of not doing this + if (!doAutoLocationMapping()) + return -1; + + // no locations added if already present, a built-in variable, a block, or an opaque + if (type.getQualifier().hasLocation() || type.isBuiltIn() || + type.getBasicType() == EbtBlock || type.containsOpaque()) + return -1; + + // no locations on blocks of built-in variables + if (type.isStruct()) { + if (type.getStruct()->size() < 1) + return -1; + if ((*type.getStruct())[0].type->isBuiltIn()) + return -1; + } + + return nextUniformLocation++; + } + bool validateInOut(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override + { + return true; + } + int resolveInOutLocation(EShLanguage /*stage*/, const char* /*name*/, const TType& type, bool /*is_live*/) override + { + // kick out of not doing this + if (!doAutoLocationMapping()) + return -1; + + // no locations added if already present, or a built-in variable + if (type.getQualifier().hasLocation() || type.isBuiltIn()) + return -1; + + // no locations on blocks of built-in variables + if (type.isStruct()) { + if (type.getStruct()->size() < 1) + return -1; + if ((*type.getStruct())[0].type->isBuiltIn()) + return -1; + } + + // Placeholder. + // TODO: It would be nice to flesh this out using + // intermediate->computeTypeLocationSize(type), or functions that call it like + // intermediate->addUsedLocation() + // These in turn would want the intermediate, which is not available here, but + // is available in many places, and a lot of copying from it could be saved if + // it were just available. + return 0; + } + int resolveInOutComponent(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override + { + return -1; + } + int resolveInOutIndex(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override + { + return -1; + } + + void notifyBinding(EShLanguage, const char* /*name*/, const TType&, bool /*is_live*/) override {} + void notifyInOut(EShLanguage, const char* /*name*/, const TType&, bool /*is_live*/) override {} + void endNotifications(EShLanguage) override {} + void beginNotifications(EShLanguage) override {} + void beginResolve(EShLanguage) override {} + void endResolve(EShLanguage) override {} + +protected: + const TIntermediate &intermediate; + int nextUniformLocation; + + // Return descriptor set specific base if there is one, and the generic base otherwise. + int selectBaseBinding(int base, int descriptorSetBase) const { + return descriptorSetBase != -1 ? descriptorSetBase : base; + } + + static int getLayoutSet(const glslang::TType& type) { + if (type.getQualifier().hasSet()) + return type.getQualifier().layoutSet; + else + return 0; + } + + static bool isSamplerType(const glslang::TType& type) { + return type.getBasicType() == glslang::EbtSampler && type.getSampler().isPureSampler(); + } + + static bool isTextureType(const glslang::TType& type) { + return (type.getBasicType() == glslang::EbtSampler && + (type.getSampler().isTexture() || type.getSampler().isSubpass())); + } + + static bool isUboType(const glslang::TType& type) { + return type.getQualifier().storage == EvqUniform; + } +}; + +/* + * Basic implementation of glslang::TIoMapResolver that replaces the + * previous offset behavior. + * It does the same, uses the offsets for the corresponding uniform + * types. Also respects the EOptionAutoMapBindings flag and binds + * them if needed. + */ +/* + * Default resolver + */ +struct TDefaultIoResolver : public TDefaultIoResolverBase +{ + TDefaultIoResolver(const TIntermediate &intermediate) : TDefaultIoResolverBase(intermediate) { } + + bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& /*type*/, bool /*is_live*/) override + { + return true; + } + + int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override + { + const int set = getLayoutSet(type); + + if (type.getQualifier().hasBinding()) { + if (isImageType(type)) + return reserveSlot(set, getBaseBinding(EResImage, set) + type.getQualifier().layoutBinding); + + if (isTextureType(type)) + return reserveSlot(set, getBaseBinding(EResTexture, set) + type.getQualifier().layoutBinding); + + if (isSsboType(type)) + return reserveSlot(set, getBaseBinding(EResSsbo, set) + type.getQualifier().layoutBinding); + + if (isSamplerType(type)) + return reserveSlot(set, getBaseBinding(EResSampler, set) + type.getQualifier().layoutBinding); + + if (isUboType(type)) + return reserveSlot(set, getBaseBinding(EResUbo, set) + type.getQualifier().layoutBinding); + } else if (is_live && doAutoBindingMapping()) { + // find free slot, the caller did make sure it passes all vars with binding + // first and now all are passed that do not have a binding and needs one + + if (isImageType(type)) + return getFreeSlot(set, getBaseBinding(EResImage, set)); + + if (isTextureType(type)) + return getFreeSlot(set, getBaseBinding(EResTexture, set)); + + if (isSsboType(type)) + return getFreeSlot(set, getBaseBinding(EResSsbo, set)); + + if (isSamplerType(type)) + return getFreeSlot(set, getBaseBinding(EResSampler, set)); + + if (isUboType(type)) + return getFreeSlot(set, getBaseBinding(EResUbo, set)); + } + + return -1; + } + +protected: + static bool isImageType(const glslang::TType& type) { + return type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage(); + } + + static bool isSsboType(const glslang::TType& type) { + return type.getQualifier().storage == EvqBuffer; + } +}; + +/******************************************************************************** +The following IO resolver maps types in HLSL register space, as follows: + +t – for shader resource views (SRV) + TEXTURE1D + TEXTURE1DARRAY + TEXTURE2D + TEXTURE2DARRAY + TEXTURE3D + TEXTURECUBE + TEXTURECUBEARRAY + TEXTURE2DMS + TEXTURE2DMSARRAY + STRUCTUREDBUFFER + BYTEADDRESSBUFFER + BUFFER + TBUFFER + +s – for samplers + SAMPLER + SAMPLER1D + SAMPLER2D + SAMPLER3D + SAMPLERCUBE + SAMPLERSTATE + SAMPLERCOMPARISONSTATE + +u – for unordered access views (UAV) + RWBYTEADDRESSBUFFER + RWSTRUCTUREDBUFFER + APPENDSTRUCTUREDBUFFER + CONSUMESTRUCTUREDBUFFER + RWBUFFER + RWTEXTURE1D + RWTEXTURE1DARRAY + RWTEXTURE2D + RWTEXTURE2DARRAY + RWTEXTURE3D + +b – for constant buffer views (CBV) + CBUFFER + CONSTANTBUFFER + ********************************************************************************/ +struct TDefaultHlslIoResolver : public TDefaultIoResolverBase +{ + TDefaultHlslIoResolver(const TIntermediate &intermediate) : TDefaultIoResolverBase(intermediate) { } + + bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& /*type*/, bool /*is_live*/) override + { + return true; + } + + int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override + { + const int set = getLayoutSet(type); + + if (type.getQualifier().hasBinding()) { + if (isUavType(type)) + return reserveSlot(set, getBaseBinding(EResUav, set) + type.getQualifier().layoutBinding); + + if (isSrvType(type)) + return reserveSlot(set, getBaseBinding(EResTexture, set) + type.getQualifier().layoutBinding); + + if (isSamplerType(type)) + return reserveSlot(set, getBaseBinding(EResSampler, set) + type.getQualifier().layoutBinding); + + if (isUboType(type)) + return reserveSlot(set, getBaseBinding(EResUbo, set) + type.getQualifier().layoutBinding); + } else if (is_live && doAutoBindingMapping()) { + // find free slot, the caller did make sure it passes all vars with binding + // first and now all are passed that do not have a binding and needs one + + if (isUavType(type)) + return getFreeSlot(set, getBaseBinding(EResUav, set)); + + if (isSrvType(type)) + return getFreeSlot(set, getBaseBinding(EResTexture, set)); + + if (isSamplerType(type)) + return getFreeSlot(set, getBaseBinding(EResSampler, set)); + + if (isUboType(type)) + return getFreeSlot(set, getBaseBinding(EResUbo, set)); + } + + return -1; + } + +protected: + // Return true if this is a SRV (shader resource view) type: + static bool isSrvType(const glslang::TType& type) { + return isTextureType(type) || type.getQualifier().storage == EvqBuffer; + } + + // Return true if this is a UAV (unordered access view) type: + static bool isUavType(const glslang::TType& type) { + if (type.getQualifier().readonly) + return false; + + return (type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage()) || + (type.getQualifier().storage == EvqBuffer); + } +}; + + +// Map I/O variables to provided offsets, and make bindings for +// unbound but live variables. +// +// Returns false if the input is too malformed to do this. +bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSink &infoSink, TIoMapResolver *resolver) +{ + bool somethingToDo = !intermediate.getResourceSetBinding().empty() || + intermediate.getAutoMapBindings() || + intermediate.getAutoMapLocations(); + + for (int res = 0; res < EResCount; ++res) { + somethingToDo = somethingToDo || + (intermediate.getShiftBinding(TResourceType(res)) != 0) || + intermediate.hasShiftBindingForSet(TResourceType(res)); + } + + if (!somethingToDo && resolver == nullptr) + return true; + + if (intermediate.getNumEntryPoints() != 1 || intermediate.isRecursive()) + return false; + + TIntermNode* root = intermediate.getTreeRoot(); + if (root == nullptr) + return false; + + // if no resolver is provided, use the default resolver with the given shifts and auto map settings + TDefaultIoResolver defaultResolver(intermediate); + TDefaultHlslIoResolver defaultHlslResolver(intermediate); + + if (resolver == nullptr) { + // TODO: use a passed in IO mapper for this + if (intermediate.usingHlslIoMapping()) + resolver = &defaultHlslResolver; + else + resolver = &defaultResolver; + } + + TVarLiveMap inVarMap, outVarMap, uniformVarMap; + TVarGatherTraverser iter_binding_all(intermediate, true, inVarMap, outVarMap, uniformVarMap); + TVarGatherTraverser iter_binding_live(intermediate, false, inVarMap, outVarMap, uniformVarMap); + + root->traverse(&iter_binding_all); + iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str()); + + while (!iter_binding_live.functions.empty()) { + TIntermNode* function = iter_binding_live.functions.back(); + iter_binding_live.functions.pop_back(); + function->traverse(&iter_binding_live); + } + + // sort entries by priority. see TVarEntryInfo::TOrderByPriority for info. + std::sort(uniformVarMap.begin(), uniformVarMap.end(), TVarEntryInfo::TOrderByPriority()); + + bool hadError = false; + TNotifyInOutAdaptor inOutNotify(stage, *resolver); + TNotifyUniformAdaptor uniformNotify(stage, *resolver); + TResolverUniformAdaptor uniformResolve(stage, *resolver, infoSink, hadError, intermediate); + TResolverInOutAdaptor inOutResolve(stage, *resolver, infoSink, hadError, intermediate); + resolver->beginNotifications(stage); + std::for_each(inVarMap.begin(), inVarMap.end(), inOutNotify); + std::for_each(outVarMap.begin(), outVarMap.end(), inOutNotify); + std::for_each(uniformVarMap.begin(), uniformVarMap.end(), uniformNotify); + resolver->endNotifications(stage); + resolver->beginResolve(stage); + std::for_each(inVarMap.begin(), inVarMap.end(), inOutResolve); + std::for_each(outVarMap.begin(), outVarMap.end(), inOutResolve); + std::for_each(uniformVarMap.begin(), uniformVarMap.end(), uniformResolve); + resolver->endResolve(stage); + + if (!hadError) { + // sort by id again, so we can use lower bound to find entries + std::sort(uniformVarMap.begin(), uniformVarMap.end(), TVarEntryInfo::TOrderById()); + TVarSetTraverser iter_iomap(intermediate, inVarMap, outVarMap, uniformVarMap); + root->traverse(&iter_iomap); + } + + return !hadError; +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/iomapper.h b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/iomapper.h new file mode 100644 index 00000000..5e0d4391 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/iomapper.h @@ -0,0 +1,63 @@ +// +// Copyright (C) 2016 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef _IOMAPPER_INCLUDED +#define _IOMAPPER_INCLUDED + +#include "../Public/ShaderLang.h" + +// +// A reflection database and its interface, consistent with the OpenGL API reflection queries. +// + +class TInfoSink; + +namespace glslang { + +class TIntermediate; + +// I/O mapper +class TIoMapper { +public: + TIoMapper() {} + virtual ~TIoMapper() {} + + // grow the reflection stage by stage + bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*); +}; + +} // end namespace glslang + +#endif // _IOMAPPER_INCLUDED diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/limits.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/limits.cpp new file mode 100644 index 00000000..64d191b4 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/limits.cpp @@ -0,0 +1,198 @@ +// +// Copyright (C) 2013 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +// +// Do sub tree walks for +// 1) inductive loop bodies to see if the inductive variable is modified +// 2) array-index expressions to see if they are "constant-index-expression" +// +// These are per Appendix A of ES 2.0: +// +// "Within the body of the loop, the loop index is not statically assigned to nor is it used as the +// argument to a function out or inout parameter." +// +// "The following are constant-index-expressions: +// - Constant expressions +// - Loop indices as defined in section 4 +// - Expressions composed of both of the above" +// +// N.B.: assuming the last rule excludes function calls +// + +#include "ParseHelper.h" + +namespace glslang { + +// +// The inductive loop-body traverser. +// +// Just look at things that might modify the loop index. +// + +class TInductiveTraverser : public TIntermTraverser { +public: + TInductiveTraverser(int id, TSymbolTable& st) + : loopId(id), symbolTable(st), bad(false) { } + + virtual bool visitBinary(TVisit, TIntermBinary* node); + virtual bool visitUnary(TVisit, TIntermUnary* node); + virtual bool visitAggregate(TVisit, TIntermAggregate* node); + + int loopId; // unique ID of the symbol that's the loop inductive variable + TSymbolTable& symbolTable; + bool bad; + TSourceLoc badLoc; + +protected: + TInductiveTraverser(TInductiveTraverser&); + TInductiveTraverser& operator=(TInductiveTraverser&); +}; + +// check binary operations for those modifying the loop index +bool TInductiveTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node) +{ + if (node->modifiesState() && node->getLeft()->getAsSymbolNode() && + node->getLeft()->getAsSymbolNode()->getId() == loopId) { + bad = true; + badLoc = node->getLoc(); + } + + return true; +} + +// check unary operations for those modifying the loop index +bool TInductiveTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node) +{ + if (node->modifiesState() && node->getOperand()->getAsSymbolNode() && + node->getOperand()->getAsSymbolNode()->getId() == loopId) { + bad = true; + badLoc = node->getLoc(); + } + + return true; +} + +// check function calls for arguments modifying the loop index +bool TInductiveTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node) +{ + if (node->getOp() == EOpFunctionCall) { + // see if an out or inout argument is the loop index + const TIntermSequence& args = node->getSequence(); + for (int i = 0; i < (int)args.size(); ++i) { + if (args[i]->getAsSymbolNode() && args[i]->getAsSymbolNode()->getId() == loopId) { + TSymbol* function = symbolTable.find(node->getName()); + const TType* type = (*function->getAsFunction())[i].type; + if (type->getQualifier().storage == EvqOut || + type->getQualifier().storage == EvqInOut) { + bad = true; + badLoc = node->getLoc(); + } + } + } + } + + return true; +} + +// +// External function to call for loop check. +// +void TParseContext::inductiveLoopBodyCheck(TIntermNode* body, int loopId, TSymbolTable& symbolTable) +{ + TInductiveTraverser it(loopId, symbolTable); + + if (body == nullptr) + return; + + body->traverse(&it); + + if (it.bad) + error(it.badLoc, "inductive loop index modified", "limitations", ""); +} + +// +// The "constant-index-expression" tranverser. +// +// Just look at things that can form an index. +// + +class TIndexTraverser : public TIntermTraverser { +public: + TIndexTraverser(const TIdSetType& ids) : inductiveLoopIds(ids), bad(false) { } + virtual void visitSymbol(TIntermSymbol* symbol); + virtual bool visitAggregate(TVisit, TIntermAggregate* node); + const TIdSetType& inductiveLoopIds; + bool bad; + TSourceLoc badLoc; + +protected: + TIndexTraverser(TIndexTraverser&); + TIndexTraverser& operator=(TIndexTraverser&); +}; + +// make sure symbols are inductive-loop indexes +void TIndexTraverser::visitSymbol(TIntermSymbol* symbol) +{ + if (inductiveLoopIds.find(symbol->getId()) == inductiveLoopIds.end()) { + bad = true; + badLoc = symbol->getLoc(); + } +} + +// check for function calls, assuming they are bad; spec. doesn't really say +bool TIndexTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node) +{ + if (node->getOp() == EOpFunctionCall) { + bad = true; + badLoc = node->getLoc(); + } + + return true; +} + +// +// External function to call for loop check. +// +void TParseContext::constantIndexExpressionCheck(TIntermNode* index) +{ + TIndexTraverser it(inductiveLoopIds); + + index->traverse(&it); + + if (it.bad) + error(it.badLoc, "Non-constant-index-expression", "limitations", ""); +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/linkValidate.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/linkValidate.cpp new file mode 100644 index 00000000..9ca1557b --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/linkValidate.cpp @@ -0,0 +1,1242 @@ +// +// Copyright (C) 2013 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +// +// Do link-time merging and validation of intermediate representations. +// +// Basic model is that during compilation, each compilation unit (shader) is +// compiled into one TIntermediate instance. Then, at link time, multiple +// units for the same stage can be merged together, which can generate errors. +// Then, after all merging, a single instance of TIntermediate represents +// the whole stage. A final error check can be done on the resulting stage, +// even if no merging was done (i.e., the stage was only one compilation unit). +// + +#include "localintermediate.h" +#include "../Include/InfoSink.h" + +namespace glslang { + +// +// Link-time error emitter. +// +void TIntermediate::error(TInfoSink& infoSink, const char* message) +{ + infoSink.info.prefix(EPrefixError); + infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n"; + + ++numErrors; +} + +// Link-time warning. +void TIntermediate::warn(TInfoSink& infoSink, const char* message) +{ + infoSink.info.prefix(EPrefixWarning); + infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n"; +} + +// TODO: 4.4 offset/align: "Two blocks linked together in the same program with the same block +// name must have the exact same set of members qualified with offset and their integral-constant +// expression values must be the same, or a link-time error results." + +// +// Merge the information from 'unit' into 'this' +// +void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit) +{ + if (source == EShSourceNone) + source = unit.source; + + if (source != unit.source) + error(infoSink, "can't link compilation units from different source languages"); + + if (unit.getNumEntryPoints() > 0) { + if (getNumEntryPoints() > 0) + error(infoSink, "can't handle multiple entry points per stage"); + else { + entryPointName = unit.getEntryPointName(); + entryPointMangledName = unit.getEntryPointMangledName(); + } + } + numEntryPoints += unit.getNumEntryPoints(); + numErrors += unit.getNumErrors(); + numPushConstants += unit.numPushConstants; + callGraph.insert(callGraph.end(), unit.callGraph.begin(), unit.callGraph.end()); + + if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger) + error(infoSink, "gl_FragCoord redeclarations must match across shaders"); + + if (! earlyFragmentTests) + earlyFragmentTests = unit.earlyFragmentTests; + + if (!postDepthCoverage) + postDepthCoverage = unit.postDepthCoverage; + + if (depthLayout == EldNone) + depthLayout = unit.depthLayout; + else if (depthLayout != unit.depthLayout) + error(infoSink, "Contradictory depth layouts"); + + blendEquations |= unit.blendEquations; + + if (inputPrimitive == ElgNone) + inputPrimitive = unit.inputPrimitive; + else if (inputPrimitive != unit.inputPrimitive) + error(infoSink, "Contradictory input layout primitives"); + + if (outputPrimitive == ElgNone) + outputPrimitive = unit.outputPrimitive; + else if (outputPrimitive != unit.outputPrimitive) + error(infoSink, "Contradictory output layout primitives"); + + if (vertices == TQualifier::layoutNotSet) + vertices = unit.vertices; + else if (vertices != unit.vertices) { + if (language == EShLangGeometry) + error(infoSink, "Contradictory layout max_vertices values"); + else if (language == EShLangTessControl) + error(infoSink, "Contradictory layout vertices values"); + else + assert(0); + } + + if (vertexSpacing == EvsNone) + vertexSpacing = unit.vertexSpacing; + else if (vertexSpacing != unit.vertexSpacing) + error(infoSink, "Contradictory input vertex spacing"); + + if (vertexOrder == EvoNone) + vertexOrder = unit.vertexOrder; + else if (vertexOrder != unit.vertexOrder) + error(infoSink, "Contradictory triangle ordering"); + + if (unit.pointMode) + pointMode = true; + + for (int i = 0; i < 3; ++i) { + if (localSize[i] > 1) + localSize[i] = unit.localSize[i]; + else if (localSize[i] != unit.localSize[i]) + error(infoSink, "Contradictory local size"); + + if (localSizeSpecId[i] != TQualifier::layoutNotSet) + localSizeSpecId[i] = unit.localSizeSpecId[i]; + else if (localSizeSpecId[i] != unit.localSizeSpecId[i]) + error(infoSink, "Contradictory local size specialization ids"); + } + + if (unit.xfbMode) + xfbMode = true; + for (size_t b = 0; b < xfbBuffers.size(); ++b) { + if (xfbBuffers[b].stride == TQualifier::layoutXfbStrideEnd) + xfbBuffers[b].stride = unit.xfbBuffers[b].stride; + else if (xfbBuffers[b].stride != unit.xfbBuffers[b].stride) + error(infoSink, "Contradictory xfb_stride"); + xfbBuffers[b].implicitStride = std::max(xfbBuffers[b].implicitStride, unit.xfbBuffers[b].implicitStride); + if (unit.xfbBuffers[b].containsDouble) + xfbBuffers[b].containsDouble = true; + // TODO: 4.4 link: enhanced layouts: compare ranges + } + + if (unit.treeRoot == 0) + return; + + if (treeRoot == 0) { + treeRoot = unit.treeRoot; + version = unit.version; + requestedExtensions = unit.requestedExtensions; + return; + } + + // Getting this far means we have two existing trees to merge... + + version = std::max(version, unit.version); + requestedExtensions.insert(unit.requestedExtensions.begin(), unit.requestedExtensions.end()); + + // Get the top-level globals of each unit + TIntermSequence& globals = treeRoot->getAsAggregate()->getSequence(); + TIntermSequence& unitGlobals = unit.treeRoot->getAsAggregate()->getSequence(); + + // Get the linker-object lists + TIntermSequence& linkerObjects = findLinkerObjects(); + TIntermSequence& unitLinkerObjects = unit.findLinkerObjects(); + + mergeBodies(infoSink, globals, unitGlobals); + mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects); + + ioAccessed.insert(unit.ioAccessed.begin(), unit.ioAccessed.end()); +} + +// +// Merge the function bodies and global-level initializers from unitGlobals into globals. +// Will error check duplication of function bodies for the same signature. +// +void TIntermediate::mergeBodies(TInfoSink& infoSink, TIntermSequence& globals, const TIntermSequence& unitGlobals) +{ + // TODO: link-time performance: Processing in alphabetical order will be faster + + // Error check the global objects, not including the linker objects + for (unsigned int child = 0; child < globals.size() - 1; ++child) { + for (unsigned int unitChild = 0; unitChild < unitGlobals.size() - 1; ++unitChild) { + TIntermAggregate* body = globals[child]->getAsAggregate(); + TIntermAggregate* unitBody = unitGlobals[unitChild]->getAsAggregate(); + if (body && unitBody && body->getOp() == EOpFunction && unitBody->getOp() == EOpFunction && body->getName() == unitBody->getName()) { + error(infoSink, "Multiple function bodies in multiple compilation units for the same signature in the same stage:"); + infoSink.info << " " << globals[child]->getAsAggregate()->getName() << "\n"; + } + } + } + + // Merge the global objects, just in front of the linker objects + globals.insert(globals.end() - 1, unitGlobals.begin(), unitGlobals.end() - 1); +} + +// +// Merge the linker objects from unitLinkerObjects into linkerObjects. +// Duplication is expected and filtered out, but contradictions are an error. +// +void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects) +{ + // Error check and merge the linker objects (duplicates should not be created) + std::size_t initialNumLinkerObjects = linkerObjects.size(); + for (unsigned int unitLinkObj = 0; unitLinkObj < unitLinkerObjects.size(); ++unitLinkObj) { + bool merge = true; + for (std::size_t linkObj = 0; linkObj < initialNumLinkerObjects; ++linkObj) { + TIntermSymbol* symbol = linkerObjects[linkObj]->getAsSymbolNode(); + TIntermSymbol* unitSymbol = unitLinkerObjects[unitLinkObj]->getAsSymbolNode(); + assert(symbol && unitSymbol); + if (symbol->getName() == unitSymbol->getName()) { + // filter out copy + merge = false; + + // but if one has an initializer and the other does not, update + // the initializer + if (symbol->getConstArray().empty() && ! unitSymbol->getConstArray().empty()) + symbol->setConstArray(unitSymbol->getConstArray()); + + // Similarly for binding + if (! symbol->getQualifier().hasBinding() && unitSymbol->getQualifier().hasBinding()) + symbol->getQualifier().layoutBinding = unitSymbol->getQualifier().layoutBinding; + + // Update implicit array sizes + mergeImplicitArraySizes(symbol->getWritableType(), unitSymbol->getType()); + + // Check for consistent types/qualification/initializers etc. + mergeErrorCheck(infoSink, *symbol, *unitSymbol, false); + } + } + if (merge) + linkerObjects.push_back(unitLinkerObjects[unitLinkObj]); + } +} + +// TODO 4.5 link functionality: cull distance array size checking + +// Recursively merge the implicit array sizes through the objects' respective type trees. +void TIntermediate::mergeImplicitArraySizes(TType& type, const TType& unitType) +{ + if (type.isImplicitlySizedArray() && unitType.isArray()) { + int newImplicitArraySize = unitType.isImplicitlySizedArray() ? unitType.getImplicitArraySize() : unitType.getOuterArraySize(); + if (newImplicitArraySize > type.getImplicitArraySize ()) + type.setImplicitArraySize(newImplicitArraySize); + } + + // Type mismatches are caught and reported after this, just be careful for now. + if (! type.isStruct() || ! unitType.isStruct() || type.getStruct()->size() != unitType.getStruct()->size()) + return; + + for (int i = 0; i < (int)type.getStruct()->size(); ++i) + mergeImplicitArraySizes(*(*type.getStruct())[i].type, *(*unitType.getStruct())[i].type); +} + +// +// Compare two global objects from two compilation units and see if they match +// well enough. Rules can be different for intra- vs. cross-stage matching. +// +// This function only does one of intra- or cross-stage matching per call. +// +void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol, bool crossStage) +{ + bool writeTypeComparison = false; + + // Types have to match + if (symbol.getType() != unitSymbol.getType()) { + error(infoSink, "Types must match:"); + writeTypeComparison = true; + } + + // Qualifiers have to (almost) match + + // Storage... + if (symbol.getQualifier().storage != unitSymbol.getQualifier().storage) { + error(infoSink, "Storage qualifiers must match:"); + writeTypeComparison = true; + } + + // Precision... + if (symbol.getQualifier().precision != unitSymbol.getQualifier().precision) { + error(infoSink, "Precision qualifiers must match:"); + writeTypeComparison = true; + } + + // Invariance... + if (! crossStage && symbol.getQualifier().invariant != unitSymbol.getQualifier().invariant) { + error(infoSink, "Presence of invariant qualifier must match:"); + writeTypeComparison = true; + } + + // Precise... + if (! crossStage && symbol.getQualifier().noContraction != unitSymbol.getQualifier().noContraction) { + error(infoSink, "Presence of precise qualifier must match:"); + writeTypeComparison = true; + } + + // Auxiliary and interpolation... + if (symbol.getQualifier().centroid != unitSymbol.getQualifier().centroid || + symbol.getQualifier().smooth != unitSymbol.getQualifier().smooth || + symbol.getQualifier().flat != unitSymbol.getQualifier().flat || + symbol.getQualifier().sample != unitSymbol.getQualifier().sample || + symbol.getQualifier().patch != unitSymbol.getQualifier().patch || + symbol.getQualifier().nopersp != unitSymbol.getQualifier().nopersp) { + error(infoSink, "Interpolation and auxiliary storage qualifiers must match:"); + writeTypeComparison = true; + } + + // Memory... + if (symbol.getQualifier().coherent != unitSymbol.getQualifier().coherent || + symbol.getQualifier().volatil != unitSymbol.getQualifier().volatil || + symbol.getQualifier().restrict != unitSymbol.getQualifier().restrict || + symbol.getQualifier().readonly != unitSymbol.getQualifier().readonly || + symbol.getQualifier().writeonly != unitSymbol.getQualifier().writeonly) { + error(infoSink, "Memory qualifiers must match:"); + writeTypeComparison = true; + } + + // Layouts... + // TODO: 4.4 enhanced layouts: Generalize to include offset/align: current spec + // requires separate user-supplied offset from actual computed offset, but + // current implementation only has one offset. + if (symbol.getQualifier().layoutMatrix != unitSymbol.getQualifier().layoutMatrix || + symbol.getQualifier().layoutPacking != unitSymbol.getQualifier().layoutPacking || + symbol.getQualifier().layoutLocation != unitSymbol.getQualifier().layoutLocation || + symbol.getQualifier().layoutComponent != unitSymbol.getQualifier().layoutComponent || + symbol.getQualifier().layoutIndex != unitSymbol.getQualifier().layoutIndex || + symbol.getQualifier().layoutBinding != unitSymbol.getQualifier().layoutBinding || + (symbol.getQualifier().hasBinding() && (symbol.getQualifier().layoutOffset != unitSymbol.getQualifier().layoutOffset))) { + error(infoSink, "Layout qualification must match:"); + writeTypeComparison = true; + } + + // Initializers have to match, if both are present, and if we don't already know the types don't match + if (! writeTypeComparison) { + if (! symbol.getConstArray().empty() && ! unitSymbol.getConstArray().empty()) { + if (symbol.getConstArray() != unitSymbol.getConstArray()) { + error(infoSink, "Initializers must match:"); + infoSink.info << " " << symbol.getName() << "\n"; + } + } + } + + if (writeTypeComparison) + infoSink.info << " " << symbol.getName() << ": \"" << symbol.getType().getCompleteString() << "\" versus \"" << + unitSymbol.getType().getCompleteString() << "\"\n"; +} + +// +// Do final link-time error checking of a complete (merged) intermediate representation. +// (Much error checking was done during merging). +// +// Also, lock in defaults of things not set, including array sizes. +// +void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) +{ + if (getTreeRoot() == nullptr) + return; + + if (numEntryPoints < 1) { + if (source == EShSourceGlsl) + error(infoSink, "Missing entry point: Each stage requires one entry point"); + else + warn(infoSink, "Entry point not found"); + } + + if (numPushConstants > 1) + error(infoSink, "Only one push_constant block is allowed per stage"); + + // recursion and missing body checking + checkCallGraphCycles(infoSink); + checkCallGraphBodies(infoSink, keepUncalled); + + // overlap/alias/missing I/O, etc. + inOutLocationCheck(infoSink); + + // invocations + if (invocations == TQualifier::layoutNotSet) + invocations = 1; + + if (inIoAccessed("gl_ClipDistance") && inIoAccessed("gl_ClipVertex")) + error(infoSink, "Can only use one of gl_ClipDistance or gl_ClipVertex (gl_ClipDistance is preferred)"); + if (inIoAccessed("gl_CullDistance") && inIoAccessed("gl_ClipVertex")) + error(infoSink, "Can only use one of gl_CullDistance or gl_ClipVertex (gl_ClipDistance is preferred)"); + + if (userOutputUsed() && (inIoAccessed("gl_FragColor") || inIoAccessed("gl_FragData"))) + error(infoSink, "Cannot use gl_FragColor or gl_FragData when using user-defined outputs"); + if (inIoAccessed("gl_FragColor") && inIoAccessed("gl_FragData")) + error(infoSink, "Cannot use both gl_FragColor and gl_FragData"); + + for (size_t b = 0; b < xfbBuffers.size(); ++b) { + if (xfbBuffers[b].containsDouble) + RoundToPow2(xfbBuffers[b].implicitStride, 8); + + // "It is a compile-time or link-time error to have + // any xfb_offset that overflows xfb_stride, whether stated on declarations before or after the xfb_stride, or + // in different compilation units. While xfb_stride can be declared multiple times for the same buffer, it is a + // compile-time or link-time error to have different values specified for the stride for the same buffer." + if (xfbBuffers[b].stride != TQualifier::layoutXfbStrideEnd && xfbBuffers[b].implicitStride > xfbBuffers[b].stride) { + error(infoSink, "xfb_stride is too small to hold all buffer entries:"); + infoSink.info.prefix(EPrefixError); + infoSink.info << " xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << ", minimum stride needed: " << xfbBuffers[b].implicitStride << "\n"; + } + if (xfbBuffers[b].stride == TQualifier::layoutXfbStrideEnd) + xfbBuffers[b].stride = xfbBuffers[b].implicitStride; + + // "If the buffer is capturing any + // outputs with double-precision components, the stride must be a multiple of 8, otherwise it must be a + // multiple of 4, or a compile-time or link-time error results." + if (xfbBuffers[b].containsDouble && ! IsMultipleOfPow2(xfbBuffers[b].stride, 8)) { + error(infoSink, "xfb_stride must be multiple of 8 for buffer holding a double:"); + infoSink.info.prefix(EPrefixError); + infoSink.info << " xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n"; + } else if (! IsMultipleOfPow2(xfbBuffers[b].stride, 4)) { + error(infoSink, "xfb_stride must be multiple of 4:"); + infoSink.info.prefix(EPrefixError); + infoSink.info << " xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n"; + } + + // "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the + // implementation-dependent constant gl_MaxTransformFeedbackInterleavedComponents." + if (xfbBuffers[b].stride > (unsigned int)(4 * resources.maxTransformFeedbackInterleavedComponents)) { + error(infoSink, "xfb_stride is too large:"); + infoSink.info.prefix(EPrefixError); + infoSink.info << " xfb_buffer " << (unsigned int)b << ", components (1/4 stride) needed are " << xfbBuffers[b].stride/4 << ", gl_MaxTransformFeedbackInterleavedComponents is " << resources.maxTransformFeedbackInterleavedComponents << "\n"; + } + } + + switch (language) { + case EShLangVertex: + break; + case EShLangTessControl: + if (vertices == TQualifier::layoutNotSet) + error(infoSink, "At least one shader must specify an output layout(vertices=...)"); + break; + case EShLangTessEvaluation: + if (source == EShSourceGlsl) { + if (inputPrimitive == ElgNone) + error(infoSink, "At least one shader must specify an input layout primitive"); + if (vertexSpacing == EvsNone) + vertexSpacing = EvsEqual; + if (vertexOrder == EvoNone) + vertexOrder = EvoCcw; + } + break; + case EShLangGeometry: + if (inputPrimitive == ElgNone) + error(infoSink, "At least one shader must specify an input layout primitive"); + if (outputPrimitive == ElgNone +#ifdef NV_EXTENSIONS + && !getGeoPassthroughEXT() +#endif + ) + error(infoSink, "At least one shader must specify an output layout primitive"); + if (vertices == TQualifier::layoutNotSet +#ifdef NV_EXTENSIONS + && !getGeoPassthroughEXT() +#endif + ) + error(infoSink, "At least one shader must specify a layout(max_vertices = value)"); + break; + case EShLangFragment: + // for GL_ARB_post_depth_coverage, EarlyFragmentTest is set automatically in + // ParseHelper.cpp. So if we reach here, this must be GL_EXT_post_depth_coverage + // requiring explicit early_fragment_tests + if (getPostDepthCoverage() && !getEarlyFragmentTests()) + error(infoSink, "post_depth_coverage requires early_fragment_tests"); + break; + case EShLangCompute: + break; + default: + error(infoSink, "Unknown Stage."); + break; + } + + // Process the tree for any node-specific work. + class TFinalLinkTraverser : public TIntermTraverser { + public: + TFinalLinkTraverser() { } + virtual ~TFinalLinkTraverser() { } + + virtual void visitSymbol(TIntermSymbol* symbol) + { + // Implicitly size arrays. + symbol->getWritableType().adoptImplicitArraySizes(); + } + } finalLinkTraverser; + + treeRoot->traverse(&finalLinkTraverser); +} + +// +// See if the call graph contains any static recursion, which is disallowed +// by the specification. +// +void TIntermediate::checkCallGraphCycles(TInfoSink& infoSink) +{ + // Clear fields we'll use for this. + for (TGraph::iterator call = callGraph.begin(); call != callGraph.end(); ++call) { + call->visited = false; + call->currentPath = false; + call->errorGiven = false; + } + + // + // Loop, looking for a new connected subgraph. One subgraph is handled per loop iteration. + // + + TCall* newRoot; + do { + // See if we have unvisited parts of the graph. + newRoot = 0; + for (TGraph::iterator call = callGraph.begin(); call != callGraph.end(); ++call) { + if (! call->visited) { + newRoot = &(*call); + break; + } + } + + // If not, we are done. + if (! newRoot) + break; + + // Otherwise, we found a new subgraph, process it: + // See what all can be reached by this new root, and if any of + // that is recursive. This is done by depth-first traversals, seeing + // if a new call is found that was already in the currentPath (a back edge), + // thereby detecting recursion. + std::list stack; + newRoot->currentPath = true; // currentPath will be true iff it is on the stack + stack.push_back(newRoot); + while (! stack.empty()) { + // get a caller + TCall* call = stack.back(); + + // Add to the stack just one callee. + // This algorithm always terminates, because only !visited and !currentPath causes a push + // and all pushes change currentPath to true, and all pops change visited to true. + TGraph::iterator child = callGraph.begin(); + for (; child != callGraph.end(); ++child) { + + // If we already visited this node, its whole subgraph has already been processed, so skip it. + if (child->visited) + continue; + + if (call->callee == child->caller) { + if (child->currentPath) { + // Then, we found a back edge + if (! child->errorGiven) { + error(infoSink, "Recursion detected:"); + infoSink.info << " " << call->callee << " calling " << child->callee << "\n"; + child->errorGiven = true; + recursive = true; + } + } else { + child->currentPath = true; + stack.push_back(&(*child)); + break; + } + } + } + if (child == callGraph.end()) { + // no more callees, we bottomed out, never look at this node again + stack.back()->currentPath = false; + stack.back()->visited = true; + stack.pop_back(); + } + } // end while, meaning nothing left to process in this subtree + + } while (newRoot); // redundant loop check; should always exit via the 'break' above +} + +// +// See which functions are reachable from the entry point and which have bodies. +// Reachable ones with missing bodies are errors. +// Unreachable bodies are dead code. +// +void TIntermediate::checkCallGraphBodies(TInfoSink& infoSink, bool keepUncalled) +{ + // Clear fields we'll use for this. + for (TGraph::iterator call = callGraph.begin(); call != callGraph.end(); ++call) { + call->visited = false; + call->calleeBodyPosition = -1; + } + + // The top level of the AST includes function definitions (bodies). + // Compare these to function calls in the call graph. + // We'll end up knowing which have bodies, and if so, + // how to map the call-graph node to the location in the AST. + TIntermSequence &functionSequence = getTreeRoot()->getAsAggregate()->getSequence(); + std::vector reachable(functionSequence.size(), true); // so that non-functions are reachable + for (int f = 0; f < (int)functionSequence.size(); ++f) { + glslang::TIntermAggregate* node = functionSequence[f]->getAsAggregate(); + if (node && (node->getOp() == glslang::EOpFunction)) { + if (node->getName().compare(getEntryPointMangledName().c_str()) != 0) + reachable[f] = false; // so that function bodies are unreachable, until proven otherwise + for (TGraph::iterator call = callGraph.begin(); call != callGraph.end(); ++call) { + if (call->callee == node->getName()) + call->calleeBodyPosition = f; + } + } + } + + // Start call-graph traversal by visiting the entry point nodes. + for (TGraph::iterator call = callGraph.begin(); call != callGraph.end(); ++call) { + if (call->caller.compare(getEntryPointMangledName().c_str()) == 0) + call->visited = true; + } + + // Propagate 'visited' through the call-graph to every part of the graph it + // can reach (seeded with the entry-point setting above). + bool changed; + do { + changed = false; + for (auto call1 = callGraph.begin(); call1 != callGraph.end(); ++call1) { + if (call1->visited) { + for (TGraph::iterator call2 = callGraph.begin(); call2 != callGraph.end(); ++call2) { + if (! call2->visited) { + if (call1->callee == call2->caller) { + changed = true; + call2->visited = true; + } + } + } + } + } + } while (changed); + + // Any call-graph node set to visited but without a callee body is an error. + for (TGraph::iterator call = callGraph.begin(); call != callGraph.end(); ++call) { + if (call->visited) { + if (call->calleeBodyPosition == -1) { + error(infoSink, "No function definition (body) found: "); + infoSink.info << " " << call->callee << "\n"; + } else + reachable[call->calleeBodyPosition] = true; + } + } + + // Bodies in the AST not reached by the call graph are dead; + // clear them out, since they can't be reached and also can't + // be translated further due to possibility of being ill defined. + if (! keepUncalled) { + for (int f = 0; f < (int)functionSequence.size(); ++f) { + if (! reachable[f]) + functionSequence[f] = nullptr; + } + functionSequence.erase(std::remove(functionSequence.begin(), functionSequence.end(), nullptr), functionSequence.end()); + } +} + +// +// Satisfy rules for location qualifiers on inputs and outputs +// +void TIntermediate::inOutLocationCheck(TInfoSink& infoSink) +{ + // ES 3.0 requires all outputs to have location qualifiers if there is more than one output + bool fragOutWithNoLocation = false; + int numFragOut = 0; + + // TODO: linker functionality: location collision checking + + TIntermSequence& linkObjects = findLinkerObjects(); + for (size_t i = 0; i < linkObjects.size(); ++i) { + const TType& type = linkObjects[i]->getAsTyped()->getType(); + const TQualifier& qualifier = type.getQualifier(); + if (language == EShLangFragment) { + if (qualifier.storage == EvqVaryingOut && qualifier.builtIn == EbvNone) { + ++numFragOut; + if (!qualifier.hasAnyLocation()) + fragOutWithNoLocation = true; + } + } + } + + if (profile == EEsProfile) { + if (numFragOut > 1 && fragOutWithNoLocation) + error(infoSink, "when more than one fragment shader output, all must have location qualifiers"); + } +} + +TIntermSequence& TIntermediate::findLinkerObjects() const +{ + // Get the top-level globals + TIntermSequence& globals = treeRoot->getAsAggregate()->getSequence(); + + // Get the last member of the sequences, expected to be the linker-object lists + assert(globals.back()->getAsAggregate()->getOp() == EOpLinkerObjects); + + return globals.back()->getAsAggregate()->getSequence(); +} + +// See if a variable was both a user-declared output and used. +// Note: the spec discusses writing to one, but this looks at read or write, which +// is more useful, and perhaps the spec should be changed to reflect that. +bool TIntermediate::userOutputUsed() const +{ + const TIntermSequence& linkerObjects = findLinkerObjects(); + + bool found = false; + for (size_t i = 0; i < linkerObjects.size(); ++i) { + const TIntermSymbol& symbolNode = *linkerObjects[i]->getAsSymbolNode(); + if (symbolNode.getQualifier().storage == EvqVaryingOut && + symbolNode.getName().compare(0, 3, "gl_") != 0 && + inIoAccessed(symbolNode.getName())) { + found = true; + break; + } + } + + return found; +} + +// Accumulate locations used for inputs, outputs, and uniforms, and check for collisions +// as the accumulation is done. +// +// Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value. +// +// typeCollision is set to true if there is no direct collision, but the types in the same location +// are different. +// +int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& type, bool& typeCollision) +{ + typeCollision = false; + + int set; + if (qualifier.isPipeInput()) + set = 0; + else if (qualifier.isPipeOutput()) + set = 1; + else if (qualifier.storage == EvqUniform) + set = 2; + else if (qualifier.storage == EvqBuffer) + set = 3; + else + return -1; + + int size; + if (qualifier.isUniformOrBuffer()) { + if (type.isExplicitlySizedArray()) + size = type.getCumulativeArraySize(); + else + size = 1; + } else { + // Strip off the outer array dimension for those having an extra one. + if (type.isArray() && qualifier.isArrayedIo(language)) { + TType elementType(type, 0); + size = computeTypeLocationSize(elementType); + } else + size = computeTypeLocationSize(type); + } + + // Locations, and components within locations. + // + // Almost always, dealing with components means a single location is involved. + // The exception is a dvec3. From the spec: + // + // "A dvec3 will consume all four components of the first location and components 0 and 1 of + // the second location. This leaves components 2 and 3 available for other component-qualified + // declarations." + // + // That means, without ever mentioning a component, a component range + // for a different location gets specified, if it's not a vertex shader input. (!) + // (A vertex shader input will show using only one location, even for a dvec3/4.) + // + // So, for the case of dvec3, we need two independent ioRanges. + + int collision = -1; // no collision + if (size == 2 && type.getBasicType() == EbtDouble && type.getVectorSize() == 3 && + (qualifier.isPipeInput() || qualifier.isPipeOutput())) { + // Dealing with dvec3 in/out split across two locations. + // Need two io-ranges. + // The case where the dvec3 doesn't start at component 0 was previously caught as overflow. + + // First range: + TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation); + TRange componentRange(0, 3); + TIoRange range(locationRange, componentRange, type.getBasicType(), 0); + + // check for collisions + collision = checkLocationRange(set, range, type, typeCollision); + if (collision < 0) { + usedIo[set].push_back(range); + + // Second range: + TRange locationRange2(qualifier.layoutLocation + 1, qualifier.layoutLocation + 1); + TRange componentRange2(0, 1); + TIoRange range2(locationRange2, componentRange2, type.getBasicType(), 0); + + // check for collisions + collision = checkLocationRange(set, range2, type, typeCollision); + if (collision < 0) + usedIo[set].push_back(range2); + } + } else { + // Not a dvec3 in/out split across two locations, generic path. + // Need a single IO-range block. + + TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation + size - 1); + TRange componentRange(0, 3); + if (qualifier.hasComponent() || type.getVectorSize() > 0) { + int consumedComponents = type.getVectorSize() * (type.getBasicType() == EbtDouble ? 2 : 1); + if (qualifier.hasComponent()) + componentRange.start = qualifier.layoutComponent; + componentRange.last = componentRange.start + consumedComponents - 1; + } + + // combine location and component ranges + TIoRange range(locationRange, componentRange, type.getBasicType(), qualifier.hasIndex() ? qualifier.layoutIndex : 0); + + // check for collisions, except for vertex inputs on desktop + if (! (profile != EEsProfile && language == EShLangVertex && qualifier.isPipeInput())) + collision = checkLocationRange(set, range, type, typeCollision); + + if (collision < 0) + usedIo[set].push_back(range); + } + + return collision; +} + +// Compare a new (the passed in) 'range' against the existing set, and see +// if there are any collisions. +// +// Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value. +// +int TIntermediate::checkLocationRange(int set, const TIoRange& range, const TType& type, bool& typeCollision) +{ + for (size_t r = 0; r < usedIo[set].size(); ++r) { + if (range.overlap(usedIo[set][r])) { + // there is a collision; pick one + return std::max(range.location.start, usedIo[set][r].location.start); + } else if (range.location.overlap(usedIo[set][r].location) && type.getBasicType() != usedIo[set][r].basicType) { + // aliased-type mismatch + typeCollision = true; + return std::max(range.location.start, usedIo[set][r].location.start); + } + } + + return -1; // no collision +} + +// Accumulate bindings and offsets, and check for collisions +// as the accumulation is done. +// +// Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value. +// +int TIntermediate::addUsedOffsets(int binding, int offset, int numOffsets) +{ + TRange bindingRange(binding, binding); + TRange offsetRange(offset, offset + numOffsets - 1); + TOffsetRange range(bindingRange, offsetRange); + + // check for collisions, except for vertex inputs on desktop + for (size_t r = 0; r < usedAtomics.size(); ++r) { + if (range.overlap(usedAtomics[r])) { + // there is a collision; pick one + return std::max(offset, usedAtomics[r].offset.start); + } + } + + usedAtomics.push_back(range); + + return -1; // no collision +} + +// Accumulate used constant_id values. +// +// Return false is one was already used. +bool TIntermediate::addUsedConstantId(int id) +{ + if (usedConstantId.find(id) != usedConstantId.end()) + return false; + + usedConstantId.insert(id); + + return true; +} + +// Recursively figure out how many locations are used up by an input or output type. +// Return the size of type, as measured by "locations". +int TIntermediate::computeTypeLocationSize(const TType& type) const +{ + // "If the declared input is an array of size n and each element takes m locations, it will be assigned m * n + // consecutive locations..." + if (type.isArray()) { + // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness + TType elementType(type, 0); + if (type.isImplicitlySizedArray()) { + // TODO: are there valid cases of having an implicitly-sized array with a location? If so, running this code too early. + return computeTypeLocationSize(elementType); + } else + return type.getOuterArraySize() * computeTypeLocationSize(elementType); + } + + // "The locations consumed by block and structure members are determined by applying the rules above + // recursively..." + if (type.isStruct()) { + int size = 0; + for (int member = 0; member < (int)type.getStruct()->size(); ++member) { + TType memberType(type, member); + size += computeTypeLocationSize(memberType); + } + return size; + } + + // ES: "If a shader input is any scalar or vector type, it will consume a single location." + + // Desktop: "If a vertex shader input is any scalar or vector type, it will consume a single location. If a non-vertex + // shader input is a scalar or vector type other than dvec3 or dvec4, it will consume a single location, while + // types dvec3 or dvec4 will consume two consecutive locations. Inputs of type double and dvec2 will + // consume only a single location, in all stages." + if (type.isScalar()) + return 1; + if (type.isVector()) { + if (language == EShLangVertex && type.getQualifier().isPipeInput()) + return 1; + if (type.getBasicType() == EbtDouble && type.getVectorSize() > 2) + return 2; + else + return 1; + } + + // "If the declared input is an n x m single- or double-precision matrix, ... + // The number of locations assigned for each matrix will be the same as + // for an n-element array of m-component vectors..." + if (type.isMatrix()) { + TType columnType(type, 0); + return type.getMatrixCols() * computeTypeLocationSize(columnType); + } + + assert(0); + return 1; +} + +// Accumulate xfb buffer ranges and check for collisions as the accumulation is done. +// +// Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value. +// +int TIntermediate::addXfbBufferOffset(const TType& type) +{ + const TQualifier& qualifier = type.getQualifier(); + + assert(qualifier.hasXfbOffset() && qualifier.hasXfbBuffer()); + TXfbBuffer& buffer = xfbBuffers[qualifier.layoutXfbBuffer]; + + // compute the range + unsigned int size = computeTypeXfbSize(type, buffer.containsDouble); + buffer.implicitStride = std::max(buffer.implicitStride, qualifier.layoutXfbOffset + size); + TRange range(qualifier.layoutXfbOffset, qualifier.layoutXfbOffset + size - 1); + + // check for collisions + for (size_t r = 0; r < buffer.ranges.size(); ++r) { + if (range.overlap(buffer.ranges[r])) { + // there is a collision; pick an example to return + return std::max(range.start, buffer.ranges[r].start); + } + } + + buffer.ranges.push_back(range); + + return -1; // no collision +} + +// Recursively figure out how many bytes of xfb buffer are used by the given type. +// Return the size of type, in bytes. +// Sets containsDouble to true if the type contains a double. +// N.B. Caller must set containsDouble to false before calling. +unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& containsDouble) const +{ + // "...if applied to an aggregate containing a double, the offset must also be a multiple of 8, + // and the space taken in the buffer will be a multiple of 8. + // ...within the qualified entity, subsequent components are each + // assigned, in order, to the next available offset aligned to a multiple of + // that component's size. Aggregate types are flattened down to the component + // level to get this sequence of components." + + if (type.isArray()) { + // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness + assert(type.isExplicitlySizedArray()); + TType elementType(type, 0); + return type.getOuterArraySize() * computeTypeXfbSize(elementType, containsDouble); + } + + if (type.isStruct()) { + unsigned int size = 0; + bool structContainsDouble = false; + for (int member = 0; member < (int)type.getStruct()->size(); ++member) { + TType memberType(type, member); + // "... if applied to + // an aggregate containing a double, the offset must also be a multiple of 8, + // and the space taken in the buffer will be a multiple of 8." + bool memberContainsDouble = false; + int memberSize = computeTypeXfbSize(memberType, memberContainsDouble); + if (memberContainsDouble) { + structContainsDouble = true; + RoundToPow2(size, 8); + } + size += memberSize; + } + + if (structContainsDouble) { + containsDouble = true; + RoundToPow2(size, 8); + } + return size; + } + + int numComponents; + if (type.isScalar()) + numComponents = 1; + else if (type.isVector()) + numComponents = type.getVectorSize(); + else if (type.isMatrix()) + numComponents = type.getMatrixCols() * type.getMatrixRows(); + else { + assert(0); + numComponents = 1; + } + + if (type.getBasicType() == EbtDouble) { + containsDouble = true; + return 8 * numComponents; + } else + return 4 * numComponents; +} + +const int baseAlignmentVec4Std140 = 16; + +// Return the size and alignment of a component of the given type. +// The size is returned in the 'size' parameter +// Return value is the alignment.. +int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size) +{ + switch (type.getBasicType()) { + case EbtInt64: + case EbtUint64: + case EbtDouble: size = 8; return 8; +#ifdef AMD_EXTENSIONS + case EbtInt16: + case EbtUint16: + case EbtFloat16: size = 2; return 2; +#endif + default: size = 4; return 4; + } +} + +// Implement base-alignment and size rules from section 7.6.2.2 Standard Uniform Block Layout +// Operates recursively. +// +// If std140 is true, it does the rounding up to vec4 size required by std140, +// otherwise it does not, yielding std430 rules. +// +// The size is returned in the 'size' parameter +// +// The stride is only non-0 for arrays or matrices, and is the stride of the +// top-level object nested within the type. E.g., for an array of matrices, +// it is the distances needed between matrices, despite the rules saying the +// stride comes from the flattening down to vectors. +// +// Return value is the alignment of the type. +int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, bool std140, bool rowMajor) +{ + int alignment; + + // When using the std140 storage layout, structures will be laid out in buffer + // storage with its members stored in monotonically increasing order based on their + // location in the declaration. A structure and each structure member have a base + // offset and a base alignment, from which an aligned offset is computed by rounding + // the base offset up to a multiple of the base alignment. The base offset of the first + // member of a structure is taken from the aligned offset of the structure itself. The + // base offset of all other structure members is derived by taking the offset of the + // last basic machine unit consumed by the previous member and adding one. Each + // structure member is stored in memory at its aligned offset. The members of a top- + // level uniform block are laid out in buffer storage by treating the uniform block as + // a structure with a base offset of zero. + // + // 1. If the member is a scalar consuming N basic machine units, the base alignment is N. + // + // 2. If the member is a two- or four-component vector with components consuming N basic + // machine units, the base alignment is 2N or 4N, respectively. + // + // 3. If the member is a three-component vector with components consuming N + // basic machine units, the base alignment is 4N. + // + // 4. If the member is an array of scalars or vectors, the base alignment and array + // stride are set to match the base alignment of a single array element, according + // to rules (1), (2), and (3), and rounded up to the base alignment of a vec4. The + // array may have padding at the end; the base offset of the member following + // the array is rounded up to the next multiple of the base alignment. + // + // 5. If the member is a column-major matrix with C columns and R rows, the + // matrix is stored identically to an array of C column vectors with R + // components each, according to rule (4). + // + // 6. If the member is an array of S column-major matrices with C columns and + // R rows, the matrix is stored identically to a row of S X C column vectors + // with R components each, according to rule (4). + // + // 7. If the member is a row-major matrix with C columns and R rows, the matrix + // is stored identically to an array of R row vectors with C components each, + // according to rule (4). + // + // 8. If the member is an array of S row-major matrices with C columns and R + // rows, the matrix is stored identically to a row of S X R row vectors with C + // components each, according to rule (4). + // + // 9. If the member is a structure, the base alignment of the structure is N , where + // N is the largest base alignment value of any of its members, and rounded + // up to the base alignment of a vec4. The individual members of this substructure + // are then assigned offsets by applying this set of rules recursively, + // where the base offset of the first member of the sub-structure is equal to the + // aligned offset of the structure. The structure may have padding at the end; + // the base offset of the member following the sub-structure is rounded up to + // the next multiple of the base alignment of the structure. + // + // 10. If the member is an array of S structures, the S elements of the array are laid + // out in order, according to rule (9). + // + // Assuming, for rule 10: The stride is the same as the size of an element. + + stride = 0; + int dummyStride; + + // rules 4, 6, 8, and 10 + if (type.isArray()) { + // TODO: perf: this might be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness + TType derefType(type, 0); + alignment = getBaseAlignment(derefType, size, dummyStride, std140, rowMajor); + if (std140) + alignment = std::max(baseAlignmentVec4Std140, alignment); + RoundToPow2(size, alignment); + stride = size; // uses full matrix size for stride of an array of matrices (not quite what rule 6/8, but what's expected) + // uses the assumption for rule 10 in the comment above + size = stride * type.getOuterArraySize(); + return alignment; + } + + // rule 9 + if (type.getBasicType() == EbtStruct) { + const TTypeList& memberList = *type.getStruct(); + + size = 0; + int maxAlignment = std140 ? baseAlignmentVec4Std140 : 0; + for (size_t m = 0; m < memberList.size(); ++m) { + int memberSize; + // modify just the children's view of matrix layout, if there is one for this member + TLayoutMatrix subMatrixLayout = memberList[m].type->getQualifier().layoutMatrix; + int memberAlignment = getBaseAlignment(*memberList[m].type, memberSize, dummyStride, std140, + (subMatrixLayout != ElmNone) ? (subMatrixLayout == ElmRowMajor) : rowMajor); + maxAlignment = std::max(maxAlignment, memberAlignment); + RoundToPow2(size, memberAlignment); + size += memberSize; + } + + // The structure may have padding at the end; the base offset of + // the member following the sub-structure is rounded up to the next + // multiple of the base alignment of the structure. + RoundToPow2(size, maxAlignment); + + return maxAlignment; + } + + // rule 1 + if (type.isScalar()) + return getBaseAlignmentScalar(type, size); + + // rules 2 and 3 + if (type.isVector()) { + int scalarAlign = getBaseAlignmentScalar(type, size); + switch (type.getVectorSize()) { + case 2: + size *= 2; + return 2 * scalarAlign; + default: + size *= type.getVectorSize(); + return 4 * scalarAlign; + } + } + + // rules 5 and 7 + if (type.isMatrix()) { + // rule 5: deref to row, not to column, meaning the size of vector is num columns instead of num rows + TType derefType(type, 0, rowMajor); + + alignment = getBaseAlignment(derefType, size, dummyStride, std140, rowMajor); + if (std140) + alignment = std::max(baseAlignmentVec4Std140, alignment); + RoundToPow2(size, alignment); + stride = size; // use intra-matrix stride for stride of a just a matrix + if (rowMajor) + size = stride * type.getMatrixRows(); + else + size = stride * type.getMatrixCols(); + + return alignment; + } + + assert(0); // all cases should be covered above + size = baseAlignmentVec4Std140; + return baseAlignmentVec4Std140; +} + +// To aid the basic HLSL rule about crossing vec4 boundaries. +bool TIntermediate::improperStraddle(const TType& type, int size, int offset) +{ + if (! type.isVector() || type.isArray()) + return false; + + return size <= 16 ? offset / 16 != (offset + size - 1) / 16 + : offset % 16 != 0; +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/localintermediate.h b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/localintermediate.h new file mode 100644 index 00000000..4d48c68d --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/localintermediate.h @@ -0,0 +1,729 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2016 LunarG, Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef _LOCAL_INTERMEDIATE_INCLUDED_ +#define _LOCAL_INTERMEDIATE_INCLUDED_ + +#include "../Include/intermediate.h" +#include "../Public/ShaderLang.h" +#include "Versions.h" + +#include +#include +#include + +class TInfoSink; + +namespace glslang { + +struct TMatrixSelector { + int coord1; // stay agnostic about column/row; this is parse order + int coord2; +}; + +typedef int TVectorSelector; + +const int MaxSwizzleSelectors = 4; + +template +class TSwizzleSelectors { +public: + TSwizzleSelectors() : size_(0) { } + + void push_back(selectorType comp) + { + if (size_ < MaxSwizzleSelectors) + components[size_++] = comp; + } + void resize(int s) + { + assert(s <= size_); + size_ = s; + } + int size() const { return size_; } + selectorType operator[](int i) const + { + assert(i < MaxSwizzleSelectors); + return components[i]; + } + +private: + int size_; + selectorType components[MaxSwizzleSelectors]; +}; + +// +// Some helper structures for TIntermediate. Their contents are encapsulated +// by TIntermediate. +// + +// Used for call-graph algorithms for detecting recursion, missing bodies, and dead bodies. +// A "call" is a pair: . +// There can be duplicates. General assumption is the list is small. +struct TCall { + TCall(const TString& pCaller, const TString& pCallee) : caller(pCaller), callee(pCallee) { } + TString caller; + TString callee; + bool visited; + bool currentPath; + bool errorGiven; + int calleeBodyPosition; +}; + +// A generic 1-D range. +struct TRange { + TRange(int start, int last) : start(start), last(last) { } + bool overlap(const TRange& rhs) const + { + return last >= rhs.start && start <= rhs.last; + } + int start; + int last; +}; + +// An IO range is a 3-D rectangle; the set of (location, component, index) triples all lying +// within the same location range, component range, and index value. Locations don't alias unless +// all other dimensions of their range overlap. +struct TIoRange { + TIoRange(TRange location, TRange component, TBasicType basicType, int index) + : location(location), component(component), basicType(basicType), index(index) { } + bool overlap(const TIoRange& rhs) const + { + return location.overlap(rhs.location) && component.overlap(rhs.component) && index == rhs.index; + } + TRange location; + TRange component; + TBasicType basicType; + int index; +}; + +// An offset range is a 2-D rectangle; the set of (binding, offset) pairs all lying +// within the same binding and offset range. +struct TOffsetRange { + TOffsetRange(TRange binding, TRange offset) + : binding(binding), offset(offset) { } + bool overlap(const TOffsetRange& rhs) const + { + return binding.overlap(rhs.binding) && offset.overlap(rhs.offset); + } + TRange binding; + TRange offset; +}; + +// Things that need to be tracked per xfb buffer. +struct TXfbBuffer { + TXfbBuffer() : stride(TQualifier::layoutXfbStrideEnd), implicitStride(0), containsDouble(false) { } + std::vector ranges; // byte offsets that have already been assigned + unsigned int stride; + unsigned int implicitStride; + bool containsDouble; +}; + +// Track a set of strings describing how the module was processed. +// Using the form: +// process arg0 arg1 arg2 ... +// process arg0 arg1 arg2 ... +// where everything is textual, and there can be zero or more arguments +class TProcesses { +public: + TProcesses() {} + ~TProcesses() {} + + void addProcess(const char* process) + { + processes.push_back(process); + } + void addProcess(const std::string& process) + { + processes.push_back(process); + } + void addArgument(int arg) + { + processes.back().append(" "); + std::string argString = std::to_string(arg); + processes.back().append(argString); + } + void addArgument(const char* arg) + { + processes.back().append(" "); + processes.back().append(arg); + } + void addArgument(const std::string& arg) + { + processes.back().append(" "); + processes.back().append(arg); + } + void addIfNonZero(const char* process, int value) + { + if (value != 0) { + addProcess(process); + addArgument(value); + } + } + + const std::vector& getProcesses() const { return processes; } + +private: + std::vector processes; +}; + +class TSymbolTable; +class TSymbol; +class TVariable; + +// +// Set of helper functions to help parse and build the tree. +// +class TIntermediate { +public: + explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) : + implicitThisName("@this"), + language(l), source(EShSourceNone), profile(p), version(v), treeRoot(0), + numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false), + invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet), + inputPrimitive(ElgNone), outputPrimitive(ElgNone), + pixelCenterInteger(false), originUpperLeft(false), + vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false), + postDepthCoverage(false), depthLayout(EldNone), depthReplacing(false), + blendEquations(0), xfbMode(false), multiStream(false), +#ifdef NV_EXTENSIONS + layoutOverrideCoverage(false), + geoPassthroughEXT(false), +#endif + autoMapBindings(false), + autoMapLocations(false), + invertY(false), + flattenUniformArrays(false), + useUnknownFormat(false), + hlslOffsets(false), + useStorageBuffer(false), + hlslIoMapping(false), + textureSamplerTransformMode(EShTexSampTransKeep), + needToLegalize(false) + { + localSize[0] = 1; + localSize[1] = 1; + localSize[2] = 1; + localSizeSpecId[0] = TQualifier::layoutNotSet; + localSizeSpecId[1] = TQualifier::layoutNotSet; + localSizeSpecId[2] = TQualifier::layoutNotSet; + xfbBuffers.resize(TQualifier::layoutXfbBufferEnd); + + shiftBinding.fill(0); + } + void setLimits(const TBuiltInResource& r) { resources = r; } + + bool postProcess(TIntermNode*, EShLanguage); + void output(TInfoSink&, bool tree); + void removeTree(); + + void setSource(EShSource s) { source = s; } + EShSource getSource() const { return source; } + void setEntryPointName(const char* ep) + { + entryPointName = ep; + processes.addProcess("entry-point"); + processes.addArgument(entryPointName); + } + void setEntryPointMangledName(const char* ep) { entryPointMangledName = ep; } + const std::string& getEntryPointName() const { return entryPointName; } + const std::string& getEntryPointMangledName() const { return entryPointMangledName; } + + void setShiftBinding(TResourceType res, unsigned int shift) + { + shiftBinding[res] = shift; + + const char* name = getResourceName(res); + if (name != nullptr) + processes.addIfNonZero(name, shift); + } + + unsigned int getShiftBinding(TResourceType res) const { return shiftBinding[res]; } + + void setShiftBindingForSet(TResourceType res, unsigned int shift, unsigned int set) + { + if (shift == 0) // ignore if there's no shift: it's a no-op. + return; + + shiftBindingForSet[res][set] = shift; + + const char* name = getResourceName(res); + if (name != nullptr) { + processes.addProcess(name); + processes.addArgument(shift); + processes.addArgument(set); + } + } + + int getShiftBindingForSet(TResourceType res, unsigned int set) const + { + const auto shift = shiftBindingForSet[res].find(set); + return shift == shiftBindingForSet[res].end() ? -1 : shift->second; + } + bool hasShiftBindingForSet(TResourceType res) const { return !shiftBindingForSet[res].empty(); } + + void setResourceSetBinding(const std::vector& shift) + { + resourceSetBinding = shift; + if (shift.size() > 0) { + processes.addProcess("resource-set-binding"); + for (int s = 0; s < (int)shift.size(); ++s) + processes.addArgument(shift[s]); + } + } + const std::vector& getResourceSetBinding() const { return resourceSetBinding; } + void setAutoMapBindings(bool map) + { + autoMapBindings = map; + if (autoMapBindings) + processes.addProcess("auto-map-bindings"); + } + bool getAutoMapBindings() const { return autoMapBindings; } + void setAutoMapLocations(bool map) + { + autoMapLocations = map; + if (autoMapLocations) + processes.addProcess("auto-map-locations"); + } + bool getAutoMapLocations() const { return autoMapLocations; } + void setInvertY(bool invert) + { + invertY = invert; + if (invertY) + processes.addProcess("invert-y"); + } + bool getInvertY() const { return invertY; } + + void setFlattenUniformArrays(bool flatten) + { + flattenUniformArrays = flatten; + if (flattenUniformArrays) + processes.addProcess("flatten-uniform-arrays"); + } + bool getFlattenUniformArrays() const { return flattenUniformArrays; } + void setNoStorageFormat(bool b) + { + useUnknownFormat = b; + if (useUnknownFormat) + processes.addProcess("no-storage-format"); + } + bool getNoStorageFormat() const { return useUnknownFormat; } + void setHlslOffsets() + { + hlslOffsets = true; + if (hlslOffsets) + processes.addProcess("hlsl-offsets"); + } + bool usingHlslOFfsets() const { return hlslOffsets; } + void setUseStorageBuffer() + { + useStorageBuffer = true; + processes.addProcess("use-storage-buffer"); + } + bool usingStorageBuffer() const { return useStorageBuffer; } + void setHlslIoMapping(bool b) + { + hlslIoMapping = b; + if (hlslIoMapping) + processes.addProcess("hlsl-iomap"); + } + bool usingHlslIoMapping() { return hlslIoMapping; } + + void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; } + + void setVersion(int v) { version = v; } + int getVersion() const { return version; } + void setProfile(EProfile p) { profile = p; } + EProfile getProfile() const { return profile; } + void setSpv(const SpvVersion& s) + { + spvVersion = s; + + // client processes + if (spvVersion.vulkan > 0) + processes.addProcess("client vulkan100"); + if (spvVersion.openGl > 0) + processes.addProcess("client opengl100"); + + // target-environment processes + if (spvVersion.vulkan == 100) + processes.addProcess("target-env vulkan1.0"); + else if (spvVersion.vulkan > 0) + processes.addProcess("target-env vulkanUnknown"); + if (spvVersion.openGl > 0) + processes.addProcess("target-env opengl"); + } + const SpvVersion& getSpv() const { return spvVersion; } + EShLanguage getStage() const { return language; } + void addRequestedExtension(const char* extension) { requestedExtensions.insert(extension); } + const std::set& getRequestedExtensions() const { return requestedExtensions; } + + void setTreeRoot(TIntermNode* r) { treeRoot = r; } + TIntermNode* getTreeRoot() const { return treeRoot; } + void incrementEntryPointCount() { ++numEntryPoints; } + int getNumEntryPoints() const { return numEntryPoints; } + int getNumErrors() const { return numErrors; } + void addPushConstantCount() { ++numPushConstants; } + bool isRecursive() const { return recursive; } + + TIntermSymbol* addSymbol(const TVariable&); + TIntermSymbol* addSymbol(const TVariable&, const TSourceLoc&); + TIntermSymbol* addSymbol(const TType&, const TSourceLoc&); + TIntermSymbol* addSymbol(const TIntermSymbol&); + TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*) const; + TIntermTyped* addUniShapeConversion(TOperator, const TType&, TIntermTyped*); + void addBiShapeConversion(TOperator, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode); + TIntermTyped* addShapeConversion(const TType&, TIntermTyped*); + TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc); + TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc); + TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc); + TIntermTyped* addUnaryMath(TOperator, TIntermTyped* child, TSourceLoc); + TIntermTyped* addBuiltInFunctionCall(const TSourceLoc& line, TOperator, bool unary, TIntermNode*, const TType& returnType); + bool canImplicitlyPromote(TBasicType from, TBasicType to, TOperator op = EOpNull) const; + TOperator mapTypeToConstructorOp(const TType&) const; + TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right); + TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&); + TIntermAggregate* makeAggregate(TIntermNode* node); + TIntermAggregate* makeAggregate(TIntermNode* node, const TSourceLoc&); + TIntermAggregate* makeAggregate(const TSourceLoc&); + TIntermTyped* setAggregateOperator(TIntermNode*, TOperator, const TType& type, TSourceLoc); + bool areAllChildConst(TIntermAggregate* aggrNode); + TIntermTyped* addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&, TSelectionControl = ESelectionControlNone); + TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&, TSelectionControl = ESelectionControlNone); + TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc&); + TIntermTyped* addMethod(TIntermTyped*, const TType&, const TString*, const TSourceLoc&); + TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, const TSourceLoc&, bool literal = false) const; + TIntermConstantUnion* addConstantUnion(int, const TSourceLoc&, bool literal = false) const; + TIntermConstantUnion* addConstantUnion(unsigned int, const TSourceLoc&, bool literal = false) const; + TIntermConstantUnion* addConstantUnion(long long, const TSourceLoc&, bool literal = false) const; + TIntermConstantUnion* addConstantUnion(unsigned long long, const TSourceLoc&, bool literal = false) const; +#ifdef AMD_EXTENSIONS + TIntermConstantUnion* addConstantUnion(short, const TSourceLoc&, bool literal = false) const; + TIntermConstantUnion* addConstantUnion(unsigned short, const TSourceLoc&, bool literal = false) const; + +#endif + TIntermConstantUnion* addConstantUnion(bool, const TSourceLoc&, bool literal = false) const; + TIntermConstantUnion* addConstantUnion(double, TBasicType, const TSourceLoc&, bool literal = false) const; + TIntermConstantUnion* addConstantUnion(const TString*, const TSourceLoc&, bool literal = false) const; + TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) const; + bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false); + TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&, TLoopControl = ELoopControlNone); + TIntermAggregate* addForLoop(TIntermNode*, TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&, TLoopControl = ELoopControlNone); + TIntermBranch* addBranch(TOperator, const TSourceLoc&); + TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&); + template TIntermTyped* addSwizzle(TSwizzleSelectors&, const TSourceLoc&); + + // Low level functions to add nodes (no conversions or other higher level transformations) + // If a type is provided, the node's type will be set to it. + TIntermBinary* addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc) const; + TIntermBinary* addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc, const TType&) const; + TIntermUnary* addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc) const; + TIntermUnary* addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc, const TType&) const; + + // Add conversion from node's type to given basic type. + TIntermTyped* convertToBasicType(TOperator op, TBasicType basicType, TIntermTyped* node) const; + + // Constant folding (in Constant.cpp) + TIntermTyped* fold(TIntermAggregate* aggrNode); + TIntermTyped* foldConstructor(TIntermAggregate* aggrNode); + TIntermTyped* foldDereference(TIntermTyped* node, int index, const TSourceLoc&); + TIntermTyped* foldSwizzle(TIntermTyped* node, TSwizzleSelectors& fields, const TSourceLoc&); + + // Tree ops + static const TIntermTyped* findLValueBase(const TIntermTyped*, bool swizzleOkay); + + // Linkage related + void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&); + void addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol&); + + bool setInvocations(int i) + { + if (invocations != TQualifier::layoutNotSet) + return invocations == i; + invocations = i; + return true; + } + int getInvocations() const { return invocations; } + bool setVertices(int m) + { + if (vertices != TQualifier::layoutNotSet) + return vertices == m; + vertices = m; + return true; + } + int getVertices() const { return vertices; } + bool setInputPrimitive(TLayoutGeometry p) + { + if (inputPrimitive != ElgNone) + return inputPrimitive == p; + inputPrimitive = p; + return true; + } + TLayoutGeometry getInputPrimitive() const { return inputPrimitive; } + bool setVertexSpacing(TVertexSpacing s) + { + if (vertexSpacing != EvsNone) + return vertexSpacing == s; + vertexSpacing = s; + return true; + } + TVertexSpacing getVertexSpacing() const { return vertexSpacing; } + bool setVertexOrder(TVertexOrder o) + { + if (vertexOrder != EvoNone) + return vertexOrder == o; + vertexOrder = o; + return true; + } + TVertexOrder getVertexOrder() const { return vertexOrder; } + void setPointMode() { pointMode = true; } + bool getPointMode() const { return pointMode; } + + bool setLocalSize(int dim, int size) + { + if (localSize[dim] > 1) + return size == localSize[dim]; + localSize[dim] = size; + return true; + } + unsigned int getLocalSize(int dim) const { return localSize[dim]; } + + bool setLocalSizeSpecId(int dim, int id) + { + if (localSizeSpecId[dim] != TQualifier::layoutNotSet) + return id == localSizeSpecId[dim]; + localSizeSpecId[dim] = id; + return true; + } + int getLocalSizeSpecId(int dim) const { return localSizeSpecId[dim]; } + + void setXfbMode() { xfbMode = true; } + bool getXfbMode() const { return xfbMode; } + void setMultiStream() { multiStream = true; } + bool isMultiStream() const { return multiStream; } + bool setOutputPrimitive(TLayoutGeometry p) + { + if (outputPrimitive != ElgNone) + return outputPrimitive == p; + outputPrimitive = p; + return true; + } + TLayoutGeometry getOutputPrimitive() const { return outputPrimitive; } + void setOriginUpperLeft() { originUpperLeft = true; } + bool getOriginUpperLeft() const { return originUpperLeft; } + void setPixelCenterInteger() { pixelCenterInteger = true; } + bool getPixelCenterInteger() const { return pixelCenterInteger; } + void setEarlyFragmentTests() { earlyFragmentTests = true; } + bool getEarlyFragmentTests() const { return earlyFragmentTests; } + void setPostDepthCoverage() { postDepthCoverage = true; } + bool getPostDepthCoverage() const { return postDepthCoverage; } + bool setDepth(TLayoutDepth d) + { + if (depthLayout != EldNone) + return depthLayout == d; + depthLayout = d; + return true; + } + TLayoutDepth getDepth() const { return depthLayout; } + void setDepthReplacing() { depthReplacing = true; } + bool isDepthReplacing() const { return depthReplacing; } + + void addBlendEquation(TBlendEquationShift b) { blendEquations |= (1 << b); } + unsigned int getBlendEquations() const { return blendEquations; } + + void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee); + void merge(TInfoSink&, TIntermediate&); + void finalCheck(TInfoSink&, bool keepUncalled); + + void addIoAccessed(const TString& name) { ioAccessed.insert(name); } + bool inIoAccessed(const TString& name) const { return ioAccessed.find(name) != ioAccessed.end(); } + + int addUsedLocation(const TQualifier&, const TType&, bool& typeCollision); + int checkLocationRange(int set, const TIoRange& range, const TType&, bool& typeCollision); + int addUsedOffsets(int binding, int offset, int numOffsets); + bool addUsedConstantId(int id); + int computeTypeLocationSize(const TType&) const; + + bool setXfbBufferStride(int buffer, unsigned stride) + { + if (xfbBuffers[buffer].stride != TQualifier::layoutXfbStrideEnd) + return xfbBuffers[buffer].stride == stride; + xfbBuffers[buffer].stride = stride; + return true; + } + unsigned getXfbStride(int buffer) const { return xfbBuffers[buffer].stride; } + int addXfbBufferOffset(const TType&); + unsigned int computeTypeXfbSize(const TType&, bool& containsDouble) const; + static int getBaseAlignmentScalar(const TType&, int& size); + static int getBaseAlignment(const TType&, int& size, int& stride, bool std140, bool rowMajor); + static bool improperStraddle(const TType& type, int size, int offset); + bool promote(TIntermOperator*); + +#ifdef NV_EXTENSIONS + void setLayoutOverrideCoverage() { layoutOverrideCoverage = true; } + bool getLayoutOverrideCoverage() const { return layoutOverrideCoverage; } + void setGeoPassthroughEXT() { geoPassthroughEXT = true; } + bool getGeoPassthroughEXT() const { return geoPassthroughEXT; } +#endif + + const char* addSemanticName(const TString& name) + { + return semanticNameSet.insert(name).first->c_str(); + } + + void setSourceFile(const char* file) { sourceFile = file; } + const std::string& getSourceFile() const { return sourceFile; } + void addSourceText(const char* text) { sourceText = sourceText + text; } + const std::string& getSourceText() const { return sourceText; } + void addProcesses(const std::vector& p) { + for (int i = 0; i < (int)p.size(); ++i) + processes.addProcess(p[i]); + } + void addProcess(const std::string& process) { processes.addProcess(process); } + void addProcessArgument(const std::string& arg) { processes.addArgument(arg); } + const std::vector& getProcesses() const { return processes.getProcesses(); } + + void setNeedsLegalization() { needToLegalize = true; } + bool needsLegalization() const { return needToLegalize; } + + const char* const implicitThisName; + +protected: + TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&); + void error(TInfoSink& infoSink, const char*); + void warn(TInfoSink& infoSink, const char*); + void mergeBodies(TInfoSink&, TIntermSequence& globals, const TIntermSequence& unitGlobals); + void mergeLinkerObjects(TInfoSink&, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects); + void mergeImplicitArraySizes(TType&, const TType&); + void mergeErrorCheck(TInfoSink&, const TIntermSymbol&, const TIntermSymbol&, bool crossStage); + void checkCallGraphCycles(TInfoSink&); + void checkCallGraphBodies(TInfoSink&, bool keepUncalled); + void inOutLocationCheck(TInfoSink&); + TIntermSequence& findLinkerObjects() const; + bool userOutputUsed() const; + bool isSpecializationOperation(const TIntermOperator&) const; + bool promoteUnary(TIntermUnary&); + bool promoteBinary(TIntermBinary&); + void addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable&, const TString&); + bool promoteAggregate(TIntermAggregate&); + void pushSelector(TIntermSequence&, const TVectorSelector&, const TSourceLoc&); + void pushSelector(TIntermSequence&, const TMatrixSelector&, const TSourceLoc&); + bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&); + void performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root); + static const char* getResourceName(TResourceType); + + const EShLanguage language; // stage, known at construction time + EShSource source; // source language, known a bit later + std::string entryPointName; + std::string entryPointMangledName; + + EProfile profile; + int version; + SpvVersion spvVersion; + TIntermNode* treeRoot; + std::set requestedExtensions; // cumulation of all enabled or required extensions; not connected to what subset of the shader used them + TBuiltInResource resources; + int numEntryPoints; + int numErrors; + int numPushConstants; + bool recursive; + int invocations; + int vertices; + TLayoutGeometry inputPrimitive; + TLayoutGeometry outputPrimitive; + bool pixelCenterInteger; + bool originUpperLeft; + TVertexSpacing vertexSpacing; + TVertexOrder vertexOrder; + bool pointMode; + int localSize[3]; + int localSizeSpecId[3]; + bool earlyFragmentTests; + bool postDepthCoverage; + TLayoutDepth depthLayout; + bool depthReplacing; + int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift + bool xfbMode; + bool multiStream; + +#ifdef NV_EXTENSIONS + bool layoutOverrideCoverage; + bool geoPassthroughEXT; +#endif + + // Base shift values + std::array shiftBinding; + + // Per-descriptor-set shift values + std::array, EResCount> shiftBindingForSet; + + std::vector resourceSetBinding; + bool autoMapBindings; + bool autoMapLocations; + bool invertY; + bool flattenUniformArrays; + bool useUnknownFormat; + bool hlslOffsets; + bool useStorageBuffer; + bool hlslIoMapping; + + typedef std::list TGraph; + TGraph callGraph; + + std::set ioAccessed; // set of names of statically read/written I/O that might need extra checking + std::vector usedIo[4]; // sets of used locations, one for each of in, out, uniform, and buffers + std::vector usedAtomics; // sets of bindings used by atomic counters + std::vector xfbBuffers; // all the data we need to track per xfb buffer + std::unordered_set usedConstantId; // specialization constant ids used + std::set semanticNameSet; + + EShTextureSamplerTransformMode textureSamplerTransformMode; + + // source code of shader, useful as part of debug information + std::string sourceFile; + std::string sourceText; + + // for OpModuleProcessed, or equivalent + TProcesses processes; + + bool needToLegalize; + +private: + void operator=(TIntermediate&); // prevent assignments +}; + +} // end namespace glslang + +#endif // _LOCAL_INTERMEDIATE_INCLUDED_ diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/parseConst.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/parseConst.cpp new file mode 100644 index 00000000..1a8e6d99 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/parseConst.cpp @@ -0,0 +1,204 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +// +// Traverse a tree of constants to create a single folded constant. +// It should only be used when the whole tree is known to be constant. +// + +#include "ParseHelper.h" + +namespace glslang { + +class TConstTraverser : public TIntermTraverser { +public: + TConstTraverser(const TConstUnionArray& cUnion, bool singleConstParam, TOperator constructType, const TType& t) + : unionArray(cUnion), type(t), + constructorType(constructType), singleConstantParam(singleConstParam), error(false), isMatrix(false), + matrixCols(0), matrixRows(0) { index = 0; tOp = EOpNull; } + + virtual void visitConstantUnion(TIntermConstantUnion* node); + virtual bool visitAggregate(TVisit, TIntermAggregate* node); + + int index; + TConstUnionArray unionArray; + TOperator tOp; + const TType& type; + TOperator constructorType; + bool singleConstantParam; + bool error; + int size; // size of the constructor ( 4 for vec4) + bool isMatrix; + int matrixCols; + int matrixRows; + +protected: + TConstTraverser(TConstTraverser&); + TConstTraverser& operator=(TConstTraverser&); +}; + +bool TConstTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node) +{ + if (! node->isConstructor() && node->getOp() != EOpComma) { + error = true; + + return false; + } + + bool flag = node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion(); + if (flag) { + singleConstantParam = true; + constructorType = node->getOp(); + size = node->getType().computeNumComponents(); + + if (node->getType().isMatrix()) { + isMatrix = true; + matrixCols = node->getType().getMatrixCols(); + matrixRows = node->getType().getMatrixRows(); + } + } + + for (TIntermSequence::iterator p = node->getSequence().begin(); + p != node->getSequence().end(); p++) { + + if (node->getOp() == EOpComma) + index = 0; + + (*p)->traverse(this); + } + if (flag) + { + singleConstantParam = false; + constructorType = EOpNull; + size = 0; + isMatrix = false; + matrixCols = 0; + matrixRows = 0; + } + + return false; +} + +void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node) +{ + TConstUnionArray leftUnionArray(unionArray); + int instanceSize = type.computeNumComponents(); + + if (index >= instanceSize) + return; + + if (! singleConstantParam) { + int rightUnionSize = node->getType().computeNumComponents(); + + const TConstUnionArray& rightUnionArray = node->getConstArray(); + for (int i = 0; i < rightUnionSize; i++) { + if (index >= instanceSize) + return; + leftUnionArray[index] = rightUnionArray[i]; + + index++; + } + } else { + int endIndex = index + size; + const TConstUnionArray& rightUnionArray = node->getConstArray(); + if (! isMatrix) { + int count = 0; + int nodeComps = node->getType().computeNumComponents(); + for (int i = index; i < endIndex; i++) { + if (i >= instanceSize) + return; + + leftUnionArray[i] = rightUnionArray[count]; + + (index)++; + + if (nodeComps > 1) + count++; + } + } else { + // constructing a matrix, but from what? + if (node->isMatrix()) { + // Matrix from a matrix; this has the outer matrix, node is the argument matrix. + // Traverse the outer, potentially bigger matrix, fill in missing pieces with the + // identity matrix. + for (int c = 0; c < matrixCols; ++c) { + for (int r = 0; r < matrixRows; ++r) { + int targetOffset = index + c * matrixRows + r; + if (r < node->getType().getMatrixRows() && c < node->getType().getMatrixCols()) { + int srcOffset = c * node->getType().getMatrixRows() + r; + leftUnionArray[targetOffset] = rightUnionArray[srcOffset]; + } else if (r == c) + leftUnionArray[targetOffset].setDConst(1.0); + else + leftUnionArray[targetOffset].setDConst(0.0); + } + } + } else { + // matrix from vector + int count = 0; + const int startIndex = index; + int nodeComps = node->getType().computeNumComponents(); + for (int i = startIndex; i < endIndex; i++) { + if (i >= instanceSize) + return; + if (i == startIndex || (i - startIndex) % (matrixRows + 1) == 0 ) + leftUnionArray[i] = rightUnionArray[count]; + else + leftUnionArray[i].setDConst(0.0); + + index++; + + if (nodeComps > 1) + count++; + } + } + } + } +} + +bool TIntermediate::parseConstTree(TIntermNode* root, TConstUnionArray unionArray, TOperator constructorType, const TType& t, bool singleConstantParam) +{ + if (root == 0) + return false; + + TConstTraverser it(unionArray, singleConstantParam, constructorType, t); + + root->traverse(&it); + if (it.error) + return true; + else + return false; +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/parseVersions.h b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/parseVersions.h new file mode 100755 index 00000000..5f26b437 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/parseVersions.h @@ -0,0 +1,140 @@ +// +// Copyright (C) 2016 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +// This is implemented in Versions.cpp + +#ifndef _PARSE_VERSIONS_INCLUDED_ +#define _PARSE_VERSIONS_INCLUDED_ + +#include "../Public/ShaderLang.h" +#include "../Include/InfoSink.h" +#include "Scan.h" + +#include + +namespace glslang { + +// +// Base class for parse helpers. +// This just has version-related information and checking. +// This class should be sufficient for preprocessing. +// +class TParseVersions { +public: + TParseVersions(TIntermediate& interm, int version, EProfile profile, + const SpvVersion& spvVersion, EShLanguage language, TInfoSink& infoSink, + bool forwardCompatible, EShMessages messages) + : infoSink(infoSink), version(version), profile(profile), language(language), + spvVersion(spvVersion), forwardCompatible(forwardCompatible), + intermediate(interm), messages(messages), numErrors(0), currentScanner(0) { } + virtual ~TParseVersions() { } + virtual void initializeExtensionBehavior(); + virtual void requireProfile(const TSourceLoc&, int queryProfiles, const char* featureDesc); + virtual void profileRequires(const TSourceLoc&, int queryProfiles, int minVersion, int numExtensions, const char* const extensions[], const char* featureDesc); + virtual void profileRequires(const TSourceLoc&, int queryProfiles, int minVersion, const char* const extension, const char* featureDesc); + virtual void requireStage(const TSourceLoc&, EShLanguageMask, const char* featureDesc); + virtual void requireStage(const TSourceLoc&, EShLanguage, const char* featureDesc); + virtual void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc); + virtual void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc); + virtual void unimplemented(const TSourceLoc&, const char* featureDesc); + virtual void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc); + virtual void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc); + virtual TExtensionBehavior getExtensionBehavior(const char*); + virtual bool extensionTurnedOn(const char* const extension); + virtual bool extensionsTurnedOn(int numExtensions, const char* const extensions[]); + virtual void updateExtensionBehavior(int line, const char* const extension, const char* behavior); + virtual void fullIntegerCheck(const TSourceLoc&, const char* op); + virtual void doubleCheck(const TSourceLoc&, const char* op); +#ifdef AMD_EXTENSIONS + virtual void int16Check(const TSourceLoc& loc, const char* op, bool builtIn = false); + virtual void float16Check(const TSourceLoc&, const char* op, bool builtIn = false); +#endif + virtual void int64Check(const TSourceLoc&, const char* op, bool builtIn = false); + virtual void spvRemoved(const TSourceLoc&, const char* op); + virtual void vulkanRemoved(const TSourceLoc&, const char* op); + virtual void requireVulkan(const TSourceLoc&, const char* op); + virtual void requireSpv(const TSourceLoc&, const char* op); + virtual bool checkExtensionsRequested(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc); + virtual void updateExtensionBehavior(const char* const extension, TExtensionBehavior); + + virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, ...) = 0; + virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, ...) = 0; + virtual void C_DECL ppError(const TSourceLoc&, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, ...) = 0; + virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, ...) = 0; + + void addError() { ++numErrors; } + int getNumErrors() const { return numErrors; } + + void setScanner(TInputScanner* scanner) { currentScanner = scanner; } + TInputScanner* getScanner() const { return currentScanner; } + const TSourceLoc& getCurrentLoc() const { return currentScanner->getSourceLoc(); } + void setCurrentLine(int line) { currentScanner->setLine(line); } + void setCurrentColumn(int col) { currentScanner->setColumn(col); } + void setCurrentSourceName(const char* name) { currentScanner->setFile(name); } + void setCurrentString(int string) { currentScanner->setString(string); } + + void getPreamble(std::string&); + bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; } + bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; } + bool isReadingHLSL() const { return (messages & EShMsgReadHlsl) == EShMsgReadHlsl; } + + TInfoSink& infoSink; + + // compilation mode + int version; // version, updated by #version in the shader + EProfile profile; // the declared profile in the shader (core by default) + EShLanguage language; // really the stage + SpvVersion spvVersion; + bool forwardCompatible; // true if errors are to be given for use of deprecated features + TIntermediate& intermediate; // helper for making and hooking up pieces of the parse tree + +protected: + TMap extensionBehavior; // for each extension string, what its current behavior is set to + EShMessages messages; // errors/warnings/rule-sets + int numErrors; // number of compile-time errors encountered + TInputScanner* currentScanner; + +private: + explicit TParseVersions(const TParseVersions&); + TParseVersions& operator=(const TParseVersions&); +}; + +} // end namespace glslang + +#endif // _PARSE_VERSIONS_INCLUDED_ diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp new file mode 100644 index 00000000..3ae711c8 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp @@ -0,0 +1,1274 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2013 LunarG, Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +/****************************************************************************\ +Copyright (c) 2002, NVIDIA Corporation. + +NVIDIA Corporation("NVIDIA") supplies this software to you in +consideration of your agreement to the following terms, and your use, +installation, modification or redistribution of this NVIDIA software +constitutes acceptance of these terms. If you do not agree with these +terms, please do not use, install, modify or redistribute this NVIDIA +software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, NVIDIA grants you a personal, non-exclusive +license, under NVIDIA's copyrights in this original NVIDIA software (the +"NVIDIA Software"), to use, reproduce, modify and redistribute the +NVIDIA Software, with or without modifications, in source and/or binary +forms; provided that if you redistribute the NVIDIA Software, you must +retain the copyright notice of NVIDIA, this notice and the following +text and disclaimers in all such redistributions of the NVIDIA Software. +Neither the name, trademarks, service marks nor logos of NVIDIA +Corporation may be used to endorse or promote products derived from the +NVIDIA Software without specific prior written permission from NVIDIA. +Except as expressly stated in this notice, no other rights or licenses +express or implied, are granted by NVIDIA herein, including but not +limited to any patent rights that may be infringed by your derivative +works or by other works in which the NVIDIA Software may be +incorporated. No hardware is licensed hereunder. + +THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, +INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR +ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER +PRODUCTS. + +IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, +INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY +OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE +NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, +TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF +NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\****************************************************************************/ + +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include +#include +#include +#include +#include + +#include "PpContext.h" +#include "PpTokens.h" + +namespace glslang { + +// Handle #define +int TPpContext::CPPdefine(TPpToken* ppToken) +{ + MacroSymbol mac; + + // get the macro name + int token = scanToken(ppToken); + if (token != PpAtomIdentifier) { + parseContext.ppError(ppToken->loc, "must be followed by macro name", "#define", ""); + return token; + } + if (ppToken->loc.string >= 0) { + // We are in user code; check for reserved name use: + parseContext.reservedPpErrorCheck(ppToken->loc, ppToken->name, "#define"); + } + + // save the macro name + const int defAtom = atomStrings.getAddAtom(ppToken->name); + + // gather parameters to the macro, between (...) + token = scanToken(ppToken); + if (token == '(' && ! ppToken->space) { + mac.emptyArgs = 1; + do { + token = scanToken(ppToken); + if (mac.args.size() == 0 && token == ')') + break; + if (token != PpAtomIdentifier) { + parseContext.ppError(ppToken->loc, "bad argument", "#define", ""); + + return token; + } + mac.emptyArgs = 0; + const int argAtom = atomStrings.getAddAtom(ppToken->name); + + // check for duplication of parameter name + bool duplicate = false; + for (size_t a = 0; a < mac.args.size(); ++a) { + if (mac.args[a] == argAtom) { + parseContext.ppError(ppToken->loc, "duplicate macro parameter", "#define", ""); + duplicate = true; + break; + } + } + if (! duplicate) + mac.args.push_back(argAtom); + token = scanToken(ppToken); + } while (token == ','); + if (token != ')') { + parseContext.ppError(ppToken->loc, "missing parenthesis", "#define", ""); + + return token; + } + + token = scanToken(ppToken); + } + + // record the definition of the macro + TSourceLoc defineLoc = ppToken->loc; // because ppToken is going to go to the next line before we report errors + while (token != '\n' && token != EndOfInput) { + mac.body.putToken(token, ppToken); + token = scanToken(ppToken); + if (token != '\n' && ppToken->space) + mac.body.putToken(' ', ppToken); + } + + // check for duplicate definition + MacroSymbol* existing = lookupMacroDef(defAtom); + if (existing != nullptr) { + if (! existing->undef) { + // Already defined -- need to make sure they are identical: + // "Two replacement lists are identical if and only if the preprocessing tokens in both have the same number, + // ordering, spelling, and white-space separation, where all white-space separations are considered identical." + if (existing->args.size() != mac.args.size() || existing->emptyArgs != mac.emptyArgs) + parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define", atomStrings.getString(defAtom)); + else { + if (existing->args != mac.args) + parseContext.ppError(defineLoc, "Macro redefined; different argument names:", "#define", atomStrings.getString(defAtom)); + existing->body.reset(); + mac.body.reset(); + int newToken; + do { + int oldToken; + TPpToken oldPpToken; + TPpToken newPpToken; + oldToken = existing->body.getToken(parseContext, &oldPpToken); + newToken = mac.body.getToken(parseContext, &newPpToken); + if (oldToken != newToken || oldPpToken != newPpToken) { + parseContext.ppError(defineLoc, "Macro redefined; different substitutions:", "#define", atomStrings.getString(defAtom)); + break; + } + } while (newToken > 0); + } + } + *existing = mac; + } else + addMacroDef(defAtom, mac); + + return '\n'; +} + +// Handle #undef +int TPpContext::CPPundef(TPpToken* ppToken) +{ + int token = scanToken(ppToken); + if (token != PpAtomIdentifier) { + parseContext.ppError(ppToken->loc, "must be followed by macro name", "#undef", ""); + + return token; + } + + parseContext.reservedPpErrorCheck(ppToken->loc, ppToken->name, "#undef"); + + MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->name)); + if (macro != nullptr) + macro->undef = 1; + token = scanToken(ppToken); + if (token != '\n') + parseContext.ppError(ppToken->loc, "can only be followed by a single macro name", "#undef", ""); + + return token; +} + +// Handle #else +/* Skip forward to appropriate spot. This is used both +** to skip to a #endif after seeing an #else, AND to skip to a #else, +** #elif, or #endif after a #if/#ifdef/#ifndef/#elif test was false. +*/ +int TPpContext::CPPelse(int matchelse, TPpToken* ppToken) +{ + int depth = 0; + int token = scanToken(ppToken); + + while (token != EndOfInput) { + if (token != '#') { + while (token != '\n' && token != EndOfInput) + token = scanToken(ppToken); + + if (token == EndOfInput) + return token; + + token = scanToken(ppToken); + continue; + } + + if ((token = scanToken(ppToken)) != PpAtomIdentifier) + continue; + + int nextAtom = atomStrings.getAtom(ppToken->name); + if (nextAtom == PpAtomIf || nextAtom == PpAtomIfdef || nextAtom == PpAtomIfndef) { + depth++; + if (ifdepth >= maxIfNesting || elsetracker >= maxIfNesting) { + parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#if/#ifdef/#ifndef", ""); + return EndOfInput; + } else { + ifdepth++; + elsetracker++; + } + } else if (nextAtom == PpAtomEndif) { + token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken)); + elseSeen[elsetracker] = false; + --elsetracker; + if (depth == 0) { + // found the #endif we are looking for + if (ifdepth > 0) + --ifdepth; + break; + } + --depth; + --ifdepth; + } else if (matchelse && depth == 0) { + if (nextAtom == PpAtomElse) { + elseSeen[elsetracker] = true; + token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken)); + // found the #else we are looking for + break; + } else if (nextAtom == PpAtomElif) { + if (elseSeen[elsetracker]) + parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", ""); + /* we decrement ifdepth here, because CPPif will increment + * it and we really want to leave it alone */ + if (ifdepth > 0) { + --ifdepth; + elseSeen[elsetracker] = false; + --elsetracker; + } + + return CPPif(ppToken); + } + } else if (nextAtom == PpAtomElse) { + if (elseSeen[elsetracker]) + parseContext.ppError(ppToken->loc, "#else after #else", "#else", ""); + else + elseSeen[elsetracker] = true; + token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken)); + } else if (nextAtom == PpAtomElif) { + if (elseSeen[elsetracker]) + parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", ""); + } + } + + return token; +} + +// Call when there should be no more tokens left on a line. +int TPpContext::extraTokenCheck(int contextAtom, TPpToken* ppToken, int token) +{ + if (token != '\n' && token != EndOfInput) { + static const char* message = "unexpected tokens following directive"; + + const char* label; + if (contextAtom == PpAtomElse) + label = "#else"; + else if (contextAtom == PpAtomElif) + label = "#elif"; + else if (contextAtom == PpAtomEndif) + label = "#endif"; + else if (contextAtom == PpAtomIf) + label = "#if"; + else if (contextAtom == PpAtomLine) + label = "#line"; + else + label = ""; + + if (parseContext.relaxedErrors()) + parseContext.ppWarn(ppToken->loc, message, label, ""); + else + parseContext.ppError(ppToken->loc, message, label, ""); + + while (token != '\n' && token != EndOfInput) + token = scanToken(ppToken); + } + + return token; +} + +enum eval_prec { + MIN_PRECEDENCE, + COND, LOGOR, LOGAND, OR, XOR, AND, EQUAL, RELATION, SHIFT, ADD, MUL, UNARY, + MAX_PRECEDENCE +}; + +namespace { + + int op_logor(int a, int b) { return a || b; } + int op_logand(int a, int b) { return a && b; } + int op_or(int a, int b) { return a | b; } + int op_xor(int a, int b) { return a ^ b; } + int op_and(int a, int b) { return a & b; } + int op_eq(int a, int b) { return a == b; } + int op_ne(int a, int b) { return a != b; } + int op_ge(int a, int b) { return a >= b; } + int op_le(int a, int b) { return a <= b; } + int op_gt(int a, int b) { return a > b; } + int op_lt(int a, int b) { return a < b; } + int op_shl(int a, int b) { return a << b; } + int op_shr(int a, int b) { return a >> b; } + int op_add(int a, int b) { return a + b; } + int op_sub(int a, int b) { return a - b; } + int op_mul(int a, int b) { return a * b; } + int op_div(int a, int b) { return a == INT_MIN && b == -1 ? 0 : a / b; } + int op_mod(int a, int b) { return a == INT_MIN && b == -1 ? 0 : a % b; } + int op_pos(int a) { return a; } + int op_neg(int a) { return -a; } + int op_cmpl(int a) { return ~a; } + int op_not(int a) { return !a; } + +}; + +struct TBinop { + int token, precedence, (*op)(int, int); +} binop[] = { + { PpAtomOr, LOGOR, op_logor }, + { PpAtomAnd, LOGAND, op_logand }, + { '|', OR, op_or }, + { '^', XOR, op_xor }, + { '&', AND, op_and }, + { PpAtomEQ, EQUAL, op_eq }, + { PpAtomNE, EQUAL, op_ne }, + { '>', RELATION, op_gt }, + { PpAtomGE, RELATION, op_ge }, + { '<', RELATION, op_lt }, + { PpAtomLE, RELATION, op_le }, + { PpAtomLeft, SHIFT, op_shl }, + { PpAtomRight, SHIFT, op_shr }, + { '+', ADD, op_add }, + { '-', ADD, op_sub }, + { '*', MUL, op_mul }, + { '/', MUL, op_div }, + { '%', MUL, op_mod }, +}; + +struct TUnop { + int token, (*op)(int); +} unop[] = { + { '+', op_pos }, + { '-', op_neg }, + { '~', op_cmpl }, + { '!', op_not }, +}; + +#define NUM_ELEMENTS(A) (sizeof(A) / sizeof(A[0])) + +int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, bool& err, TPpToken* ppToken) +{ + TSourceLoc loc = ppToken->loc; // because we sometimes read the newline before reporting the error + if (token == PpAtomIdentifier) { + if (strcmp("defined", ppToken->name) == 0) { + if (! parseContext.isReadingHLSL() && isMacroInput()) { + if (parseContext.relaxedErrors()) + parseContext.ppWarn(ppToken->loc, "nonportable when expanded from macros for preprocessor expression", + "defined", ""); + else + parseContext.ppError(ppToken->loc, "cannot use in preprocessor expression when expanded from macros", + "defined", ""); + } + bool needclose = 0; + token = scanToken(ppToken); + if (token == '(') { + needclose = true; + token = scanToken(ppToken); + } + if (token != PpAtomIdentifier) { + parseContext.ppError(loc, "incorrect directive, expected identifier", "preprocessor evaluation", ""); + err = true; + res = 0; + + return token; + } + + MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->name)); + res = macro != nullptr ? !macro->undef : 0; + token = scanToken(ppToken); + if (needclose) { + if (token != ')') { + parseContext.ppError(loc, "expected ')'", "preprocessor evaluation", ""); + err = true; + res = 0; + + return token; + } + token = scanToken(ppToken); + } + } else { + token = evalToToken(token, shortCircuit, res, err, ppToken); + return eval(token, precedence, shortCircuit, res, err, ppToken); + } + } else if (token == PpAtomConstInt) { + res = ppToken->ival; + token = scanToken(ppToken); + } else if (token == '(') { + token = scanToken(ppToken); + token = eval(token, MIN_PRECEDENCE, shortCircuit, res, err, ppToken); + if (! err) { + if (token != ')') { + parseContext.ppError(loc, "expected ')'", "preprocessor evaluation", ""); + err = true; + res = 0; + + return token; + } + token = scanToken(ppToken); + } + } else { + int op = NUM_ELEMENTS(unop) - 1; + for (; op >= 0; op--) { + if (unop[op].token == token) + break; + } + if (op >= 0) { + token = scanToken(ppToken); + token = eval(token, UNARY, shortCircuit, res, err, ppToken); + res = unop[op].op(res); + } else { + parseContext.ppError(loc, "bad expression", "preprocessor evaluation", ""); + err = true; + res = 0; + + return token; + } + } + + token = evalToToken(token, shortCircuit, res, err, ppToken); + + // Perform evaluation of binary operation, if there is one, otherwise we are done. + while (! err) { + if (token == ')' || token == '\n') + break; + int op; + for (op = NUM_ELEMENTS(binop) - 1; op >= 0; op--) { + if (binop[op].token == token) + break; + } + if (op < 0 || binop[op].precedence <= precedence) + break; + int leftSide = res; + + // Setup short-circuiting, needed for ES, unless already in a short circuit. + // (Once in a short-circuit, can't turn off again, until that whole subexpression is done. + if (! shortCircuit) { + if ((token == PpAtomOr && leftSide == 1) || + (token == PpAtomAnd && leftSide == 0)) + shortCircuit = true; + } + + token = scanToken(ppToken); + token = eval(token, binop[op].precedence, shortCircuit, res, err, ppToken); + + if (binop[op].op == op_div || binop[op].op == op_mod) { + if (res == 0) { + parseContext.ppError(loc, "division by 0", "preprocessor evaluation", ""); + res = 1; + } + } + res = binop[op].op(leftSide, res); + } + + return token; +} + +// Expand macros, skipping empty expansions, to get to the first real token in those expansions. +int TPpContext::evalToToken(int token, bool shortCircuit, int& res, bool& err, TPpToken* ppToken) +{ + while (token == PpAtomIdentifier && strcmp("defined", ppToken->name) != 0) { + int macroReturn = MacroExpand(ppToken, true, false); + if (macroReturn == 0) { + parseContext.ppError(ppToken->loc, "can't evaluate expression", "preprocessor evaluation", ""); + err = true; + res = 0; + token = scanToken(ppToken); + break; + } + if (macroReturn == -1) { + if (! shortCircuit && parseContext.profile == EEsProfile) { + const char* message = "undefined macro in expression not allowed in es profile"; + if (parseContext.relaxedErrors()) + parseContext.ppWarn(ppToken->loc, message, "preprocessor evaluation", ppToken->name); + else + parseContext.ppError(ppToken->loc, message, "preprocessor evaluation", ppToken->name); + } + } + token = scanToken(ppToken); + } + + return token; +} + +// Handle #if +int TPpContext::CPPif(TPpToken* ppToken) +{ + int token = scanToken(ppToken); + if (ifdepth >= maxIfNesting || elsetracker >= maxIfNesting) { + parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#if", ""); + return EndOfInput; + } else { + elsetracker++; + ifdepth++; + } + int res = 0; + bool err = false; + token = eval(token, MIN_PRECEDENCE, false, res, err, ppToken); + token = extraTokenCheck(PpAtomIf, ppToken, token); + if (!res && !err) + token = CPPelse(1, ppToken); + + return token; +} + +// Handle #ifdef +int TPpContext::CPPifdef(int defined, TPpToken* ppToken) +{ + int token = scanToken(ppToken); + if (ifdepth > maxIfNesting || elsetracker > maxIfNesting) { + parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#ifdef", ""); + return EndOfInput; + } else { + elsetracker++; + ifdepth++; + } + + if (token != PpAtomIdentifier) { + if (defined) + parseContext.ppError(ppToken->loc, "must be followed by macro name", "#ifdef", ""); + else + parseContext.ppError(ppToken->loc, "must be followed by macro name", "#ifndef", ""); + } else { + MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->name)); + token = scanToken(ppToken); + if (token != '\n') { + parseContext.ppError(ppToken->loc, "unexpected tokens following #ifdef directive - expected a newline", "#ifdef", ""); + while (token != '\n' && token != EndOfInput) + token = scanToken(ppToken); + } + if (((macro != nullptr && !macro->undef) ? 1 : 0) != defined) + token = CPPelse(1, ppToken); + } + + return token; +} + +// Handle #include ... +// TODO: Handle macro expansions for the header name +int TPpContext::CPPinclude(TPpToken* ppToken) +{ + const TSourceLoc directiveLoc = ppToken->loc; + bool startWithLocalSearch = true; // to additionally include the extra "" paths + int token = scanToken(ppToken); + + // handle -style #include + if (token == '<') { + startWithLocalSearch = false; + token = scanHeaderName(ppToken, '>'); + } + // otherwise ppToken already has the header name and it was "header-name" style + + if (token != PpAtomConstString) { + parseContext.ppError(directiveLoc, "must be followed by a header name", "#include", ""); + return token; + } + + // Make a copy of the name because it will be overwritten by the next token scan. + const std::string filename = ppToken->name; + + // See if the directive was well formed + token = scanToken(ppToken); + if (token != '\n') { + if (token == EndOfInput) + parseContext.ppError(ppToken->loc, "expected newline after header name:", "#include", "%s", filename.c_str()); + else + parseContext.ppError(ppToken->loc, "extra content after header name:", "#include", "%s", filename.c_str()); + return token; + } + + // Process well-formed directive + + // Find the inclusion, first look in "Local" ("") paths, if requested, + // otherwise, only search the "System" (<>) paths. + TShader::Includer::IncludeResult* res = nullptr; + if (startWithLocalSearch) + res = includer.includeLocal(filename.c_str(), currentSourceFile.c_str(), includeStack.size() + 1); + if (res == nullptr || res->headerName.empty()) { + includer.releaseInclude(res); + res = includer.includeSystem(filename.c_str(), currentSourceFile.c_str(), includeStack.size() + 1); + } + + // Process the results + if (res != nullptr && !res->headerName.empty()) { + if (res->headerData != nullptr && res->headerLength > 0) { + // path for processing one or more tokens from an included header, hand off 'res' + const bool forNextLine = parseContext.lineDirectiveShouldSetNextLine(); + std::ostringstream prologue; + std::ostringstream epilogue; + prologue << "#line " << forNextLine << " " << "\"" << res->headerName << "\"\n"; + epilogue << (res->headerData[res->headerLength - 1] == '\n'? "" : "\n") << + "#line " << directiveLoc.line + forNextLine << " " << directiveLoc.getStringNameOrNum() << "\n"; + pushInput(new TokenizableIncludeFile(directiveLoc, prologue.str(), res, epilogue.str(), this)); + // There's no "current" location anymore. + parseContext.setCurrentColumn(0); + } else { + // things are okay, but there is nothing to process + includer.releaseInclude(res); + } + } else { + // error path, clean up + std::string message = + res != nullptr ? std::string(res->headerData, res->headerLength) + : std::string("Could not process include directive"); + parseContext.ppError(directiveLoc, message.c_str(), "#include", "for header name: %s", filename.c_str()); + includer.releaseInclude(res); + } + + return token; +} + +// Handle #line +int TPpContext::CPPline(TPpToken* ppToken) +{ + // "#line must have, after macro substitution, one of the following forms: + // "#line line + // "#line line source-string-number" + + int token = scanToken(ppToken); + const TSourceLoc directiveLoc = ppToken->loc; + if (token == '\n') { + parseContext.ppError(ppToken->loc, "must by followed by an integral literal", "#line", ""); + return token; + } + + int lineRes = 0; // Line number after macro expansion. + int lineToken = 0; + bool hasFile = false; + int fileRes = 0; // Source file number after macro expansion. + const char* sourceName = nullptr; // Optional source file name. + bool lineErr = false; + bool fileErr = false; + token = eval(token, MIN_PRECEDENCE, false, lineRes, lineErr, ppToken); + if (! lineErr) { + lineToken = lineRes; + if (token == '\n') + ++lineRes; + + if (parseContext.lineDirectiveShouldSetNextLine()) + --lineRes; + parseContext.setCurrentLine(lineRes); + + if (token != '\n') { + if (token == PpAtomConstString) { + parseContext.ppRequireExtensions(directiveLoc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based #line"); + // We need to save a copy of the string instead of pointing + // to the name field of the token since the name field + // will likely be overwritten by the next token scan. + sourceName = atomStrings.getString(atomStrings.getAddAtom(ppToken->name)); + parseContext.setCurrentSourceName(sourceName); + hasFile = true; + token = scanToken(ppToken); + } else { + token = eval(token, MIN_PRECEDENCE, false, fileRes, fileErr, ppToken); + if (! fileErr) { + parseContext.setCurrentString(fileRes); + hasFile = true; + } + } + } + } + if (!fileErr && !lineErr) { + parseContext.notifyLineDirective(directiveLoc.line, lineToken, hasFile, fileRes, sourceName); + } + token = extraTokenCheck(PpAtomLine, ppToken, token); + + return token; +} + +// Handle #error +int TPpContext::CPPerror(TPpToken* ppToken) +{ + int token = scanToken(ppToken); + std::string message; + TSourceLoc loc = ppToken->loc; + + while (token != '\n' && token != EndOfInput) { + if (token == PpAtomConstInt || token == PpAtomConstUint || + token == PpAtomConstInt64 || token == PpAtomConstUint64 || +#ifdef AMD_EXTENSIONS + token == PpAtomConstInt16 || token == PpAtomConstUint16 || + token == PpAtomConstFloat16 || +#endif + token == PpAtomConstFloat || token == PpAtomConstDouble) { + message.append(ppToken->name); + } else if (token == PpAtomIdentifier || token == PpAtomConstString) { + message.append(ppToken->name); + } else { + message.append(atomStrings.getString(token)); + } + message.append(" "); + token = scanToken(ppToken); + } + parseContext.notifyErrorDirective(loc.line, message.c_str()); + // store this msg into the shader's information log..set the Compile Error flag!!!! + parseContext.ppError(loc, message.c_str(), "#error", ""); + + return '\n'; +} + +// Handle #pragma +int TPpContext::CPPpragma(TPpToken* ppToken) +{ + char SrcStrName[2]; + TVector tokens; + + TSourceLoc loc = ppToken->loc; // because we go to the next line before processing + int token = scanToken(ppToken); + while (token != '\n' && token != EndOfInput) { + switch (token) { + case PpAtomIdentifier: + case PpAtomConstInt: + case PpAtomConstUint: + case PpAtomConstInt64: + case PpAtomConstUint64: +#ifdef AMD_EXTENSIONS + case PpAtomConstInt16: + case PpAtomConstUint16: +#endif + case PpAtomConstFloat: + case PpAtomConstDouble: +#ifdef AMD_EXTENSIONS + case PpAtomConstFloat16: +#endif + tokens.push_back(ppToken->name); + break; + default: + SrcStrName[0] = (char)token; + SrcStrName[1] = '\0'; + tokens.push_back(SrcStrName); + } + token = scanToken(ppToken); + } + + if (token == EndOfInput) + parseContext.ppError(loc, "directive must end with a newline", "#pragma", ""); + else + parseContext.handlePragma(loc, tokens); + + return token; +} + +// #version: This is just for error checking: the version and profile are decided before preprocessing starts +int TPpContext::CPPversion(TPpToken* ppToken) +{ + int token = scanToken(ppToken); + + if (errorOnVersion || versionSeen) { + if (parseContext.isReadingHLSL()) + parseContext.ppError(ppToken->loc, "invalid preprocessor command", "#version", ""); + else + parseContext.ppError(ppToken->loc, "must occur first in shader", "#version", ""); + } + versionSeen = true; + + if (token == '\n') { + parseContext.ppError(ppToken->loc, "must be followed by version number", "#version", ""); + + return token; + } + + if (token != PpAtomConstInt) + parseContext.ppError(ppToken->loc, "must be followed by version number", "#version", ""); + + ppToken->ival = atoi(ppToken->name); + int versionNumber = ppToken->ival; + int line = ppToken->loc.line; + token = scanToken(ppToken); + + if (token == '\n') { + parseContext.notifyVersion(line, versionNumber, nullptr); + return token; + } else { + int profileAtom = atomStrings.getAtom(ppToken->name); + if (profileAtom != PpAtomCore && + profileAtom != PpAtomCompatibility && + profileAtom != PpAtomEs) + parseContext.ppError(ppToken->loc, "bad profile name; use es, core, or compatibility", "#version", ""); + parseContext.notifyVersion(line, versionNumber, ppToken->name); + token = scanToken(ppToken); + + if (token == '\n') + return token; + else + parseContext.ppError(ppToken->loc, "bad tokens following profile -- expected newline", "#version", ""); + } + + return token; +} + +// Handle #extension +int TPpContext::CPPextension(TPpToken* ppToken) +{ + int line = ppToken->loc.line; + int token = scanToken(ppToken); + char extensionName[MaxTokenLength + 1]; + + if (token=='\n') { + parseContext.ppError(ppToken->loc, "extension name not specified", "#extension", ""); + return token; + } + + if (token != PpAtomIdentifier) + parseContext.ppError(ppToken->loc, "extension name expected", "#extension", ""); + + assert(strlen(ppToken->name) <= MaxTokenLength); + strcpy(extensionName, ppToken->name); + + token = scanToken(ppToken); + if (token != ':') { + parseContext.ppError(ppToken->loc, "':' missing after extension name", "#extension", ""); + return token; + } + + token = scanToken(ppToken); + if (token != PpAtomIdentifier) { + parseContext.ppError(ppToken->loc, "behavior for extension not specified", "#extension", ""); + return token; + } + + parseContext.updateExtensionBehavior(line, extensionName, ppToken->name); + parseContext.notifyExtensionDirective(line, extensionName, ppToken->name); + + token = scanToken(ppToken); + if (token == '\n') + return token; + else + parseContext.ppError(ppToken->loc, "extra tokens -- expected newline", "#extension",""); + + return token; +} + +int TPpContext::readCPPline(TPpToken* ppToken) +{ + int token = scanToken(ppToken); + + if (token == PpAtomIdentifier) { + switch (atomStrings.getAtom(ppToken->name)) { + case PpAtomDefine: + token = CPPdefine(ppToken); + break; + case PpAtomElse: + if (elseSeen[elsetracker]) + parseContext.ppError(ppToken->loc, "#else after #else", "#else", ""); + elseSeen[elsetracker] = true; + if (ifdepth == 0) + parseContext.ppError(ppToken->loc, "mismatched statements", "#else", ""); + token = extraTokenCheck(PpAtomElse, ppToken, scanToken(ppToken)); + token = CPPelse(0, ppToken); + break; + case PpAtomElif: + if (ifdepth == 0) + parseContext.ppError(ppToken->loc, "mismatched statements", "#elif", ""); + if (elseSeen[elsetracker]) + parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", ""); + // this token is really a dont care, but we still need to eat the tokens + token = scanToken(ppToken); + while (token != '\n' && token != EndOfInput) + token = scanToken(ppToken); + token = CPPelse(0, ppToken); + break; + case PpAtomEndif: + if (ifdepth == 0) + parseContext.ppError(ppToken->loc, "mismatched statements", "#endif", ""); + else { + elseSeen[elsetracker] = false; + --elsetracker; + --ifdepth; + } + token = extraTokenCheck(PpAtomEndif, ppToken, scanToken(ppToken)); + break; + case PpAtomIf: + token = CPPif(ppToken); + break; + case PpAtomIfdef: + token = CPPifdef(1, ppToken); + break; + case PpAtomIfndef: + token = CPPifdef(0, ppToken); + break; + case PpAtomInclude: + if(!parseContext.isReadingHLSL()) { + parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_include_directive, "#include"); + } + token = CPPinclude(ppToken); + break; + case PpAtomLine: + token = CPPline(ppToken); + break; + case PpAtomPragma: + token = CPPpragma(ppToken); + break; + case PpAtomUndef: + token = CPPundef(ppToken); + break; + case PpAtomError: + token = CPPerror(ppToken); + break; + case PpAtomVersion: + token = CPPversion(ppToken); + break; + case PpAtomExtension: + token = CPPextension(ppToken); + break; + default: + parseContext.ppError(ppToken->loc, "invalid directive:", "#", ppToken->name); + break; + } + } else if (token != '\n' && token != EndOfInput) + parseContext.ppError(ppToken->loc, "invalid directive", "#", ""); + + while (token != '\n' && token != EndOfInput) + token = scanToken(ppToken); + + return token; +} + +// Context-dependent parsing of a #include . +// Assumes no macro expansions etc. are being done; the name is just on the current input. +// Always creates a name and returns PpAtomicConstString, unless we run out of input. +int TPpContext::scanHeaderName(TPpToken* ppToken, char delimit) +{ + bool tooLong = false; + + if (inputStack.empty()) + return EndOfInput; + + int len = 0; + ppToken->name[0] = '\0'; + do { + int ch = inputStack.back()->getch(); + + // done yet? + if (ch == delimit) { + ppToken->name[len] = '\0'; + if (tooLong) + parseContext.ppError(ppToken->loc, "header name too long", "", ""); + return PpAtomConstString; + } else if (ch == EndOfInput) + return EndOfInput; + + // found a character to expand the name with + if (len < MaxTokenLength) + ppToken->name[len++] = (char)ch; + else + tooLong = true; + } while (true); +} + +// Macro-expand a macro argument 'arg' to create 'expandedArg'. +// Does not replace 'arg'. +// Returns nullptr if no expanded argument is created. +TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream& arg, TPpToken* ppToken, bool newLineOkay) +{ + // expand the argument + TokenStream* expandedArg = new TokenStream; + pushInput(new tMarkerInput(this)); + pushTokenStreamInput(arg); + int token; + while ((token = scanToken(ppToken)) != tMarkerInput::marker && token != EndOfInput) { + token = tokenPaste(token, *ppToken); + if (token == tMarkerInput::marker || token == EndOfInput) + break; + if (token == PpAtomIdentifier && MacroExpand(ppToken, false, newLineOkay) != 0) + continue; + expandedArg->putToken(token, ppToken); + } + + if (token == EndOfInput) { + // MacroExpand ate the marker, so had bad input, recover + delete expandedArg; + expandedArg = nullptr; + } else { + // remove the marker + popInput(); + } + + return expandedArg; +} + +// +// Return the next token for a macro expansion, handling macro arguments, +// whose semantics are dependent on being adjacent to ##. +// +int TPpContext::tMacroInput::scan(TPpToken* ppToken) +{ + int token; + do { + token = mac->body.getToken(pp->parseContext, ppToken); + } while (token == ' '); // handle white space in macro + + // Hash operators basically turn off a round of macro substitution + // (the round done on the argument before the round done on the RHS of the + // macro definition): + // + // "A parameter in the replacement list, unless preceded by a # or ## + // preprocessing token or followed by a ## preprocessing token (see below), + // is replaced by the corresponding argument after all macros contained + // therein have been expanded." + // + // "If, in the replacement list, a parameter is immediately preceded or + // followed by a ## preprocessing token, the parameter is replaced by the + // corresponding argument's preprocessing token sequence." + + bool pasting = false; + if (postpaste) { + // don't expand next token + pasting = true; + postpaste = false; + } + + if (prepaste) { + // already know we should be on a ##, verify + assert(token == PpAtomPaste); + prepaste = false; + postpaste = true; + } + + // see if are preceding a ## + if (mac->body.peekUntokenizedPasting()) { + prepaste = true; + pasting = true; + } + + // HLSL does expand macros before concatenation + if (pasting && pp->parseContext.isReadingHLSL()) + pasting = false; + + // TODO: preprocessor: properly handle whitespace (or lack of it) between tokens when expanding + if (token == PpAtomIdentifier) { + int i; + for (i = (int)mac->args.size() - 1; i >= 0; i--) + if (strcmp(pp->atomStrings.getString(mac->args[i]), ppToken->name) == 0) + break; + if (i >= 0) { + TokenStream* arg = expandedArgs[i]; + if (arg == nullptr || pasting) + arg = args[i]; + pp->pushTokenStreamInput(*arg, prepaste); + + return pp->scanToken(ppToken); + } + } + + if (token == EndOfInput) + mac->busy = 0; + + return token; +} + +// return a textual zero, for scanning a macro that was never defined +int TPpContext::tZeroInput::scan(TPpToken* ppToken) +{ + if (done) + return EndOfInput; + + strcpy(ppToken->name, "0"); + ppToken->ival = 0; + ppToken->space = false; + done = true; + + return PpAtomConstInt; +} + +// +// Check a token to see if it is a macro that should be expanded. +// If it is, and defined, push a tInput that will produce the appropriate expansion +// and return 1. +// If it is, but undefined, and expandUndef is requested, push a tInput that will +// expand to 0 and return -1. +// Otherwise, return 0 to indicate no expansion, which is not necessarily an error. +// +int TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOkay) +{ + ppToken->space = false; + int macroAtom = atomStrings.getAtom(ppToken->name); + switch (macroAtom) { + case PpAtomLineMacro: + ppToken->ival = parseContext.getCurrentLoc().line; + snprintf(ppToken->name, sizeof(ppToken->name), "%d", ppToken->ival); + UngetToken(PpAtomConstInt, ppToken); + return 1; + + case PpAtomFileMacro: { + if (parseContext.getCurrentLoc().name) + parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based __FILE__"); + ppToken->ival = parseContext.getCurrentLoc().string; + snprintf(ppToken->name, sizeof(ppToken->name), "%s", ppToken->loc.getStringNameOrNum().c_str()); + UngetToken(PpAtomConstInt, ppToken); + return 1; + } + + case PpAtomVersionMacro: + ppToken->ival = parseContext.version; + snprintf(ppToken->name, sizeof(ppToken->name), "%d", ppToken->ival); + UngetToken(PpAtomConstInt, ppToken); + return 1; + + default: + break; + } + + MacroSymbol* macro = macroAtom == 0 ? nullptr : lookupMacroDef(macroAtom); + int depth = 0; + + // no recursive expansions + if (macro != nullptr && macro->busy) + return 0; + + // not expanding undefined macros + if ((macro == nullptr || macro->undef) && ! expandUndef) + return 0; + + // 0 is the value of an undefined macro + if ((macro == nullptr || macro->undef) && expandUndef) { + pushInput(new tZeroInput(this)); + return -1; + } + + tMacroInput *in = new tMacroInput(this); + + TSourceLoc loc = ppToken->loc; // in case we go to the next line before discovering the error + in->mac = macro; + if (macro->args.size() > 0 || macro->emptyArgs) { + int token = scanToken(ppToken); + if (newLineOkay) { + while (token == '\n') + token = scanToken(ppToken); + } + if (token != '(') { + UngetToken(token, ppToken); + delete in; + return 0; + } + in->args.resize(in->mac->args.size()); + for (size_t i = 0; i < in->mac->args.size(); i++) + in->args[i] = new TokenStream; + in->expandedArgs.resize(in->mac->args.size()); + for (size_t i = 0; i < in->mac->args.size(); i++) + in->expandedArgs[i] = nullptr; + size_t arg = 0; + bool tokenRecorded = false; + do { + depth = 0; + while (1) { + token = scanToken(ppToken); + if (token == EndOfInput || token == tMarkerInput::marker) { + parseContext.ppError(loc, "End of input in macro", "macro expansion", atomStrings.getString(macroAtom)); + delete in; + return 0; + } + if (token == '\n') { + if (! newLineOkay) { + parseContext.ppError(loc, "End of line in macro substitution:", "macro expansion", atomStrings.getString(macroAtom)); + delete in; + return 0; + } + continue; + } + if (token == '#') { + parseContext.ppError(ppToken->loc, "unexpected '#'", "macro expansion", atomStrings.getString(macroAtom)); + delete in; + return 0; + } + if (in->mac->args.size() == 0 && token != ')') + break; + if (depth == 0 && (token == ',' || token == ')')) + break; + if (token == '(') + depth++; + if (token == ')') + depth--; + in->args[arg]->putToken(token, ppToken); + tokenRecorded = true; + } + if (token == ')') { + if (in->mac->args.size() == 1 && tokenRecorded == 0) + break; + arg++; + break; + } + arg++; + } while (arg < in->mac->args.size()); + + if (arg < in->mac->args.size()) + parseContext.ppError(loc, "Too few args in Macro", "macro expansion", atomStrings.getString(macroAtom)); + else if (token != ')') { + depth=0; + while (token != EndOfInput && (depth > 0 || token != ')')) { + if (token == ')') + depth--; + token = scanToken(ppToken); + if (token == '(') + depth++; + } + + if (token == EndOfInput) { + parseContext.ppError(loc, "End of input in macro", "macro expansion", atomStrings.getString(macroAtom)); + delete in; + return 0; + } + parseContext.ppError(loc, "Too many args in macro", "macro expansion", atomStrings.getString(macroAtom)); + } + + // We need both expanded and non-expanded forms of the argument, for whether or + // not token pasting will be applied later when the argument is consumed next to ##. + for (size_t i = 0; i < in->mac->args.size(); i++) + in->expandedArgs[i] = PrescanMacroArg(*in->args[i], ppToken, newLineOkay); + } + + pushInput(in); + macro->busy = 1; + macro->body.reset(); + + return 1; +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpAtom.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpAtom.cpp new file mode 100644 index 00000000..06c2333e --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpAtom.cpp @@ -0,0 +1,181 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2013 LunarG, Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +/****************************************************************************\ +Copyright (c) 2002, NVIDIA Corporation. + +NVIDIA Corporation("NVIDIA") supplies this software to you in +consideration of your agreement to the following terms, and your use, +installation, modification or redistribution of this NVIDIA software +constitutes acceptance of these terms. If you do not agree with these +terms, please do not use, install, modify or redistribute this NVIDIA +software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, NVIDIA grants you a personal, non-exclusive +license, under NVIDIA's copyrights in this original NVIDIA software (the +"NVIDIA Software"), to use, reproduce, modify and redistribute the +NVIDIA Software, with or without modifications, in source and/or binary +forms; provided that if you redistribute the NVIDIA Software, you must +retain the copyright notice of NVIDIA, this notice and the following +text and disclaimers in all such redistributions of the NVIDIA Software. +Neither the name, trademarks, service marks nor logos of NVIDIA +Corporation may be used to endorse or promote products derived from the +NVIDIA Software without specific prior written permission from NVIDIA. +Except as expressly stated in this notice, no other rights or licenses +express or implied, are granted by NVIDIA herein, including but not +limited to any patent rights that may be infringed by your derivative +works or by other works in which the NVIDIA Software may be +incorporated. No hardware is licensed hereunder. + +THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, +INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR +ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER +PRODUCTS. + +IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, +INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY +OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE +NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, +TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF +NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\****************************************************************************/ + +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include +#include +#include + +#include "PpContext.h" +#include "PpTokens.h" + +namespace { + +using namespace glslang; + +const struct { + int val; + const char* str; +} tokens[] = { + + { PPAtomAddAssign, "+=" }, + { PPAtomSubAssign, "-=" }, + { PPAtomMulAssign, "*=" }, + { PPAtomDivAssign, "/=" }, + { PPAtomModAssign, "%=" }, + + { PpAtomRight, ">>" }, + { PpAtomLeft, "<<" }, + { PpAtomAnd, "&&" }, + { PpAtomOr, "||" }, + { PpAtomXor, "^^" }, + + { PpAtomRightAssign, ">>=" }, + { PpAtomLeftAssign, "<<=" }, + { PpAtomAndAssign, "&=" }, + { PpAtomOrAssign, "|=" }, + { PpAtomXorAssign, "^=" }, + + { PpAtomEQ, "==" }, + { PpAtomNE, "!=" }, + { PpAtomGE, ">=" }, + { PpAtomLE, "<=" }, + + { PpAtomDecrement, "--" }, + { PpAtomIncrement, "++" }, + + { PpAtomColonColon, "::" }, + + { PpAtomDefine, "define" }, + { PpAtomUndef, "undef" }, + { PpAtomIf, "if" }, + { PpAtomElif, "elif" }, + { PpAtomElse, "else" }, + { PpAtomEndif, "endif" }, + { PpAtomIfdef, "ifdef" }, + { PpAtomIfndef, "ifndef" }, + { PpAtomLine, "line" }, + { PpAtomPragma, "pragma" }, + { PpAtomError, "error" }, + + { PpAtomVersion, "version" }, + { PpAtomCore, "core" }, + { PpAtomCompatibility, "compatibility" }, + { PpAtomEs, "es" }, + { PpAtomExtension, "extension" }, + + { PpAtomLineMacro, "__LINE__" }, + { PpAtomFileMacro, "__FILE__" }, + { PpAtomVersionMacro, "__VERSION__" }, + + { PpAtomInclude, "include" }, +}; + +} // end anonymous namespace + +namespace glslang { + +// +// Initialize the atom table. +// +TStringAtomMap::TStringAtomMap() +{ + badToken.assign(""); + + // Add single character tokens to the atom table: + const char* s = "~!%^&*()-+=|,.<>/?;:[]{}#\\"; + char t[2]; + + t[1] = '\0'; + while (*s) { + t[0] = *s; + addAtomFixed(t, s[0]); + s++; + } + + // Add multiple character scanner tokens : + for (size_t ii = 0; ii < sizeof(tokens)/sizeof(tokens[0]); ii++) + addAtomFixed(tokens[ii].str, tokens[ii].val); + + nextAtom = PpAtomLast; +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp new file mode 100644 index 00000000..6a2e05fe --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp @@ -0,0 +1,115 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2013 LunarG, Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +/****************************************************************************\ +Copyright (c) 2002, NVIDIA Corporation. + +NVIDIA Corporation("NVIDIA") supplies this software to you in +consideration of your agreement to the following terms, and your use, +installation, modification or redistribution of this NVIDIA software +constitutes acceptance of these terms. If you do not agree with these +terms, please do not use, install, modify or redistribute this NVIDIA +software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, NVIDIA grants you a personal, non-exclusive +license, under NVIDIA's copyrights in this original NVIDIA software (the +"NVIDIA Software"), to use, reproduce, modify and redistribute the +NVIDIA Software, with or without modifications, in source and/or binary +forms; provided that if you redistribute the NVIDIA Software, you must +retain the copyright notice of NVIDIA, this notice and the following +text and disclaimers in all such redistributions of the NVIDIA Software. +Neither the name, trademarks, service marks nor logos of NVIDIA +Corporation may be used to endorse or promote products derived from the +NVIDIA Software without specific prior written permission from NVIDIA. +Except as expressly stated in this notice, no other rights or licenses +express or implied, are granted by NVIDIA herein, including but not +limited to any patent rights that may be infringed by your derivative +works or by other works in which the NVIDIA Software may be +incorporated. No hardware is licensed hereunder. + +THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, +INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR +ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER +PRODUCTS. + +IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, +INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY +OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE +NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, +TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF +NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\****************************************************************************/ + +#include + +#include "PpContext.h" + +namespace glslang { + +TPpContext::TPpContext(TParseContextBase& pc, const std::string& rootFileName, TShader::Includer& inclr) : + preamble(0), strings(0), previous_token('\n'), parseContext(pc), includer(inclr), inComment(false), + rootFileName(rootFileName), + currentSourceFile(rootFileName) +{ + ifdepth = 0; + for (elsetracker = 0; elsetracker < maxIfNesting; elsetracker++) + elseSeen[elsetracker] = false; + elsetracker = 0; +} + +TPpContext::~TPpContext() +{ + delete [] preamble; + + // free up the inputStack + while (! inputStack.empty()) + popInput(); +} + +void TPpContext::setInput(TInputScanner& input, bool versionWillBeError) +{ + assert(inputStack.size() == 0); + + pushInput(new tStringInput(this, input)); + + errorOnVersion = versionWillBeError; + versionSeen = false; +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.h b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.h new file mode 100644 index 00000000..854bbbad --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.h @@ -0,0 +1,622 @@ +// +// Copyright (C) 2013 LunarG, Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +/****************************************************************************\ +Copyright (c) 2002, NVIDIA Corporation. + +NVIDIA Corporation("NVIDIA") supplies this software to you in +consideration of your agreement to the following terms, and your use, +installation, modification or redistribution of this NVIDIA software +constitutes acceptance of these terms. If you do not agree with these +terms, please do not use, install, modify or redistribute this NVIDIA +software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, NVIDIA grants you a personal, non-exclusive +license, under NVIDIA's copyrights in this original NVIDIA software (the +"NVIDIA Software"), to use, reproduce, modify and redistribute the +NVIDIA Software, with or without modifications, in source and/or binary +forms; provided that if you redistribute the NVIDIA Software, you must +retain the copyright notice of NVIDIA, this notice and the following +text and disclaimers in all such redistributions of the NVIDIA Software. +Neither the name, trademarks, service marks nor logos of NVIDIA +Corporation may be used to endorse or promote products derived from the +NVIDIA Software without specific prior written permission from NVIDIA. +Except as expressly stated in this notice, no other rights or licenses +express or implied, are granted by NVIDIA herein, including but not +limited to any patent rights that may be infringed by your derivative +works or by other works in which the NVIDIA Software may be +incorporated. No hardware is licensed hereunder. + +THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, +INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR +ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER +PRODUCTS. + +IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, +INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY +OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE +NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, +TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF +NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\****************************************************************************/ + +#ifndef PPCONTEXT_H +#define PPCONTEXT_H + +#include +#include + +#include "../ParseHelper.h" + +/* windows only pragma */ +#ifdef _MSC_VER + #pragma warning(disable : 4127) +#endif + +namespace glslang { + +class TPpToken { +public: + TPpToken() : space(false), i64val(0) + { + loc.init(); + name[0] = 0; + } + + // This is used for comparing macro definitions, so checks what is relevant for that. + bool operator==(const TPpToken& right) + { + return space == right.space && + ival == right.ival && dval == right.dval && i64val == right.i64val && + strncmp(name, right.name, MaxTokenLength) == 0; + } + bool operator!=(const TPpToken& right) { return ! operator==(right); } + + TSourceLoc loc; + bool space; // true if a space (for white space or a removed comment) should also be recognized, in front of the token returned + + union { + int ival; + double dval; + long long i64val; + }; + + char name[MaxTokenLength + 1]; +}; + +class TStringAtomMap { +// +// Implementation is in PpAtom.cpp +// +// Maintain a bi-directional mapping between relevant preprocessor strings and +// "atoms" which a unique integers (small, contiguous, not hash-like) per string. +// +public: + TStringAtomMap(); + + // Map string -> atom. + // Return 0 if no existing string. + int getAtom(const char* s) const + { + auto it = atomMap.find(s); + return it == atomMap.end() ? 0 : it->second; + } + + // Map a new or existing string -> atom, inventing a new atom if necessary. + int getAddAtom(const char* s) + { + int atom = getAtom(s); + if (atom == 0) { + atom = nextAtom++; + addAtomFixed(s, atom); + } + return atom; + } + + // Map atom -> string. + const char* getString(int atom) const { return stringMap[atom]->c_str(); } + +protected: + TStringAtomMap(TStringAtomMap&); + TStringAtomMap& operator=(TStringAtomMap&); + + TUnorderedMap atomMap; + TVector stringMap; // these point into the TString in atomMap + int nextAtom; + + // Bad source characters can lead to bad atoms, so gracefully handle those by + // pre-filling the table with them (to avoid if tests later). + TString badToken; + + // Add bi-directional mappings: + // - string -> atom + // - atom -> string + void addAtomFixed(const char* s, int atom) + { + auto it = atomMap.insert(std::pair(s, atom)).first; + if (stringMap.size() < (size_t)atom + 1) + stringMap.resize(atom + 100, &badToken); + stringMap[atom] = &it->first; + } +}; + +class TInputScanner; + +// This class is the result of turning a huge pile of C code communicating through globals +// into a class. This was done to allowing instancing to attain thread safety. +// Don't expect too much in terms of OO design. +class TPpContext { +public: + TPpContext(TParseContextBase&, const std::string& rootFileName, TShader::Includer&); + virtual ~TPpContext(); + + void setPreamble(const char* preamble, size_t length); + + int tokenize(TPpToken& ppToken); + int tokenPaste(int token, TPpToken&); + + class tInput { + public: + tInput(TPpContext* p) : done(false), pp(p) { } + virtual ~tInput() { } + + virtual int scan(TPpToken*) = 0; + virtual int getch() = 0; + virtual void ungetch() = 0; + virtual bool peekPasting() { return false; } // true when about to see ## + virtual bool endOfReplacementList() { return false; } // true when at the end of a macro replacement list (RHS of #define) + virtual bool isMacroInput() { return false; } + + // Will be called when we start reading tokens from this instance + virtual void notifyActivated() {} + // Will be called when we do not read tokens from this instance anymore + virtual void notifyDeleted() {} + protected: + bool done; + TPpContext* pp; + }; + + void setInput(TInputScanner& input, bool versionWillBeError); + + void pushInput(tInput* in) + { + inputStack.push_back(in); + in->notifyActivated(); + } + void popInput() + { + inputStack.back()->notifyDeleted(); + delete inputStack.back(); + inputStack.pop_back(); + } + + // + // From PpTokens.cpp + // + + class TokenStream { + public: + TokenStream() : current(0) { } + + void putToken(int token, TPpToken* ppToken); + int getToken(TParseContextBase&, TPpToken*); + bool atEnd() { return current >= data.size(); } + bool peekTokenizedPasting(bool lastTokenPastes); + bool peekUntokenizedPasting(); + void reset() { current = 0; } + + protected: + void putSubtoken(char); + int getSubtoken(); + void ungetSubtoken(); + + TVector data; + size_t current; + }; + + // + // From Pp.cpp + // + + struct MacroSymbol { + MacroSymbol() : emptyArgs(0), busy(0), undef(0) { } + TVector args; + TokenStream body; + unsigned emptyArgs : 1; + unsigned busy : 1; + unsigned undef : 1; + }; + + typedef TMap TSymbolMap; + TSymbolMap macroDefs; // map atoms to macro definitions + MacroSymbol* lookupMacroDef(int atom) + { + auto existingMacroIt = macroDefs.find(atom); + return (existingMacroIt == macroDefs.end()) ? nullptr : &(existingMacroIt->second); + } + void addMacroDef(int atom, MacroSymbol& macroDef) { macroDefs[atom] = macroDef; } + +protected: + TPpContext(TPpContext&); + TPpContext& operator=(TPpContext&); + + TStringAtomMap atomStrings; + char* preamble; // string to parse, all before line 1 of string 0, it is 0 if no preamble + int preambleLength; + char** strings; // official strings of shader, starting a string 0 line 1 + size_t* lengths; + int numStrings; // how many official strings there are + int currentString; // which string we're currently parsing (-1 for preamble) + + // Scanner data: + int previous_token; + TParseContextBase& parseContext; + + // Get the next token from *stack* of input sources, popping input sources + // that are out of tokens, down until an input source is found that has a token. + // Return EndOfInput when there are no more tokens to be found by doing this. + int scanToken(TPpToken* ppToken) + { + int token = EndOfInput; + + while (! inputStack.empty()) { + token = inputStack.back()->scan(ppToken); + if (token != EndOfInput || inputStack.empty()) + break; + popInput(); + } + + return token; + } + int getChar() { return inputStack.back()->getch(); } + void ungetChar() { inputStack.back()->ungetch(); } + bool peekPasting() { return !inputStack.empty() && inputStack.back()->peekPasting(); } + bool endOfReplacementList() { return inputStack.empty() || inputStack.back()->endOfReplacementList(); } + bool isMacroInput() { return inputStack.size() > 0 && inputStack.back()->isMacroInput(); } + + static const int maxIfNesting = 65; + + int ifdepth; // current #if-#else-#endif nesting in the cpp.c file (pre-processor) + bool elseSeen[maxIfNesting]; // Keep a track of whether an else has been seen at a particular depth + int elsetracker; // #if-#else and #endif constructs...Counter. + + class tMacroInput : public tInput { + public: + tMacroInput(TPpContext* pp) : tInput(pp), prepaste(false), postpaste(false) { } + virtual ~tMacroInput() + { + for (size_t i = 0; i < args.size(); ++i) + delete args[i]; + for (size_t i = 0; i < expandedArgs.size(); ++i) + delete expandedArgs[i]; + } + + virtual int scan(TPpToken*) override; + virtual int getch() override { assert(0); return EndOfInput; } + virtual void ungetch() override { assert(0); } + bool peekPasting() override { return prepaste; } + bool endOfReplacementList() override { return mac->body.atEnd(); } + bool isMacroInput() override { return true; } + + MacroSymbol *mac; + TVector args; + TVector expandedArgs; + + protected: + bool prepaste; // true if we are just before ## + bool postpaste; // true if we are right after ## + }; + + class tMarkerInput : public tInput { + public: + tMarkerInput(TPpContext* pp) : tInput(pp) { } + virtual int scan(TPpToken*) override + { + if (done) + return EndOfInput; + done = true; + + return marker; + } + virtual int getch() override { assert(0); return EndOfInput; } + virtual void ungetch() override { assert(0); } + static const int marker = -3; + }; + + class tZeroInput : public tInput { + public: + tZeroInput(TPpContext* pp) : tInput(pp) { } + virtual int scan(TPpToken*) override; + virtual int getch() override { assert(0); return EndOfInput; } + virtual void ungetch() override { assert(0); } + }; + + std::vector inputStack; + bool errorOnVersion; + bool versionSeen; + + // + // from Pp.cpp + // + + // Used to obtain #include content. + TShader::Includer& includer; + + int CPPdefine(TPpToken * ppToken); + int CPPundef(TPpToken * ppToken); + int CPPelse(int matchelse, TPpToken * ppToken); + int extraTokenCheck(int atom, TPpToken* ppToken, int token); + int eval(int token, int precedence, bool shortCircuit, int& res, bool& err, TPpToken * ppToken); + int evalToToken(int token, bool shortCircuit, int& res, bool& err, TPpToken * ppToken); + int CPPif (TPpToken * ppToken); + int CPPifdef(int defined, TPpToken * ppToken); + int CPPinclude(TPpToken * ppToken); + int CPPline(TPpToken * ppToken); + int CPPerror(TPpToken * ppToken); + int CPPpragma(TPpToken * ppToken); + int CPPversion(TPpToken * ppToken); + int CPPextension(TPpToken * ppToken); + int readCPPline(TPpToken * ppToken); + int scanHeaderName(TPpToken* ppToken, char delimit); + TokenStream* PrescanMacroArg(TokenStream&, TPpToken*, bool newLineOkay); + int MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOkay); + + // + // From PpTokens.cpp + // + void pushTokenStreamInput(TokenStream&, bool pasting = false); + void UngetToken(int token, TPpToken*); + + class tTokenInput : public tInput { + public: + tTokenInput(TPpContext* pp, TokenStream* t, bool prepasting) : tInput(pp), tokens(t), lastTokenPastes(prepasting) { } + virtual int scan(TPpToken *ppToken) override { return tokens->getToken(pp->parseContext, ppToken); } + virtual int getch() override { assert(0); return EndOfInput; } + virtual void ungetch() override { assert(0); } + virtual bool peekPasting() override { return tokens->peekTokenizedPasting(lastTokenPastes); } + protected: + TokenStream* tokens; + bool lastTokenPastes; // true if the last token in the input is to be pasted, rather than consumed as a token + }; + + class tUngotTokenInput : public tInput { + public: + tUngotTokenInput(TPpContext* pp, int t, TPpToken* p) : tInput(pp), token(t), lval(*p) { } + virtual int scan(TPpToken *) override; + virtual int getch() override { assert(0); return EndOfInput; } + virtual void ungetch() override { assert(0); } + protected: + int token; + TPpToken lval; + }; + + // + // From PpScanner.cpp + // + class tStringInput : public tInput { + public: + tStringInput(TPpContext* pp, TInputScanner& i) : tInput(pp), input(&i) { } + virtual int scan(TPpToken*) override; + + // Scanner used to get source stream characters. + // - Escaped newlines are handled here, invisibly to the caller. + // - All forms of newline are handled, and turned into just a '\n'. + int getch() override + { + int ch = input->get(); + + if (ch == '\\') { + // Move past escaped newlines, as many as sequentially exist + do { + if (input->peek() == '\r' || input->peek() == '\n') { + bool allowed = pp->parseContext.lineContinuationCheck(input->getSourceLoc(), pp->inComment); + if (! allowed && pp->inComment) + return '\\'; + + // escape one newline now + ch = input->get(); + int nextch = input->get(); + if (ch == '\r' && nextch == '\n') + ch = input->get(); + else + ch = nextch; + } else + return '\\'; + } while (ch == '\\'); + } + + // handle any non-escaped newline + if (ch == '\r' || ch == '\n') { + if (ch == '\r' && input->peek() == '\n') + input->get(); + return '\n'; + } + + return ch; + } + + // Scanner used to backup the source stream characters. Newlines are + // handled here, invisibly to the caller, meaning have to undo exactly + // what getch() above does (e.g., don't leave things in the middle of a + // sequence of escaped newlines). + void ungetch() override + { + input->unget(); + + do { + int ch = input->peek(); + if (ch == '\r' || ch == '\n') { + if (ch == '\n') { + // correct for two-character newline + input->unget(); + if (input->peek() != '\r') + input->get(); + } + // now in front of a complete newline, move past an escape character + input->unget(); + if (input->peek() == '\\') + input->unget(); + else { + input->get(); + break; + } + } else + break; + } while (true); + } + + protected: + TInputScanner* input; + }; + + // Holds a reference to included file data, as well as a + // prologue and an epilogue string. This can be scanned using the tInput + // interface and acts as a single source string. + class TokenizableIncludeFile : public tInput { + public: + // Copies prologue and epilogue. The includedFile must remain valid + // until this TokenizableIncludeFile is no longer used. + TokenizableIncludeFile(const TSourceLoc& startLoc, + const std::string& prologue, + TShader::Includer::IncludeResult* includedFile, + const std::string& epilogue, + TPpContext* pp) + : tInput(pp), + prologue_(prologue), + epilogue_(epilogue), + includedFile_(includedFile), + scanner(3, strings, lengths, names, 0, 0, true), + prevScanner(nullptr), + stringInput(pp, scanner) + { + strings[0] = prologue_.data(); + strings[1] = includedFile_->headerData; + strings[2] = epilogue_.data(); + + lengths[0] = prologue_.size(); + lengths[1] = includedFile_->headerLength; + lengths[2] = epilogue_.size(); + + scanner.setLine(startLoc.line); + scanner.setString(startLoc.string); + + scanner.setFile(startLoc.name, 0); + scanner.setFile(startLoc.name, 1); + scanner.setFile(startLoc.name, 2); + } + + // tInput methods: + int scan(TPpToken* t) override { return stringInput.scan(t); } + int getch() override { return stringInput.getch(); } + void ungetch() override { stringInput.ungetch(); } + + void notifyActivated() override + { + prevScanner = pp->parseContext.getScanner(); + pp->parseContext.setScanner(&scanner); + pp->push_include(includedFile_); + } + + void notifyDeleted() override + { + pp->parseContext.setScanner(prevScanner); + pp->pop_include(); + } + + private: + TokenizableIncludeFile& operator=(const TokenizableIncludeFile&); + + // Stores the prologue for this string. + const std::string prologue_; + + // Stores the epilogue for this string. + const std::string epilogue_; + + // Points to the IncludeResult that this TokenizableIncludeFile represents. + TShader::Includer::IncludeResult* includedFile_; + + // Will point to prologue_, includedFile_->headerData and epilogue_ + // This is passed to scanner constructor. + // These do not own the storage and it must remain valid until this + // object has been destroyed. + const char* strings[3]; + // Length of str_, passed to scanner constructor. + size_t lengths[3]; + // String names + const char* names[3]; + // Scans over str_. + TInputScanner scanner; + // The previous effective scanner before the scanner in this instance + // has been activated. + TInputScanner* prevScanner; + // Delegate object implementing the tInput interface. + tStringInput stringInput; + }; + + int ScanFromString(char* s); + void missingEndifCheck(); + int lFloatConst(int len, int ch, TPpToken* ppToken); + int characterLiteral(TPpToken* ppToken); + + void push_include(TShader::Includer::IncludeResult* result) + { + currentSourceFile = result->headerName; + includeStack.push(result); + } + + void pop_include() + { + TShader::Includer::IncludeResult* include = includeStack.top(); + includeStack.pop(); + includer.releaseInclude(include); + if (includeStack.empty()) { + currentSourceFile = rootFileName; + } else { + currentSourceFile = includeStack.top()->headerName; + } + } + + bool inComment; + std::string rootFileName; + std::stack includeStack; + std::string currentSourceFile; +}; + +} // end namespace glslang + +#endif // PPCONTEXT_H diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp new file mode 100644 index 00000000..b58bbeea --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp @@ -0,0 +1,1082 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2013 LunarG, Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +/****************************************************************************\ +Copyright (c) 2002, NVIDIA Corporation. + +NVIDIA Corporation("NVIDIA") supplies this software to you in +consideration of your agreement to the following terms, and your use, +installation, modification or redistribution of this NVIDIA software +constitutes acceptance of these terms. If you do not agree with these +terms, please do not use, install, modify or redistribute this NVIDIA +software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, NVIDIA grants you a personal, non-exclusive +license, under NVIDIA's copyrights in this original NVIDIA software (the +"NVIDIA Software"), to use, reproduce, modify and redistribute the +NVIDIA Software, with or without modifications, in source and/or binary +forms; provided that if you redistribute the NVIDIA Software, you must +retain the copyright notice of NVIDIA, this notice and the following +text and disclaimers in all such redistributions of the NVIDIA Software. +Neither the name, trademarks, service marks nor logos of NVIDIA +Corporation may be used to endorse or promote products derived from the +NVIDIA Software without specific prior written permission from NVIDIA. +Except as expressly stated in this notice, no other rights or licenses +express or implied, are granted by NVIDIA herein, including but not +limited to any patent rights that may be infringed by your derivative +works or by other works in which the NVIDIA Software may be +incorporated. No hardware is licensed hereunder. + +THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, +INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR +ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER +PRODUCTS. + +IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, +INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY +OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE +NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, +TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF +NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\****************************************************************************/ + +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include +#include + +#include "PpContext.h" +#include "PpTokens.h" +#include "../Scan.h" + +namespace glslang { + +/////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////// Floating point constants: ///////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////// + +/* +* lFloatConst() - Scan a single- or double-precision floating point constant. Assumes that the scanner +* has seen at least one digit, followed by either a decimal '.' or the +* letter 'e', or a precision ending (e.g., F or LF). +*/ + +int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken) +{ + bool HasDecimalOrExponent = false; + int isDouble = 0; + bool generateFloat16 = false; + bool acceptFloat16 = parseContext.intermediate.getSource() == EShSourceHlsl; + bool isFloat16 = false; + bool requireHF = false; +#ifdef AMD_EXTENSIONS + if (parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float)) { + acceptFloat16 = true; + generateFloat16 = true; + requireHF = true; + } +#endif + + const auto saveName = [&](int ch) { + if (len <= MaxTokenLength) + ppToken->name[len++] = static_cast(ch); + }; + + // Decimal: + + if (ch == '.') { + HasDecimalOrExponent = true; + saveName(ch); + ch = getChar(); + + // 1.#INF or -1.#INF + if (parseContext.intermediate.getSource() == EShSourceHlsl && ch == '#') { + if ((len < 2) || + (len == 2 && ppToken->name[0] != '1') || + (len == 3 && ppToken->name[1] != '1' && !(ppToken->name[0] == '-' || ppToken->name[0] == '+')) || + (len > 3)) + parseContext.ppError(ppToken->loc, "unexpected use of", "#", ""); + else { + // we have 1.# or -1.# or +1.#, check for 'INF' + if ((ch = getChar()) != 'I' || + (ch = getChar()) != 'N' || + (ch = getChar()) != 'F') + parseContext.ppError(ppToken->loc, "expected 'INF'", "#", ""); + else { + // we have [+-].#INF, and we are targeting IEEE 754, so wrap it up: + saveName('I'); + saveName('N'); + saveName('F'); + ppToken->name[len] = '\0'; + if (ppToken->name[0] == '-') + ppToken->i64val = 0xfff0000000000000; // -Infinity + else + ppToken->i64val = 0x7ff0000000000000; // +Infinity + return PpAtomConstFloat; + } + } + } + + while (ch >= '0' && ch <= '9') { + saveName(ch); + ch = getChar(); + } + } + + // Exponent: + + if (ch == 'e' || ch == 'E') { + HasDecimalOrExponent = true; + saveName(ch); + ch = getChar(); + if (ch == '+' || ch == '-') { + saveName(ch); + ch = getChar(); + } + if (ch >= '0' && ch <= '9') { + while (ch >= '0' && ch <= '9') { + saveName(ch); + ch = getChar(); + } + } else { + parseContext.ppError(ppToken->loc, "bad character in float exponent", "", ""); + } + } + + // Suffix: + + if (ch == 'l' || ch == 'L') { + parseContext.doubleCheck(ppToken->loc, "double floating-point suffix"); + if (! HasDecimalOrExponent) + parseContext.ppError(ppToken->loc, "float literal needs a decimal point or exponent", "", ""); + int ch2 = getChar(); + if (ch2 != 'f' && ch2 != 'F') { + ungetChar(); + ungetChar(); + } else { + saveName(ch); + saveName(ch2); + isDouble = 1; + } + } else if (acceptFloat16 && (ch == 'h' || ch == 'H')) { +#ifdef AMD_EXTENSIONS + if (generateFloat16) + parseContext.float16Check(ppToken->loc, "half floating-point suffix"); +#endif + if (!HasDecimalOrExponent) + parseContext.ppError(ppToken->loc, "float literal needs a decimal point or exponent", "", ""); + if (requireHF) { + int ch2 = getChar(); + if (ch2 != 'f' && ch2 != 'F') { + ungetChar(); + ungetChar(); + } else { + saveName(ch); + saveName(ch2); + isFloat16 = generateFloat16; + } + } else { + saveName(ch); + isFloat16 = generateFloat16; + } + } else if (ch == 'f' || ch == 'F') { + parseContext.profileRequires(ppToken->loc, EEsProfile, 300, nullptr, "floating-point suffix"); + if (! parseContext.relaxedErrors()) + parseContext.profileRequires(ppToken->loc, ~EEsProfile, 120, nullptr, "floating-point suffix"); + if (! HasDecimalOrExponent) + parseContext.ppError(ppToken->loc, "float literal needs a decimal point or exponent", "", ""); + saveName(ch); + } else + ungetChar(); + + // Patch up the name, length, etc. + + if (len > MaxTokenLength) { + len = MaxTokenLength; + parseContext.ppError(ppToken->loc, "float literal too long", "", ""); + } + ppToken->name[len] = '\0'; + + // Get the numerical value + ppToken->dval = strtod(ppToken->name, nullptr); + + // Return the right token type + if (isDouble) + return PpAtomConstDouble; + else if (isFloat16) + return PpAtomConstFloat16; + else + return PpAtomConstFloat; +} + +// Recognize a character literal. +// +// The first ' has already been accepted, read the rest, through the closing '. +// +// Always returns PpAtomConstInt. +// +int TPpContext::characterLiteral(TPpToken* ppToken) +{ + ppToken->name[0] = 0; + ppToken->ival = 0; + + if (parseContext.intermediate.getSource() != EShSourceHlsl) { + // illegal, except in macro definition, for which case we report the character + return '\''; + } + + int ch = getChar(); + switch (ch) { + case '\'': + // As empty sequence: '' + parseContext.ppError(ppToken->loc, "unexpected", "\'", ""); + return PpAtomConstInt; + case '\\': + // As escape sequence: '\XXX' + switch (ch = getChar()) { + case 'a': + ppToken->ival = 7; + break; + case 'b': + ppToken->ival = 8; + break; + case 't': + ppToken->ival = 9; + break; + case 'n': + ppToken->ival = 10; + break; + case 'v': + ppToken->ival = 11; + break; + case 'f': + ppToken->ival = 12; + break; + case 'r': + ppToken->ival = 13; + break; + case 'x': + case '0': + parseContext.ppError(ppToken->loc, "octal and hex sequences not supported", "\\", ""); + break; + default: + // This catches '\'', '\"', '\?', etc. + // Also, things like '\C' mean the same thing as 'C' + // (after the above cases are filtered out). + ppToken->ival = ch; + break; + } + break; + default: + ppToken->ival = ch; + break; + } + ppToken->name[0] = (char)ppToken->ival; + ppToken->name[1] = '\0'; + ch = getChar(); + if (ch != '\'') { + parseContext.ppError(ppToken->loc, "expected", "\'", ""); + // Look ahead for a closing ' + do { + ch = getChar(); + } while (ch != '\'' && ch != EndOfInput && ch != '\n'); + } + + return PpAtomConstInt; +} + +// +// Scanner used to tokenize source stream. +// +int TPpContext::tStringInput::scan(TPpToken* ppToken) +{ + int AlreadyComplained = 0; + int len = 0; + int ch = 0; + int ii = 0; + unsigned long long ival = 0; + bool enableInt64 = pp->parseContext.version >= 450 && pp->parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_int64); +#ifdef AMD_EXTENSIONS + bool enableInt16 = pp->parseContext.version >= 450 && pp->parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_int16); +#endif + bool acceptHalf = pp->parseContext.intermediate.getSource() == EShSourceHlsl; +#ifdef AMD_EXTENSIONS + if (pp->parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float)) + acceptHalf = true; +#endif + + const auto floatingPointChar = [&](int ch) { return ch == '.' || ch == 'e' || ch == 'E' || + ch == 'f' || ch == 'F' || + (acceptHalf && (ch == 'h' || ch == 'H')); }; + + ppToken->ival = 0; + ppToken->i64val = 0; + ppToken->space = false; + ch = getch(); + for (;;) { + while (ch == ' ' || ch == '\t') { + ppToken->space = true; + ch = getch(); + } + + ppToken->loc = pp->parseContext.getCurrentLoc(); + len = 0; + switch (ch) { + default: + // Single character token, including EndOfInput, '#' and '\' (escaped newlines are handled at a lower level, so this is just a '\' token) + if (ch > PpAtomMaxSingle) + ch = PpAtomBadToken; + return ch; + + case 'A': case 'B': case 'C': case 'D': case 'E': + case 'F': case 'G': case 'H': case 'I': case 'J': + case 'K': case 'L': case 'M': case 'N': case 'O': + case 'P': case 'Q': case 'R': case 'S': case 'T': + case 'U': case 'V': case 'W': case 'X': case 'Y': + case 'Z': case '_': + case 'a': case 'b': case 'c': case 'd': case 'e': + case 'f': case 'g': case 'h': case 'i': case 'j': + case 'k': case 'l': case 'm': case 'n': case 'o': + case 'p': case 'q': case 'r': case 's': case 't': + case 'u': case 'v': case 'w': case 'x': case 'y': + case 'z': + do { + if (len < MaxTokenLength) { + ppToken->name[len++] = (char)ch; + ch = getch(); + } else { + if (! AlreadyComplained) { + pp->parseContext.ppError(ppToken->loc, "name too long", "", ""); + AlreadyComplained = 1; + } + ch = getch(); + } + } while ((ch >= 'a' && ch <= 'z') || + (ch >= 'A' && ch <= 'Z') || + (ch >= '0' && ch <= '9') || + ch == '_'); + + // line continuation with no token before or after makes len == 0, and need to start over skipping white space, etc. + if (len == 0) + continue; + + ppToken->name[len] = '\0'; + ungetch(); + return PpAtomIdentifier; + case '0': + ppToken->name[len++] = (char)ch; + ch = getch(); + if (ch == 'x' || ch == 'X') { + // must be hexadecimal + + bool isUnsigned = false; + bool isInt64 = false; +#ifdef AMD_EXTENSIONS + bool isInt16 = false; +#endif + ppToken->name[len++] = (char)ch; + ch = getch(); + if ((ch >= '0' && ch <= '9') || + (ch >= 'A' && ch <= 'F') || + (ch >= 'a' && ch <= 'f')) { + + ival = 0; + do { + if (len < MaxTokenLength && (ival <= 0x0fffffffu || (enableInt64 && ival <= 0x0fffffffffffffffull))) { + ppToken->name[len++] = (char)ch; + if (ch >= '0' && ch <= '9') { + ii = ch - '0'; + } else if (ch >= 'A' && ch <= 'F') { + ii = ch - 'A' + 10; + } else if (ch >= 'a' && ch <= 'f') { + ii = ch - 'a' + 10; + } else + pp->parseContext.ppError(ppToken->loc, "bad digit in hexadecimal literal", "", ""); + ival = (ival << 4) | ii; + } else { + if (! AlreadyComplained) { + if(len < MaxTokenLength) + pp->parseContext.ppError(ppToken->loc, "hexadecimal literal too big", "", ""); + else + pp->parseContext.ppError(ppToken->loc, "hexadecimal literal too long", "", ""); + AlreadyComplained = 1; + } + ival = 0xffffffffffffffffull; + } + ch = getch(); + } while ((ch >= '0' && ch <= '9') || + (ch >= 'A' && ch <= 'F') || + (ch >= 'a' && ch <= 'f')); + } else { + pp->parseContext.ppError(ppToken->loc, "bad digit in hexadecimal literal", "", ""); + } + if (ch == 'u' || ch == 'U') { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)ch; + isUnsigned = true; + + if (enableInt64) { + int nextCh = getch(); + if ((ch == 'u' && nextCh == 'l') || (ch == 'U' && nextCh == 'L')) { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)nextCh; + isInt64 = true; + } else + ungetch(); + } + +#ifdef AMD_EXTENSIONS + if (enableInt16) { + int nextCh = getch(); + if ((ch == 'u' && nextCh == 's') || (ch == 'U' && nextCh == 'S')) { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)nextCh; + isInt16 = true; + } else + ungetch(); + } +#endif + } else if (enableInt64 && (ch == 'l' || ch == 'L')) { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)ch; + isInt64 = true; +#ifdef AMD_EXTENSIONS + } else if (enableInt16 && (ch == 's' || ch == 'S')) { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)ch; + isInt16 = true; +#endif + } else + ungetch(); + ppToken->name[len] = '\0'; + + if (isInt64) { + ppToken->i64val = ival; + return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64; +#ifdef AMD_EXTENSIONS + } else if (isInt16) { + ppToken->ival = (int)ival; + return isUnsigned ? PpAtomConstUint16 : PpAtomConstInt16; +#endif + } else { + ppToken->ival = (int)ival; + return isUnsigned ? PpAtomConstUint : PpAtomConstInt; + } + } else { + // could be octal integer or floating point, speculative pursue octal until it must be floating point + + bool isUnsigned = false; + bool isInt64 = false; +#ifdef AMD_EXTENSIONS + bool isInt16 = false; +#endif + bool octalOverflow = false; + bool nonOctal = false; + ival = 0; + + // see how much octal-like stuff we can read + while (ch >= '0' && ch <= '7') { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)ch; + else if (! AlreadyComplained) { + pp->parseContext.ppError(ppToken->loc, "numeric literal too long", "", ""); + AlreadyComplained = 1; + } + if (ival <= 0x1fffffffu || (enableInt64 && ival <= 0x1fffffffffffffffull)) { + ii = ch - '0'; + ival = (ival << 3) | ii; + } else + octalOverflow = true; + ch = getch(); + } + + // could be part of a float... + if (ch == '8' || ch == '9') { + nonOctal = true; + do { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)ch; + else if (! AlreadyComplained) { + pp->parseContext.ppError(ppToken->loc, "numeric literal too long", "", ""); + AlreadyComplained = 1; + } + ch = getch(); + } while (ch >= '0' && ch <= '9'); + } + if (floatingPointChar(ch)) + return pp->lFloatConst(len, ch, ppToken); + + // wasn't a float, so must be octal... + if (nonOctal) + pp->parseContext.ppError(ppToken->loc, "octal literal digit too large", "", ""); + + if (ch == 'u' || ch == 'U') { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)ch; + isUnsigned = true; + + if (enableInt64) { + int nextCh = getch(); + if ((ch == 'u' && nextCh == 'l') || (ch == 'U' && nextCh == 'L')) { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)nextCh; + isInt64 = true; + } else + ungetch(); + } + +#ifdef AMD_EXTENSIONS + if (enableInt16) { + int nextCh = getch(); + if ((ch == 'u' && nextCh == 's') || (ch == 'U' && nextCh == 'S')) { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)nextCh; + isInt16 = true; + } else + ungetch(); + } +#endif + } else if (enableInt64 && (ch == 'l' || ch == 'L')) { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)ch; + isInt64 = true; +#ifdef AMD_EXTENSIONS + } else if (enableInt16 && (ch == 's' || ch == 'S')) { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)ch; + isInt16 = true; +#endif + } else + ungetch(); + ppToken->name[len] = '\0'; + + if (octalOverflow) + pp->parseContext.ppError(ppToken->loc, "octal literal too big", "", ""); + + if (isInt64) { + ppToken->i64val = ival; + return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64; +#ifdef AMD_EXTENSIONS + } else if (isInt16) { + ppToken->ival = (int)ival; + return isUnsigned ? PpAtomConstUint16 : PpAtomConstInt16; +#endif + } else { + ppToken->ival = (int)ival; + return isUnsigned ? PpAtomConstUint : PpAtomConstInt; + } + } + break; + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + // can't be hexadecimal or octal, is either decimal or floating point + + do { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)ch; + else if (! AlreadyComplained) { + pp->parseContext.ppError(ppToken->loc, "numeric literal too long", "", ""); + AlreadyComplained = 1; + } + ch = getch(); + } while (ch >= '0' && ch <= '9'); + if (floatingPointChar(ch)) + return pp->lFloatConst(len, ch, ppToken); + else { + // Finish handling signed and unsigned integers + int numericLen = len; + bool isUnsigned = false; + bool isInt64 = false; +#ifdef AMD_EXTENSIONS + bool isInt16 = false; +#endif + if (ch == 'u' || ch == 'U') { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)ch; + isUnsigned = true; + + if (enableInt64) { + int nextCh = getch(); + if ((ch == 'u' && nextCh == 'l') || (ch == 'U' && nextCh == 'L')) { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)nextCh; + isInt64 = true; + } else + ungetch(); + } + +#ifdef AMD_EXTENSIONS + if (enableInt16) { + int nextCh = getch(); + if ((ch == 'u' && nextCh == 's') || (ch == 'U' && nextCh == 'S')) { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)nextCh; + isInt16 = true; + } else + ungetch(); + } +#endif + } else if (enableInt64 && (ch == 'l' || ch == 'L')) { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)ch; + isInt64 = true; +#ifdef AMD_EXTENSIONS + } else if (enableInt16 && (ch == 's' || ch == 'S')) { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)ch; + isInt16 = true; +#endif + } else + ungetch(); + + ppToken->name[len] = '\0'; + ival = 0; + const unsigned oneTenthMaxInt = 0xFFFFFFFFu / 10; + const unsigned remainderMaxInt = 0xFFFFFFFFu - 10 * oneTenthMaxInt; + const unsigned long long oneTenthMaxInt64 = 0xFFFFFFFFFFFFFFFFull / 10; + const unsigned long long remainderMaxInt64 = 0xFFFFFFFFFFFFFFFFull - 10 * oneTenthMaxInt64; +#ifdef AMD_EXTENSIONS + const unsigned short oneTenthMaxInt16 = 0xFFFFu / 10; + const unsigned short remainderMaxInt16 = 0xFFFFu - 10 * oneTenthMaxInt16; +#endif + for (int i = 0; i < numericLen; i++) { + ch = ppToken->name[i] - '0'; + bool overflow = false; + if (isInt64) + overflow = (ival > oneTenthMaxInt64 || (ival == oneTenthMaxInt64 && (unsigned long long)ch > remainderMaxInt64)); +#ifdef AMD_EXTENSIONS + else if (isInt16) + overflow = (ival > oneTenthMaxInt16 || (ival == oneTenthMaxInt16 && (unsigned short)ch > remainderMaxInt16)); +#endif + else + overflow = (ival > oneTenthMaxInt || (ival == oneTenthMaxInt && (unsigned)ch > remainderMaxInt)); + if (overflow) { + pp->parseContext.ppError(ppToken->loc, "numeric literal too big", "", ""); + ival = 0xFFFFFFFFFFFFFFFFull; + break; + } else + ival = ival * 10 + ch; + } + + if (isInt64) { + ppToken->i64val = ival; + return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64; +#ifdef AMD_EXTENSIONS + } else if (isInt16) { + ppToken->ival = (int)ival; + return isUnsigned ? PpAtomConstUint16 : PpAtomConstInt16; +#endif + } else { + ppToken->ival = (int)ival; + return isUnsigned ? PpAtomConstUint : PpAtomConstInt; + } + } + break; + case '-': + ch = getch(); + if (ch == '-') { + return PpAtomDecrement; + } else if (ch == '=') { + return PPAtomSubAssign; + } else { + ungetch(); + return '-'; + } + case '+': + ch = getch(); + if (ch == '+') { + return PpAtomIncrement; + } else if (ch == '=') { + return PPAtomAddAssign; + } else { + ungetch(); + return '+'; + } + case '*': + ch = getch(); + if (ch == '=') { + return PPAtomMulAssign; + } else { + ungetch(); + return '*'; + } + case '%': + ch = getch(); + if (ch == '=') { + return PPAtomModAssign; + } else { + ungetch(); + return '%'; + } + case '^': + ch = getch(); + if (ch == '^') { + return PpAtomXor; + } else { + if (ch == '=') + return PpAtomXorAssign; + else{ + ungetch(); + return '^'; + } + } + + case '=': + ch = getch(); + if (ch == '=') { + return PpAtomEQ; + } else { + ungetch(); + return '='; + } + case '!': + ch = getch(); + if (ch == '=') { + return PpAtomNE; + } else { + ungetch(); + return '!'; + } + case '|': + ch = getch(); + if (ch == '|') { + return PpAtomOr; + } else if (ch == '=') { + return PpAtomOrAssign; + } else { + ungetch(); + return '|'; + } + case '&': + ch = getch(); + if (ch == '&') { + return PpAtomAnd; + } else if (ch == '=') { + return PpAtomAndAssign; + } else { + ungetch(); + return '&'; + } + case '<': + ch = getch(); + if (ch == '<') { + ch = getch(); + if (ch == '=') + return PpAtomLeftAssign; + else { + ungetch(); + return PpAtomLeft; + } + } else if (ch == '=') { + return PpAtomLE; + } else { + ungetch(); + return '<'; + } + case '>': + ch = getch(); + if (ch == '>') { + ch = getch(); + if (ch == '=') + return PpAtomRightAssign; + else { + ungetch(); + return PpAtomRight; + } + } else if (ch == '=') { + return PpAtomGE; + } else { + ungetch(); + return '>'; + } + case '.': + ch = getch(); + if (ch >= '0' && ch <= '9') { + ungetch(); + return pp->lFloatConst(0, '.', ppToken); + } else { + ungetch(); + return '.'; + } + case '/': + ch = getch(); + if (ch == '/') { + pp->inComment = true; + do { + ch = getch(); + } while (ch != '\n' && ch != EndOfInput); + ppToken->space = true; + pp->inComment = false; + + return ch; + } else if (ch == '*') { + ch = getch(); + do { + while (ch != '*') { + if (ch == EndOfInput) { + pp->parseContext.ppError(ppToken->loc, "End of input in comment", "comment", ""); + return ch; + } + ch = getch(); + } + ch = getch(); + if (ch == EndOfInput) { + pp->parseContext.ppError(ppToken->loc, "End of input in comment", "comment", ""); + return ch; + } + } while (ch != '/'); + ppToken->space = true; + // loop again to get the next token... + break; + } else if (ch == '=') { + return PPAtomDivAssign; + } else { + ungetch(); + return '/'; + } + break; + case '\'': + return pp->characterLiteral(ppToken); + case '"': + // TODO: If this gets enhanced to handle escape sequences, or + // anything that is different than what #include needs, then + // #include needs to use scanHeaderName() for this. + ch = getch(); + while (ch != '"' && ch != '\n' && ch != EndOfInput) { + if (len < MaxTokenLength) { + ppToken->name[len] = (char)ch; + len++; + ch = getch(); + } else + break; + }; + ppToken->name[len] = '\0'; + if (ch != '"') { + ungetch(); + pp->parseContext.ppError(ppToken->loc, "End of line in string", "string", ""); + } + return PpAtomConstString; + case ':': + ch = getch(); + if (ch == ':') + return PpAtomColonColon; + ungetch(); + return ':'; + } + + ch = getch(); + } +} + +// +// The main functional entry point into the preprocessor, which will +// scan the source strings to figure out and return the next processing token. +// +// Return the token, or EndOfInput when no more tokens. +// +int TPpContext::tokenize(TPpToken& ppToken) +{ + for(;;) { + int token = scanToken(&ppToken); + + // Handle token-pasting logic + token = tokenPaste(token, ppToken); + + if (token == EndOfInput) { + missingEndifCheck(); + return EndOfInput; + } + if (token == '#') { + if (previous_token == '\n') { + token = readCPPline(&ppToken); + if (token == EndOfInput) { + missingEndifCheck(); + return EndOfInput; + } + continue; + } else { + parseContext.ppError(ppToken.loc, "preprocessor directive cannot be preceded by another token", "#", ""); + return EndOfInput; + } + } + previous_token = token; + + if (token == '\n') + continue; + + // expand macros + if (token == PpAtomIdentifier && MacroExpand(&ppToken, false, true) != 0) + continue; + + switch (token) { + case PpAtomIdentifier: + case PpAtomConstInt: + case PpAtomConstUint: + case PpAtomConstFloat: + case PpAtomConstInt64: + case PpAtomConstUint64: +#ifdef AMD_EXTENSIONS + case PpAtomConstInt16: + case PpAtomConstUint16: +#endif + case PpAtomConstDouble: +#ifdef AMD_EXTENSIONS + case PpAtomConstFloat16: +#endif + if (ppToken.name[0] == '\0') + continue; + break; + case PpAtomConstString: + if (parseContext.intermediate.getSource() != EShSourceHlsl) { + // HLSL allows string literals. + parseContext.ppError(ppToken.loc, "string literals not supported", "\"\"", ""); + continue; + } + break; + case '\'': + parseContext.ppError(ppToken.loc, "character literals not supported", "\'", ""); + continue; + default: + strcpy(ppToken.name, atomStrings.getString(token)); + break; + } + + return token; + } +} + +// +// Do all token-pasting related combining of two pasted tokens when getting a +// stream of tokens from a replacement list. Degenerates to no processing if a +// replacement list is not the source of the token stream. +// +int TPpContext::tokenPaste(int token, TPpToken& ppToken) +{ + // starting with ## is illegal, skip to next token + if (token == PpAtomPaste) { + parseContext.ppError(ppToken.loc, "unexpected location", "##", ""); + return scanToken(&ppToken); + } + + int resultToken = token; // "foo" pasted with "35" is an identifier, not a number + + // ## can be chained, process all in the chain at once + while (peekPasting()) { + TPpToken pastedPpToken; + + // next token has to be ## + token = scanToken(&pastedPpToken); + assert(token == PpAtomPaste); + + // This covers end of macro expansion + if (endOfReplacementList()) { + parseContext.ppError(ppToken.loc, "unexpected location; end of replacement list", "##", ""); + break; + } + + // get the token after the ## + token = scanToken(&pastedPpToken); + + // This covers end of argument expansion + if (token == tMarkerInput::marker) { + parseContext.ppError(ppToken.loc, "unexpected location; end of argument", "##", ""); + break; + } + + // get the token text + switch (resultToken) { + case PpAtomIdentifier: + // already have the correct text in token.names + break; + case '=': + case '!': + case '-': + case '~': + case '+': + case '*': + case '/': + case '%': + case '<': + case '>': + case '|': + case '^': + case '&': + case PpAtomRight: + case PpAtomLeft: + case PpAtomAnd: + case PpAtomOr: + case PpAtomXor: + strcpy(ppToken.name, atomStrings.getString(resultToken)); + strcpy(pastedPpToken.name, atomStrings.getString(token)); + break; + default: + parseContext.ppError(ppToken.loc, "not supported for these tokens", "##", ""); + return resultToken; + } + + // combine the tokens + if (strlen(ppToken.name) + strlen(pastedPpToken.name) > MaxTokenLength) { + parseContext.ppError(ppToken.loc, "combined tokens are too long", "##", ""); + return resultToken; + } + strncat(ppToken.name, pastedPpToken.name, MaxTokenLength - strlen(ppToken.name)); + + // correct the kind of token we are making, if needed (identifiers stay identifiers) + if (resultToken != PpAtomIdentifier) { + int newToken = atomStrings.getAtom(ppToken.name); + if (newToken > 0) + resultToken = newToken; + else + parseContext.ppError(ppToken.loc, "combined token is invalid", "##", ""); + } + } + + return resultToken; +} + +// Checks if we've seen balanced #if...#endif +void TPpContext::missingEndifCheck() +{ + if (ifdepth > 0) + parseContext.ppError(parseContext.getCurrentLoc(), "missing #endif", "", ""); +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp new file mode 100644 index 00000000..bc145e25 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp @@ -0,0 +1,365 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2013 LunarG, Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +/****************************************************************************\ +Copyright (c) 2002, NVIDIA Corporation. + +NVIDIA Corporation("NVIDIA") supplies this software to you in +consideration of your agreement to the following terms, and your use, +installation, modification or redistribution of this NVIDIA software +constitutes acceptance of these terms. If you do not agree with these +terms, please do not use, install, modify or redistribute this NVIDIA +software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, NVIDIA grants you a personal, non-exclusive +license, under NVIDIA's copyrights in this original NVIDIA software (the +"NVIDIA Software"), to use, reproduce, modify and redistribute the +NVIDIA Software, with or without modifications, in source and/or binary +forms; provided that if you redistribute the NVIDIA Software, you must +retain the copyright notice of NVIDIA, this notice and the following +text and disclaimers in all such redistributions of the NVIDIA Software. +Neither the name, trademarks, service marks nor logos of NVIDIA +Corporation may be used to endorse or promote products derived from the +NVIDIA Software without specific prior written permission from NVIDIA. +Except as expressly stated in this notice, no other rights or licenses +express or implied, are granted by NVIDIA herein, including but not +limited to any patent rights that may be infringed by your derivative +works or by other works in which the NVIDIA Software may be +incorporated. No hardware is licensed hereunder. + +THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, +INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR +ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER +PRODUCTS. + +IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, +INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY +OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE +NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, +TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF +NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\****************************************************************************/ + +// +// For recording and playing back the stream of tokens in a macro definition. +// + +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif +#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/) +#define snprintf sprintf_s +#endif + +#include +#include +#include +#include + +#include "PpContext.h" +#include "PpTokens.h" + +namespace glslang { + +// push onto back of stream +void TPpContext::TokenStream::putSubtoken(char subtoken) +{ + data.push_back(static_cast(subtoken)); +} + +// get the next token in stream +int TPpContext::TokenStream::getSubtoken() +{ + if (current < data.size()) + return data[current++]; + else + return EndOfInput; +} + +// back up one position in the stream +void TPpContext::TokenStream::ungetSubtoken() +{ + if (current > 0) + --current; +} + +// Add a complete token (including backing string) to the end of a list +// for later playback. +void TPpContext::TokenStream::putToken(int token, TPpToken* ppToken) +{ + const char* s; + char* str = NULL; + + assert((token & ~0xff) == 0); + putSubtoken(static_cast(token)); + + switch (token) { + case PpAtomIdentifier: + case PpAtomConstString: + s = ppToken->name; + while (*s) + putSubtoken(*s++); + putSubtoken(0); + break; + case PpAtomConstInt: + case PpAtomConstUint: + case PpAtomConstInt64: + case PpAtomConstUint64: +#ifdef AMD_EXTENSIONS + case PpAtomConstInt16: + case PpAtomConstUint16: +#endif + case PpAtomConstFloat: + case PpAtomConstDouble: +#ifdef AMD_EXTENSIONS + case PpAtomConstFloat16: +#endif + str = ppToken->name; + while (*str) { + putSubtoken(*str); + str++; + } + putSubtoken(0); + break; + default: + break; + } +} + +// Read the next token from a token stream. +// (Not the source stream, but a stream used to hold a tokenized macro). +int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken *ppToken) +{ + int len; + int ch; + + int subtoken = getSubtoken(); + ppToken->loc = parseContext.getCurrentLoc(); + switch (subtoken) { + case '#': + // Check for ##, unless the current # is the last character + if (current < data.size()) { + if (getSubtoken() == '#') { + parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)"); + parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)"); + subtoken = PpAtomPaste; + } else + ungetSubtoken(); + } + break; + case PpAtomConstString: + case PpAtomIdentifier: + case PpAtomConstFloat: + case PpAtomConstDouble: +#ifdef AMD_EXTENSIONS + case PpAtomConstFloat16: +#endif + case PpAtomConstInt: + case PpAtomConstUint: + case PpAtomConstInt64: + case PpAtomConstUint64: +#ifdef AMD_EXTENSIONS + case PpAtomConstInt16: + case PpAtomConstUint16: +#endif + len = 0; + ch = getSubtoken(); + while (ch != 0 && ch != EndOfInput) { + if (len < MaxTokenLength) { + ppToken->name[len] = (char)ch; + len++; + ch = getSubtoken(); + } else { + parseContext.error(ppToken->loc, "token too long", "", ""); + break; + } + } + ppToken->name[len] = 0; + + switch (subtoken) { + case PpAtomIdentifier: + break; + case PpAtomConstString: + break; + case PpAtomConstFloat: + case PpAtomConstDouble: +#ifdef AMD_EXTENSIONS + case PpAtomConstFloat16: +#endif + ppToken->dval = atof(ppToken->name); + break; + case PpAtomConstInt: +#ifdef AMD_EXTENSIONS + case PpAtomConstInt16: +#endif + if (len > 0 && ppToken->name[0] == '0') { + if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X')) + ppToken->ival = (int)strtol(ppToken->name, 0, 16); + else + ppToken->ival = (int)strtol(ppToken->name, 0, 8); + } else + ppToken->ival = atoi(ppToken->name); + break; + case PpAtomConstUint: +#ifdef AMD_EXTENSIONS + case PpAtomConstUint16: +#endif + if (len > 0 && ppToken->name[0] == '0') { + if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X')) + ppToken->ival = (int)strtoul(ppToken->name, 0, 16); + else + ppToken->ival = (int)strtoul(ppToken->name, 0, 8); + } else + ppToken->ival = (int)strtoul(ppToken->name, 0, 10); + break; + case PpAtomConstInt64: + if (len > 0 && ppToken->name[0] == '0') { + if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X')) + ppToken->i64val = strtoll(ppToken->name, nullptr, 16); + else + ppToken->i64val = strtoll(ppToken->name, nullptr, 8); + } else + ppToken->i64val = atoll(ppToken->name); + break; + case PpAtomConstUint64: + if (len > 0 && ppToken->name[0] == '0') { + if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X')) + ppToken->i64val = (long long)strtoull(ppToken->name, nullptr, 16); + else + ppToken->i64val = (long long)strtoull(ppToken->name, nullptr, 8); + } else + ppToken->i64val = (long long)strtoull(ppToken->name, 0, 10); + break; + } + } + + return subtoken; +} + +// We are pasting if +// 1. we are preceding a pasting operator within this stream +// or +// 2. the entire macro is preceding a pasting operator (lastTokenPastes) +// and we are also on the last token +bool TPpContext::TokenStream::peekTokenizedPasting(bool lastTokenPastes) +{ + // 1. preceding ##? + + size_t savePos = current; + int subtoken; + // skip white space + do { + subtoken = getSubtoken(); + } while (subtoken == ' '); + current = savePos; + if (subtoken == PpAtomPaste) + return true; + + // 2. last token and we've been told after this there will be a ## + + if (! lastTokenPastes) + return false; + // Getting here means the last token will be pasted, after this + + // Are we at the last non-whitespace token? + savePos = current; + bool moreTokens = false; + do { + subtoken = getSubtoken(); + if (subtoken == EndOfInput) + break; + if (subtoken != ' ') { + moreTokens = true; + break; + } + } while (true); + current = savePos; + + return !moreTokens; +} + +// See if the next non-white-space tokens are two consecutive # +bool TPpContext::TokenStream::peekUntokenizedPasting() +{ + // don't return early, have to restore this + size_t savePos = current; + + // skip white-space + int subtoken; + do { + subtoken = getSubtoken(); + } while (subtoken == ' '); + + // check for ## + bool pasting = false; + if (subtoken == '#') { + subtoken = getSubtoken(); + if (subtoken == '#') + pasting = true; + } + + current = savePos; + + return pasting; +} + +void TPpContext::pushTokenStreamInput(TokenStream& ts, bool prepasting) +{ + pushInput(new tTokenInput(this, &ts, prepasting)); + ts.reset(); +} + +int TPpContext::tUngotTokenInput::scan(TPpToken* ppToken) +{ + if (done) + return EndOfInput; + + int ret = token; + *ppToken = lval; + done = true; + + return ret; +} + +void TPpContext::UngetToken(int token, TPpToken* ppToken) +{ + pushInput(new tUngotTokenInput(this, token, ppToken)); +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.h b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.h new file mode 100644 index 00000000..d56df576 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.h @@ -0,0 +1,181 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +/****************************************************************************\ +Copyright (c) 2002, NVIDIA Corporation. + +NVIDIA Corporation("NVIDIA") supplies this software to you in +consideration of your agreement to the following terms, and your use, +installation, modification or redistribution of this NVIDIA software +constitutes acceptance of these terms. If you do not agree with these +terms, please do not use, install, modify or redistribute this NVIDIA +software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, NVIDIA grants you a personal, non-exclusive +license, under NVIDIA's copyrights in this original NVIDIA software (the +"NVIDIA Software"), to use, reproduce, modify and redistribute the +NVIDIA Software, with or without modifications, in source and/or binary +forms; provided that if you redistribute the NVIDIA Software, you must +retain the copyright notice of NVIDIA, this notice and the following +text and disclaimers in all such redistributions of the NVIDIA Software. +Neither the name, trademarks, service marks nor logos of NVIDIA +Corporation may be used to endorse or promote products derived from the +NVIDIA Software without specific prior written permission from NVIDIA. +Except as expressly stated in this notice, no other rights or licenses +express or implied, are granted by NVIDIA herein, including but not +limited to any patent rights that may be infringed by your derivative +works or by other works in which the NVIDIA Software may be +incorporated. No hardware is licensed hereunder. + +THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, +INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR +ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER +PRODUCTS. + +IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, +INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY +OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE +NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, +TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF +NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\****************************************************************************/ + +#ifndef PARSER_H +#define PARSER_H + +namespace glslang { + +// Multi-character tokens +enum EFixedAtoms { + // single character tokens get their own char value as their token; start here for multi-character tokens + PpAtomMaxSingle = 127, + + // replace bad character tokens with this, to avoid accidental aliasing with the below + PpAtomBadToken, + + // Operators + + PPAtomAddAssign, + PPAtomSubAssign, + PPAtomMulAssign, + PPAtomDivAssign, + PPAtomModAssign, + + PpAtomRight, + PpAtomLeft, + + PpAtomRightAssign, + PpAtomLeftAssign, + PpAtomAndAssign, + PpAtomOrAssign, + PpAtomXorAssign, + + PpAtomAnd, + PpAtomOr, + PpAtomXor, + + PpAtomEQ, + PpAtomNE, + PpAtomGE, + PpAtomLE, + + PpAtomDecrement, + PpAtomIncrement, + + PpAtomColonColon, + + PpAtomPaste, + + // Constants + + PpAtomConstInt, + PpAtomConstUint, + PpAtomConstInt64, + PpAtomConstUint64, +#ifdef AMD_EXTENSIONS + PpAtomConstInt16, + PpAtomConstUint16, +#endif + PpAtomConstFloat, + PpAtomConstDouble, + PpAtomConstFloat16, + PpAtomConstString, + + // Identifiers + PpAtomIdentifier, + + // preprocessor "keywords" + + PpAtomDefine, + PpAtomUndef, + + PpAtomIf, + PpAtomIfdef, + PpAtomIfndef, + PpAtomElse, + PpAtomElif, + PpAtomEndif, + + PpAtomLine, + PpAtomPragma, + PpAtomError, + + // #version ... + PpAtomVersion, + PpAtomCore, + PpAtomCompatibility, + PpAtomEs, + + // #extension + PpAtomExtension, + + // __LINE__, __FILE__, __VERSION__ + + PpAtomLineMacro, + PpAtomFileMacro, + PpAtomVersionMacro, + + // #include + PpAtomInclude, + + PpAtomLast, +}; + +} // end namespace glslang + +#endif /* not PARSER_H */ diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/propagateNoContraction.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/propagateNoContraction.cpp new file mode 100644 index 00000000..ae95688a --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/propagateNoContraction.cpp @@ -0,0 +1,866 @@ +// +// Copyright (C) 2015-2016 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +// +// Visit the nodes in the glslang intermediate tree representation to +// propagate the 'noContraction' qualifier. +// + +#include "propagateNoContraction.h" + +#include +#include +#include +#include +#include + +#include "localintermediate.h" +namespace { + +// Use a string to hold the access chain information, as in most cases the +// access chain is short and may contain only one element, which is the symbol +// ID. +// Example: struct {float a; float b;} s; +// Object s.a will be represented with: /0 +// Object s.b will be represented with: /1 +// Object s will be represented with: +// For members of vector, matrix and arrays, they will be represented with the +// same symbol ID of their container symbol objects. This is because their +// preciseness is always the same as their container symbol objects. +typedef std::string ObjectAccessChain; + +// The delimiter used in the ObjectAccessChain string to separate symbol ID and +// different level of struct indices. +const char ObjectAccesschainDelimiter = '/'; + +// Mapping from Symbol IDs of symbol nodes, to their defining operation +// nodes. +typedef std::unordered_multimap NodeMapping; +// Mapping from object nodes to their access chain info string. +typedef std::unordered_map AccessChainMapping; + +// Set of object IDs. +typedef std::unordered_set ObjectAccesschainSet; +// Set of return branch nodes. +typedef std::unordered_set ReturnBranchNodeSet; + +// A helper function to tell whether a node is 'noContraction'. Returns true if +// the node has 'noContraction' qualifier, otherwise false. +bool isPreciseObjectNode(glslang::TIntermTyped* node) +{ + return node->getType().getQualifier().noContraction; +} + +// Returns true if the opcode is a dereferencing one. +bool isDereferenceOperation(glslang::TOperator op) +{ + switch (op) { + case glslang::EOpIndexDirect: + case glslang::EOpIndexDirectStruct: + case glslang::EOpIndexIndirect: + case glslang::EOpVectorSwizzle: + case glslang::EOpMatrixSwizzle: + return true; + default: + return false; + } +} + +// Returns true if the opcode leads to an assignment operation. +bool isAssignOperation(glslang::TOperator op) +{ + switch (op) { + case glslang::EOpAssign: + case glslang::EOpAddAssign: + case glslang::EOpSubAssign: + case glslang::EOpMulAssign: + case glslang::EOpVectorTimesMatrixAssign: + case glslang::EOpVectorTimesScalarAssign: + case glslang::EOpMatrixTimesScalarAssign: + case glslang::EOpMatrixTimesMatrixAssign: + case glslang::EOpDivAssign: + case glslang::EOpModAssign: + case glslang::EOpAndAssign: + case glslang::EOpLeftShiftAssign: + case glslang::EOpRightShiftAssign: + case glslang::EOpInclusiveOrAssign: + case glslang::EOpExclusiveOrAssign: + + case glslang::EOpPostIncrement: + case glslang::EOpPostDecrement: + case glslang::EOpPreIncrement: + case glslang::EOpPreDecrement: + return true; + default: + return false; + } +} + +// A helper function to get the unsigned int from a given constant union node. +// Note the node should only hold a uint scalar. +unsigned getStructIndexFromConstantUnion(glslang::TIntermTyped* node) +{ + assert(node->getAsConstantUnion() && node->getAsConstantUnion()->isScalar()); + unsigned struct_dereference_index = node->getAsConstantUnion()->getConstArray()[0].getUConst(); + return struct_dereference_index; +} + +// A helper function to generate symbol_label. +ObjectAccessChain generateSymbolLabel(glslang::TIntermSymbol* node) +{ + ObjectAccessChain symbol_id = + std::to_string(node->getId()) + "(" + node->getName().c_str() + ")"; + return symbol_id; +} + +// Returns true if the operation is an arithmetic operation and valid for +// the 'NoContraction' decoration. +bool isArithmeticOperation(glslang::TOperator op) +{ + switch (op) { + case glslang::EOpAddAssign: + case glslang::EOpSubAssign: + case glslang::EOpMulAssign: + case glslang::EOpVectorTimesMatrixAssign: + case glslang::EOpVectorTimesScalarAssign: + case glslang::EOpMatrixTimesScalarAssign: + case glslang::EOpMatrixTimesMatrixAssign: + case glslang::EOpDivAssign: + case glslang::EOpModAssign: + + case glslang::EOpNegative: + + case glslang::EOpAdd: + case glslang::EOpSub: + case glslang::EOpMul: + case glslang::EOpDiv: + case glslang::EOpMod: + + case glslang::EOpVectorTimesScalar: + case glslang::EOpVectorTimesMatrix: + case glslang::EOpMatrixTimesVector: + case glslang::EOpMatrixTimesScalar: + case glslang::EOpMatrixTimesMatrix: + + case glslang::EOpDot: + + case glslang::EOpPostIncrement: + case glslang::EOpPostDecrement: + case glslang::EOpPreIncrement: + case glslang::EOpPreDecrement: + return true; + default: + return false; + } +} + +// A helper class to help manage the populating_initial_no_contraction_ flag. +template class StateSettingGuard { +public: + StateSettingGuard(T* state_ptr, T new_state_value) + : state_ptr_(state_ptr), previous_state_(*state_ptr) + { + *state_ptr = new_state_value; + } + StateSettingGuard(T* state_ptr) : state_ptr_(state_ptr), previous_state_(*state_ptr) {} + void setState(T new_state_value) { *state_ptr_ = new_state_value; } + ~StateSettingGuard() { *state_ptr_ = previous_state_; } + +private: + T* state_ptr_; + T previous_state_; +}; + +// A helper function to get the front element from a given ObjectAccessChain +ObjectAccessChain getFrontElement(const ObjectAccessChain& chain) +{ + size_t pos_delimiter = chain.find(ObjectAccesschainDelimiter); + return pos_delimiter == std::string::npos ? chain : chain.substr(0, pos_delimiter); +} + +// A helper function to get the access chain starting from the second element. +ObjectAccessChain subAccessChainFromSecondElement(const ObjectAccessChain& chain) +{ + size_t pos_delimiter = chain.find(ObjectAccesschainDelimiter); + return pos_delimiter == std::string::npos ? "" : chain.substr(pos_delimiter + 1); +} + +// A helper function to get the access chain after removing a given prefix. +ObjectAccessChain getSubAccessChainAfterPrefix(const ObjectAccessChain& chain, + const ObjectAccessChain& prefix) +{ + size_t pos = chain.find(prefix); + if (pos != 0) + return chain; + return chain.substr(prefix.length() + sizeof(ObjectAccesschainDelimiter)); +} + +// +// A traverser which traverses the whole AST and populates: +// 1) A mapping from symbol nodes' IDs to their defining operation nodes. +// 2) A set of access chains of the initial precise object nodes. +// +class TSymbolDefinitionCollectingTraverser : public glslang::TIntermTraverser { +public: + TSymbolDefinitionCollectingTraverser(NodeMapping* symbol_definition_mapping, + AccessChainMapping* accesschain_mapping, + ObjectAccesschainSet* precise_objects, + ReturnBranchNodeSet* precise_return_nodes); + + bool visitUnary(glslang::TVisit, glslang::TIntermUnary*) override; + bool visitBinary(glslang::TVisit, glslang::TIntermBinary*) override; + void visitSymbol(glslang::TIntermSymbol*) override; + bool visitAggregate(glslang::TVisit, glslang::TIntermAggregate*) override; + bool visitBranch(glslang::TVisit, glslang::TIntermBranch*) override; + +protected: + TSymbolDefinitionCollectingTraverser& operator=(const TSymbolDefinitionCollectingTraverser&); + + // The mapping from symbol node IDs to their defining nodes. This should be + // populated along traversing the AST. + NodeMapping& symbol_definition_mapping_; + // The set of symbol node IDs for precise symbol nodes, the ones marked as + // 'noContraction'. + ObjectAccesschainSet& precise_objects_; + // The set of precise return nodes. + ReturnBranchNodeSet& precise_return_nodes_; + // A temporary cache of the symbol node whose defining node is to be found + // currently along traversing the AST. + ObjectAccessChain current_object_; + // A map from object node to its access chain. This traverser stores + // the built access chains into this map for each object node it has + // visited. + AccessChainMapping& accesschain_mapping_; + // The pointer to the Function Definition node, so we can get the + // preciseness of the return expression from it when we traverse the + // return branch node. + glslang::TIntermAggregate* current_function_definition_node_; +}; + +TSymbolDefinitionCollectingTraverser::TSymbolDefinitionCollectingTraverser( + NodeMapping* symbol_definition_mapping, AccessChainMapping* accesschain_mapping, + ObjectAccesschainSet* precise_objects, + std::unordered_set* precise_return_nodes) + : TIntermTraverser(true, false, false), symbol_definition_mapping_(*symbol_definition_mapping), + precise_objects_(*precise_objects), precise_return_nodes_(*precise_return_nodes), + current_object_(), accesschain_mapping_(*accesschain_mapping), + current_function_definition_node_(nullptr) {} + +// Visits a symbol node, set the current_object_ to the +// current node symbol ID, and record a mapping from this node to the current +// current_object_, which is the just obtained symbol +// ID. +void TSymbolDefinitionCollectingTraverser::visitSymbol(glslang::TIntermSymbol* node) +{ + current_object_ = generateSymbolLabel(node); + accesschain_mapping_[node] = current_object_; +} + +// Visits an aggregate node, traverses all of its children. +bool TSymbolDefinitionCollectingTraverser::visitAggregate(glslang::TVisit, + glslang::TIntermAggregate* node) +{ + // This aggregate node might be a function definition node, in which case we need to + // cache this node, so we can get the preciseness information of the return value + // of this function later. + StateSettingGuard current_function_definition_node_setting_guard( + ¤t_function_definition_node_); + if (node->getOp() == glslang::EOpFunction) { + // This is function definition node, we need to cache this node so that we can + // get the preciseness of the return value later. + current_function_definition_node_setting_guard.setState(node); + } + // Traverse the items in the sequence. + glslang::TIntermSequence& seq = node->getSequence(); + for (int i = 0; i < (int)seq.size(); ++i) { + current_object_.clear(); + seq[i]->traverse(this); + } + return false; +} + +bool TSymbolDefinitionCollectingTraverser::visitBranch(glslang::TVisit, + glslang::TIntermBranch* node) +{ + if (node->getFlowOp() == glslang::EOpReturn && node->getExpression() && + current_function_definition_node_ && + current_function_definition_node_->getType().getQualifier().noContraction) { + // This node is a return node with an expression, and its function has a + // precise return value. We need to find the involved objects in its + // expression and add them to the set of initial precise objects. + precise_return_nodes_.insert(node); + node->getExpression()->traverse(this); + } + return false; +} + +// Visits a unary node. This might be an implicit assignment like i++, i--. etc. +bool TSymbolDefinitionCollectingTraverser::visitUnary(glslang::TVisit /* visit */, + glslang::TIntermUnary* node) +{ + current_object_.clear(); + node->getOperand()->traverse(this); + if (isAssignOperation(node->getOp())) { + // We should always be able to get an access chain of the operand node. + assert(!current_object_.empty()); + + // If the operand node object is 'precise', we collect its access chain + // for the initial set of 'precise' objects. + if (isPreciseObjectNode(node->getOperand())) { + // The operand node is an 'precise' object node, add its + // access chain to the set of 'precise' objects. This is to collect + // the initial set of 'precise' objects. + precise_objects_.insert(current_object_); + } + // Gets the symbol ID from the object's access chain. + ObjectAccessChain id_symbol = getFrontElement(current_object_); + // Add a mapping from the symbol ID to this assignment operation node. + symbol_definition_mapping_.insert(std::make_pair(id_symbol, node)); + } + // A unary node is not a dereference node, so we clear the access chain which + // is under construction. + current_object_.clear(); + return false; +} + +// Visits a binary node and updates the mapping from symbol IDs to the definition +// nodes. Also collects the access chains for the initial precise objects. +bool TSymbolDefinitionCollectingTraverser::visitBinary(glslang::TVisit /* visit */, + glslang::TIntermBinary* node) +{ + // Traverses the left node to build the access chain info for the object. + current_object_.clear(); + node->getLeft()->traverse(this); + + if (isAssignOperation(node->getOp())) { + // We should always be able to get an access chain for the left node. + assert(!current_object_.empty()); + + // If the left node object is 'precise', it is an initial precise object + // specified in the shader source. Adds it to the initial work list to + // process later. + if (isPreciseObjectNode(node->getLeft())) { + // The left node is an 'precise' object node, add its access chain to + // the set of 'precise' objects. This is to collect the initial set + // of 'precise' objects. + precise_objects_.insert(current_object_); + } + // Gets the symbol ID from the object access chain, which should be the + // first element recorded in the access chain. + ObjectAccessChain id_symbol = getFrontElement(current_object_); + // Adds a mapping from the symbol ID to this assignment operation node. + symbol_definition_mapping_.insert(std::make_pair(id_symbol, node)); + + // Traverses the right node, there may be other 'assignment' + // operations in the right. + current_object_.clear(); + node->getRight()->traverse(this); + + } else if (isDereferenceOperation(node->getOp())) { + // The left node (parent node) is a struct type object. We need to + // record the access chain information of the current node into its + // object id. + if (node->getOp() == glslang::EOpIndexDirectStruct) { + unsigned struct_dereference_index = getStructIndexFromConstantUnion(node->getRight()); + current_object_.push_back(ObjectAccesschainDelimiter); + current_object_.append(std::to_string(struct_dereference_index)); + } + accesschain_mapping_[node] = current_object_; + + // For a dereference node, there is no need to traverse the right child + // node as the right node should always be an integer type object. + + } else { + // For other binary nodes, still traverse the right node. + current_object_.clear(); + node->getRight()->traverse(this); + } + return false; +} + +// Traverses the AST and returns a tuple of four members: +// 1) a mapping from symbol IDs to the definition nodes (aka. assignment nodes) of these symbols. +// 2) a mapping from object nodes in the AST to the access chains of these objects. +// 3) a set of access chains of precise objects. +// 4) a set of return nodes with precise expressions. +std::tuple +getSymbolToDefinitionMappingAndPreciseSymbolIDs(const glslang::TIntermediate& intermediate) +{ + auto result_tuple = std::make_tuple(NodeMapping(), AccessChainMapping(), ObjectAccesschainSet(), + ReturnBranchNodeSet()); + + TIntermNode* root = intermediate.getTreeRoot(); + if (root == 0) + return result_tuple; + + NodeMapping& symbol_definition_mapping = std::get<0>(result_tuple); + AccessChainMapping& accesschain_mapping = std::get<1>(result_tuple); + ObjectAccesschainSet& precise_objects = std::get<2>(result_tuple); + ReturnBranchNodeSet& precise_return_nodes = std::get<3>(result_tuple); + + // Traverses the AST and populate the results. + TSymbolDefinitionCollectingTraverser collector(&symbol_definition_mapping, &accesschain_mapping, + &precise_objects, &precise_return_nodes); + root->traverse(&collector); + + return result_tuple; +} + +// +// A traverser that determine whether the left node (or operand node for unary +// node) of an assignment node is 'precise', containing 'precise' or not, +// according to the access chain a given precise object which share the same +// symbol as the left node. +// +// Post-orderly traverses the left node subtree of an binary assignment node and: +// +// 1) Propagates the 'precise' from the left object nodes to this object node. +// +// 2) Builds object access chain along the traversal, and also compares with +// the access chain of the given 'precise' object along with the traversal to +// tell if the node to be defined is 'precise' or not. +// +class TNoContractionAssigneeCheckingTraverser : public glslang::TIntermTraverser { + + enum DecisionStatus { + // The object node to be assigned to may contain 'precise' objects and also not 'precise' objects. + Mixed = 0, + // The object node to be assigned to is either a 'precise' object or a struct objects whose members are all 'precise'. + Precise = 1, + // The object node to be assigned to is not a 'precise' object. + NotPreicse = 2, + }; + +public: + TNoContractionAssigneeCheckingTraverser(const AccessChainMapping& accesschain_mapping) + : TIntermTraverser(true, false, false), accesschain_mapping_(accesschain_mapping), + precise_object_(nullptr) {} + + // Checks the preciseness of a given assignment node with a precise object + // represented as access chain. The precise object shares the same symbol + // with the assignee of the given assignment node. Return a tuple of two: + // + // 1) The preciseness of the assignee node of this assignment node. True + // if the assignee contains 'precise' objects or is 'precise', false if + // the assignee is not 'precise' according to the access chain of the given + // precise object. + // + // 2) The incremental access chain from the assignee node to its nested + // 'precise' object, according to the access chain of the given precise + // object. This incremental access chain can be empty, which means the + // assignee is 'precise'. Otherwise it shows the path to the nested + // precise object. + std::tuple + getPrecisenessAndRemainedAccessChain(glslang::TIntermOperator* node, + const ObjectAccessChain& precise_object) + { + assert(isAssignOperation(node->getOp())); + precise_object_ = &precise_object; + ObjectAccessChain assignee_object; + if (glslang::TIntermBinary* BN = node->getAsBinaryNode()) { + // This is a binary assignment node, we need to check the + // preciseness of the left node. + assert(accesschain_mapping_.count(BN->getLeft())); + // The left node (assignee node) is an object node, traverse the + // node to let the 'precise' of nesting objects being transfered to + // nested objects. + BN->getLeft()->traverse(this); + // After traversing the left node, if the left node is 'precise', + // we can conclude this assignment should propagate 'precise'. + if (isPreciseObjectNode(BN->getLeft())) { + return make_tuple(true, ObjectAccessChain()); + } + // If the preciseness of the left node (assignee node) can not + // be determined by now, we need to compare the access chain string + // of the assignee object with the given precise object. + assignee_object = accesschain_mapping_.at(BN->getLeft()); + + } else if (glslang::TIntermUnary* UN = node->getAsUnaryNode()) { + // This is a unary assignment node, we need to check the + // preciseness of the operand node. For unary assignment node, the + // operand node should always be an object node. + assert(accesschain_mapping_.count(UN->getOperand())); + // Traverse the operand node to let the 'precise' being propagated + // from lower nodes to upper nodes. + UN->getOperand()->traverse(this); + // After traversing the operand node, if the operand node is + // 'precise', this assignment should propagate 'precise'. + if (isPreciseObjectNode(UN->getOperand())) { + return make_tuple(true, ObjectAccessChain()); + } + // If the preciseness of the operand node (assignee node) can not + // be determined by now, we need to compare the access chain string + // of the assignee object with the given precise object. + assignee_object = accesschain_mapping_.at(UN->getOperand()); + } else { + // Not a binary or unary node, should not happen. + assert(false); + } + + // Compare the access chain string of the assignee node with the given + // precise object to determine if this assignment should propagate + // 'precise'. + if (assignee_object.find(precise_object) == 0) { + // The access chain string of the given precise object is a prefix + // of assignee's access chain string. The assignee should be + // 'precise'. + return make_tuple(true, ObjectAccessChain()); + } else if (precise_object.find(assignee_object) == 0) { + // The assignee's access chain string is a prefix of the given + // precise object, the assignee object contains 'precise' object, + // and we need to pass the remained access chain to the object nodes + // in the right. + return make_tuple(true, getSubAccessChainAfterPrefix(precise_object, assignee_object)); + } else { + // The access chain strings do not match, the assignee object can + // not be labeled as 'precise' according to the given precise + // object. + return make_tuple(false, ObjectAccessChain()); + } + } + +protected: + TNoContractionAssigneeCheckingTraverser& operator=(const TNoContractionAssigneeCheckingTraverser&); + + bool visitBinary(glslang::TVisit, glslang::TIntermBinary* node) override; + void visitSymbol(glslang::TIntermSymbol* node) override; + + // A map from object nodes to their access chain string (used as object ID). + const AccessChainMapping& accesschain_mapping_; + // A given precise object, represented in it access chain string. This + // precise object is used to be compared with the assignee node to tell if + // the assignee node is 'precise', contains 'precise' object or not + // 'precise'. + const ObjectAccessChain* precise_object_; +}; + +// Visits a binary node. If the node is an object node, it must be a dereference +// node. In such cases, if the left node is 'precise', this node should also be +// 'precise'. +bool TNoContractionAssigneeCheckingTraverser::visitBinary(glslang::TVisit, + glslang::TIntermBinary* node) +{ + // Traverses the left so that we transfer the 'precise' from nesting object + // to its nested object. + node->getLeft()->traverse(this); + // If this binary node is an object node, we should have it in the + // accesschain_mapping_. + if (accesschain_mapping_.count(node)) { + // A binary object node must be a dereference node. + assert(isDereferenceOperation(node->getOp())); + // If the left node is 'precise', this node should also be precise, + // otherwise, compare with the given precise_object_. If the + // access chain of this node matches with the given precise_object_, + // this node should be marked as 'precise'. + if (isPreciseObjectNode(node->getLeft())) { + node->getWritableType().getQualifier().noContraction = true; + } else if (accesschain_mapping_.at(node) == *precise_object_) { + node->getWritableType().getQualifier().noContraction = true; + } + } + return false; +} + +// Visits a symbol node, if the symbol node ID (its access chain string) matches +// with the given precise object, this node should be 'precise'. +void TNoContractionAssigneeCheckingTraverser::visitSymbol(glslang::TIntermSymbol* node) +{ + // A symbol node should always be an object node, and should have been added + // to the map from object nodes to their access chain strings. + assert(accesschain_mapping_.count(node)); + if (accesschain_mapping_.at(node) == *precise_object_) { + node->getWritableType().getQualifier().noContraction = true; + } +} + +// +// A traverser that only traverses the right side of binary assignment nodes +// and the operand node of unary assignment nodes. +// +// 1) Marks arithmetic operations as 'NoContraction'. +// +// 2) Find the object which should be marked as 'precise' in the right and +// update the 'precise' object work list. +// +class TNoContractionPropagator : public glslang::TIntermTraverser { +public: + TNoContractionPropagator(ObjectAccesschainSet* precise_objects, + const AccessChainMapping& accesschain_mapping) + : TIntermTraverser(true, false, false), + precise_objects_(*precise_objects), added_precise_object_ids_(), + remained_accesschain_(), accesschain_mapping_(accesschain_mapping) {} + + // Propagates 'precise' in the right nodes of a given assignment node with + // access chain record from the assignee node to a 'precise' object it + // contains. + void + propagateNoContractionInOneExpression(glslang::TIntermTyped* defining_node, + const ObjectAccessChain& assignee_remained_accesschain) + { + remained_accesschain_ = assignee_remained_accesschain; + if (glslang::TIntermBinary* BN = defining_node->getAsBinaryNode()) { + assert(isAssignOperation(BN->getOp())); + BN->getRight()->traverse(this); + if (isArithmeticOperation(BN->getOp())) { + BN->getWritableType().getQualifier().noContraction = true; + } + } else if (glslang::TIntermUnary* UN = defining_node->getAsUnaryNode()) { + assert(isAssignOperation(UN->getOp())); + UN->getOperand()->traverse(this); + if (isArithmeticOperation(UN->getOp())) { + UN->getWritableType().getQualifier().noContraction = true; + } + } + } + + // Propagates 'precise' in a given precise return node. + void propagateNoContractionInReturnNode(glslang::TIntermBranch* return_node) + { + remained_accesschain_ = ""; + assert(return_node->getFlowOp() == glslang::EOpReturn && return_node->getExpression()); + return_node->getExpression()->traverse(this); + } + +protected: + TNoContractionPropagator& operator=(const TNoContractionPropagator&); + + // Visits an aggregate node. The node can be a initializer list, in which + // case we need to find the 'precise' or 'precise' containing object node + // with the access chain record. In other cases, just need to traverse all + // the children nodes. + bool visitAggregate(glslang::TVisit, glslang::TIntermAggregate* node) override + { + if (!remained_accesschain_.empty() && node->getOp() == glslang::EOpConstructStruct) { + // This is a struct initializer node, and the remained + // access chain is not empty, we need to refer to the + // assignee_remained_access_chain_ to find the nested + // 'precise' object. And we don't need to visit other nodes in this + // aggregate node. + + // Gets the struct dereference index that leads to 'precise' object. + ObjectAccessChain precise_accesschain_index_str = + getFrontElement(remained_accesschain_); + unsigned precise_accesschain_index = (unsigned)strtoul(precise_accesschain_index_str.c_str(), nullptr, 10); + // Gets the node pointed by the access chain index extracted before. + glslang::TIntermTyped* potential_precise_node = + node->getSequence()[precise_accesschain_index]->getAsTyped(); + assert(potential_precise_node); + // Pop the front access chain index from the path, and visit the nested node. + { + ObjectAccessChain next_level_accesschain = + subAccessChainFromSecondElement(remained_accesschain_); + StateSettingGuard setup_remained_accesschain_for_next_level( + &remained_accesschain_, next_level_accesschain); + potential_precise_node->traverse(this); + } + return false; + } + return true; + } + + // Visits a binary node. A binary node can be an object node, e.g. a dereference node. + // As only the top object nodes in the right side of an assignment needs to be visited + // and added to 'precise' work list, this traverser won't visit the children nodes of + // an object node. If the binary node does not represent an object node, it should + // go on to traverse its children nodes and if it is an arithmetic operation node, this + // operation should be marked as 'noContraction'. + bool visitBinary(glslang::TVisit, glslang::TIntermBinary* node) override + { + if (isDereferenceOperation(node->getOp())) { + // This binary node is an object node. Need to update the precise + // object set with the access chain of this node + remained + // access chain . + ObjectAccessChain new_precise_accesschain = accesschain_mapping_.at(node); + if (remained_accesschain_.empty()) { + node->getWritableType().getQualifier().noContraction = true; + } else { + new_precise_accesschain += ObjectAccesschainDelimiter + remained_accesschain_; + } + // Cache the access chain as added precise object, so we won't add the + // same object to the work list again. + if (!added_precise_object_ids_.count(new_precise_accesschain)) { + precise_objects_.insert(new_precise_accesschain); + added_precise_object_ids_.insert(new_precise_accesschain); + } + // Only the upper-most object nodes should be visited, so do not + // visit children of this object node. + return false; + } + // If this is an arithmetic operation, marks this node as 'noContraction'. + if (isArithmeticOperation(node->getOp()) && node->getBasicType() != glslang::EbtInt) { + node->getWritableType().getQualifier().noContraction = true; + } + // As this node is not an object node, need to traverse the children nodes. + return true; + } + + // Visits a unary node. A unary node can not be an object node. If the operation + // is an arithmetic operation, need to mark this node as 'noContraction'. + bool visitUnary(glslang::TVisit /* visit */, glslang::TIntermUnary* node) override + { + // If this is an arithmetic operation, marks this with 'noContraction' + if (isArithmeticOperation(node->getOp())) { + node->getWritableType().getQualifier().noContraction = true; + } + return true; + } + + // Visits a symbol node. A symbol node is always an object node. So we + // should always be able to find its in our collected mapping from object + // nodes to access chains. As an object node, a symbol node can be either + // 'precise' or containing 'precise' objects according to unused + // access chain information we have when we visit this node. + void visitSymbol(glslang::TIntermSymbol* node) override + { + // Symbol nodes are object nodes and should always have an + // access chain collected before matches with it. + assert(accesschain_mapping_.count(node)); + ObjectAccessChain new_precise_accesschain = accesschain_mapping_.at(node); + // If the unused access chain is empty, this symbol node should be + // marked as 'precise'. Otherwise, the unused access chain should be + // appended to the symbol ID to build a new access chain which points to + // the nested 'precise' object in this symbol object. + if (remained_accesschain_.empty()) { + node->getWritableType().getQualifier().noContraction = true; + } else { + new_precise_accesschain += ObjectAccesschainDelimiter + remained_accesschain_; + } + // Add the new 'precise' access chain to the work list and make sure we + // don't visit it again. + if (!added_precise_object_ids_.count(new_precise_accesschain)) { + precise_objects_.insert(new_precise_accesschain); + added_precise_object_ids_.insert(new_precise_accesschain); + } + } + + // A set of precise objects, represented as access chains. + ObjectAccesschainSet& precise_objects_; + // Visited symbol nodes, should not revisit these nodes. + ObjectAccesschainSet added_precise_object_ids_; + // The left node of an assignment operation might be an parent of 'precise' objects. + // This means the left node might not be an 'precise' object node, but it may contains + // 'precise' qualifier which should be propagated to the corresponding child node in + // the right. So we need the path from the left node to its nested 'precise' node to + // tell us how to find the corresponding 'precise' node in the right. + ObjectAccessChain remained_accesschain_; + // A map from node pointers to their access chains. + const AccessChainMapping& accesschain_mapping_; +}; +} + +namespace glslang { + +void PropagateNoContraction(const glslang::TIntermediate& intermediate) +{ + // First, traverses the AST, records symbols with their defining operations + // and collects the initial set of precise symbols (symbol nodes that marked + // as 'noContraction') and precise return nodes. + auto mappings_and_precise_objects = + getSymbolToDefinitionMappingAndPreciseSymbolIDs(intermediate); + + // The mapping of symbol node IDs to their defining nodes. This enables us + // to get the defining node directly from a given symbol ID without + // traversing the tree again. + NodeMapping& symbol_definition_mapping = std::get<0>(mappings_and_precise_objects); + + // The mapping of object nodes to their access chains recorded. + AccessChainMapping& accesschain_mapping = std::get<1>(mappings_and_precise_objects); + + // The initial set of 'precise' objects which are represented as the + // access chain toward them. + ObjectAccesschainSet& precise_object_accesschains = std::get<2>(mappings_and_precise_objects); + + // The set of 'precise' return nodes. + ReturnBranchNodeSet& precise_return_nodes = std::get<3>(mappings_and_precise_objects); + + // Second, uses the initial set of precise objects as a work list, pops an + // access chain, extract the symbol ID from it. Then: + // 1) Check the assignee object, see if it is 'precise' object node or + // contains 'precise' object. Obtain the incremental access chain from the + // assignee node to its nested 'precise' node (if any). + // 2) If the assignee object node is 'precise' or it contains 'precise' + // objects, traverses the right side of the assignment operation + // expression to mark arithmetic operations as 'noContration' and update + // 'precise' access chain work list with new found object nodes. + // Repeat above steps until the work list is empty. + TNoContractionAssigneeCheckingTraverser checker(accesschain_mapping); + TNoContractionPropagator propagator(&precise_object_accesschains, accesschain_mapping); + + // We have two initial precise work lists to handle: + // 1) precise return nodes + // 2) precise object access chains + // We should process the precise return nodes first and the involved + // objects in the return expression should be added to the precise object + // access chain set. + while (!precise_return_nodes.empty()) { + glslang::TIntermBranch* precise_return_node = *precise_return_nodes.begin(); + propagator.propagateNoContractionInReturnNode(precise_return_node); + precise_return_nodes.erase(precise_return_node); + } + + while (!precise_object_accesschains.empty()) { + // Get the access chain of a precise object from the work list. + ObjectAccessChain precise_object_accesschain = *precise_object_accesschains.begin(); + // Get the symbol id from the access chain. + ObjectAccessChain symbol_id = getFrontElement(precise_object_accesschain); + // Get all the defining nodes of that symbol ID. + std::pair range = + symbol_definition_mapping.equal_range(symbol_id); + // Visits all the assignment nodes of that symbol ID and + // 1) Check if the assignee node is 'precise' or contains 'precise' + // objects. + // 2) Propagate the 'precise' to the top layer object nodes + // in the right side of the assignment operation, update the 'precise' + // work list with new access chains representing the new 'precise' + // objects, and mark arithmetic operations as 'noContraction'. + for (NodeMapping::iterator defining_node_iter = range.first; + defining_node_iter != range.second; defining_node_iter++) { + TIntermOperator* defining_node = defining_node_iter->second; + // Check the assignee node. + auto checker_result = checker.getPrecisenessAndRemainedAccessChain( + defining_node, precise_object_accesschain); + bool& contain_precise = std::get<0>(checker_result); + ObjectAccessChain& remained_accesschain = std::get<1>(checker_result); + // If the assignee node is 'precise' or contains 'precise', propagate the + // 'precise' to the right. Otherwise just skip this assignment node. + if (contain_precise) { + propagator.propagateNoContractionInOneExpression(defining_node, + remained_accesschain); + } + } + // Remove the last processed 'precise' object from the work list. + precise_object_accesschains.erase(precise_object_accesschain); + } +} +}; diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/propagateNoContraction.h b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/propagateNoContraction.h new file mode 100644 index 00000000..8521ad7d --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/propagateNoContraction.h @@ -0,0 +1,55 @@ +// +// Copyright (C) 2015-2016 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +// +// Visit the nodes in the glslang intermediate tree representation to +// propagate 'noContraction' qualifier. +// + +#pragma once + +#include "../Include/intermediate.h" + +namespace glslang { + +// Propagates the 'precise' qualifier for objects (objects marked with +// 'noContraction' qualifier) from the shader source specified 'precise' +// variables to all the involved objects, and add 'noContraction' qualifier for +// the involved arithmetic operations. +// Note that the same qualifier: 'noContraction' is used in both object nodes +// and arithmetic operation nodes, but has different meaning. For object nodes, +// 'noContraction' means the object is 'precise'; and for arithmetic operation +// nodes, it means the operation should not be contracted. +void PropagateNoContraction(const glslang::TIntermediate& intermediate); +}; diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/reflection.cpp b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/reflection.cpp new file mode 100644 index 00000000..50fb6027 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/reflection.cpp @@ -0,0 +1,793 @@ +// +// Copyright (C) 2013-2016 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#include "../Include/Common.h" +#include "reflection.h" +#include "LiveTraverser.h" +#include "localintermediate.h" + +#include "gl_types.h" + +// +// Grow the reflection database through a friend traverser class of TReflection and a +// collection of functions to do a liveness traversal that note what uniforms are used +// in semantically non-dead code. +// +// Can be used multiple times, once per stage, to grow a program reflection. +// +// High-level algorithm for one stage: +// +// 1. Put the entry point on the list of live functions. +// +// 2. Traverse any live function, while skipping if-tests with a compile-time constant +// condition of false, and while adding any encountered function calls to the live +// function list. +// +// Repeat until the live function list is empty. +// +// 3. Add any encountered uniform variables and blocks to the reflection database. +// +// Can be attempted with a failed link, but will return false if recursion had been detected, or +// there wasn't exactly one entry point. +// + +namespace glslang { + +// +// The traverser: mostly pass through, except +// - processing binary nodes to see if they are dereferences of an aggregates to track +// - processing symbol nodes to see if they are non-aggregate objects to track +// +// This ignores semantically dead code by using TLiveTraverser. +// +// This is in the glslang namespace directly so it can be a friend of TReflection. +// + +class TReflectionTraverser : public TLiveTraverser { +public: + TReflectionTraverser(const TIntermediate& i, TReflection& r) : + TLiveTraverser(i), reflection(r) { } + + virtual bool visitBinary(TVisit, TIntermBinary* node); + virtual void visitSymbol(TIntermSymbol* base); + + // Add a simple reference to a uniform variable to the uniform database, no dereference involved. + // However, no dereference doesn't mean simple... it could be a complex aggregate. + void addUniform(const TIntermSymbol& base) + { + if (processedDerefs.find(&base) == processedDerefs.end()) { + processedDerefs.insert(&base); + + // Use a degenerate (empty) set of dereferences to immediately put as at the end of + // the dereference change expected by blowUpActiveAggregate. + TList derefs; + blowUpActiveAggregate(base.getType(), base.getName(), derefs, derefs.end(), -1, -1, 0); + } + } + + void addAttribute(const TIntermSymbol& base) + { + if (processedDerefs.find(&base) == processedDerefs.end()) { + processedDerefs.insert(&base); + + const TString &name = base.getName(); + const TType &type = base.getType(); + + TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name); + if (it == reflection.nameToIndex.end()) { + reflection.nameToIndex[name] = (int)reflection.indexToAttribute.size(); + reflection.indexToAttribute.push_back(TObjectReflection(name, type, 0, mapToGlType(type), 0, 0)); + } + } + } + + // Lookup or calculate the offset of a block member, using the recursively + // defined block offset rules. + int getOffset(const TType& type, int index) + { + const TTypeList& memberList = *type.getStruct(); + + // Don't calculate offset if one is present, it could be user supplied + // and different than what would be calculated. That is, this is faster, + // but not just an optimization. + if (memberList[index].type->getQualifier().hasOffset()) + return memberList[index].type->getQualifier().layoutOffset; + + int memberSize; + int dummyStride; + int offset = 0; + for (int m = 0; m <= index; ++m) { + // modify just the children's view of matrix layout, if there is one for this member + TLayoutMatrix subMatrixLayout = memberList[m].type->getQualifier().layoutMatrix; + int memberAlignment = intermediate.getBaseAlignment(*memberList[m].type, memberSize, dummyStride, + type.getQualifier().layoutPacking == ElpStd140, + subMatrixLayout != ElmNone + ? subMatrixLayout == ElmRowMajor + : type.getQualifier().layoutMatrix == ElmRowMajor); + RoundToPow2(offset, memberAlignment); + if (m < index) + offset += memberSize; + } + + return offset; + } + + // Calculate the block data size. + // Block arrayness is not taken into account, each element is backed by a separate buffer. + int getBlockSize(const TType& blockType) + { + const TTypeList& memberList = *blockType.getStruct(); + int lastIndex = (int)memberList.size() - 1; + int lastOffset = getOffset(blockType, lastIndex); + + int lastMemberSize; + int dummyStride; + intermediate.getBaseAlignment(*memberList[lastIndex].type, lastMemberSize, dummyStride, + blockType.getQualifier().layoutPacking == ElpStd140, + blockType.getQualifier().layoutMatrix == ElmRowMajor); + + return lastOffset + lastMemberSize; + } + + // Traverse the provided deref chain, including the base, and + // - build a full reflection-granularity name, array size, etc. entry out of it, if it goes down to that granularity + // - recursively expand any variable array index in the middle of that traversal + // - recursively expand what's left at the end if the deref chain did not reach down to reflection granularity + // + // arraySize tracks, just for the final dereference in the chain, if there was a specific known size. + // A value of 0 for arraySize will mean to use the full array's size. + void blowUpActiveAggregate(const TType& baseType, const TString& baseName, const TList& derefs, + TList::const_iterator deref, int offset, int blockIndex, int arraySize) + { + // process the part of the dereference chain that was explicit in the shader + TString name = baseName; + const TType* terminalType = &baseType; + for (; deref != derefs.end(); ++deref) { + TIntermBinary* visitNode = *deref; + terminalType = &visitNode->getType(); + int index; + switch (visitNode->getOp()) { + case EOpIndexIndirect: + // Visit all the indices of this array, and for each one add on the remaining dereferencing + for (int i = 0; i < std::max(visitNode->getLeft()->getType().getOuterArraySize(), 1); ++i) { + TString newBaseName = name; + if (baseType.getBasicType() != EbtBlock) + newBaseName.append(TString("[") + String(i) + "]"); + TList::const_iterator nextDeref = deref; + ++nextDeref; + TType derefType(*terminalType, 0); + blowUpActiveAggregate(derefType, newBaseName, derefs, nextDeref, offset, blockIndex, arraySize); + } + + // it was all completed in the recursive calls above + return; + case EOpIndexDirect: + index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst(); + if (baseType.getBasicType() != EbtBlock) + name.append(TString("[") + String(index) + "]"); + break; + case EOpIndexDirectStruct: + index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst(); + if (offset >= 0) + offset += getOffset(visitNode->getLeft()->getType(), index); + if (name.size() > 0) + name.append("."); + name.append((*visitNode->getLeft()->getType().getStruct())[index].type->getFieldName()); + break; + default: + break; + } + } + + // if the terminalType is still too coarse a granularity, this is still an aggregate to expand, expand it... + if (! isReflectionGranularity(*terminalType)) { + if (terminalType->isArray()) { + // Visit all the indices of this array, and for each one, + // fully explode the remaining aggregate to dereference + for (int i = 0; i < std::max(terminalType->getOuterArraySize(), 1); ++i) { + TString newBaseName = name; + newBaseName.append(TString("[") + String(i) + "]"); + TType derefType(*terminalType, 0); + blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0); + } + } else { + // Visit all members of this aggregate, and for each one, + // fully explode the remaining aggregate to dereference + const TTypeList& typeList = *terminalType->getStruct(); + for (int i = 0; i < (int)typeList.size(); ++i) { + TString newBaseName = name; + newBaseName.append(TString(".") + typeList[i].type->getFieldName()); + TType derefType(*terminalType, i); + blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0); + } + } + + // it was all completed in the recursive calls above + return; + } + + // Finally, add a full string to the reflection database, and update the array size if necessary. + // If the dereferenced entity to record is an array, compute the size and update the maximum size. + + // there might not be a final array dereference, it could have been copied as an array object + if (arraySize == 0) + arraySize = mapToGlArraySize(*terminalType); + + TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name); + if (it == reflection.nameToIndex.end()) { + reflection.nameToIndex[name] = (int)reflection.indexToUniform.size(); + reflection.indexToUniform.push_back(TObjectReflection(name, *terminalType, offset, + mapToGlType(*terminalType), + arraySize, blockIndex)); + } else if (arraySize > 1) { + int& reflectedArraySize = reflection.indexToUniform[it->second].size; + reflectedArraySize = std::max(arraySize, reflectedArraySize); + } + } + + // Add a uniform dereference where blocks/struct/arrays are involved in the access. + // Handles the situation where the left node is at the correct or too coarse a + // granularity for reflection. (That is, further dereferences up the tree will be + // skipped.) Earlier dereferences, down the tree, will be handled + // at the same time, and logged to prevent reprocessing as the tree is traversed. + // + // Note: Other things like the following must be caught elsewhere: + // - a simple non-array, non-struct variable (no dereference even conceivable) + // - an aggregrate consumed en masse, without a dereference + // + // So, this code is for cases like + // - a struct/block dereferencing a member (whether the member is array or not) + // - an array of struct + // - structs/arrays containing the above + // + void addDereferencedUniform(TIntermBinary* topNode) + { + // See if too fine-grained to process (wait to get further down the tree) + const TType& leftType = topNode->getLeft()->getType(); + if ((leftType.isVector() || leftType.isMatrix()) && ! leftType.isArray()) + return; + + // We have an array or structure or block dereference, see if it's a uniform + // based dereference (if not, skip it). + TIntermSymbol* base = findBase(topNode); + if (! base || ! base->getQualifier().isUniformOrBuffer()) + return; + + // See if we've already processed this (e.g., in the middle of something + // we did earlier), and if so skip it + if (processedDerefs.find(topNode) != processedDerefs.end()) + return; + + // Process this uniform dereference + + int offset = -1; + int blockIndex = -1; + bool anonymous = false; + + // See if we need to record the block itself + bool block = base->getBasicType() == EbtBlock; + if (block) { + offset = 0; + anonymous = IsAnonymous(base->getName()); + + const TString& blockName = base->getType().getTypeName(); + + if (base->getType().isArray()) { + TType derefType(base->getType(), 0); + + assert(! anonymous); + for (int e = 0; e < base->getType().getCumulativeArraySize(); ++e) + blockIndex = addBlockName(blockName + "[" + String(e) + "]", derefType, + getBlockSize(base->getType())); + } else + blockIndex = addBlockName(blockName, base->getType(), getBlockSize(base->getType())); + } + + // Process the dereference chain, backward, accumulating the pieces for later forward traversal. + // If the topNode is a reflection-granularity-array dereference, don't include that last dereference. + TList derefs; + for (TIntermBinary* visitNode = topNode; visitNode; visitNode = visitNode->getLeft()->getAsBinaryNode()) { + if (isReflectionGranularity(visitNode->getLeft()->getType())) + continue; + + derefs.push_front(visitNode); + processedDerefs.insert(visitNode); + } + processedDerefs.insert(base); + + // See if we have a specific array size to stick to while enumerating the explosion of the aggregate + int arraySize = 0; + if (isReflectionGranularity(topNode->getLeft()->getType()) && topNode->getLeft()->isArray()) { + if (topNode->getOp() == EOpIndexDirect) + arraySize = topNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst() + 1; + } + + // Put the dereference chain together, forward + TString baseName; + if (! anonymous) { + if (block) + baseName = base->getType().getTypeName(); + else + baseName = base->getName(); + } + blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.begin(), offset, blockIndex, arraySize); + } + + int addBlockName(const TString& name, const TType& type, int size) + { + int blockIndex; + TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name); + if (reflection.nameToIndex.find(name) == reflection.nameToIndex.end()) { + blockIndex = (int)reflection.indexToUniformBlock.size(); + reflection.nameToIndex[name] = blockIndex; + reflection.indexToUniformBlock.push_back(TObjectReflection(name, type, -1, -1, size, -1)); + } else + blockIndex = it->second; + + return blockIndex; + } + + // Are we at a level in a dereference chain at which individual active uniform queries are made? + bool isReflectionGranularity(const TType& type) + { + return type.getBasicType() != EbtBlock && type.getBasicType() != EbtStruct; + } + + // For a binary operation indexing into an aggregate, chase down the base of the aggregate. + // Return 0 if the topology does not fit this situation. + TIntermSymbol* findBase(const TIntermBinary* node) + { + TIntermSymbol *base = node->getLeft()->getAsSymbolNode(); + if (base) + return base; + TIntermBinary* left = node->getLeft()->getAsBinaryNode(); + if (! left) + return nullptr; + + return findBase(left); + } + + // + // Translate a glslang sampler type into the GL API #define number. + // + int mapSamplerToGlType(TSampler sampler) + { + if (! sampler.image) { + // a sampler... + switch (sampler.type) { + case EbtFloat: + switch ((int)sampler.dim) { + case Esd1D: + switch ((int)sampler.shadow) { + case false: return sampler.arrayed ? GL_SAMPLER_1D_ARRAY : GL_SAMPLER_1D; + case true: return sampler.arrayed ? GL_SAMPLER_1D_ARRAY_SHADOW : GL_SAMPLER_1D_SHADOW; + } + case Esd2D: + switch ((int)sampler.ms) { + case false: + switch ((int)sampler.shadow) { + case false: return sampler.arrayed ? GL_SAMPLER_2D_ARRAY : GL_SAMPLER_2D; + case true: return sampler.arrayed ? GL_SAMPLER_2D_ARRAY_SHADOW : GL_SAMPLER_2D_SHADOW; + } + case true: return sampler.arrayed ? GL_SAMPLER_2D_MULTISAMPLE_ARRAY : GL_SAMPLER_2D_MULTISAMPLE; + } + case Esd3D: + return GL_SAMPLER_3D; + case EsdCube: + switch ((int)sampler.shadow) { + case false: return sampler.arrayed ? GL_SAMPLER_CUBE_MAP_ARRAY : GL_SAMPLER_CUBE; + case true: return sampler.arrayed ? GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW : GL_SAMPLER_CUBE_SHADOW; + } + case EsdRect: + return sampler.shadow ? GL_SAMPLER_2D_RECT_SHADOW : GL_SAMPLER_2D_RECT; + case EsdBuffer: + return GL_SAMPLER_BUFFER; + } + case EbtInt: + switch ((int)sampler.dim) { + case Esd1D: + return sampler.arrayed ? GL_INT_SAMPLER_1D_ARRAY : GL_INT_SAMPLER_1D; + case Esd2D: + switch ((int)sampler.ms) { + case false: return sampler.arrayed ? GL_INT_SAMPLER_2D_ARRAY : GL_INT_SAMPLER_2D; + case true: return sampler.arrayed ? GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY + : GL_INT_SAMPLER_2D_MULTISAMPLE; + } + case Esd3D: + return GL_INT_SAMPLER_3D; + case EsdCube: + return sampler.arrayed ? GL_INT_SAMPLER_CUBE_MAP_ARRAY : GL_INT_SAMPLER_CUBE; + case EsdRect: + return GL_INT_SAMPLER_2D_RECT; + case EsdBuffer: + return GL_INT_SAMPLER_BUFFER; + } + case EbtUint: + switch ((int)sampler.dim) { + case Esd1D: + return sampler.arrayed ? GL_UNSIGNED_INT_SAMPLER_1D_ARRAY : GL_UNSIGNED_INT_SAMPLER_1D; + case Esd2D: + switch ((int)sampler.ms) { + case false: return sampler.arrayed ? GL_UNSIGNED_INT_SAMPLER_2D_ARRAY : GL_UNSIGNED_INT_SAMPLER_2D; + case true: return sampler.arrayed ? GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY + : GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE; + } + case Esd3D: + return GL_UNSIGNED_INT_SAMPLER_3D; + case EsdCube: + return sampler.arrayed ? GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY : GL_UNSIGNED_INT_SAMPLER_CUBE; + case EsdRect: + return GL_UNSIGNED_INT_SAMPLER_2D_RECT; + case EsdBuffer: + return GL_UNSIGNED_INT_SAMPLER_BUFFER; + } + default: + return 0; + } + } else { + // an image... + switch (sampler.type) { + case EbtFloat: + switch ((int)sampler.dim) { + case Esd1D: + return sampler.arrayed ? GL_IMAGE_1D_ARRAY : GL_IMAGE_1D; + case Esd2D: + switch ((int)sampler.ms) { + case false: return sampler.arrayed ? GL_IMAGE_2D_ARRAY : GL_IMAGE_2D; + case true: return sampler.arrayed ? GL_IMAGE_2D_MULTISAMPLE_ARRAY : GL_IMAGE_2D_MULTISAMPLE; + } + case Esd3D: + return GL_IMAGE_3D; + case EsdCube: + return sampler.arrayed ? GL_IMAGE_CUBE_MAP_ARRAY : GL_IMAGE_CUBE; + case EsdRect: + return GL_IMAGE_2D_RECT; + case EsdBuffer: + return GL_IMAGE_BUFFER; + } + case EbtInt: + switch ((int)sampler.dim) { + case Esd1D: + return sampler.arrayed ? GL_INT_IMAGE_1D_ARRAY : GL_INT_IMAGE_1D; + case Esd2D: + switch ((int)sampler.ms) { + case false: return sampler.arrayed ? GL_INT_IMAGE_2D_ARRAY : GL_INT_IMAGE_2D; + case true: return sampler.arrayed ? GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY : GL_INT_IMAGE_2D_MULTISAMPLE; + } + case Esd3D: + return GL_INT_IMAGE_3D; + case EsdCube: + return sampler.arrayed ? GL_INT_IMAGE_CUBE_MAP_ARRAY : GL_INT_IMAGE_CUBE; + case EsdRect: + return GL_INT_IMAGE_2D_RECT; + case EsdBuffer: + return GL_INT_IMAGE_BUFFER; + } + case EbtUint: + switch ((int)sampler.dim) { + case Esd1D: + return sampler.arrayed ? GL_UNSIGNED_INT_IMAGE_1D_ARRAY : GL_UNSIGNED_INT_IMAGE_1D; + case Esd2D: + switch ((int)sampler.ms) { + case false: return sampler.arrayed ? GL_UNSIGNED_INT_IMAGE_2D_ARRAY : GL_UNSIGNED_INT_IMAGE_2D; + case true: return sampler.arrayed ? GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY + : GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE; + } + case Esd3D: + return GL_UNSIGNED_INT_IMAGE_3D; + case EsdCube: + return sampler.arrayed ? GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY : GL_UNSIGNED_INT_IMAGE_CUBE; + case EsdRect: + return GL_UNSIGNED_INT_IMAGE_2D_RECT; + case EsdBuffer: + return GL_UNSIGNED_INT_IMAGE_BUFFER; + } + default: + return 0; + } + } + } + + // + // Translate a glslang type into the GL API #define number. + // Ignores arrayness. + // + int mapToGlType(const TType& type) + { + switch (type.getBasicType()) { + case EbtSampler: + return mapSamplerToGlType(type.getSampler()); + case EbtStruct: + case EbtBlock: + case EbtVoid: + return 0; + default: + break; + } + + if (type.isVector()) { + int offset = type.getVectorSize() - 2; + switch (type.getBasicType()) { + case EbtFloat: return GL_FLOAT_VEC2 + offset; + case EbtDouble: return GL_DOUBLE_VEC2 + offset; +#ifdef AMD_EXTENSIONS + case EbtFloat16: return GL_FLOAT16_VEC2_NV + offset; +#endif + case EbtInt: return GL_INT_VEC2 + offset; + case EbtUint: return GL_UNSIGNED_INT_VEC2 + offset; + case EbtInt64: return GL_INT64_ARB + offset; + case EbtUint64: return GL_UNSIGNED_INT64_ARB + offset; + case EbtBool: return GL_BOOL_VEC2 + offset; + case EbtAtomicUint: return GL_UNSIGNED_INT_ATOMIC_COUNTER + offset; + default: return 0; + } + } + if (type.isMatrix()) { + switch (type.getBasicType()) { + case EbtFloat: + switch (type.getMatrixCols()) { + case 2: + switch (type.getMatrixRows()) { + case 2: return GL_FLOAT_MAT2; + case 3: return GL_FLOAT_MAT2x3; + case 4: return GL_FLOAT_MAT2x4; + default: return 0; + } + case 3: + switch (type.getMatrixRows()) { + case 2: return GL_FLOAT_MAT3x2; + case 3: return GL_FLOAT_MAT3; + case 4: return GL_FLOAT_MAT3x4; + default: return 0; + } + case 4: + switch (type.getMatrixRows()) { + case 2: return GL_FLOAT_MAT4x2; + case 3: return GL_FLOAT_MAT4x3; + case 4: return GL_FLOAT_MAT4; + default: return 0; + } + } + case EbtDouble: + switch (type.getMatrixCols()) { + case 2: + switch (type.getMatrixRows()) { + case 2: return GL_DOUBLE_MAT2; + case 3: return GL_DOUBLE_MAT2x3; + case 4: return GL_DOUBLE_MAT2x4; + default: return 0; + } + case 3: + switch (type.getMatrixRows()) { + case 2: return GL_DOUBLE_MAT3x2; + case 3: return GL_DOUBLE_MAT3; + case 4: return GL_DOUBLE_MAT3x4; + default: return 0; + } + case 4: + switch (type.getMatrixRows()) { + case 2: return GL_DOUBLE_MAT4x2; + case 3: return GL_DOUBLE_MAT4x3; + case 4: return GL_DOUBLE_MAT4; + default: return 0; + } + } +#ifdef AMD_EXTENSIONS + case EbtFloat16: + switch (type.getMatrixCols()) { + case 2: + switch (type.getMatrixRows()) { + case 2: return GL_FLOAT16_MAT2_AMD; + case 3: return GL_FLOAT16_MAT2x3_AMD; + case 4: return GL_FLOAT16_MAT2x4_AMD; + default: return 0; + } + case 3: + switch (type.getMatrixRows()) { + case 2: return GL_FLOAT16_MAT3x2_AMD; + case 3: return GL_FLOAT16_MAT3_AMD; + case 4: return GL_FLOAT16_MAT3x4_AMD; + default: return 0; + } + case 4: + switch (type.getMatrixRows()) { + case 2: return GL_FLOAT16_MAT4x2_AMD; + case 3: return GL_FLOAT16_MAT4x3_AMD; + case 4: return GL_FLOAT16_MAT4_AMD; + default: return 0; + } + } +#endif + default: + return 0; + } + } + if (type.getVectorSize() == 1) { + switch (type.getBasicType()) { + case EbtFloat: return GL_FLOAT; + case EbtDouble: return GL_DOUBLE; +#ifdef AMD_EXTENSIONS + case EbtFloat16: return GL_FLOAT16_NV; +#endif + case EbtInt: return GL_INT; + case EbtUint: return GL_UNSIGNED_INT; + case EbtInt64: return GL_INT64_ARB; + case EbtUint64: return GL_UNSIGNED_INT64_ARB; + case EbtBool: return GL_BOOL; + case EbtAtomicUint: return GL_UNSIGNED_INT_ATOMIC_COUNTER; + default: return 0; + } + } + + return 0; + } + + int mapToGlArraySize(const TType& type) + { + return type.isArray() ? type.getOuterArraySize() : 1; + } + + TReflection& reflection; + std::set processedDerefs; + +protected: + TReflectionTraverser(TReflectionTraverser&); + TReflectionTraverser& operator=(TReflectionTraverser&); +}; + +// +// Implement the traversal functions of interest. +// + +// To catch dereferenced aggregates that must be reflected. +// This catches them at the highest level possible in the tree. +bool TReflectionTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node) +{ + switch (node->getOp()) { + case EOpIndexDirect: + case EOpIndexIndirect: + case EOpIndexDirectStruct: + addDereferencedUniform(node); + break; + default: + break; + } + + // still need to visit everything below, which could contain sub-expressions + // containing different uniforms + return true; +} + +// To reflect non-dereferenced objects. +void TReflectionTraverser::visitSymbol(TIntermSymbol* base) +{ + if (base->getQualifier().storage == EvqUniform) + addUniform(*base); + + if (intermediate.getStage() == EShLangVertex && base->getQualifier().isPipeInput()) + addAttribute(*base); +} + +// +// Implement TReflection methods. +// + +// Track any required attribute reflection, such as compute shader numthreads. +// +void TReflection::buildAttributeReflection(EShLanguage stage, const TIntermediate& intermediate) +{ + if (stage == EShLangCompute) { + // Remember thread dimensions + for (int dim=0; dim<3; ++dim) + localSize[dim] = intermediate.getLocalSize(dim); + } +} + +// build counter block index associations for buffers +void TReflection::buildCounterIndices() +{ + // search for ones that have counters + for (int i = 0; i < int(indexToUniformBlock.size()); ++i) { + const TString counterName(indexToUniformBlock[i].name + "@count"); + const int index = getIndex(counterName); + + if (index >= 0) + indexToUniformBlock[i].counterIndex = index; + } +} + +// Merge live symbols from 'intermediate' into the existing reflection database. +// +// Returns false if the input is too malformed to do this. +bool TReflection::addStage(EShLanguage stage, const TIntermediate& intermediate) +{ + if (intermediate.getTreeRoot() == nullptr || + intermediate.getNumEntryPoints() != 1 || + intermediate.isRecursive()) + return false; + + buildAttributeReflection(stage, intermediate); + + TReflectionTraverser it(intermediate, *this); + + // put the entry point on the list of functions to process + it.pushFunction(intermediate.getEntryPointMangledName().c_str()); + + // process all the functions + while (! it.functions.empty()) { + TIntermNode* function = it.functions.back(); + it.functions.pop_back(); + function->traverse(&it); + } + + buildCounterIndices(); + + return true; +} + +void TReflection::dump() +{ + printf("Uniform reflection:\n"); + for (size_t i = 0; i < indexToUniform.size(); ++i) + indexToUniform[i].dump(); + printf("\n"); + + printf("Uniform block reflection:\n"); + for (size_t i = 0; i < indexToUniformBlock.size(); ++i) + indexToUniformBlock[i].dump(); + printf("\n"); + + printf("Vertex attribute reflection:\n"); + for (size_t i = 0; i < indexToAttribute.size(); ++i) + indexToAttribute[i].dump(); + printf("\n"); + + if (getLocalSize(0) > 1) { + static const char* axis[] = { "X", "Y", "Z" }; + + for (int dim=0; dim<3; ++dim) + if (getLocalSize(dim) > 1) + printf("Local size %s: %d\n", axis[dim], getLocalSize(dim)); + + printf("\n"); + } + + // printf("Live names\n"); + // for (TNameToIndex::const_iterator it = nameToIndex.begin(); it != nameToIndex.end(); ++it) + // printf("%s: %d\n", it->first.c_str(), it->second); + // printf("\n"); +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/reflection.h b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/reflection.h new file mode 100644 index 00000000..fedfbe8d --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/MachineIndependent/reflection.h @@ -0,0 +1,177 @@ +// +// Copyright (C) 2013-2016 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef _REFLECTION_INCLUDED +#define _REFLECTION_INCLUDED + +#include "../Public/ShaderLang.h" +#include "../Include/Types.h" + +#include +#include + +// +// A reflection database and its interface, consistent with the OpenGL API reflection queries. +// + +namespace glslang { + +class TIntermediate; +class TIntermAggregate; +class TReflectionTraverser; + +// Data needed for just a single object at the granularity exchanged by the reflection API +class TObjectReflection { +public: + TObjectReflection(const TString& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex) : + name(pName), offset(pOffset), + glDefineType(pGLDefineType), size(pSize), index(pIndex), counterIndex(-1), type(pType.clone()) { } + + const TType* const getType() const { return type; } + int getBinding() const + { + if (type == nullptr || !type->getQualifier().hasBinding()) + return -1; + return type->getQualifier().layoutBinding; + } + void dump() const + { + printf("%s: offset %d, type %x, size %d, index %d, binding %d", + name.c_str(), offset, glDefineType, size, index, getBinding() ); + + if (counterIndex != -1) + printf(", counter %d", counterIndex); + + printf("\n"); + } + static TObjectReflection badReflection() { return TObjectReflection(); } + + TString name; + int offset; + int glDefineType; + int size; // data size in bytes for a block, array size for a (non-block) object that's an array + int index; + int counterIndex; + +protected: + TObjectReflection() : offset(-1), glDefineType(-1), size(-1), index(-1), type(nullptr) { } + + const TType* type; +}; + +// The full reflection database +class TReflection { +public: + TReflection() : badReflection(TObjectReflection::badReflection()) + { + for (int dim=0; dim<3; ++dim) + localSize[dim] = 0; + } + + virtual ~TReflection() {} + + // grow the reflection stage by stage + bool addStage(EShLanguage, const TIntermediate&); + + // for mapping a uniform index to a uniform object's description + int getNumUniforms() { return (int)indexToUniform.size(); } + const TObjectReflection& getUniform(int i) const + { + if (i >= 0 && i < (int)indexToUniform.size()) + return indexToUniform[i]; + else + return badReflection; + } + + // for mapping a block index to the block's description + int getNumUniformBlocks() const { return (int)indexToUniformBlock.size(); } + const TObjectReflection& getUniformBlock(int i) const + { + if (i >= 0 && i < (int)indexToUniformBlock.size()) + return indexToUniformBlock[i]; + else + return badReflection; + } + + // for mapping an attribute index to the attribute's description + int getNumAttributes() { return (int)indexToAttribute.size(); } + const TObjectReflection& getAttribute(int i) const + { + if (i >= 0 && i < (int)indexToAttribute.size()) + return indexToAttribute[i]; + else + return badReflection; + } + + // for mapping any name to its index (block names, uniform names and attribute names) + int getIndex(const char* name) const + { + TNameToIndex::const_iterator it = nameToIndex.find(name); + if (it == nameToIndex.end()) + return -1; + else + return it->second; + } + + // see getIndex(const char*) + int getIndex(const TString& name) const { return getIndex(name.c_str()); } + + // Thread local size + unsigned getLocalSize(int dim) const { return dim <= 2 ? localSize[dim] : 0; } + + void dump(); + +protected: + friend class glslang::TReflectionTraverser; + + void buildCounterIndices(); + void buildAttributeReflection(EShLanguage, const TIntermediate&); + + // Need a TString hash: typedef std::unordered_map TNameToIndex; + typedef std::map TNameToIndex; + typedef std::vector TMapIndexToReflection; + + TObjectReflection badReflection; // return for queries of -1 or generally out of range; has expected descriptions with in it for this + TNameToIndex nameToIndex; // maps names to indexes; can hold all types of data: uniform/buffer and which function names have been processed + TMapIndexToReflection indexToUniform; + TMapIndexToReflection indexToUniformBlock; + TMapIndexToReflection indexToAttribute; + + unsigned int localSize[3]; +}; + +} // end namespace glslang + +#endif // _REFLECTION_INCLUDED diff --git a/love/src/jni/love/src/libraries/glslang/glslang/OSDependent/Unix/ossource.cpp b/love/src/jni/love/src/libraries/glslang/glslang/OSDependent/Unix/ossource.cpp new file mode 100644 index 00000000..f59bbceb --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/OSDependent/Unix/ossource.cpp @@ -0,0 +1,204 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +// +// This file contains the Linux-specific functions +// +#include "../osinclude.h" +#include "../../../OGLCompilersDLL/InitializeDll.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace glslang { + +// +// Thread cleanup +// + +// +// Wrapper for Linux call to DetachThread. This is required as pthread_cleanup_push() expects +// the cleanup routine to return void. +// +static void DetachThreadLinux(void *) +{ + DetachThread(); +} + +// +// Registers cleanup handler, sets cancel type and state, and executes the thread specific +// cleanup handler. This function will be called in the Standalone.cpp for regression +// testing. When OpenGL applications are run with the driver code, Linux OS does the +// thread cleanup. +// +void OS_CleanupThreadData(void) +{ +#ifdef __ANDROID__ + DetachThreadLinux(NULL); +#else + int old_cancel_state, old_cancel_type; + void *cleanupArg = NULL; + + // + // Set thread cancel state and push cleanup handler. + // + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_cancel_state); + pthread_cleanup_push(DetachThreadLinux, (void *) cleanupArg); + + // + // Put the thread in deferred cancellation mode. + // + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &old_cancel_type); + + // + // Pop cleanup handler and execute it prior to unregistering the cleanup handler. + // + pthread_cleanup_pop(1); + + // + // Restore the thread's previous cancellation mode. + // + pthread_setcanceltype(old_cancel_state, NULL); +#endif +} + +// +// Thread Local Storage Operations +// +inline OS_TLSIndex PthreadKeyToTLSIndex(pthread_key_t key) +{ + return (OS_TLSIndex)((uintptr_t)key + 1); +} + +inline pthread_key_t TLSIndexToPthreadKey(OS_TLSIndex nIndex) +{ + return (pthread_key_t)((uintptr_t)nIndex - 1); +} + +OS_TLSIndex OS_AllocTLSIndex() +{ + pthread_key_t pPoolIndex; + + // + // Create global pool key. + // + if ((pthread_key_create(&pPoolIndex, NULL)) != 0) { + assert(0 && "OS_AllocTLSIndex(): Unable to allocate Thread Local Storage"); + return OS_INVALID_TLS_INDEX; + } + else + return PthreadKeyToTLSIndex(pPoolIndex); +} + +bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue) +{ + if (nIndex == OS_INVALID_TLS_INDEX) { + assert(0 && "OS_SetTLSValue(): Invalid TLS Index"); + return false; + } + + if (pthread_setspecific(TLSIndexToPthreadKey(nIndex), lpvValue) == 0) + return true; + else + return false; +} + +void* OS_GetTLSValue(OS_TLSIndex nIndex) +{ + // + // This function should return 0 if nIndex is invalid. + // + assert(nIndex != OS_INVALID_TLS_INDEX); + return pthread_getspecific(TLSIndexToPthreadKey(nIndex)); +} + +bool OS_FreeTLSIndex(OS_TLSIndex nIndex) +{ + if (nIndex == OS_INVALID_TLS_INDEX) { + assert(0 && "OS_SetTLSValue(): Invalid TLS Index"); + return false; + } + + // + // Delete the global pool key. + // + if (pthread_key_delete(TLSIndexToPthreadKey(nIndex)) == 0) + return true; + else + return false; +} + +namespace { + pthread_mutex_t gMutex; +} + +void InitGlobalLock() +{ + pthread_mutexattr_t mutexattr; + pthread_mutexattr_init(&mutexattr); + pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&gMutex, &mutexattr); +} + +void GetGlobalLock() +{ + pthread_mutex_lock(&gMutex); +} + +void ReleaseGlobalLock() +{ + pthread_mutex_unlock(&gMutex); +} + +// #define DUMP_COUNTERS + +void OS_DumpMemoryCounters() +{ +#ifdef DUMP_COUNTERS + struct rusage usage; + + if (getrusage(RUSAGE_SELF, &usage) == 0) + printf("Working set size: %ld\n", usage.ru_maxrss * 1024); +#else + printf("Recompile with DUMP_COUNTERS defined to see counters.\n"); +#endif +} + +} // end namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/OSDependent/Windows/main.cpp b/love/src/jni/love/src/libraries/glslang/glslang/OSDependent/Windows/main.cpp new file mode 100644 index 00000000..0217e0a6 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/OSDependent/Windows/main.cpp @@ -0,0 +1,74 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#include "glslang/OGLCompilersDLL/InitializeDll.h" + +#define STRICT +#define VC_EXTRALEAN 1 +#include +#include + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + + if (! glslang::InitProcess()) + return FALSE; + break; + case DLL_THREAD_ATTACH: + + if (! glslang::InitThread()) + return FALSE; + break; + + case DLL_THREAD_DETACH: + + if (! glslang::DetachThread()) + return FALSE; + break; + + case DLL_PROCESS_DETACH: + + glslang::DetachProcess(); + break; + + default: + assert(0 && "DllMain(): Reason for calling DLL Main is unknown"); + return FALSE; + } + + return TRUE; +} diff --git a/love/src/jni/love/src/libraries/glslang/glslang/OSDependent/Windows/ossource.cpp b/love/src/jni/love/src/libraries/glslang/glslang/OSDependent/Windows/ossource.cpp new file mode 100644 index 00000000..870840c5 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/OSDependent/Windows/ossource.cpp @@ -0,0 +1,147 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#include "../osinclude.h" + +#define STRICT +#define VC_EXTRALEAN 1 +#include +#include +#include +#include +#include +#include + +// +// This file contains the Window-OS-specific functions +// + +#if !(defined(_WIN32) || defined(_WIN64)) +#error Trying to build a windows specific file in a non windows build. +#endif + +namespace glslang { + +inline OS_TLSIndex ToGenericTLSIndex (DWORD handle) +{ + return (OS_TLSIndex)((uintptr_t)handle + 1); +} + +inline DWORD ToNativeTLSIndex (OS_TLSIndex nIndex) +{ + return (DWORD)((uintptr_t)nIndex - 1); +} + +// +// Thread Local Storage Operations +// +OS_TLSIndex OS_AllocTLSIndex() +{ + DWORD dwIndex = TlsAlloc(); + if (dwIndex == TLS_OUT_OF_INDEXES) { + assert(0 && "OS_AllocTLSIndex(): Unable to allocate Thread Local Storage"); + return OS_INVALID_TLS_INDEX; + } + + return ToGenericTLSIndex(dwIndex); +} + +bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue) +{ + if (nIndex == OS_INVALID_TLS_INDEX) { + assert(0 && "OS_SetTLSValue(): Invalid TLS Index"); + return false; + } + + if (TlsSetValue(ToNativeTLSIndex(nIndex), lpvValue)) + return true; + else + return false; +} + +void* OS_GetTLSValue(OS_TLSIndex nIndex) +{ + assert(nIndex != OS_INVALID_TLS_INDEX); + return TlsGetValue(ToNativeTLSIndex(nIndex)); +} + +bool OS_FreeTLSIndex(OS_TLSIndex nIndex) +{ + if (nIndex == OS_INVALID_TLS_INDEX) { + assert(0 && "OS_SetTLSValue(): Invalid TLS Index"); + return false; + } + + if (TlsFree(ToNativeTLSIndex(nIndex))) + return true; + else + return false; +} + +HANDLE GlobalLock; + +void InitGlobalLock() +{ + GlobalLock = CreateMutex(0, false, 0); +} + +void GetGlobalLock() +{ + WaitForSingleObject(GlobalLock, INFINITE); +} + +void ReleaseGlobalLock() +{ + ReleaseMutex(GlobalLock); +} + +unsigned int __stdcall EnterGenericThread (void* entry) +{ + return ((TThreadEntrypoint)entry)(0); +} + +//#define DUMP_COUNTERS + +void OS_DumpMemoryCounters() +{ +#ifdef DUMP_COUNTERS + PROCESS_MEMORY_COUNTERS counters; + GetProcessMemoryInfo(GetCurrentProcess(), &counters, sizeof(counters)); + printf("Working set size: %d\n", counters.WorkingSetSize); +#else + printf("Recompile with DUMP_COUNTERS defined to see counters.\n"); +#endif +} + +} // namespace glslang diff --git a/love/src/jni/love/src/libraries/glslang/glslang/OSDependent/osinclude.h b/love/src/jni/love/src/libraries/glslang/glslang/OSDependent/osinclude.h new file mode 100644 index 00000000..218abe4f --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/OSDependent/osinclude.h @@ -0,0 +1,63 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef __OSINCLUDE_H +#define __OSINCLUDE_H + +namespace glslang { + +// +// Thread Local Storage Operations +// +typedef void* OS_TLSIndex; +#define OS_INVALID_TLS_INDEX ((void*)0) + +OS_TLSIndex OS_AllocTLSIndex(); +bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue); +bool OS_FreeTLSIndex(OS_TLSIndex nIndex); +void* OS_GetTLSValue(OS_TLSIndex nIndex); + +void InitGlobalLock(); +void GetGlobalLock(); +void ReleaseGlobalLock(); + +typedef unsigned int (*TThreadEntrypoint)(void*); + +void OS_CleanupThreadData(void); + +void OS_DumpMemoryCounters(); + +} // end namespace glslang + +#endif // __OSINCLUDE_H diff --git a/love/src/jni/love/src/libraries/glslang/glslang/Public/ShaderLang.h b/love/src/jni/love/src/libraries/glslang/glslang/Public/ShaderLang.h new file mode 100644 index 00000000..35d84636 --- /dev/null +++ b/love/src/jni/love/src/libraries/glslang/glslang/Public/ShaderLang.h @@ -0,0 +1,682 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2013-2016 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +#ifndef _COMPILER_INTERFACE_INCLUDED_ +#define _COMPILER_INTERFACE_INCLUDED_ + +#include "../Include/ResourceLimits.h" +#include "../MachineIndependent/Versions.h" + +#include +#include + +#ifdef _WIN32 +#define C_DECL __cdecl +//#ifdef SH_EXPORTING +// #define SH_IMPORT_EXPORT __declspec(dllexport) +//#else +// #define SH_IMPORT_EXPORT __declspec(dllimport) +//#endif +#define SH_IMPORT_EXPORT +#else +#define SH_IMPORT_EXPORT +#ifndef __fastcall +#define __fastcall +#endif +#define C_DECL +#endif + +// +// This is the platform independent interface between an OGL driver +// and the shading language compiler/linker. +// + +#ifdef __cplusplus + extern "C" { +#endif + +// +// Call before doing any other compiler/linker operations. +// +// (Call once per process, not once per thread.) +// +SH_IMPORT_EXPORT int ShInitialize(); + +// +// Call this at process shutdown to clean up memory. +// +SH_IMPORT_EXPORT int __fastcall ShFinalize(); + +// +// Types of languages the compiler can consume. +// +typedef enum { + EShLangVertex, + EShLangTessControl, + EShLangTessEvaluation, + EShLangGeometry, + EShLangFragment, + EShLangCompute, + EShLangCount, +} EShLanguage; // would be better as stage, but this is ancient now + +typedef enum { + EShLangVertexMask = (1 << EShLangVertex), + EShLangTessControlMask = (1 << EShLangTessControl), + EShLangTessEvaluationMask = (1 << EShLangTessEvaluation), + EShLangGeometryMask = (1 << EShLangGeometry), + EShLangFragmentMask = (1 << EShLangFragment), + EShLangComputeMask = (1 << EShLangCompute), +} EShLanguageMask; + +namespace glslang { + +class TType; + +typedef enum { + EShSourceNone, + EShSourceGlsl, + EShSourceHlsl, +} EShSource; // if EShLanguage were EShStage, this could be EShLanguage instead + +typedef enum { + EShClientNone, + EShClientVulkan, + EShClientOpenGL, +} EShClient; + +typedef enum { + EShTargetNone, + EshTargetSpv, +} EShTargetLanguage; + +struct TInputLanguage { + EShSource languageFamily; // redundant information with other input, this one overrides when not EShSourceNone + EShLanguage stage; // redundant information with other input, this one overrides when not EShSourceNone + EShClient dialect; + int dialectVersion; // version of client's language definition, not the client (when not EShClientNone) +}; + +struct TClient { + EShClient client; + int version; // version of client itself (not the client's input dialect) +}; + +struct TTarget { + EShTargetLanguage language; + unsigned int version; // the version to target, if SPIR-V, defined by "word 1" of the SPIR-V binary header +}; + +// All source/client/target versions and settings. +// Can override previous methods of setting, when items are set here. +// Expected to grow, as more are added, rather than growing parameter lists. +struct TEnvironment { + TInputLanguage input; // definition of the input language + TClient client; // what client is the overall compilation being done for? + TTarget target; // what to generate +}; + +const char* StageName(EShLanguage); + +} // end namespace glslang + +// +// Types of output the linker will create. +// +typedef enum { + EShExVertexFragment, + EShExFragment +} EShExecutable; + +// +// Optimization level for the compiler. +// +typedef enum { + EShOptNoGeneration, + EShOptNone, + EShOptSimple, // Optimizations that can be done quickly + EShOptFull, // Optimizations that will take more time +} EShOptimizationLevel; + +// +// Texture and Sampler transformation mode. +// +typedef enum { + EShTexSampTransKeep, // keep textures and samplers as is (default) + EShTexSampTransUpgradeTextureRemoveSampler, // change texture w/o embeded sampler into sampled texture and throw away all samplers +} EShTextureSamplerTransformMode; + +// +// Message choices for what errors and warnings are given. +// +enum EShMessages { + EShMsgDefault = 0, // default is to give all required errors and extra warnings + EShMsgRelaxedErrors = (1 << 0), // be liberal in accepting input + EShMsgSuppressWarnings = (1 << 1), // suppress all warnings, except those required by the specification + EShMsgAST = (1 << 2), // print the AST intermediate representation + EShMsgSpvRules = (1 << 3), // issue messages for SPIR-V generation + EShMsgVulkanRules = (1 << 4), // issue messages for Vulkan-requirements of GLSL for SPIR-V + EShMsgOnlyPreprocessor = (1 << 5), // only print out errors produced by the preprocessor + EShMsgReadHlsl = (1 << 6), // use HLSL parsing rules and semantics + EShMsgCascadingErrors = (1 << 7), // get cascading errors; risks error-recovery issues, instead of an early exit + EShMsgKeepUncalled = (1 << 8), // for testing, don't eliminate uncalled functions + EShMsgHlslOffsets = (1 << 9), // allow block offsets to follow HLSL rules instead of GLSL rules + EShMsgDebugInfo = (1 << 10), // save debug information +}; + +// +// Build a table for bindings. This can be used for locating +// attributes, uniforms, globals, etc., as needed. +// +typedef struct { + const char* name; + int binding; +} ShBinding; + +typedef struct { + int numBindings; + ShBinding* bindings; // array of bindings +} ShBindingTable; + +// +// ShHandle held by but opaque to the driver. It is allocated, +// managed, and de-allocated by the compiler/linker. It's contents +// are defined by and used by the compiler and linker. For example, +// symbol table information and object code passed from the compiler +// to the linker can be stored where ShHandle points. +// +// If handle creation fails, 0 will be returned. +// +typedef void* ShHandle; + +// +// Driver calls these to create and destroy compiler/linker +// objects. +// +SH_IMPORT_EXPORT ShHandle ShConstructCompiler(const EShLanguage, int debugOptions); // one per shader +SH_IMPORT_EXPORT ShHandle ShConstructLinker(const EShExecutable, int debugOptions); // one per shader pair +SH_IMPORT_EXPORT ShHandle ShConstructUniformMap(); // one per uniform namespace (currently entire program object) +SH_IMPORT_EXPORT void ShDestruct(ShHandle); + +// +// The return value of ShCompile is boolean, non-zero indicating +// success. +// +// The info-log should be written by ShCompile into +// ShHandle, so it can answer future queries. +// +SH_IMPORT_EXPORT int ShCompile( + const ShHandle, + const char* const shaderStrings[], + const int numStrings, + const int* lengths, + const EShOptimizationLevel, + const TBuiltInResource *resources, + int debugOptions, + int defaultVersion = 110, // use 100 for ES environment, overridden by #version in shader + bool forwardCompatible = false, // give errors for use of deprecated features + EShMessages messages = EShMsgDefault // warnings and errors + ); + +SH_IMPORT_EXPORT int ShLinkExt( + const ShHandle, // linker object + const ShHandle h[], // compiler objects to link together + const int numHandles); + +// +// ShSetEncrpytionMethod is a place-holder for specifying +// how source code is encrypted. +// +SH_IMPORT_EXPORT void ShSetEncryptionMethod(ShHandle); + +// +// All the following return 0 if the information is not +// available in the object passed down, or the object is bad. +// +SH_IMPORT_EXPORT const char* ShGetInfoLog(const ShHandle); +SH_IMPORT_EXPORT const void* ShGetExecutable(const ShHandle); +SH_IMPORT_EXPORT int ShSetVirtualAttributeBindings(const ShHandle, const ShBindingTable*); // to detect user aliasing +SH_IMPORT_EXPORT int ShSetFixedAttributeBindings(const ShHandle, const ShBindingTable*); // to force any physical mappings +// +// Tell the linker to never assign a vertex attribute to this list of physical attributes +// +SH_IMPORT_EXPORT int ShExcludeAttributes(const ShHandle, int *attributes, int count); + +// +// Returns the location ID of the named uniform. +// Returns -1 if error. +// +SH_IMPORT_EXPORT int ShGetUniformLocation(const ShHandle uniformMap, const char* name); + +#ifdef __cplusplus + } // end extern "C" +#endif + +//////////////////////////////////////////////////////////////////////////////////////////// +// +// Deferred-Lowering C++ Interface +// ----------------------------------- +// +// Below is a new alternate C++ interface, which deprecates the above +// opaque handle-based interface. +// +// The below is further designed to handle multiple compilation units per stage, where +// the intermediate results, including the parse tree, are preserved until link time, +// rather than the above interface which is designed to have each compilation unit +// lowered at compile time. In the above model, linking occurs on the lowered results, +// whereas in this model intra-stage linking can occur at the parse tree +// (treeRoot in TIntermediate) level, and then a full stage can be lowered. +// + +#include +#include +#include + +class TCompiler; +class TInfoSink; + +namespace glslang { + +const char* GetEsslVersionString(); +const char* GetGlslVersionString(); +int GetKhronosToolId(); + +class TIntermediate; +class TProgram; +class TPoolAllocator; + +// Call this exactly once per process before using anything else +bool InitializeProcess(); + +// Call once per process to tear down everything +void FinalizeProcess(); + +// Resource type for IO resolver +enum TResourceType { + EResSampler, + EResTexture, + EResImage, + EResUbo, + EResSsbo, + EResUav, + EResCount +}; + +// Make one TShader per shader that you will link into a program. Then provide +// the shader through setStrings() or setStringsWithLengths(), then call parse(), +// then query the info logs. +// Optionally use setPreamble() to set a special shader string that will be +// processed before all others but won't affect the validity of #version. +// +// N.B.: Does not yet support having the same TShader instance being linked into +// multiple programs. +// +// N.B.: Destruct a linked program *before* destructing the shaders linked into it. +// +class TShader { +public: + explicit TShader(EShLanguage); + virtual ~TShader(); + void setStrings(const char* const* s, int n); + void setStringsWithLengths(const char* const* s, const int* l, int n); + void setStringsWithLengthsAndNames( + const char* const* s, const int* l, const char* const* names, int n); + void setPreamble(const char* s) { preamble = s; } + void setEntryPoint(const char* entryPoint); + void setSourceEntryPoint(const char* sourceEntryPointName); + void addProcesses(const std::vector&); + + // IO resolver binding data: see comments in ShaderLang.cpp + void setShiftBinding(TResourceType res, unsigned int base); + void setShiftSamplerBinding(unsigned int base); // DEPRECATED: use setShiftBinding + void setShiftTextureBinding(unsigned int base); // DEPRECATED: use setShiftBinding + void setShiftImageBinding(unsigned int base); // DEPRECATED: use setShiftBinding + void setShiftUboBinding(unsigned int base); // DEPRECATED: use setShiftBinding + void setShiftUavBinding(unsigned int base); // DEPRECATED: use setShiftBinding + void setShiftCbufferBinding(unsigned int base); // synonym for setShiftUboBinding + void setShiftSsboBinding(unsigned int base); // DEPRECATED: use setShiftBinding + void setShiftBindingForSet(TResourceType res, unsigned int base, unsigned int set); + void setResourceSetBinding(const std::vector& base); + void setAutoMapBindings(bool map); + void setAutoMapLocations(bool map); + void setInvertY(bool invert); + void setHlslIoMapping(bool hlslIoMap); + void setFlattenUniformArrays(bool flatten); + void setNoStorageFormat(bool useUnknownFormat); + void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode); + + // For setting up the environment (initialized in the constructor): + void setEnvInput(EShSource lang, EShLanguage envStage, EShClient client, int version) + { + environment.input.languageFamily = lang; + environment.input.stage = envStage; + environment.input.dialect = client; + environment.input.dialectVersion = version; + } + void setEnvClient(EShClient client, int version) + { + environment.client.client = client; + environment.client.version = version; + } + void setEnvTarget(EShTargetLanguage lang, unsigned int version) + { + environment.target.language = lang; + environment.target.version = version; + } + + // Interface to #include handlers. + // + // To support #include, a client of Glslang does the following: + // 1. Call setStringsWithNames to set the source strings and associated + // names. For example, the names could be the names of the files + // containing the shader sources. + // 2. Call parse with an Includer. + // + // When the Glslang parser encounters an #include directive, it calls + // the Includer's include method with the requested include name + // together with the current string name. The returned IncludeResult + // contains the fully resolved name of the included source, together + // with the source text that should replace the #include directive + // in the source stream. After parsing that source, Glslang will + // release the IncludeResult object. + class Includer { + public: + // An IncludeResult contains the resolved name and content of a source + // inclusion. + struct IncludeResult { + IncludeResult(const std::string& headerName, const char* const headerData, const size_t headerLength, void* userData) : + headerName(headerName), headerData(headerData), headerLength(headerLength), userData(userData) { } + // For a successful inclusion, the fully resolved name of the requested + // include. For example, in a file system-based includer, full resolution + // should convert a relative path name into an absolute path name. + // For a failed inclusion, this is an empty string. + const std::string headerName; + // The content and byte length of the requested inclusion. The + // Includer producing this IncludeResult retains ownership of the + // storage. + // For a failed inclusion, the header + // field points to a string containing error details. + const char* const headerData; + const size_t headerLength; + // Include resolver's context. + void* userData; + protected: + IncludeResult& operator=(const IncludeResult&); + IncludeResult(); + }; + + // For both include methods below: + // + // Resolves an inclusion request by name, current source name, + // and include depth. + // On success, returns an IncludeResult containing the resolved name + // and content of the include. + // On failure, returns a nullptr, or an IncludeResult + // with an empty string for the headerName and error details in the + // header field. + // The Includer retains ownership of the contents + // of the returned IncludeResult value, and those contents must + // remain valid until the releaseInclude method is called on that + // IncludeResult object. + // + // Note "local" vs. "system" is not an "either/or": "local" is an + // extra thing to do over "system". Both might get called, as per + // the C++ specification. + + // For the "system" or <>-style includes; search the "system" paths. + virtual IncludeResult* includeSystem(const char* /*headerName*/, + const char* /*includerName*/, + size_t /*inclusionDepth*/) { return nullptr; } + + // For the "local"-only aspect of a "" include. Should not search in the + // "system" paths, because on returning a failure, the parser will + // call includeSystem() to look in the "system" locations. + virtual IncludeResult* includeLocal(const char* /*headerName*/, + const char* /*includerName*/, + size_t /*inclusionDepth*/) { return nullptr; } + + // Signals that the parser will no longer use the contents of the + // specified IncludeResult. + virtual void releaseInclude(IncludeResult*) = 0; + virtual ~Includer() {} + }; + + // Fail all Includer searches + class ForbidIncluder : public Includer { + public: + virtual void releaseInclude(IncludeResult*) override { } + }; + + bool parse(const TBuiltInResource*, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile, + bool forwardCompatible, EShMessages, Includer&); + + bool parse(const TBuiltInResource* res, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile, + bool forwardCompatible, EShMessages messages) + { + TShader::ForbidIncluder includer; + return parse(res, defaultVersion, defaultProfile, forceDefaultVersionAndProfile, forwardCompatible, messages, includer); + } + + // Equivalent to parse() without a default profile and without forcing defaults. + bool parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages) + { + return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages); + } + + bool parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages, + Includer& includer) + { + return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages, includer); + } + + bool preprocess(const TBuiltInResource* builtInResources, + int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile, + bool forwardCompatible, EShMessages message, std::string* outputString, + Includer& includer); + + const char* getInfoLog(); + const char* getInfoDebugLog(); + EShLanguage getStage() const { return stage; } + TIntermediate* getIntermediate() const { return intermediate; } + +protected: + TPoolAllocator* pool; + EShLanguage stage; + TCompiler* compiler; + TIntermediate* intermediate; + TInfoSink* infoSink; + // strings and lengths follow the standard for glShaderSource: + // strings is an array of numStrings pointers to string data. + // lengths can be null, but if not it is an array of numStrings + // integers containing the length of the associated strings. + // if lengths is null or lengths[n] < 0 the associated strings[n] is + // assumed to be null-terminated. + // stringNames is the optional names for all the strings. If stringNames + // is null, then none of the strings has name. If a certain element in + // stringNames is null, then the corresponding string does not have name. + const char* const* strings; + const int* lengths; + const char* const* stringNames; + const char* preamble; + int numStrings; + + // a function in the source string can be renamed FROM this TO the name given in setEntryPoint. + std::string sourceEntryPointName; + + TEnvironment environment; + + friend class TProgram; + +private: + TShader& operator=(TShader&); +}; + +class TReflection; +class TIoMapper; + +// Allows to customize the binding layout after linking. +// All used uniform variables will invoke at least validateBinding. +// If validateBinding returned true then the other resolveBinding, +// resolveSet, and resolveLocation are invoked to resolve the binding +// and descriptor set index respectively. +// +// Invocations happen in a particular order: +// 1) all shader inputs +// 2) all shader outputs +// 3) all uniforms with binding and set already defined +// 4) all uniforms with binding but no set defined +// 5) all uniforms with set but no binding defined +// 6) all uniforms with no binding and no set defined +// +// mapIO will use this resolver in two phases. The first +// phase is a notification phase, calling the corresponging +// notifiy callbacks, this phase ends with a call to endNotifications. +// Phase two starts directly after the call to endNotifications +// and calls all other callbacks to validate and to get the +// bindings, sets, locations, component and color indices. +// +// NOTE: that still limit checks are applied to bindings and sets +// and may result in an error. +class TIoMapResolver +{ +public: + virtual ~TIoMapResolver() {} + + // Should return true if the resulting/current binding would be okay. + // Basic idea is to do aliasing binding checks with this. + virtual bool validateBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; + // Should return a value >= 0 if the current binding should be overridden. + // Return -1 if the current binding (including no binding) should be kept. + virtual int resolveBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; + // Should return a value >= 0 if the current set should be overridden. + // Return -1 if the current set (including no set) should be kept. + virtual int resolveSet(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; + // Should return a value >= 0 if the current location should be overridden. + // Return -1 if the current location (including no location) should be kept. + virtual int resolveUniformLocation(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; + // Should return true if the resulting/current setup would be okay. + // Basic idea is to do aliasing checks and reject invalid semantic names. + virtual bool validateInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; + // Should return a value >= 0 if the current location should be overridden. + // Return -1 if the current location (including no location) should be kept. + virtual int resolveInOutLocation(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; + // Should return a value >= 0 if the current component index should be overridden. + // Return -1 if the current component index (including no index) should be kept. + virtual int resolveInOutComponent(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; + // Should return a value >= 0 if the current color index should be overridden. + // Return -1 if the current color index (including no index) should be kept. + virtual int resolveInOutIndex(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; + // Notification of a uniform variable + virtual void notifyBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; + // Notification of a in or out variable + virtual void notifyInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; + // Called by mapIO when it has finished the notify pass + virtual void endNotifications(EShLanguage stage) = 0; + // Called by mapIO when it starts its notify pass for the given stage + virtual void beginNotifications(EShLanguage stage) = 0; + // Called by mipIO when it starts its resolve pass for the given stage + virtual void beginResolve(EShLanguage stage) = 0; + // Called by mapIO when it has finished the resolve pass + virtual void endResolve(EShLanguage stage) = 0; +}; + +// Make one TProgram per set of shaders that will get linked together. Add all +// the shaders that are to be linked together. After calling shader.parse() +// for all shaders, call link(). +// +// N.B.: Destruct a linked program *before* destructing the shaders linked into it. +// +class TProgram { +public: + TProgram(); + virtual ~TProgram(); + void addShader(TShader* shader) { stages[shader->stage].push_back(shader); } + + // Link Validation interface + bool link(EShMessages); + const char* getInfoLog(); + const char* getInfoDebugLog(); + + TIntermediate* getIntermediate(EShLanguage stage) const { return intermediate[stage]; } + + // Reflection Interface + bool buildReflection(); // call first, to do liveness analysis, index mapping, etc.; returns false on failure + int getNumLiveUniformVariables() const; // can be used for glGetProgramiv(GL_ACTIVE_UNIFORMS) + int getNumLiveUniformBlocks() const; // can be used for glGetProgramiv(GL_ACTIVE_UNIFORM_BLOCKS) + const char* getUniformName(int index) const; // can be used for "name" part of glGetActiveUniform() + const char* getUniformBlockName(int blockIndex) const; // can be used for glGetActiveUniformBlockName() + int getUniformBlockSize(int blockIndex) const; // can be used for glGetActiveUniformBlockiv(UNIFORM_BLOCK_DATA_SIZE) + int getUniformIndex(const char* name) const; // can be used for glGetUniformIndices() + int getUniformBinding(int index) const; // returns the binding number + int getUniformBlockIndex(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_BLOCK_INDEX) + int getUniformBlockCounterIndex(int index) const; // returns block index of associated counter. + int getUniformType(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_TYPE) + int getUniformBufferOffset(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_OFFSET) + int getUniformArraySize(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_SIZE) + int getNumLiveAttributes() const; // can be used for glGetProgramiv(GL_ACTIVE_ATTRIBUTES) + unsigned getLocalSize(int dim) const; // return dim'th local size + const char *getAttributeName(int index) const; // can be used for glGetActiveAttrib() + int getAttributeType(int index) const; // can be used for glGetActiveAttrib() + const TType* getUniformTType(int index) const; // returns a TType* + const TType* getUniformBlockTType(int index) const; // returns a TType* + const TType* getAttributeTType(int index) const; // returns a TType* + + void dumpReflection(); + + // I/O mapping: apply base offsets and map live unbound variables + // If resolver is not provided it uses the previous approach + // and respects auto assignment and offsets. + bool mapIO(TIoMapResolver* resolver = NULL); + +protected: + bool linkStage(EShLanguage, EShMessages); + + TPoolAllocator* pool; + std::list stages[EShLangCount]; + TIntermediate* intermediate[EShLangCount]; + bool newedIntermediate[EShLangCount]; // track which intermediate were "new" versus reusing a singleton unit in a stage + TInfoSink* infoSink; + TReflection* reflection; + TIoMapper* ioMapper; + bool linked; + +private: + TProgram(TProgram&); + TProgram& operator=(TProgram&); +}; + +} // end namespace glslang + +#endif // _COMPILER_INTERFACE_INCLUDED_ diff --git a/love/src/jni/love/src/libraries/lodepng/lodepng.cpp b/love/src/jni/love/src/libraries/lodepng/lodepng.cpp old mode 100644 new mode 100755 index 7f1b1c12..37b0562b --- a/love/src/jni/love/src/libraries/lodepng/lodepng.cpp +++ b/love/src/jni/love/src/libraries/lodepng/lodepng.cpp @@ -1,7 +1,7 @@ /* -LodePNG version 20141130 +LodePNG version 20170917 -Copyright (c) 2005-2014 Lode Vandevenne +Copyright (c) 2005-2017 Lode Vandevenne This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,18 +30,17 @@ Rename this file to lodepng.cpp to use it for C++, or to lodepng.c to use it for #include "lodepng.h" +#include #include #include -#ifdef LODEPNG_COMPILE_CPP -#include -#endif /*LODEPNG_COMPILE_CPP*/ - #if defined(_MSC_VER) && (_MSC_VER >= 1310) /*Visual Studio: A few warning types are not desired here.*/ #pragma warning( disable : 4244 ) /*implicit conversions: not warned by gcc -Wall -Wextra and requires too much casts*/ #pragma warning( disable : 4996 ) /*VS does not like fopen, but fopen_s is not standard C so unusable here*/ #endif /*_MSC_VER */ +const char* LODEPNG_VERSION_STRING = "20170917"; + /* This source file is built up in the following large parts. The code sections with the "LODEPNG_COMPILE_" #defines divide this up further in an intermixed way. @@ -197,15 +196,6 @@ static unsigned uivector_push_back(uivector* p, unsigned c) p->data[p->size - 1] = c; return 1; } - -/*copy q to p, returns 1 if success, 0 if failure ==> nothing done*/ -static unsigned uivector_copy(uivector* p, const uivector* q) -{ - size_t i; - if(!uivector_resize(p, q->size)) return 0; - for(i = 0; i != q->size; ++i) p->data[i] = q->data[i]; - return 1; -} #endif /*LODEPNG_COMPILE_ENCODER*/ #endif /*LODEPNG_COMPILE_ZLIB*/ @@ -258,17 +248,6 @@ static void ucvector_init(ucvector* p) p->data = NULL; p->size = p->allocsize = 0; } - -#ifdef LODEPNG_COMPILE_DECODER -/*resize and give all new elements the value*/ -static unsigned ucvector_resizev(ucvector* p, size_t size, unsigned char value) -{ - size_t oldsize = p->size, i; - if(!ucvector_resize(p, size)) return 0; - for(i = oldsize; i < size; ++i) p->data[i] = value; - return 1; -} -#endif /*LODEPNG_COMPILE_DECODER*/ #endif /*LODEPNG_COMPILE_PNG*/ #ifdef LODEPNG_COMPILE_ZLIB @@ -368,33 +347,55 @@ static void lodepng_add32bitInt(ucvector* buffer, unsigned value) #ifdef LODEPNG_COMPILE_DISK -unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* filename) +/* returns negative value on error. This should be pure C compatible, so no fstat. */ +static long lodepng_filesize(const char* filename) { FILE* file; long size; + file = fopen(filename, "rb"); + if(!file) return -1; - /*provide some proper output values if error will happen*/ - *out = 0; - *outsize = 0; + if(fseek(file, 0, SEEK_END) != 0) + { + fclose(file); + return -1; + } + size = ftell(file); + /* It may give LONG_MAX as directory size, this is invalid for us. */ + if(size == LONG_MAX) size = -1; + + fclose(file); + return size; +} + +/* load file into buffer that already has the correct allocated size. Returns error code.*/ +static unsigned lodepng_buffer_file(unsigned char* out, size_t size, const char* filename) +{ + FILE* file; + size_t readsize; file = fopen(filename, "rb"); if(!file) return 78; - /*get filesize:*/ - fseek(file , 0 , SEEK_END); - size = ftell(file); - rewind(file); - - /*read contents of the file into the vector*/ - *outsize = 0; - *out = (unsigned char*)lodepng_malloc((size_t)size); - if(size && (*out)) (*outsize) = fread(*out, 1, (size_t)size, file); - + readsize = fread(out, 1, size, file); fclose(file); - if(!(*out) && size) return 83; /*the above malloc failed*/ + + if (readsize != size) return 78; return 0; } +unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* filename) +{ + long size = lodepng_filesize(filename); + if (size < 0) return 78; + *outsize = (size_t)size; + + *out = (unsigned char*)lodepng_malloc((size_t)size); + if(!(*out) && size > 0) return 83; /*the above malloc failed*/ + + return lodepng_buffer_file(*out, (size_t)size, filename); +} + /*write given buffer to the file, overwriting the file, it doesn't append to it.*/ unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename) { @@ -556,7 +557,7 @@ static unsigned HuffmanTree_make2DTree(HuffmanTree* tree) uninited, a value >= numcodes is an address to another bit, a value < numcodes is a code. The 2 rows are the 2 possible bit values (0 or 1), there are as many columns as codes - 1. - A good huffmann tree has N * 2 - 1 nodes, of which N - 1 are internal nodes. + A good huffman tree has N * 2 - 1 nodes, of which N - 1 are internal nodes. Here, the internal nodes are stored (what their 0 and 1 option point to). There is only memory for such good tree currently, if there are more nodes (due to too long length codes), error 55 will happen @@ -666,101 +667,153 @@ static unsigned HuffmanTree_makeFromLengths(HuffmanTree* tree, const unsigned* b #ifdef LODEPNG_COMPILE_ENCODER -/* -A coin, this is the terminology used for the package-merge algorithm and the -coin collector's problem. This is used to generate the huffman tree. -A coin can be multiple coins (when they're merged) -*/ -typedef struct Coin +/*BPM: Boundary Package Merge, see "A Fast and Space-Economical Algorithm for Length-Limited Coding", +Jyrki Katajainen, Alistair Moffat, Andrew Turpin, 1995.*/ + +/*chain node for boundary package merge*/ +typedef struct BPMNode { - uivector symbols; - float weight; /*the sum of all weights in this coin*/ -} Coin; + int weight; /*the sum of all weights in this chain*/ + unsigned index; /*index of this leaf node (called "count" in the paper)*/ + struct BPMNode* tail; /*the next nodes in this chain (null if last)*/ + int in_use; +} BPMNode; -static void coin_init(Coin* c) +/*lists of chains*/ +typedef struct BPMLists { - uivector_init(&c->symbols); -} + /*memory pool*/ + unsigned memsize; + BPMNode* memory; + unsigned numfree; + unsigned nextfree; + BPMNode** freelist; + /*two heads of lookahead chains per list*/ + unsigned listsize; + BPMNode** chains0; + BPMNode** chains1; +} BPMLists; -/*argument c is void* so that this dtor can be given as function pointer to the vector resize function*/ -static void coin_cleanup(void* c) -{ - uivector_cleanup(&((Coin*)c)->symbols); -} - -static void coin_copy(Coin* c1, const Coin* c2) -{ - c1->weight = c2->weight; - uivector_copy(&c1->symbols, &c2->symbols); -} - -static void add_coins(Coin* c1, const Coin* c2) -{ - size_t i; - for(i = 0; i != c2->symbols.size; ++i) uivector_push_back(&c1->symbols, c2->symbols.data[i]); - c1->weight += c2->weight; -} - -static void init_coins(Coin* coins, size_t num) -{ - size_t i; - for(i = 0; i != num; ++i) coin_init(&coins[i]); -} - -static void cleanup_coins(Coin* coins, size_t num) -{ - size_t i; - for(i = 0; i != num; ++i) coin_cleanup(&coins[i]); -} - -static int coin_compare(const void* a, const void* b) { - float wa = ((const Coin*)a)->weight; - float wb = ((const Coin*)b)->weight; - return wa > wb ? 1 : wa < wb ? -1 : 0; -} - -static unsigned append_symbol_coins(Coin* coins, const unsigned* frequencies, unsigned numcodes, size_t sum) +/*creates a new chain node with the given parameters, from the memory in the lists */ +static BPMNode* bpmnode_create(BPMLists* lists, int weight, unsigned index, BPMNode* tail) { unsigned i; - unsigned j = 0; /*index of present symbols*/ - for(i = 0; i != numcodes; ++i) + BPMNode* result; + + /*memory full, so garbage collect*/ + if(lists->nextfree >= lists->numfree) { - if(frequencies[i] != 0) /*only include symbols that are present*/ + /*mark only those that are in use*/ + for(i = 0; i != lists->memsize; ++i) lists->memory[i].in_use = 0; + for(i = 0; i != lists->listsize; ++i) { - coins[j].weight = frequencies[i] / (float)sum; - uivector_push_back(&coins[j].symbols, i); - ++j; + BPMNode* node; + for(node = lists->chains0[i]; node != 0; node = node->tail) node->in_use = 1; + for(node = lists->chains1[i]; node != 0; node = node->tail) node->in_use = 1; + } + /*collect those that are free*/ + lists->numfree = 0; + for(i = 0; i != lists->memsize; ++i) + { + if(!lists->memory[i].in_use) lists->freelist[lists->numfree++] = &lists->memory[i]; + } + lists->nextfree = 0; + } + + result = lists->freelist[lists->nextfree++]; + result->weight = weight; + result->index = index; + result->tail = tail; + return result; +} + +/*sort the leaves with stable mergesort*/ +static void bpmnode_sort(BPMNode* leaves, size_t num) +{ + BPMNode* mem = (BPMNode*)lodepng_malloc(sizeof(*leaves) * num); + size_t width, counter = 0; + for(width = 1; width < num; width *= 2) + { + BPMNode* a = (counter & 1) ? mem : leaves; + BPMNode* b = (counter & 1) ? leaves : mem; + size_t p; + for(p = 0; p < num; p += 2 * width) + { + size_t q = (p + width > num) ? num : (p + width); + size_t r = (p + 2 * width > num) ? num : (p + 2 * width); + size_t i = p, j = q, k; + for(k = p; k < r; k++) + { + if(i < q && (j >= r || a[i].weight <= a[j].weight)) b[k] = a[i++]; + else b[k] = a[j++]; + } + } + counter++; + } + if(counter & 1) memcpy(leaves, mem, sizeof(*leaves) * num); + lodepng_free(mem); +} + +/*Boundary Package Merge step, numpresent is the amount of leaves, and c is the current chain.*/ +static void boundaryPM(BPMLists* lists, BPMNode* leaves, size_t numpresent, int c, int num) +{ + unsigned lastindex = lists->chains1[c]->index; + + if(c == 0) + { + if(lastindex >= numpresent) return; + lists->chains0[c] = lists->chains1[c]; + lists->chains1[c] = bpmnode_create(lists, leaves[lastindex].weight, lastindex + 1, 0); + } + else + { + /*sum of the weights of the head nodes of the previous lookahead chains.*/ + int sum = lists->chains0[c - 1]->weight + lists->chains1[c - 1]->weight; + lists->chains0[c] = lists->chains1[c]; + if(lastindex < numpresent && sum > leaves[lastindex].weight) + { + lists->chains1[c] = bpmnode_create(lists, leaves[lastindex].weight, lastindex + 1, lists->chains1[c]->tail); + return; + } + lists->chains1[c] = bpmnode_create(lists, sum, lastindex, lists->chains1[c - 1]); + /*in the end we are only interested in the chain of the last list, so no + need to recurse if we're at the last one (this gives measurable speedup)*/ + if(num + 1 < (int)(2 * numpresent - 2)) + { + boundaryPM(lists, leaves, numpresent, c - 1, num); + boundaryPM(lists, leaves, numpresent, c - 1, num); } } - return 0; } unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequencies, size_t numcodes, unsigned maxbitlen) { - unsigned i, j; - size_t sum = 0, numpresent = 0; unsigned error = 0; - Coin* coins; /*the coins of the currently calculated row*/ - Coin* prev_row; /*the previous row of coins*/ - size_t numcoins; - size_t coinmem; + unsigned i; + size_t numpresent = 0; /*number of symbols with non-zero frequency*/ + BPMNode* leaves; /*the symbols, only those with > 0 frequency*/ if(numcodes == 0) return 80; /*error: a tree of 0 symbols is not supposed to be made*/ + if((1u << maxbitlen) < numcodes) return 80; /*error: represent all symbols*/ + + leaves = (BPMNode*)lodepng_malloc(numcodes * sizeof(*leaves)); + if(!leaves) return 83; /*alloc fail*/ for(i = 0; i != numcodes; ++i) { if(frequencies[i] > 0) { + leaves[numpresent].weight = (int)frequencies[i]; + leaves[numpresent].index = i; ++numpresent; - sum += frequencies[i]; } } for(i = 0; i != numcodes; ++i) lengths[i] = 0; /*ensure at least two present symbols. There should be at least one symbol - according to RFC 1951 section 3.2.7. To decoders incorrectly require two. To + according to RFC 1951 section 3.2.7. Some decoders incorrectly require two. To make these work as well ensure there are at least two symbols. The Package-Merge code below also doesn't work correctly if there's only one symbol, it'd give it the theoritical 0 bits but in practice zlib wants 1 bit*/ @@ -770,87 +823,55 @@ unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequen } else if(numpresent == 1) { - for(i = 0; i != numcodes; ++i) - { - if(frequencies[i]) - { - lengths[i] = 1; - lengths[i == 0 ? 1 : 0] = 1; - break; - } - } + lengths[leaves[0].index] = 1; + lengths[leaves[0].index == 0 ? 1 : 0] = 1; } else { - /*Package-Merge algorithm represented by coin collector's problem - For every symbol, maxbitlen coins will be created*/ + BPMLists lists; + BPMNode* node; - coinmem = numpresent * 2; /*max amount of coins needed with the current algo*/ - coins = (Coin*)lodepng_malloc(sizeof(Coin) * coinmem); - prev_row = (Coin*)lodepng_malloc(sizeof(Coin) * coinmem); - if(!coins || !prev_row) - { - lodepng_free(coins); - lodepng_free(prev_row); - return 83; /*alloc fail*/ - } - init_coins(coins, coinmem); - init_coins(prev_row, coinmem); + bpmnode_sort(leaves, numpresent); - /*first row, lowest denominator*/ - error = append_symbol_coins(coins, frequencies, numcodes, sum); - numcoins = numpresent; - qsort(coins, numcoins, sizeof(Coin), coin_compare); - if(!error) - { - unsigned numprev = 0; - for(j = 1; j <= maxbitlen && !error; ++j) /*each of the remaining rows*/ - { - unsigned tempnum; - Coin* tempcoins; - /*swap prev_row and coins, and their amounts*/ - tempcoins = prev_row; prev_row = coins; coins = tempcoins; - tempnum = numprev; numprev = numcoins; numcoins = tempnum; - - cleanup_coins(coins, numcoins); - init_coins(coins, numcoins); - - numcoins = 0; - - /*fill in the merged coins of the previous row*/ - for(i = 0; i + 1 < numprev; i += 2) - { - /*merge prev_row[i] and prev_row[i + 1] into new coin*/ - Coin* coin = &coins[numcoins++]; - coin_copy(coin, &prev_row[i]); - add_coins(coin, &prev_row[i + 1]); - } - /*fill in all the original symbols again*/ - if(j < maxbitlen) - { - error = append_symbol_coins(coins + numcoins, frequencies, numcodes, sum); - numcoins += numpresent; - } - qsort(coins, numcoins, sizeof(Coin), coin_compare); - } - } + lists.listsize = maxbitlen; + lists.memsize = 2 * maxbitlen * (maxbitlen + 1); + lists.nextfree = 0; + lists.numfree = lists.memsize; + lists.memory = (BPMNode*)lodepng_malloc(lists.memsize * sizeof(*lists.memory)); + lists.freelist = (BPMNode**)lodepng_malloc(lists.memsize * sizeof(BPMNode*)); + lists.chains0 = (BPMNode**)lodepng_malloc(lists.listsize * sizeof(BPMNode*)); + lists.chains1 = (BPMNode**)lodepng_malloc(lists.listsize * sizeof(BPMNode*)); + if(!lists.memory || !lists.freelist || !lists.chains0 || !lists.chains1) error = 83; /*alloc fail*/ if(!error) { - /*calculate the lengths of each symbol, as the amount of times a coin of each symbol is used*/ - for(i = 0; i + 1 < numpresent; ++i) + for(i = 0; i != lists.memsize; ++i) lists.freelist[i] = &lists.memory[i]; + + bpmnode_create(&lists, leaves[0].weight, 1, 0); + bpmnode_create(&lists, leaves[1].weight, 2, 0); + + for(i = 0; i != lists.listsize; ++i) { - Coin* coin = &coins[i]; - for(j = 0; j < coin->symbols.size; ++j) ++lengths[coin->symbols.data[j]]; + lists.chains0[i] = &lists.memory[0]; + lists.chains1[i] = &lists.memory[1]; + } + + /*each boundaryPM call adds one chain to the last list, and we need 2 * numpresent - 2 chains.*/ + for(i = 2; i != 2 * numpresent - 2; ++i) boundaryPM(&lists, leaves, numpresent, (int)maxbitlen - 1, (int)i); + + for(node = lists.chains1[maxbitlen - 1]; node; node = node->tail) + { + for(i = 0; i != node->index; ++i) ++lengths[leaves[i].index]; } } - cleanup_coins(coins, coinmem); - lodepng_free(coins); - cleanup_coins(prev_row, coinmem); - lodepng_free(prev_row); + lodepng_free(lists.memory); + lodepng_free(lists.freelist); + lodepng_free(lists.chains0); + lodepng_free(lists.chains1); } + lodepng_free(leaves); return error; } @@ -1026,7 +1047,7 @@ static unsigned getTreeInflateDynamic(HuffmanTree* tree_ll, HuffmanTree* tree_d, unsigned replength = 3; /*read in the 2 bits that indicate repeat length (3-6)*/ unsigned value; /*set value to the previous code*/ - if (i == 0) ERROR_BREAK(54); /*can't repeat previous if i is 0*/ + if(i == 0) ERROR_BREAK(54); /*can't repeat previous if i is 0*/ if((*bp + 2) > inbitlength) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ replength += readBitsFromStream(bp, in, 2); @@ -1150,7 +1171,7 @@ static unsigned inflateHuffmanBlock(ucvector* out, const unsigned char* in, size code_d = huffmanDecodeSymbol(in, bp, &tree_d, inbitlength); if(code_d > 29) { - if(code_ll == (unsigned)(-1)) /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ + if(code_d == (unsigned)(-1)) /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ { /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol (10=no endcode, 11=wrong jump outside of tree)*/ @@ -1172,12 +1193,14 @@ static unsigned inflateHuffmanBlock(ucvector* out, const unsigned char* in, size backward = start - distance; if(!ucvector_resize(out, (*pos) + length)) ERROR_BREAK(83 /*alloc fail*/); - for(forward = 0; forward < length; ++forward) - { - out->data[(*pos)] = out->data[backward]; - ++(*pos); - ++backward; - if(backward >= start) backward = start - distance; + if (distance < length) { + for(forward = 0; forward < length; ++forward) + { + out->data[(*pos)++] = out->data[backward++]; + } + } else { + memcpy(out->data + *pos, out->data + backward, length); + *pos += length; } } else if(code_ll == 256) @@ -1304,21 +1327,17 @@ static void addHuffmanSymbol(size_t* bp, ucvector* compressed, unsigned code, un given array must be sorted (if no value is smaller, it returns the size of the given array)*/ static size_t searchCodeIndex(const unsigned* array, size_t array_size, size_t value) { - /*linear search implementation*/ - /*for(size_t i = 1; i < array_size; ++i) if(array[i] > value) return i - 1; - return array_size - 1;*/ - - /*binary search implementation (not that much faster) (precondition: array_size > 0)*/ - size_t left = 1; + /*binary search (only small gain over linear). TODO: use CPU log2 instruction for getting symbols instead*/ + size_t left = 1; size_t right = array_size - 1; - while(left <= right) - { - size_t mid = (left + right) / 2; - if(array[mid] <= value) left = mid + 1; /*the value to find is more to the right*/ - else if(array[mid - 1] > value) right = mid - 1; /*the value to find is more to the left*/ - else return mid - 1; + + while(left <= right) { + size_t mid = (left + right) >> 1; + if (array[mid] >= value) right = mid - 1; + else left = mid + 1; } - return array_size - 1; + if(left >= array_size || array[left] > value) left--; + return left; } static void addLengthDistance(uivector* values, size_t length, size_t distance) @@ -1402,7 +1421,7 @@ static void hash_cleanup(Hash* hash) static unsigned getHash(const unsigned char* data, size_t size, size_t pos) { unsigned result = 0; - if (pos + 2 < size) + if(pos + 2 < size) { /*A simple shift and xor hash is used. Since the data of PNGs is dominated by zeroes due to the filters, a better hash does not have a significant @@ -1426,7 +1445,7 @@ static unsigned countZeros(const unsigned char* data, size_t size, size_t pos) const unsigned char* end = start + MAX_SUPPORTED_DEFLATE_LENGTH; if(end > data + size) end = data + size; data = start; - while (data != end && *data == 0) ++data; + while(data != end && *data == 0) ++data; /*subtracting two addresses returned as 32-bit number (max value is MAX_SUPPORTED_DEFLATE_LENGTH)*/ return (unsigned)(data - start); } @@ -1489,8 +1508,8 @@ static unsigned encodeLZ77(uivector* out, Hash* hash, if(usezeros && hashval == 0) { - if (numzeros == 0) numzeros = countZeros(in, insize, pos); - else if (pos + numzeros > insize || in[pos + numzeros - 1] != 0) --numzeros; + if(numzeros == 0) numzeros = countZeros(in, insize, pos); + else if(pos + numzeros > insize || in[pos + numzeros - 1] != 0) --numzeros; } else { @@ -1550,10 +1569,13 @@ static unsigned encodeLZ77(uivector* out, Hash* hash, if(hashpos == hash->chain[hashpos]) break; - if(numzeros >= 3 && length > numzeros) { + if(numzeros >= 3 && length > numzeros) + { hashpos = hash->chainz[hashpos]; if(hash->zeros[hashpos] != numzeros) break; - } else { + } + else + { hashpos = hash->chain[hashpos]; /*outdated hash value, happens if particular value was not encountered in whole last window*/ if(hash->val[hashpos] != (int)hashval) break; @@ -1611,8 +1633,8 @@ static unsigned encodeLZ77(uivector* out, Hash* hash, hashval = getHash(in, insize, pos); if(usezeros && hashval == 0) { - if (numzeros == 0) numzeros = countZeros(in, insize, pos); - else if (pos + numzeros > insize || in[pos + numzeros - 1] != 0) --numzeros; + if(numzeros == 0) numzeros = countZeros(in, insize, pos); + else if(pos + numzeros > insize || in[pos + numzeros - 1] != 0) --numzeros; } else { @@ -1650,10 +1672,10 @@ static unsigned deflateNoCompression(ucvector* out, const unsigned char* data, s if(datasize - datapos < 65535) LEN = (unsigned)datasize - datapos; NLEN = 65535 - LEN; - ucvector_push_back(out, (unsigned char)(LEN % 256)); - ucvector_push_back(out, (unsigned char)(LEN / 256)); - ucvector_push_back(out, (unsigned char)(NLEN % 256)); - ucvector_push_back(out, (unsigned char)(NLEN / 256)); + ucvector_push_back(out, (unsigned char)(LEN & 255)); + ucvector_push_back(out, (unsigned char)(LEN >> 8)); + ucvector_push_back(out, (unsigned char)(NLEN & 255)); + ucvector_push_back(out, (unsigned char)(NLEN >> 8)); /*Decompressed data*/ for(j = 0; j < 65535 && datapos < datasize; ++j) @@ -1767,7 +1789,7 @@ static unsigned deflateDynamic(ucvector* out, size_t* bp, Hash* hash, else { if(!uivector_resize(&lz77_encoded, datasize)) ERROR_BREAK(83 /*alloc fail*/); - for(i = datapos; i < dataend; ++i) lz77_encoded.data[i] = data[i]; /*no LZ77, but still will be Huffman compressed*/ + for(i = datapos; i < dataend; ++i) lz77_encoded.data[i - datapos] = data[i]; /*no LZ77, but still will be Huffman compressed*/ } if(!uivector_resizev(&frequencies_ll, 286, 0)) ERROR_BREAK(83 /*alloc fail*/); @@ -2005,8 +2027,10 @@ static unsigned lodepng_deflatev(ucvector* out, const unsigned char* in, size_t else if(settings->btype == 1) blocksize = insize; else /*if(settings->btype == 2)*/ { + /*on PNGs, deflate blocks of 65-262k seem to give most dense encoding*/ blocksize = insize / 8 + 8; - if(blocksize < 65535) blocksize = 65535; + if(blocksize < 65536) blocksize = 65536; + if(blocksize > 262144) blocksize = 262144; } numdeflateblocks = (insize + blocksize - 1) / blocksize; @@ -2183,8 +2207,8 @@ unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize, const unsig /*ucvector-controlled version of the output buffer, for dynamic array*/ ucvector_init_buffer(&outv, *out, *outsize); - ucvector_push_back(&outv, (unsigned char)(CMFFLG / 256)); - ucvector_push_back(&outv, (unsigned char)(CMFFLG % 256)); + ucvector_push_back(&outv, (unsigned char)(CMFFLG >> 8)); + ucvector_push_back(&outv, (unsigned char)(CMFFLG & 255)); error = deflate(&deflatedata, &deflatesize, in, insize, settings); @@ -2224,7 +2248,7 @@ static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsign static unsigned zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings) { - if (!settings->custom_zlib) return 87; /*no custom zlib function provided */ + if(!settings->custom_zlib) return 87; /*no custom zlib function provided */ return settings->custom_zlib(out, outsize, in, insize, settings); } #endif /*LODEPNG_COMPILE_DECODER*/ @@ -2232,7 +2256,7 @@ static unsigned zlib_decompress(unsigned char** out, size_t* outsize, const unsi static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGCompressSettings* settings) { - if (!settings->custom_zlib) return 87; /*no custom zlib function provided */ + if(!settings->custom_zlib) return 87; /*no custom zlib function provided */ return settings->custom_zlib(out, outsize, in, insize, settings); } #endif /*LODEPNG_COMPILE_ENCODER*/ @@ -2293,6 +2317,8 @@ const LodePNGDecompressSettings lodepng_default_decompress_settings = {0, 0, 0, /* / CRC32 / */ /* ////////////////////////////////////////////////////////////////////////// */ + +#ifndef LODEPNG_NO_COMPILE_CRC /* CRC polynomial: 0xedb88320 */ static unsigned lodepng_crc32_table[256] = { 0u, 1996959894u, 3993919788u, 2567524794u, 124634137u, 1886057615u, 3915621685u, 2657392035u, @@ -2330,17 +2356,19 @@ static unsigned lodepng_crc32_table[256] = { }; /*Return the CRC of the bytes buf[0..len-1].*/ -unsigned lodepng_crc32(const unsigned char* buf, size_t len) +unsigned lodepng_crc32(const unsigned char* data, size_t length) { - unsigned c = 0xffffffffL; - size_t n; - - for(n = 0; n < len; ++n) + unsigned r = 0xffffffffu; + size_t i; + for(i = 0; i < length; ++i) { - c = lodepng_crc32_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); + r = lodepng_crc32_table[(r ^ data[i]) & 0xff] ^ (r >> 8); } - return c ^ 0xffffffffL; + return r ^ 0xffffffffu; } +#else /* !LODEPNG_NO_COMPILE_CRC */ +unsigned lodepng_crc32(const unsigned char* data, size_t length); +#endif /* !LODEPNG_NO_COMPILE_CRC */ /* ////////////////////////////////////////////////////////////////////////// */ /* / Reading and writing single bits and bytes from/to stream for LodePNG / */ @@ -2357,9 +2385,10 @@ static unsigned readBitsFromReversedStream(size_t* bitpointer, const unsigned ch { unsigned result = 0; size_t i; - for(i = nbits - 1; i < nbits; --i) + for(i = 0 ; i < nbits; ++i) { - result += (unsigned)readBitFromReversedStream(bitpointer, bitstream) << i; + result <<= 1; + result |= (unsigned)readBitFromReversedStream(bitpointer, bitstream); } return result; } @@ -2592,10 +2621,15 @@ static int lodepng_color_mode_equal(const LodePNGColorMode* a, const LodePNGColo if(a->key_g != b->key_g) return 0; if(a->key_b != b->key_b) return 0; } - if(a->palettesize != b->palettesize) return 0; - for(i = 0; i != a->palettesize * 4; ++i) - { - if(a->palette[i] != b->palette[i]) return 0; + /*if one of the palette sizes is 0, then we consider it to be the same as the + other: it means that e.g. the palette was not given by the user and should be + considered the same as the palette inside the PNG.*/ + if(1/*a->palettesize != 0 && b->palettesize != 0*/) { + if(a->palettesize != b->palettesize) return 0; + for(i = 0; i != a->palettesize * 4; ++i) + { + if(a->palette[i] != b->palette[i]) return 0; + } } return 1; } @@ -2673,12 +2707,18 @@ unsigned lodepng_can_have_alpha(const LodePNGColorMode* info) size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* color) { - return (w * h * lodepng_get_bpp(color) + 7) / 8; + /*will not overflow for any color type if roughly w * h < 268435455*/ + size_t bpp = lodepng_get_bpp(color); + size_t n = w * h; + return ((n / 8) * bpp) + ((n & 7) * bpp + 7) / 8; } size_t lodepng_get_raw_size_lct(unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) { - return (w * h * lodepng_get_bpp_lct(colortype, bitdepth) + 7) / 8; + /*will not overflow for any color type if roughly w * h < 268435455*/ + size_t bpp = lodepng_get_bpp_lct(colortype, bitdepth); + size_t n = w * h; + return ((n / 8) * bpp) + ((n & 7) * bpp + 7) / 8; } @@ -2687,7 +2727,10 @@ size_t lodepng_get_raw_size_lct(unsigned w, unsigned h, LodePNGColorType colorty /*in an idat chunk, each scanline is a multiple of 8 bits, unlike the lodepng output buffer*/ static size_t lodepng_get_raw_size_idat(unsigned w, unsigned h, const LodePNGColorMode* color) { - return h * ((w * lodepng_get_bpp(color) + 7) / 8); + /*will not overflow for any color type if roughly w * h < 268435455*/ + size_t bpp = lodepng_get_bpp(color); + size_t line = ((w / 8) * bpp) + ((w & 7) * bpp + 7) / 8; + return h * line; } #endif /*LODEPNG_COMPILE_DECODER*/ #endif /*LODEPNG_COMPILE_PNG*/ @@ -3390,35 +3433,37 @@ static void getPixelColorRGBA16(unsigned short* r, unsigned short* g, unsigned s } else if(mode->colortype == LCT_RGB) { - *r = 256 * in[i * 6 + 0] + in[i * 6 + 1]; - *g = 256 * in[i * 6 + 2] + in[i * 6 + 3]; - *b = 256 * in[i * 6 + 4] + in[i * 6 + 5]; - if(mode->key_defined && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r - && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g - && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) *a = 0; + *r = 256u * in[i * 6 + 0] + in[i * 6 + 1]; + *g = 256u * in[i * 6 + 2] + in[i * 6 + 3]; + *b = 256u * in[i * 6 + 4] + in[i * 6 + 5]; + if(mode->key_defined + && 256u * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r + && 256u * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g + && 256u * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) *a = 0; else *a = 65535; } else if(mode->colortype == LCT_GREY_ALPHA) { - *r = *g = *b = 256 * in[i * 4 + 0] + in[i * 4 + 1]; - *a = 256 * in[i * 4 + 2] + in[i * 4 + 3]; + *r = *g = *b = 256u * in[i * 4 + 0] + in[i * 4 + 1]; + *a = 256u * in[i * 4 + 2] + in[i * 4 + 3]; } else if(mode->colortype == LCT_RGBA) { - *r = 256 * in[i * 8 + 0] + in[i * 8 + 1]; - *g = 256 * in[i * 8 + 2] + in[i * 8 + 3]; - *b = 256 * in[i * 8 + 4] + in[i * 8 + 5]; - *a = 256 * in[i * 8 + 6] + in[i * 8 + 7]; + *r = 256u * in[i * 8 + 0] + in[i * 8 + 1]; + *g = 256u * in[i * 8 + 2] + in[i * 8 + 3]; + *b = 256u * in[i * 8 + 4] + in[i * 8 + 5]; + *a = 256u * in[i * 8 + 6] + in[i * 8 + 7]; } } unsigned lodepng_convert(unsigned char* out, const unsigned char* in, - LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in, + const LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in, unsigned w, unsigned h) { size_t i; ColorTree tree; size_t numpixels = w * h; + unsigned error = 0; if(lodepng_color_mode_equal(mode_out, mode_in)) { @@ -3429,12 +3474,22 @@ unsigned lodepng_convert(unsigned char* out, const unsigned char* in, if(mode_out->colortype == LCT_PALETTE) { + size_t palettesize = mode_out->palettesize; + const unsigned char* palette = mode_out->palette; size_t palsize = 1u << mode_out->bitdepth; - if(mode_out->palettesize < palsize) palsize = mode_out->palettesize; + /*if the user specified output palette but did not give the values, assume + they want the values of the input color type (assuming that one is palette). + Note that we never create a new palette ourselves.*/ + if(palettesize == 0) + { + palettesize = mode_in->palettesize; + palette = mode_in->palette; + } + if(palettesize < palsize) palsize = palettesize; color_tree_init(&tree); for(i = 0; i != palsize; ++i) { - unsigned char* p = &mode_out->palette[i * 4]; + const unsigned char* p = &palette[i * 4]; color_tree_add(&tree, p[0], p[1], p[2], p[3], i); } } @@ -3462,7 +3517,8 @@ unsigned lodepng_convert(unsigned char* out, const unsigned char* in, for(i = 0; i != numpixels; ++i) { getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in); - rgba8ToPixel(out, i, mode_out, &tree, r, g, b, a); + error = rgba8ToPixel(out, i, mode_out, &tree, r, g, b, a); + if (error) break; } } @@ -3471,7 +3527,7 @@ unsigned lodepng_convert(unsigned char* out, const unsigned char* in, color_tree_cleanup(&tree); } - return 0; /*no error (this function currently never has one, but maybe OOM detection added later.)*/ + return error; } #ifdef LODEPNG_COMPILE_ENCODER @@ -3480,8 +3536,8 @@ void lodepng_color_profile_init(LodePNGColorProfile* profile) { profile->colored = 0; profile->key = 0; - profile->alpha = 0; profile->key_r = profile->key_g = profile->key_b = 0; + profile->alpha = 0; profile->numcolors = 0; profile->bits = 1; } @@ -3568,8 +3624,8 @@ unsigned lodepng_get_color_profile(LodePNGColorProfile* profile, if(a != 65535 && (a != 0 || (profile->key && !matchkey))) { profile->alpha = 1; + profile->key = 0; alpha_done = 1; - if(profile->bits < 8) profile->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ } else if(a == 0 && !profile->alpha && !profile->key) { @@ -3582,18 +3638,33 @@ unsigned lodepng_get_color_profile(LodePNGColorProfile* profile, { /* Color key cannot be used if an opaque pixel also has that RGB color. */ profile->alpha = 1; + profile->key = 0; alpha_done = 1; } } - if(alpha_done && numcolors_done && colored_done && bits_done) break; } + + if(profile->key && !profile->alpha) + { + for(i = 0; i != numpixels; ++i) + { + getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode); + if(a != 0 && r == profile->key_r && g == profile->key_g && b == profile->key_b) + { + /* Color key cannot be used if an opaque pixel also has that RGB color. */ + profile->alpha = 1; + profile->key = 0; + alpha_done = 1; + } + } + } } else /* < 16-bit */ { + unsigned char r = 0, g = 0, b = 0, a = 0; for(i = 0; i != numpixels; ++i) { - unsigned char r = 0, g = 0, b = 0, a = 0; getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode); if(!bits_done && profile->bits < 8) @@ -3617,6 +3688,7 @@ unsigned lodepng_get_color_profile(LodePNGColorProfile* profile, if(a != 255 && (a != 0 || (profile->key && !matchkey))) { profile->alpha = 1; + profile->key = 0; alpha_done = 1; if(profile->bits < 8) profile->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ } @@ -3631,6 +3703,7 @@ unsigned lodepng_get_color_profile(LodePNGColorProfile* profile, { /* Color key cannot be used if an opaque pixel also has that RGB color. */ profile->alpha = 1; + profile->key = 0; alpha_done = 1; if(profile->bits < 8) profile->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ } @@ -3658,6 +3731,22 @@ unsigned lodepng_get_color_profile(LodePNGColorProfile* profile, if(alpha_done && numcolors_done && colored_done && bits_done) break; } + if(profile->key && !profile->alpha) + { + for(i = 0; i != numpixels; ++i) + { + getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode); + if(a != 0 && r == profile->key_r && g == profile->key_g && b == profile->key_b) + { + /* Color key cannot be used if an opaque pixel also has that RGB color. */ + profile->alpha = 1; + profile->key = 0; + alpha_done = 1; + if(profile->bits < 8) profile->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ + } + } + } + /*make the profile's key always 16-bit for consistency - repeat each byte twice*/ profile->key_r += (profile->key_r << 8); profile->key_g += (profile->key_g << 8); @@ -3679,23 +3768,24 @@ unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out, { LodePNGColorProfile prof; unsigned error = 0; - unsigned i, n, palettebits, grey_ok, palette_ok; + unsigned i, n, palettebits, palette_ok; lodepng_color_profile_init(&prof); error = lodepng_get_color_profile(&prof, image, w, h, mode_in); if(error) return error; mode_out->key_defined = 0; - if(prof.key && w * h <= 16) { + if(prof.key && w * h <= 16) + { prof.alpha = 1; /*too few pixels to justify tRNS chunk overhead*/ + prof.key = 0; if(prof.bits < 8) prof.bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ } - grey_ok = !prof.colored && !prof.alpha; /*grey without alpha, with potentially low bits*/ n = prof.numcolors; palettebits = n <= 2 ? 1 : (n <= 4 ? 2 : (n <= 16 ? 4 : 8)); - palette_ok = n <= 256 && (n * 2 < w * h) && prof.bits <= 8; + palette_ok = n <= 256 && prof.bits <= 8; if(w * h < n * 2) palette_ok = 0; /*don't add palette overhead if image has only a few pixels*/ - if(grey_ok && prof.bits <= palettebits) palette_ok = 0; /*grey is less overhead*/ + if(!prof.colored && prof.bits <= palettebits) palette_ok = 0; /*grey is less overhead*/ if(palette_ok) { @@ -3724,7 +3814,7 @@ unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out, mode_out->colortype = prof.alpha ? (prof.colored ? LCT_RGBA : LCT_GREY_ALPHA) : (prof.colored ? LCT_RGB : LCT_GREY); - if(prof.key && !prof.alpha) + if(prof.key) { unsigned mask = (1u << mode_out->bitdepth) - 1u; /*profile always uses 16-bit, mask converts it*/ mode_out->key_r = prof.key_r & mask; @@ -3834,7 +3924,11 @@ unsigned lodepng_inspect(unsigned* w, unsigned* h, LodePNGState* state, { CERROR_RETURN_ERROR(state->error, 28); /*error: the first 8 bytes are not the correct PNG signature*/ } - if(in[12] != 'I' || in[13] != 'H' || in[14] != 'D' || in[15] != 'R') + if(lodepng_chunk_length(in + 8) != 13) + { + CERROR_RETURN_ERROR(state->error, 94); /*error: header size must be 13 bytes*/ + } + if(!lodepng_chunk_type_equals(in + 8, "IHDR")) { CERROR_RETURN_ERROR(state->error, 29); /*error: it doesn't start with a IHDR chunk!*/ } @@ -3909,13 +4003,13 @@ static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scan case 3: if(precon) { - for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i] + precon[i] / 2; - for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) / 2); + for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i] + (precon[i] >> 1); + for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) >> 1); } else { for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i]; - for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + recon[i - bytewidth] / 2; + for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + (recon[i - bytewidth] >> 1); } break; case 4: @@ -4090,7 +4184,7 @@ static unsigned postProcessScanlines(unsigned char* out, unsigned char* in, CERROR_TRY_RETURN(unfilter(in, in, w, h, bpp)); removePaddingBits(out, in, w * bpp, ((w * bpp + 7) / 8) * 8, h); } - /*we can immediatly filter into the out buffer, no other steps needed*/ + /*we can immediately filter into the out buffer, no other steps needed*/ else CERROR_TRY_RETURN(unfilter(out, in, w, h, bpp)); } else /*interlace_method is 1 (Adam7)*/ @@ -4438,6 +4532,7 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h, ucvector scanlines; size_t predict; size_t numpixels; + size_t outsize = 0; /*for unknown chunk order*/ unsigned unknown = 0; @@ -4596,13 +4691,13 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h, /*Adam-7 interlaced: predicted size is the sum of the 7 sub-images sizes*/ const LodePNGColorMode* color = &state->info_png.color; predict = 0; - predict += lodepng_get_raw_size_idat((*w + 7) / 8, (*h + 7) / 8, color) + (*h + 7) / 8; - if(*w > 4) predict += lodepng_get_raw_size_idat((*w + 3) / 8, (*h + 7) / 8, color) + (*h + 7) / 8; - predict += lodepng_get_raw_size_idat((*w + 3) / 4, (*h + 3) / 8, color) + (*h + 3) / 8; - if(*w > 2) predict += lodepng_get_raw_size_idat((*w + 1) / 4, (*h + 3) / 4, color) + (*h + 3) / 4; - predict += lodepng_get_raw_size_idat((*w + 1) / 2, (*h + 1) / 4, color) + (*h + 1) / 4; - if(*w > 1) predict += lodepng_get_raw_size_idat((*w + 0) / 2, (*h + 1) / 2, color) + (*h + 1) / 2; - predict += lodepng_get_raw_size_idat((*w + 0) / 1, (*h + 0) / 2, color) + (*h + 0) / 2; + predict += lodepng_get_raw_size_idat((*w + 7) >> 3, (*h + 7) >> 3, color) + ((*h + 7) >> 3); + if(*w > 4) predict += lodepng_get_raw_size_idat((*w + 3) >> 3, (*h + 7) >> 3, color) + ((*h + 7) >> 3); + predict += lodepng_get_raw_size_idat((*w + 3) >> 2, (*h + 3) >> 3, color) + ((*h + 3) >> 3); + if(*w > 2) predict += lodepng_get_raw_size_idat((*w + 1) >> 2, (*h + 3) >> 2, color) + ((*h + 3) >> 2); + predict += lodepng_get_raw_size_idat((*w + 1) >> 1, (*h + 1) >> 2, color) + ((*h + 1) >> 2); + if(*w > 1) predict += lodepng_get_raw_size_idat((*w + 0) >> 1, (*h + 1) >> 1, color) + ((*h + 1) >> 1); + predict += lodepng_get_raw_size_idat((*w + 0), (*h + 0) >> 1, color) + ((*h + 0) >> 1); } if(!state->error && !ucvector_reserve(&scanlines, predict)) state->error = 83; /*alloc fail*/ if(!state->error) @@ -4615,12 +4710,14 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h, if(!state->error) { - size_t outsize = lodepng_get_raw_size(*w, *h, &state->info_png.color); - ucvector outv; - ucvector_init(&outv); - if(!ucvector_resizev(&outv, outsize, 0)) state->error = 83; /*alloc fail*/ - if(!state->error) state->error = postProcessScanlines(outv.data, scanlines.data, *w, *h, &state->info_png); - *out = outv.data; + outsize = lodepng_get_raw_size(*w, *h, &state->info_png.color); + *out = (unsigned char*)lodepng_malloc(outsize); + if(!*out) state->error = 83; /*alloc fail*/ + } + if(!state->error) + { + for(i = 0; i < outsize; i++) (*out)[i] = 0; + state->error = postProcessScanlines(*out, scanlines.data, *w, *h, &state->info_png); } ucvector_cleanup(&scanlines); } @@ -4697,7 +4794,7 @@ unsigned lodepng_decode24(unsigned char** out, unsigned* w, unsigned* h, const u unsigned lodepng_decode_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename, LodePNGColorType colortype, unsigned bitdepth) { - unsigned char* buffer; + unsigned char* buffer = 0; size_t buffersize; unsigned error; error = lodepng_load_file(&buffer, &buffersize, filename); @@ -4850,20 +4947,20 @@ static unsigned addChunk_tRNS(ucvector* out, const LodePNGColorMode* info) { if(info->key_defined) { - ucvector_push_back(&tRNS, (unsigned char)(info->key_r / 256)); - ucvector_push_back(&tRNS, (unsigned char)(info->key_r % 256)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_r >> 8)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_r & 255)); } } else if(info->colortype == LCT_RGB) { if(info->key_defined) { - ucvector_push_back(&tRNS, (unsigned char)(info->key_r / 256)); - ucvector_push_back(&tRNS, (unsigned char)(info->key_r % 256)); - ucvector_push_back(&tRNS, (unsigned char)(info->key_g / 256)); - ucvector_push_back(&tRNS, (unsigned char)(info->key_g % 256)); - ucvector_push_back(&tRNS, (unsigned char)(info->key_b / 256)); - ucvector_push_back(&tRNS, (unsigned char)(info->key_b % 256)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_r >> 8)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_r & 255)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_g >> 8)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_g & 255)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_b >> 8)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_b & 255)); } } @@ -4988,21 +5085,21 @@ static unsigned addChunk_bKGD(ucvector* out, const LodePNGInfo* info) ucvector_init(&bKGD); if(info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA) { - ucvector_push_back(&bKGD, (unsigned char)(info->background_r / 256)); - ucvector_push_back(&bKGD, (unsigned char)(info->background_r % 256)); + ucvector_push_back(&bKGD, (unsigned char)(info->background_r >> 8)); + ucvector_push_back(&bKGD, (unsigned char)(info->background_r & 255)); } else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA) { - ucvector_push_back(&bKGD, (unsigned char)(info->background_r / 256)); - ucvector_push_back(&bKGD, (unsigned char)(info->background_r % 256)); - ucvector_push_back(&bKGD, (unsigned char)(info->background_g / 256)); - ucvector_push_back(&bKGD, (unsigned char)(info->background_g % 256)); - ucvector_push_back(&bKGD, (unsigned char)(info->background_b / 256)); - ucvector_push_back(&bKGD, (unsigned char)(info->background_b % 256)); + ucvector_push_back(&bKGD, (unsigned char)(info->background_r >> 8)); + ucvector_push_back(&bKGD, (unsigned char)(info->background_r & 255)); + ucvector_push_back(&bKGD, (unsigned char)(info->background_g >> 8)); + ucvector_push_back(&bKGD, (unsigned char)(info->background_g & 255)); + ucvector_push_back(&bKGD, (unsigned char)(info->background_b >> 8)); + ucvector_push_back(&bKGD, (unsigned char)(info->background_b & 255)); } else if(info->color.colortype == LCT_PALETTE) { - ucvector_push_back(&bKGD, (unsigned char)(info->background_r % 256)); /*palette index*/ + ucvector_push_back(&bKGD, (unsigned char)(info->background_r & 255)); /*palette index*/ } error = addChunk(out, "bKGD", bKGD.data, bKGD.size); @@ -5016,8 +5113,8 @@ static unsigned addChunk_tIME(ucvector* out, const LodePNGTime* time) unsigned error = 0; unsigned char* data = (unsigned char*)lodepng_malloc(7); if(!data) return 83; /*alloc fail*/ - data[0] = (unsigned char)(time->year / 256); - data[1] = (unsigned char)(time->year % 256); + data[0] = (unsigned char)(time->year >> 8); + data[1] = (unsigned char)(time->year & 255); data[2] = (unsigned char)time->month; data[3] = (unsigned char)time->day; data[4] = (unsigned char)time->hour; @@ -5072,13 +5169,13 @@ static void filterScanline(unsigned char* out, const unsigned char* scanline, co case 3: /*Average*/ if(prevline) { - for(i = 0; i != bytewidth; ++i) out[i] = scanline[i] - prevline[i] / 2; - for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - ((scanline[i - bytewidth] + prevline[i]) / 2); + for(i = 0; i != bytewidth; ++i) out[i] = scanline[i] - (prevline[i] >> 1); + for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - ((scanline[i - bytewidth] + prevline[i]) >> 1); } else { for(i = 0; i != bytewidth; ++i) out[i] = scanline[i]; - for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - scanline[i - bytewidth] / 2; + for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - (scanline[i - bytewidth] >> 1); } break; case 4: /*Paeth*/ @@ -5163,14 +5260,14 @@ static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, { /*adaptive filtering*/ size_t sum[5]; - ucvector attempt[5]; /*five filtering attempts, one for each filter type*/ + unsigned char* attempt[5]; /*five filtering attempts, one for each filter type*/ size_t smallest = 0; unsigned char type, bestType = 0; for(type = 0; type != 5; ++type) { - ucvector_init(&attempt[type]); - if(!ucvector_resize(&attempt[type], linebytes)) return 83; /*alloc fail*/ + attempt[type] = (unsigned char*)lodepng_malloc(linebytes); + if(!attempt[type]) return 83; /*alloc fail*/ } if(!error) @@ -5180,13 +5277,13 @@ static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, /*try the 5 filter types*/ for(type = 0; type != 5; ++type) { - filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type); + filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type); /*calculate the sum of the result*/ sum[type] = 0; if(type == 0) { - for(x = 0; x != linebytes; ++x) sum[type] += (unsigned char)(attempt[type].data[x]); + for(x = 0; x != linebytes; ++x) sum[type] += (unsigned char)(attempt[type][x]); } else { @@ -5195,7 +5292,7 @@ static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, /*For differences, each byte should be treated as signed, values above 127 are negative (converted to signed char). Filtertype 0 isn't a difference though, so use unsigned there. This means filtertype 0 is almost never chosen, but that is justified.*/ - unsigned char s = attempt[type].data[x]; + unsigned char s = attempt[type][x]; sum[type] += s < 128 ? s : (255U - s); } } @@ -5212,24 +5309,24 @@ static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, /*now fill the out values*/ out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ - for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x]; + for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x]; } } - for(type = 0; type != 5; ++type) ucvector_cleanup(&attempt[type]); + for(type = 0; type != 5; ++type) lodepng_free(attempt[type]); } else if(strategy == LFS_ENTROPY) { float sum[5]; - ucvector attempt[5]; /*five filtering attempts, one for each filter type*/ + unsigned char* attempt[5]; /*five filtering attempts, one for each filter type*/ float smallest = 0; unsigned type, bestType = 0; unsigned count[256]; for(type = 0; type != 5; ++type) { - ucvector_init(&attempt[type]); - if(!ucvector_resize(&attempt[type], linebytes)) return 83; /*alloc fail*/ + attempt[type] = (unsigned char*)lodepng_malloc(linebytes); + if(!attempt[type]) return 83; /*alloc fail*/ } for(y = 0; y != h; ++y) @@ -5237,9 +5334,9 @@ static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, /*try the 5 filter types*/ for(type = 0; type != 5; ++type) { - filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type); + filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type); for(x = 0; x != 256; ++x) count[x] = 0; - for(x = 0; x != linebytes; ++x) ++count[attempt[type].data[x]]; + for(x = 0; x != linebytes; ++x) ++count[attempt[type][x]]; ++count[type]; /*the filter type itself is part of the scanline*/ sum[type] = 0; for(x = 0; x != 256; ++x) @@ -5259,10 +5356,10 @@ static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, /*now fill the out values*/ out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ - for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x]; + for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x]; } - for(type = 0; type != 5; ++type) ucvector_cleanup(&attempt[type]); + for(type = 0; type != 5; ++type) lodepng_free(attempt[type]); } else if(strategy == LFS_PREDEFINED) { @@ -5282,7 +5379,7 @@ static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, deflate the scanline after every filter attempt to see which one deflates best. This is very slow and gives only slightly smaller, sometimes even larger, result*/ size_t size[5]; - ucvector attempt[5]; /*five filtering attempts, one for each filter type*/ + unsigned char* attempt[5]; /*five filtering attempts, one for each filter type*/ size_t smallest = 0; unsigned type = 0, bestType = 0; unsigned char* dummy; @@ -5298,20 +5395,20 @@ static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, zlibsettings.custom_deflate = 0; for(type = 0; type != 5; ++type) { - ucvector_init(&attempt[type]); - ucvector_resize(&attempt[type], linebytes); /*todo: give error if resize failed*/ + attempt[type] = (unsigned char*)lodepng_malloc(linebytes); + if(!attempt[type]) return 83; /*alloc fail*/ } for(y = 0; y != h; ++y) /*try the 5 filter types*/ { for(type = 0; type != 5; ++type) { - unsigned testsize = attempt[type].size; + unsigned testsize = linebytes; /*if(testsize > 8) testsize /= 8;*/ /*it already works good enough by testing a part of the row*/ - filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type); + filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type); size[type] = 0; dummy = 0; - zlib_compress(&dummy, &size[type], attempt[type].data, testsize, &zlibsettings); + zlib_compress(&dummy, &size[type], attempt[type], testsize, &zlibsettings); lodepng_free(dummy); /*check if this is smallest size (or if type == 0 it's the first case so always store the values)*/ if(type == 0 || size[type] < smallest) @@ -5322,9 +5419,9 @@ static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, } prevline = &in[y * linebytes]; out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ - for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x]; + for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x]; } - for(type = 0; type != 5; ++type) ucvector_cleanup(&attempt[type]); + for(type = 0; type != 5; ++type) lodepng_free(attempt[type]); } else return 88; /* unknown filter strategy */ @@ -5449,7 +5546,7 @@ static unsigned preProcessScanlines(unsigned char** out, size_t* outsize, const } else { - /*we can immediatly filter into the out buffer, no other steps needed*/ + /*we can immediately filter into the out buffer, no other steps needed*/ error = filter(*out, in, w, h, &info_png->color, settings); } } @@ -5556,22 +5653,12 @@ unsigned lodepng_encode(unsigned char** out, size_t* outsize, *outsize = 0; state->error = 0; - lodepng_info_init(&info); - lodepng_info_copy(&info, &state->info_png); - - if((info.color.colortype == LCT_PALETTE || state->encoder.force_palette) - && (info.color.palettesize == 0 || info.color.palettesize > 256)) + /*check input values validity*/ + if((state->info_png.color.colortype == LCT_PALETTE || state->encoder.force_palette) + && (state->info_png.color.palettesize == 0 || state->info_png.color.palettesize > 256)) { - state->error = 68; /*invalid palette size, it is only allowed to be 1-256*/ - return state->error; + CERROR_RETURN_ERROR(state->error, 68); /*invalid palette size, it is only allowed to be 1-256*/ } - - if(state->encoder.auto_convert) - { - state->error = lodepng_auto_choose_color(&info.color, image, w, h, &state->info_raw); - } - if(state->error) return state->error; - if(state->encoder.zlibsettings.btype > 2) { CERROR_RETURN_ERROR(state->error, 61); /*error: unexisting btype*/ @@ -5580,28 +5667,38 @@ unsigned lodepng_encode(unsigned char** out, size_t* outsize, { CERROR_RETURN_ERROR(state->error, 71); /*error: unexisting interlace mode*/ } - - state->error = checkColorValidity(info.color.colortype, info.color.bitdepth); + state->error = checkColorValidity(state->info_png.color.colortype, state->info_png.color.bitdepth); if(state->error) return state->error; /*error: unexisting color type given*/ state->error = checkColorValidity(state->info_raw.colortype, state->info_raw.bitdepth); if(state->error) return state->error; /*error: unexisting color type given*/ - if(!lodepng_color_mode_equal(&state->info_raw, &info.color)) + /* color convert and compute scanline filter types */ + lodepng_info_init(&info); + lodepng_info_copy(&info, &state->info_png); + if(state->encoder.auto_convert) { - unsigned char* converted; - size_t size = (w * h * lodepng_get_bpp(&info.color) + 7) / 8; - - converted = (unsigned char*)lodepng_malloc(size); - if(!converted && size) state->error = 83; /*alloc fail*/ - if(!state->error) - { - state->error = lodepng_convert(converted, image, &info.color, &state->info_raw, w, h); - } - if(!state->error) preProcessScanlines(&data, &datasize, converted, w, h, &info, &state->encoder); - lodepng_free(converted); + state->error = lodepng_auto_choose_color(&info.color, image, w, h, &state->info_raw); } - else preProcessScanlines(&data, &datasize, image, w, h, &info, &state->encoder); + if (!state->error) + { + if(!lodepng_color_mode_equal(&state->info_raw, &info.color)) + { + unsigned char* converted; + size_t size = (w * h * (size_t)lodepng_get_bpp(&info.color) + 7) / 8; + converted = (unsigned char*)lodepng_malloc(size); + if(!converted && size) state->error = 83; /*alloc fail*/ + if(!state->error) + { + state->error = lodepng_convert(converted, image, &info.color, &state->info_raw, w, h); + } + if(!state->error) preProcessScanlines(&data, &datasize, converted, w, h, &info, &state->encoder); + lodepng_free(converted); + } + else preProcessScanlines(&data, &datasize, image, w, h, &info, &state->encoder); + } + + /* output all PNG chunks */ ucvector_init(&outv); while(!state->error) /*while only executed once, to break on error*/ { @@ -5852,8 +5949,7 @@ const char* lodepng_error_text(unsigned code) case 43: return "bKGD chunk has wrong size for palette image"; case 44: return "bKGD chunk has wrong size for greyscale image"; case 45: return "bKGD chunk has wrong size for RGB image"; - /*the input data is empty, maybe a PNG file doesn't exist or is in the wrong path*/ - case 48: return "empty input or file doesn't exist"; + case 48: return "empty input buffer given to decoder. Maybe caused by non-existing file?"; case 49: return "jumped past memory while generating dynamic huffman tree"; case 50: return "jumped past memory while generating dynamic huffman tree"; case 51: return "jumped past memory while inflating huffman block"; @@ -5903,6 +5999,7 @@ const char* lodepng_error_text(unsigned code) case 91: return "invalid decompressed idat size"; case 92: return "too many pixels, not supported"; case 93: return "zero width or height is invalid"; + case 94: return "header chunk must have a size of 13 bytes"; } return "unknown error code"; } @@ -5919,27 +6016,20 @@ namespace lodepng { #ifdef LODEPNG_COMPILE_DISK -void load_file(std::vector& buffer, const std::string& filename) +unsigned load_file(std::vector& buffer, const std::string& filename) { - std::ifstream file(filename.c_str(), std::ios::in|std::ios::binary|std::ios::ate); - - /*get filesize*/ - std::streamsize size = 0; - if(file.seekg(0, std::ios::end).good()) size = file.tellg(); - if(file.seekg(0, std::ios::beg).good()) size -= file.tellg(); - - /*read contents of the file into the vector*/ - buffer.resize(size_t(size)); - if(size > 0) file.read((char*)(&buffer[0]), size); + long size = lodepng_filesize(filename.c_str()); + if(size < 0) return 78; + buffer.resize((size_t)size); + return size == 0 ? 0 : lodepng_buffer_file(&buffer[0], (size_t)size, filename.c_str()); } /*write given buffer to the file, overwriting the file, it doesn't append to it.*/ -void save_file(const std::vector& buffer, const std::string& filename) +unsigned save_file(const std::vector& buffer, const std::string& filename) { - std::ofstream file(filename.c_str(), std::ios::out|std::ios::binary); - file.write(buffer.empty() ? 0 : (char*)&buffer[0], std::streamsize(buffer.size())); + return lodepng_save_file(buffer.empty() ? 0 : &buffer[0], buffer.size(), filename.c_str()); } -#endif //LODEPNG_COMPILE_DISK +#endif /* LODEPNG_COMPILE_DISK */ #ifdef LODEPNG_COMPILE_ZLIB #ifdef LODEPNG_COMPILE_DECODER @@ -5962,7 +6052,7 @@ unsigned decompress(std::vector& out, const std::vector& out, const unsigned char* in, size_t insize, @@ -5984,8 +6074,8 @@ unsigned compress(std::vector& out, const std::vector& out, unsigned& w, unsigned& h, const LodePNGColorType colortype, unsigned bitdepth) { std::vector buffer; - load_file(buffer, filename); + unsigned error = load_file(buffer, filename); + if(error) return error; return decode(out, w, h, buffer, colortype, bitdepth); } -#endif //LODEPNG_COMPILE_DECODER -#endif //LODEPNG_COMPILE_DISK +#endif /* LODEPNG_COMPILE_DECODER */ +#endif /* LODEPNG_COMPILE_DISK */ #ifdef LODEPNG_COMPILE_ENCODER unsigned encode(std::vector& out, const unsigned char* in, unsigned w, unsigned h, @@ -6123,7 +6214,7 @@ unsigned encode(const std::string& filename, { std::vector buffer; unsigned error = encode(buffer, in, w, h, colortype, bitdepth); - if(!error) save_file(buffer, filename); + if(!error) error = save_file(buffer, filename); return error; } @@ -6134,8 +6225,8 @@ unsigned encode(const std::string& filename, if(lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size()) return 84; return encode(filename, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth); } -#endif //LODEPNG_COMPILE_DISK -#endif //LODEPNG_COMPILE_ENCODER -#endif //LODEPNG_COMPILE_PNG -} //namespace lodepng +#endif /* LODEPNG_COMPILE_DISK */ +#endif /* LODEPNG_COMPILE_ENCODER */ +#endif /* LODEPNG_COMPILE_PNG */ +} /* namespace lodepng */ #endif /*LODEPNG_COMPILE_CPP*/ diff --git a/love/src/jni/love/src/libraries/lodepng/lodepng.h b/love/src/jni/love/src/libraries/lodepng/lodepng.h old mode 100644 new mode 100755 index 1c70e939..d633bfae --- a/love/src/jni/love/src/libraries/lodepng/lodepng.h +++ b/love/src/jni/love/src/libraries/lodepng/lodepng.h @@ -1,7 +1,7 @@ /* -LodePNG version 20141130 +LodePNG version 20170917 -Copyright (c) 2005-2014 Lode Vandevenne +Copyright (c) 2005-2017 Lode Vandevenne This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,12 +28,7 @@ freely, subject to the following restrictions: #include /*for size_t*/ -#ifdef __cplusplus -#include -#include -#endif /*__cplusplus*/ - -#define LODEPNG_VERSION_STRING "20141130" +extern const char* LODEPNG_VERSION_STRING; /* The following #defines are used to create code sections. They can be disabled @@ -41,6 +36,8 @@ to disable code sections, which can give faster compile time and smaller binary. The "NO_COMPILE" defines are designed to be used to pass as defines to the compiler command to disable them without modifying this header, e.g. -DLODEPNG_NO_COMPILE_ZLIB for gcc. +In addition to those below, you can also define LODEPNG_NO_COMPILE_CRC to +allow implementing a custom lodepng_crc32. */ /*deflate & zlib. If disabled, you must specify alternative zlib functions in the custom_zlib field of the compress and decompress settings*/ @@ -61,7 +58,7 @@ the custom_zlib field of the compress and decompress settings*/ #endif /*the optional built in harddisk file loading and saving functions*/ #ifndef LODEPNG_NO_COMPILE_DISK -//#define LODEPNG_COMPILE_DISK +#define LODEPNG_COMPILE_DISK #endif /*support for chunks other than IHDR, IDAT, PLTE, tRNS, IEND: ancillary and unknown chunks*/ #ifndef LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS @@ -84,6 +81,11 @@ source files with custom allocators.*/ #endif #endif +#ifdef LODEPNG_COMPILE_CPP +#include +#include +#endif /*LODEPNG_COMPILE_CPP*/ + #ifdef LODEPNG_COMPILE_PNG /*The PNG color types (also used for raw).*/ typedef enum LodePNGColorType @@ -213,8 +215,8 @@ Same as the other decode functions, but instead takes a filename as input. unsigned decode(std::vector& out, unsigned& w, unsigned& h, const std::string& filename, LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); -#endif //LODEPNG_COMPILE_DISK -#endif //LODEPNG_COMPILE_DECODER +#endif /* LODEPNG_COMPILE_DISK */ +#endif /* LODEPNG_COMPILE_DECODER */ #ifdef LODEPNG_COMPILE_ENCODER /*Same as lodepng_encode_memory, but encodes to an std::vector. colortype @@ -237,9 +239,9 @@ unsigned encode(const std::string& filename, unsigned encode(const std::string& filename, const std::vector& in, unsigned w, unsigned h, LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); -#endif //LODEPNG_COMPILE_DISK -#endif //LODEPNG_COMPILE_ENCODER -} //namespace lodepng +#endif /* LODEPNG_COMPILE_DISK */ +#endif /* LODEPNG_COMPILE_ENCODER */ +} /* namespace lodepng */ #endif /*LODEPNG_COMPILE_CPP*/ #endif /*LODEPNG_COMPILE_PNG*/ @@ -506,7 +508,7 @@ For 16-bit per channel colors, uses big endian format like PNG does. Return value is LodePNG error code */ unsigned lodepng_convert(unsigned char* out, const unsigned char* in, - LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in, + const LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in, unsigned w, unsigned h); #ifdef LODEPNG_COMPILE_DECODER @@ -538,7 +540,7 @@ typedef enum LodePNGFilterStrategy { /*every filter at zero*/ LFS_ZERO, - /*Use filter that gives minumum sum, as described in the official PNG filter heuristic.*/ + /*Use filter that gives minimum sum, as described in the official PNG filter heuristic.*/ LFS_MINSUM, /*Use the filter type that gives smallest Shannon entropy for this scanline. Depending on the image, this is better or worse than minsum.*/ @@ -557,11 +559,11 @@ Used internally by default if "auto_convert" is enabled. Public because it's use typedef struct LodePNGColorProfile { unsigned colored; /*not greyscale*/ - unsigned key; /*if true, image is not opaque. Only if true and alpha is false, color key is possible.*/ - unsigned short key_r; /*these values are always in 16-bit bitdepth in the profile*/ + unsigned key; /*image is not opaque and color key is possible instead of full alpha*/ + unsigned short key_r; /*key values, always as 16-bit, in 8-bit case the byte is duplicated, e.g. 65535 means 255*/ unsigned short key_g; unsigned short key_b; - unsigned alpha; /*alpha channel or alpha palette required*/ + unsigned alpha; /*image is not opaque and alpha channel or alpha palette required*/ unsigned numcolors; /*amount of colors, up to 257. Not valid if bits == 16.*/ unsigned char palette[1024]; /*Remembers up to the first 256 RGBA colors, in no particular order*/ unsigned bits; /*bits per channel (not for palette). 1,2 or 4 for greyscale only. 16 if 16-bit per channel required.*/ @@ -629,7 +631,7 @@ typedef struct LodePNGState LodePNGInfo info_png; /*info of the PNG image obtained after decoding*/ unsigned error; #ifdef LODEPNG_COMPILE_CPP - //For the lodepng::State subclass. + /* For the lodepng::State subclass. */ virtual ~LodePNGState(){} #endif } LodePNGState; @@ -811,7 +813,7 @@ unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const #endif /*LODEPNG_COMPILE_DISK*/ #ifdef LODEPNG_COMPILE_CPP -//The LodePNG C++ wrapper uses std::vectors instead of manually allocated memory buffers. +/* The LodePNG C++ wrapper uses std::vectors instead of manually allocated memory buffers. */ namespace lodepng { #ifdef LODEPNG_COMPILE_PNG @@ -825,7 +827,7 @@ class State : public LodePNGState }; #ifdef LODEPNG_COMPILE_DECODER -//Same as other lodepng::decode, but using a State for more settings and information. +/* Same as other lodepng::decode, but using a State for more settings and information. */ unsigned decode(std::vector& out, unsigned& w, unsigned& h, State& state, const unsigned char* in, size_t insize); @@ -835,7 +837,7 @@ unsigned decode(std::vector& out, unsigned& w, unsigned& h, #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER -//Same as other lodepng::encode, but using a State for more settings and information. +/* Same as other lodepng::encode, but using a State for more settings and information. */ unsigned encode(std::vector& out, const unsigned char* in, unsigned w, unsigned h, State& state); @@ -846,47 +848,47 @@ unsigned encode(std::vector& out, #ifdef LODEPNG_COMPILE_DISK /* -Load a file from disk into an std::vector. If the vector is empty, then either -the file doesn't exist or is an empty file. +Load a file from disk into an std::vector. +return value: error code (0 means ok) */ -void load_file(std::vector& buffer, const std::string& filename); +unsigned load_file(std::vector& buffer, const std::string& filename); /* Save the binary data in an std::vector to a file on disk. The file is overwritten without warning. */ -void save_file(const std::vector& buffer, const std::string& filename); -#endif //LODEPNG_COMPILE_DISK -#endif //LODEPNG_COMPILE_PNG +unsigned save_file(const std::vector& buffer, const std::string& filename); +#endif /* LODEPNG_COMPILE_DISK */ +#endif /* LODEPNG_COMPILE_PNG */ #ifdef LODEPNG_COMPILE_ZLIB #ifdef LODEPNG_COMPILE_DECODER -//Zlib-decompress an unsigned char buffer +/* Zlib-decompress an unsigned char buffer */ unsigned decompress(std::vector& out, const unsigned char* in, size_t insize, const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings); -//Zlib-decompress an std::vector +/* Zlib-decompress an std::vector */ unsigned decompress(std::vector& out, const std::vector& in, const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings); -#endif //LODEPNG_COMPILE_DECODER +#endif /* LODEPNG_COMPILE_DECODER */ #ifdef LODEPNG_COMPILE_ENCODER -//Zlib-compress an unsigned char buffer +/* Zlib-compress an unsigned char buffer */ unsigned compress(std::vector& out, const unsigned char* in, size_t insize, const LodePNGCompressSettings& settings = lodepng_default_compress_settings); -//Zlib-compress an std::vector +/* Zlib-compress an std::vector */ unsigned compress(std::vector& out, const std::vector& in, const LodePNGCompressSettings& settings = lodepng_default_compress_settings); -#endif //LODEPNG_COMPILE_ENCODER -#endif //LODEPNG_COMPILE_ZLIB -} //namespace lodepng +#endif /* LODEPNG_COMPILE_ENCODER */ +#endif /* LODEPNG_COMPILE_ZLIB */ +} /* namespace lodepng */ #endif /*LODEPNG_COMPILE_CPP*/ /* TODO: [.] test if there are no memory leaks or security exploits - done a lot but needs to be checked often -[.] check compatibility with vareous compilers - done but needs to be redone for every newer version +[.] check compatibility with various compilers - done but needs to be redone for every newer version [X] converting color to 16-bit per channel types [ ] read all public PNG chunk types (but never let the color profile and gamma ones touch RGB values) [ ] make sure encoder generates no chunks with size > (2^31)-1 @@ -894,8 +896,10 @@ TODO: [X] let the "isFullyOpaque" function check color keys and transparent palettes too [X] better name for the variables "codes", "codesD", "codelengthcodes", "clcl" and "lldl" [ ] don't stop decoding on errors like 69, 57, 58 (make warnings) +[ ] make warnings like: oob palette, checksum fail, data after iend, wrong/unknown crit chunk, no null terminator in text, ... [ ] let the C++ wrapper catch exceptions coming from the standard library and return LodePNG error codes [ ] allow user to provide custom color conversion functions, e.g. for premultiplied alpha, padding bits or not, ... +[ ] allow user to give data (void*) to custom allocator */ #endif /*LODEPNG_H inclusion guard*/ @@ -925,8 +929,9 @@ LodePNG Documentation 10. examples 10.1. decoder C++ example 10.2. decoder C example - 11. changes - 12. contact information + 11. state settings reference + 12. changes + 13. contact information 1. about @@ -1552,8 +1557,49 @@ int main(int argc, char *argv[]) return 0; } +11. state settings reference +---------------------------- -11. changes +A quick reference of some settings to set on the LodePNGState + +For decoding: + +state.decoder.zlibsettings.ignore_adler32: ignore ADLER32 checksums +state.decoder.zlibsettings.custom_...: use custom inflate function +state.decoder.ignore_crc: ignore CRC checksums +state.decoder.color_convert: convert internal PNG color to chosen one +state.decoder.read_text_chunks: whether to read in text metadata chunks +state.decoder.remember_unknown_chunks: whether to read in unknown chunks +state.info_raw.colortype: desired color type for decoded image +state.info_raw.bitdepth: desired bit depth for decoded image +state.info_raw....: more color settings, see struct LodePNGColorMode +state.info_png....: no settings for decoder but ouput, see struct LodePNGInfo + +For encoding: + +state.encoder.zlibsettings.btype: disable compression by setting it to 0 +state.encoder.zlibsettings.use_lz77: use LZ77 in compression +state.encoder.zlibsettings.windowsize: tweak LZ77 windowsize +state.encoder.zlibsettings.minmatch: tweak min LZ77 length to match +state.encoder.zlibsettings.nicematch: tweak LZ77 match where to stop searching +state.encoder.zlibsettings.lazymatching: try one more LZ77 matching +state.encoder.zlibsettings.custom_...: use custom deflate function +state.encoder.auto_convert: choose optimal PNG color type, if 0 uses info_png +state.encoder.filter_palette_zero: PNG filter strategy for palette +state.encoder.filter_strategy: PNG filter strategy to encode with +state.encoder.force_palette: add palette even if not encoding to one +state.encoder.add_id: add LodePNG identifier and version as a text chunk +state.encoder.text_compression: use compressed text chunks for metadata +state.info_raw.colortype: color type of raw input image you provide +state.info_raw.bitdepth: bit depth of raw input image you provide +state.info_raw: more color settings, see struct LodePNGColorMode +state.info_png.color.colortype: desired color type if auto_convert is false +state.info_png.color.bitdepth: desired bit depth if auto_convert is false +state.info_png.color....: more color settings, see struct LodePNGColorMode +state.info_png....: more PNG related settings, see struct LodePNGInfo + + +12. changes ----------- The version number of LodePNG is the date of the change given in the format @@ -1562,6 +1608,14 @@ yyyymmdd. Some changes aren't backwards compatible. Those are indicated with a (!) symbol. +*) 17 sep 2017: fix memory leak for some encoder input error cases +*) 27 nov 2016: grey+alpha auto color model detection bugfix +*) 18 apr 2016: Changed qsort to custom stable sort (for platforms w/o qsort). +*) 09 apr 2016: Fixed colorkey usage detection, and better file loading (within + the limits of pure C90). +*) 08 dec 2015: Made load_file function return error if file can't be opened. +*) 24 okt 2015: Bugfix with decoding to palette output. +*) 18 apr 2015: Boundary PM instead of just package-merge for faster encoding. *) 23 aug 2014: Reduced needless memory usage of decoder. *) 28 jun 2014: Removed fix_png setting, always support palette OOB for simplicity. Made ColorProfile public. @@ -1586,7 +1640,7 @@ symbol. *) 22 apr 2012 (!): Made interface more consistent, renaming a lot. Removed redundant C++ codec classes. Reduced amount of structs. Everything changed, but it is cleaner now imho and functionality remains the same. Also fixed - several bugs and shrinked the implementation code. Made new samples. + several bugs and shrunk the implementation code. Made new samples. *) 6 nov 2011 (!): By default, the encoder now automatically chooses the best PNG color model and bit depth, based on the amount and type of colors of the raw image. For this, autoLeaveOutAlphaChannel replaced by auto_choose_color. @@ -1621,7 +1675,7 @@ symbol. *) 20 jan 2008: support for unknown chunks allowing using LodePNG for an editor. *) 18 jan 2008: support for tIME and pHYs chunks added to encoder and decoder. *) 17 jan 2008: ability to encode and decode compressed zTXt chunks added - Also vareous fixes, such as in the deflate and the padding bits code. + Also various fixes, such as in the deflate and the padding bits code. *) 13 jan 2008: Added ability to encode Adam7-interlaced images. Improved filtering code of encoder. *) 07 jan 2008: (!) changed LodePNG to use ISO C90 instead of C++. A @@ -1692,7 +1746,7 @@ symbol. *) 12 aug 2005: Initial release (C++, decoder only) -12. contact information +13. contact information ----------------------- Feel free to contact me with suggestions, problems, comments, ... concerning @@ -1704,5 +1758,5 @@ Domain: gmail dot com. Account: lode dot vandevenne. -Copyright (c) 2005-2014 Lode Vandevenne +Copyright (c) 2005-2017 Lode Vandevenne */ diff --git a/love/src/jni/love/src/libraries/luautf8/lprefix.h b/love/src/jni/love/src/libraries/lua53/lprefix.h similarity index 100% rename from love/src/jni/love/src/libraries/luautf8/lprefix.h rename to love/src/jni/love/src/libraries/lua53/lprefix.h diff --git a/love/src/jni/love/src/libraries/lua53/lstrlib.c b/love/src/jni/love/src/libraries/lua53/lstrlib.c new file mode 100755 index 00000000..03f574f1 --- /dev/null +++ b/love/src/jni/love/src/libraries/lua53/lstrlib.c @@ -0,0 +1,600 @@ +/* +** $Id: lstrlib.c,v 1.254 2016/12/22 13:08:50 roberto Exp $ +** Standard library for string operations and pattern-matching +** Modified by the Kepler Project and the LOVE Development Team to work with +** Lua 5.1's API +*/ + +/********************************************************************* + * The MIT License (MIT) + * + * Copyright (c) 2015 Kepler Project. + * + * 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. + *********************************************************************/ + +/********************************************************************* + * This file contains parts of Lua 5.2's and Lua 5.3's source code: + * + * Copyright (C) 1994-2014 Lua.org, PUC-Rio. + * + * 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 "lprefix.h" + + +#include +#include +#include +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" +#include "lstrlib.h" + +#if LUA_VERSION_NUM == 501 +typedef size_t lua_Unsigned; +#endif + +#if LUA_VERSION_NUM == 501 +# define LUAL_BUFFER53_BUFFER(B) (B)->b.buffer +#else +# define LUAL_BUFFER53_BUFFER(B) (B)->b.initb +#endif + +static void luaL_buffinit_53 (lua_State *L, luaL_Buffer_53 *B) { +#if LUA_VERSION_NUM == 501 + /* make it crash if used via pointer to a 5.1-style luaL_Buffer */ + B->b.p = NULL; + B->b.L = NULL; + B->b.lvl = 0; + /* reuse the buffer from the 5.1-style luaL_Buffer though! */ + B->ptr = B->b.buffer; + B->capacity = LUAL_BUFFERSIZE; + B->nelems = 0; + B->L2 = L; +#else + return luaL_buffinit(L, (luaL_Buffer*) B); +#endif +} + + +static char *luaL_prepbuffsize_53 (luaL_Buffer_53 *B, size_t s) { +#if LUA_VERSION_NUM == 501 + if (B->capacity - B->nelems < s) { /* needs to grow */ + char* newptr = NULL; + size_t newcap = B->capacity * 2; + if (newcap - B->nelems < s) + newcap = B->nelems + s; + if (newcap < B->capacity) /* overflow */ + luaL_error(B->L2, "buffer too large"); + newptr = (char*)lua_newuserdata(B->L2, newcap); + memcpy(newptr, B->ptr, B->nelems); + if (B->ptr != B->b.buffer) + lua_replace(B->L2, -2); /* remove old buffer */ + B->ptr = newptr; + B->capacity = newcap; + } + return B->ptr+B->nelems; +#else + return luaL_prepbuffsize((luaL_Buffer*) B, s); +#endif +} + + +#define luaL_addsize_53(B, s) \ + ((B)->nelems += (s)) + +#define luaL_addchar_53(B, c) \ + ((void)((B)->nelems < (B)->capacity || luaL_prepbuffsize_53((B), 1)), \ + ((B)->ptr[(B)->nelems++] = (c))) + + +static void luaL_addlstring_53 (luaL_Buffer_53 *B, const char *s, size_t l) { + memcpy(luaL_prepbuffsize_53(B, l), s, l); + luaL_addsize_53(B, l); +} + + +void lua53_pushresult (luaL_Buffer_53 *B) { + lua_pushlstring(B->L2, B->ptr, B->nelems); + if (B->ptr != LUAL_BUFFER53_BUFFER(B)) + lua_replace(B->L2, -2); /* remove userdata buffer */ +} + +void lua53_cleanupbuffer (luaL_Buffer_53 *B) { + if (B->ptr != LUAL_BUFFER53_BUFFER(B)) + lua_replace(B->L2, -1); /* remove userdata buffer */ +} + +/* +** Some sizes are better limited to fit in 'int', but must also fit in +** 'size_t'. (We assume that 'lua_Integer' cannot be smaller than 'int'.) +*/ +#define MAX_SIZET ((size_t)(~(size_t)0)) + +#define MAXSIZE \ + (sizeof(size_t) < sizeof(int) ? MAX_SIZET : (size_t)(INT_MAX)) + + +/* translate a relative string position: negative means back from end */ +static lua_Integer posrelat (lua_Integer pos, size_t len) { + if (pos >= 0) return pos; + else if (0u - (size_t)pos > len) return 0; + else return (lua_Integer)len + pos + 1; +} + + +/* +** {====================================================== +** PACK/UNPACK +** ======================================================= +*/ + + +/* value used for padding */ +#if !defined(LUAL_PACKPADBYTE) +#define LUAL_PACKPADBYTE 0x00 +#endif + +/* maximum size for the binary representation of an integer */ +#define MAXINTSIZE 16 + +/* number of bits in a character */ +#define NB CHAR_BIT + +/* mask for one character (NB 1's) */ +#define MC ((1 << NB) - 1) + +/* size of a lua_Integer */ +#define SZINT ((int)sizeof(lua_Integer)) + + +/* dummy union to get native endianness */ +static const union { + int dummy; + char little; /* true iff machine is little endian */ +} nativeendian = {1}; + + +/* dummy structure to get native alignment requirements */ +struct cD { + char c; + union { double d; void *p; lua_Integer i; lua_Number n; } u; +}; + +#define MAXALIGN (offsetof(struct cD, u)) + + +/* +** Union for serializing floats +*/ +typedef union Ftypes { + float f; + double d; + lua_Number n; + char buff[5 * sizeof(lua_Number)]; /* enough for any float type */ +} Ftypes; + + +/* +** information to pack/unpack stuff +*/ +typedef struct Header { + lua_State *L; + int islittle; + int maxalign; +} Header; + + +/* +** options for pack/unpack +*/ +typedef enum KOption { + Kint, /* signed integers */ + Kuint, /* unsigned integers */ + Kfloat, /* floating-point numbers */ + Kchar, /* fixed-length strings */ + Kstring, /* strings with prefixed length */ + Kzstr, /* zero-terminated strings */ + Kpadding, /* padding */ + Kpaddalign, /* padding for alignment */ + Knop /* no-op (configuration or spaces) */ +} KOption; + + +/* +** Read an integer numeral from string 'fmt' or return 'df' if +** there is no numeral +*/ +static int digit (int c) { return '0' <= c && c <= '9'; } + +static int getnum (const char **fmt, int df) { + if (!digit(**fmt)) /* no number? */ + return df; /* return default value */ + else { + int a = 0; + do { + a = a*10 + (*((*fmt)++) - '0'); + } while (digit(**fmt) && a <= ((int)MAXSIZE - 9)/10); + return a; + } +} + + +/* +** Read an integer numeral and raises an error if it is larger +** than the maximum size for integers. +*/ +static int getnumlimit (Header *h, const char **fmt, int df) { + int sz = getnum(fmt, df); + if (sz > MAXINTSIZE || sz <= 0) + luaL_error(h->L, "integral size (%d) out of limits [1,%d]", + sz, MAXINTSIZE); + return sz; +} + + +/* +** Initialize Header +*/ +static void initheader (lua_State *L, Header *h) { + h->L = L; + h->islittle = nativeendian.little; + h->maxalign = 1; +} + + +/* +** Read and classify next option. 'size' is filled with option's size. +*/ +static KOption getoption (Header *h, const char **fmt, int *size) { + int opt = *((*fmt)++); + *size = 0; /* default */ + switch (opt) { + case 'b': *size = sizeof(char); return Kint; + case 'B': *size = sizeof(char); return Kuint; + case 'h': *size = sizeof(short); return Kint; + case 'H': *size = sizeof(short); return Kuint; + case 'l': *size = sizeof(long); return Kint; + case 'L': *size = sizeof(long); return Kuint; + case 'j': *size = sizeof(lua_Integer); return Kint; + case 'J': *size = sizeof(lua_Integer); return Kuint; + case 'T': *size = sizeof(size_t); return Kuint; + case 'f': *size = sizeof(float); return Kfloat; + case 'd': *size = sizeof(double); return Kfloat; + case 'n': *size = sizeof(lua_Number); return Kfloat; + case 'i': *size = getnumlimit(h, fmt, sizeof(int)); return Kint; + case 'I': *size = getnumlimit(h, fmt, sizeof(int)); return Kuint; + case 's': *size = getnumlimit(h, fmt, sizeof(size_t)); return Kstring; + case 'c': + *size = getnum(fmt, -1); + if (*size == -1) + luaL_error(h->L, "missing size for format option 'c'"); + return Kchar; + case 'z': return Kzstr; + case 'x': *size = 1; return Kpadding; + case 'X': return Kpaddalign; + case ' ': break; + case '<': h->islittle = 1; break; + case '>': h->islittle = 0; break; + case '=': h->islittle = nativeendian.little; break; + case '!': h->maxalign = getnumlimit(h, fmt, MAXALIGN); break; + default: luaL_error(h->L, "invalid format option '%c'", opt); + } + return Knop; +} + + +/* +** Read, classify, and fill other details about the next option. +** 'psize' is filled with option's size, 'notoalign' with its +** alignment requirements. +** Local variable 'size' gets the size to be aligned. (Kpadal option +** always gets its full alignment, other options are limited by +** the maximum alignment ('maxalign'). Kchar option needs no alignment +** despite its size. +*/ +static KOption getdetails (Header *h, size_t totalsize, + const char **fmt, int *psize, int *ntoalign) { + KOption opt = getoption(h, fmt, psize); + int align = *psize; /* usually, alignment follows size */ + if (opt == Kpaddalign) { /* 'X' gets alignment from following option */ + if (**fmt == '\0' || getoption(h, fmt, &align) == Kchar || align == 0) + luaL_argerror(h->L, 1, "invalid next option for option 'X'"); + } + if (align <= 1 || opt == Kchar) /* need no alignment? */ + *ntoalign = 0; + else { + if (align > h->maxalign) /* enforce maximum alignment */ + align = h->maxalign; + if ((align & (align - 1)) != 0) /* is 'align' not a power of 2? */ + luaL_argerror(h->L, 1, "format asks for alignment not power of 2"); + *ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1); + } + return opt; +} + + +/* +** Pack integer 'n' with 'size' bytes and 'islittle' endianness. +** The final 'if' handles the case when 'size' is larger than +** the size of a Lua integer, correcting the extra sign-extension +** bytes if necessary (by default they would be zeros). +*/ +static void packint (luaL_Buffer_53 *b, lua_Unsigned n, + int islittle, int size, int neg) { + char *buff = luaL_prepbuffsize_53(b, size); + int i; + buff[islittle ? 0 : size - 1] = (char)(n & MC); /* first byte */ + for (i = 1; i < size; i++) { + n >>= NB; + buff[islittle ? i : size - 1 - i] = (char)(n & MC); + } + if (neg && size > SZINT) { /* negative number need sign extension? */ + for (i = SZINT; i < size; i++) /* correct extra bytes */ + buff[islittle ? i : size - 1 - i] = (char)MC; + } + luaL_addsize_53(b, size); /* add result to buffer */ +} + + +/* +** Copy 'size' bytes from 'src' to 'dest', correcting endianness if +** given 'islittle' is different from native endianness. +*/ +static void copywithendian (volatile char *dest, volatile const char *src, + int size, int islittle) { + if (islittle == nativeendian.little) { + while (size-- != 0) + *(dest++) = *(src++); + } + else { + dest += size - 1; + while (size-- != 0) + *(dest--) = *(src++); + } +} + + +void lua53_str_pack (lua_State *L, const char *fmt, int startidx, luaL_Buffer_53 *b) { + Header h; + int arg = startidx - 1; /* current argument to pack */ + size_t totalsize = 0; /* accumulate total size of result */ + initheader(L, &h); + lua_pushnil(L); /* mark to separate arguments from string buffer */ + luaL_buffinit_53(L, b); + while (*fmt != '\0') { + int size, ntoalign; + KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); + totalsize += ntoalign + size; + while (ntoalign-- > 0) + luaL_addchar_53(b, LUAL_PACKPADBYTE); /* fill alignment */ + arg++; + switch (opt) { + case Kint: { /* signed integers */ + lua_Integer n = luaL_checkinteger(L, arg); + if (size < SZINT) { /* need overflow check? */ + lua_Integer lim = (lua_Integer)1 << ((size * NB) - 1); + luaL_argcheck(L, -lim <= n && n < lim, arg, "integer overflow"); + } + packint(b, (lua_Unsigned)n, h.islittle, size, (n < 0)); + break; + } + case Kuint: { /* unsigned integers */ + lua_Integer n = luaL_checkinteger(L, arg); + if (size < SZINT) /* need overflow check? */ + luaL_argcheck(L, (lua_Unsigned)n < ((lua_Unsigned)1 << (size * NB)), + arg, "unsigned overflow"); + packint(b, (lua_Unsigned)n, h.islittle, size, 0); + break; + } + case Kfloat: { /* floating-point options */ + volatile Ftypes u; + char *buff = luaL_prepbuffsize_53(b, size); + lua_Number n = luaL_checknumber(L, arg); /* get argument */ + if (size == sizeof(u.f)) u.f = (float)n; /* copy it into 'u' */ + else if (size == sizeof(u.d)) u.d = (double)n; + else u.n = n; + /* move 'u' to final result, correcting endianness if needed */ + copywithendian(buff, u.buff, size, h.islittle); + luaL_addsize_53(b, size); + break; + } + case Kchar: { /* fixed-size string */ + size_t len; + const char *s = luaL_checklstring(L, arg, &len); + luaL_argcheck(L, len <= (size_t)size, arg, + "string longer than given size"); + luaL_addlstring_53(b, s, len); /* add string */ + while (len++ < (size_t)size) /* pad extra space */ + luaL_addchar_53(b, LUAL_PACKPADBYTE); + break; + } + case Kstring: { /* strings with length count */ + size_t len; + const char *s = luaL_checklstring(L, arg, &len); + luaL_argcheck(L, size >= (int)sizeof(size_t) || + len < ((size_t)1 << (size * NB)), + arg, "string length does not fit in given size"); + packint(b, (lua_Unsigned)len, h.islittle, size, 0); /* pack length */ + luaL_addlstring_53(b, s, len); + totalsize += len; + break; + } + case Kzstr: { /* zero-terminated string */ + size_t len; + const char *s = luaL_checklstring(L, arg, &len); + luaL_argcheck(L, strlen(s) == len, arg, "string contains zeros"); + luaL_addlstring_53(b, s, len); + luaL_addchar_53(b, '\0'); /* add zero at the end */ + totalsize += len + 1; + break; + } + case Kpadding: luaL_addchar_53(b, LUAL_PACKPADBYTE); /* FALLTHROUGH */ + case Kpaddalign: case Knop: + arg--; /* undo increment */ + break; + } + } +} + + +int lua53_str_packsize (lua_State *L) { + Header h; + const char *fmt = luaL_checkstring(L, 1); /* format string */ + size_t totalsize = 0; /* accumulate total size of result */ + initheader(L, &h); + while (*fmt != '\0') { + int size, ntoalign; + KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); + size += ntoalign; /* total space used by option */ + luaL_argcheck(L, totalsize <= MAXSIZE - size, 1, + "format result too large"); + totalsize += size; + switch (opt) { + case Kstring: /* strings with length count */ + case Kzstr: /* zero-terminated string */ + luaL_argerror(L, 1, "variable-length format"); + /* call never return, but to avoid warnings: *//* FALLTHROUGH */ + default: break; + } + } + lua_pushinteger(L, (lua_Integer)totalsize); + return 1; +} + + +/* +** Unpack an integer with 'size' bytes and 'islittle' endianness. +** If size is smaller than the size of a Lua integer and integer +** is signed, must do sign extension (propagating the sign to the +** higher bits); if size is larger than the size of a Lua integer, +** it must check the unread bytes to see whether they do not cause an +** overflow. +*/ +static lua_Integer unpackint (lua_State *L, const char *str, + int islittle, int size, int issigned) { + lua_Unsigned res = 0; + int i; + int limit = (size <= SZINT) ? size : SZINT; + for (i = limit - 1; i >= 0; i--) { + res <<= NB; + res |= (lua_Unsigned)(unsigned char)str[islittle ? i : size - 1 - i]; + } + if (size < SZINT) { /* real size smaller than lua_Integer? */ + if (issigned) { /* needs sign extension? */ + lua_Unsigned mask = (lua_Unsigned)1 << (size*NB - 1); + res = ((res ^ mask) - mask); /* do sign extension */ + } + } + else if (size > SZINT) { /* must check unread bytes */ + int mask = (!issigned || (lua_Integer)res >= 0) ? 0 : MC; + for (i = limit; i < size; i++) { + if ((unsigned char)str[islittle ? i : size - 1 - i] != mask) + luaL_error(L, "%d-byte integer does not fit into Lua Integer", size); + } + } + return (lua_Integer)res; +} + + +int lua53_str_unpack (lua_State *L, const char *fmt, const char *data, size_t ld, int dataidx, int posidx) { + Header h; + size_t pos = (size_t)posrelat(luaL_optinteger(L, posidx, 1), ld) - 1; + int n = 0; /* number of results */ + luaL_argcheck(L, pos <= ld, posidx, "initial position out of string"); + initheader(L, &h); + while (*fmt != '\0') { + int size, ntoalign; + KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign); + if ((size_t)ntoalign + size > ~pos || pos + ntoalign + size > ld) + luaL_argerror(L, dataidx, "data string too short"); + pos += ntoalign; /* skip alignment */ + /* stack space for item + next position */ + luaL_checkstack(L, dataidx, "too many results"); + n++; + switch (opt) { + case Kint: + case Kuint: { + lua_Integer res = unpackint(L, data + pos, h.islittle, size, + (opt == Kint)); + lua_pushinteger(L, res); + break; + } + case Kfloat: { + volatile Ftypes u; + lua_Number num; + copywithendian(u.buff, data + pos, size, h.islittle); + if (size == sizeof(u.f)) num = (lua_Number)u.f; + else if (size == sizeof(u.d)) num = (lua_Number)u.d; + else num = u.n; + lua_pushnumber(L, num); + break; + } + case Kchar: { + lua_pushlstring(L, data + pos, size); + break; + } + case Kstring: { + size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0); + luaL_argcheck(L, pos + len + size <= ld, dataidx, "data string too short"); + lua_pushlstring(L, data + pos + size, len); + pos += len; /* skip string */ + break; + } + case Kzstr: { + size_t len = (int)strlen(data + pos); + lua_pushlstring(L, data + pos, len); + pos += len + 1; /* skip string plus final '\0' */ + break; + } + case Kpaddalign: case Kpadding: case Knop: + n--; /* undo increment */ + break; + } + pos += size; + } + lua_pushinteger(L, pos + 1); /* next position */ + return n + 1; +} + +/* }====================================================== */ + diff --git a/love/src/jni/love/src/libraries/lua53/lstrlib.h b/love/src/jni/love/src/libraries/lua53/lstrlib.h new file mode 100644 index 00000000..f341313c --- /dev/null +++ b/love/src/jni/love/src/libraries/lua53/lstrlib.h @@ -0,0 +1,30 @@ + +#ifndef LUA53_LSTRLIB_H +#define LUA53_LSTRLIB_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lua.h" + +typedef struct luaL_Buffer_53 { + luaL_Buffer b; /* make incorrect code crash! */ + char *ptr; + size_t nelems; + size_t capacity; + lua_State *L2; +} luaL_Buffer_53; + +void lua53_pushresult (luaL_Buffer_53 *B); +void lua53_cleanupbuffer (luaL_Buffer_53 *B); + +void lua53_str_pack (lua_State *L, const char *fmt, int startidx, luaL_Buffer_53 *b); +int lua53_str_packsize (lua_State *L); +int lua53_str_unpack (lua_State *L, const char *fmt, const char *data, size_t ld, int dataidx, int posidx); + +#ifdef __cplusplus +} +#endif + +#endif /* LUA53_LSTRLIB_H */ diff --git a/love/src/jni/love/src/libraries/luautf8/lutf8lib.c b/love/src/jni/love/src/libraries/lua53/lutf8lib.c similarity index 100% rename from love/src/jni/love/src/libraries/luautf8/lutf8lib.c rename to love/src/jni/love/src/libraries/lua53/lutf8lib.c diff --git a/love/src/jni/love/src/libraries/luautf8/lutf8lib.h b/love/src/jni/love/src/libraries/lua53/lutf8lib.h similarity index 59% rename from love/src/jni/love/src/libraries/luautf8/lutf8lib.h rename to love/src/jni/love/src/libraries/lua53/lutf8lib.h index bb4627b5..34999f04 100644 --- a/love/src/jni/love/src/libraries/luautf8/lutf8lib.h +++ b/love/src/jni/love/src/libraries/lua53/lutf8lib.h @@ -1,6 +1,6 @@ -#ifndef LUAUTF8_LUTF8LIB_H -#define LUAUTF8_LUTF8LIB_H +#ifndef LUA53_LUTF8LIB_H +#define LUA53_LUTF8LIB_H #ifdef __cplusplus extern "C" { @@ -14,4 +14,4 @@ LUALIB_API int luaopen_luautf8(lua_State *L); } #endif -#endif /* LOVE_LUAUTF8_LUTF8LIB_H */ +#endif /* LUA53_LUTF8LIB_H */ diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/auxiliar.c b/love/src/jni/love/src/libraries/luasocket/libluasocket/auxiliar.c index 95149701..18fa8e4c 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/auxiliar.c +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/auxiliar.c @@ -1,8 +1,6 @@ /*=========================================================================*\ * Auxiliar routines for class hierarchy manipulation * LuaSocket toolkit -* -* RCS ID: $Id: auxiliar.c,v 1.14 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ #include #include @@ -24,11 +22,11 @@ int auxiliar_open(lua_State *L) { * Creates a new class with given methods * Methods whose names start with __ are passed directly to the metatable. \*-------------------------------------------------------------------------*/ -void auxiliar_newclass(lua_State *L, const char *classname, luaL_reg *func) { +void auxiliar_newclass(lua_State *L, const char *classname, luaL_Reg *func) { luaL_newmetatable(L, classname); /* mt */ /* create __index table to place methods */ lua_pushstring(L, "__index"); /* mt,"__index" */ - lua_newtable(L); /* mt,"__index",it */ + lua_newtable(L); /* mt,"__index",it */ /* put class name into class metatable */ lua_pushstring(L, "class"); /* mt,"__index",it,"class" */ lua_pushstring(L, classname); /* mt,"__index",it,"class",classname */ @@ -81,12 +79,12 @@ void auxiliar_add2group(lua_State *L, const char *classname, const char *groupna \*-------------------------------------------------------------------------*/ int auxiliar_checkboolean(lua_State *L, int objidx) { if (!lua_isboolean(L, objidx)) - luaL_typerror(L, objidx, lua_typename(L, LUA_TBOOLEAN)); + auxiliar_typeerror(L, objidx, lua_typename(L, LUA_TBOOLEAN)); return lua_toboolean(L, objidx); } /*-------------------------------------------------------------------------*\ -* Return userdata pointer if object belongs to a given class, abort with +* Return userdata pointer if object belongs to a given class, abort with * error otherwise \*-------------------------------------------------------------------------*/ void *auxiliar_checkclass(lua_State *L, const char *classname, int objidx) { @@ -100,7 +98,7 @@ void *auxiliar_checkclass(lua_State *L, const char *classname, int objidx) { } /*-------------------------------------------------------------------------*\ -* Return userdata pointer if object belongs to a given group, abort with +* Return userdata pointer if object belongs to a given group, abort with * error otherwise \*-------------------------------------------------------------------------*/ void *auxiliar_checkgroup(lua_State *L, const char *groupname, int objidx) { @@ -123,7 +121,7 @@ void auxiliar_setclass(lua_State *L, const char *classname, int objidx) { } /*-------------------------------------------------------------------------*\ -* Get a userdata pointer if object belongs to a given group. Return NULL +* Get a userdata pointer if object belongs to a given group. Return NULL * otherwise \*-------------------------------------------------------------------------*/ void *auxiliar_getgroupudata(lua_State *L, const char *groupname, int objidx) { @@ -141,9 +139,20 @@ void *auxiliar_getgroupudata(lua_State *L, const char *groupname, int objidx) { } /*-------------------------------------------------------------------------*\ -* Get a userdata pointer if object belongs to a given class. Return NULL +* Get a userdata pointer if object belongs to a given class. Return NULL * otherwise \*-------------------------------------------------------------------------*/ void *auxiliar_getclassudata(lua_State *L, const char *classname, int objidx) { return luaL_checkudata(L, objidx, classname); } + +/*-------------------------------------------------------------------------*\ +* Throws error when argument does not have correct type. +* Used to be part of lauxlib in Lua 5.1, was dropped from 5.2. +\*-------------------------------------------------------------------------*/ +int auxiliar_typeerror (lua_State *L, int narg, const char *tname) { + const char *msg = lua_pushfstring(L, "%s expected, got %s", tname, + luaL_typename(L, narg)); + return luaL_argerror(L, narg, msg); +} + diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/auxiliar.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/auxiliar.h index 18b84955..65511d4d 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/auxiliar.h +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/auxiliar.h @@ -4,12 +4,12 @@ * Auxiliar routines for class hierarchy manipulation * LuaSocket toolkit (but completely independent of other LuaSocket modules) * -* A LuaSocket class is a name associated with Lua metatables. A LuaSocket -* group is a name associated with a class. A class can belong to any number +* A LuaSocket class is a name associated with Lua metatables. A LuaSocket +* group is a name associated with a class. A class can belong to any number * of groups. This module provides the functionality to: * -* - create new classes -* - add classes to groups +* - create new classes +* - add classes to groups * - set the class of objects * - check if an object belongs to a given class or group * - get the userdata associated to objects @@ -26,16 +26,15 @@ * "class" with the class name. * * The mapping from class name to the corresponding metatable and the -* reverse mapping are done using lauxlib. -* -* RCS ID: $Id: auxiliar.h,v 1.9 2005/10/07 04:40:59 diego Exp $ +* reverse mapping are done using lauxlib. \*=========================================================================*/ #include "lua.h" #include "lauxlib.h" +#include "compat.h" int auxiliar_open(lua_State *L); -void auxiliar_newclass(lua_State *L, const char *classname, luaL_reg *func); +void auxiliar_newclass(lua_State *L, const char *classname, luaL_Reg *func); void auxiliar_add2group(lua_State *L, const char *classname, const char *group); void auxiliar_setclass(lua_State *L, const char *classname, int objidx); void *auxiliar_checkclass(lua_State *L, const char *classname, int objidx); @@ -44,5 +43,6 @@ void *auxiliar_getclassudata(lua_State *L, const char *groupname, int objidx); void *auxiliar_getgroupudata(lua_State *L, const char *groupname, int objidx); int auxiliar_checkboolean(lua_State *L, int objidx); int auxiliar_tostring(lua_State *L); +int auxiliar_typeerror(lua_State *L, int narg, const char *tname); #endif /* AUXILIAR_H */ diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/buffer.c b/love/src/jni/love/src/libraries/luasocket/libluasocket/buffer.c index 73f4ffa8..fff16346 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/buffer.c +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/buffer.c @@ -1,11 +1,10 @@ /*=========================================================================*\ * Input/Output interface for Lua programs * LuaSocket toolkit -* -* RCS ID: $Id: buffer.c,v 1.28 2007/06/11 23:44:54 diego Exp $ \*=========================================================================*/ #include "lua.h" #include "lauxlib.h" +#include "compat.h" #include "buffer.h" @@ -39,10 +38,10 @@ int buffer_open(lua_State *L) { } /*-------------------------------------------------------------------------*\ -* Initializes C structure +* Initializes C structure \*-------------------------------------------------------------------------*/ void buffer_init(p_buffer buf, p_io io, p_timeout tm) { - buf->first = buf->last = 0; + buf->first = buf->last = 0; buf->io = io; buf->tm = tm; buf->received = buf->sent = 0; @@ -53,8 +52,8 @@ void buffer_init(p_buffer buf, p_io io, p_timeout tm) { * object:getstats() interface \*-------------------------------------------------------------------------*/ int buffer_meth_getstats(lua_State *L, p_buffer buf) { - lua_pushnumber(L, buf->received); - lua_pushnumber(L, buf->sent); + lua_pushnumber(L, (lua_Number) buf->received); + lua_pushnumber(L, (lua_Number) buf->sent); lua_pushnumber(L, timeout_gettime() - buf->birthday); return 3; } @@ -63,8 +62,8 @@ int buffer_meth_getstats(lua_State *L, p_buffer buf) { * object:setstats() interface \*-------------------------------------------------------------------------*/ int buffer_meth_setstats(lua_State *L, p_buffer buf) { - buf->received = (long) luaL_optnumber(L, 2, buf->received); - buf->sent = (long) luaL_optnumber(L, 3, buf->sent); + buf->received = (long) luaL_optnumber(L, 2, (lua_Number) buf->received); + buf->sent = (long) luaL_optnumber(L, 3, (lua_Number) buf->sent); if (lua_isnumber(L, 4)) buf->birthday = timeout_gettime() - lua_tonumber(L, 4); lua_pushnumber(L, 1); return 1; @@ -80,7 +79,7 @@ int buffer_meth_send(lua_State *L, p_buffer buf) { const char *data = luaL_checklstring(L, 2, &size); long start = (long) luaL_optnumber(L, 3, 1); long end = (long) luaL_optnumber(L, 4, -1); - p_timeout tm = timeout_markstart(buf->tm); + timeout_markstart(buf->tm); if (start < 0) start = (long) (size+start+1); if (end < 0) end = (long) (size+end+1); if (start < 1) start = (long) 1; @@ -89,16 +88,16 @@ int buffer_meth_send(lua_State *L, p_buffer buf) { /* check if there was an error */ if (err != IO_DONE) { lua_pushnil(L); - lua_pushstring(L, buf->io->error(buf->io->ctx, err)); - lua_pushnumber(L, sent+start-1); + lua_pushstring(L, buf->io->error(buf->io->ctx, err)); + lua_pushnumber(L, (lua_Number) (sent+start-1)); } else { - lua_pushnumber(L, sent+start-1); + lua_pushnumber(L, (lua_Number) (sent+start-1)); lua_pushnil(L); lua_pushnil(L); } #ifdef LUASOCKET_DEBUG /* push time elapsed during operation as the last return value */ - lua_pushnumber(L, timeout_gettime() - timeout_getstart(tm)); + lua_pushnumber(L, timeout_gettime() - timeout_getstart(buf->tm)); #endif return lua_gettop(L) - top; } @@ -111,8 +110,8 @@ int buffer_meth_receive(lua_State *L, p_buffer buf) { luaL_Buffer b; size_t size; const char *part = luaL_optlstring(L, 3, "", &size); - p_timeout tm = timeout_markstart(buf->tm); - /* initialize buffer with optional extra prefix + timeout_markstart(buf->tm); + /* initialize buffer with optional extra prefix * (useful for concatenating previous partial results) */ luaL_buffinit(L, &b); luaL_addlstring(&b, part, size); @@ -120,18 +119,24 @@ int buffer_meth_receive(lua_State *L, p_buffer buf) { if (!lua_isnumber(L, 2)) { const char *p= luaL_optstring(L, 2, "*l"); if (p[0] == '*' && p[1] == 'l') err = recvline(buf, &b); - else if (p[0] == '*' && p[1] == 'a') err = recvall(buf, &b); + else if (p[0] == '*' && p[1] == 'a') err = recvall(buf, &b); else luaL_argcheck(L, 0, 2, "invalid receive pattern"); - /* get a fixed number of bytes (minus what was already partially - * received) */ - } else err = recvraw(buf, (size_t) lua_tonumber(L, 2)-size, &b); + /* get a fixed number of bytes (minus what was already partially + * received) */ + } else { + double n = lua_tonumber(L, 2); + size_t wanted = (size_t) n; + luaL_argcheck(L, n >= 0, 2, "invalid receive pattern"); + if (size == 0 || wanted > size) + err = recvraw(buf, wanted-size, &b); + } /* check if there was an error */ if (err != IO_DONE) { /* we can't push anyting in the stack before pushing the * contents of the buffer. this is the reason for the complication */ luaL_pushresult(&b); - lua_pushstring(L, buf->io->error(buf->io->ctx, err)); - lua_pushvalue(L, -2); + lua_pushstring(L, buf->io->error(buf->io->ctx, err)); + lua_pushvalue(L, -2); lua_pushnil(L); lua_replace(L, -4); } else { @@ -141,7 +146,7 @@ int buffer_meth_receive(lua_State *L, p_buffer buf) { } #ifdef LUASOCKET_DEBUG /* push time elapsed during operation as the last return value */ - lua_pushnumber(L, timeout_gettime() - timeout_getstart(tm)); + lua_pushnumber(L, timeout_gettime() - timeout_getstart(buf->tm)); #endif return lua_gettop(L) - top; } @@ -166,7 +171,7 @@ static int sendraw(p_buffer buf, const char *data, size_t count, size_t *sent) { size_t total = 0; int err = IO_DONE; while (total < count && err == IO_DONE) { - size_t done; + size_t done = 0; size_t step = (count-total <= STEPSIZE)? count-total: STEPSIZE; err = io->send(io->ctx, data+total, step, &done, tm); total += done; @@ -214,7 +219,7 @@ static int recvall(p_buffer buf, luaL_Buffer *b) { } /*-------------------------------------------------------------------------*\ -* Reads a line terminated by a CR LF pair or just by a LF. The CR and LF +* Reads a line terminated by a CR LF pair or just by a LF. The CR and LF * are not returned by the function and are discarded from the buffer \*-------------------------------------------------------------------------*/ static int recvline(p_buffer buf, luaL_Buffer *b) { @@ -225,7 +230,7 @@ static int recvline(p_buffer buf, luaL_Buffer *b) { pos = 0; while (pos < count && data[pos] != '\n') { /* we ignore all \r's */ - if (data[pos] != '\r') luaL_putchar(b, data[pos]); + if (data[pos] != '\r') luaL_addchar(b, data[pos]); pos++; } if (pos < count) { /* found '\n' */ @@ -244,7 +249,7 @@ static int recvline(p_buffer buf, luaL_Buffer *b) { static void buffer_skip(p_buffer buf, size_t count) { buf->received += count; buf->first += count; - if (buffer_isempty(buf)) + if (buffer_isempty(buf)) buf->first = buf->last = 0; } diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/buffer.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/buffer.h index baf93caa..1281bb39 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/buffer.h +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/buffer.h @@ -14,8 +14,6 @@ * * The module is built on top of the I/O abstraction defined in io.h and the * timeout management is done with the timeout.h interface. -* -* RCS ID: $Id: buffer.h,v 1.12 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ #include "lua.h" @@ -31,8 +29,8 @@ typedef struct t_buffer_ { size_t sent, received; /* bytes sent, and bytes received */ p_io io; /* IO driver used for this buffer */ p_timeout tm; /* timeout management for this buffer */ - size_t first, last; /* index of first and last bytes of stored data */ - char data[BUF_SIZE]; /* storage space for buffer data */ + size_t first, last; /* index of first and last bytes of stored data */ + char data[BUF_SIZE]; /* storage space for buffer data */ } t_buffer; typedef t_buffer *p_buffer; diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/compat.c b/love/src/jni/love/src/libraries/luasocket/libluasocket/compat.c new file mode 100644 index 00000000..c2d99cb2 --- /dev/null +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/compat.c @@ -0,0 +1,19 @@ +#include "compat.h" + +#if LUA_VERSION_NUM==501 +/* +** Adapted from Lua 5.2 +*/ +void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { + luaL_checkstack(L, nup+1, "too many upvalues"); + for (; l->name != NULL; l++) { /* fill the table with given functions */ + int i; + lua_pushstring(L, l->name); + for (i = 0; i < nup; i++) /* copy upvalues to the top */ + lua_pushvalue(L, -(nup+1)); + lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ + lua_settable(L, -(nup + 3)); + } + lua_pop(L, nup); /* remove upvalues */ +} +#endif diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/compat.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/compat.h new file mode 100644 index 00000000..7bf8010e --- /dev/null +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/compat.h @@ -0,0 +1,11 @@ +#ifndef COMPAT_H +#define COMPAT_H + +#include "lua.h" +#include "lauxlib.h" + +#if LUA_VERSION_NUM==501 +void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup); +#endif + +#endif diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/except.c b/love/src/jni/love/src/libraries/luasocket/libluasocket/except.c index c8dc5915..60b50058 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/except.c +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/except.c @@ -1,17 +1,23 @@ /*=========================================================================*\ * Simple exception support * LuaSocket toolkit -* -* RCS ID: $Id: except.c,v 1.8 2005/09/29 06:11:41 diego Exp $ \*=========================================================================*/ #include #include "lua.h" #include "lauxlib.h" +#include "compat.h" #include "except.h" -extern void luax_register(lua_State *L, const char *name, const luaL_Reg *l); +#if LUA_VERSION_NUM < 502 +#define lua_pcallk(L, na, nr, err, ctx, cont) \ + (((void)ctx),((void)cont),lua_pcall(L, na, nr, err)) +#endif + +#if LUA_VERSION_NUM < 503 +typedef int lua_KContext; +#endif /*=========================================================================*\ * Internal function prototypes. @@ -23,7 +29,7 @@ static int finalize(lua_State *L); static int do_nothing(lua_State *L); /* except functions */ -static luaL_reg func[] = { +static luaL_Reg func[] = { {"newtry", global_newtry}, {"protect", global_protect}, {NULL, NULL} @@ -33,18 +39,17 @@ static luaL_reg func[] = { * Try factory \*-------------------------------------------------------------------------*/ static void wrap(lua_State *L) { - lua_newtable(L); - lua_pushnumber(L, 1); - lua_pushvalue(L, -3); - lua_settable(L, -3); - lua_insert(L, -2); - lua_pop(L, 1); + lua_createtable(L, 1, 0); + lua_pushvalue(L, -2); + lua_rawseti(L, -2, 1); + lua_pushvalue(L, lua_upvalueindex(1)); + lua_setmetatable(L, -2); } static int finalize(lua_State *L) { if (!lua_toboolean(L, 1)) { - lua_pushvalue(L, lua_upvalueindex(1)); - lua_pcall(L, 0, 0, 0); + lua_pushvalue(L, lua_upvalueindex(2)); + lua_call(L, 0, 0); lua_settop(L, 2); wrap(L); lua_error(L); @@ -52,15 +57,17 @@ static int finalize(lua_State *L) { } else return lua_gettop(L); } -static int do_nothing(lua_State *L) { +static int do_nothing(lua_State *L) { (void) L; - return 0; + return 0; } static int global_newtry(lua_State *L) { lua_settop(L, 1); if (lua_isnil(L, 1)) lua_pushcfunction(L, do_nothing); - lua_pushcclosure(L, finalize, 1); + lua_pushvalue(L, lua_upvalueindex(1)); + lua_insert(L, -2); + lua_pushcclosure(L, finalize, 2); return 1; } @@ -68,27 +75,49 @@ static int global_newtry(lua_State *L) { * Protect factory \*-------------------------------------------------------------------------*/ static int unwrap(lua_State *L) { - if (lua_istable(L, -1)) { - lua_pushnumber(L, 1); - lua_gettable(L, -2); - lua_pushnil(L); - lua_insert(L, -2); - return 1; - } else return 0; + if (lua_istable(L, -1) && lua_getmetatable(L, -1)) { + int r = lua_rawequal(L, -1, lua_upvalueindex(1)); + lua_pop(L, 1); + if (r) { + lua_pushnil(L); + lua_rawgeti(L, -2, 1); + return 1; + } + } + return 0; } -static int protected_(lua_State *L) { - lua_pushvalue(L, lua_upvalueindex(1)); - lua_insert(L, 1); - if (lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0) != 0) { +static int protected_finish(lua_State *L, int status, lua_KContext ctx) { + (void)ctx; + if (status != 0 && status != LUA_YIELD) { if (unwrap(L)) return 2; - else lua_error(L); - return 0; + else return lua_error(L); } else return lua_gettop(L); } +#if LUA_VERSION_NUM == 502 +static int protected_cont(lua_State *L) { + int ctx = 0; + int status = lua_getctx(L, &ctx); + return protected_finish(L, status, ctx); +} +#else +#define protected_cont protected_finish +#endif + +static int protected_(lua_State *L) { + int status; + lua_pushvalue(L, lua_upvalueindex(2)); + lua_insert(L, 1); + status = lua_pcallk(L, lua_gettop(L) - 1, LUA_MULTRET, 0, 0, protected_cont); + return protected_finish(L, status, 0); +} + static int global_protect(lua_State *L) { - lua_pushcclosure(L, protected_, 1); + lua_settop(L, 1); + lua_pushvalue(L, lua_upvalueindex(1)); + lua_insert(L, 1); + lua_pushcclosure(L, protected_, 2); return 1; } @@ -96,6 +125,9 @@ static int global_protect(lua_State *L) { * Init module \*-------------------------------------------------------------------------*/ int except_open(lua_State *L) { - luax_register(L, NULL, func); + lua_newtable(L); /* metatable for wrapped exceptions */ + lua_pushboolean(L, 0); + lua_setfield(L, -2, "__metatable"); + luaL_setfuncs(L, func, 1); return 0; } diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/except.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/except.h index 81efb29b..2497c056 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/except.h +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/except.h @@ -9,23 +9,26 @@ * error checking was taking a substantial amount of the coding. These * function greatly simplify the task of checking errors. * -* The main idea is that functions should return nil as its first return -* value when it finds an error, and return an error message (or value) +* The main idea is that functions should return nil as their first return +* values when they find an error, and return an error message (or value) * following nil. In case of success, as long as the first value is not nil, * the other values don't matter. * * The idea is to nest function calls with the "try" function. This function -* checks the first value, and calls "error" on the second if the first is -* nil. Otherwise, it returns all values it received. +* checks the first value, and, if it's falsy, wraps the second value in a +* table with metatable and calls "error" on it. Otherwise, it returns all +* values it received. Basically, it works like the Lua "assert" function, +* but it creates errors targeted specifically at "protect". * -* The protect function returns a new function that behaves exactly like the -* function it receives, but the new function doesn't throw exceptions: it -* returns nil followed by the error message instead. +* The "newtry" function is a factory for "try" functions that call a +* finalizer in protected mode before calling "error". * -* With these two function, it's easy to write functions that throw -* exceptions on error, but that don't interrupt the user script. +* The "protect" function returns a new function that behaves exactly like +* the function it receives, but the new function catches exceptions thrown +* by "try" functions and returns nil followed by the error message instead. * -* RCS ID: $Id: except.h,v 1.2 2005/09/29 06:11:41 diego Exp $ +* With these three functions, it's easy to write functions that throw +* exceptions on error, but that don't interrupt the user script. \*=========================================================================*/ #include "lua.h" diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/ftp.lua b/love/src/jni/love/src/libraries/luasocket/libluasocket/ftp.lua index 598f65dc..bd528caa 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/ftp.lua +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/ftp.lua @@ -2,7 +2,6 @@ -- FTP support for the Lua language -- LuaSocket toolkit. -- Author: Diego Nehab --- RCS ID: $Id: ftp.lua,v 1.45 2007/07/11 19:25:47 diego Exp $ ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- @@ -16,27 +15,27 @@ local socket = require("socket") local url = require("socket.url") local tp = require("socket.tp") local ltn12 = require("ltn12") -module("socket.ftp") - +socket.ftp = {} +local _M = socket.ftp ----------------------------------------------------------------------------- -- Program constants ----------------------------------------------------------------------------- -- timeout in seconds before the program gives up on a connection -TIMEOUT = 60 +_M.TIMEOUT = 60 -- default port for ftp service -PORT = 21 +local PORT = 21 -- this is the default anonymous password. used when no password is -- provided in url. should be changed to your e-mail. -USER = "ftp" -PASSWORD = "anonymous@anonymous.org" +_M.USER = "ftp" +_M.PASSWORD = "anonymous@anonymous.org" ----------------------------------------------------------------------------- -- Low level FTP API ----------------------------------------------------------------------------- local metat = { __index = {} } -function open(server, port, create) - local tp = socket.try(tp.connect(server, port or PORT, TIMEOUT, create)) +function _M.open(server, port, create) + local tp = socket.try(tp.connect(server, port or PORT, _M.TIMEOUT, create)) local f = base.setmetatable({ tp = tp }, metat) -- make sure everything gets closed in an exception f.try = socket.newtry(function() f:close() end) @@ -44,22 +43,22 @@ function open(server, port, create) end function metat.__index:portconnect() - self.try(self.server:settimeout(TIMEOUT)) + self.try(self.server:settimeout(_M.TIMEOUT)) self.data = self.try(self.server:accept()) - self.try(self.data:settimeout(TIMEOUT)) + self.try(self.data:settimeout(_M.TIMEOUT)) end function metat.__index:pasvconnect() self.data = self.try(socket.tcp()) - self.try(self.data:settimeout(TIMEOUT)) - self.try(self.data:connect(self.pasvt.ip, self.pasvt.port)) + self.try(self.data:settimeout(_M.TIMEOUT)) + self.try(self.data:connect(self.pasvt.address, self.pasvt.port)) end function metat.__index:login(user, password) - self.try(self.tp:command("user", user or USER)) + self.try(self.tp:command("user", user or _M.USER)) local code, reply = self.try(self.tp:check{"2..", 331}) if code == 331 then - self.try(self.tp:command("pass", password or PASSWORD)) + self.try(self.tp:command("pass", password or _M.PASSWORD)) self.try(self.tp:check("2..")) end return 1 @@ -72,32 +71,65 @@ function metat.__index:pasv() local a, b, c, d, p1, p2 = socket.skip(2, string.find(reply, pattern)) self.try(a and b and c and d and p1 and p2, reply) self.pasvt = { - ip = string.format("%d.%d.%d.%d", a, b, c, d), + address = string.format("%d.%d.%d.%d", a, b, c, d), port = p1*256 + p2 } if self.server then self.server:close() self.server = nil end - return self.pasvt.ip, self.pasvt.port + return self.pasvt.address, self.pasvt.port end -function metat.__index:port(ip, port) +function metat.__index:epsv() + self.try(self.tp:command("epsv")) + local code, reply = self.try(self.tp:check("229")) + local pattern = "%((.)(.-)%1(.-)%1(.-)%1%)" + local d, prt, address, port = string.match(reply, pattern) + self.try(port, "invalid epsv response") + self.pasvt = { + address = self.tp:getpeername(), + port = port + } + if self.server then + self.server:close() + self.server = nil + end + return self.pasvt.address, self.pasvt.port +end + + +function metat.__index:port(address, port) self.pasvt = nil - if not ip then - ip, port = self.try(self.tp:getcontrol():getsockname()) - self.server = self.try(socket.bind(ip, 0)) - ip, port = self.try(self.server:getsockname()) - self.try(self.server:settimeout(TIMEOUT)) + if not address then + address, port = self.try(self.tp:getsockname()) + self.server = self.try(socket.bind(address, 0)) + address, port = self.try(self.server:getsockname()) + self.try(self.server:settimeout(_M.TIMEOUT)) end local pl = math.mod(port, 256) local ph = (port - pl)/256 - local arg = string.gsub(string.format("%s,%d,%d", ip, ph, pl), "%.", ",") + local arg = string.gsub(string.format("%s,%d,%d", address, ph, pl), "%.", ",") self.try(self.tp:command("port", arg)) self.try(self.tp:check("2..")) return 1 end +function metat.__index:eprt(family, address, port) + self.pasvt = nil + if not address then + address, port = self.try(self.tp:getsockname()) + self.server = self.try(socket.bind(address, 0)) + address, port = self.try(self.server:getsockname()) + self.try(self.server:settimeout(_M.TIMEOUT)) + end + local arg = string.format("|%s|%s|%d|", family, address, port) + self.try(self.tp:command("eprt", arg)) + self.try(self.tp:check("2..")) + return 1 +end + + function metat.__index:send(sendt) self.try(self.pasvt or self.server, "need port or pasv first") -- if there is a pasvt table, we already sent a PASV command @@ -111,12 +143,12 @@ function metat.__index:send(sendt) -- send the transfer command and check the reply self.try(self.tp:command(command, argument)) local code, reply = self.try(self.tp:check{"2..", "1.."}) - -- if there is not a a pasvt table, then there is a server + -- if there is not a pasvt table, then there is a server -- and we already sent a PORT command if not self.pasvt then self:portconnect() end -- get the sink, source and step for the transfer local step = sendt.step or ltn12.pump.step - local readt = {self.tp.c} + local readt = { self.tp } local checkstep = function(src, snk) -- check status in control connection while downloading local readyt = socket.select(readt, nil, 0) @@ -143,7 +175,11 @@ function metat.__index:receive(recvt) if argument == "" then argument = nil end local command = recvt.command or "retr" self.try(self.tp:command(command, argument)) - local code = self.try(self.tp:check{"1..", "2.."}) + local code,reply = self.try(self.tp:check{"1..", "2.."}) + if (code >= 200) and (code <= 299) then + recvt.sink(reply) + return 1 + end if not self.pasvt then self:portconnect() end local source = socket.source("until-closed", self.data) local step = recvt.step or ltn12.pump.step @@ -200,11 +236,11 @@ end local function tput(putt) putt = override(putt) socket.try(putt.host, "missing hostname") - local f = open(putt.host, putt.port, putt.create) + local f = _M.open(putt.host, putt.port, putt.create) f:greet() f:login(putt.user, putt.password) if putt.type then f:type(putt.type) end - f:pasv() + f:epsv() local sent = f:send(putt) f:quit() f:close() @@ -212,11 +248,11 @@ local function tput(putt) end local default = { - path = "/", - scheme = "ftp" + path = "/", + scheme = "ftp" } -local function parse(u) +local function genericform(u) local t = socket.try(url.parse(u, default)) socket.try(t.scheme == "ftp", "wrong scheme '" .. t.scheme .. "'") socket.try(t.host, "missing hostname") @@ -229,13 +265,15 @@ local function parse(u) return t end +_M.genericform = genericform + local function sput(u, body) - local putt = parse(u) + local putt = genericform(u) putt.source = ltn12.source.string(body) return tput(putt) end -put = socket.protect(function(putt, body) +_M.put = socket.protect(function(putt, body) if base.type(putt) == "string" then return sput(putt, body) else return tput(putt) end end) @@ -243,39 +281,49 @@ end) local function tget(gett) gett = override(gett) socket.try(gett.host, "missing hostname") - local f = open(gett.host, gett.port, gett.create) + local f = _M.open(gett.host, gett.port, gett.create) f:greet() f:login(gett.user, gett.password) if gett.type then f:type(gett.type) end - f:pasv() + f:epsv() f:receive(gett) f:quit() return f:close() end local function sget(u) - local gett = parse(u) + local gett = genericform(u) local t = {} gett.sink = ltn12.sink.table(t) tget(gett) return table.concat(t) end -command = socket.protect(function(cmdt) +_M.command = socket.protect(function(cmdt) cmdt = override(cmdt) socket.try(cmdt.host, "missing hostname") socket.try(cmdt.command, "missing command") - local f = open(cmdt.host, cmdt.port, cmdt.create) + local f = _M.open(cmdt.host, cmdt.port, cmdt.create) f:greet() f:login(cmdt.user, cmdt.password) - f.try(f.tp:command(cmdt.command, cmdt.argument)) - if cmdt.check then f.try(f.tp:check(cmdt.check)) end + if type(cmdt.command) == "table" then + local argument = cmdt.argument or {} + local check = cmdt.check or {} + for i,cmd in ipairs(cmdt.command) do + f.try(f.tp:command(cmd, argument[i])) + if check[i] then f.try(f.tp:check(check[i])) end + end + else + f.try(f.tp:command(cmdt.command, cmdt.argument)) + if cmdt.check then f.try(f.tp:check(cmdt.check)) end + end f:quit() return f:close() end) -get = socket.protect(function(gett) +_M.get = socket.protect(function(gett) if base.type(gett) == "string" then return sget(gett) else return tget(gett) end end) +return _M diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/ftp.lua.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/ftp.lua.h index 0f6c8153..fcb0d403 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/ftp.lua.h +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/ftp.lua.h @@ -1,7 +1,7 @@ /* code automatically generated by bin2c -- DO NOT EDIT */ { /* #include'ing this file in a C program is equivalent to calling - if (luaL_loadfile(L,"ftp.lua")==0) lua_call(L, 0, 0); + if (luaL_loadfile(L,"ftp.lua")==0) lua_call(L, 0, LUA_MULTRET); */ /* ftp.lua */ static const unsigned char B1[]={ @@ -13,174 +13,225 @@ static const unsigned char B1[]={ 32, 76,117, 97, 32,108, 97,110,103,117, 97,103,101, 10, 45, 45, 32, 76,117, 97, 83,111, 99,107,101,116, 32,116,111,111,108,107,105,116, 46, 10, 45, 45, 32, 65, 117,116,104,111,114, 58, 32, 68,105,101,103,111, 32, 78,101,104, 97, 98, 10, 45, - 45, 32, 82, 67, 83, 32, 73, 68, 58, 32, 36, 73,100, 58, 32,102,116,112, 46,108, -117, 97, 44,118, 32, 49, 46, 52, 53, 32, 50, 48, 48, 55, 47, 48, 55, 47, 49, 49, - 32, 49, 57, 58, 50, 53, 58, 52, 55, 32,100,105,101,103,111, 32, 69,120,112, 32, - 36, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, - 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, - 45, 32, 68,101, 99,108, 97,114,101, 32,109,111,100,117,108,101, 32, 97,110,100, - 32,105,109,112,111,114,116, 32,100,101,112,101,110,100,101,110, 99,105,101,115, - 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108, -111, 99, 97,108, 32, 98, 97,115,101, 32, 61, 32, 95, 71, 10,108,111, 99, 97,108, - 32,116, 97, 98,108,101, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,116, 97, - 98,108,101, 34, 41, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, 32, 61, - 32,114,101,113,117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10,108, -111, 99, 97,108, 32,109, 97,116,104, 32, 61, 32,114,101,113,117,105,114,101, 40, - 34,109, 97,116,104, 34, 41, 10,108,111, 99, 97,108, 32,115,111, 99,107,101,116, - 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,111, 99,107,101,116, 34, 41, - 10,108,111, 99, 97,108, 32,117,114,108, 32, 61, 32,114,101,113,117,105,114,101, - 40, 34,115,111, 99,107,101,116, 46,117,114,108, 34, 41, 10,108,111, 99, 97,108, - 32,116,112, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,111, 99,107,101, -116, 46,116,112, 34, 41, 10,108,111, 99, 97,108, 32,108,116,110, 49, 50, 32, 61, - 32,114,101,113,117,105,114,101, 40, 34,108,116,110, 49, 50, 34, 41, 10,109,111, -100,117,108,101, 40, 34,115,111, 99,107,101,116, 46,102,116,112, 34, 41, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, - 32, 80,114,111,103,114, 97,109, 32, 99,111,110,115,116, 97,110,116,115, 10, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68, +101, 99,108, 97,114,101, 32,109,111,100,117,108,101, 32, 97,110,100, 32,105,109, +112,111,114,116, 32,100,101,112,101,110,100,101,110, 99,105,101,115, 10, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97, +108, 32, 98, 97,115,101, 32, 61, 32, 95, 71, 10,108,111, 99, 97,108, 32,116, 97, + 98,108,101, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,116, 97, 98,108,101, + 34, 41, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, 32, 61, 32,114,101, +113,117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10,108,111, 99, 97, +108, 32,109, 97,116,104, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,109, 97, +116,104, 34, 41, 10,108,111, 99, 97,108, 32,115,111, 99,107,101,116, 32, 61, 32, +114,101,113,117,105,114,101, 40, 34,115,111, 99,107,101,116, 34, 41, 10,108,111, + 99, 97,108, 32,117,114,108, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115, +111, 99,107,101,116, 46,117,114,108, 34, 41, 10,108,111, 99, 97,108, 32,116,112, + 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,111, 99,107,101,116, 46,116, +112, 34, 41, 10,108,111, 99, 97,108, 32,108,116,110, 49, 50, 32, 61, 32,114,101, +113,117,105,114,101, 40, 34,108,116,110, 49, 50, 34, 41, 10,115,111, 99,107,101, +116, 46,102,116,112, 32, 61, 32,123,125, 10,108,111, 99, 97,108, 32, 95, 77, 32, + 61, 32,115,111, 99,107,101,116, 46,102,116,112, 10, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 80,114,111,103,114, 97, +109, 32, 99,111,110,115,116, 97,110,116,115, 10, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32,116,105,109,101,111,117,116, + 32,105,110, 32,115,101, 99,111,110,100,115, 32, 98,101,102,111,114,101, 32,116, +104,101, 32,112,114,111,103,114, 97,109, 32,103,105,118,101,115, 32,117,112, 32, +111,110, 32, 97, 32, 99,111,110,110,101, 99,116,105,111,110, 10, 95, 77, 46, 84, + 73, 77, 69, 79, 85, 84, 32, 61, 32, 54, 48, 10, 45, 45, 32,100,101,102, 97,117, +108,116, 32,112,111,114,116, 32,102,111,114, 32,102,116,112, 32,115,101,114,118, +105, 99,101, 10,108,111, 99, 97,108, 32, 80, 79, 82, 84, 32, 61, 32, 50, 49, 10, + 45, 45, 32,116,104,105,115, 32,105,115, 32,116,104,101, 32,100,101,102, 97,117, +108,116, 32, 97,110,111,110,121,109,111,117,115, 32,112, 97,115,115,119,111,114, +100, 46, 32,117,115,101,100, 32,119,104,101,110, 32,110,111, 32,112, 97,115,115, +119,111,114,100, 32,105,115, 10, 45, 45, 32,112,114,111,118,105,100,101,100, 32, +105,110, 32,117,114,108, 46, 32,115,104,111,117,108,100, 32, 98,101, 32, 99,104, + 97,110,103,101,100, 32,116,111, 32,121,111,117,114, 32,101, 45,109, 97,105,108, + 46, 10, 95, 77, 46, 85, 83, 69, 82, 32, 61, 32, 34,102,116,112, 34, 10, 95, 77, + 46, 80, 65, 83, 83, 87, 79, 82, 68, 32, 61, 32, 34, 97,110,111,110,121,109,111, +117,115, 64, 97,110,111,110,121,109,111,117,115, 46,111,114,103, 34, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, -116,105,109,101,111,117,116, 32,105,110, 32,115,101, 99,111,110,100,115, 32, 98, -101,102,111,114,101, 32,116,104,101, 32,112,114,111,103,114, 97,109, 32,103,105, -118,101,115, 32,117,112, 32,111,110, 32, 97, 32, 99,111,110,110,101, 99,116,105, -111,110, 10, 84, 73, 77, 69, 79, 85, 84, 32, 61, 32, 54, 48, 10, 45, 45, 32,100, -101,102, 97,117,108,116, 32,112,111,114,116, 32,102,111,114, 32,102,116,112, 32, -115,101,114,118,105, 99,101, 10, 80, 79, 82, 84, 32, 61, 32, 50, 49, 10, 45, 45, - 32,116,104,105,115, 32,105,115, 32,116,104,101, 32,100,101,102, 97,117,108,116, - 32, 97,110,111,110,121,109,111,117,115, 32,112, 97,115,115,119,111,114,100, 46, - 32,117,115,101,100, 32,119,104,101,110, 32,110,111, 32,112, 97,115,115,119,111, -114,100, 32,105,115, 10, 45, 45, 32,112,114,111,118,105,100,101,100, 32,105,110, - 32,117,114,108, 46, 32,115,104,111,117,108,100, 32, 98,101, 32, 99,104, 97,110, -103,101,100, 32,116,111, 32,121,111,117,114, 32,101, 45,109, 97,105,108, 46, 10, - 85, 83, 69, 82, 32, 61, 32, 34,102,116,112, 34, 10, 80, 65, 83, 83, 87, 79, 82, - 68, 32, 61, 32, 34, 97,110,111,110,121,109,111,117,115, 64, 97,110,111,110,121, -109,111,117,115, 46,111,114,103, 34, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 76,111,119, 32,108,101,118,101,108, 32, 70, 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 76,111,119, 32,108,101,118,101, -108, 32, 70, 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,109,101,116, 97,116, 32, - 61, 32,123, 32, 95, 95,105,110,100,101,120, 32, 61, 32,123,125, 32,125, 10, 10, -102,117,110, 99,116,105,111,110, 32,111,112,101,110, 40,115,101,114,118,101,114, - 44, 32,112,111,114,116, 44, 32, 99,114,101, 97,116,101, 41, 10, 32, 32, 32, 32, -108,111, 99, 97,108, 32,116,112, 32, 61, 32,115,111, 99,107,101,116, 46,116,114, -121, 40,116,112, 46, 99,111,110,110,101, 99,116, 40,115,101,114,118,101,114, 44, - 32,112,111,114,116, 32,111,114, 32, 80, 79, 82, 84, 44, 32, 84, 73, 77, 69, 79, - 85, 84, 44, 32, 99,114,101, 97,116,101, 41, 41, 10, 32, 32, 32, 32,108,111, 99, - 97,108, 32,102, 32, 61, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97,116, - 97, 98,108,101, 40,123, 32,116,112, 32, 61, 32,116,112, 32,125, 44, 32,109,101, -116, 97,116, 41, 10, 32, 32, 32, 32, 45, 45, 32,109, 97,107,101, 32,115,117,114, -101, 32,101,118,101,114,121,116,104,105,110,103, 32,103,101,116,115, 32, 99,108, -111,115,101,100, 32,105,110, 32, 97,110, 32,101,120, 99,101,112,116,105,111,110, - 10, 32, 32, 32, 32,102, 46,116,114,121, 32, 61, 32,115,111, 99,107,101,116, 46, -110,101,119,116,114,121, 40,102,117,110, 99,116,105,111,110, 40, 41, 32,102, 58, - 99,108,111,115,101, 40, 41, 32,101,110,100, 41, 10, 32, 32, 32, 32,114,101,116, -117,114,110, 32,102, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32, -109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,112,111,114,116, 99,111, -110,110,101, 99,116, 40, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, - 40,115,101,108,102, 46,115,101,114,118,101,114, 58,115,101,116,116,105,109,101, -111,117,116, 40, 84, 73, 77, 69, 79, 85, 84, 41, 41, 10, 32, 32, 32, 32,115,101, -108,102, 46,100, 97,116, 97, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115, -101,108,102, 46,115,101,114,118,101,114, 58, 97, 99, 99,101,112,116, 40, 41, 41, - 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,100, - 97,116, 97, 58,115,101,116,116,105,109,101,111,117,116, 40, 84, 73, 77, 69, 79, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97, +108, 32,109,101,116, 97,116, 32, 61, 32,123, 32, 95, 95,105,110,100,101,120, 32, + 61, 32,123,125, 32,125, 10, 10,102,117,110, 99,116,105,111,110, 32, 95, 77, 46, +111,112,101,110, 40,115,101,114,118,101,114, 44, 32,112,111,114,116, 44, 32, 99, +114,101, 97,116,101, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,116,112, 32, + 61, 32,115,111, 99,107,101,116, 46,116,114,121, 40,116,112, 46, 99,111,110,110, +101, 99,116, 40,115,101,114,118,101,114, 44, 32,112,111,114,116, 32,111,114, 32, + 80, 79, 82, 84, 44, 32, 95, 77, 46, 84, 73, 77, 69, 79, 85, 84, 44, 32, 99,114, +101, 97,116,101, 41, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,102, 32, 61, + 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97,116, 97, 98,108,101, 40,123, + 32,116,112, 32, 61, 32,116,112, 32,125, 44, 32,109,101,116, 97,116, 41, 10, 32, + 32, 32, 32, 45, 45, 32,109, 97,107,101, 32,115,117,114,101, 32,101,118,101,114, +121,116,104,105,110,103, 32,103,101,116,115, 32, 99,108,111,115,101,100, 32,105, +110, 32, 97,110, 32,101,120, 99,101,112,116,105,111,110, 10, 32, 32, 32, 32,102, + 46,116,114,121, 32, 61, 32,115,111, 99,107,101,116, 46,110,101,119,116,114,121, + 40,102,117,110, 99,116,105,111,110, 40, 41, 32,102, 58, 99,108,111,115,101, 40, + 41, 32,101,110,100, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102, 10, +101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, + 95, 95,105,110,100,101,120, 58,112,111,114,116, 99,111,110,110,101, 99,116, 40, + 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46, +115,101,114,118,101,114, 58,115,101,116,116,105,109,101,111,117,116, 40, 95, 77, + 46, 84, 73, 77, 69, 79, 85, 84, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46, +100, 97,116, 97, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, + 46,115,101,114,118,101,114, 58, 97, 99, 99,101,112,116, 40, 41, 41, 10, 32, 32, + 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,100, 97,116, 97, + 58,115,101,116,116,105,109,101,111,117,116, 40, 95, 77, 46, 84, 73, 77, 69, 79, 85, 84, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109, 101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,112, 97,115,118, 99,111,110, 110,101, 99,116, 40, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,100, 97,116, 97, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115,111, 99,107,101,116, 46,116, 99,112, 40, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115, 101,108,102, 46,100, 97,116, 97, 58,115,101,116,116,105,109,101,111,117,116, 40, - 84, 73, 77, 69, 79, 85, 84, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116, -114,121, 40,115,101,108,102, 46,100, 97,116, 97, 58, 99,111,110,110,101, 99,116, - 40,115,101,108,102, 46,112, 97,115,118,116, 46,105,112, 44, 32,115,101,108,102, - 46,112, 97,115,118,116, 46,112,111,114,116, 41, 41, 10,101,110,100, 10, 10,102, -117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101, -120, 58,108,111,103,105,110, 40,117,115,101,114, 44, 32,112, 97,115,115,119,111, -114,100, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108, -102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34,117,115,101,114, 34, 44, - 32,117,115,101,114, 32,111,114, 32, 85, 83, 69, 82, 41, 41, 10, 32, 32, 32, 32, -108,111, 99, 97,108, 32, 99,111,100,101, 44, 32,114,101,112,108,121, 32, 61, 32, -115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, - 99,107,123, 34, 50, 46, 46, 34, 44, 32, 51, 51, 49,125, 41, 10, 32, 32, 32, 32, -105,102, 32, 99,111,100,101, 32, 61, 61, 32, 51, 51, 49, 32,116,104,101,110, 10, - 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108, -102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34,112, 97,115,115, 34, 44, - 32,112, 97,115,115,119,111,114,100, 32,111,114, 32, 80, 65, 83, 83, 87, 79, 82, - 68, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, - 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, - 41, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114, -110, 32, 49, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101, -116, 97,116, 46, 95, 95,105,110,100,101,120, 58,112, 97,115,118, 40, 41, 10, 32, + 95, 77, 46, 84, 73, 77, 69, 79, 85, 84, 41, 41, 10, 32, 32, 32, 32,115,101,108, +102, 46,116,114,121, 40,115,101,108,102, 46,100, 97,116, 97, 58, 99,111,110,110, +101, 99,116, 40,115,101,108,102, 46,112, 97,115,118,116, 46, 97,100,100,114,101, +115,115, 44, 32,115,101,108,102, 46,112, 97,115,118,116, 46,112,111,114,116, 41, + 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97, +116, 46, 95, 95,105,110,100,101,120, 58,108,111,103,105,110, 40,117,115,101,114, + 44, 32,112, 97,115,115,119,111,114,100, 41, 10, 32, 32, 32, 32,115,101,108,102, + 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, + 40, 34,117,115,101,114, 34, 44, 32,117,115,101,114, 32,111,114, 32, 95, 77, 46, + 85, 83, 69, 82, 41, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,111,100, +101, 44, 32,114,101,112,108,121, 32, 61, 32,115,101,108,102, 46,116,114,121, 40, +115,101,108,102, 46,116,112, 58, 99,104,101, 99,107,123, 34, 50, 46, 46, 34, 44, + 32, 51, 51, 49,125, 41, 10, 32, 32, 32, 32,105,102, 32, 99,111,100,101, 32, 61, + 61, 32, 51, 51, 49, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,115, +101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, + 97,110,100, 40, 34,112, 97,115,115, 34, 44, 32,112, 97,115,115,119,111,114,100, + 32,111,114, 32, 95, 77, 46, 80, 65, 83, 83, 87, 79, 82, 68, 41, 41, 10, 32, 32, + 32, 32, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46, +116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10, 32, 32, 32, + 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101,110, +100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95, +105,110,100,101,120, 58,112, 97,115,118, 40, 41, 10, 32, 32, 32, 32,115,101,108, +102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110, +100, 40, 34,112, 97,115,118, 34, 41, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, + 32, 99,111,100,101, 44, 32,114,101,112,108,121, 32, 61, 32,115,101,108,102, 46, +116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, + 46, 46, 34, 41, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112, 97,116,116, +101,114,110, 32, 61, 32, 34, 40, 37,100, 43, 41, 37, 68, 40, 37,100, 43, 41, 37, + 68, 40, 37,100, 43, 41, 37, 68, 40, 37,100, 43, 41, 37, 68, 40, 37,100, 43, 41, + 37, 68, 40, 37,100, 43, 41, 34, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 97, + 44, 32, 98, 44, 32, 99, 44, 32,100, 44, 32,112, 49, 44, 32,112, 50, 32, 61, 32, +115,111, 99,107,101,116, 46,115,107,105,112, 40, 50, 44, 32,115,116,114,105,110, +103, 46,102,105,110,100, 40,114,101,112,108,121, 44, 32,112, 97,116,116,101,114, +110, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40, 97, 32, 97, +110,100, 32, 98, 32, 97,110,100, 32, 99, 32, 97,110,100, 32,100, 32, 97,110,100, + 32,112, 49, 32, 97,110,100, 32,112, 50, 44, 32,114,101,112,108,121, 41, 10, 32, + 32, 32, 32,115,101,108,102, 46,112, 97,115,118,116, 32, 61, 32,123, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 97,100,100,114,101,115,115, 32, 61, 32,115,116,114,105, +110,103, 46,102,111,114,109, 97,116, 40, 34, 37,100, 46, 37,100, 46, 37,100, 46, + 37,100, 34, 44, 32, 97, 44, 32, 98, 44, 32, 99, 44, 32,100, 41, 44, 10, 32, 32, + 32, 32, 32, 32, 32, 32,112,111,114,116, 32, 61, 32,112, 49, 42, 50, 53, 54, 32, + 43, 32,112, 50, 10, 32, 32, 32, 32,125, 10, 32, 32, 32, 32,105,102, 32,115,101, +108,102, 46,115,101,114,118,101,114, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, + 32, 32, 32,115,101,108,102, 46,115,101,114,118,101,114, 58, 99,108,111,115,101, + 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 46,115,101,114,118, +101,114, 32, 61, 32,110,105,108, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, + 32,114,101,116,117,114,110, 32,115,101,108,102, 46,112, 97,115,118,116, 46, 97, +100,100,114,101,115,115, 44, 32,115,101,108,102, 46,112, 97,115,118,116, 46,112, +111,114,116, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101, +116, 97,116, 46, 95, 95,105,110,100,101,120, 58,101,112,115,118, 40, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, - 99,111,109,109, 97,110,100, 40, 34,112, 97,115,118, 34, 41, 41, 10, 32, 32, 32, + 99,111,109,109, 97,110,100, 40, 34,101,112,115,118, 34, 41, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,111,100,101, 44, 32,114,101,112,108,121, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104, -101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10, 32, 32, 32, 32,108,111, 99, 97, -108, 32,112, 97,116,116,101,114,110, 32, 61, 32, 34, 40, 37,100, 43, 41, 37, 68, - 40, 37,100, 43, 41, 37, 68, 40, 37,100, 43, 41, 37, 68, 40, 37,100, 43, 41, 37, - 68, 40, 37,100, 43, 41, 37, 68, 40, 37,100, 43, 41, 34, 10, 32, 32, 32, 32,108, -111, 99, 97,108, 32, 97, 44, 32, 98, 44, 32, 99, 44, 32,100, 44, 32,112, 49, 44, - 32,112, 50, 32, 61, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 50, 44, - 32,115,116,114,105,110,103, 46,102,105,110,100, 40,114,101,112,108,121, 44, 32, -112, 97,116,116,101,114,110, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116, -114,121, 40, 97, 32, 97,110,100, 32, 98, 32, 97,110,100, 32, 99, 32, 97,110,100, - 32,100, 32, 97,110,100, 32,112, 49, 32, 97,110,100, 32,112, 50, 44, 32,114,101, -112,108,121, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,112, 97,115,118,116, 32, - 61, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,112, 32, 61, 32,115,116,114, -105,110,103, 46,102,111,114,109, 97,116, 40, 34, 37,100, 46, 37,100, 46, 37,100, - 46, 37,100, 34, 44, 32, 97, 44, 32, 98, 44, 32, 99, 44, 32,100, 41, 44, 10, 32, - 32, 32, 32, 32, 32, 32, 32,112,111,114,116, 32, 61, 32,112, 49, 42, 50, 53, 54, - 32, 43, 32,112, 50, 10, 32, 32, 32, 32,125, 10, 32, 32, 32, 32,105,102, 32,115, -101,108,102, 46,115,101,114,118,101,114, 32,116,104,101,110, 10, 32, 32, 32, 32, - 32, 32, 32, 32,115,101,108,102, 46,115,101,114,118,101,114, 58, 99,108,111,115, -101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 46,115,101,114, -118,101,114, 32, 61, 32,110,105,108, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, - 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,112, 97,115,118,116, 46, -105,112, 44, 32,115,101,108,102, 46,112, 97,115,118,116, 46,112,111,114,116, 10, -101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, - 95, 95,105,110,100,101,120, 58,112,111,114,116, 40,105,112, 44, 32,112,111,114, -116, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,112, 97,115,118,116, 32, 61, 32, -110,105,108, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,105,112, 32,116,104, -101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,112, 44, 32,112,111,114,116, 32, - 61, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58,103, -101,116, 99,111,110,116,114,111,108, 40, 41, 58,103,101,116,115,111, 99,107,110, - 97,109,101, 40, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 46, -115,101,114,118,101,114, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115,111, - 99,107,101,116, 46, 98,105,110,100, 40,105,112, 44, 32, 48, 41, 41, 10, 32, 32, - 32, 32, 32, 32, 32, 32,105,112, 44, 32,112,111,114,116, 32, 61, 32,115,101,108, -102, 46,116,114,121, 40,115,101,108,102, 46,115,101,114,118,101,114, 58,103,101, -116,115,111, 99,107,110, 97,109,101, 40, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, - 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,115,101,114,118,101, -114, 58,115,101,116,116,105,109,101,111,117,116, 40, 84, 73, 77, 69, 79, 85, 84, - 41, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, - 32,112,108, 32, 61, 32,109, 97,116,104, 46,109,111,100, 40,112,111,114,116, 44, - 32, 50, 53, 54, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112,104, 32, 61, - 32, 40,112,111,114,116, 32, 45, 32,112,108, 41, 47, 50, 53, 54, 10, 32, 32, 32, - 32,108,111, 99, 97,108, 32, 97,114,103, 32, 61, 32,115,116,114,105,110,103, 46, -103,115,117, 98, 40,115,116,114,105,110,103, 46,102,111,114,109, 97,116, 40, 34, - 37,115, 44, 37,100, 44, 37,100, 34, 44, 32,105,112, 44, 32,112,104, 44, 32,112, -108, 41, 44, 32, 34, 37, 46, 34, 44, 32, 34, 44, 34, 41, 10, 32, 32, 32, 32,115, -101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, - 97,110,100, 40, 34,112,111,114,116, 34, 44, 32, 97,114,103, 41, 41, 10, 32, 32, - 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99, -104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10, 32, 32, 32, 32,114,101,116, -117,114,110, 32, 49, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32, +101, 99,107, 40, 34, 50, 50, 57, 34, 41, 41, 10, 32, 32, 32, 32,108,111, 99, 97, +108, 32,112, 97,116,116,101,114,110, 32, 61, 32, 34, 37, 40, 40, 46, 41, 40, 46, + 45, 41, 37, 49, 40, 46, 45, 41, 37, 49, 40, 46, 45, 41, 37, 49, 37, 41, 34, 10, + 32, 32, 32, 32,108,111, 99, 97,108, 32,100, 44, 32,112,114,116, 44, 32, 97,100, +100,114,101,115,115, 44, 32,112,111,114,116, 32, 61, 32,115,116,114,105,110,103, + 46,109, 97,116, 99,104, 40,114,101,112,108,121, 44, 32,112, 97,116,116,101,114, +110, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,112,111,114,116, + 44, 32, 34,105,110,118, 97,108,105,100, 32,101,112,115,118, 32,114,101,115,112, +111,110,115,101, 34, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,112, 97,115,118, +116, 32, 61, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 97,100,100,114,101,115, +115, 32, 61, 32,115,101,108,102, 46,116,112, 58,103,101,116,112,101,101,114,110, + 97,109,101, 40, 41, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,112,111,114,116, 32, + 61, 32,112,111,114,116, 10, 32, 32, 32, 32,125, 10, 32, 32, 32, 32,105,102, 32, +115,101,108,102, 46,115,101,114,118,101,114, 32,116,104,101,110, 10, 32, 32, 32, + 32, 32, 32, 32, 32,115,101,108,102, 46,115,101,114,118,101,114, 58, 99,108,111, +115,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 46,115,101, +114,118,101,114, 32, 61, 32,110,105,108, 10, 32, 32, 32, 32,101,110,100, 10, 32, + 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,112, 97,115,118,116, + 46, 97,100,100,114,101,115,115, 44, 32,115,101,108,102, 46,112, 97,115,118,116, + 46,112,111,114,116, 10,101,110,100, 10, 10, 10,102,117,110, 99,116,105,111,110, + 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,112,111,114,116, 40, + 97,100,100,114,101,115,115, 44, 32,112,111,114,116, 41, 10, 32, 32, 32, 32,115, +101,108,102, 46,112, 97,115,118,116, 32, 61, 32,110,105,108, 10, 32, 32, 32, 32, +105,102, 32,110,111,116, 32, 97,100,100,114,101,115,115, 32,116,104,101,110, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 97,100,100,114,101,115,115, 44, 32,112,111,114, +116, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, + 58,103,101,116,115,111, 99,107,110, 97,109,101, 40, 41, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32,115,101,108,102, 46,115,101,114,118,101,114, 32, 61, 32,115,101, +108,102, 46,116,114,121, 40,115,111, 99,107,101,116, 46, 98,105,110,100, 40, 97, +100,100,114,101,115,115, 44, 32, 48, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 97,100,100,114,101,115,115, 44, 32,112,111,114,116, 32, 61, 32,115,101,108,102, + 46,116,114,121, 40,115,101,108,102, 46,115,101,114,118,101,114, 58,103,101,116, +115,111, 99,107,110, 97,109,101, 40, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, +115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,115,101,114,118,101,114, + 58,115,101,116,116,105,109,101,111,117,116, 40, 95, 77, 46, 84, 73, 77, 69, 79, + 85, 84, 41, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,112,108, 32, 61, 32,109, 97,116,104, 46,109,111,100, 40,112,111,114, +116, 44, 32, 50, 53, 54, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112,104, + 32, 61, 32, 40,112,111,114,116, 32, 45, 32,112,108, 41, 47, 50, 53, 54, 10, 32, + 32, 32, 32,108,111, 99, 97,108, 32, 97,114,103, 32, 61, 32,115,116,114,105,110, +103, 46,103,115,117, 98, 40,115,116,114,105,110,103, 46,102,111,114,109, 97,116, + 40, 34, 37,115, 44, 37,100, 44, 37,100, 34, 44, 32, 97,100,100,114,101,115,115, + 44, 32,112,104, 44, 32,112,108, 41, 44, 32, 34, 37, 46, 34, 44, 32, 34, 44, 34, + 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46, +116,112, 58, 99,111,109,109, 97,110,100, 40, 34,112,111,114,116, 34, 44, 32, 97, +114,103, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101, +108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10, + 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101,110,100, 10, 10,102,117, +110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, + 58,101,112,114,116, 40,102, 97,109,105,108,121, 44, 32, 97,100,100,114,101,115, +115, 44, 32,112,111,114,116, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,112, 97, +115,118,116, 32, 61, 32,110,105,108, 10, 32, 32, 32, 32,105,102, 32,110,111,116, + 32, 97,100,100,114,101,115,115, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 97,100,100,114,101,115,115, 44, 32,112,111,114,116, 32, 61, 32,115,101, +108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58,103,101,116,115,111, + 99,107,110, 97,109,101, 40, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101, +108,102, 46,115,101,114,118,101,114, 32, 61, 32,115,101,108,102, 46,116,114,121, + 40,115,111, 99,107,101,116, 46, 98,105,110,100, 40, 97,100,100,114,101,115,115, + 44, 32, 48, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 97,100,100,114,101,115, +115, 44, 32,112,111,114,116, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115, +101,108,102, 46,115,101,114,118,101,114, 58,103,101,116,115,111, 99,107,110, 97, +109,101, 40, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 46,116, +114,121, 40,115,101,108,102, 46,115,101,114,118,101,114, 58,115,101,116,116,105, +109,101,111,117,116, 40, 95, 77, 46, 84, 73, 77, 69, 79, 85, 84, 41, 41, 10, 32, + 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 97,114,103, + 32, 61, 32,115,116,114,105,110,103, 46,102,111,114,109, 97,116, 40, 34,124, 37, +115,124, 37,115,124, 37,100,124, 34, 44, 32,102, 97,109,105,108,121, 44, 32, 97, +100,100,114,101,115,115, 44, 32,112,111,114,116, 41, 10, 32, 32, 32, 32,115,101, +108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97, +110,100, 40, 34,101,112,114,116, 34, 44, 32, 97,114,103, 41, 41, 10, 32, 32, 32, + 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104, +101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10, 32, 32, 32, 32,114,101,116,117, +114,110, 32, 49, 10,101,110,100, 10, 10, 10,102,117,110, 99,116,105,111,110, 32, 109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,115,101,110,100, 40,115, 101,110,100,116, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115, 101,108,102, 46,112, 97,115,118,116, 32,111,114, 32,115,101,108,102, 46,115,101, @@ -215,254 +266,279 @@ static const unsigned char B1[]={ 121, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107,123, 34, 50, 46, 46, 34, 44, 32, 34, 49, 46, 46, 34,125, 41, 10, 32, 32, 32, 32, 45, 45, 32,105,102, 32,116,104,101,114,101, 32,105,115, - 32,110,111,116, 32, 97, 32, 97, 32,112, 97,115,118,116, 32,116, 97, 98,108,101, - 44, 32,116,104,101,110, 32,116,104,101,114,101, 32,105,115, 32, 97, 32,115,101, -114,118,101,114, 10, 32, 32, 32, 32, 45, 45, 32, 97,110,100, 32,119,101, 32, 97, -108,114,101, 97,100,121, 32,115,101,110,116, 32, 97, 32, 80, 79, 82, 84, 32, 99, -111,109,109, 97,110,100, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,115,101, -108,102, 46,112, 97,115,118,116, 32,116,104,101,110, 32,115,101,108,102, 58,112, -111,114,116, 99,111,110,110,101, 99,116, 40, 41, 32,101,110,100, 10, 32, 32, 32, - 32, 45, 45, 32,103,101,116, 32,116,104,101, 32,115,105,110,107, 44, 32,115,111, -117,114, 99,101, 32, 97,110,100, 32,115,116,101,112, 32,102,111,114, 32,116,104, -101, 32,116,114, 97,110,115,102,101,114, 10, 32, 32, 32, 32,108,111, 99, 97,108, - 32,115,116,101,112, 32, 61, 32,115,101,110,100,116, 46,115,116,101,112, 32,111, -114, 32,108,116,110, 49, 50, 46,112,117,109,112, 46,115,116,101,112, 10, 32, 32, - 32, 32,108,111, 99, 97,108, 32,114,101, 97,100,116, 32, 61, 32,123,115,101,108, -102, 46,116,112, 46, 99,125, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104, -101, 99,107,115,116,101,112, 32, 61, 32,102,117,110, 99,116,105,111,110, 40,115, -114, 99, 44, 32,115,110,107, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32, - 99,104,101, 99,107, 32,115,116, 97,116,117,115, 32,105,110, 32, 99,111,110,116, -114,111,108, 32, 99,111,110,110,101, 99,116,105,111,110, 32,119,104,105,108,101, - 32,100,111,119,110,108,111, 97,100,105,110,103, 10, 32, 32, 32, 32, 32, 32, 32, - 32,108,111, 99, 97,108, 32,114,101, 97,100,121,116, 32, 61, 32,115,111, 99,107, -101,116, 46,115,101,108,101, 99,116, 40,114,101, 97,100,116, 44, 32,110,105,108, - 44, 32, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,114,101, 97,100, -121,116, 91,116,112, 93, 32,116,104,101,110, 32, 99,111,100,101, 32, 61, 32,115, -101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99, -107, 40, 34, 50, 46, 46, 34, 41, 41, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, - 32, 32,114,101,116,117,114,110, 32,115,116,101,112, 40,115,114, 99, 44, 32,115, -110,107, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97, -108, 32,115,105,110,107, 32, 61, 32,115,111, 99,107,101,116, 46,115,105,110,107, - 40, 34, 99,108,111,115,101, 45,119,104,101,110, 45,100,111,110,101, 34, 44, 32, -115,101,108,102, 46,100, 97,116, 97, 41, 10, 32, 32, 32, 32, 45, 45, 32,116,114, - 97,110,115,102,101,114, 32, 97,108,108, 32,100, 97,116, 97, 32, 97,110,100, 32, - 99,104,101, 99,107, 32,101,114,114,111,114, 10, 32, 32, 32, 32,115,101,108,102, - 46,116,114,121, 40,108,116,110, 49, 50, 46,112,117,109,112, 46, 97,108,108, 40, -115,101,110,100,116, 46,115,111,117,114, 99,101, 44, 32,115,105,110,107, 44, 32, - 99,104,101, 99,107,115,116,101,112, 41, 41, 10, 32, 32, 32, 32,105,102, 32,115, -116,114,105,110,103, 46,102,105,110,100, 40, 99,111,100,101, 44, 32, 34, 49, 46, - 46, 34, 41, 32,116,104,101,110, 32,115,101,108,102, 46,116,114,121, 40,115,101, -108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 32, -101,110,100, 10, 32, 32, 32, 32, 45, 45, 32,100,111,110,101, 32,119,105,116,104, - 32,100, 97,116, 97, 32, 99,111,110,110,101, 99,116,105,111,110, 10, 32, 32, 32, - 32,115,101,108,102, 46,100, 97,116, 97, 58, 99,108,111,115,101, 40, 41, 10, 32, - 32, 32, 32, 45, 45, 32,102,105,110,100, 32,111,117,116, 32,104,111,119, 32,109, - 97,110,121, 32, 98,121,116,101,115, 32,119,101,114,101, 32,115,101,110,116, 10, - 32, 32, 32, 32,108,111, 99, 97,108, 32,115,101,110,116, 32, 61, 32,115,111, 99, -107,101,116, 46,115,107,105,112, 40, 49, 44, 32,115,101,108,102, 46,100, 97,116, - 97, 58,103,101,116,115,116, 97,116,115, 40, 41, 41, 10, 32, 32, 32, 32,115,101, -108,102, 46,100, 97,116, 97, 32, 61, 32,110,105,108, 10, 32, 32, 32, 32,114,101, -116,117,114,110, 32,115,101,110,116, 10,101,110,100, 10, 10,102,117,110, 99,116, -105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,114,101, - 99,101,105,118,101, 40,114,101, 99,118,116, 41, 10, 32, 32, 32, 32,115,101,108, -102, 46,116,114,121, 40,115,101,108,102, 46,112, 97,115,118,116, 32,111,114, 32, -115,101,108,102, 46,115,101,114,118,101,114, 44, 32, 34,110,101,101,100, 32,112, -111,114,116, 32,111,114, 32,112, 97,115,118, 32,102,105,114,115,116, 34, 41, 10, - 32, 32, 32, 32,105,102, 32,115,101,108,102, 46,112, 97,115,118,116, 32,116,104, -101,110, 32,115,101,108,102, 58,112, 97,115,118, 99,111,110,110,101, 99,116, 40, - 41, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 97,114,103,117, -109,101,110,116, 32, 61, 32,114,101, 99,118,116, 46, 97,114,103,117,109,101,110, -116, 32,111,114, 10, 32, 32, 32, 32, 32, 32, 32, 32,117,114,108, 46,117,110,101, -115, 99, 97,112,101, 40,115,116,114,105,110,103, 46,103,115,117, 98, 40,114,101, - 99,118,116, 46,112, 97,116,104, 32,111,114, 32, 34, 34, 44, 32, 34, 94, 91, 47, - 92, 92, 93, 34, 44, 32, 34, 34, 41, 41, 10, 32, 32, 32, 32,105,102, 32, 97,114, -103,117,109,101,110,116, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 32, 97,114, -103,117,109,101,110,116, 32, 61, 32,110,105,108, 32,101,110,100, 10, 32, 32, 32, - 32,108,111, 99, 97,108, 32, 99,111,109,109, 97,110,100, 32, 61, 32,114,101, 99, -118,116, 46, 99,111,109,109, 97,110,100, 32,111,114, 32, 34,114,101,116,114, 34, - 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116, -112, 58, 99,111,109,109, 97,110,100, 40, 99,111,109,109, 97,110,100, 44, 32, 97, -114,103,117,109,101,110,116, 41, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, - 99,111,100,101, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, - 46,116,112, 58, 99,104,101, 99,107,123, 34, 49, 46, 46, 34, 44, 32, 34, 50, 46, - 46, 34,125, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,115,101,108,102, + 32,110,111,116, 32, 97, 32,112, 97,115,118,116, 32,116, 97, 98,108,101, 44, 32, +116,104,101,110, 32,116,104,101,114,101, 32,105,115, 32, 97, 32,115,101,114,118, +101,114, 10, 32, 32, 32, 32, 45, 45, 32, 97,110,100, 32,119,101, 32, 97,108,114, +101, 97,100,121, 32,115,101,110,116, 32, 97, 32, 80, 79, 82, 84, 32, 99,111,109, +109, 97,110,100, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,115,101,108,102, 46,112, 97,115,118,116, 32,116,104,101,110, 32,115,101,108,102, 58,112,111,114, -116, 99,111,110,110,101, 99,116, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,108, -111, 99, 97,108, 32,115,111,117,114, 99,101, 32, 61, 32,115,111, 99,107,101,116, - 46,115,111,117,114, 99,101, 40, 34,117,110,116,105,108, 45, 99,108,111,115,101, -100, 34, 44, 32,115,101,108,102, 46,100, 97,116, 97, 41, 10, 32, 32, 32, 32,108, -111, 99, 97,108, 32,115,116,101,112, 32, 61, 32,114,101, 99,118,116, 46,115,116, -101,112, 32,111,114, 32,108,116,110, 49, 50, 46,112,117,109,112, 46,115,116,101, -112, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,108,116,110, 49, 50, - 46,112,117,109,112, 46, 97,108,108, 40,115,111,117,114, 99,101, 44, 32,114,101, - 99,118,116, 46,115,105,110,107, 44, 32,115,116,101,112, 41, 41, 10, 32, 32, 32, - 32,105,102, 32,115,116,114,105,110,103, 46,102,105,110,100, 40, 99,111,100,101, - 44, 32, 34, 49, 46, 46, 34, 41, 32,116,104,101,110, 32,115,101,108,102, 46,116, -114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, - 46, 34, 41, 41, 32,101,110,100, 10, 32, 32, 32, 32,115,101,108,102, 46,100, 97, -116, 97, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,115,101,108,102, 46, -100, 97,116, 97, 32, 61, 32,110,105,108, 10, 32, 32, 32, 32,114,101,116,117,114, -110, 32, 49, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101, -116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 99,119,100, 40,100,105,114, 41, - 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116, -112, 58, 99,111,109,109, 97,110,100, 40, 34, 99,119,100, 34, 44, 32,100,105,114, - 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, - 46,116,112, 58, 99,104,101, 99,107, 40, 50, 53, 48, 41, 41, 10, 32, 32, 32, 32, -114,101,116,117,114,110, 32, 49, 10,101,110,100, 10, 10,102,117,110, 99,116,105, -111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,116,121,112, -101, 40,116,121,112,101, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, - 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34,116,121, -112,101, 34, 44, 32,116,121,112,101, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, - 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 50, - 48, 48, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101,110, -100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95, -105,110,100,101,120, 58,103,114,101,101,116, 40, 41, 10, 32, 32, 32, 32,108,111, - 99, 97,108, 32, 99,111,100,101, 32, 61, 32,115,101,108,102, 46,116,114,121, 40, +116, 99,111,110,110,101, 99,116, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32, 45, + 45, 32,103,101,116, 32,116,104,101, 32,115,105,110,107, 44, 32,115,111,117,114, + 99,101, 32, 97,110,100, 32,115,116,101,112, 32,102,111,114, 32,116,104,101, 32, +116,114, 97,110,115,102,101,114, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115, +116,101,112, 32, 61, 32,115,101,110,100,116, 46,115,116,101,112, 32,111,114, 32, +108,116,110, 49, 50, 46,112,117,109,112, 46,115,116,101,112, 10, 32, 32, 32, 32, +108,111, 99, 97,108, 32,114,101, 97,100,116, 32, 61, 32,123, 32,115,101,108,102, + 46,116,112, 32,125, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104,101, 99, +107,115,116,101,112, 32, 61, 32,102,117,110, 99,116,105,111,110, 40,115,114, 99, + 44, 32,115,110,107, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32, 99,104, +101, 99,107, 32,115,116, 97,116,117,115, 32,105,110, 32, 99,111,110,116,114,111, +108, 32, 99,111,110,110,101, 99,116,105,111,110, 32,119,104,105,108,101, 32,100, +111,119,110,108,111, 97,100,105,110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32,108, +111, 99, 97,108, 32,114,101, 97,100,121,116, 32, 61, 32,115,111, 99,107,101,116, + 46,115,101,108,101, 99,116, 40,114,101, 97,100,116, 44, 32,110,105,108, 44, 32, + 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,114,101, 97,100,121,116, + 91,116,112, 93, 32,116,104,101,110, 32, 99,111,100,101, 32, 61, 32,115,101,108, +102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, + 34, 50, 46, 46, 34, 41, 41, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, +114,101,116,117,114,110, 32,115,116,101,112, 40,115,114, 99, 44, 32,115,110,107, + 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, +115,105,110,107, 32, 61, 32,115,111, 99,107,101,116, 46,115,105,110,107, 40, 34, + 99,108,111,115,101, 45,119,104,101,110, 45,100,111,110,101, 34, 44, 32,115,101, +108,102, 46,100, 97,116, 97, 41, 10, 32, 32, 32, 32, 45, 45, 32,116,114, 97,110, +115,102,101,114, 32, 97,108,108, 32,100, 97,116, 97, 32, 97,110,100, 32, 99,104, +101, 99,107, 32,101,114,114,111,114, 10, 32, 32, 32, 32,115,101,108,102, 46,116, +114,121, 40,108,116,110, 49, 50, 46,112,117,109,112, 46, 97,108,108, 40,115,101, +110,100,116, 46,115,111,117,114, 99,101, 44, 32,115,105,110,107, 44, 32, 99,104, +101, 99,107,115,116,101,112, 41, 41, 10, 32, 32, 32, 32,105,102, 32,115,116,114, +105,110,103, 46,102,105,110,100, 40, 99,111,100,101, 44, 32, 34, 49, 46, 46, 34, + 41, 32,116,104,101,110, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, + 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 32,101,110, +100, 10, 32, 32, 32, 32, 45, 45, 32,100,111,110,101, 32,119,105,116,104, 32,100, + 97,116, 97, 32, 99,111,110,110,101, 99,116,105,111,110, 10, 32, 32, 32, 32,115, +101,108,102, 46,100, 97,116, 97, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, + 32, 45, 45, 32,102,105,110,100, 32,111,117,116, 32,104,111,119, 32,109, 97,110, +121, 32, 98,121,116,101,115, 32,119,101,114,101, 32,115,101,110,116, 10, 32, 32, + 32, 32,108,111, 99, 97,108, 32,115,101,110,116, 32, 61, 32,115,111, 99,107,101, +116, 46,115,107,105,112, 40, 49, 44, 32,115,101,108,102, 46,100, 97,116, 97, 58, +103,101,116,115,116, 97,116,115, 40, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, + 46,100, 97,116, 97, 32, 61, 32,110,105,108, 10, 32, 32, 32, 32,114,101,116,117, +114,110, 32,115,101,110,116, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111, +110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,114,101, 99,101, +105,118,101, 40,114,101, 99,118,116, 41, 10, 32, 32, 32, 32,115,101,108,102, 46, +116,114,121, 40,115,101,108,102, 46,112, 97,115,118,116, 32,111,114, 32,115,101, +108,102, 46,115,101,114,118,101,114, 44, 32, 34,110,101,101,100, 32,112,111,114, +116, 32,111,114, 32,112, 97,115,118, 32,102,105,114,115,116, 34, 41, 10, 32, 32, + 32, 32,105,102, 32,115,101,108,102, 46,112, 97,115,118,116, 32,116,104,101,110, + 32,115,101,108,102, 58,112, 97,115,118, 99,111,110,110,101, 99,116, 40, 41, 32, +101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 97,114,103,117,109,101, +110,116, 32, 61, 32,114,101, 99,118,116, 46, 97,114,103,117,109,101,110,116, 32, +111,114, 10, 32, 32, 32, 32, 32, 32, 32, 32,117,114,108, 46,117,110,101,115, 99, + 97,112,101, 40,115,116,114,105,110,103, 46,103,115,117, 98, 40,114,101, 99,118, +116, 46,112, 97,116,104, 32,111,114, 32, 34, 34, 44, 32, 34, 94, 91, 47, 92, 92, + 93, 34, 44, 32, 34, 34, 41, 41, 10, 32, 32, 32, 32,105,102, 32, 97,114,103,117, +109,101,110,116, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 32, 97,114,103,117, +109,101,110,116, 32, 61, 32,110,105,108, 32,101,110,100, 10, 32, 32, 32, 32,108, +111, 99, 97,108, 32, 99,111,109,109, 97,110,100, 32, 61, 32,114,101, 99,118,116, + 46, 99,111,109,109, 97,110,100, 32,111,114, 32, 34,114,101,116,114, 34, 10, 32, + 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, + 99,111,109,109, 97,110,100, 40, 99,111,109,109, 97,110,100, 44, 32, 97,114,103, +117,109,101,110,116, 41, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,111, +100,101, 44,114,101,112,108,121, 32, 61, 32,115,101,108,102, 46,116,114,121, 40, 115,101,108,102, 46,116,112, 58, 99,104,101, 99,107,123, 34, 49, 46, 46, 34, 44, - 32, 34, 50, 46, 46, 34,125, 41, 10, 32, 32, 32, 32,105,102, 32,115,116,114,105, -110,103, 46,102,105,110,100, 40, 99,111,100,101, 44, 32, 34, 49, 46, 46, 34, 41, - 32,116,104,101,110, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46, -116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 32,101,110,100, + 32, 34, 50, 46, 46, 34,125, 41, 10, 32, 32, 32, 32,105,102, 32, 40, 99,111,100, +101, 32, 62, 61, 32, 50, 48, 48, 41, 32, 97,110,100, 32, 40, 99,111,100,101, 32, + 60, 61, 32, 50, 57, 57, 41, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, + 32,114,101, 99,118,116, 46,115,105,110,107, 40,114,101,112,108,121, 41, 10, 32, + 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10, 32, 32, 32, 32, +101,110,100, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,115,101,108,102, 46, +112, 97,115,118,116, 32,116,104,101,110, 32,115,101,108,102, 58,112,111,114,116, + 99,111,110,110,101, 99,116, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,108,111, + 99, 97,108, 32,115,111,117,114, 99,101, 32, 61, 32,115,111, 99,107,101,116, 46, +115,111,117,114, 99,101, 40, 34,117,110,116,105,108, 45, 99,108,111,115,101,100, + 34, 44, 32,115,101,108,102, 46,100, 97,116, 97, 41, 10, 32, 32, 32, 32,108,111, + 99, 97,108, 32,115,116,101,112, 32, 61, 32,114,101, 99,118,116, 46,115,116,101, +112, 32,111,114, 32,108,116,110, 49, 50, 46,112,117,109,112, 46,115,116,101,112, + 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,108,116,110, 49, 50, 46, +112,117,109,112, 46, 97,108,108, 40,115,111,117,114, 99,101, 44, 32,114,101, 99, +118,116, 46,115,105,110,107, 44, 32,115,116,101,112, 41, 41, 10, 32, 32, 32, 32, +105,102, 32,115,116,114,105,110,103, 46,102,105,110,100, 40, 99,111,100,101, 44, + 32, 34, 49, 46, 46, 34, 41, 32,116,104,101,110, 32,115,101,108,102, 46,116,114, +121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, + 34, 41, 41, 32,101,110,100, 10, 32, 32, 32, 32,115,101,108,102, 46,100, 97,116, + 97, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,100, + 97,116, 97, 32, 61, 32,110,105,108, 10, 32, 32, 32, 32,114,101,116,117,114,110, + 32, 49, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, + 97,116, 46, 95, 95,105,110,100,101,120, 58, 99,119,100, 40,100,105,114, 41, 10, + 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, + 58, 99,111,109,109, 97,110,100, 40, 34, 99,119,100, 34, 44, 32,100,105,114, 41, + 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46, +116,112, 58, 99,104,101, 99,107, 40, 50, 53, 48, 41, 41, 10, 32, 32, 32, 32,114, +101,116,117,114,110, 32, 49, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111, +110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,116,121,112,101, + 40,116,121,112,101, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40, +115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34,116,121,112, +101, 34, 44, 32,116,121,112,101, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46, +116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 50, 48, + 48, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101,110,100, + 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105, +110,100,101,120, 58,103,114,101,101,116, 40, 41, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32, 99,111,100,101, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115, +101,108,102, 46,116,112, 58, 99,104,101, 99,107,123, 34, 49, 46, 46, 34, 44, 32, + 34, 50, 46, 46, 34,125, 41, 10, 32, 32, 32, 32,105,102, 32,115,116,114,105,110, +103, 46,102,105,110,100, 40, 99,111,100,101, 44, 32, 34, 49, 46, 46, 34, 41, 32, +116,104,101,110, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116, +112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 32,101,110,100, 10, + 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101,110,100, 10, 10,102,117, +110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, + 58,113,117,105,116, 40, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, + 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34,113,117, +105,116, 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115, +101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101,110,100, 10, 10,102, 117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101, -120, 58,113,117,105,116, 40, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114, -121, 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34,113, -117,105,116, 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40, -115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, - 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101,110,100, 10, 10, -102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100, -101,120, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,105,102, 32,115,101, -108,102, 46,100, 97,116, 97, 32,116,104,101,110, 32,115,101,108,102, 46,100, 97, -116, 97, 58, 99,108,111,115,101, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,105, -102, 32,115,101,108,102, 46,115,101,114,118,101,114, 32,116,104,101,110, 32,115, -101,108,102, 46,115,101,114,118,101,114, 58, 99,108,111,115,101, 40, 41, 32,101, -110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,116, -112, 58, 99,108,111,115,101, 40, 41, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, +120, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,105,102, 32,115,101,108, +102, 46,100, 97,116, 97, 32,116,104,101,110, 32,115,101,108,102, 46,100, 97,116, + 97, 58, 99,108,111,115,101, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,105,102, + 32,115,101,108,102, 46,115,101,114,118,101,114, 32,116,104,101,110, 32,115,101, +108,102, 46,115,101,114,118,101,114, 58, 99,108,111,115,101, 40, 41, 32,101,110, +100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,116,112, + 58, 99,108,111,115,101, 40, 41, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 72,105,103,104, - 32,108,101,118,101,108, 32, 70, 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 72,105,103,104, 32, +108,101,118,101,108, 32, 70, 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,102, -117,110, 99,116,105,111,110, 32,111,118,101,114,114,105,100,101, 40,116, 41, 10, - 32, 32, 32, 32,105,102, 32,116, 46,117,114,108, 32,116,104,101,110, 10, 32, 32, - 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,117, 32, 61, 32,117,114,108, 46, -112, 97,114,115,101, 40,116, 46,117,114,108, 41, 10, 32, 32, 32, 32, 32, 32, 32, - 32,102,111,114, 32,105, 44,118, 32,105,110, 32, 98, 97,115,101, 46,112, 97,105, -114,115, 40,116, 41, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32,117, 91,105, 93, 32, 61, 32,118, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110, -100, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,117, 10, 32, - 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,116, 32,101,110,100, - 10,101,110,100, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, - 32,116,112,117,116, 40,112,117,116,116, 41, 10, 32, 32, 32, 32,112,117,116,116, - 32, 61, 32,111,118,101,114,114,105,100,101, 40,112,117,116,116, 41, 10, 32, 32, - 32, 32,115,111, 99,107,101,116, 46,116,114,121, 40,112,117,116,116, 46,104,111, -115,116, 44, 32, 34,109,105,115,115,105,110,103, 32,104,111,115,116,110, 97,109, -101, 34, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,102, 32, 61, 32,111,112, -101,110, 40,112,117,116,116, 46,104,111,115,116, 44, 32,112,117,116,116, 46,112, -111,114,116, 44, 32,112,117,116,116, 46, 99,114,101, 97,116,101, 41, 10, 32, 32, - 32, 32,102, 58,103,114,101,101,116, 40, 41, 10, 32, 32, 32, 32,102, 58,108,111, -103,105,110, 40,112,117,116,116, 46,117,115,101,114, 44, 32,112,117,116,116, 46, -112, 97,115,115,119,111,114,100, 41, 10, 32, 32, 32, 32,105,102, 32,112,117,116, -116, 46,116,121,112,101, 32,116,104,101,110, 32,102, 58,116,121,112,101, 40,112, -117,116,116, 46,116,121,112,101, 41, 32,101,110,100, 10, 32, 32, 32, 32,102, 58, -112, 97,115,118, 40, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,101,110, -116, 32, 61, 32,102, 58,115,101,110,100, 40,112,117,116,116, 41, 10, 32, 32, 32, - 32,102, 58,113,117,105,116, 40, 41, 10, 32, 32, 32, 32,102, 58, 99,108,111,115, -101, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,110,116, 10, -101,110,100, 10, 10,108,111, 99, 97,108, 32,100,101,102, 97,117,108,116, 32, 61, - 32,123, 10, 9,112, 97,116,104, 32, 61, 32, 34, 47, 34, 44, 10, 9,115, 99,104, -101,109,101, 32, 61, 32, 34,102,116,112, 34, 10,125, 10, 10,108,111, 99, 97,108, - 32,102,117,110, 99,116,105,111,110, 32,112, 97,114,115,101, 40,117, 41, 10, 32, - 32, 32, 32,108,111, 99, 97,108, 32,116, 32, 61, 32,115,111, 99,107,101,116, 46, -116,114,121, 40,117,114,108, 46,112, 97,114,115,101, 40,117, 44, 32,100,101,102, - 97,117,108,116, 41, 41, 10, 32, 32, 32, 32,115,111, 99,107,101,116, 46,116,114, -121, 40,116, 46,115, 99,104,101,109,101, 32, 61, 61, 32, 34,102,116,112, 34, 44, - 32, 34,119,114,111,110,103, 32,115, 99,104,101,109,101, 32, 39, 34, 32, 46, 46, - 32,116, 46,115, 99,104,101,109,101, 32, 46, 46, 32, 34, 39, 34, 41, 10, 32, 32, - 32, 32,115,111, 99,107,101,116, 46,116,114,121, 40,116, 46,104,111,115,116, 44, - 32, 34,109,105,115,115,105,110,103, 32,104,111,115,116,110, 97,109,101, 34, 41, - 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112, 97,116, 32, 61, 32, 34, 94,116, -121,112,101, 61, 40, 46, 41, 36, 34, 10, 32, 32, 32, 32,105,102, 32,116, 46,112, - 97,114, 97,109,115, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,116, - 46,116,121,112,101, 32, 61, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, - 50, 44, 32,115,116,114,105,110,103, 46,102,105,110,100, 40,116, 46,112, 97,114, - 97,109,115, 44, 32,112, 97,116, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115, -111, 99,107,101,116, 46,116,114,121, 40,116, 46,116,121,112,101, 32, 61, 61, 32, - 34, 97, 34, 32,111,114, 32,116, 46,116,121,112,101, 32, 61, 61, 32, 34,105, 34, - 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 34,105,110,118, 97,108, -105,100, 32,116,121,112,101, 32, 39, 34, 32, 46, 46, 32,116, 46,116,121,112,101, - 32, 46, 46, 32, 34, 39, 34, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, - 32,114,101,116,117,114,110, 32,116, 10,101,110,100, 10, 10,108,111, 99, 97,108, - 32,102,117,110, 99,116,105,111,110, 32,115,112,117,116, 40,117, 44, 32, 98,111, -100,121, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112,117,116,116, 32, 61, - 32,112, 97,114,115,101, 40,117, 41, 10, 32, 32, 32, 32,112,117,116,116, 46,115, -111,117,114, 99,101, 32, 61, 32,108,116,110, 49, 50, 46,115,111,117,114, 99,101, - 46,115,116,114,105,110,103, 40, 98,111,100,121, 41, 10, 32, 32, 32, 32,114,101, -116,117,114,110, 32,116,112,117,116, 40,112,117,116,116, 41, 10,101,110,100, 10, - 10,112,117,116, 32, 61, 32,115,111, 99,107,101,116, 46,112,114,111,116,101, 99, -116, 40,102,117,110, 99,116,105,111,110, 40,112,117,116,116, 44, 32, 98,111,100, -121, 41, 10, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46,116,121,112,101, 40, -112,117,116,116, 41, 32, 61, 61, 32, 34,115,116,114,105,110,103, 34, 32,116,104, -101,110, 32,114,101,116,117,114,110, 32,115,112,117,116, 40,112,117,116,116, 44, - 32, 98,111,100,121, 41, 10, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117, -114,110, 32,116,112,117,116, 40,112,117,116,116, 41, 32,101,110,100, 10,101,110, -100, 41, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,116, -103,101,116, 40,103,101,116,116, 41, 10, 32, 32, 32, 32,103,101,116,116, 32, 61, - 32,111,118,101,114,114,105,100,101, 40,103,101,116,116, 41, 10, 32, 32, 32, 32, -115,111, 99,107,101,116, 46,116,114,121, 40,103,101,116,116, 46,104,111,115,116, - 44, 32, 34,109,105,115,115,105,110,103, 32,104,111,115,116,110, 97,109,101, 34, - 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,102, 32, 61, 32,111,112,101,110, - 40,103,101,116,116, 46,104,111,115,116, 44, 32,103,101,116,116, 46,112,111,114, -116, 44, 32,103,101,116,116, 46, 99,114,101, 97,116,101, 41, 10, 32, 32, 32, 32, -102, 58,103,114,101,101,116, 40, 41, 10, 32, 32, 32, 32,102, 58,108,111,103,105, -110, 40,103,101,116,116, 46,117,115,101,114, 44, 32,103,101,116,116, 46,112, 97, -115,115,119,111,114,100, 41, 10, 32, 32, 32, 32,105,102, 32,103,101,116,116, 46, -116,121,112,101, 32,116,104,101,110, 32,102, 58,116,121,112,101, 40,103,101,116, -116, 46,116,121,112,101, 41, 32,101,110,100, 10, 32, 32, 32, 32,102, 58,112, 97, -115,118, 40, 41, 10, 32, 32, 32, 32,102, 58,114,101, 99,101,105,118,101, 40,103, -101,116,116, 41, 10, 32, 32, 32, 32,102, 58,113,117,105,116, 40, 41, 10, 32, 32, - 32, 32,114,101,116,117,114,110, 32,102, 58, 99,108,111,115,101, 40, 41, 10,101, -110,100, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,115, -103,101,116, 40,117, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,103,101,116, -116, 32, 61, 32,112, 97,114,115,101, 40,117, 41, 10, 32, 32, 32, 32,108,111, 99, - 97,108, 32,116, 32, 61, 32,123,125, 10, 32, 32, 32, 32,103,101,116,116, 46,115, -105,110,107, 32, 61, 32,108,116,110, 49, 50, 46,115,105,110,107, 46,116, 97, 98, -108,101, 40,116, 41, 10, 32, 32, 32, 32,116,103,101,116, 40,103,101,116,116, 41, - 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,116, 97, 98,108,101, 46, 99,111, -110, 99, 97,116, 40,116, 41, 10,101,110,100, 10, 10, 99,111,109,109, 97,110,100, - 32, 61, 32,115,111, 99,107,101,116, 46,112,114,111,116,101, 99,116, 40,102,117, -110, 99,116,105,111,110, 40, 99,109,100,116, 41, 10, 32, 32, 32, 32, 99,109,100, -116, 32, 61, 32,111,118,101,114,114,105,100,101, 40, 99,109,100,116, 41, 10, 32, - 32, 32, 32,115,111, 99,107,101,116, 46,116,114,121, 40, 99,109,100,116, 46,104, -111,115,116, 44, 32, 34,109,105,115,115,105,110,103, 32,104,111,115,116,110, 97, -109,101, 34, 41, 10, 32, 32, 32, 32,115,111, 99,107,101,116, 46,116,114,121, 40, - 99,109,100,116, 46, 99,111,109,109, 97,110,100, 44, 32, 34,109,105,115,115,105, -110,103, 32, 99,111,109,109, 97,110,100, 34, 41, 10, 32, 32, 32, 32,108,111, 99, - 97,108, 32,102, 32, 61, 32,111,112,101,110, 40, 99,109,100,116, 46,104,111,115, -116, 44, 32, 99,109,100,116, 46,112,111,114,116, 44, 32, 99,109,100,116, 46, 99, -114,101, 97,116,101, 41, 10, 32, 32, 32, 32,102, 58,103,114,101,101,116, 40, 41, - 10, 32, 32, 32, 32,102, 58,108,111,103,105,110, 40, 99,109,100,116, 46,117,115, -101,114, 44, 32, 99,109,100,116, 46,112, 97,115,115,119,111,114,100, 41, 10, 32, - 32, 32, 32,102, 46,116,114,121, 40,102, 46,116,112, 58, 99,111,109,109, 97,110, -100, 40, 99,109,100,116, 46, 99,111,109,109, 97,110,100, 44, 32, 99,109,100,116, - 46, 97,114,103,117,109,101,110,116, 41, 41, 10, 32, 32, 32, 32,105,102, 32, 99, -109,100,116, 46, 99,104,101, 99,107, 32,116,104,101,110, 32,102, 46,116,114,121, - 40,102, 46,116,112, 58, 99,104,101, 99,107, 40, 99,109,100,116, 46, 99,104,101, - 99,107, 41, 41, 32,101,110,100, 10, 32, 32, 32, 32,102, 58,113,117,105,116, 40, - 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102, 58, 99,108,111,115,101, - 40, 41, 10,101,110,100, 41, 10, 10,103,101,116, 32, 61, 32,115,111, 99,107,101, -116, 46,112,114,111,116,101, 99,116, 40,102,117,110, 99,116,105,111,110, 40,103, -101,116,116, 41, 10, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46,116,121,112, -101, 40,103,101,116,116, 41, 32, 61, 61, 32, 34,115,116,114,105,110,103, 34, 32, -116,104,101,110, 32,114,101,116,117,114,110, 32,115,103,101,116, 40,103,101,116, -116, 41, 10, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,116, -103,101,116, 40,103,101,116,116, 41, 32,101,110,100, 10,101,110,100, 41, 10, 10, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,102,117, +110, 99,116,105,111,110, 32,111,118,101,114,114,105,100,101, 40,116, 41, 10, 32, + 32, 32, 32,105,102, 32,116, 46,117,114,108, 32,116,104,101,110, 10, 32, 32, 32, + 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,117, 32, 61, 32,117,114,108, 46,112, + 97,114,115,101, 40,116, 46,117,114,108, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, +102,111,114, 32,105, 44,118, 32,105,110, 32, 98, 97,115,101, 46,112, 97,105,114, +115, 40,116, 41, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +117, 91,105, 93, 32, 61, 32,118, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, + 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,117, 10, 32, 32, + 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,116, 32,101,110,100, 10, +101,110,100, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32, +116,112,117,116, 40,112,117,116,116, 41, 10, 32, 32, 32, 32,112,117,116,116, 32, + 61, 32,111,118,101,114,114,105,100,101, 40,112,117,116,116, 41, 10, 32, 32, 32, + 32,115,111, 99,107,101,116, 46,116,114,121, 40,112,117,116,116, 46,104,111,115, +116, 44, 32, 34,109,105,115,115,105,110,103, 32,104,111,115,116,110, 97,109,101, + 34, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,102, 32, 61, 32, 95, 77, 46, +111,112,101,110, 40,112,117,116,116, 46,104,111,115,116, 44, 32,112,117,116,116, + 46,112,111,114,116, 44, 32,112,117,116,116, 46, 99,114,101, 97,116,101, 41, 10, + 32, 32, 32, 32,102, 58,103,114,101,101,116, 40, 41, 10, 32, 32, 32, 32,102, 58, +108,111,103,105,110, 40,112,117,116,116, 46,117,115,101,114, 44, 32,112,117,116, +116, 46,112, 97,115,115,119,111,114,100, 41, 10, 32, 32, 32, 32,105,102, 32,112, +117,116,116, 46,116,121,112,101, 32,116,104,101,110, 32,102, 58,116,121,112,101, + 40,112,117,116,116, 46,116,121,112,101, 41, 32,101,110,100, 10, 32, 32, 32, 32, +102, 58,101,112,115,118, 40, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115, +101,110,116, 32, 61, 32,102, 58,115,101,110,100, 40,112,117,116,116, 41, 10, 32, + 32, 32, 32,102, 58,113,117,105,116, 40, 41, 10, 32, 32, 32, 32,102, 58, 99,108, +111,115,101, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,110, +116, 10,101,110,100, 10, 10,108,111, 99, 97,108, 32,100,101,102, 97,117,108,116, + 32, 61, 32,123, 10, 32, 32, 32, 32,112, 97,116,104, 32, 61, 32, 34, 47, 34, 44, + 10, 32, 32, 32, 32,115, 99,104,101,109,101, 32, 61, 32, 34,102,116,112, 34, 10, +125, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,103,101, +110,101,114,105, 99,102,111,114,109, 40,117, 41, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,116, 32, 61, 32,115,111, 99,107,101,116, 46,116,114,121, 40,117,114, +108, 46,112, 97,114,115,101, 40,117, 44, 32,100,101,102, 97,117,108,116, 41, 41, + 10, 32, 32, 32, 32,115,111, 99,107,101,116, 46,116,114,121, 40,116, 46,115, 99, +104,101,109,101, 32, 61, 61, 32, 34,102,116,112, 34, 44, 32, 34,119,114,111,110, +103, 32,115, 99,104,101,109,101, 32, 39, 34, 32, 46, 46, 32,116, 46,115, 99,104, +101,109,101, 32, 46, 46, 32, 34, 39, 34, 41, 10, 32, 32, 32, 32,115,111, 99,107, +101,116, 46,116,114,121, 40,116, 46,104,111,115,116, 44, 32, 34,109,105,115,115, +105,110,103, 32,104,111,115,116,110, 97,109,101, 34, 41, 10, 32, 32, 32, 32,108, +111, 99, 97,108, 32,112, 97,116, 32, 61, 32, 34, 94,116,121,112,101, 61, 40, 46, + 41, 36, 34, 10, 32, 32, 32, 32,105,102, 32,116, 46,112, 97,114, 97,109,115, 32, +116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,116, 46,116,121,112,101, 32, + 61, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 50, 44, 32,115,116,114, +105,110,103, 46,102,105,110,100, 40,116, 46,112, 97,114, 97,109,115, 44, 32,112, + 97,116, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,111, 99,107,101,116, 46, +116,114,121, 40,116, 46,116,121,112,101, 32, 61, 61, 32, 34, 97, 34, 32,111,114, + 32,116, 46,116,121,112,101, 32, 61, 61, 32, 34,105, 34, 44, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 34,105,110,118, 97,108,105,100, 32,116,121,112, +101, 32, 39, 34, 32, 46, 46, 32,116, 46,116,121,112,101, 32, 46, 46, 32, 34, 39, + 34, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114, +110, 32,116, 10,101,110,100, 10, 10, 95, 77, 46,103,101,110,101,114,105, 99,102, +111,114,109, 32, 61, 32,103,101,110,101,114,105, 99,102,111,114,109, 10, 10,108, +111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,115,112,117,116, 40,117, + 44, 32, 98,111,100,121, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112,117, +116,116, 32, 61, 32,103,101,110,101,114,105, 99,102,111,114,109, 40,117, 41, 10, + 32, 32, 32, 32,112,117,116,116, 46,115,111,117,114, 99,101, 32, 61, 32,108,116, +110, 49, 50, 46,115,111,117,114, 99,101, 46,115,116,114,105,110,103, 40, 98,111, +100,121, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,116,112,117,116, 40, +112,117,116,116, 41, 10,101,110,100, 10, 10, 95, 77, 46,112,117,116, 32, 61, 32, +115,111, 99,107,101,116, 46,112,114,111,116,101, 99,116, 40,102,117,110, 99,116, +105,111,110, 40,112,117,116,116, 44, 32, 98,111,100,121, 41, 10, 32, 32, 32, 32, +105,102, 32, 98, 97,115,101, 46,116,121,112,101, 40,112,117,116,116, 41, 32, 61, + 61, 32, 34,115,116,114,105,110,103, 34, 32,116,104,101,110, 32,114,101,116,117, +114,110, 32,115,112,117,116, 40,112,117,116,116, 44, 32, 98,111,100,121, 41, 10, + 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,116,112,117,116, + 40,112,117,116,116, 41, 32,101,110,100, 10,101,110,100, 41, 10, 10,108,111, 99, + 97,108, 32,102,117,110, 99,116,105,111,110, 32,116,103,101,116, 40,103,101,116, +116, 41, 10, 32, 32, 32, 32,103,101,116,116, 32, 61, 32,111,118,101,114,114,105, +100,101, 40,103,101,116,116, 41, 10, 32, 32, 32, 32,115,111, 99,107,101,116, 46, +116,114,121, 40,103,101,116,116, 46,104,111,115,116, 44, 32, 34,109,105,115,115, +105,110,103, 32,104,111,115,116,110, 97,109,101, 34, 41, 10, 32, 32, 32, 32,108, +111, 99, 97,108, 32,102, 32, 61, 32, 95, 77, 46,111,112,101,110, 40,103,101,116, +116, 46,104,111,115,116, 44, 32,103,101,116,116, 46,112,111,114,116, 44, 32,103, +101,116,116, 46, 99,114,101, 97,116,101, 41, 10, 32, 32, 32, 32,102, 58,103,114, +101,101,116, 40, 41, 10, 32, 32, 32, 32,102, 58,108,111,103,105,110, 40,103,101, +116,116, 46,117,115,101,114, 44, 32,103,101,116,116, 46,112, 97,115,115,119,111, +114,100, 41, 10, 32, 32, 32, 32,105,102, 32,103,101,116,116, 46,116,121,112,101, + 32,116,104,101,110, 32,102, 58,116,121,112,101, 40,103,101,116,116, 46,116,121, +112,101, 41, 32,101,110,100, 10, 32, 32, 32, 32,102, 58,101,112,115,118, 40, 41, + 10, 32, 32, 32, 32,102, 58,114,101, 99,101,105,118,101, 40,103,101,116,116, 41, + 10, 32, 32, 32, 32,102, 58,113,117,105,116, 40, 41, 10, 32, 32, 32, 32,114,101, +116,117,114,110, 32,102, 58, 99,108,111,115,101, 40, 41, 10,101,110,100, 10, 10, +108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,115,103,101,116, 40, +117, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,103,101,116,116, 32, 61, 32, +103,101,110,101,114,105, 99,102,111,114,109, 40,117, 41, 10, 32, 32, 32, 32,108, +111, 99, 97,108, 32,116, 32, 61, 32,123,125, 10, 32, 32, 32, 32,103,101,116,116, + 46,115,105,110,107, 32, 61, 32,108,116,110, 49, 50, 46,115,105,110,107, 46,116, + 97, 98,108,101, 40,116, 41, 10, 32, 32, 32, 32,116,103,101,116, 40,103,101,116, +116, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,116, 97, 98,108,101, 46, + 99,111,110, 99, 97,116, 40,116, 41, 10,101,110,100, 10, 10, 95, 77, 46, 99,111, +109,109, 97,110,100, 32, 61, 32,115,111, 99,107,101,116, 46,112,114,111,116,101, + 99,116, 40,102,117,110, 99,116,105,111,110, 40, 99,109,100,116, 41, 10, 32, 32, + 32, 32, 99,109,100,116, 32, 61, 32,111,118,101,114,114,105,100,101, 40, 99,109, +100,116, 41, 10, 32, 32, 32, 32,115,111, 99,107,101,116, 46,116,114,121, 40, 99, +109,100,116, 46,104,111,115,116, 44, 32, 34,109,105,115,115,105,110,103, 32,104, +111,115,116,110, 97,109,101, 34, 41, 10, 32, 32, 32, 32,115,111, 99,107,101,116, + 46,116,114,121, 40, 99,109,100,116, 46, 99,111,109,109, 97,110,100, 44, 32, 34, +109,105,115,115,105,110,103, 32, 99,111,109,109, 97,110,100, 34, 41, 10, 32, 32, + 32, 32,108,111, 99, 97,108, 32,102, 32, 61, 32, 95, 77, 46,111,112,101,110, 40, + 99,109,100,116, 46,104,111,115,116, 44, 32, 99,109,100,116, 46,112,111,114,116, + 44, 32, 99,109,100,116, 46, 99,114,101, 97,116,101, 41, 10, 32, 32, 32, 32,102, + 58,103,114,101,101,116, 40, 41, 10, 32, 32, 32, 32,102, 58,108,111,103,105,110, + 40, 99,109,100,116, 46,117,115,101,114, 44, 32, 99,109,100,116, 46,112, 97,115, +115,119,111,114,100, 41, 10, 32, 32, 32, 32,105,102, 32,116,121,112,101, 40, 99, +109,100,116, 46, 99,111,109,109, 97,110,100, 41, 32, 61, 61, 32, 34,116, 97, 98, +108,101, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, + 97,108, 32, 97,114,103,117,109,101,110,116, 32, 61, 32, 99,109,100,116, 46, 97, +114,103,117,109,101,110,116, 32,111,114, 32,123,125, 10, 32, 32, 32, 32, 32, 32, + 32, 32,108,111, 99, 97,108, 32, 99,104,101, 99,107, 32, 61, 32, 99,109,100,116, + 46, 99,104,101, 99,107, 32,111,114, 32,123,125, 10, 32, 32, 32, 32, 32, 32, 32, + 32,102,111,114, 32,105, 44, 99,109,100, 32,105,110, 32,105,112, 97,105,114,115, + 40, 99,109,100,116, 46, 99,111,109,109, 97,110,100, 41, 32,100,111, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,102, 46,116,114,121, 40,102, 46,116,112, + 58, 99,111,109,109, 97,110,100, 40, 99,109,100, 44, 32, 97,114,103,117,109,101, +110,116, 91,105, 93, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +105,102, 32, 99,104,101, 99,107, 91,105, 93, 32,116,104,101,110, 32,102, 46,116, +114,121, 40,102, 46,116,112, 58, 99,104,101, 99,107, 40, 99,104,101, 99,107, 91, +105, 93, 41, 41, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, + 10, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,102, 46, +116,114,121, 40,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 99,109,100, +116, 46, 99,111,109,109, 97,110,100, 44, 32, 99,109,100,116, 46, 97,114,103,117, +109,101,110,116, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,109, +100,116, 46, 99,104,101, 99,107, 32,116,104,101,110, 32,102, 46,116,114,121, 40, +102, 46,116,112, 58, 99,104,101, 99,107, 40, 99,109,100,116, 46, 99,104,101, 99, +107, 41, 41, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, +102, 58,113,117,105,116, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, +102, 58, 99,108,111,115,101, 40, 41, 10,101,110,100, 41, 10, 10, 95, 77, 46,103, +101,116, 32, 61, 32,115,111, 99,107,101,116, 46,112,114,111,116,101, 99,116, 40, +102,117,110, 99,116,105,111,110, 40,103,101,116,116, 41, 10, 32, 32, 32, 32,105, +102, 32, 98, 97,115,101, 46,116,121,112,101, 40,103,101,116,116, 41, 32, 61, 61, + 32, 34,115,116,114,105,110,103, 34, 32,116,104,101,110, 32,114,101,116,117,114, +110, 32,115,103,101,116, 40,103,101,116,116, 41, 10, 32, 32, 32, 32,101,108,115, +101, 32,114,101,116,117,114,110, 32,116,103,101,116, 40,103,101,116,116, 41, 32, +101,110,100, 10,101,110,100, 41, 10, 10,114,101,116,117,114,110, 32, 95, 77, 10, }; - if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"ftp.lua")==0) lua_call(L, 0, 0); + if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"ftp.lua")==0) lua_call(L, 0, LUA_MULTRET); } diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/headers.lua b/love/src/jni/love/src/libraries/luasocket/libluasocket/headers.lua new file mode 100644 index 00000000..1eb8223b --- /dev/null +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/headers.lua @@ -0,0 +1,104 @@ +----------------------------------------------------------------------------- +-- Canonic header field capitalization +-- LuaSocket toolkit. +-- Author: Diego Nehab +----------------------------------------------------------------------------- +local socket = require("socket") +socket.headers = {} +local _M = socket.headers + +_M.canonic = { + ["accept"] = "Accept", + ["accept-charset"] = "Accept-Charset", + ["accept-encoding"] = "Accept-Encoding", + ["accept-language"] = "Accept-Language", + ["accept-ranges"] = "Accept-Ranges", + ["action"] = "Action", + ["alternate-recipient"] = "Alternate-Recipient", + ["age"] = "Age", + ["allow"] = "Allow", + ["arrival-date"] = "Arrival-Date", + ["authorization"] = "Authorization", + ["bcc"] = "Bcc", + ["cache-control"] = "Cache-Control", + ["cc"] = "Cc", + ["comments"] = "Comments", + ["connection"] = "Connection", + ["content-description"] = "Content-Description", + ["content-disposition"] = "Content-Disposition", + ["content-encoding"] = "Content-Encoding", + ["content-id"] = "Content-ID", + ["content-language"] = "Content-Language", + ["content-length"] = "Content-Length", + ["content-location"] = "Content-Location", + ["content-md5"] = "Content-MD5", + ["content-range"] = "Content-Range", + ["content-transfer-encoding"] = "Content-Transfer-Encoding", + ["content-type"] = "Content-Type", + ["cookie"] = "Cookie", + ["date"] = "Date", + ["diagnostic-code"] = "Diagnostic-Code", + ["dsn-gateway"] = "DSN-Gateway", + ["etag"] = "ETag", + ["expect"] = "Expect", + ["expires"] = "Expires", + ["final-log-id"] = "Final-Log-ID", + ["final-recipient"] = "Final-Recipient", + ["from"] = "From", + ["host"] = "Host", + ["if-match"] = "If-Match", + ["if-modified-since"] = "If-Modified-Since", + ["if-none-match"] = "If-None-Match", + ["if-range"] = "If-Range", + ["if-unmodified-since"] = "If-Unmodified-Since", + ["in-reply-to"] = "In-Reply-To", + ["keywords"] = "Keywords", + ["last-attempt-date"] = "Last-Attempt-Date", + ["last-modified"] = "Last-Modified", + ["location"] = "Location", + ["max-forwards"] = "Max-Forwards", + ["message-id"] = "Message-ID", + ["mime-version"] = "MIME-Version", + ["original-envelope-id"] = "Original-Envelope-ID", + ["original-recipient"] = "Original-Recipient", + ["pragma"] = "Pragma", + ["proxy-authenticate"] = "Proxy-Authenticate", + ["proxy-authorization"] = "Proxy-Authorization", + ["range"] = "Range", + ["received"] = "Received", + ["received-from-mta"] = "Received-From-MTA", + ["references"] = "References", + ["referer"] = "Referer", + ["remote-mta"] = "Remote-MTA", + ["reply-to"] = "Reply-To", + ["reporting-mta"] = "Reporting-MTA", + ["resent-bcc"] = "Resent-Bcc", + ["resent-cc"] = "Resent-Cc", + ["resent-date"] = "Resent-Date", + ["resent-from"] = "Resent-From", + ["resent-message-id"] = "Resent-Message-ID", + ["resent-reply-to"] = "Resent-Reply-To", + ["resent-sender"] = "Resent-Sender", + ["resent-to"] = "Resent-To", + ["retry-after"] = "Retry-After", + ["return-path"] = "Return-Path", + ["sender"] = "Sender", + ["server"] = "Server", + ["smtp-remote-recipient"] = "SMTP-Remote-Recipient", + ["status"] = "Status", + ["subject"] = "Subject", + ["te"] = "TE", + ["to"] = "To", + ["trailer"] = "Trailer", + ["transfer-encoding"] = "Transfer-Encoding", + ["upgrade"] = "Upgrade", + ["user-agent"] = "User-Agent", + ["vary"] = "Vary", + ["via"] = "Via", + ["warning"] = "Warning", + ["will-retry-until"] = "Will-Retry-Until", + ["www-authenticate"] = "WWW-Authenticate", + ["x-mailer"] = "X-Mailer", +} + +return _M \ No newline at end of file diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/headers.lua.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/headers.lua.h new file mode 100644 index 00000000..0d8d891a --- /dev/null +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/headers.lua.h @@ -0,0 +1,196 @@ +/* code automatically generated by bin2c -- DO NOT EDIT */ +{ +/* #include'ing this file in a C program is equivalent to calling + if (luaL_loadfile(L,"headers.lua")==0) lua_call(L, 0, LUA_MULTRET); +*/ +/* headers.lua */ +static const unsigned char B1[]={ + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, + 32, 67, 97,110,111,110,105, 99, 32,104,101, 97,100,101,114, 32,102,105,101,108, +100, 32, 99, 97,112,105,116, 97,108,105,122, 97,116,105,111,110, 10, 45, 45, 32, + 76,117, 97, 83,111, 99,107,101,116, 32,116,111,111,108,107,105,116, 46, 10, 45, + 45, 32, 65,117,116,104,111,114, 58, 32, 68,105,101,103,111, 32, 78,101,104, 97, + 98, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, +108,111, 99, 97,108, 32,115,111, 99,107,101,116, 32, 61, 32,114,101,113,117,105, +114,101, 40, 34,115,111, 99,107,101,116, 34, 41, 10,115,111, 99,107,101,116, 46, +104,101, 97,100,101,114,115, 32, 61, 32,123,125, 10,108,111, 99, 97,108, 32, 95, + 77, 32, 61, 32,115,111, 99,107,101,116, 46,104,101, 97,100,101,114,115, 10, 10, + 95, 77, 46, 99, 97,110,111,110,105, 99, 32, 61, 32,123, 10, 32, 32, 32, 32, 91, + 34, 97, 99, 99,101,112,116, 34, 93, 32, 61, 32, 34, 65, 99, 99,101,112,116, 34, + 44, 10, 32, 32, 32, 32, 91, 34, 97, 99, 99,101,112,116, 45, 99,104, 97,114,115, +101,116, 34, 93, 32, 61, 32, 34, 65, 99, 99,101,112,116, 45, 67,104, 97,114,115, +101,116, 34, 44, 10, 32, 32, 32, 32, 91, 34, 97, 99, 99,101,112,116, 45,101,110, + 99,111,100,105,110,103, 34, 93, 32, 61, 32, 34, 65, 99, 99,101,112,116, 45, 69, +110, 99,111,100,105,110,103, 34, 44, 10, 32, 32, 32, 32, 91, 34, 97, 99, 99,101, +112,116, 45,108, 97,110,103,117, 97,103,101, 34, 93, 32, 61, 32, 34, 65, 99, 99, +101,112,116, 45, 76, 97,110,103,117, 97,103,101, 34, 44, 10, 32, 32, 32, 32, 91, + 34, 97, 99, 99,101,112,116, 45,114, 97,110,103,101,115, 34, 93, 32, 61, 32, 34, + 65, 99, 99,101,112,116, 45, 82, 97,110,103,101,115, 34, 44, 10, 32, 32, 32, 32, + 91, 34, 97, 99,116,105,111,110, 34, 93, 32, 61, 32, 34, 65, 99,116,105,111,110, + 34, 44, 10, 32, 32, 32, 32, 91, 34, 97,108,116,101,114,110, 97,116,101, 45,114, +101, 99,105,112,105,101,110,116, 34, 93, 32, 61, 32, 34, 65,108,116,101,114,110, + 97,116,101, 45, 82,101, 99,105,112,105,101,110,116, 34, 44, 10, 32, 32, 32, 32, + 91, 34, 97,103,101, 34, 93, 32, 61, 32, 34, 65,103,101, 34, 44, 10, 32, 32, 32, + 32, 91, 34, 97,108,108,111,119, 34, 93, 32, 61, 32, 34, 65,108,108,111,119, 34, + 44, 10, 32, 32, 32, 32, 91, 34, 97,114,114,105,118, 97,108, 45,100, 97,116,101, + 34, 93, 32, 61, 32, 34, 65,114,114,105,118, 97,108, 45, 68, 97,116,101, 34, 44, + 10, 32, 32, 32, 32, 91, 34, 97,117,116,104,111,114,105,122, 97,116,105,111,110, + 34, 93, 32, 61, 32, 34, 65,117,116,104,111,114,105,122, 97,116,105,111,110, 34, + 44, 10, 32, 32, 32, 32, 91, 34, 98, 99, 99, 34, 93, 32, 61, 32, 34, 66, 99, 99, + 34, 44, 10, 32, 32, 32, 32, 91, 34, 99, 97, 99,104,101, 45, 99,111,110,116,114, +111,108, 34, 93, 32, 61, 32, 34, 67, 97, 99,104,101, 45, 67,111,110,116,114,111, +108, 34, 44, 10, 32, 32, 32, 32, 91, 34, 99, 99, 34, 93, 32, 61, 32, 34, 67, 99, + 34, 44, 10, 32, 32, 32, 32, 91, 34, 99,111,109,109,101,110,116,115, 34, 93, 32, + 61, 32, 34, 67,111,109,109,101,110,116,115, 34, 44, 10, 32, 32, 32, 32, 91, 34, + 99,111,110,110,101, 99,116,105,111,110, 34, 93, 32, 61, 32, 34, 67,111,110,110, +101, 99,116,105,111,110, 34, 44, 10, 32, 32, 32, 32, 91, 34, 99,111,110,116,101, +110,116, 45,100,101,115, 99,114,105,112,116,105,111,110, 34, 93, 32, 61, 32, 34, + 67,111,110,116,101,110,116, 45, 68,101,115, 99,114,105,112,116,105,111,110, 34, + 44, 10, 32, 32, 32, 32, 91, 34, 99,111,110,116,101,110,116, 45,100,105,115,112, +111,115,105,116,105,111,110, 34, 93, 32, 61, 32, 34, 67,111,110,116,101,110,116, + 45, 68,105,115,112,111,115,105,116,105,111,110, 34, 44, 10, 32, 32, 32, 32, 91, + 34, 99,111,110,116,101,110,116, 45,101,110, 99,111,100,105,110,103, 34, 93, 32, + 61, 32, 34, 67,111,110,116,101,110,116, 45, 69,110, 99,111,100,105,110,103, 34, + 44, 10, 32, 32, 32, 32, 91, 34, 99,111,110,116,101,110,116, 45,105,100, 34, 93, + 32, 61, 32, 34, 67,111,110,116,101,110,116, 45, 73, 68, 34, 44, 10, 32, 32, 32, + 32, 91, 34, 99,111,110,116,101,110,116, 45,108, 97,110,103,117, 97,103,101, 34, + 93, 32, 61, 32, 34, 67,111,110,116,101,110,116, 45, 76, 97,110,103,117, 97,103, +101, 34, 44, 10, 32, 32, 32, 32, 91, 34, 99,111,110,116,101,110,116, 45,108,101, +110,103,116,104, 34, 93, 32, 61, 32, 34, 67,111,110,116,101,110,116, 45, 76,101, +110,103,116,104, 34, 44, 10, 32, 32, 32, 32, 91, 34, 99,111,110,116,101,110,116, + 45,108,111, 99, 97,116,105,111,110, 34, 93, 32, 61, 32, 34, 67,111,110,116,101, +110,116, 45, 76,111, 99, 97,116,105,111,110, 34, 44, 10, 32, 32, 32, 32, 91, 34, + 99,111,110,116,101,110,116, 45,109,100, 53, 34, 93, 32, 61, 32, 34, 67,111,110, +116,101,110,116, 45, 77, 68, 53, 34, 44, 10, 32, 32, 32, 32, 91, 34, 99,111,110, +116,101,110,116, 45,114, 97,110,103,101, 34, 93, 32, 61, 32, 34, 67,111,110,116, +101,110,116, 45, 82, 97,110,103,101, 34, 44, 10, 32, 32, 32, 32, 91, 34, 99,111, +110,116,101,110,116, 45,116,114, 97,110,115,102,101,114, 45,101,110, 99,111,100, +105,110,103, 34, 93, 32, 61, 32, 34, 67,111,110,116,101,110,116, 45, 84,114, 97, +110,115,102,101,114, 45, 69,110, 99,111,100,105,110,103, 34, 44, 10, 32, 32, 32, + 32, 91, 34, 99,111,110,116,101,110,116, 45,116,121,112,101, 34, 93, 32, 61, 32, + 34, 67,111,110,116,101,110,116, 45, 84,121,112,101, 34, 44, 10, 32, 32, 32, 32, + 91, 34, 99,111,111,107,105,101, 34, 93, 32, 61, 32, 34, 67,111,111,107,105,101, + 34, 44, 10, 32, 32, 32, 32, 91, 34,100, 97,116,101, 34, 93, 32, 61, 32, 34, 68, + 97,116,101, 34, 44, 10, 32, 32, 32, 32, 91, 34,100,105, 97,103,110,111,115,116, +105, 99, 45, 99,111,100,101, 34, 93, 32, 61, 32, 34, 68,105, 97,103,110,111,115, +116,105, 99, 45, 67,111,100,101, 34, 44, 10, 32, 32, 32, 32, 91, 34,100,115,110, + 45,103, 97,116,101,119, 97,121, 34, 93, 32, 61, 32, 34, 68, 83, 78, 45, 71, 97, +116,101,119, 97,121, 34, 44, 10, 32, 32, 32, 32, 91, 34,101,116, 97,103, 34, 93, + 32, 61, 32, 34, 69, 84, 97,103, 34, 44, 10, 32, 32, 32, 32, 91, 34,101,120,112, +101, 99,116, 34, 93, 32, 61, 32, 34, 69,120,112,101, 99,116, 34, 44, 10, 32, 32, + 32, 32, 91, 34,101,120,112,105,114,101,115, 34, 93, 32, 61, 32, 34, 69,120,112, +105,114,101,115, 34, 44, 10, 32, 32, 32, 32, 91, 34,102,105,110, 97,108, 45,108, +111,103, 45,105,100, 34, 93, 32, 61, 32, 34, 70,105,110, 97,108, 45, 76,111,103, + 45, 73, 68, 34, 44, 10, 32, 32, 32, 32, 91, 34,102,105,110, 97,108, 45,114,101, + 99,105,112,105,101,110,116, 34, 93, 32, 61, 32, 34, 70,105,110, 97,108, 45, 82, +101, 99,105,112,105,101,110,116, 34, 44, 10, 32, 32, 32, 32, 91, 34,102,114,111, +109, 34, 93, 32, 61, 32, 34, 70,114,111,109, 34, 44, 10, 32, 32, 32, 32, 91, 34, +104,111,115,116, 34, 93, 32, 61, 32, 34, 72,111,115,116, 34, 44, 10, 32, 32, 32, + 32, 91, 34,105,102, 45,109, 97,116, 99,104, 34, 93, 32, 61, 32, 34, 73,102, 45, + 77, 97,116, 99,104, 34, 44, 10, 32, 32, 32, 32, 91, 34,105,102, 45,109,111,100, +105,102,105,101,100, 45,115,105,110, 99,101, 34, 93, 32, 61, 32, 34, 73,102, 45, + 77,111,100,105,102,105,101,100, 45, 83,105,110, 99,101, 34, 44, 10, 32, 32, 32, + 32, 91, 34,105,102, 45,110,111,110,101, 45,109, 97,116, 99,104, 34, 93, 32, 61, + 32, 34, 73,102, 45, 78,111,110,101, 45, 77, 97,116, 99,104, 34, 44, 10, 32, 32, + 32, 32, 91, 34,105,102, 45,114, 97,110,103,101, 34, 93, 32, 61, 32, 34, 73,102, + 45, 82, 97,110,103,101, 34, 44, 10, 32, 32, 32, 32, 91, 34,105,102, 45,117,110, +109,111,100,105,102,105,101,100, 45,115,105,110, 99,101, 34, 93, 32, 61, 32, 34, + 73,102, 45, 85,110,109,111,100,105,102,105,101,100, 45, 83,105,110, 99,101, 34, + 44, 10, 32, 32, 32, 32, 91, 34,105,110, 45,114,101,112,108,121, 45,116,111, 34, + 93, 32, 61, 32, 34, 73,110, 45, 82,101,112,108,121, 45, 84,111, 34, 44, 10, 32, + 32, 32, 32, 91, 34,107,101,121,119,111,114,100,115, 34, 93, 32, 61, 32, 34, 75, +101,121,119,111,114,100,115, 34, 44, 10, 32, 32, 32, 32, 91, 34,108, 97,115,116, + 45, 97,116,116,101,109,112,116, 45,100, 97,116,101, 34, 93, 32, 61, 32, 34, 76, + 97,115,116, 45, 65,116,116,101,109,112,116, 45, 68, 97,116,101, 34, 44, 10, 32, + 32, 32, 32, 91, 34,108, 97,115,116, 45,109,111,100,105,102,105,101,100, 34, 93, + 32, 61, 32, 34, 76, 97,115,116, 45, 77,111,100,105,102,105,101,100, 34, 44, 10, + 32, 32, 32, 32, 91, 34,108,111, 99, 97,116,105,111,110, 34, 93, 32, 61, 32, 34, + 76,111, 99, 97,116,105,111,110, 34, 44, 10, 32, 32, 32, 32, 91, 34,109, 97,120, + 45,102,111,114,119, 97,114,100,115, 34, 93, 32, 61, 32, 34, 77, 97,120, 45, 70, +111,114,119, 97,114,100,115, 34, 44, 10, 32, 32, 32, 32, 91, 34,109,101,115,115, + 97,103,101, 45,105,100, 34, 93, 32, 61, 32, 34, 77,101,115,115, 97,103,101, 45, + 73, 68, 34, 44, 10, 32, 32, 32, 32, 91, 34,109,105,109,101, 45,118,101,114,115, +105,111,110, 34, 93, 32, 61, 32, 34, 77, 73, 77, 69, 45, 86,101,114,115,105,111, +110, 34, 44, 10, 32, 32, 32, 32, 91, 34,111,114,105,103,105,110, 97,108, 45,101, +110,118,101,108,111,112,101, 45,105,100, 34, 93, 32, 61, 32, 34, 79,114,105,103, +105,110, 97,108, 45, 69,110,118,101,108,111,112,101, 45, 73, 68, 34, 44, 10, 32, + 32, 32, 32, 91, 34,111,114,105,103,105,110, 97,108, 45,114,101, 99,105,112,105, +101,110,116, 34, 93, 32, 61, 32, 34, 79,114,105,103,105,110, 97,108, 45, 82,101, + 99,105,112,105,101,110,116, 34, 44, 10, 32, 32, 32, 32, 91, 34,112,114, 97,103, +109, 97, 34, 93, 32, 61, 32, 34, 80,114, 97,103,109, 97, 34, 44, 10, 32, 32, 32, + 32, 91, 34,112,114,111,120,121, 45, 97,117,116,104,101,110,116,105, 99, 97,116, +101, 34, 93, 32, 61, 32, 34, 80,114,111,120,121, 45, 65,117,116,104,101,110,116, +105, 99, 97,116,101, 34, 44, 10, 32, 32, 32, 32, 91, 34,112,114,111,120,121, 45, + 97,117,116,104,111,114,105,122, 97,116,105,111,110, 34, 93, 32, 61, 32, 34, 80, +114,111,120,121, 45, 65,117,116,104,111,114,105,122, 97,116,105,111,110, 34, 44, + 10, 32, 32, 32, 32, 91, 34,114, 97,110,103,101, 34, 93, 32, 61, 32, 34, 82, 97, +110,103,101, 34, 44, 10, 32, 32, 32, 32, 91, 34,114,101, 99,101,105,118,101,100, + 34, 93, 32, 61, 32, 34, 82,101, 99,101,105,118,101,100, 34, 44, 10, 32, 32, 32, + 32, 91, 34,114,101, 99,101,105,118,101,100, 45,102,114,111,109, 45,109,116, 97, + 34, 93, 32, 61, 32, 34, 82,101, 99,101,105,118,101,100, 45, 70,114,111,109, 45, + 77, 84, 65, 34, 44, 10, 32, 32, 32, 32, 91, 34,114,101,102,101,114,101,110, 99, +101,115, 34, 93, 32, 61, 32, 34, 82,101,102,101,114,101,110, 99,101,115, 34, 44, + 10, 32, 32, 32, 32, 91, 34,114,101,102,101,114,101,114, 34, 93, 32, 61, 32, 34, + 82,101,102,101,114,101,114, 34, 44, 10, 32, 32, 32, 32, 91, 34,114,101,109,111, +116,101, 45,109,116, 97, 34, 93, 32, 61, 32, 34, 82,101,109,111,116,101, 45, 77, + 84, 65, 34, 44, 10, 32, 32, 32, 32, 91, 34,114,101,112,108,121, 45,116,111, 34, + 93, 32, 61, 32, 34, 82,101,112,108,121, 45, 84,111, 34, 44, 10, 32, 32, 32, 32, + 91, 34,114,101,112,111,114,116,105,110,103, 45,109,116, 97, 34, 93, 32, 61, 32, + 34, 82,101,112,111,114,116,105,110,103, 45, 77, 84, 65, 34, 44, 10, 32, 32, 32, + 32, 91, 34,114,101,115,101,110,116, 45, 98, 99, 99, 34, 93, 32, 61, 32, 34, 82, +101,115,101,110,116, 45, 66, 99, 99, 34, 44, 10, 32, 32, 32, 32, 91, 34,114,101, +115,101,110,116, 45, 99, 99, 34, 93, 32, 61, 32, 34, 82,101,115,101,110,116, 45, + 67, 99, 34, 44, 10, 32, 32, 32, 32, 91, 34,114,101,115,101,110,116, 45,100, 97, +116,101, 34, 93, 32, 61, 32, 34, 82,101,115,101,110,116, 45, 68, 97,116,101, 34, + 44, 10, 32, 32, 32, 32, 91, 34,114,101,115,101,110,116, 45,102,114,111,109, 34, + 93, 32, 61, 32, 34, 82,101,115,101,110,116, 45, 70,114,111,109, 34, 44, 10, 32, + 32, 32, 32, 91, 34,114,101,115,101,110,116, 45,109,101,115,115, 97,103,101, 45, +105,100, 34, 93, 32, 61, 32, 34, 82,101,115,101,110,116, 45, 77,101,115,115, 97, +103,101, 45, 73, 68, 34, 44, 10, 32, 32, 32, 32, 91, 34,114,101,115,101,110,116, + 45,114,101,112,108,121, 45,116,111, 34, 93, 32, 61, 32, 34, 82,101,115,101,110, +116, 45, 82,101,112,108,121, 45, 84,111, 34, 44, 10, 32, 32, 32, 32, 91, 34,114, +101,115,101,110,116, 45,115,101,110,100,101,114, 34, 93, 32, 61, 32, 34, 82,101, +115,101,110,116, 45, 83,101,110,100,101,114, 34, 44, 10, 32, 32, 32, 32, 91, 34, +114,101,115,101,110,116, 45,116,111, 34, 93, 32, 61, 32, 34, 82,101,115,101,110, +116, 45, 84,111, 34, 44, 10, 32, 32, 32, 32, 91, 34,114,101,116,114,121, 45, 97, +102,116,101,114, 34, 93, 32, 61, 32, 34, 82,101,116,114,121, 45, 65,102,116,101, +114, 34, 44, 10, 32, 32, 32, 32, 91, 34,114,101,116,117,114,110, 45,112, 97,116, +104, 34, 93, 32, 61, 32, 34, 82,101,116,117,114,110, 45, 80, 97,116,104, 34, 44, + 10, 32, 32, 32, 32, 91, 34,115,101,110,100,101,114, 34, 93, 32, 61, 32, 34, 83, +101,110,100,101,114, 34, 44, 10, 32, 32, 32, 32, 91, 34,115,101,114,118,101,114, + 34, 93, 32, 61, 32, 34, 83,101,114,118,101,114, 34, 44, 10, 32, 32, 32, 32, 91, + 34,115,109,116,112, 45,114,101,109,111,116,101, 45,114,101, 99,105,112,105,101, +110,116, 34, 93, 32, 61, 32, 34, 83, 77, 84, 80, 45, 82,101,109,111,116,101, 45, + 82,101, 99,105,112,105,101,110,116, 34, 44, 10, 32, 32, 32, 32, 91, 34,115,116, + 97,116,117,115, 34, 93, 32, 61, 32, 34, 83,116, 97,116,117,115, 34, 44, 10, 32, + 32, 32, 32, 91, 34,115,117, 98,106,101, 99,116, 34, 93, 32, 61, 32, 34, 83,117, + 98,106,101, 99,116, 34, 44, 10, 32, 32, 32, 32, 91, 34,116,101, 34, 93, 32, 61, + 32, 34, 84, 69, 34, 44, 10, 32, 32, 32, 32, 91, 34,116,111, 34, 93, 32, 61, 32, + 34, 84,111, 34, 44, 10, 32, 32, 32, 32, 91, 34,116,114, 97,105,108,101,114, 34, + 93, 32, 61, 32, 34, 84,114, 97,105,108,101,114, 34, 44, 10, 32, 32, 32, 32, 91, + 34,116,114, 97,110,115,102,101,114, 45,101,110, 99,111,100,105,110,103, 34, 93, + 32, 61, 32, 34, 84,114, 97,110,115,102,101,114, 45, 69,110, 99,111,100,105,110, +103, 34, 44, 10, 32, 32, 32, 32, 91, 34,117,112,103,114, 97,100,101, 34, 93, 32, + 61, 32, 34, 85,112,103,114, 97,100,101, 34, 44, 10, 32, 32, 32, 32, 91, 34,117, +115,101,114, 45, 97,103,101,110,116, 34, 93, 32, 61, 32, 34, 85,115,101,114, 45, + 65,103,101,110,116, 34, 44, 10, 32, 32, 32, 32, 91, 34,118, 97,114,121, 34, 93, + 32, 61, 32, 34, 86, 97,114,121, 34, 44, 10, 32, 32, 32, 32, 91, 34,118,105, 97, + 34, 93, 32, 61, 32, 34, 86,105, 97, 34, 44, 10, 32, 32, 32, 32, 91, 34,119, 97, +114,110,105,110,103, 34, 93, 32, 61, 32, 34, 87, 97,114,110,105,110,103, 34, 44, + 10, 32, 32, 32, 32, 91, 34,119,105,108,108, 45,114,101,116,114,121, 45,117,110, +116,105,108, 34, 93, 32, 61, 32, 34, 87,105,108,108, 45, 82,101,116,114,121, 45, + 85,110,116,105,108, 34, 44, 10, 32, 32, 32, 32, 91, 34,119,119,119, 45, 97,117, +116,104,101,110,116,105, 99, 97,116,101, 34, 93, 32, 61, 32, 34, 87, 87, 87, 45, + 65,117,116,104,101,110,116,105, 99, 97,116,101, 34, 44, 10, 32, 32, 32, 32, 91, + 34,120, 45,109, 97,105,108,101,114, 34, 93, 32, 61, 32, 34, 88, 45, 77, 97,105, +108,101,114, 34, 44, 10,125, 10, 10,114,101,116,117,114,110, 32, 95, 77, +}; + + if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"headers.lua")==0) lua_call(L, 0, LUA_MULTRET); +} diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/http.lua b/love/src/jni/love/src/libraries/luasocket/libluasocket/http.lua index ad8db1ee..ab5daf61 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/http.lua +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/http.lua @@ -2,7 +2,6 @@ -- HTTP/1.1 client support for the Lua language. -- LuaSocket toolkit. -- Author: Diego Nehab --- RCS ID: $Id: http.lua,v 1.71 2007/10/13 23:55:20 diego Exp $ ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- @@ -13,19 +12,24 @@ local url = require("socket.url") local ltn12 = require("ltn12") local mime = require("mime") local string = require("string") +local headers = require("socket.headers") local base = _G local table = require("table") -module("socket.http") +socket.http = {} +local _M = socket.http ----------------------------------------------------------------------------- -- Program constants ----------------------------------------------------------------------------- -- connection timeout in seconds -TIMEOUT = 60 --- default port for document retrieval -PORT = 80 +_M.TIMEOUT = 60 -- user agent field sent in request -USERAGENT = socket._VERSION +_M.USERAGENT = socket._VERSION + +-- supported schemes +local SCHEMES = { ["http"] = true } +-- default port for document retrieval +local PORT = 80 ----------------------------------------------------------------------------- -- Reads MIME headers from a connection, unfolding where needed @@ -40,7 +44,7 @@ local function receiveheaders(sock, headers) while line ~= "" do -- get field-name and value name, value = socket.skip(2, string.find(line, "^(.-):%s*(.*)")) - if not (name and value) then return nil, "malformed reponse headers" end + if not (name and value) then return nil, "malformed response headers" end name = string.lower(name) -- get next line (value might be folded) line, err = sock:receive() @@ -67,7 +71,7 @@ socket.sourcet["http-chunked"] = function(sock, headers) dirty = function() return sock:dirty() end }, { __call = function() - -- get chunk size, skip extention + -- get chunk size, skip extension local line, err = sock:receive() if err then return nil, err end local size = base.tonumber(string.gsub(line, ";.*", ""), 16) @@ -105,14 +109,14 @@ end ----------------------------------------------------------------------------- local metat = { __index = {} } -function open(host, port, create) +function _M.open(host, port, create) -- create socket with user connect function, or with default local c = socket.try((create or socket.tcp)()) local h = base.setmetatable({ c = c }, metat) -- create finalized try h.try = socket.newtry(function() h:close() end) -- set timeout before connecting - h.try(c:settimeout(TIMEOUT)) + h.try(c:settimeout(_M.TIMEOUT)) h.try(c:connect(host, port or PORT)) -- here everything worked return h @@ -123,10 +127,11 @@ function metat.__index:sendrequestline(method, uri) return self.try(self.c:send(reqline)) end -function metat.__index:sendheaders(headers) +function metat.__index:sendheaders(tosend) + local canonic = headers.canonic local h = "\r\n" - for i, v in base.pairs(headers) do - h = i .. ": " .. v .. "\r\n" .. h + for f, v in base.pairs(tosend) do + h = (canonic[f] or f) .. ": " .. v .. "\r\n" .. h end self.try(self.c:send(h)) return 1 @@ -184,7 +189,7 @@ end local function adjusturi(reqt) local u = reqt -- if there is a proxy, we need the full url. otherwise, just a part. - if not reqt.proxy and not PROXY then + if not reqt.proxy and not _M.PROXY then u = { path = socket.try(reqt.path, "invalid path 'nil'"), params = reqt.params, @@ -196,7 +201,7 @@ local function adjusturi(reqt) end local function adjustproxy(reqt) - local proxy = reqt.proxy or PROXY + local proxy = reqt.proxy or _M.PROXY if proxy then proxy = url.parse(proxy) return proxy.host, proxy.port or 3128 @@ -207,16 +212,27 @@ end local function adjustheaders(reqt) -- default headers + local host = string.gsub(reqt.authority, "^.-@", "") local lower = { - ["user-agent"] = USERAGENT, - ["host"] = reqt.host, + ["user-agent"] = _M.USERAGENT, + ["host"] = host, ["connection"] = "close, TE", ["te"] = "trailers" } -- if we have authentication information, pass it along if reqt.user and reqt.password then - lower["authorization"] = - "Basic " .. (mime.b64(reqt.user .. ":" .. reqt.password)) + lower["authorization"] = + "Basic " .. (mime.b64(reqt.user .. ":" .. + url.unescape(reqt.password))) + end + -- if we have proxy authentication information, pass it along + local proxy = reqt.proxy or _M.PROXY + if proxy then + proxy = url.parse(proxy) + if proxy.user and proxy.password then + lower["proxy-authorization"] = + "Basic " .. (mime.b64(proxy.user .. ":" .. proxy.password)) + end end -- override with user headers for i,v in base.pairs(reqt.headers or lower) do @@ -238,23 +254,28 @@ local function adjustrequest(reqt) local nreqt = reqt.url and url.parse(reqt.url, default) or {} -- explicit components override url for i,v in base.pairs(reqt) do nreqt[i] = v end - if nreqt.port == "" then nreqt.port = 80 end - socket.try(nreqt.host and nreqt.host ~= "", - "invalid host '" .. base.tostring(nreqt.host) .. "'") - -- compute uri if user hasn't overriden + if nreqt.port == "" then nreqt.port = PORT end + if not (nreqt.host and nreqt.host ~= "") then + socket.try(nil, "invalid host '" .. base.tostring(nreqt.host) .. "'") + end + -- compute uri if user hasn't overridden nreqt.uri = reqt.uri or adjusturi(nreqt) - -- ajust host and port if there is a proxy - nreqt.host, nreqt.port = adjustproxy(nreqt) -- adjust headers in request nreqt.headers = adjustheaders(nreqt) + -- ajust host and port if there is a proxy + nreqt.host, nreqt.port = adjustproxy(nreqt) return nreqt end local function shouldredirect(reqt, code, headers) - return headers.location and - string.gsub(headers.location, "%s", "") ~= "" and - (reqt.redirect ~= false) and - (code == 301 or code == 302) and + local location = headers.location + if not location then return false end + location = string.gsub(location, "%s", "") + if location == "" then return false end + local scheme = string.match(location, "^([%w][%w%+%-%.]*)%:") + if scheme and not SCHEMES[scheme] then return false end + return (reqt.redirect ~= false) and + (code == 301 or code == 302 or code == 303 or code == 307) and (not reqt.method or reqt.method == "GET" or reqt.method == "HEAD") and (not reqt.nredirects or reqt.nredirects < 5) end @@ -269,7 +290,7 @@ end -- forward declarations local trequest, tredirect -function tredirect(reqt, location) +--[[local]] function tredirect(reqt, location) local result, code, headers, status = trequest { -- the RFC says the redirect URL has to be absolute, but some -- servers do not respect that @@ -277,27 +298,27 @@ function tredirect(reqt, location) source = reqt.source, sink = reqt.sink, headers = reqt.headers, - proxy = reqt.proxy, + proxy = reqt.proxy, nredirects = (reqt.nredirects or 0) + 1, create = reqt.create - } + } -- pass location header back as a hint we redirected headers = headers or {} headers.location = headers.location or location return result, code, headers, status end -function trequest(reqt) +--[[local]] function trequest(reqt) -- we loop until we get what we want, or -- until we are sure there is no way to get it local nreqt = adjustrequest(reqt) - local h = open(nreqt.host, nreqt.port, nreqt.create) + local h = _M.open(nreqt.host, nreqt.port, nreqt.create) -- send request line and headers h:sendrequestline(nreqt.method, nreqt.uri) h:sendheaders(nreqt.headers) -- if there is a body, send it if nreqt.source then - h:sendbody(nreqt.headers, nreqt.source, nreqt.step) + h:sendbody(nreqt.headers, nreqt.source, nreqt.step) end local code, status = h:receivestatusline() -- if it is an HTTP/0.9 server, simply get the body and we are done @@ -307,13 +328,13 @@ function trequest(reqt) end local headers -- ignore any 100-continue messages - while code == 100 do + while code == 100 do headers = h:receiveheaders() code, status = h:receivestatusline() end headers = h:receiveheaders() -- at this point we should have a honest reply from the server - -- we can't redirect if we already used the source, so we report the error + -- we can't redirect if we already used the source, so we report the error if shouldredirect(nreqt, code, headers) and not nreqt.source then h:close() return tredirect(reqt, headers.location) @@ -326,11 +347,13 @@ function trequest(reqt) return 1, code, headers, status end -local function srequest(u, b) +-- turns an url and a body into a generic request +local function genericform(u, b) local t = {} local reqt = { url = u, - sink = ltn12.sink.table(t) + sink = ltn12.sink.table(t), + target = t } if b then reqt.source = ltn12.source.string(b) @@ -340,11 +363,20 @@ local function srequest(u, b) } reqt.method = "POST" end - local code, headers, status = socket.skip(1, trequest(reqt)) - return table.concat(t), code, headers, status + return reqt end -request = socket.protect(function(reqt, body) +_M.genericform = genericform + +local function srequest(u, b) + local reqt = genericform(u, b) + local _, code, headers, status = trequest(reqt) + return table.concat(reqt.target), code, headers, status +end + +_M.request = socket.protect(function(reqt, body) if base.type(reqt) == "string" then return srequest(reqt, body) else return trequest(reqt) end end) + +return _M diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/http.lua.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/http.lua.h index 556a57bb..840cd85c 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/http.lua.h +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/http.lua.h @@ -1,8 +1,8 @@ /* code automatically generated by bin2c -- DO NOT EDIT */ -/* #include'ing this file in a C program is equivalent to calling - if (luaL_loadfile(L,"http.lua")==0) lua_call(L, 0, 0); -*/ { +/* #include'ing this file in a C program is equivalent to calling + if (luaL_loadfile(L,"http.lua")==0) lua_call(L, 0, LUA_MULTRET); +*/ /* http.lua */ static const unsigned char B1[]={ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, @@ -13,609 +13,660 @@ static const unsigned char B1[]={ 112,111,114,116, 32,102,111,114, 32,116,104,101, 32, 76,117, 97, 32,108, 97,110, 103,117, 97,103,101, 46, 10, 45, 45, 32, 76,117, 97, 83,111, 99,107,101,116, 32, 116,111,111,108,107,105,116, 46, 10, 45, 45, 32, 65,117,116,104,111,114, 58, 32, - 68,105,101,103,111, 32, 78,101,104, 97, 98, 10, 45, 45, 32, 82, 67, 83, 32, 73, - 68, 58, 32, 36, 73,100, 58, 32,104,116,116,112, 46,108,117, 97, 44,118, 32, 49, - 46, 55, 49, 32, 50, 48, 48, 55, 47, 49, 48, 47, 49, 51, 32, 50, 51, 58, 53, 53, - 58, 50, 48, 32,100,105,101,103,111, 32, 69,120,112, 32, 36, 10, 45, 45, 45, 45, + 68,105,101,103,111, 32, 78,101,104, 97, 98, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, - 97,114,101, 32,109,111,100,117,108,101, 32, 97,110,100, 32,105,109,112,111,114, -116, 32,100,101,112,101,110,100,101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97,114,101, 32, +109,111,100,117,108,101, 32, 97,110,100, 32,105,109,112,111,114,116, 32,100,101, +112,101,110,100,101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, - 32,115,111, 99,107,101,116, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115, -111, 99,107,101,116, 34, 41, 10,108,111, 99, 97,108, 32,117,114,108, 32, 61, 32, -114,101,113,117,105,114,101, 40, 34,115,111, 99,107,101,116, 46,117,114,108, 34, - 41, 10,108,111, 99, 97,108, 32,108,116,110, 49, 50, 32, 61, 32,114,101,113,117, -105,114,101, 40, 34,108,116,110, 49, 50, 34, 41, 10,108,111, 99, 97,108, 32,109, -105,109,101, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,109,105,109,101, 34, - 41, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, 32, 61, 32,114,101,113, -117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10,108,111, 99, 97,108, - 32, 98, 97,115,101, 32, 61, 32, 95, 71, 10,108,111, 99, 97,108, 32,116, 97, 98, -108,101, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,116, 97, 98,108,101, 34, - 41, 10,109,111,100,117,108,101, 40, 34,115,111, 99,107,101,116, 46,104,116,116, -112, 34, 41, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,115,111, 99, +107,101,116, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,111, 99,107,101, +116, 34, 41, 10,108,111, 99, 97,108, 32,117,114,108, 32, 61, 32,114,101,113,117, +105,114,101, 40, 34,115,111, 99,107,101,116, 46,117,114,108, 34, 41, 10,108,111, + 99, 97,108, 32,108,116,110, 49, 50, 32, 61, 32,114,101,113,117,105,114,101, 40, + 34,108,116,110, 49, 50, 34, 41, 10,108,111, 99, 97,108, 32,109,105,109,101, 32, + 61, 32,114,101,113,117,105,114,101, 40, 34,109,105,109,101, 34, 41, 10,108,111, + 99, 97,108, 32,115,116,114,105,110,103, 32, 61, 32,114,101,113,117,105,114,101, + 40, 34,115,116,114,105,110,103, 34, 41, 10,108,111, 99, 97,108, 32,104,101, 97, +100,101,114,115, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,111, 99,107, +101,116, 46,104,101, 97,100,101,114,115, 34, 41, 10,108,111, 99, 97,108, 32, 98, + 97,115,101, 32, 61, 32, 95, 71, 10,108,111, 99, 97,108, 32,116, 97, 98,108,101, + 32, 61, 32,114,101,113,117,105,114,101, 40, 34,116, 97, 98,108,101, 34, 41, 10, +115,111, 99,107,101,116, 46,104,116,116,112, 32, 61, 32,123,125, 10,108,111, 99, + 97,108, 32, 95, 77, 32, 61, 32,115,111, 99,107,101,116, 46,104,116,116,112, 10, + 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, + 45, 32, 80,114,111,103,114, 97,109, 32, 99,111,110,115,116, 97,110,116,115, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 10, 45, 45, 32, 80,114,111,103,114, 97,109, 32, 99,111,110,115,116, 97, -110,116,115, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, + 32, 99,111,110,110,101, 99,116,105,111,110, 32,116,105,109,101,111,117,116, 32, +105,110, 32,115,101, 99,111,110,100,115, 10, 95, 77, 46, 84, 73, 77, 69, 79, 85, + 84, 32, 61, 32, 54, 48, 10, 45, 45, 32,117,115,101,114, 32, 97,103,101,110,116, + 32,102,105,101,108,100, 32,115,101,110,116, 32,105,110, 32,114,101,113,117,101, +115,116, 10, 95, 77, 46, 85, 83, 69, 82, 65, 71, 69, 78, 84, 32, 61, 32,115,111, + 99,107,101,116, 46, 95, 86, 69, 82, 83, 73, 79, 78, 10, 10, 45, 45, 32,115,117, +112,112,111,114,116,101,100, 32,115, 99,104,101,109,101,115, 10,108,111, 99, 97, +108, 32, 83, 67, 72, 69, 77, 69, 83, 32, 61, 32,123, 32, 91, 34,104,116,116,112, + 34, 93, 32, 61, 32,116,114,117,101, 32,125, 10, 45, 45, 32,100,101,102, 97,117, +108,116, 32,112,111,114,116, 32,102,111,114, 32,100,111, 99,117,109,101,110,116, + 32,114,101,116,114,105,101,118, 97,108, 10,108,111, 99, 97,108, 32, 80, 79, 82, + 84, 32, 61, 32, 56, 48, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 10, 45, 45, 32, 99,111,110,110,101, 99,116,105,111,110, 32,116,105,109,101, -111,117,116, 32,105,110, 32,115,101, 99,111,110,100,115, 10, 84, 73, 77, 69, 79, - 85, 84, 32, 61, 32, 54, 48, 10, 45, 45, 32,100,101,102, 97,117,108,116, 32,112, -111,114,116, 32,102,111,114, 32,100,111, 99,117,109,101,110,116, 32,114,101,116, -114,105,101,118, 97,108, 10, 80, 79, 82, 84, 32, 61, 32, 56, 48, 10, 45, 45, 32, -117,115,101,114, 32, 97,103,101,110,116, 32,102,105,101,108,100, 32,115,101,110, -116, 32,105,110, 32,114,101,113,117,101,115,116, 10, 85, 83, 69, 82, 65, 71, 69, - 78, 84, 32, 61, 32,115,111, 99,107,101,116, 46, 95, 86, 69, 82, 83, 73, 79, 78, + 45, 45, 45, 45, 45, 10, 45, 45, 32, 82,101, 97,100,115, 32, 77, 73, 77, 69, 32, +104,101, 97,100,101,114,115, 32,102,114,111,109, 32, 97, 32, 99,111,110,110,101, + 99,116,105,111,110, 44, 32,117,110,102,111,108,100,105,110,103, 32,119,104,101, +114,101, 32,110,101,101,100,101,100, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105, +111,110, 32,114,101, 99,101,105,118,101,104,101, 97,100,101,114,115, 40,115,111, + 99,107, 44, 32,104,101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,108,105,110,101, 44, 32,110, 97,109,101, 44, 32,118, 97,108,117,101, + 44, 32,101,114,114, 10, 32, 32, 32, 32,104,101, 97,100,101,114,115, 32, 61, 32, +104,101, 97,100,101,114,115, 32,111,114, 32,123,125, 10, 32, 32, 32, 32, 45, 45, + 32,103,101,116, 32,102,105,114,115,116, 32,108,105,110,101, 10, 32, 32, 32, 32, +108,105,110,101, 44, 32,101,114,114, 32, 61, 32,115,111, 99,107, 58,114,101, 99, +101,105,118,101, 40, 41, 10, 32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104, +101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101, +110,100, 10, 32, 32, 32, 32, 45, 45, 32,104,101, 97,100,101,114,115, 32,103,111, + 32,117,110,116,105,108, 32, 97, 32, 98,108, 97,110,107, 32,108,105,110,101, 32, +105,115, 32,102,111,117,110,100, 10, 32, 32, 32, 32,119,104,105,108,101, 32,108, +105,110,101, 32,126, 61, 32, 34, 34, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 45, 45, 32,103,101,116, 32,102,105,101,108,100, 45,110, 97,109,101, 32, 97, +110,100, 32,118, 97,108,117,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,110, 97,109, +101, 44, 32,118, 97,108,117,101, 32, 61, 32,115,111, 99,107,101,116, 46,115,107, +105,112, 40, 50, 44, 32,115,116,114,105,110,103, 46,102,105,110,100, 40,108,105, +110,101, 44, 32, 34, 94, 40, 46, 45, 41, 58, 37,115, 42, 40, 46, 42, 41, 34, 41, + 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32, 40,110, 97, +109,101, 32, 97,110,100, 32,118, 97,108,117,101, 41, 32,116,104,101,110, 32,114, +101,116,117,114,110, 32,110,105,108, 44, 32, 34,109, 97,108,102,111,114,109,101, +100, 32,114,101,112,111,110,115,101, 32,104,101, 97,100,101,114,115, 34, 32,101, +110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,110, 97,109,101, 32, 61, 32,115,116, +114,105,110,103, 46,108,111,119,101,114, 40,110, 97,109,101, 41, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 45, 45, 32,103,101,116, 32,110,101,120,116, 32,108,105,110, +101, 32, 40,118, 97,108,117,101, 32,109,105,103,104,116, 32, 98,101, 32,102,111, +108,100,101,100, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,105,110,101, 44, 32, +101,114,114, 32, 32, 61, 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40, + 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104,101, +110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110, +100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,117,110,102,111,108,100, 32, + 97,110,121, 32,102,111,108,100,101,100, 32,118, 97,108,117,101,115, 10, 32, 32, + 32, 32, 32, 32, 32, 32,119,104,105,108,101, 32,115,116,114,105,110,103, 46,102, +105,110,100, 40,108,105,110,101, 44, 32, 34, 94, 37,115, 34, 41, 32,100,111, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,118, 97,108,117,101, 32, 61, 32, +118, 97,108,117,101, 32, 46, 46, 32,108,105,110,101, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,108,105,110,101, 32, 61, 32,115,111, 99,107, 58,114,101, + 99,101,105,118,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +105,102, 32,101,114,114, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110, +105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, +101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,115, 97,118,101, 32, +112, 97,105,114, 32,105,110, 32,116, 97, 98,108,101, 10, 32, 32, 32, 32, 32, 32, + 32, 32,105,102, 32,104,101, 97,100,101,114,115, 91,110, 97,109,101, 93, 32,116, +104,101,110, 32,104,101, 97,100,101,114,115, 91,110, 97,109,101, 93, 32, 61, 32, +104,101, 97,100,101,114,115, 91,110, 97,109,101, 93, 32, 46, 46, 32, 34, 44, 32, + 34, 32, 46, 46, 32,118, 97,108,117,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,101, +108,115,101, 32,104,101, 97,100,101,114,115, 91,110, 97,109,101, 93, 32, 61, 32, +118, 97,108,117,101, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, + 32, 32,114,101,116,117,114,110, 32,104,101, 97,100,101,114,115, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, - 45, 45, 32, 82,101, 97,100,115, 32, 77, 73, 77, 69, 32,104,101, 97,100,101,114, -115, 32,102,114,111,109, 32, 97, 32, 99,111,110,110,101, 99,116,105,111,110, 44, - 32,117,110,102,111,108,100,105,110,103, 32,119,104,101,114,101, 32,110,101,101, -100,101,100, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 32, 69,120,116,114, 97, 32,115,111,117,114, 99,101,115, 32, 97,110,100, + 32,115,105,110,107,115, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,114,101, 99, -101,105,118,101,104,101, 97,100,101,114,115, 40,115,111, 99,107, 44, 32,104,101, - 97,100,101,114,115, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,108,105,110, -101, 44, 32,110, 97,109,101, 44, 32,118, 97,108,117,101, 44, 32,101,114,114, 10, - 32, 32, 32, 32,104,101, 97,100,101,114,115, 32, 61, 32,104,101, 97,100,101,114, -115, 32,111,114, 32,123,125, 10, 32, 32, 32, 32, 45, 45, 32,103,101,116, 32,102, -105,114,115,116, 32,108,105,110,101, 10, 32, 32, 32, 32,108,105,110,101, 44, 32, -101,114,114, 32, 61, 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40, 41, - 10, 32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104,101,110, 32,114,101,116, + 45, 45, 45, 45, 10,115,111, 99,107,101,116, 46,115,111,117,114, 99,101,116, 91, + 34,104,116,116,112, 45, 99,104,117,110,107,101,100, 34, 93, 32, 61, 32,102,117, +110, 99,116,105,111,110, 40,115,111, 99,107, 44, 32,104,101, 97,100,101,114,115, + 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101, +116,109,101,116, 97,116, 97, 98,108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, + 32,103,101,116,102,100, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32, +114,101,116,117,114,110, 32,115,111, 99,107, 58,103,101,116,102,100, 40, 41, 32, +101,110,100, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, + 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115, +111, 99,107, 58,100,105,114,116,121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32, +125, 44, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, + 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 45, 45, 32,103,101,116, 32, 99,104,117,110,107, 32,115,105, +122,101, 44, 32,115,107,105,112, 32,101,120,116,101,110,116,105,111,110, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,108,105,110, +101, 44, 32,101,114,114, 32, 61, 32,115,111, 99,107, 58,114,101, 99,101,105,118, +101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101, +114,114, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32, +101,114,114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +108,111, 99, 97,108, 32,115,105,122,101, 32, 61, 32, 98, 97,115,101, 46,116,111, +110,117,109, 98,101,114, 40,115,116,114,105,110,103, 46,103,115,117, 98, 40,108, +105,110,101, 44, 32, 34, 59, 46, 42, 34, 44, 32, 34, 34, 41, 44, 32, 49, 54, 41, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32, +115,105,122,101, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, + 44, 32, 34,105,110,118, 97,108,105,100, 32, 99,104,117,110,107, 32,115,105,122, +101, 34, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, + 45, 32,119, 97,115, 32,105,116, 32,116,104,101, 32,108, 97,115,116, 32, 99,104, +117,110,107, 63, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, +115,105,122,101, 32, 62, 32, 48, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,105,102, 32,110,111,116, 44, + 32,103,101,116, 32, 99,104,117,110,107, 32, 97,110,100, 32,115,107,105,112, 32, +116,101,114,109,105,110, 97,116,105,110,103, 32, 67, 82, 76, 70, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99, +104,117,110,107, 44, 32,101,114,114, 44, 32,112, 97,114,116, 32, 61, 32,115,111, + 99,107, 58,114,101, 99,101,105,118,101, 40,115,105,122,101, 41, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104,117,110, +107, 32,116,104,101,110, 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40, + 41, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,114,101,116,117,114,110, 32, 99,104,117,110,107, 44, 32,101,114,114, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,105,102, 32,105, +116, 32,119, 97,115, 44, 32,114,101, 97,100, 32,116,114, 97,105,108,101,114,115, + 32,105,110,116,111, 32,104,101, 97,100,101,114,115, 32,116, 97, 98,108,101, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,104,101, 97,100, +101,114,115, 44, 32,101,114,114, 32, 61, 32,114,101, 99,101,105,118,101,104,101, + 97,100,101,114,115, 40,115,111, 99,107, 44, 32,104,101, 97,100,101,114,115, 41, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, +110,111,116, 32,104,101, 97,100,101,114,115, 32,116,104,101,110, 32,114,101,116, 117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, - 32, 45, 45, 32,104,101, 97,100,101,114,115, 32,103,111, 32,117,110,116,105,108, - 32, 97, 32, 98,108, 97,110,107, 32,108,105,110,101, 32,105,115, 32,102,111,117, -110,100, 10, 32, 32, 32, 32,119,104,105,108,101, 32,108,105,110,101, 32,126, 61, - 32, 34, 34, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,103,101, -116, 32,102,105,101,108,100, 45,110, 97,109,101, 32, 97,110,100, 32,118, 97,108, -117,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,110, 97,109,101, 44, 32,118, 97,108, -117,101, 32, 61, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 50, 44, 32, -115,116,114,105,110,103, 46,102,105,110,100, 40,108,105,110,101, 44, 32, 34, 94, - 40, 46, 45, 41, 58, 37,115, 42, 40, 46, 42, 41, 34, 41, 41, 10, 32, 32, 32, 32, - 32, 32, 32, 32,105,102, 32,110,111,116, 32, 40,110, 97,109,101, 32, 97,110,100, - 32,118, 97,108,117,101, 41, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, -110,105,108, 44, 32, 34,109, 97,108,102,111,114,109,101,100, 32,114,101,112,111, -110,115,101, 32,104,101, 97,100,101,114,115, 34, 32,101,110,100, 10, 32, 32, 32, - 32, 32, 32, 32, 32,110, 97,109,101, 32, 61, 32,115,116,114,105,110,103, 46,108, -111,119,101,114, 40,110, 97,109,101, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, - 45, 32,103,101,116, 32,110,101,120,116, 32,108,105,110,101, 32, 40,118, 97,108, -117,101, 32,109,105,103,104,116, 32, 98,101, 32,102,111,108,100,101,100, 41, 10, - 32, 32, 32, 32, 32, 32, 32, 32,108,105,110,101, 44, 32,101,114,114, 32, 32, 61, - 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40, 41, 10, 32, 32, 32, 32, - 32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104,101,110, 32,114,101,116,117, -114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, 32, - 32, 32, 32, 32, 45, 45, 32,117,110,102,111,108,100, 32, 97,110,121, 32,102,111, -108,100,101,100, 32,118, 97,108,117,101,115, 10, 32, 32, 32, 32, 32, 32, 32, 32, -119,104,105,108,101, 32,115,116,114,105,110,103, 46,102,105,110,100, 40,108,105, -110,101, 44, 32, 34, 94, 37,115, 34, 41, 32,100,111, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32,118, 97,108,117,101, 32, 61, 32,118, 97,108,117,101, 32, - 46, 46, 32,108,105,110,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, -108,105,110,101, 32, 61, 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40, - 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114, - 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114, -114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, - 32, 32, 32, 32, 32, 32, 45, 45, 32,115, 97,118,101, 32,112, 97,105,114, 32,105, -110, 32,116, 97, 98,108,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,104, -101, 97,100,101,114,115, 91,110, 97,109,101, 93, 32,116,104,101,110, 32,104,101, - 97,100,101,114,115, 91,110, 97,109,101, 93, 32, 61, 32,104,101, 97,100,101,114, -115, 91,110, 97,109,101, 93, 32, 46, 46, 32, 34, 44, 32, 34, 32, 46, 46, 32,118, - 97,108,117,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,104,101, - 97,100,101,114,115, 91,110, 97,109,101, 93, 32, 61, 32,118, 97,108,117,101, 32, -101,110,100, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117, -114,110, 32,104,101, 97,100,101,114,115, 10,101,110,100, 10, 10, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 69,120,116, -114, 97, 32,115,111,117,114, 99,101,115, 32, 97,110,100, 32,115,105,110,107,115, + 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, + 32,101,110,100, 10, 32, 32, 32, 32,125, 41, 10,101,110,100, 10, 10,115,111, 99, +107,101,116, 46,115,105,110,107,116, 91, 34,104,116,116,112, 45, 99,104,117,110, +107,101,100, 34, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40,115,111, 99, +107, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 98, 97,115,101, 46,115, +101,116,109,101,116, 97,116, 97, 98,108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, + 32, 32,103,101,116,102,100, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, + 32,114,101,116,117,114,110, 32,115,111, 99,107, 58,103,101,116,102,100, 40, 41, + 32,101,110,100, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,100,105,114,116,121, 32, + 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,110, 32, +115,111, 99,107, 58,100,105,114,116,121, 40, 41, 32,101,110,100, 10, 32, 32, 32, + 32,125, 44, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, + 32, 61, 32,102,117,110, 99,116,105,111,110, 40,115,101,108,102, 44, 32, 99,104, +117,110,107, 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,105,102, 32,110,111,116, 32, 99,104,117,110,107, 32,116,104,101,110, 32, +114,101,116,117,114,110, 32,115,111, 99,107, 58,115,101,110,100, 40, 34, 48, 92, +114, 92,110, 92,114, 92,110, 34, 41, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,105,122,101, 32, 61, 32,115, +116,114,105,110,103, 46,102,111,114,109, 97,116, 40, 34, 37, 88, 92,114, 92,110, + 34, 44, 32,115,116,114,105,110,103, 46,108,101,110, 40, 99,104,117,110,107, 41, + 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, + 32,115,111, 99,107, 58,115,101,110,100, 40,115,105,122,101, 32, 46, 46, 32, 32, + 99,104,117,110,107, 32, 46, 46, 32, 34, 92,114, 92,110, 34, 41, 10, 32, 32, 32, + 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,125, 41, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,115, -111, 99,107,101,116, 46,115,111,117,114, 99,101,116, 91, 34,104,116,116,112, 45, - 99,104,117,110,107,101,100, 34, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, - 40,115,111, 99,107, 44, 32,104,101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32, -114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97,116, - 97, 98,108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103,101,116,102,100, - 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,110, - 32,115,111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101,110,100, 44, 10, 32, - 32, 32, 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32,102,117,110, 99,116, -105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58,100,105, -114,116,121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, 44, 32,123, 10, 32, - 32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, 32,102,117,110, 99, -116,105,111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, - 45, 32,103,101,116, 32, 99,104,117,110,107, 32,115,105,122,101, 44, 32,115,107, -105,112, 32,101,120,116,101,110,116,105,111,110, 10, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,108,105,110,101, 44, 32,101,114,114, - 32, 61, 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40, 41, 10, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104,101, -110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110, -100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, -115,105,122,101, 32, 61, 32, 98, 97,115,101, 46,116,111,110,117,109, 98,101,114, - 40,115,116,114,105,110,103, 46,103,115,117, 98, 40,108,105,110,101, 44, 32, 34, - 59, 46, 42, 34, 44, 32, 34, 34, 41, 44, 32, 49, 54, 41, 10, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,115,105,122,101, 32,116, -104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32, 34,105,110,118, - 97,108,105,100, 32, 99,104,117,110,107, 32,115,105,122,101, 34, 32,101,110,100, - 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,119, 97,115, 32, -105,116, 32,116,104,101, 32,108, 97,115,116, 32, 99,104,117,110,107, 63, 10, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,115,105,122,101, 32, 62, - 32, 48, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 45, 45, 32,105,102, 32,110,111,116, 44, 32,103,101,116, 32, 99, -104,117,110,107, 32, 97,110,100, 32,115,107,105,112, 32,116,101,114,109,105,110, - 97,116,105,110,103, 32, 67, 82, 76, 70, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104,117,110,107, 44, 32, -101,114,114, 44, 32,112, 97,114,116, 32, 61, 32,115,111, 99,107, 58,114,101, 99, -101,105,118,101, 40,115,105,122,101, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104,117,110,107, 32,116,104,101,110, - 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40, 41, 32,101,110,100, 10, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117, -114,110, 32, 99,104,117,110,107, 44, 32,101,114,114, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,105,102, 32,105,116, 32,119, 97,115, 44, - 32,114,101, 97,100, 32,116,114, 97,105,108,101,114,115, 32,105,110,116,111, 32, -104,101, 97,100,101,114,115, 32,116, 97, 98,108,101, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,104,101, 97,100,101,114,115, 44, 32,101, -114,114, 32, 61, 32,114,101, 99,101,105,118,101,104,101, 97,100,101,114,115, 40, -115,111, 99,107, 44, 32,104,101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,104,101, - 97,100,101,114,115, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105, -108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, - 32, 32, 32,125, 41, 10,101,110,100, 10, 10,115,111, 99,107,101,116, 46,115,105, -110,107,116, 91, 34,104,116,116,112, 45, 99,104,117,110,107,101,100, 34, 93, 32, - 61, 32,102,117,110, 99,116,105,111,110, 40,115,111, 99,107, 41, 10, 32, 32, 32, - 32,114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97, -116, 97, 98,108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103,101,116,102, -100, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114, -110, 32,115,111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101,110,100, 44, 10, - 32, 32, 32, 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32,102,117,110, 99, -116,105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58,100, -105,114,116,121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, 44, 32,123, 10, - 32, 32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, 32,102,117,110, - 99,116,105,111,110, 40,115,101,108,102, 44, 32, 99,104,117,110,107, 44, 32,101, -114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110, -111,116, 32, 99,104,117,110,107, 32,116,104,101,110, 32,114,101,116,117,114,110, - 32,115,111, 99,107, 58,115,101,110,100, 40, 34, 48, 92,114, 92,110, 92,114, 92, -110, 34, 41, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, -108,111, 99, 97,108, 32,115,105,122,101, 32, 61, 32,115,116,114,105,110,103, 46, -102,111,114,109, 97,116, 40, 34, 37, 88, 92,114, 92,110, 34, 44, 32,115,116,114, -105,110,103, 46,108,101,110, 40, 99,104,117,110,107, 41, 41, 10, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58, -115,101,110,100, 40,115,105,122,101, 32, 46, 46, 32, 32, 99,104,117,110,107, 32, - 46, 46, 32, 34, 92,114, 92,110, 34, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101, -110,100, 10, 32, 32, 32, 32,125, 41, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, + 45, 32, 76,111,119, 32,108,101,118,101,108, 32, 72, 84, 84, 80, 32, 65, 80, 73, + 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 76,111,119, 32, -108,101,118,101,108, 32, 72, 84, 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,109, -101,116, 97,116, 32, 61, 32,123, 32, 95, 95,105,110,100,101,120, 32, 61, 32,123, -125, 32,125, 10, 10,102,117,110, 99,116,105,111,110, 32,111,112,101,110, 40,104, -111,115,116, 44, 32,112,111,114,116, 44, 32, 99,114,101, 97,116,101, 41, 10, 32, - 32, 32, 32, 45, 45, 32, 99,114,101, 97,116,101, 32,115,111, 99,107,101,116, 32, -119,105,116,104, 32,117,115,101,114, 32, 99,111,110,110,101, 99,116, 32,102,117, -110, 99,116,105,111,110, 44, 32,111,114, 32,119,105,116,104, 32,100,101,102, 97, -117,108,116, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99, 32, 61, 32,115,111, - 99,107,101,116, 46,116,114,121, 40, 40, 99,114,101, 97,116,101, 32,111,114, 32, -115,111, 99,107,101,116, 46,116, 99,112, 41, 40, 41, 41, 10, 32, 32, 32, 32,108, -111, 99, 97,108, 32,104, 32, 61, 32, 98, 97,115,101, 46,115,101,116,109,101,116, - 97,116, 97, 98,108,101, 40,123, 32, 99, 32, 61, 32, 99, 32,125, 44, 32,109,101, -116, 97,116, 41, 10, 32, 32, 32, 32, 45, 45, 32, 99,114,101, 97,116,101, 32,102, -105,110, 97,108,105,122,101,100, 32,116,114,121, 10, 32, 32, 32, 32,104, 46,116, -114,121, 32, 61, 32,115,111, 99,107,101,116, 46,110,101,119,116,114,121, 40,102, -117,110, 99,116,105,111,110, 40, 41, 32,104, 58, 99,108,111,115,101, 40, 41, 32, -101,110,100, 41, 10, 32, 32, 32, 32, 45, 45, 32,115,101,116, 32,116,105,109,101, -111,117,116, 32, 98,101,102,111,114,101, 32, 99,111,110,110,101, 99,116,105,110, -103, 10, 32, 32, 32, 32,104, 46,116,114,121, 40, 99, 58,115,101,116,116,105,109, -101,111,117,116, 40, 84, 73, 77, 69, 79, 85, 84, 41, 41, 10, 32, 32, 32, 32,104, - 46,116,114,121, 40, 99, 58, 99,111,110,110,101, 99,116, 40,104,111,115,116, 44, - 32,112,111,114,116, 32,111,114, 32, 80, 79, 82, 84, 41, 41, 10, 32, 32, 32, 32, - 45, 45, 32,104,101,114,101, 32,101,118,101,114,121,116,104,105,110,103, 32,119, -111,114,107,101,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,104, 10,101, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108, +111, 99, 97,108, 32,109,101,116, 97,116, 32, 61, 32,123, 32, 95, 95,105,110,100, +101,120, 32, 61, 32,123,125, 32,125, 10, 10,102,117,110, 99,116,105,111,110, 32, + 95, 77, 46,111,112,101,110, 40,104,111,115,116, 44, 32,112,111,114,116, 44, 32, + 99,114,101, 97,116,101, 41, 10, 32, 32, 32, 32, 45, 45, 32, 99,114,101, 97,116, +101, 32,115,111, 99,107,101,116, 32,119,105,116,104, 32,117,115,101,114, 32, 99, +111,110,110,101, 99,116, 32,102,117,110, 99,116,105,111,110, 44, 32,111,114, 32, +119,105,116,104, 32,100,101,102, 97,117,108,116, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32, 99, 32, 61, 32,115,111, 99,107,101,116, 46,116,114,121, 40, 40, 99, +114,101, 97,116,101, 32,111,114, 32,115,111, 99,107,101,116, 46,116, 99,112, 41, + 40, 41, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104, 32, 61, 32, 98, 97, +115,101, 46,115,101,116,109,101,116, 97,116, 97, 98,108,101, 40,123, 32, 99, 32, + 61, 32, 99, 32,125, 44, 32,109,101,116, 97,116, 41, 10, 32, 32, 32, 32, 45, 45, + 32, 99,114,101, 97,116,101, 32,102,105,110, 97,108,105,122,101,100, 32,116,114, +121, 10, 32, 32, 32, 32,104, 46,116,114,121, 32, 61, 32,115,111, 99,107,101,116, + 46,110,101,119,116,114,121, 40,102,117,110, 99,116,105,111,110, 40, 41, 32,104, + 58, 99,108,111,115,101, 40, 41, 32,101,110,100, 41, 10, 32, 32, 32, 32, 45, 45, + 32,115,101,116, 32,116,105,109,101,111,117,116, 32, 98,101,102,111,114,101, 32, + 99,111,110,110,101, 99,116,105,110,103, 10, 32, 32, 32, 32,104, 46,116,114,121, + 40, 99, 58,115,101,116,116,105,109,101,111,117,116, 40, 95, 77, 46, 84, 73, 77, + 69, 79, 85, 84, 41, 41, 10, 32, 32, 32, 32,104, 46,116,114,121, 40, 99, 58, 99, +111,110,110,101, 99,116, 40,104,111,115,116, 44, 32,112,111,114,116, 32,111,114, + 32, 80, 79, 82, 84, 41, 41, 10, 32, 32, 32, 32, 45, 45, 32,104,101,114,101, 32, +101,118,101,114,121,116,104,105,110,103, 32,119,111,114,107,101,100, 10, 32, 32, + 32, 32,114,101,116,117,114,110, 32,104, 10,101,110,100, 10, 10,102,117,110, 99, +116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,115, +101,110,100,114,101,113,117,101,115,116,108,105,110,101, 40,109,101,116,104,111, +100, 44, 32,117,114,105, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101, +113,108,105,110,101, 32, 61, 32,115,116,114,105,110,103, 46,102,111,114,109, 97, +116, 40, 34, 37,115, 32, 37,115, 32, 72, 84, 84, 80, 47, 49, 46, 49, 92,114, 92, +110, 34, 44, 32,109,101,116,104,111,100, 32,111,114, 32, 34, 71, 69, 84, 34, 44, + 32,117,114,105, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108, +102, 46,116,114,121, 40,115,101,108,102, 46, 99, 58,115,101,110,100, 40,114,101, +113,108,105,110,101, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111, +110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,115,101,110,100, +104,101, 97,100,101,114,115, 40,116,111,115,101,110,100, 41, 10, 32, 32, 32, 32, +108,111, 99, 97,108, 32, 99, 97,110,111,110,105, 99, 32, 61, 32,104,101, 97,100, +101,114,115, 46, 99, 97,110,111,110,105, 99, 10, 32, 32, 32, 32,108,111, 99, 97, +108, 32,104, 32, 61, 32, 34, 92,114, 92,110, 34, 10, 32, 32, 32, 32,102,111,114, + 32,102, 44, 32,118, 32,105,110, 32, 98, 97,115,101, 46,112, 97,105,114,115, 40, +116,111,115,101,110,100, 41, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32,104, + 32, 61, 32, 40, 99, 97,110,111,110,105, 99, 91,102, 93, 32,111,114, 32,102, 41, + 32, 46, 46, 32, 34, 58, 32, 34, 32, 46, 46, 32,118, 32, 46, 46, 32, 34, 92,114, + 92,110, 34, 32, 46, 46, 32,104, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, + 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46, 99, 58,115,101,110, +100, 40,104, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101, 110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, - 95,105,110,100,101,120, 58,115,101,110,100,114,101,113,117,101,115,116,108,105, -110,101, 40,109,101,116,104,111,100, 44, 32,117,114,105, 41, 10, 32, 32, 32, 32, -108,111, 99, 97,108, 32,114,101,113,108,105,110,101, 32, 61, 32,115,116,114,105, -110,103, 46,102,111,114,109, 97,116, 40, 34, 37,115, 32, 37,115, 32, 72, 84, 84, - 80, 47, 49, 46, 49, 92,114, 92,110, 34, 44, 32,109,101,116,104,111,100, 32,111, -114, 32, 34, 71, 69, 84, 34, 44, 32,117,114,105, 41, 10, 32, 32, 32, 32,114,101, -116,117,114,110, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46, 99, - 58,115,101,110,100, 40,114,101,113,108,105,110,101, 41, 41, 10,101,110,100, 10, - 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110, -100,101,120, 58,115,101,110,100,104,101, 97,100,101,114,115, 40,104,101, 97,100, -101,114,115, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104, 32, 61, 32, 34, - 92,114, 92,110, 34, 10, 32, 32, 32, 32,102,111,114, 32,105, 44, 32,118, 32,105, -110, 32, 98, 97,115,101, 46,112, 97,105,114,115, 40,104,101, 97,100,101,114,115, - 41, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32,104, 32, 61, 32,105, 32, 46, - 46, 32, 34, 58, 32, 34, 32, 46, 46, 32,118, 32, 46, 46, 32, 34, 92,114, 92,110, - 34, 32, 46, 46, 32,104, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,115, -101,108,102, 46,116,114,121, 40,115,101,108,102, 46, 99, 58,115,101,110,100, 40, -104, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101,110,100, - 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105, -110,100,101,120, 58,115,101,110,100, 98,111,100,121, 40,104,101, 97,100,101,114, -115, 44, 32,115,111,117,114, 99,101, 44, 32,115,116,101,112, 41, 10, 32, 32, 32, - 32,115,111,117,114, 99,101, 32, 61, 32,115,111,117,114, 99,101, 32,111,114, 32, -108,116,110, 49, 50, 46,115,111,117,114, 99,101, 46,101,109,112,116,121, 40, 41, - 10, 32, 32, 32, 32,115,116,101,112, 32, 61, 32,115,116,101,112, 32,111,114, 32, -108,116,110, 49, 50, 46,112,117,109,112, 46,115,116,101,112, 10, 32, 32, 32, 32, - 45, 45, 32,105,102, 32,119,101, 32,100,111,110, 39,116, 32,107,110,111,119, 32, -116,104,101, 32,115,105,122,101, 32,105,110, 32, 97,100,118, 97,110, 99,101, 44, - 32,115,101,110,100, 32, 99,104,117,110,107,101,100, 32, 97,110,100, 32,104,111, -112,101, 32,102,111,114, 32,116,104,101, 32, 98,101,115,116, 10, 32, 32, 32, 32, -108,111, 99, 97,108, 32,109,111,100,101, 32, 61, 32, 34,104,116,116,112, 45, 99, -104,117,110,107,101,100, 34, 10, 32, 32, 32, 32,105,102, 32,104,101, 97,100,101, -114,115, 91, 34, 99,111,110,116,101,110,116, 45,108,101,110,103,116,104, 34, 93, - 32,116,104,101,110, 32,109,111,100,101, 32, 61, 32, 34,107,101,101,112, 45,111, -112,101,110, 34, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, -115,101,108,102, 46,116,114,121, 40,108,116,110, 49, 50, 46,112,117,109,112, 46, - 97,108,108, 40,115,111,117,114, 99,101, 44, 32,115,111, 99,107,101,116, 46,115, -105,110,107, 40,109,111,100,101, 44, 32,115,101,108,102, 46, 99, 41, 44, 32,115, -116,101,112, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32, -109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,114,101, 99,101,105,118, -101,115,116, 97,116,117,115,108,105,110,101, 40, 41, 10, 32, 32, 32, 32,108,111, - 99, 97,108, 32,115,116, 97,116,117,115, 32, 61, 32,115,101,108,102, 46,116,114, -121, 40,115,101,108,102, 46, 99, 58,114,101, 99,101,105,118,101, 40, 53, 41, 41, - 10, 32, 32, 32, 32, 45, 45, 32,105,100,101,110,116,105,102,121, 32, 72, 84, 84, - 80, 47, 48, 46, 57, 32,114,101,115,112,111,110,115,101,115, 44, 32,119,104,105, - 99,104, 32,100,111, 32,110,111,116, 32, 99,111,110,116, 97,105,110, 32, 97, 32, -115,116, 97,116,117,115, 32,108,105,110,101, 10, 32, 32, 32, 32, 45, 45, 32,116, -104,105,115, 32,105,115, 32,106,117,115,116, 32, 97, 32,104,101,117,114,105,115, -116,105, 99, 44, 32, 98,117,116, 32,105,115, 32,119,104, 97,116, 32,116,104,101, - 32, 82, 70, 67, 32,114,101, 99,111,109,109,101,110,100,115, 10, 32, 32, 32, 32, -105,102, 32,115,116, 97,116,117,115, 32,126, 61, 32, 34, 72, 84, 84, 80, 47, 34, - 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,115,116, - 97,116,117,115, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, 32,111,116,104,101, -114,119,105,115,101, 32,112,114,111, 99,101,101,100, 32,114,101, 97,100,105,110, -103, 32, 97, 32,115,116, 97,116,117,115, 32,108,105,110,101, 10, 32, 32, 32, 32, -115,116, 97,116,117,115, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115,101, -108,102, 46, 99, 58,114,101, 99,101,105,118,101, 40, 34, 42,108, 34, 44, 32,115, -116, 97,116,117,115, 41, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,111, -100,101, 32, 61, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 50, 44, 32, -115,116,114,105,110,103, 46,102,105,110,100, 40,115,116, 97,116,117,115, 44, 32, - 34, 72, 84, 84, 80, 47, 37,100, 42, 37, 46, 37,100, 42, 32, 40, 37,100, 37,100, - 37,100, 41, 34, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101, -108,102, 46,116,114,121, 40, 98, 97,115,101, 46,116,111,110,117,109, 98,101,114, - 40, 99,111,100,101, 41, 44, 32,115,116, 97,116,117,115, 41, 10,101,110,100, 10, - 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110, -100,101,120, 58,114,101, 99,101,105,118,101,104,101, 97,100,101,114,115, 40, 41, - 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,116,114,121, - 40,114,101, 99,101,105,118,101,104,101, 97,100,101,114,115, 40,115,101,108,102, - 46, 99, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109, -101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,114,101, 99,101,105,118,101, - 98,111,100,121, 40,104,101, 97,100,101,114,115, 44, 32,115,105,110,107, 44, 32, -115,116,101,112, 41, 10, 32, 32, 32, 32,115,105,110,107, 32, 61, 32,115,105,110, -107, 32,111,114, 32,108,116,110, 49, 50, 46,115,105,110,107, 46,110,117,108,108, + 95,105,110,100,101,120, 58,115,101,110,100, 98,111,100,121, 40,104,101, 97,100, +101,114,115, 44, 32,115,111,117,114, 99,101, 44, 32,115,116,101,112, 41, 10, 32, + 32, 32, 32,115,111,117,114, 99,101, 32, 61, 32,115,111,117,114, 99,101, 32,111, +114, 32,108,116,110, 49, 50, 46,115,111,117,114, 99,101, 46,101,109,112,116,121, 40, 41, 10, 32, 32, 32, 32,115,116,101,112, 32, 61, 32,115,116,101,112, 32,111, 114, 32,108,116,110, 49, 50, 46,112,117,109,112, 46,115,116,101,112, 10, 32, 32, - 32, 32,108,111, 99, 97,108, 32,108,101,110,103,116,104, 32, 61, 32, 98, 97,115, -101, 46,116,111,110,117,109, 98,101,114, 40,104,101, 97,100,101,114,115, 91, 34, - 99,111,110,116,101,110,116, 45,108,101,110,103,116,104, 34, 93, 41, 10, 32, 32, - 32, 32,108,111, 99, 97,108, 32,116, 32, 61, 32,104,101, 97,100,101,114,115, 91, - 34,116,114, 97,110,115,102,101,114, 45,101,110, 99,111,100,105,110,103, 34, 93, - 32, 45, 45, 32,115,104,111,114,116, 99,117,116, 10, 32, 32, 32, 32,108,111, 99, - 97,108, 32,109,111,100,101, 32, 61, 32, 34,100,101,102, 97,117,108,116, 34, 32, - 45, 45, 32, 99,111,110,110,101, 99,116,105,111,110, 32, 99,108,111,115,101, 10, - 32, 32, 32, 32,105,102, 32,116, 32, 97,110,100, 32,116, 32,126, 61, 32, 34,105, -100,101,110,116,105,116,121, 34, 32,116,104,101,110, 32,109,111,100,101, 32, 61, - 32, 34,104,116,116,112, 45, 99,104,117,110,107,101,100, 34, 10, 32, 32, 32, 32, -101,108,115,101,105,102, 32, 98, 97,115,101, 46,116,111,110,117,109, 98,101,114, - 40,104,101, 97,100,101,114,115, 91, 34, 99,111,110,116,101,110,116, 45,108,101, -110,103,116,104, 34, 93, 41, 32,116,104,101,110, 32,109,111,100,101, 32, 61, 32, - 34, 98,121, 45,108,101,110,103,116,104, 34, 32,101,110,100, 10, 32, 32, 32, 32, -114,101,116,117,114,110, 32,115,101,108,102, 46,116,114,121, 40,108,116,110, 49, - 50, 46,112,117,109,112, 46, 97,108,108, 40,115,111, 99,107,101,116, 46,115,111, -117,114, 99,101, 40,109,111,100,101, 44, 32,115,101,108,102, 46, 99, 44, 32,108, -101,110,103,116,104, 41, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,105,110,107, - 44, 32,115,116,101,112, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105, -111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,114,101, 99, -101,105,118,101, 48, 57, 98,111,100,121, 40,115,116, 97,116,117,115, 44, 32,115, -105,110,107, 44, 32,115,116,101,112, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, - 32,115,111,117,114, 99,101, 32, 61, 32,108,116,110, 49, 50, 46,115,111,117,114, - 99,101, 46,114,101,119,105,110,100, 40,115,111, 99,107,101,116, 46,115,111,117, -114, 99,101, 40, 34,117,110,116,105,108, 45, 99,108,111,115,101,100, 34, 44, 32, -115,101,108,102, 46, 99, 41, 41, 10, 32, 32, 32, 32,115,111,117,114, 99,101, 40, -115,116, 97,116,117,115, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115, -101,108,102, 46,116,114,121, 40,108,116,110, 49, 50, 46,112,117,109,112, 46, 97, -108,108, 40,115,111,117,114, 99,101, 44, 32,115,105,110,107, 44, 32,115,116,101, -112, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101, -116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 99,108,111,115,101, 40, 41, 10, - 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46, 99, 58, 99,108, -111,115,101, 40, 41, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 32, 32, 45, 45, 32,105,102, 32,119,101, 32,100,111,110, 39,116, 32,107,110,111, +119, 32,116,104,101, 32,115,105,122,101, 32,105,110, 32, 97,100,118, 97,110, 99, +101, 44, 32,115,101,110,100, 32, 99,104,117,110,107,101,100, 32, 97,110,100, 32, +104,111,112,101, 32,102,111,114, 32,116,104,101, 32, 98,101,115,116, 10, 32, 32, + 32, 32,108,111, 99, 97,108, 32,109,111,100,101, 32, 61, 32, 34,104,116,116,112, + 45, 99,104,117,110,107,101,100, 34, 10, 32, 32, 32, 32,105,102, 32,104,101, 97, +100,101,114,115, 91, 34, 99,111,110,116,101,110,116, 45,108,101,110,103,116,104, + 34, 93, 32,116,104,101,110, 32,109,111,100,101, 32, 61, 32, 34,107,101,101,112, + 45,111,112,101,110, 34, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114, +110, 32,115,101,108,102, 46,116,114,121, 40,108,116,110, 49, 50, 46,112,117,109, +112, 46, 97,108,108, 40,115,111,117,114, 99,101, 44, 32,115,111, 99,107,101,116, + 46,115,105,110,107, 40,109,111,100,101, 44, 32,115,101,108,102, 46, 99, 41, 44, + 32,115,116,101,112, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111, +110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,114,101, 99,101, +105,118,101,115,116, 97,116,117,115,108,105,110,101, 40, 41, 10, 32, 32, 32, 32, +108,111, 99, 97,108, 32,115,116, 97,116,117,115, 32, 61, 32,115,101,108,102, 46, +116,114,121, 40,115,101,108,102, 46, 99, 58,114,101, 99,101,105,118,101, 40, 53, + 41, 41, 10, 32, 32, 32, 32, 45, 45, 32,105,100,101,110,116,105,102,121, 32, 72, + 84, 84, 80, 47, 48, 46, 57, 32,114,101,115,112,111,110,115,101,115, 44, 32,119, +104,105, 99,104, 32,100,111, 32,110,111,116, 32, 99,111,110,116, 97,105,110, 32, + 97, 32,115,116, 97,116,117,115, 32,108,105,110,101, 10, 32, 32, 32, 32, 45, 45, + 32,116,104,105,115, 32,105,115, 32,106,117,115,116, 32, 97, 32,104,101,117,114, +105,115,116,105, 99, 44, 32, 98,117,116, 32,105,115, 32,119,104, 97,116, 32,116, +104,101, 32, 82, 70, 67, 32,114,101, 99,111,109,109,101,110,100,115, 10, 32, 32, + 32, 32,105,102, 32,115,116, 97,116,117,115, 32,126, 61, 32, 34, 72, 84, 84, 80, + 47, 34, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32, +115,116, 97,116,117,115, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, 32,111,116, +104,101,114,119,105,115,101, 32,112,114,111, 99,101,101,100, 32,114,101, 97,100, +105,110,103, 32, 97, 32,115,116, 97,116,117,115, 32,108,105,110,101, 10, 32, 32, + 32, 32,115,116, 97,116,117,115, 32, 61, 32,115,101,108,102, 46,116,114,121, 40, +115,101,108,102, 46, 99, 58,114,101, 99,101,105,118,101, 40, 34, 42,108, 34, 44, + 32,115,116, 97,116,117,115, 41, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, + 99,111,100,101, 32, 61, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 50, + 44, 32,115,116,114,105,110,103, 46,102,105,110,100, 40,115,116, 97,116,117,115, + 44, 32, 34, 72, 84, 84, 80, 47, 37,100, 42, 37, 46, 37,100, 42, 32, 40, 37,100, + 37,100, 37,100, 41, 34, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, +115,101,108,102, 46,116,114,121, 40, 98, 97,115,101, 46,116,111,110,117,109, 98, +101,114, 40, 99,111,100,101, 41, 44, 32,115,116, 97,116,117,115, 41, 10,101,110, +100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95, +105,110,100,101,120, 58,114,101, 99,101,105,118,101,104,101, 97,100,101,114,115, + 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,116, +114,121, 40,114,101, 99,101,105,118,101,104,101, 97,100,101,114,115, 40,115,101, +108,102, 46, 99, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, + 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,114,101, 99,101,105, +118,101, 98,111,100,121, 40,104,101, 97,100,101,114,115, 44, 32,115,105,110,107, + 44, 32,115,116,101,112, 41, 10, 32, 32, 32, 32,115,105,110,107, 32, 61, 32,115, +105,110,107, 32,111,114, 32,108,116,110, 49, 50, 46,115,105,110,107, 46,110,117, +108,108, 40, 41, 10, 32, 32, 32, 32,115,116,101,112, 32, 61, 32,115,116,101,112, + 32,111,114, 32,108,116,110, 49, 50, 46,112,117,109,112, 46,115,116,101,112, 10, + 32, 32, 32, 32,108,111, 99, 97,108, 32,108,101,110,103,116,104, 32, 61, 32, 98, + 97,115,101, 46,116,111,110,117,109, 98,101,114, 40,104,101, 97,100,101,114,115, + 91, 34, 99,111,110,116,101,110,116, 45,108,101,110,103,116,104, 34, 93, 41, 10, + 32, 32, 32, 32,108,111, 99, 97,108, 32,116, 32, 61, 32,104,101, 97,100,101,114, +115, 91, 34,116,114, 97,110,115,102,101,114, 45,101,110, 99,111,100,105,110,103, + 34, 93, 32, 45, 45, 32,115,104,111,114,116, 99,117,116, 10, 32, 32, 32, 32,108, +111, 99, 97,108, 32,109,111,100,101, 32, 61, 32, 34,100,101,102, 97,117,108,116, + 34, 32, 45, 45, 32, 99,111,110,110,101, 99,116,105,111,110, 32, 99,108,111,115, +101, 10, 32, 32, 32, 32,105,102, 32,116, 32, 97,110,100, 32,116, 32,126, 61, 32, + 34,105,100,101,110,116,105,116,121, 34, 32,116,104,101,110, 32,109,111,100,101, + 32, 61, 32, 34,104,116,116,112, 45, 99,104,117,110,107,101,100, 34, 10, 32, 32, + 32, 32,101,108,115,101,105,102, 32, 98, 97,115,101, 46,116,111,110,117,109, 98, +101,114, 40,104,101, 97,100,101,114,115, 91, 34, 99,111,110,116,101,110,116, 45, +108,101,110,103,116,104, 34, 93, 41, 32,116,104,101,110, 32,109,111,100,101, 32, + 61, 32, 34, 98,121, 45,108,101,110,103,116,104, 34, 32,101,110,100, 10, 32, 32, + 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,116,114,121, 40,108,116, +110, 49, 50, 46,112,117,109,112, 46, 97,108,108, 40,115,111, 99,107,101,116, 46, +115,111,117,114, 99,101, 40,109,111,100,101, 44, 32,115,101,108,102, 46, 99, 44, + 32,108,101,110,103,116,104, 41, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,105, +110,107, 44, 32,115,116,101,112, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99, +116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,114, +101, 99,101,105,118,101, 48, 57, 98,111,100,121, 40,115,116, 97,116,117,115, 44, + 32,115,105,110,107, 44, 32,115,116,101,112, 41, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,115,111,117,114, 99,101, 32, 61, 32,108,116,110, 49, 50, 46,115,111, +117,114, 99,101, 46,114,101,119,105,110,100, 40,115,111, 99,107,101,116, 46,115, +111,117,114, 99,101, 40, 34,117,110,116,105,108, 45, 99,108,111,115,101,100, 34, + 44, 32,115,101,108,102, 46, 99, 41, 41, 10, 32, 32, 32, 32,115,111,117,114, 99, +101, 40,115,116, 97,116,117,115, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, + 32,115,101,108,102, 46,116,114,121, 40,108,116,110, 49, 50, 46,112,117,109,112, + 46, 97,108,108, 40,115,111,117,114, 99,101, 44, 32,115,105,110,107, 44, 32,115, +116,101,112, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32, +109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 99,108,111,115,101, 40, + 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46, 99, 58, + 99,108,111,115,101, 40, 41, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 72,105,103,104, 32,108,101,118, -101,108, 32, 72, 84, 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 72,105,103,104, 32,108, +101,118,101,108, 32, 72, 84, 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,102,117,110, 99, -116,105,111,110, 32, 97,100,106,117,115,116,117,114,105, 40,114,101,113,116, 41, - 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,117, 32, 61, 32,114,101,113,116, 10, - 32, 32, 32, 32, 45, 45, 32,105,102, 32,116,104,101,114,101, 32,105,115, 32, 97, - 32,112,114,111,120,121, 44, 32,119,101, 32,110,101,101,100, 32,116,104,101, 32, -102,117,108,108, 32,117,114,108, 46, 32,111,116,104,101,114,119,105,115,101, 44, - 32,106,117,115,116, 32, 97, 32,112, 97,114,116, 46, 10, 32, 32, 32, 32,105,102, - 32,110,111,116, 32,114,101,113,116, 46,112,114,111,120,121, 32, 97,110,100, 32, -110,111,116, 32, 80, 82, 79, 88, 89, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, - 32, 32, 32,117, 32, 61, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, -112, 97,116,104, 32, 61, 32,115,111, 99,107,101,116, 46,116,114,121, 40,114,101, -113,116, 46,112, 97,116,104, 44, 32, 34,105,110,118, 97,108,105,100, 32,112, 97, -116,104, 32, 39,110,105,108, 39, 34, 41, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32,112, 97,114, 97,109,115, 32, 61, 32,114,101,113,116, 46,112, 97,114, - 97,109,115, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,113,117,101,114, -121, 32, 61, 32,114,101,113,116, 46,113,117,101,114,121, 44, 10, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32,102,114, 97,103,109,101,110,116, 32, 61, 32,114,101, -113,116, 46,102,114, 97,103,109,101,110,116, 10, 32, 32, 32, 32, 32, 32, 32, 32, -125, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, - 32,117,114,108, 46, 98,117,105,108,100, 40,117, 41, 10,101,110,100, 10, 10,108, -111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32, 97,100,106,117,115,116, -112,114,111,120,121, 40,114,101,113,116, 41, 10, 32, 32, 32, 32,108,111, 99, 97, -108, 32,112,114,111,120,121, 32, 61, 32,114,101,113,116, 46,112,114,111,120,121, - 32,111,114, 32, 80, 82, 79, 88, 89, 10, 32, 32, 32, 32,105,102, 32,112,114,111, -120,121, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,112,114,111,120, -121, 32, 61, 32,117,114,108, 46,112, 97,114,115,101, 40,112,114,111,120,121, 41, - 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,112,114,111,120, -121, 46,104,111,115,116, 44, 32,112,114,111,120,121, 46,112,111,114,116, 32,111, -114, 32, 51, 49, 50, 56, 10, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, - 32, 32, 32, 32,114,101,116,117,114,110, 32,114,101,113,116, 46,104,111,115,116, - 44, 32,114,101,113,116, 46,112,111,114,116, 10, 32, 32, 32, 32,101,110,100, 10, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,102,117, +110, 99,116,105,111,110, 32, 97,100,106,117,115,116,117,114,105, 40,114,101,113, +116, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,117, 32, 61, 32,114,101,113, +116, 10, 32, 32, 32, 32, 45, 45, 32,105,102, 32,116,104,101,114,101, 32,105,115, + 32, 97, 32,112,114,111,120,121, 44, 32,119,101, 32,110,101,101,100, 32,116,104, +101, 32,102,117,108,108, 32,117,114,108, 46, 32,111,116,104,101,114,119,105,115, +101, 44, 32,106,117,115,116, 32, 97, 32,112, 97,114,116, 46, 10, 32, 32, 32, 32, +105,102, 32,110,111,116, 32,114,101,113,116, 46,112,114,111,120,121, 32, 97,110, +100, 32,110,111,116, 32, 95, 77, 46, 80, 82, 79, 88, 89, 32,116,104,101,110, 10, + 32, 32, 32, 32, 32, 32, 32, 32,117, 32, 61, 32,123, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,112, 97,116,104, 32, 61, 32,115,111, 99,107,101,116, 46,116, +114,121, 40,114,101,113,116, 46,112, 97,116,104, 44, 32, 34,105,110,118, 97,108, +105,100, 32,112, 97,116,104, 32, 39,110,105,108, 39, 34, 41, 44, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32,112, 97,114, 97,109,115, 32, 61, 32,114,101,113, +116, 46,112, 97,114, 97,109,115, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32,113,117,101,114,121, 32, 61, 32,114,101,113,116, 46,113,117,101,114,121, 44, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,102,114, 97,103,109,101,110,116, + 32, 61, 32,114,101,113,116, 46,102,114, 97,103,109,101,110,116, 10, 32, 32, 32, + 32, 32, 32, 32, 32,125, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,114, +101,116,117,114,110, 32,117,114,108, 46, 98,117,105,108,100, 40,117, 41, 10,101, +110,100, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32, 97, +100,106,117,115,116,112,114,111,120,121, 40,114,101,113,116, 41, 10, 32, 32, 32, + 32,108,111, 99, 97,108, 32,112,114,111,120,121, 32, 61, 32,114,101,113,116, 46, +112,114,111,120,121, 32,111,114, 32, 95, 77, 46, 80, 82, 79, 88, 89, 10, 32, 32, + 32, 32,105,102, 32,112,114,111,120,121, 32,116,104,101,110, 10, 32, 32, 32, 32, + 32, 32, 32, 32,112,114,111,120,121, 32, 61, 32,117,114,108, 46,112, 97,114,115, +101, 40,112,114,111,120,121, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116, +117,114,110, 32,112,114,111,120,121, 46,104,111,115,116, 44, 32,112,114,111,120, +121, 46,112,111,114,116, 32,111,114, 32, 51, 49, 50, 56, 10, 32, 32, 32, 32,101, +108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,114, +101,113,116, 46,104,111,115,116, 44, 32,114,101,113,116, 46,112,111,114,116, 10, + 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10,108,111, 99, 97,108, 32,102, +117,110, 99,116,105,111,110, 32, 97,100,106,117,115,116,104,101, 97,100,101,114, +115, 40,114,101,113,116, 41, 10, 32, 32, 32, 32, 45, 45, 32,100,101,102, 97,117, +108,116, 32,104,101, 97,100,101,114,115, 10, 32, 32, 32, 32,108,111, 99, 97,108, + 32,104,111,115,116, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, +114,101,113,116, 46, 97,117,116,104,111,114,105,116,121, 44, 32, 34, 94, 46, 45, + 64, 34, 44, 32, 34, 34, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,108,111, +119,101,114, 32, 61, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 91, 34,117,115, +101,114, 45, 97,103,101,110,116, 34, 93, 32, 61, 32, 95, 77, 46, 85, 83, 69, 82, + 65, 71, 69, 78, 84, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 91, 34,104,111,115, +116, 34, 93, 32, 61, 32,104,111,115,116, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 91, 34, 99,111,110,110,101, 99,116,105,111,110, 34, 93, 32, 61, 32, 34, 99,108, +111,115,101, 44, 32, 84, 69, 34, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 91, 34, +116,101, 34, 93, 32, 61, 32, 34,116,114, 97,105,108,101,114,115, 34, 10, 32, 32, + 32, 32,125, 10, 32, 32, 32, 32, 45, 45, 32,105,102, 32,119,101, 32,104, 97,118, +101, 32, 97,117,116,104,101,110,116,105, 99, 97,116,105,111,110, 32,105,110,102, +111,114,109, 97,116,105,111,110, 44, 32,112, 97,115,115, 32,105,116, 32, 97,108, +111,110,103, 10, 32, 32, 32, 32,105,102, 32,114,101,113,116, 46,117,115,101,114, + 32, 97,110,100, 32,114,101,113,116, 46,112, 97,115,115,119,111,114,100, 32,116, +104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111,119,101,114, 91, 34, 97, +117,116,104,111,114,105,122, 97,116,105,111,110, 34, 93, 32, 61, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 34, 66, 97,115,105, 99, 32, 34, 32, 46, 46, + 32, 32, 40,109,105,109,101, 46, 98, 54, 52, 40,114,101,113,116, 46,117,115,101, +114, 32, 46, 46, 32, 34, 58, 34, 32, 46, 46, 10, 9, 9,117,114,108, 46,117,110, +101,115, 99, 97,112,101, 40,114,101,113,116, 46,112, 97,115,115,119,111,114,100, + 41, 41, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, 32,105, +102, 32,119,101, 32,104, 97,118,101, 32,112,114,111,120,121, 32, 97,117,116,104, +101,110,116,105, 99, 97,116,105,111,110, 32,105,110,102,111,114,109, 97,116,105, +111,110, 44, 32,112, 97,115,115, 32,105,116, 32, 97,108,111,110,103, 10, 32, 32, + 32, 32,108,111, 99, 97,108, 32,112,114,111,120,121, 32, 61, 32,114,101,113,116, + 46,112,114,111,120,121, 32,111,114, 32, 95, 77, 46, 80, 82, 79, 88, 89, 10, 32, + 32, 32, 32,105,102, 32,112,114,111,120,121, 32,116,104,101,110, 10, 32, 32, 32, + 32, 32, 32, 32, 32,112,114,111,120,121, 32, 61, 32,117,114,108, 46,112, 97,114, +115,101, 40,112,114,111,120,121, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, + 32,112,114,111,120,121, 46,117,115,101,114, 32, 97,110,100, 32,112,114,111,120, +121, 46,112, 97,115,115,119,111,114,100, 32,116,104,101,110, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32,108,111,119,101,114, 91, 34,112,114,111,120,121, + 45, 97,117,116,104,111,114,105,122, 97,116,105,111,110, 34, 93, 32, 61, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 34, 66, 97,115,105, + 99, 32, 34, 32, 46, 46, 32, 32, 40,109,105,109,101, 46, 98, 54, 52, 40,112,114, +111,120,121, 46,117,115,101,114, 32, 46, 46, 32, 34, 58, 34, 32, 46, 46, 32,112, +114,111,120,121, 46,112, 97,115,115,119,111,114,100, 41, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, + 45, 45, 32,111,118,101,114,114,105,100,101, 32,119,105,116,104, 32,117,115,101, +114, 32,104,101, 97,100,101,114,115, 10, 32, 32, 32, 32,102,111,114, 32,105, 44, +118, 32,105,110, 32, 98, 97,115,101, 46,112, 97,105,114,115, 40,114,101,113,116, + 46,104,101, 97,100,101,114,115, 32,111,114, 32,108,111,119,101,114, 41, 32,100, +111, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111,119,101,114, 91,115,116,114,105, +110,103, 46,108,111,119,101,114, 40,105, 41, 93, 32, 61, 32,118, 10, 32, 32, 32, + 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,108,111,119,101, +114, 10,101,110,100, 10, 10, 45, 45, 32,100,101,102, 97,117,108,116, 32,117,114, +108, 32,112, 97,114,116,115, 10,108,111, 99, 97,108, 32,100,101,102, 97,117,108, +116, 32, 61, 32,123, 10, 32, 32, 32, 32,104,111,115,116, 32, 61, 32, 34, 34, 44, + 10, 32, 32, 32, 32,112,111,114,116, 32, 61, 32, 80, 79, 82, 84, 44, 10, 32, 32, + 32, 32,112, 97,116,104, 32, 61, 34, 47, 34, 44, 10, 32, 32, 32, 32,115, 99,104, +101,109,101, 32, 61, 32, 34,104,116,116,112, 34, 10,125, 10, 10,108,111, 99, 97, +108, 32,102,117,110, 99,116,105,111,110, 32, 97,100,106,117,115,116,114,101,113, +117,101,115,116, 40,114,101,113,116, 41, 10, 32, 32, 32, 32, 45, 45, 32,112, 97, +114,115,101, 32,117,114,108, 32,105,102, 32,112,114,111,118,105,100,101,100, 10, + 32, 32, 32, 32,108,111, 99, 97,108, 32,110,114,101,113,116, 32, 61, 32,114,101, +113,116, 46,117,114,108, 32, 97,110,100, 32,117,114,108, 46,112, 97,114,115,101, + 40,114,101,113,116, 46,117,114,108, 44, 32,100,101,102, 97,117,108,116, 41, 32, +111,114, 32,123,125, 10, 32, 32, 32, 32, 45, 45, 32,101,120,112,108,105, 99,105, +116, 32, 99,111,109,112,111,110,101,110,116,115, 32,111,118,101,114,114,105,100, +101, 32,117,114,108, 10, 32, 32, 32, 32,102,111,114, 32,105, 44,118, 32,105,110, + 32, 98, 97,115,101, 46,112, 97,105,114,115, 40,114,101,113,116, 41, 32,100,111, + 32,110,114,101,113,116, 91,105, 93, 32, 61, 32,118, 32,101,110,100, 10, 32, 32, + 32, 32,105,102, 32,110,114,101,113,116, 46,112,111,114,116, 32, 61, 61, 32, 34, + 34, 32,116,104,101,110, 32,110,114,101,113,116, 46,112,111,114,116, 32, 61, 32, + 80, 79, 82, 84, 32,101,110,100, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32, + 40,110,114,101,113,116, 46,104,111,115,116, 32, 97,110,100, 32,110,114,101,113, +116, 46,104,111,115,116, 32,126, 61, 32, 34, 34, 41, 32,116,104,101,110, 10, 32, + 32, 32, 32, 32, 32, 32, 32,115,111, 99,107,101,116, 46,116,114,121, 40,110,105, +108, 44, 32, 34,105,110,118, 97,108,105,100, 32,104,111,115,116, 32, 39, 34, 32, + 46, 46, 32, 98, 97,115,101, 46,116,111,115,116,114,105,110,103, 40,110,114,101, +113,116, 46,104,111,115,116, 41, 32, 46, 46, 32, 34, 39, 34, 41, 10, 32, 32, 32, + 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, 32, 99,111,109,112,117,116,101, 32, +117,114,105, 32,105,102, 32,117,115,101,114, 32,104, 97,115,110, 39,116, 32,111, +118,101,114,114,105,100,101,110, 10, 32, 32, 32, 32,110,114,101,113,116, 46,117, +114,105, 32, 61, 32,114,101,113,116, 46,117,114,105, 32,111,114, 32, 97,100,106, +117,115,116,117,114,105, 40,110,114,101,113,116, 41, 10, 32, 32, 32, 32, 45, 45, + 32, 97,100,106,117,115,116, 32,104,101, 97,100,101,114,115, 32,105,110, 32,114, +101,113,117,101,115,116, 10, 32, 32, 32, 32,110,114,101,113,116, 46,104,101, 97, +100,101,114,115, 32, 61, 32, 97,100,106,117,115,116,104,101, 97,100,101,114,115, + 40,110,114,101,113,116, 41, 10, 32, 32, 32, 32, 45, 45, 32, 97,106,117,115,116, + 32,104,111,115,116, 32, 97,110,100, 32,112,111,114,116, 32,105,102, 32,116,104, +101,114,101, 32,105,115, 32, 97, 32,112,114,111,120,121, 10, 32, 32, 32, 32,110, +114,101,113,116, 46,104,111,115,116, 44, 32,110,114,101,113,116, 46,112,111,114, +116, 32, 61, 32, 97,100,106,117,115,116,112,114,111,120,121, 40,110,114,101,113, +116, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,110,114,101,113,116, 10, 101,110,100, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32, - 97,100,106,117,115,116,104,101, 97,100,101,114,115, 40,114,101,113,116, 41, 10, - 32, 32, 32, 32, 45, 45, 32,100,101,102, 97,117,108,116, 32,104,101, 97,100,101, -114,115, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,108,111,119,101,114, 32, 61, - 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 91, 34,117,115,101,114, 45, 97,103, -101,110,116, 34, 93, 32, 61, 32, 85, 83, 69, 82, 65, 71, 69, 78, 84, 44, 10, 32, - 32, 32, 32, 32, 32, 32, 32, 91, 34,104,111,115,116, 34, 93, 32, 61, 32,114,101, -113,116, 46,104,111,115,116, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 91, 34, 99, -111,110,110,101, 99,116,105,111,110, 34, 93, 32, 61, 32, 34, 99,108,111,115,101, - 44, 32, 84, 69, 34, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 91, 34,116,101, 34, - 93, 32, 61, 32, 34,116,114, 97,105,108,101,114,115, 34, 10, 32, 32, 32, 32,125, - 10, 32, 32, 32, 32, 45, 45, 32,105,102, 32,119,101, 32,104, 97,118,101, 32, 97, -117,116,104,101,110,116,105, 99, 97,116,105,111,110, 32,105,110,102,111,114,109, - 97,116,105,111,110, 44, 32,112, 97,115,115, 32,105,116, 32, 97,108,111,110,103, - 10, 32, 32, 32, 32,105,102, 32,114,101,113,116, 46,117,115,101,114, 32, 97,110, -100, 32,114,101,113,116, 46,112, 97,115,115,119,111,114,100, 32,116,104,101,110, - 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111,119,101,114, 91, 34, 97,117,116,104, -111,114,105,122, 97,116,105,111,110, 34, 93, 32, 61, 32, 10, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 34, 66, 97,115,105, 99, 32, 34, 32, 46, 46, 32, 32, - 40,109,105,109,101, 46, 98, 54, 52, 40,114,101,113,116, 46,117,115,101,114, 32, - 46, 46, 32, 34, 58, 34, 32, 46, 46, 32,114,101,113,116, 46,112, 97,115,115,119, -111,114,100, 41, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, - 32,111,118,101,114,114,105,100,101, 32,119,105,116,104, 32,117,115,101,114, 32, -104,101, 97,100,101,114,115, 10, 32, 32, 32, 32,102,111,114, 32,105, 44,118, 32, -105,110, 32, 98, 97,115,101, 46,112, 97,105,114,115, 40,114,101,113,116, 46,104, -101, 97,100,101,114,115, 32,111,114, 32,108,111,119,101,114, 41, 32,100,111, 10, - 32, 32, 32, 32, 32, 32, 32, 32,108,111,119,101,114, 91,115,116,114,105,110,103, - 46,108,111,119,101,114, 40,105, 41, 93, 32, 61, 32,118, 10, 32, 32, 32, 32,101, -110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,108,111,119,101,114, 10, -101,110,100, 10, 10, 45, 45, 32,100,101,102, 97,117,108,116, 32,117,114,108, 32, -112, 97,114,116,115, 10,108,111, 99, 97,108, 32,100,101,102, 97,117,108,116, 32, - 61, 32,123, 10, 32, 32, 32, 32,104,111,115,116, 32, 61, 32, 34, 34, 44, 10, 32, - 32, 32, 32,112,111,114,116, 32, 61, 32, 80, 79, 82, 84, 44, 10, 32, 32, 32, 32, -112, 97,116,104, 32, 61, 34, 47, 34, 44, 10, 32, 32, 32, 32,115, 99,104,101,109, -101, 32, 61, 32, 34,104,116,116,112, 34, 10,125, 10, 10,108,111, 99, 97,108, 32, -102,117,110, 99,116,105,111,110, 32, 97,100,106,117,115,116,114,101,113,117,101, -115,116, 40,114,101,113,116, 41, 10, 32, 32, 32, 32, 45, 45, 32,112, 97,114,115, -101, 32,117,114,108, 32,105,102, 32,112,114,111,118,105,100,101,100, 10, 32, 32, - 32, 32,108,111, 99, 97,108, 32,110,114,101,113,116, 32, 61, 32,114,101,113,116, - 46,117,114,108, 32, 97,110,100, 32,117,114,108, 46,112, 97,114,115,101, 40,114, -101,113,116, 46,117,114,108, 44, 32,100,101,102, 97,117,108,116, 41, 32,111,114, - 32,123,125, 10, 32, 32, 32, 32, 45, 45, 32,101,120,112,108,105, 99,105,116, 32, - 99,111,109,112,111,110,101,110,116,115, 32,111,118,101,114,114,105,100,101, 32, -117,114,108, 10, 32, 32, 32, 32,102,111,114, 32,105, 44,118, 32,105,110, 32, 98, - 97,115,101, 46,112, 97,105,114,115, 40,114,101,113,116, 41, 32,100,111, 32,110, -114,101,113,116, 91,105, 93, 32, 61, 32,118, 32,101,110,100, 10, 32, 32, 32, 32, -105,102, 32,110,114,101,113,116, 46,112,111,114,116, 32, 61, 61, 32, 34, 34, 32, -116,104,101,110, 32,110,114,101,113,116, 46,112,111,114,116, 32, 61, 32, 56, 48, - 32,101,110,100, 10, 32, 32, 32, 32,115,111, 99,107,101,116, 46,116,114,121, 40, -110,114,101,113,116, 46,104,111,115,116, 32, 97,110,100, 32,110,114,101,113,116, - 46,104,111,115,116, 32,126, 61, 32, 34, 34, 44, 32, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 34,105,110,118, 97,108,105,100, 32,104,111,115,116, 32, 39, 34, 32, 46, - 46, 32, 98, 97,115,101, 46,116,111,115,116,114,105,110,103, 40,110,114,101,113, -116, 46,104,111,115,116, 41, 32, 46, 46, 32, 34, 39, 34, 41, 10, 32, 32, 32, 32, - 45, 45, 32, 99,111,109,112,117,116,101, 32,117,114,105, 32,105,102, 32,117,115, -101,114, 32,104, 97,115,110, 39,116, 32,111,118,101,114,114,105,100,101,110, 10, - 32, 32, 32, 32,110,114,101,113,116, 46,117,114,105, 32, 61, 32,114,101,113,116, - 46,117,114,105, 32,111,114, 32, 97,100,106,117,115,116,117,114,105, 40,110,114, -101,113,116, 41, 10, 32, 32, 32, 32, 45, 45, 32, 97,106,117,115,116, 32,104,111, -115,116, 32, 97,110,100, 32,112,111,114,116, 32,105,102, 32,116,104,101,114,101, - 32,105,115, 32, 97, 32,112,114,111,120,121, 10, 32, 32, 32, 32,110,114,101,113, -116, 46,104,111,115,116, 44, 32,110,114,101,113,116, 46,112,111,114,116, 32, 61, - 32, 97,100,106,117,115,116,112,114,111,120,121, 40,110,114,101,113,116, 41, 10, - 32, 32, 32, 32, 45, 45, 32, 97,100,106,117,115,116, 32,104,101, 97,100,101,114, -115, 32,105,110, 32,114,101,113,117,101,115,116, 10, 32, 32, 32, 32,110,114,101, -113,116, 46,104,101, 97,100,101,114,115, 32, 61, 32, 97,100,106,117,115,116,104, -101, 97,100,101,114,115, 40,110,114,101,113,116, 41, 10, 32, 32, 32, 32,114,101, -116,117,114,110, 32,110,114,101,113,116, 10,101,110,100, 10, 10,108,111, 99, 97, -108, 32,102,117,110, 99,116,105,111,110, 32,115,104,111,117,108,100,114,101,100, -105,114,101, 99,116, 40,114,101,113,116, 44, 32, 99,111,100,101, 44, 32,104,101, - 97,100,101,114,115, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,104,101, - 97,100,101,114,115, 46,108,111, 99, 97,116,105,111,110, 32, 97,110,100, 10, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,116,114,105,110,103, 46,103,115,117, - 98, 40,104,101, 97,100,101,114,115, 46,108,111, 99, 97,116,105,111,110, 44, 32, - 34, 37,115, 34, 44, 32, 34, 34, 41, 32,126, 61, 32, 34, 34, 32, 97,110,100, 10, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40,114,101,113,116, 46,114,101,100, -105,114,101, 99,116, 32,126, 61, 32,102, 97,108,115,101, 41, 32, 97,110,100, 10, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 99,111,100,101, 32, 61, 61, 32, - 51, 48, 49, 32,111,114, 32, 99,111,100,101, 32, 61, 61, 32, 51, 48, 50, 41, 32, - 97,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40,110,111,116, 32, -114,101,113,116, 46,109,101,116,104,111,100, 32,111,114, 32,114,101,113,116, 46, -109,101,116,104,111,100, 32, 61, 61, 32, 34, 71, 69, 84, 34, 32,111,114, 32,114, -101,113,116, 46,109,101,116,104,111,100, 32, 61, 61, 32, 34, 72, 69, 65, 68, 34, - 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 97,110,100, 32, 40,110,111, -116, 32,114,101,113,116, 46,110,114,101,100,105,114,101, 99,116,115, 32,111,114, - 32,114,101,113,116, 46,110,114,101,100,105,114,101, 99,116,115, 32, 60, 32, 53, - 41, 10,101,110,100, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111, -110, 32,115,104,111,117,108,100,114,101, 99,101,105,118,101, 98,111,100,121, 40, -114,101,113,116, 44, 32, 99,111,100,101, 41, 10, 32, 32, 32, 32,105,102, 32,114, -101,113,116, 46,109,101,116,104,111,100, 32, 61, 61, 32, 34, 72, 69, 65, 68, 34, - 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 32,101,110,100, - 10, 32, 32, 32, 32,105,102, 32, 99,111,100,101, 32, 61, 61, 32, 50, 48, 52, 32, -111,114, 32, 99,111,100,101, 32, 61, 61, 32, 51, 48, 52, 32,116,104,101,110, 32, -114,101,116,117,114,110, 32,110,105,108, 32,101,110,100, 10, 32, 32, 32, 32,105, -102, 32, 99,111,100,101, 32, 62, 61, 32, 49, 48, 48, 32, 97,110,100, 32, 99,111, -100,101, 32, 60, 32, 50, 48, 48, 32,116,104,101,110, 32,114,101,116,117,114,110, - 32,110,105,108, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, - 49, 10,101,110,100, 10, 10, 45, 45, 32,102,111,114,119, 97,114,100, 32,100,101, - 99,108, 97,114, 97,116,105,111,110,115, 10,108,111, 99, 97,108, 32,116,114,101, -113,117,101,115,116, 44, 32,116,114,101,100,105,114,101, 99,116, 10, 10,102,117, -110, 99,116,105,111,110, 32,116,114,101,100,105,114,101, 99,116, 40,114,101,113, -116, 44, 32,108,111, 99, 97,116,105,111,110, 41, 10, 32, 32, 32, 32,108,111, 99, - 97,108, 32,114,101,115,117,108,116, 44, 32, 99,111,100,101, 44, 32,104,101, 97, -100,101,114,115, 44, 32,115,116, 97,116,117,115, 32, 61, 32,116,114,101,113,117, -101,115,116, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,116,104,101, - 32, 82, 70, 67, 32,115, 97,121,115, 32,116,104,101, 32,114,101,100,105,114,101, - 99,116, 32, 85, 82, 76, 32,104, 97,115, 32,116,111, 32, 98,101, 32, 97, 98,115, -111,108,117,116,101, 44, 32, 98,117,116, 32,115,111,109,101, 10, 32, 32, 32, 32, - 32, 32, 32, 32, 45, 45, 32,115,101,114,118,101,114,115, 32,100,111, 32,110,111, -116, 32,114,101,115,112,101, 99,116, 32,116,104, 97,116, 10, 32, 32, 32, 32, 32, - 32, 32, 32,117,114,108, 32, 61, 32,117,114,108, 46, 97, 98,115,111,108,117,116, -101, 40,114,101,113,116, 46,117,114,108, 44, 32,108,111, 99, 97,116,105,111,110, - 41, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,111,117,114, 99,101, 32, 61, 32, -114,101,113,116, 46,115,111,117,114, 99,101, 44, 10, 32, 32, 32, 32, 32, 32, 32, - 32,115,105,110,107, 32, 61, 32,114,101,113,116, 46,115,105,110,107, 44, 10, 32, - 32, 32, 32, 32, 32, 32, 32,104,101, 97,100,101,114,115, 32, 61, 32,114,101,113, -116, 46,104,101, 97,100,101,114,115, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,112, -114,111,120,121, 32, 61, 32,114,101,113,116, 46,112,114,111,120,121, 44, 32, 10, - 32, 32, 32, 32, 32, 32, 32, 32,110,114,101,100,105,114,101, 99,116,115, 32, 61, - 32, 40,114,101,113,116, 46,110,114,101,100,105,114,101, 99,116,115, 32,111,114, - 32, 48, 41, 32, 43, 32, 49, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99,114,101, - 97,116,101, 32, 61, 32,114,101,113,116, 46, 99,114,101, 97,116,101, 10, 32, 32, - 32, 32,125, 32, 32, 32, 10, 32, 32, 32, 32, 45, 45, 32,112, 97,115,115, 32,108, -111, 99, 97,116,105,111,110, 32,104,101, 97,100,101,114, 32, 98, 97, 99,107, 32, - 97,115, 32, 97, 32,104,105,110,116, 32,119,101, 32,114,101,100,105,114,101, 99, -116,101,100, 10, 32, 32, 32, 32,104,101, 97,100,101,114,115, 32, 61, 32,104,101, - 97,100,101,114,115, 32,111,114, 32,123,125, 10, 32, 32, 32, 32,104,101, 97,100, -101,114,115, 46,108,111, 99, 97,116,105,111,110, 32, 61, 32,104,101, 97,100,101, -114,115, 46,108,111, 99, 97,116,105,111,110, 32,111,114, 32,108,111, 99, 97,116, -105,111,110, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,114,101,115,117,108, -116, 44, 32, 99,111,100,101, 44, 32,104,101, 97,100,101,114,115, 44, 32,115,116, - 97,116,117,115, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,116, -114,101,113,117,101,115,116, 40,114,101,113,116, 41, 10, 32, 32, 32, 32, 45, 45, - 32,119,101, 32,108,111,111,112, 32,117,110,116,105,108, 32,119,101, 32,103,101, -116, 32,119,104, 97,116, 32,119,101, 32,119, 97,110,116, 44, 32,111,114, 10, 32, - 32, 32, 32, 45, 45, 32,117,110,116,105,108, 32,119,101, 32, 97,114,101, 32,115, -117,114,101, 32,116,104,101,114,101, 32,105,115, 32,110,111, 32,119, 97,121, 32, -116,111, 32,103,101,116, 32,105,116, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, -110,114,101,113,116, 32, 61, 32, 97,100,106,117,115,116,114,101,113,117,101,115, -116, 40,114,101,113,116, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104, 32, - 61, 32,111,112,101,110, 40,110,114,101,113,116, 46,104,111,115,116, 44, 32,110, -114,101,113,116, 46,112,111,114,116, 44, 32,110,114,101,113,116, 46, 99,114,101, - 97,116,101, 41, 10, 32, 32, 32, 32, 45, 45, 32,115,101,110,100, 32,114,101,113, -117,101,115,116, 32,108,105,110,101, 32, 97,110,100, 32,104,101, 97,100,101,114, -115, 10, 32, 32, 32, 32,104, 58,115,101,110,100,114,101,113,117,101,115,116,108, -105,110,101, 40,110,114,101,113,116, 46,109,101,116,104,111,100, 44, 32,110,114, -101,113,116, 46,117,114,105, 41, 10, 32, 32, 32, 32,104, 58,115,101,110,100,104, -101, 97,100,101,114,115, 40,110,114,101,113,116, 46,104,101, 97,100,101,114,115, - 41, 10, 32, 32, 32, 32, 45, 45, 32,105,102, 32,116,104,101,114,101, 32,105,115, - 32, 97, 32, 98,111,100,121, 44, 32,115,101,110,100, 32,105,116, 10, 32, 32, 32, - 32,105,102, 32,110,114,101,113,116, 46,115,111,117,114, 99,101, 32,116,104,101, -110, 10, 32, 32, 32, 32, 32, 32, 32, 32,104, 58,115,101,110,100, 98,111,100,121, - 40,110,114,101,113,116, 46,104,101, 97,100,101,114,115, 44, 32,110,114,101,113, -116, 46,115,111,117,114, 99,101, 44, 32,110,114,101,113,116, 46,115,116,101,112, - 41, 32, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, - 32, 99,111,100,101, 44, 32,115,116, 97,116,117,115, 32, 61, 32,104, 58,114,101, - 99,101,105,118,101,115,116, 97,116,117,115,108,105,110,101, 40, 41, 10, 32, 32, - 32, 32, 45, 45, 32,105,102, 32,105,116, 32,105,115, 32, 97,110, 32, 72, 84, 84, - 80, 47, 48, 46, 57, 32,115,101,114,118,101,114, 44, 32,115,105,109,112,108,121, - 32,103,101,116, 32,116,104,101, 32, 98,111,100,121, 32, 97,110,100, 32,119,101, - 32, 97,114,101, 32,100,111,110,101, 10, 32, 32, 32, 32,105,102, 32,110,111,116, - 32, 99,111,100,101, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,104, - 58,114,101, 99,101,105,118,101, 48, 57, 98,111,100,121, 40,115,116, 97,116,117, -115, 44, 32,110,114,101,113,116, 46,115,105,110,107, 44, 32,110,114,101,113,116, - 46,115,116,101,112, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114, -110, 32, 49, 44, 32, 50, 48, 48, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, - 32,108,111, 99, 97,108, 32,104,101, 97,100,101,114,115, 10, 32, 32, 32, 32, 45, - 45, 32,105,103,110,111,114,101, 32, 97,110,121, 32, 49, 48, 48, 45, 99,111,110, -116,105,110,117,101, 32,109,101,115,115, 97,103,101,115, 10, 32, 32, 32, 32,119, -104,105,108,101, 32, 99,111,100,101, 32, 61, 61, 32, 49, 48, 48, 32,100,111, 32, - 10, 32, 32, 32, 32, 32, 32, 32, 32,104,101, 97,100,101,114,115, 32, 61, 32,104, - 58,114,101, 99,101,105,118,101,104,101, 97,100,101,114,115, 40, 41, 10, 32, 32, - 32, 32, 32, 32, 32, 32, 99,111,100,101, 44, 32,115,116, 97,116,117,115, 32, 61, +115,104,111,117,108,100,114,101,100,105,114,101, 99,116, 40,114,101,113,116, 44, + 32, 99,111,100,101, 44, 32,104,101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32, +108,111, 99, 97,108, 32,108,111, 99, 97,116,105,111,110, 32, 61, 32,104,101, 97, +100,101,114,115, 46,108,111, 99, 97,116,105,111,110, 10, 32, 32, 32, 32,105,102, + 32,110,111,116, 32,108,111, 99, 97,116,105,111,110, 32,116,104,101,110, 32,114, +101,116,117,114,110, 32,102, 97,108,115,101, 32,101,110,100, 10, 32, 32, 32, 32, +108,111, 99, 97,116,105,111,110, 32, 61, 32,115,116,114,105,110,103, 46,103,115, +117, 98, 40,108,111, 99, 97,116,105,111,110, 44, 32, 34, 37,115, 34, 44, 32, 34, + 34, 41, 10, 32, 32, 32, 32,105,102, 32,108,111, 99, 97,116,105,111,110, 32, 61, + 61, 32, 34, 34, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,102, 97,108, +115,101, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115, 99,104, +101,109,101, 32, 61, 32,115,116,114,105,110,103, 46,109, 97,116, 99,104, 40,108, +111, 99, 97,116,105,111,110, 44, 32, 34, 94, 40, 91, 37,119, 93, 91, 37,119, 37, + 43, 37, 45, 37, 46, 93, 42, 41, 37, 58, 34, 41, 10, 32, 32, 32, 32,105,102, 32, +115, 99,104,101,109,101, 32, 97,110,100, 32,110,111,116, 32, 83, 67, 72, 69, 77, + 69, 83, 91,115, 99,104,101,109,101, 93, 32,116,104,101,110, 32,114,101,116,117, +114,110, 32,102, 97,108,115,101, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116, +117,114,110, 32, 40,114,101,113,116, 46,114,101,100,105,114,101, 99,116, 32,126, + 61, 32,102, 97,108,115,101, 41, 32, 97,110,100, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 40, 99,111,100,101, 32, 61, 61, 32, 51, 48, 49, 32,111,114, 32, + 99,111,100,101, 32, 61, 61, 32, 51, 48, 50, 32,111,114, 32, 99,111,100,101, 32, + 61, 61, 32, 51, 48, 51, 32,111,114, 32, 99,111,100,101, 32, 61, 61, 32, 51, 48, + 55, 41, 32, 97,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40,110, +111,116, 32,114,101,113,116, 46,109,101,116,104,111,100, 32,111,114, 32,114,101, +113,116, 46,109,101,116,104,111,100, 32, 61, 61, 32, 34, 71, 69, 84, 34, 32,111, +114, 32,114,101,113,116, 46,109,101,116,104,111,100, 32, 61, 61, 32, 34, 72, 69, + 65, 68, 34, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 97,110,100, 32, + 40,110,111,116, 32,114,101,113,116, 46,110,114,101,100,105,114,101, 99,116,115, + 32,111,114, 32,114,101,113,116, 46,110,114,101,100,105,114,101, 99,116,115, 32, + 60, 32, 53, 41, 10,101,110,100, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99, +116,105,111,110, 32,115,104,111,117,108,100,114,101, 99,101,105,118,101, 98,111, +100,121, 40,114,101,113,116, 44, 32, 99,111,100,101, 41, 10, 32, 32, 32, 32,105, +102, 32,114,101,113,116, 46,109,101,116,104,111,100, 32, 61, 61, 32, 34, 72, 69, + 65, 68, 34, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 32, +101,110,100, 10, 32, 32, 32, 32,105,102, 32, 99,111,100,101, 32, 61, 61, 32, 50, + 48, 52, 32,111,114, 32, 99,111,100,101, 32, 61, 61, 32, 51, 48, 52, 32,116,104, +101,110, 32,114,101,116,117,114,110, 32,110,105,108, 32,101,110,100, 10, 32, 32, + 32, 32,105,102, 32, 99,111,100,101, 32, 62, 61, 32, 49, 48, 48, 32, 97,110,100, + 32, 99,111,100,101, 32, 60, 32, 50, 48, 48, 32,116,104,101,110, 32,114,101,116, +117,114,110, 32,110,105,108, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117, +114,110, 32, 49, 10,101,110,100, 10, 10, 45, 45, 32,102,111,114,119, 97,114,100, + 32,100,101, 99,108, 97,114, 97,116,105,111,110,115, 10,108,111, 99, 97,108, 32, +116,114,101,113,117,101,115,116, 44, 32,116,114,101,100,105,114,101, 99,116, 10, + 10, 45, 45, 91, 91,108,111, 99, 97,108, 93, 93, 32,102,117,110, 99,116,105,111, +110, 32,116,114,101,100,105,114,101, 99,116, 40,114,101,113,116, 44, 32,108,111, + 99, 97,116,105,111,110, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101, +115,117,108,116, 44, 32, 99,111,100,101, 44, 32,104,101, 97,100,101,114,115, 44, + 32,115,116, 97,116,117,115, 32, 61, 32,116,114,101,113,117,101,115,116, 32,123, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,116,104,101, 32, 82, 70, 67, 32, +115, 97,121,115, 32,116,104,101, 32,114,101,100,105,114,101, 99,116, 32, 85, 82, + 76, 32,104, 97,115, 32,116,111, 32, 98,101, 32, 97, 98,115,111,108,117,116,101, + 44, 32, 98,117,116, 32,115,111,109,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, + 45, 32,115,101,114,118,101,114,115, 32,100,111, 32,110,111,116, 32,114,101,115, +112,101, 99,116, 32,116,104, 97,116, 10, 32, 32, 32, 32, 32, 32, 32, 32,117,114, +108, 32, 61, 32,117,114,108, 46, 97, 98,115,111,108,117,116,101, 40,114,101,113, +116, 46,117,114,108, 44, 32,108,111, 99, 97,116,105,111,110, 41, 44, 10, 32, 32, + 32, 32, 32, 32, 32, 32,115,111,117,114, 99,101, 32, 61, 32,114,101,113,116, 46, +115,111,117,114, 99,101, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,105,110,107, + 32, 61, 32,114,101,113,116, 46,115,105,110,107, 44, 10, 32, 32, 32, 32, 32, 32, + 32, 32,104,101, 97,100,101,114,115, 32, 61, 32,114,101,113,116, 46,104,101, 97, +100,101,114,115, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,112,114,111,120,121, 32, + 61, 32,114,101,113,116, 46,112,114,111,120,121, 44, 10, 32, 32, 32, 32, 32, 32, + 32, 32,110,114,101,100,105,114,101, 99,116,115, 32, 61, 32, 40,114,101,113,116, + 46,110,114,101,100,105,114,101, 99,116,115, 32,111,114, 32, 48, 41, 32, 43, 32, + 49, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99,114,101, 97,116,101, 32, 61, 32, +114,101,113,116, 46, 99,114,101, 97,116,101, 10, 32, 32, 32, 32,125, 10, 32, 32, + 32, 32, 45, 45, 32,112, 97,115,115, 32,108,111, 99, 97,116,105,111,110, 32,104, +101, 97,100,101,114, 32, 98, 97, 99,107, 32, 97,115, 32, 97, 32,104,105,110,116, + 32,119,101, 32,114,101,100,105,114,101, 99,116,101,100, 10, 32, 32, 32, 32,104, +101, 97,100,101,114,115, 32, 61, 32,104,101, 97,100,101,114,115, 32,111,114, 32, +123,125, 10, 32, 32, 32, 32,104,101, 97,100,101,114,115, 46,108,111, 99, 97,116, +105,111,110, 32, 61, 32,104,101, 97,100,101,114,115, 46,108,111, 99, 97,116,105, +111,110, 32,111,114, 32,108,111, 99, 97,116,105,111,110, 10, 32, 32, 32, 32,114, +101,116,117,114,110, 32,114,101,115,117,108,116, 44, 32, 99,111,100,101, 44, 32, +104,101, 97,100,101,114,115, 44, 32,115,116, 97,116,117,115, 10,101,110,100, 10, + 10, 45, 45, 91, 91,108,111, 99, 97,108, 93, 93, 32,102,117,110, 99,116,105,111, +110, 32,116,114,101,113,117,101,115,116, 40,114,101,113,116, 41, 10, 32, 32, 32, + 32, 45, 45, 32,119,101, 32,108,111,111,112, 32,117,110,116,105,108, 32,119,101, + 32,103,101,116, 32,119,104, 97,116, 32,119,101, 32,119, 97,110,116, 44, 32,111, +114, 10, 32, 32, 32, 32, 45, 45, 32,117,110,116,105,108, 32,119,101, 32, 97,114, +101, 32,115,117,114,101, 32,116,104,101,114,101, 32,105,115, 32,110,111, 32,119, + 97,121, 32,116,111, 32,103,101,116, 32,105,116, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,110,114,101,113,116, 32, 61, 32, 97,100,106,117,115,116,114,101,113, +117,101,115,116, 40,114,101,113,116, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, + 32,104, 32, 61, 32, 95, 77, 46,111,112,101,110, 40,110,114,101,113,116, 46,104, +111,115,116, 44, 32,110,114,101,113,116, 46,112,111,114,116, 44, 32,110,114,101, +113,116, 46, 99,114,101, 97,116,101, 41, 10, 32, 32, 32, 32, 45, 45, 32,115,101, +110,100, 32,114,101,113,117,101,115,116, 32,108,105,110,101, 32, 97,110,100, 32, +104,101, 97,100,101,114,115, 10, 32, 32, 32, 32,104, 58,115,101,110,100,114,101, +113,117,101,115,116,108,105,110,101, 40,110,114,101,113,116, 46,109,101,116,104, +111,100, 44, 32,110,114,101,113,116, 46,117,114,105, 41, 10, 32, 32, 32, 32,104, + 58,115,101,110,100,104,101, 97,100,101,114,115, 40,110,114,101,113,116, 46,104, +101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32, 45, 45, 32,105,102, 32,116,104, +101,114,101, 32,105,115, 32, 97, 32, 98,111,100,121, 44, 32,115,101,110,100, 32, +105,116, 10, 32, 32, 32, 32,105,102, 32,110,114,101,113,116, 46,115,111,117,114, + 99,101, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,104, 58,115,101, +110,100, 98,111,100,121, 40,110,114,101,113,116, 46,104,101, 97,100,101,114,115, + 44, 32,110,114,101,113,116, 46,115,111,117,114, 99,101, 44, 32,110,114,101,113, +116, 46,115,116,101,112, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, +108,111, 99, 97,108, 32, 99,111,100,101, 44, 32,115,116, 97,116,117,115, 32, 61, 32,104, 58,114,101, 99,101,105,118,101,115,116, 97,116,117,115,108,105,110,101, - 40, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,104,101, 97,100,101, -114,115, 32, 61, 32,104, 58,114,101, 99,101,105,118,101,104,101, 97,100,101,114, -115, 40, 41, 10, 32, 32, 32, 32, 45, 45, 32, 97,116, 32,116,104,105,115, 32,112, -111,105,110,116, 32,119,101, 32,115,104,111,117,108,100, 32,104, 97,118,101, 32, - 97, 32,104,111,110,101,115,116, 32,114,101,112,108,121, 32,102,114,111,109, 32, -116,104,101, 32,115,101,114,118,101,114, 10, 32, 32, 32, 32, 45, 45, 32,119,101, - 32, 99, 97,110, 39,116, 32,114,101,100,105,114,101, 99,116, 32,105,102, 32,119, -101, 32, 97,108,114,101, 97,100,121, 32,117,115,101,100, 32,116,104,101, 32,115, -111,117,114, 99,101, 44, 32,115,111, 32,119,101, 32,114,101,112,111,114,116, 32, -116,104,101, 32,101,114,114,111,114, 32, 10, 32, 32, 32, 32,105,102, 32,115,104, -111,117,108,100,114,101,100,105,114,101, 99,116, 40,110,114,101,113,116, 44, 32, - 99,111,100,101, 44, 32,104,101, 97,100,101,114,115, 41, 32, 97,110,100, 32,110, -111,116, 32,110,114,101,113,116, 46,115,111,117,114, 99,101, 32,116,104,101,110, - 10, 32, 32, 32, 32, 32, 32, 32, 32,104, 58, 99,108,111,115,101, 40, 41, 10, 32, - 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,116,114,101,100,105,114, -101, 99,116, 40,114,101,113,116, 44, 32,104,101, 97,100,101,114,115, 46,108,111, - 99, 97,116,105,111,110, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, - 45, 45, 32,104,101,114,101, 32,119,101, 32, 97,114,101, 32,102,105,110, 97,108, -108,121, 32,100,111,110,101, 10, 32, 32, 32, 32,105,102, 32,115,104,111,117,108, -100,114,101, 99,101,105,118,101, 98,111,100,121, 40,110,114,101,113,116, 44, 32, - 99,111,100,101, 41, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,104, - 58,114,101, 99,101,105,118,101, 98,111,100,121, 40,104,101, 97,100,101,114,115, - 44, 32,110,114,101,113,116, 46,115,105,110,107, 44, 32,110,114,101,113,116, 46, -115,116,101,112, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,104, 58, - 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, - 44, 32, 99,111,100,101, 44, 32,104,101, 97,100,101,114,115, 44, 32,115,116, 97, -116,117,115, 10,101,110,100, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116, -105,111,110, 32,115,114,101,113,117,101,115,116, 40,117, 44, 32, 98, 41, 10, 32, - 32, 32, 32,108,111, 99, 97,108, 32,116, 32, 61, 32,123,125, 10, 32, 32, 32, 32, -108,111, 99, 97,108, 32,114,101,113,116, 32, 61, 32,123, 10, 32, 32, 32, 32, 32, - 32, 32, 32,117,114,108, 32, 61, 32,117, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, -115,105,110,107, 32, 61, 32,108,116,110, 49, 50, 46,115,105,110,107, 46,116, 97, - 98,108,101, 40,116, 41, 10, 32, 32, 32, 32,125, 10, 32, 32, 32, 32,105,102, 32, - 98, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,113,116, 46, -115,111,117,114, 99,101, 32, 61, 32,108,116,110, 49, 50, 46,115,111,117,114, 99, -101, 46,115,116,114,105,110,103, 40, 98, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, -114,101,113,116, 46,104,101, 97,100,101,114,115, 32, 61, 32,123, 10, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 91, 34, 99,111,110,116,101,110,116, 45,108, -101,110,103,116,104, 34, 93, 32, 61, 32,115,116,114,105,110,103, 46,108,101,110, - 40, 98, 41, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 91, 34, 99, -111,110,116,101,110,116, 45,116,121,112,101, 34, 93, 32, 61, 32, 34, 97,112,112, -108,105, 99, 97,116,105,111,110, 47,120, 45,119,119,119, 45,102,111,114,109, 45, -117,114,108,101,110, 99,111,100,101,100, 34, 10, 32, 32, 32, 32, 32, 32, 32, 32, -125, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,113,116, 46,109,101,116,104,111, -100, 32, 61, 32, 34, 80, 79, 83, 84, 34, 10, 32, 32, 32, 32,101,110,100, 10, 32, - 32, 32, 32,108,111, 99, 97,108, 32, 99,111,100,101, 44, 32,104,101, 97,100,101, -114,115, 44, 32,115,116, 97,116,117,115, 32, 61, 32,115,111, 99,107,101,116, 46, -115,107,105,112, 40, 49, 44, 32,116,114,101,113,117,101,115,116, 40,114,101,113, -116, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,116, 97, 98,108,101, - 46, 99,111,110, 99, 97,116, 40,116, 41, 44, 32, 99,111,100,101, 44, 32,104,101, - 97,100,101,114,115, 44, 32,115,116, 97,116,117,115, 10,101,110,100, 10, 10,114, -101,113,117,101,115,116, 32, 61, 32,115,111, 99,107,101,116, 46,112,114,111,116, -101, 99,116, 40,102,117,110, 99,116,105,111,110, 40,114,101,113,116, 44, 32, 98, -111,100,121, 41, 10, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46,116,121,112, -101, 40,114,101,113,116, 41, 32, 61, 61, 32, 34,115,116,114,105,110,103, 34, 32, -116,104,101,110, 32,114,101,116,117,114,110, 32,115,114,101,113,117,101,115,116, - 40,114,101,113,116, 44, 32, 98,111,100,121, 41, 10, 32, 32, 32, 32,101,108,115, -101, 32,114,101,116,117,114,110, 32,116,114,101,113,117,101,115,116, 40,114,101, -113,116, 41, 32,101,110,100, 10,101,110,100, 41, 10, + 40, 41, 10, 32, 32, 32, 32, 45, 45, 32,105,102, 32,105,116, 32,105,115, 32, 97, +110, 32, 72, 84, 84, 80, 47, 48, 46, 57, 32,115,101,114,118,101,114, 44, 32,115, +105,109,112,108,121, 32,103,101,116, 32,116,104,101, 32, 98,111,100,121, 32, 97, +110,100, 32,119,101, 32, 97,114,101, 32,100,111,110,101, 10, 32, 32, 32, 32,105, +102, 32,110,111,116, 32, 99,111,100,101, 32,116,104,101,110, 10, 32, 32, 32, 32, + 32, 32, 32, 32,104, 58,114,101, 99,101,105,118,101, 48, 57, 98,111,100,121, 40, +115,116, 97,116,117,115, 44, 32,110,114,101,113,116, 46,115,105,110,107, 44, 32, +110,114,101,113,116, 46,115,116,101,112, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, +114,101,116,117,114,110, 32, 49, 44, 32, 50, 48, 48, 10, 32, 32, 32, 32,101,110, +100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104,101, 97,100,101,114,115, 10, + 32, 32, 32, 32, 45, 45, 32,105,103,110,111,114,101, 32, 97,110,121, 32, 49, 48, + 48, 45, 99,111,110,116,105,110,117,101, 32,109,101,115,115, 97,103,101,115, 10, + 32, 32, 32, 32,119,104,105,108,101, 32, 99,111,100,101, 32, 61, 61, 32, 49, 48, + 48, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32,104,101, 97,100,101,114,115, + 32, 61, 32,104, 58,114,101, 99,101,105,118,101,104,101, 97,100,101,114,115, 40, + 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99,111,100,101, 44, 32,115,116, 97,116, +117,115, 32, 61, 32,104, 58,114,101, 99,101,105,118,101,115,116, 97,116,117,115, +108,105,110,101, 40, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,104, +101, 97,100,101,114,115, 32, 61, 32,104, 58,114,101, 99,101,105,118,101,104,101, + 97,100,101,114,115, 40, 41, 10, 32, 32, 32, 32, 45, 45, 32, 97,116, 32,116,104, +105,115, 32,112,111,105,110,116, 32,119,101, 32,115,104,111,117,108,100, 32,104, + 97,118,101, 32, 97, 32,104,111,110,101,115,116, 32,114,101,112,108,121, 32,102, +114,111,109, 32,116,104,101, 32,115,101,114,118,101,114, 10, 32, 32, 32, 32, 45, + 45, 32,119,101, 32, 99, 97,110, 39,116, 32,114,101,100,105,114,101, 99,116, 32, +105,102, 32,119,101, 32, 97,108,114,101, 97,100,121, 32,117,115,101,100, 32,116, +104,101, 32,115,111,117,114, 99,101, 44, 32,115,111, 32,119,101, 32,114,101,112, +111,114,116, 32,116,104,101, 32,101,114,114,111,114, 10, 32, 32, 32, 32,105,102, + 32,115,104,111,117,108,100,114,101,100,105,114,101, 99,116, 40,110,114,101,113, +116, 44, 32, 99,111,100,101, 44, 32,104,101, 97,100,101,114,115, 41, 32, 97,110, +100, 32,110,111,116, 32,110,114,101,113,116, 46,115,111,117,114, 99,101, 32,116, +104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,104, 58, 99,108,111,115,101, 40, + 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,116,114,101, +100,105,114,101, 99,116, 40,114,101,113,116, 44, 32,104,101, 97,100,101,114,115, + 46,108,111, 99, 97,116,105,111,110, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, + 32, 32, 32, 45, 45, 32,104,101,114,101, 32,119,101, 32, 97,114,101, 32,102,105, +110, 97,108,108,121, 32,100,111,110,101, 10, 32, 32, 32, 32,105,102, 32,115,104, +111,117,108,100,114,101, 99,101,105,118,101, 98,111,100,121, 40,110,114,101,113, +116, 44, 32, 99,111,100,101, 41, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, + 32, 32,104, 58,114,101, 99,101,105,118,101, 98,111,100,121, 40,104,101, 97,100, +101,114,115, 44, 32,110,114,101,113,116, 46,115,105,110,107, 44, 32,110,114,101, +113,116, 46,115,116,101,112, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, + 32,104, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114, +110, 32, 49, 44, 32, 99,111,100,101, 44, 32,104,101, 97,100,101,114,115, 44, 32, +115,116, 97,116,117,115, 10,101,110,100, 10, 10, 45, 45, 32,116,117,114,110,115, + 32, 97,110, 32,117,114,108, 32, 97,110,100, 32, 97, 32, 98,111,100,121, 32,105, +110,116,111, 32, 97, 32,103,101,110,101,114,105, 99, 32,114,101,113,117,101,115, +116, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,103,101,110, +101,114,105, 99,102,111,114,109, 40,117, 44, 32, 98, 41, 10, 32, 32, 32, 32,108, +111, 99, 97,108, 32,116, 32, 61, 32,123,125, 10, 32, 32, 32, 32,108,111, 99, 97, +108, 32,114,101,113,116, 32, 61, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,117, +114,108, 32, 61, 32,117, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,105,110,107, + 32, 61, 32,108,116,110, 49, 50, 46,115,105,110,107, 46,116, 97, 98,108,101, 40, +116, 41, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,116, 97,114,103,101,116, 32, 61, + 32,116, 10, 32, 32, 32, 32,125, 10, 32, 32, 32, 32,105,102, 32, 98, 32,116,104, +101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,113,116, 46,115,111,117,114, + 99,101, 32, 61, 32,108,116,110, 49, 50, 46,115,111,117,114, 99,101, 46,115,116, +114,105,110,103, 40, 98, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,113,116, + 46,104,101, 97,100,101,114,115, 32, 61, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 91, 34, 99,111,110,116,101,110,116, 45,108,101,110,103,116, +104, 34, 93, 32, 61, 32,115,116,114,105,110,103, 46,108,101,110, 40, 98, 41, 44, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 91, 34, 99,111,110,116,101, +110,116, 45,116,121,112,101, 34, 93, 32, 61, 32, 34, 97,112,112,108,105, 99, 97, +116,105,111,110, 47,120, 45,119,119,119, 45,102,111,114,109, 45,117,114,108,101, +110, 99,111,100,101,100, 34, 10, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 32, 32, + 32, 32, 32, 32, 32, 32,114,101,113,116, 46,109,101,116,104,111,100, 32, 61, 32, + 34, 80, 79, 83, 84, 34, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,114, +101,116,117,114,110, 32,114,101,113,116, 10,101,110,100, 10, 10, 95, 77, 46,103, +101,110,101,114,105, 99,102,111,114,109, 32, 61, 32,103,101,110,101,114,105, 99, +102,111,114,109, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, + 32,115,114,101,113,117,101,115,116, 40,117, 44, 32, 98, 41, 10, 32, 32, 32, 32, +108,111, 99, 97,108, 32,114,101,113,116, 32, 61, 32,103,101,110,101,114,105, 99, +102,111,114,109, 40,117, 44, 32, 98, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, + 32, 95, 44, 32, 99,111,100,101, 44, 32,104,101, 97,100,101,114,115, 44, 32,115, +116, 97,116,117,115, 32, 61, 32,116,114,101,113,117,101,115,116, 40,114,101,113, +116, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,116, 97, 98,108,101, 46, + 99,111,110, 99, 97,116, 40,114,101,113,116, 46,116, 97,114,103,101,116, 41, 44, + 32, 99,111,100,101, 44, 32,104,101, 97,100,101,114,115, 44, 32,115,116, 97,116, +117,115, 10,101,110,100, 10, 10, 95, 77, 46,114,101,113,117,101,115,116, 32, 61, + 32,115,111, 99,107,101,116, 46,112,114,111,116,101, 99,116, 40,102,117,110, 99, +116,105,111,110, 40,114,101,113,116, 44, 32, 98,111,100,121, 41, 10, 32, 32, 32, + 32,105,102, 32, 98, 97,115,101, 46,116,121,112,101, 40,114,101,113,116, 41, 32, + 61, 61, 32, 34,115,116,114,105,110,103, 34, 32,116,104,101,110, 32,114,101,116, +117,114,110, 32,115,114,101,113,117,101,115,116, 40,114,101,113,116, 44, 32, 98, +111,100,121, 41, 10, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, + 32,116,114,101,113,117,101,115,116, 40,114,101,113,116, 41, 32,101,110,100, 10, +101,110,100, 41, 10, 10,114,101,116,117,114,110, 32, 95, 77, 10, }; - if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"http.lua")==0) lua_call(L, 0, 0); + if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"http.lua")==0) lua_call(L, 0, LUA_MULTRET); } diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/inet.c b/love/src/jni/love/src/libraries/luasocket/libluasocket/inet.c index dff84432..f4c84044 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/inet.c +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/inet.c @@ -1,31 +1,33 @@ /*=========================================================================*\ * Internet domain functions * LuaSocket toolkit -* -* RCS ID: $Id: inet.c,v 1.28 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ #include +#include #include #include "lua.h" #include "lauxlib.h" +#include "compat.h" #include "inet.h" -extern void luax_register(lua_State *L, const char *name, const luaL_Reg *l); - /*=========================================================================*\ * Internal function prototypes. \*=========================================================================*/ static int inet_global_toip(lua_State *L); +static int inet_global_getaddrinfo(lua_State *L); static int inet_global_tohostname(lua_State *L); +static int inet_global_getnameinfo(lua_State *L); static void inet_pushresolved(lua_State *L, struct hostent *hp); static int inet_global_gethostname(lua_State *L); /* DNS functions */ -static luaL_reg func[] = { - { "toip", inet_global_toip }, - { "tohostname", inet_global_tohostname }, +static luaL_Reg func[] = { + { "toip", inet_global_toip}, + { "getaddrinfo", inet_global_getaddrinfo}, + { "tohostname", inet_global_tohostname}, + { "getnameinfo", inet_global_getnameinfo}, { "gethostname", inet_global_gethostname}, { NULL, NULL} }; @@ -40,7 +42,7 @@ int inet_open(lua_State *L) { lua_pushstring(L, "dns"); lua_newtable(L); - luax_register(L, NULL, func); + luaL_setfuncs(L, func, 0); lua_settable(L, -3); return 0; } @@ -56,7 +58,7 @@ static int inet_gethost(const char *address, struct hostent **hp) { struct in_addr addr; if (inet_aton(address, &addr)) return socket_gethostbyaddr((char *) &addr, sizeof(addr), hp); - else + else return socket_gethostbyname(address, hp); } @@ -66,7 +68,7 @@ static int inet_gethost(const char *address, struct hostent **hp) { \*-------------------------------------------------------------------------*/ static int inet_global_tohostname(lua_State *L) { const char *address = luaL_checkstring(L, 1); - struct hostent *hp = NULL; + struct hostent *hp = NULL; int err = inet_gethost(address, &hp); if (err != IO_DONE) { lua_pushnil(L); @@ -78,6 +80,50 @@ static int inet_global_tohostname(lua_State *L) { return 2; } +static int inet_global_getnameinfo(lua_State *L) { + char hbuf[NI_MAXHOST]; + char sbuf[NI_MAXSERV]; + int i, ret; + struct addrinfo hints; + struct addrinfo *resolved, *iter; + const char *host = luaL_optstring(L, 1, NULL); + const char *serv = luaL_optstring(L, 2, NULL); + + if (!(host || serv)) + luaL_error(L, "host and serv cannot be both nil"); + + memset(&hints, 0, sizeof(hints)); + hints.ai_socktype = SOCK_STREAM; + hints.ai_family = AF_UNSPEC; + + ret = getaddrinfo(host, serv, &hints, &resolved); + if (ret != 0) { + lua_pushnil(L); + lua_pushstring(L, socket_gaistrerror(ret)); + return 2; + } + + lua_newtable(L); + for (i = 1, iter = resolved; iter; i++, iter = iter->ai_next) { + getnameinfo(iter->ai_addr, (socklen_t) iter->ai_addrlen, + hbuf, host? (socklen_t) sizeof(hbuf): 0, + sbuf, serv? (socklen_t) sizeof(sbuf): 0, 0); + if (host) { + lua_pushnumber(L, i); + lua_pushstring(L, hbuf); + lua_settable(L, -3); + } + } + freeaddrinfo(resolved); + + if (serv) { + lua_pushstring(L, sbuf); + return 2; + } else { + return 1; + } +} + /*-------------------------------------------------------------------------*\ * Returns all information provided by the resolver given a host name * or ip address @@ -85,7 +131,7 @@ static int inet_global_tohostname(lua_State *L) { static int inet_global_toip(lua_State *L) { const char *address = luaL_checkstring(L, 1); - struct hostent *hp = NULL; + struct hostent *hp = NULL; int err = inet_gethost(address, &hp); if (err != IO_DONE) { lua_pushnil(L); @@ -97,6 +143,81 @@ static int inet_global_toip(lua_State *L) return 2; } +int inet_optfamily(lua_State* L, int narg, const char* def) +{ + static const char* optname[] = { "unspec", "inet", "inet6", NULL }; + static int optvalue[] = { AF_UNSPEC, AF_INET, AF_INET6, 0 }; + + return optvalue[luaL_checkoption(L, narg, def, optname)]; +} + +int inet_optsocktype(lua_State* L, int narg, const char* def) +{ + static const char* optname[] = { "stream", "dgram", NULL }; + static int optvalue[] = { SOCK_STREAM, SOCK_DGRAM, 0 }; + + return optvalue[luaL_checkoption(L, narg, def, optname)]; +} + +static int inet_global_getaddrinfo(lua_State *L) +{ + const char *hostname = luaL_checkstring(L, 1); + struct addrinfo *iterator = NULL, *resolved = NULL; + struct addrinfo hints; + int i = 1, ret = 0; + memset(&hints, 0, sizeof(hints)); + hints.ai_socktype = SOCK_STREAM; + hints.ai_family = AF_UNSPEC; + ret = getaddrinfo(hostname, NULL, &hints, &resolved); + if (ret != 0) { + lua_pushnil(L); + lua_pushstring(L, socket_gaistrerror(ret)); + return 2; + } + lua_newtable(L); + for (iterator = resolved; iterator; iterator = iterator->ai_next) { + char hbuf[NI_MAXHOST]; + ret = getnameinfo(iterator->ai_addr, (socklen_t) iterator->ai_addrlen, + hbuf, (socklen_t) sizeof(hbuf), NULL, 0, NI_NUMERICHOST); + if (ret){ + freeaddrinfo(resolved); + lua_pushnil(L); + lua_pushstring(L, socket_gaistrerror(ret)); + return 2; + } + lua_pushnumber(L, i); + lua_newtable(L); + switch (iterator->ai_family) { + case AF_INET: + lua_pushliteral(L, "family"); + lua_pushliteral(L, "inet"); + lua_settable(L, -3); + break; + case AF_INET6: + lua_pushliteral(L, "family"); + lua_pushliteral(L, "inet6"); + lua_settable(L, -3); + break; + case AF_UNSPEC: + lua_pushliteral(L, "family"); + lua_pushliteral(L, "unspec"); + lua_settable(L, -3); + break; + default: + lua_pushliteral(L, "family"); + lua_pushliteral(L, "unknown"); + lua_settable(L, -3); + break; + } + lua_pushliteral(L, "addr"); + lua_pushstring(L, hbuf); + lua_settable(L, -3); + lua_settable(L, -3); + i++; + } + freeaddrinfo(resolved); + return 1; +} /*-------------------------------------------------------------------------*\ * Gets the host name @@ -107,7 +228,7 @@ static int inet_global_gethostname(lua_State *L) name[256] = '\0'; if (gethostname(name, 256) < 0) { lua_pushnil(L); - lua_pushstring(L, "gethostname failed"); + lua_pushstring(L, socket_strerror(errno)); return 2; } else { lua_pushstring(L, name); @@ -115,43 +236,74 @@ static int inet_global_gethostname(lua_State *L) } } - - /*=========================================================================*\ * Lua methods \*=========================================================================*/ /*-------------------------------------------------------------------------*\ * Retrieves socket peer name \*-------------------------------------------------------------------------*/ -int inet_meth_getpeername(lua_State *L, p_socket ps) +int inet_meth_getpeername(lua_State *L, p_socket ps, int family) { - struct sockaddr_in peer; + int err; + struct sockaddr_storage peer; socklen_t peer_len = sizeof(peer); + char name[INET6_ADDRSTRLEN]; + char port[6]; /* 65535 = 5 bytes + 0 to terminate it */ if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) { lua_pushnil(L); - lua_pushstring(L, "getpeername failed"); - } else { - lua_pushstring(L, inet_ntoa(peer.sin_addr)); - lua_pushnumber(L, ntohs(peer.sin_port)); + lua_pushstring(L, socket_strerror(errno)); + return 2; } - return 2; + err = getnameinfo((struct sockaddr *) &peer, peer_len, + name, INET6_ADDRSTRLEN, + port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV); + if (err) { + lua_pushnil(L); + lua_pushstring(L, gai_strerror(err)); + return 2; + } + lua_pushstring(L, name); + lua_pushinteger(L, (int) strtol(port, (char **) NULL, 10)); + switch (family) { + case AF_INET: lua_pushliteral(L, "inet"); break; + case AF_INET6: lua_pushliteral(L, "inet6"); break; + case AF_UNSPEC: lua_pushliteral(L, "unspec"); break; + default: lua_pushliteral(L, "unknown"); break; + } + return 3; } /*-------------------------------------------------------------------------*\ * Retrieves socket local name \*-------------------------------------------------------------------------*/ -int inet_meth_getsockname(lua_State *L, p_socket ps) +int inet_meth_getsockname(lua_State *L, p_socket ps, int family) { - struct sockaddr_in local; - socklen_t local_len = sizeof(local); - if (getsockname(*ps, (SA *) &local, &local_len) < 0) { + int err; + struct sockaddr_storage peer; + socklen_t peer_len = sizeof(peer); + char name[INET6_ADDRSTRLEN]; + char port[6]; /* 65535 = 5 bytes + 0 to terminate it */ + if (getsockname(*ps, (SA *) &peer, &peer_len) < 0) { lua_pushnil(L); - lua_pushstring(L, "getsockname failed"); - } else { - lua_pushstring(L, inet_ntoa(local.sin_addr)); - lua_pushnumber(L, ntohs(local.sin_port)); + lua_pushstring(L, socket_strerror(errno)); + return 2; } - return 2; + err=getnameinfo((struct sockaddr *)&peer, peer_len, + name, INET6_ADDRSTRLEN, port, 6, NI_NUMERICHOST | NI_NUMERICSERV); + if (err) { + lua_pushnil(L); + lua_pushstring(L, gai_strerror(err)); + return 2; + } + lua_pushstring(L, name); + lua_pushstring(L, port); + switch (family) { + case AF_INET: lua_pushliteral(L, "inet"); break; + case AF_INET6: lua_pushliteral(L, "inet6"); break; + case AF_UNSPEC: lua_pushliteral(L, "unspec"); break; + default: lua_pushliteral(L, "unknown"); break; + } + return 3; } /*=========================================================================*\ @@ -200,65 +352,151 @@ static void inet_pushresolved(lua_State *L, struct hostent *hp) /*-------------------------------------------------------------------------*\ * Tries to create a new inet socket \*-------------------------------------------------------------------------*/ -const char *inet_trycreate(p_socket ps, int type) { - return socket_strerror(socket_create(ps, AF_INET, type, 0)); +const char *inet_trycreate(p_socket ps, int family, int type, int protocol) { + const char *err = socket_strerror(socket_create(ps, family, type, protocol)); + if (err == NULL && family == AF_INET6) { + int yes = 1; + setsockopt(*ps, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&yes, sizeof(yes)); + } + return err; +} + +/*-------------------------------------------------------------------------*\ +* "Disconnects" a DGRAM socket +\*-------------------------------------------------------------------------*/ +const char *inet_trydisconnect(p_socket ps, int family, p_timeout tm) +{ + switch (family) { + case AF_INET: { + struct sockaddr_in sin; + memset((char *) &sin, 0, sizeof(sin)); + sin.sin_family = AF_UNSPEC; + sin.sin_addr.s_addr = INADDR_ANY; + return socket_strerror(socket_connect(ps, (SA *) &sin, + sizeof(sin), tm)); + } + case AF_INET6: { + struct sockaddr_in6 sin6; + struct in6_addr addrany = IN6ADDR_ANY_INIT; + memset((char *) &sin6, 0, sizeof(sin6)); + sin6.sin6_family = AF_UNSPEC; + sin6.sin6_addr = addrany; + return socket_strerror(socket_connect(ps, (SA *) &sin6, + sizeof(sin6), tm)); + } + } + return NULL; } /*-------------------------------------------------------------------------*\ * Tries to connect to remote address (address, port) \*-------------------------------------------------------------------------*/ -const char *inet_tryconnect(p_socket ps, const char *address, - unsigned short port, p_timeout tm) +const char *inet_tryconnect(p_socket ps, int *family, const char *address, + const char *serv, p_timeout tm, struct addrinfo *connecthints) { - struct sockaddr_in remote; - int err; - memset(&remote, 0, sizeof(remote)); - remote.sin_family = AF_INET; - remote.sin_port = htons(port); - if (strcmp(address, "*")) { - if (!inet_aton(address, &remote.sin_addr)) { - struct hostent *hp = NULL; - struct in_addr **addr; - err = socket_gethostbyname(address, &hp); - if (err != IO_DONE) return socket_hoststrerror(err); - addr = (struct in_addr **) hp->h_addr_list; - memcpy(&remote.sin_addr, *addr, sizeof(struct in_addr)); + struct addrinfo *iterator = NULL, *resolved = NULL; + const char *err = NULL; + int current_family = *family; + /* try resolving */ + err = socket_gaistrerror(getaddrinfo(address, serv, + connecthints, &resolved)); + if (err != NULL) { + if (resolved) freeaddrinfo(resolved); + return err; + } + for (iterator = resolved; iterator; iterator = iterator->ai_next) { + timeout_markstart(tm); + /* create new socket if necessary. if there was no + * bind, we need to create one for every new family + * that shows up while iterating. if there was a + * bind, all families will be the same and we will + * not enter this branch. */ + if (current_family != iterator->ai_family || *ps == SOCKET_INVALID) { + socket_destroy(ps); + err = inet_trycreate(ps, iterator->ai_family, + iterator->ai_socktype, iterator->ai_protocol); + if (err) continue; + current_family = iterator->ai_family; + /* set non-blocking before connect */ + socket_setnonblocking(ps); } - } else remote.sin_family = AF_UNSPEC; - err = socket_connect(ps, (SA *) &remote, sizeof(remote), tm); - return socket_strerror(err); + /* try connecting to remote address */ + err = socket_strerror(socket_connect(ps, (SA *) iterator->ai_addr, + (socklen_t) iterator->ai_addrlen, tm)); + /* if success or timeout is zero, break out of loop */ + if (err == NULL || timeout_iszero(tm)) { + *family = current_family; + break; + } + } + freeaddrinfo(resolved); + /* here, if err is set, we failed */ + return err; +} + +/*-------------------------------------------------------------------------*\ +* Tries to accept a socket +\*-------------------------------------------------------------------------*/ +const char *inet_tryaccept(p_socket server, int family, p_socket client, + p_timeout tm) { + socklen_t len; + t_sockaddr_storage addr; + switch (family) { + case AF_INET6: len = sizeof(struct sockaddr_in6); break; + case AF_INET: len = sizeof(struct sockaddr_in); break; + default: len = sizeof(addr); break; + } + return socket_strerror(socket_accept(server, client, (SA *) &addr, + &len, tm)); } /*-------------------------------------------------------------------------*\ * Tries to bind socket to (address, port) \*-------------------------------------------------------------------------*/ -const char *inet_trybind(p_socket ps, const char *address, unsigned short port) -{ - struct sockaddr_in local; - int err; - memset(&local, 0, sizeof(local)); - /* address is either wildcard or a valid ip address */ - local.sin_addr.s_addr = htonl(INADDR_ANY); - local.sin_port = htons(port); - local.sin_family = AF_INET; - if (strcmp(address, "*") && !inet_aton(address, &local.sin_addr)) { - struct hostent *hp = NULL; - struct in_addr **addr; - err = socket_gethostbyname(address, &hp); - if (err != IO_DONE) return socket_hoststrerror(err); - addr = (struct in_addr **) hp->h_addr_list; - memcpy(&local.sin_addr, *addr, sizeof(struct in_addr)); +const char *inet_trybind(p_socket ps, int *family, const char *address, + const char *serv, struct addrinfo *bindhints) { + struct addrinfo *iterator = NULL, *resolved = NULL; + const char *err = NULL; + int current_family = *family; + /* translate luasocket special values to C */ + if (strcmp(address, "*") == 0) address = NULL; + if (!serv) serv = "0"; + /* try resolving */ + err = socket_gaistrerror(getaddrinfo(address, serv, bindhints, &resolved)); + if (err) { + if (resolved) freeaddrinfo(resolved); + return err; } - err = socket_bind(ps, (SA *) &local, sizeof(local)); - if (err != IO_DONE) socket_destroy(ps); - return socket_strerror(err); + /* iterate over resolved addresses until one is good */ + for (iterator = resolved; iterator; iterator = iterator->ai_next) { + if (current_family != iterator->ai_family || *ps == SOCKET_INVALID) { + socket_destroy(ps); + err = inet_trycreate(ps, iterator->ai_family, + iterator->ai_socktype, iterator->ai_protocol); + if (err) continue; + current_family = iterator->ai_family; + } + /* try binding to local address */ + err = socket_strerror(socket_bind(ps, (SA *) iterator->ai_addr, + (socklen_t) iterator->ai_addrlen)); + /* keep trying unless bind succeeded */ + if (err == NULL) { + *family = current_family; + /* set to non-blocking after bind */ + socket_setnonblocking(ps); + break; + } + } + /* cleanup and return error */ + freeaddrinfo(resolved); + /* here, if err is set, we failed */ + return err; } /*-------------------------------------------------------------------------*\ -* Some systems do not provide this so that we provide our own. It's not -* marvelously fast, but it works just fine. +* Some systems do not provide these so that we provide our own. \*-------------------------------------------------------------------------*/ -#ifdef INET_ATON +#ifdef LUASOCKET_INET_ATON int inet_aton(const char *cp, struct in_addr *inp) { unsigned int a = 0, b = 0, c = 0, d = 0; @@ -280,4 +518,26 @@ int inet_aton(const char *cp, struct in_addr *inp) } #endif +#ifdef LUASOCKET_INET_PTON +int inet_pton(int af, const char *src, void *dst) +{ + struct addrinfo hints, *res; + int ret = 1; + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = af; + hints.ai_flags = AI_NUMERICHOST; + if (getaddrinfo(src, NULL, &hints, &res) != 0) return -1; + if (af == AF_INET) { + struct sockaddr_in *in = (struct sockaddr_in *) res->ai_addr; + memcpy(dst, &in->sin_addr, sizeof(in->sin_addr)); + } else if (af == AF_INET6) { + struct sockaddr_in6 *in = (struct sockaddr_in6 *) res->ai_addr; + memcpy(dst, &in->sin6_addr, sizeof(in->sin6_addr)); + } else { + ret = -1; + } + freeaddrinfo(res); + return ret; +} +#endif diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/inet.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/inet.h index 76622661..feb3541d 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/inet.h +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/inet.h @@ -1,42 +1,50 @@ -#ifndef INET_H -#define INET_H +#ifndef INET_H +#define INET_H /*=========================================================================*\ * Internet domain functions * LuaSocket toolkit * * This module implements the creation and connection of internet domain * sockets, on top of the socket.h interface, and the interface of with the -* resolver. +* resolver. * * The function inet_aton is provided for the platforms where it is not * available. The module also implements the interface of the internet * getpeername and getsockname functions as seen by Lua programs. * * The Lua functions toip and tohostname are also implemented here. -* -* RCS ID: $Id: inet.h,v 1.16 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ #include "lua.h" #include "socket.h" #include "timeout.h" #ifdef _WIN32 -#define INET_ATON +#define LUASOCKET_INET_ATON #endif int inet_open(lua_State *L); -const char *inet_trycreate(p_socket ps, int type); -const char *inet_tryconnect(p_socket ps, const char *address, - unsigned short port, p_timeout tm); -const char *inet_trybind(p_socket ps, const char *address, - unsigned short port); +const char *inet_trycreate(p_socket ps, int family, int type, int protocol); +const char *inet_tryconnect(p_socket ps, int *family, const char *address, + const char *serv, p_timeout tm, struct addrinfo *connecthints); +const char *inet_trybind(p_socket ps, int *family, const char *address, + const char *serv, struct addrinfo *bindhints); +const char *inet_trydisconnect(p_socket ps, int family, p_timeout tm); +const char *inet_tryaccept(p_socket server, int family, p_socket client, p_timeout tm); -int inet_meth_getpeername(lua_State *L, p_socket ps); -int inet_meth_getsockname(lua_State *L, p_socket ps); +int inet_meth_getpeername(lua_State *L, p_socket ps, int family); +int inet_meth_getsockname(lua_State *L, p_socket ps, int family); -#ifdef INET_ATON +int inet_optfamily(lua_State* L, int narg, const char* def); +int inet_optsocktype(lua_State* L, int narg, const char* def); + +#ifdef LUASOCKET_INET_ATON int inet_aton(const char *cp, struct in_addr *inp); #endif +#ifdef LUASOCKET_INET_PTON +const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt); +int inet_pton(int af, const char *src, void *dst); +#endif + #endif /* INET_H */ diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/io.c b/love/src/jni/love/src/libraries/luasocket/libluasocket/io.c index 06dc50ec..a4230ce8 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/io.c +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/io.c @@ -1,8 +1,6 @@ /*=========================================================================*\ * Input/Output abstraction * LuaSocket toolkit -* -* RCS ID: $Id: io.c,v 1.6 2005/09/29 06:11:41 diego Exp $ \*=========================================================================*/ #include "io.h" @@ -27,6 +25,6 @@ const char *io_strerror(int err) { case IO_DONE: return NULL; case IO_CLOSED: return "closed"; case IO_TIMEOUT: return "timeout"; - default: return "unknown error"; + default: return "unknown error"; } } diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/io.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/io.h index cce3aaf5..8cca08a8 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/io.h +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/io.h @@ -11,8 +11,6 @@ * * The module socket.h implements this interface, and thus the module tcp.h * is very simple. -* -* RCS ID: $Id: io.h,v 1.11 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ #include #include "lua.h" diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/ltn12.lua b/love/src/jni/love/src/libraries/luasocket/libluasocket/ltn12.lua index b42689a3..575c5a7f 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/ltn12.lua +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/ltn12.lua @@ -2,7 +2,6 @@ -- LTN12 - Filters, sources, sinks and pumps. -- LuaSocket toolkit. -- Author: Diego Nehab --- RCS ID: $Id: ltn12.lua,v 1.31 2006/04/03 04:45:42 diego Exp $ ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- @@ -10,17 +9,25 @@ ----------------------------------------------------------------------------- local string = require("string") local table = require("table") +local unpack = unpack or table.unpack local base = _G -module("ltn12") +local _M = {} +if module then -- heuristic for exporting a global package table + ltn12 = _M +end +local filter,source,sink,pump = {},{},{},{} -filter = {} -source = {} -sink = {} -pump = {} +_M.filter = filter +_M.source = source +_M.sink = sink +_M.pump = pump + +local unpack = unpack or table.unpack +local select = base.select -- 2048 seems to be better in windows... -BLOCKSIZE = 2048 -_VERSION = "LTN12 1.0.1" +_M.BLOCKSIZE = 2048 +_M._VERSION = "LTN12 1.0.3" ----------------------------------------------------------------------------- -- Filter stuff @@ -38,7 +45,8 @@ end -- chains a bunch of filters together -- (thanks to Wim Couwenberg) function filter.chain(...) - local n = table.getn(arg) + local arg = {...} + local n = base.select('#',...) local top, index = 1, 1 local retry = "" return function(chunk) @@ -89,7 +97,7 @@ end function source.file(handle, io_err) if handle then return function() - local chunk = handle:read(BLOCKSIZE) + local chunk = handle:read(_M.BLOCKSIZE) if not chunk then handle:close() end return chunk end @@ -112,8 +120,8 @@ function source.string(s) if s then local i = 1 return function() - local chunk = string.sub(s, i, i+BLOCKSIZE-1) - i = i + BLOCKSIZE + local chunk = string.sub(s, i, i+_M.BLOCKSIZE-1) + i = i + _M.BLOCKSIZE if chunk ~= "" then return chunk else return nil end end @@ -135,7 +143,9 @@ function source.rewind(src) end end -function source.chain(src, f) +-- chains a source with one or several filter(s) +function source.chain(src, f, ...) + if ... then f=filter.chain(f, ...) end base.assert(src and f) local last_in, last_out = "", "" local state = "feeding" @@ -186,6 +196,7 @@ end -- other, as if they were concatenated -- (thanks to Wim Couwenberg) function source.cat(...) + local arg = {...} local src = table.remove(arg, 1) return function() while src do @@ -249,8 +260,13 @@ function sink.error(err) end end --- chains a sink with a filter -function sink.chain(f, snk) +-- chains a sink with one or several filter(s) +function sink.chain(f, snk, ...) + if ... then + local args = { f, snk, ... } + snk = table.remove(args, #args) + f = filter.chain(unpack(args)) + end base.assert(f and snk) return function(chunk, err) if chunk ~= "" then @@ -290,3 +306,4 @@ function pump.all(src, snk, step) end end +return _M diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/ltn12.lua.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/ltn12.lua.h index 254c0683..6fcfed99 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/ltn12.lua.h +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/ltn12.lua.h @@ -1,7 +1,7 @@ /* code automatically generated by bin2c -- DO NOT EDIT */ { /* #include'ing this file in a C program is equivalent to calling - if (luaL_loadfile(L,"ltn12.lua")==0) lua_call(L, 0, 0); + if (luaL_loadfile(L,"ltn12.lua")==0) lua_call(L, 0, LUA_MULTRET); */ /* ltn12.lua */ static const unsigned char B1[]={ @@ -13,408 +13,434 @@ static const unsigned char B1[]={ 117,114, 99,101,115, 44, 32,115,105,110,107,115, 32, 97,110,100, 32,112,117,109, 112,115, 46, 10, 45, 45, 32, 76,117, 97, 83,111, 99,107,101,116, 32,116,111,111, 108,107,105,116, 46, 10, 45, 45, 32, 65,117,116,104,111,114, 58, 32, 68,105,101, -103,111, 32, 78,101,104, 97, 98, 10, 45, 45, 32, 82, 67, 83, 32, 73, 68, 58, 32, - 36, 73,100, 58, 32,108,116,110, 49, 50, 46,108,117, 97, 44,118, 32, 49, 46, 51, - 49, 32, 50, 48, 48, 54, 47, 48, 52, 47, 48, 51, 32, 48, 52, 58, 52, 53, 58, 52, - 50, 32,100,105,101,103,111, 32, 69,120,112, 32, 36, 10, 45, 45, 45, 45, 45, 45, +103,111, 32, 78,101,104, 97, 98, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97,114, -101, 32,109,111,100,117,108,101, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97,114,101, 32,109,111,100, +117,108,101, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, 32, - 61, 32,114,101,113,117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10, -108,111, 99, 97,108, 32,116, 97, 98,108,101, 32, 61, 32,114,101,113,117,105,114, -101, 40, 34,116, 97, 98,108,101, 34, 41, 10,108,111, 99, 97,108, 32, 98, 97,115, -101, 32, 61, 32, 95, 71, 10,109,111,100,117,108,101, 40, 34,108,116,110, 49, 50, - 34, 41, 10, 10,102,105,108,116,101,114, 32, 61, 32,123,125, 10,115,111,117,114, - 99,101, 32, 61, 32,123,125, 10,115,105,110,107, 32, 61, 32,123,125, 10,112,117, -109,112, 32, 61, 32,123,125, 10, 10, 45, 45, 32, 50, 48, 52, 56, 32,115,101,101, -109,115, 32,116,111, 32, 98,101, 32, 98,101,116,116,101,114, 32,105,110, 32,119, -105,110,100,111,119,115, 46, 46, 46, 10, 66, 76, 79, 67, 75, 83, 73, 90, 69, 32, - 61, 32, 50, 48, 52, 56, 10, 95, 86, 69, 82, 83, 73, 79, 78, 32, 61, 32, 34, 76, - 84, 78, 49, 50, 32, 49, 46, 48, 46, 49, 34, 10, 10, 45, 45, 45, 45, 45, 45, 45, + 45, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, 32, 61, 32,114,101,113, +117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10,108,111, 99, 97,108, + 32,116, 97, 98,108,101, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,116, 97, + 98,108,101, 34, 41, 10,108,111, 99, 97,108, 32,117,110,112, 97, 99,107, 32, 61, + 32,117,110,112, 97, 99,107, 32,111,114, 32,116, 97, 98,108,101, 46,117,110,112, + 97, 99,107, 10,108,111, 99, 97,108, 32, 98, 97,115,101, 32, 61, 32, 95, 71, 10, +108,111, 99, 97,108, 32, 95, 77, 32, 61, 32,123,125, 10,105,102, 32,109,111,100, +117,108,101, 32,116,104,101,110, 32, 45, 45, 32,104,101,117,114,105,115,116,105, + 99, 32,102,111,114, 32,101,120,112,111,114,116,105,110,103, 32, 97, 32,103,108, +111, 98, 97,108, 32,112, 97, 99,107, 97,103,101, 32,116, 97, 98,108,101, 10, 32, + 32, 32, 32,108,116,110, 49, 50, 32, 61, 32, 95, 77, 10,101,110,100, 10,108,111, + 99, 97,108, 32,102,105,108,116,101,114, 44,115,111,117,114, 99,101, 44,115,105, +110,107, 44,112,117,109,112, 32, 61, 32,123,125, 44,123,125, 44,123,125, 44,123, +125, 10, 10, 95, 77, 46,102,105,108,116,101,114, 32, 61, 32,102,105,108,116,101, +114, 10, 95, 77, 46,115,111,117,114, 99,101, 32, 61, 32,115,111,117,114, 99,101, + 10, 95, 77, 46,115,105,110,107, 32, 61, 32,115,105,110,107, 10, 95, 77, 46,112, +117,109,112, 32, 61, 32,112,117,109,112, 10, 10,108,111, 99, 97,108, 32,117,110, +112, 97, 99,107, 32, 61, 32,117,110,112, 97, 99,107, 32,111,114, 32,116, 97, 98, +108,101, 46,117,110,112, 97, 99,107, 10,108,111, 99, 97,108, 32,115,101,108,101, + 99,116, 32, 61, 32, 98, 97,115,101, 46,115,101,108,101, 99,116, 10, 10, 45, 45, + 32, 50, 48, 52, 56, 32,115,101,101,109,115, 32,116,111, 32, 98,101, 32, 98,101, +116,116,101,114, 32,105,110, 32,119,105,110,100,111,119,115, 46, 46, 46, 10, 95, + 77, 46, 66, 76, 79, 67, 75, 83, 73, 90, 69, 32, 61, 32, 50, 48, 52, 56, 10, 95, + 77, 46, 95, 86, 69, 82, 83, 73, 79, 78, 32, 61, 32, 34, 76, 84, 78, 49, 50, 32, + 49, 46, 48, 46, 51, 34, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 70,105,108,116,101,114, - 32,115,116,117,102,102, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 10, 45, 45, 32, 70,105,108,116,101,114, 32,115,116,117,102, +102, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, + 45, 45, 32,114,101,116,117,114,110,115, 32, 97, 32,104,105,103,104, 32,108,101, +118,101,108, 32,102,105,108,116,101,114, 32,116,104, 97,116, 32, 99,121, 99,108, +101,115, 32, 97, 32,108,111,119, 45,108,101,118,101,108, 32,102,105,108,116,101, +114, 10,102,117,110, 99,116,105,111,110, 32,102,105,108,116,101,114, 46, 99,121, + 99,108,101, 40,108,111,119, 44, 32, 99,116,120, 44, 32,101,120,116,114, 97, 41, + 10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115,115,101,114,116, 40,108,111,119, + 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111, +110, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, + 97,108, 32,114,101,116, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116, 44, 32, + 99,116,120, 32, 61, 32,108,111,119, 40, 99,116,120, 44, 32, 99,104,117,110,107, + 44, 32,101,120,116,114, 97, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116, +117,114,110, 32,114,101,116, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, + 10, 45, 45, 32, 99,104, 97,105,110,115, 32, 97, 32, 98,117,110, 99,104, 32,111, +102, 32,102,105,108,116,101,114,115, 32,116,111,103,101,116,104,101,114, 10, 45, + 45, 32, 40,116,104, 97,110,107,115, 32,116,111, 32, 87,105,109, 32, 67,111,117, +119,101,110, 98,101,114,103, 41, 10,102,117,110, 99,116,105,111,110, 32,102,105, +108,116,101,114, 46, 99,104, 97,105,110, 40, 46, 46, 46, 41, 10, 32, 32, 32, 32, +108,111, 99, 97,108, 32, 97,114,103, 32, 61, 32,123, 46, 46, 46,125, 10, 32, 32, + 32, 32,108,111, 99, 97,108, 32,110, 32, 61, 32, 98, 97,115,101, 46,115,101,108, +101, 99,116, 40, 39, 35, 39, 44, 46, 46, 46, 41, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,116,111,112, 44, 32,105,110,100,101,120, 32, 61, 32, 49, 44, 32, 49, + 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,116,114,121, 32, 61, 32, 34, + 34, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111, +110, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116, +114,121, 32, 61, 32, 99,104,117,110,107, 32, 97,110,100, 32,114,101,116,114,121, + 10, 32, 32, 32, 32, 32, 32, 32, 32,119,104,105,108,101, 32,116,114,117,101, 32, +100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,105,110, +100,101,120, 32, 61, 61, 32,116,111,112, 32,116,104,101,110, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 99,104,117,110,107, 32, 61, 32, + 97,114,103, 91,105,110,100,101,120, 93, 40, 99,104,117,110,107, 41, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104,117, +110,107, 32, 61, 61, 32, 34, 34, 32,111,114, 32,116,111,112, 32, 61, 61, 32,110, + 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 99,104,117,110,107, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101,105, +102, 32, 99,104,117,110,107, 32,116,104,101,110, 32,105,110,100,101,120, 32, 61, + 32,105,110,100,101,120, 32, 43, 32, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,116,111,112, 32, 61, 32,116,111, +112, 43, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,105,110,100,101,120, 32, 61, 32,116,111,112, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 99,104,117,110,107, 32, 61, 32, 97,114,103, + 91,105,110,100,101,120, 93, 40, 99,104,117,110,107, 32,111,114, 32, 34, 34, 41, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, + 99,104,117,110,107, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,110,100, +101,120, 32, 61, 32,105,110,100,101,120, 32, 45, 32, 49, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 99,104,117,110,107, + 32, 61, 32,114,101,116,114,121, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,101,108,115,101,105,102, 32, 99,104,117,110,107, 32,116,104, +101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,105,102, 32,105,110,100,101,120, 32, 61, 61, 32,110, 32,116,104,101, +110, 32,114,101,116,117,114,110, 32, 99,104,117,110,107, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32, +105,110,100,101,120, 32, 61, 32,105,110,100,101,120, 32, 43, 32, 49, 32,101,110, +100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108, +115,101, 32, 98, 97,115,101, 46,101,114,114,111,114, 40, 34,102,105,108,116,101, +114, 32,114,101,116,117,114,110,101,100, 32,105,110, 97,112,112,114,111,112,114, +105, 97,116,101, 32,110,105,108, 34, 41, 32,101,110,100, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101, +110,100, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 10, 45, 45, 32,114,101,116,117,114,110,115, 32, 97, 32,104,105, -103,104, 32,108,101,118,101,108, 32,102,105,108,116,101,114, 32,116,104, 97,116, - 32, 99,121, 99,108,101,115, 32, 97, 32,108,111,119, 45,108,101,118,101,108, 32, -102,105,108,116,101,114, 10,102,117,110, 99,116,105,111,110, 32,102,105,108,116, -101,114, 46, 99,121, 99,108,101, 40,108,111,119, 44, 32, 99,116,120, 44, 32,101, -120,116,114, 97, 41, 10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115,115,101,114, -116, 40,108,111,119, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117, -110, 99,116,105,111,110, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32, - 32, 32,108,111, 99, 97,108, 32,114,101,116, 10, 32, 32, 32, 32, 32, 32, 32, 32, -114,101,116, 44, 32, 99,116,120, 32, 61, 32,108,111,119, 40, 99,116,120, 44, 32, - 99,104,117,110,107, 44, 32,101,120,116,114, 97, 41, 10, 32, 32, 32, 32, 32, 32, - 32, 32,114,101,116,117,114,110, 32,114,101,116, 10, 32, 32, 32, 32,101,110,100, - 10,101,110,100, 10, 10, 45, 45, 32, 99,104, 97,105,110,115, 32, 97, 32, 98,117, -110, 99,104, 32,111,102, 32,102,105,108,116,101,114,115, 32,116,111,103,101,116, -104,101,114, 10, 45, 45, 32, 40,116,104, 97,110,107,115, 32,116,111, 32, 87,105, -109, 32, 67,111,117,119,101,110, 98,101,114,103, 41, 10,102,117,110, 99,116,105, -111,110, 32,102,105,108,116,101,114, 46, 99,104, 97,105,110, 40, 46, 46, 46, 41, - 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,110, 32, 61, 32,116, 97, 98,108,101, - 46,103,101,116,110, 40, 97,114,103, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, - 32,116,111,112, 44, 32,105,110,100,101,120, 32, 61, 32, 49, 44, 32, 49, 10, 32, - 32, 32, 32,108,111, 99, 97,108, 32,114,101,116,114,121, 32, 61, 32, 34, 34, 10, - 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, - 99,104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,114,121, - 32, 61, 32, 99,104,117,110,107, 32, 97,110,100, 32,114,101,116,114,121, 10, 32, - 32, 32, 32, 32, 32, 32, 32,119,104,105,108,101, 32,116,114,117,101, 32,100,111, - 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,105,110,100,101, -120, 32, 61, 61, 32,116,111,112, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 99,104,117,110,107, 32, 61, 32, 97,114, -103, 91,105,110,100,101,120, 93, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104,117,110,107, - 32, 61, 61, 32, 34, 34, 32,111,114, 32,116,111,112, 32, 61, 61, 32,110, 32,116, -104,101,110, 32,114,101,116,117,114,110, 32, 99,104,117,110,107, 10, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101,105,102, 32, - 99,104,117,110,107, 32,116,104,101,110, 32,105,110,100,101,120, 32, 61, 32,105, -110,100,101,120, 32, 43, 32, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,116,111,112, 32, 61, 32,116,111,112, 43, - 49, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32,105,110,100,101,120, 32, 61, 32,116,111,112, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 99,104,117,110,107, 32, 61, 32, 97,114,103, 91,105, -110,100,101,120, 93, 40, 99,104,117,110,107, 32,111,114, 32, 34, 34, 41, 10, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104, -117,110,107, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,110,100,101,120, - 32, 61, 32,105,110,100,101,120, 32, 45, 32, 49, 10, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 99,104,117,110,107, 32, 61, - 32,114,101,116,114,121, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32,101,108,115,101,105,102, 32, 99,104,117,110,107, 32,116,104,101,110, - 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32,105,102, 32,105,110,100,101,120, 32, 61, 61, 32,110, 32,116,104,101,110, 32, -114,101,116,117,114,110, 32, 99,104,117,110,107, 10, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,105,110, -100,101,120, 32, 61, 32,105,110,100,101,120, 32, 43, 32, 49, 32,101,110,100, 10, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, - 32, 98, 97,115,101, 46,101,114,114,111,114, 40, 34,102,105,108,116,101,114, 32, -114,101,116,117,114,110,101,100, 32,105,110, 97,112,112,114,111,112,114,105, 97, -116,101, 32,110,105,108, 34, 41, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, - 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 83,111,117, +114, 99,101, 32,115,116,117,102,102, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 83,111,117,114, 99, -101, 32,115,116,117,102,102, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 10, 45, 45, 32, 99,114,101, 97,116,101, 32, 97,110, 32,101, -109,112,116,121, 32,115,111,117,114, 99,101, 10,108,111, 99, 97,108, 32,102,117, -110, 99,116,105,111,110, 32,101,109,112,116,121, 40, 41, 10, 32, 32, 32, 32,114, -101,116,117,114,110, 32,110,105,108, 10,101,110,100, 10, 10,102,117,110, 99,116, -105,111,110, 32,115,111,117,114, 99,101, 46,101,109,112,116,121, 40, 41, 10, 32, - 32, 32, 32,114,101,116,117,114,110, 32,101,109,112,116,121, 10,101,110,100, 10, - 10, 45, 45, 32,114,101,116,117,114,110,115, 32, 97, 32,115,111,117,114, 99,101, - 32,116,104, 97,116, 32,106,117,115,116, 32,111,117,116,112,117,116,115, 32, 97, -110, 32,101,114,114,111,114, 10,102,117,110, 99,116,105,111,110, 32,115,111,117, -114, 99,101, 46,101,114,114,111,114, 40,101,114,114, 41, 10, 32, 32, 32, 32,114, -101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, - 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, - 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 99,114,101, - 97,116,101,115, 32, 97, 32,102,105,108,101, 32,115,111,117,114, 99,101, 10,102, -117,110, 99,116,105,111,110, 32,115,111,117,114, 99,101, 46,102,105,108,101, 40, -104, 97,110,100,108,101, 44, 32,105,111, 95,101,114,114, 41, 10, 32, 32, 32, 32, -105,102, 32,104, 97,110,100,108,101, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, - 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 41, - 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99, -104,117,110,107, 32, 61, 32,104, 97,110,100,108,101, 58,114,101, 97,100, 40, 66, - 76, 79, 67, 75, 83, 73, 90, 69, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32,105,102, 32,110,111,116, 32, 99,104,117,110,107, 32,116,104,101,110, 32, -104, 97,110,100,108,101, 58, 99,108,111,115,101, 40, 41, 32,101,110,100, 10, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 99,104, -117,110,107, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, -101,108,115,101, 32,114,101,116,117,114,110, 32,115,111,117,114, 99,101, 46,101, -114,114,111,114, 40,105,111, 95,101,114,114, 32,111,114, 32, 34,117,110, 97, 98, -108,101, 32,116,111, 32,111,112,101,110, 32,102,105,108,101, 34, 41, 32,101,110, -100, 10,101,110,100, 10, 10, 45, 45, 32,116,117,114,110,115, 32, 97, 32,102, 97, -110, 99,121, 32,115,111,117,114, 99,101, 32,105,110,116,111, 32, 97, 32,115,105, -109,112,108,101, 32,115,111,117,114, 99,101, 10,102,117,110, 99,116,105,111,110, - 32,115,111,117,114, 99,101, 46,115,105,109,112,108,105,102,121, 40,115,114, 99, - 41, 10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115,115,101,114,116, 40,115,114, - 99, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105, -111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99, -104,117,110,107, 44, 32,101,114,114, 95,111,114, 95,110,101,119, 32, 61, 32,115, -114, 99, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,114, 99, 32, 61, 32,101, -114,114, 95,111,114, 95,110,101,119, 32,111,114, 32,115,114, 99, 10, 32, 32, 32, - 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32, 99,104,117,110,107, 32,116,104, -101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 95,111, -114, 95,110,101,119, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,114, -101,116,117,114,110, 32, 99,104,117,110,107, 32,101,110,100, 10, 32, 32, 32, 32, -101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 99,114,101, 97,116,101,115, 32, -115,116,114,105,110,103, 32,115,111,117,114, 99,101, 10,102,117,110, 99,116,105, -111,110, 32,115,111,117,114, 99,101, 46,115,116,114,105,110,103, 40,115, 41, 10, - 32, 32, 32, 32,105,102, 32,115, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, - 32, 32,108,111, 99, 97,108, 32,105, 32, 61, 32, 49, 10, 32, 32, 32, 32, 32, 32, - 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 41, 10, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104, -117,110,107, 32, 61, 32,115,116,114,105,110,103, 46,115,117, 98, 40,115, 44, 32, -105, 44, 32,105, 43, 66, 76, 79, 67, 75, 83, 73, 90, 69, 45, 49, 41, 10, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105, 32, 61, 32,105, 32, 43, 32, 66, 76, - 79, 67, 75, 83, 73, 90, 69, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, -105,102, 32, 99,104,117,110,107, 32,126, 61, 32, 34, 34, 32,116,104,101,110, 32, -114,101,116,117,114,110, 32, 99,104,117,110,107, 10, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,110,105,108, - 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, - 32,101,108,115,101, 32,114,101,116,117,114,110, 32,115,111,117,114, 99,101, 46, -101,109,112,116,121, 40, 41, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, - 99,114,101, 97,116,101,115, 32,114,101,119,105,110,100, 97, 98,108,101, 32,115, -111,117,114, 99,101, 10,102,117,110, 99,116,105,111,110, 32,115,111,117,114, 99, -101, 46,114,101,119,105,110,100, 40,115,114, 99, 41, 10, 32, 32, 32, 32, 98, 97, -115,101, 46, 97,115,115,101,114,116, 40,115,114, 99, 41, 10, 32, 32, 32, 32,108, -111, 99, 97,108, 32,116, 32, 61, 32,123,125, 10, 32, 32, 32, 32,114,101,116,117, -114,110, 32,102,117,110, 99,116,105,111,110, 40, 99,104,117,110,107, 41, 10, 32, + 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 99,114,101, 97,116,101, 32, 97,110, + 32,101,109,112,116,121, 32,115,111,117,114, 99,101, 10,108,111, 99, 97,108, 32, +102,117,110, 99,116,105,111,110, 32,101,109,112,116,121, 40, 41, 10, 32, 32, 32, + 32,114,101,116,117,114,110, 32,110,105,108, 10,101,110,100, 10, 10,102,117,110, + 99,116,105,111,110, 32,115,111,117,114, 99,101, 46,101,109,112,116,121, 40, 41, + 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,101,109,112,116,121, 10,101,110, +100, 10, 10, 45, 45, 32,114,101,116,117,114,110,115, 32, 97, 32,115,111,117,114, + 99,101, 32,116,104, 97,116, 32,106,117,115,116, 32,111,117,116,112,117,116,115, + 32, 97,110, 32,101,114,114,111,114, 10,102,117,110, 99,116,105,111,110, 32,115, +111,117,114, 99,101, 46,101,114,114,111,114, 40,101,114,114, 41, 10, 32, 32, 32, + 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, + 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101, +114,114, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 99, +114,101, 97,116,101,115, 32, 97, 32,102,105,108,101, 32,115,111,117,114, 99,101, + 10,102,117,110, 99,116,105,111,110, 32,115,111,117,114, 99,101, 46,102,105,108, +101, 40,104, 97,110,100,108,101, 44, 32,105,111, 95,101,114,114, 41, 10, 32, 32, + 32, 32,105,102, 32,104, 97,110,100,108,101, 32,116,104,101,110, 10, 32, 32, 32, + 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, + 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, + 32, 99,104,117,110,107, 32, 61, 32,104, 97,110,100,108,101, 58,114,101, 97,100, + 40, 95, 77, 46, 66, 76, 79, 67, 75, 83, 73, 90, 69, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32, 99,104,117,110,107, 32, -116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 99,104,117, -110,107, 32, 61, 32,116, 97, 98,108,101, 46,114,101,109,111,118,101, 40,116, 41, - 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32, - 99,104,117,110,107, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,115,114, - 99, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, - 32,114,101,116,117,114,110, 32, 99,104,117,110,107, 32,101,110,100, 10, 32, 32, - 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32,116, 97, 98,108,101, 46,105,110,115,101,114,116, 40,116, 44, 32, 99, -104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, - 32, 32,101,110,100, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32, -115,111,117,114, 99,101, 46, 99,104, 97,105,110, 40,115,114, 99, 44, 32,102, 41, - 10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115,115,101,114,116, 40,115,114, 99, - 32, 97,110,100, 32,102, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,108, 97, -115,116, 95,105,110, 44, 32,108, 97,115,116, 95,111,117,116, 32, 61, 32, 34, 34, - 44, 32, 34, 34, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,116, 97,116,101, - 32, 61, 32, 34,102,101,101,100,105,110,103, 34, 10, 32, 32, 32, 32,108,111, 99, - 97,108, 32,101,114,114, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117, -110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, -110,111,116, 32,108, 97,115,116, 95,111,117,116, 32,116,104,101,110, 10, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115,101, 46,101,114,114,111,114, - 40, 39,115,111,117,114, 99,101, 32,105,115, 32,101,109,112,116,121, 33, 39, 44, - 32, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, - 32, 32, 32, 32,119,104,105,108,101, 32,116,114,117,101, 32,100,111, 10, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,115,116, 97,116,101, 32, 61, - 61, 32, 34,102,101,101,100,105,110,103, 34, 32,116,104,101,110, 10, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108, 97,115,116, 95,105,110, - 44, 32,101,114,114, 32, 61, 32,115,114, 99, 40, 41, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104,101, -110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110, -100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108, 97, -115,116, 95,111,117,116, 32, 61, 32,102, 40,108, 97,115,116, 95,105,110, 41, 10, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110, -111,116, 32,108, 97,115,116, 95,111,117,116, 32,116,104,101,110, 10, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, -108, 97,115,116, 95,105,110, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115, -101, 46,101,114,114,111,114, 40, 39,102,105,108,116,101,114, 32,114,101,116,117, -114,110,101,100, 32,105,110, 97,112,112,114,111,112,114,105, 97,116,101, 32,110, -105,108, 39, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, - 32,110,105,108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32,101,108,115,101,105,102, 32,108, 97,115,116, 95,111,117,116, - 32,126, 61, 32, 34, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,116, 97,116,101, 32, 61, 32, - 34,101, 97,116,105,110,103, 34, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,108, 97,115,116, 95,105,110, 32, -116,104,101,110, 32,108, 97,115,116, 95,105,110, 32, 61, 32, 34, 34, 32,101,110, -100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32,114,101,116,117,114,110, 32,108, 97,115,116, 95,111,117,116, 10, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108, 97,115,116, 95,111,117,116, 32, - 61, 32,102, 40,108, 97,115,116, 95,105,110, 41, 10, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,108, 97,115,116, 95,111,117,116, - 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,108, 97,115,116, 95, -105,110, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,116, - 97,116,101, 32, 61, 32, 34,102,101,101,100,105,110,103, 34, 10, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, +116,104,101,110, 32,104, 97,110,100,108,101, 58, 99,108,111,115,101, 40, 41, 32, +101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117, +114,110, 32, 99,104,117,110,107, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, + 10, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,115,111,117, +114, 99,101, 46,101,114,114,111,114, 40,105,111, 95,101,114,114, 32,111,114, 32, + 34,117,110, 97, 98,108,101, 32,116,111, 32,111,112,101,110, 32,102,105,108,101, + 34, 41, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32,116,117,114,110,115, + 32, 97, 32,102, 97,110, 99,121, 32,115,111,117,114, 99,101, 32,105,110,116,111, + 32, 97, 32,115,105,109,112,108,101, 32,115,111,117,114, 99,101, 10,102,117,110, + 99,116,105,111,110, 32,115,111,117,114, 99,101, 46,115,105,109,112,108,105,102, +121, 40,115,114, 99, 41, 10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115,115,101, +114,116, 40,115,114, 99, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102, +117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, + 99, 97,108, 32, 99,104,117,110,107, 44, 32,101,114,114, 95,111,114, 95,110,101, +119, 32, 61, 32,115,114, 99, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,114, + 99, 32, 61, 32,101,114,114, 95,111,114, 95,110,101,119, 32,111,114, 32,115,114, + 99, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32, 99,104,117, +110,107, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32, +101,114,114, 95,111,114, 95,110,101,119, 10, 32, 32, 32, 32, 32, 32, 32, 32,101, +108,115,101, 32,114,101,116,117,114,110, 32, 99,104,117,110,107, 32,101,110,100, + 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 99,114,101, + 97,116,101,115, 32,115,116,114,105,110,103, 32,115,111,117,114, 99,101, 10,102, +117,110, 99,116,105,111,110, 32,115,111,117,114, 99,101, 46,115,116,114,105,110, +103, 40,115, 41, 10, 32, 32, 32, 32,105,102, 32,115, 32,116,104,101,110, 10, 32, + 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,105, 32, 61, 32, 49, 10, 32, + 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105, +111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, + 97,108, 32, 99,104,117,110,107, 32, 61, 32,115,116,114,105,110,103, 46,115,117, + 98, 40,115, 44, 32,105, 44, 32,105, 43, 95, 77, 46, 66, 76, 79, 67, 75, 83, 73, + 90, 69, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105, 32, + 61, 32,105, 32, 43, 32, 95, 77, 46, 66, 76, 79, 67, 75, 83, 73, 90, 69, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104,117,110,107, 32, +126, 61, 32, 34, 34, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 99,104, +117,110,107, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, + 32,114,101,116,117,114,110, 32,110,105,108, 32,101,110,100, 10, 32, 32, 32, 32, + 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,101,108,115,101, 32,114,101,116, +117,114,110, 32,115,111,117,114, 99,101, 46,101,109,112,116,121, 40, 41, 32,101, +110,100, 10,101,110,100, 10, 10, 45, 45, 32, 99,114,101, 97,116,101,115, 32,114, +101,119,105,110,100, 97, 98,108,101, 32,115,111,117,114, 99,101, 10,102,117,110, + 99,116,105,111,110, 32,115,111,117,114, 99,101, 46,114,101,119,105,110,100, 40, +115,114, 99, 41, 10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115,115,101,114,116, + 40,115,114, 99, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,116, 32, 61, 32, +123,125, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105, +111,110, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, + 32,110,111,116, 32, 99,104,117,110,107, 32,116,104,101,110, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 99,104,117,110,107, 32, 61, 32,116, 97, 98,108, +101, 46,114,101,109,111,118,101, 40,116, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,105,102, 32,110,111,116, 32, 99,104,117,110,107, 32,116,104,101, +110, 32,114,101,116,117,114,110, 32,115,114, 99, 40, 41, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32, 99, +104,117,110,107, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115, +101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,116, 97, 98,108,101, 46, +105,110,115,101,114,116, 40,116, 44, 32, 99,104,117,110,107, 41, 10, 32, 32, 32, + 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, + 10, 10, 45, 45, 32, 99,104, 97,105,110,115, 32, 97, 32,115,111,117,114, 99,101, + 32,119,105,116,104, 32,111,110,101, 32,111,114, 32,115,101,118,101,114, 97,108, + 32,102,105,108,116,101,114, 40,115, 41, 10,102,117,110, 99,116,105,111,110, 32, +115,111,117,114, 99,101, 46, 99,104, 97,105,110, 40,115,114, 99, 44, 32,102, 44, + 32, 46, 46, 46, 41, 10, 32, 32, 32, 32,105,102, 32, 46, 46, 46, 32,116,104,101, +110, 32,102, 61,102,105,108,116,101,114, 46, 99,104, 97,105,110, 40,102, 44, 32, + 46, 46, 46, 41, 32,101,110,100, 10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115, +115,101,114,116, 40,115,114, 99, 32, 97,110,100, 32,102, 41, 10, 32, 32, 32, 32, +108,111, 99, 97,108, 32,108, 97,115,116, 95,105,110, 44, 32,108, 97,115,116, 95, +111,117,116, 32, 61, 32, 34, 34, 44, 32, 34, 34, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,115,116, 97,116,101, 32, 61, 32, 34,102,101,101,100,105,110,103, 34, + 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,101,114,114, 10, 32, 32, 32, 32,114, +101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, + 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,108, 97,115,116, 95,111,117,116, + 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97, +115,101, 46,101,114,114,111,114, 40, 39,115,111,117,114, 99,101, 32,105,115, 32, +101,109,112,116,121, 33, 39, 44, 32, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, +101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,119,104,105,108,101, 32,116,114, +117,101, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, + 32,115,116, 97,116,101, 32, 61, 61, 32, 34,102,101,101,100,105,110,103, 34, 32, +116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32,108, 97,115,116, 95,105,110, 44, 32,101,114,114, 32, 61, 32,115,114, 99, 40, + 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, + 32,101,114,114, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, + 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,108, 97,115,116, 95,111,117,116, 32, 61, 32,102, 40,108, + 97,115,116, 95,105,110, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,105,102, 32,110,111,116, 32,108, 97,115,116, 95,111,117,116, 32, +116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,105,102, 32,108, 97,115,116, 95,105,110, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115,101, 46,101,114,114,111,114, 40, 39,102,105,108, -116,101,114, 32,114,101,116,117,114,110,101,100, 32, 34, 34, 39, 41, 10, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110, -100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108, -115,101,105,102, 32,110,111,116, 32,108, 97,115,116, 95,111,117,116, 32,116,104, -101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32,105,102, 32,108, 97,115,116, 95,105,110, 32,116,104,101,110, 10, 32, +116,101,114, 32,114,101,116,117,114,110,101,100, 32,105,110, 97,112,112,114,111, +112,114,105, 97,116,101, 32,110,105,108, 39, 41, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 98, 97,115,101, 46,101,114,114,111,114, 40, 39,102,105,108,116,101, -114, 32,114,101,116,117,114,110,101,100, 32,105,110, 97,112,112,114,111,112,114, -105, 97,116,101, 32,110,105,108, 39, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, + 32, 32,114,101,116,117,114,110, 32,110,105,108, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101,105,102, 32, +108, 97,115,116, 95,111,117,116, 32,126, 61, 32, 34, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, -114,101,116,117,114,110, 32,110,105,108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117, -114,110, 32,108, 97,115,116, 95,111,117,116, 10, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, - 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 99,114,101, 97, -116,101,115, 32, 97, 32,115,111,117,114, 99,101, 32,116,104, 97,116, 32,112,114, -111,100,117, 99,101,115, 32, 99,111,110,116,101,110,116,115, 32,111,102, 32,115, -101,118,101,114, 97,108, 32,115,111,117,114, 99,101,115, 44, 32,111,110,101, 32, - 97,102,116,101,114, 32,116,104,101, 10, 45, 45, 32,111,116,104,101,114, 44, 32, - 97,115, 32,105,102, 32,116,104,101,121, 32,119,101,114,101, 32, 99,111,110, 99, - 97,116,101,110, 97,116,101,100, 10, 45, 45, 32, 40,116,104, 97,110,107,115, 32, -116,111, 32, 87,105,109, 32, 67,111,117,119,101,110, 98,101,114,103, 41, 10,102, -117,110, 99,116,105,111,110, 32,115,111,117,114, 99,101, 46, 99, 97,116, 40, 46, - 46, 46, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,114, 99, 32, 61, 32, -116, 97, 98,108,101, 46,114,101,109,111,118,101, 40, 97,114,103, 44, 32, 49, 41, - 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, - 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,119,104,105,108,101, 32,115,114, 99, - 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97, -108, 32, 99,104,117,110,107, 44, 32,101,114,114, 32, 61, 32,115,114, 99, 40, 41, - 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104,117,110, -107, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 99,104,117,110,107, 32, -101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101, -114,114, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32, -101,114,114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, -115,114, 99, 32, 61, 32,116, 97, 98,108,101, 46,114,101,109,111,118,101, 40, 97, -114,103, 44, 32, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, - 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 83,105,110,107, 32,115,116, -117,102,102, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 10, 45, 45, 32, 99,114,101, 97,116,101,115, 32, 97, 32,115,105,110,107, 32, -116,104, 97,116, 32,115,116,111,114,101,115, 32,105,110,116,111, 32, 97, 32,116, - 97, 98,108,101, 10,102,117,110, 99,116,105,111,110, 32,115,105,110,107, 46,116, - 97, 98,108,101, 40,116, 41, 10, 32, 32, 32, 32,116, 32, 61, 32,116, 32,111,114, - 32,123,125, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,102, 32, 61, 32,102,117, -110, 99,116,105,111,110, 40, 99,104,117,110,107, 44, 32,101,114,114, 41, 10, 32, - 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104,117,110,107, 32,116,104,101,110, - 32,116, 97, 98,108,101, 46,105,110,115,101,114,116, 40,116, 44, 32, 99,104,117, -110,107, 41, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117, -114,110, 32, 49, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116, -117,114,110, 32,102, 44, 32,116, 10,101,110,100, 10, 10, 45, 45, 32,116,117,114, -110,115, 32, 97, 32,102, 97,110, 99,121, 32,115,105,110,107, 32,105,110,116,111, - 32, 97, 32,115,105,109,112,108,101, 32,115,105,110,107, 10,102,117,110, 99,116, -105,111,110, 32,115,105,110,107, 46,115,105,109,112,108,105,102,121, 40,115,110, -107, 41, 10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115,115,101,114,116, 40,115, -110,107, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116, -105,111,110, 40, 99,104,117,110,107, 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, - 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,116, 44, 32,101,114,114, 95,111, -114, 95,110,101,119, 32, 61, 32,115,110,107, 40, 99,104,117,110,107, 44, 32,101, -114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114, -101,116, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32, -101,114,114, 95,111,114, 95,110,101,119, 32,101,110,100, 10, 32, 32, 32, 32, 32, - 32, 32, 32,115,110,107, 32, 61, 32,101,114,114, 95,111,114, 95,110,101,119, 32, -111,114, 32,115,110,107, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114, -110, 32, 49, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, - 99,114,101, 97,116,101,115, 32, 97, 32,102,105,108,101, 32,115,105,110,107, 10, -102,117,110, 99,116,105,111,110, 32,115,105,110,107, 46,102,105,108,101, 40,104, - 97,110,100,108,101, 44, 32,105,111, 95,101,114,114, 41, 10, 32, 32, 32, 32,105, -102, 32,104, 97,110,100,108,101, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, - 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 99,104, -117,110,107, 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32,105,102, 32,110,111,116, 32, 99,104,117,110,107, 32,116,104,101,110, 10, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,104, 97,110,100, -108,101, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32, -104, 97,110,100,108,101, 58,119,114,105,116,101, 40, 99,104,117,110,107, 41, 32, -101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, -101,108,115,101, 32,114,101,116,117,114,110, 32,115,105,110,107, 46,101,114,114, -111,114, 40,105,111, 95,101,114,114, 32,111,114, 32, 34,117,110, 97, 98,108,101, - 32,116,111, 32,111,112,101,110, 32,102,105,108,101, 34, 41, 32,101,110,100, 10, -101,110,100, 10, 10, 45, 45, 32, 99,114,101, 97,116,101,115, 32, 97, 32,115,105, -110,107, 32,116,104, 97,116, 32,100,105,115, 99, 97,114,100,115, 32,100, 97,116, - 97, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,110,117,108, -108, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101,110,100, - 10, 10,102,117,110, 99,116,105,111,110, 32,115,105,110,107, 46,110,117,108,108, - 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,110,117,108,108, 10,101, -110,100, 10, 10, 45, 45, 32, 99,114,101, 97,116,101,115, 32, 97, 32,115,105,110, -107, 32,116,104, 97,116, 32,106,117,115,116, 32,114,101,116,117,114,110,115, 32, - 97,110, 32,101,114,114,111,114, 10,102,117,110, 99,116,105,111,110, 32,115,105, -110,107, 46,101,114,114,111,114, 40,101,114,114, 41, 10, 32, 32, 32, 32,114,101, -116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32, - 32, 32, 32, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 10, - 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 99,104, 97,105, -110,115, 32, 97, 32,115,105,110,107, 32,119,105,116,104, 32, 97, 32,102,105,108, -116,101,114, 10,102,117,110, 99,116,105,111,110, 32,115,105,110,107, 46, 99,104, - 97,105,110, 40,102, 44, 32,115,110,107, 41, 10, 32, 32, 32, 32, 98, 97,115,101, - 46, 97,115,115,101,114,116, 40,102, 32, 97,110,100, 32,115,110,107, 41, 10, 32, - 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 99, -104,117,110,107, 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105, -102, 32, 99,104,117,110,107, 32,126, 61, 32, 34, 34, 32,116,104,101,110, 10, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,102,105,108, -116,101,114,101,100, 32, 61, 32,102, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,100,111,110,101, 32, - 61, 32, 99,104,117,110,107, 32, 97,110,100, 32, 34, 34, 10, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32,119,104,105,108,101, 32,116,114,117,101, 32,100,111, - 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, - 97,108, 32,114,101,116, 44, 32,115,110,107,101,114,114, 32, 61, 32,115,110,107, - 40,102,105,108,116,101,114,101,100, 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114, -101,116, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32, -115,110,107,101,114,114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32,105,102, 32,102,105,108,116,101,114,101,100, 32, 61, - 61, 32,100,111,110,101, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 49, - 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32,102,105,108,116,101,114,101,100, 32, 61, 32,102, 40,100,111,110,101, 41, 10, +115,116, 97,116,101, 32, 61, 32, 34,101, 97,116,105,110,103, 34, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, +108, 97,115,116, 95,105,110, 32,116,104,101,110, 32,108, 97,115,116, 95,105,110, + 32, 61, 32, 34, 34, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,108, 97,115, +116, 95,111,117,116, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108, +115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108, + 97,115,116, 95,111,117,116, 32, 61, 32,102, 40,108, 97,115,116, 95,105,110, 41, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, +108, 97,115,116, 95,111,117,116, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +105,102, 32,108, 97,115,116, 95,105,110, 32, 61, 61, 32, 34, 34, 32,116,104,101, +110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,115,116, 97,116,101, 32, 61, 32, 34,102,101,101,100,105, +110,103, 34, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115,101, 46,101,114, +114,111,114, 40, 39,102,105,108,116,101,114, 32,114,101,116,117,114,110,101,100, + 32, 34, 34, 39, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,101,108,115,101,105,102, 32,110,111,116, 32,108, 97,115, +116, 95,111,117,116, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,108, 97,115,116, 95,105, +110, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115,101, 46,101,114,114,111, +114, 40, 39,102,105,108,116,101,114, 32,114,101,116,117,114,110,101,100, 32,105, +110, 97,112,112,114,111,112,114,105, 97,116,101, 32,110,105,108, 39, 41, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101, +108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,110,105,108, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101, +110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101, +108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,114,101,116,117,114,110, 32,108, 97,115,116, 95,111,117,116, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, - 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32, 49, 32,101,110, -100, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, + 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, + 10, 45, 45, 32, 99,114,101, 97,116,101,115, 32, 97, 32,115,111,117,114, 99,101, + 32,116,104, 97,116, 32,112,114,111,100,117, 99,101,115, 32, 99,111,110,116,101, +110,116,115, 32,111,102, 32,115,101,118,101,114, 97,108, 32,115,111,117,114, 99, +101,115, 44, 32,111,110,101, 32, 97,102,116,101,114, 32,116,104,101, 10, 45, 45, + 32,111,116,104,101,114, 44, 32, 97,115, 32,105,102, 32,116,104,101,121, 32,119, +101,114,101, 32, 99,111,110, 99, 97,116,101,110, 97,116,101,100, 10, 45, 45, 32, + 40,116,104, 97,110,107,115, 32,116,111, 32, 87,105,109, 32, 67,111,117,119,101, +110, 98,101,114,103, 41, 10,102,117,110, 99,116,105,111,110, 32,115,111,117,114, + 99,101, 46, 99, 97,116, 40, 46, 46, 46, 41, 10, 32, 32, 32, 32,108,111, 99, 97, +108, 32, 97,114,103, 32, 61, 32,123, 46, 46, 46,125, 10, 32, 32, 32, 32,108,111, + 99, 97,108, 32,115,114, 99, 32, 61, 32,116, 97, 98,108,101, 46,114,101,109,111, +118,101, 40, 97,114,103, 44, 32, 49, 41, 10, 32, 32, 32, 32,114,101,116,117,114, +110, 32,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, + 32,119,104,105,108,101, 32,115,114, 99, 32,100,111, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104,117,110,107, 44, 32,101, +114,114, 32, 61, 32,115,114, 99, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,105,102, 32, 99,104,117,110,107, 32,116,104,101,110, 32,114,101,116, +117,114,110, 32, 99,104,117,110,107, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104,101,110, 32,114,101, +116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,114, 99, 32, 61, 32,116, 97, 98,108, +101, 46,114,101,109,111,118,101, 40, 97,114,103, 44, 32, 49, 41, 10, 32, 32, 32, + 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, + 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, + 45, 45, 32, 83,105,110,107, 32,115,116,117,102,102, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 80,117,109,112, - 32,115,116,117,102,102, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 99,114,101, 97,116, +101,115, 32, 97, 32,115,105,110,107, 32,116,104, 97,116, 32,115,116,111,114,101, +115, 32,105,110,116,111, 32, 97, 32,116, 97, 98,108,101, 10,102,117,110, 99,116, +105,111,110, 32,115,105,110,107, 46,116, 97, 98,108,101, 40,116, 41, 10, 32, 32, + 32, 32,116, 32, 61, 32,116, 32,111,114, 32,123,125, 10, 32, 32, 32, 32,108,111, + 99, 97,108, 32,102, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 99,104,117, +110,107, 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, + 99,104,117,110,107, 32,116,104,101,110, 32,116, 97, 98,108,101, 46,105,110,115, +101,114,116, 40,116, 44, 32, 99,104,117,110,107, 41, 32,101,110,100, 10, 32, 32, + 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10, 32, 32, 32, 32,101, +110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102, 44, 32,116, 10,101, +110,100, 10, 10, 45, 45, 32,116,117,114,110,115, 32, 97, 32,102, 97,110, 99,121, + 32,115,105,110,107, 32,105,110,116,111, 32, 97, 32,115,105,109,112,108,101, 32, +115,105,110,107, 10,102,117,110, 99,116,105,111,110, 32,115,105,110,107, 46,115, +105,109,112,108,105,102,121, 40,115,110,107, 41, 10, 32, 32, 32, 32, 98, 97,115, +101, 46, 97,115,115,101,114,116, 40,115,110,107, 41, 10, 32, 32, 32, 32,114,101, +116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 99,104,117,110,107, 44, + 32,101,114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, +114,101,116, 44, 32,101,114,114, 95,111,114, 95,110,101,119, 32, 61, 32,115,110, +107, 40, 99,104,117,110,107, 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, 32, 32, + 32, 32,105,102, 32,110,111,116, 32,114,101,116, 32,116,104,101,110, 32,114,101, +116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 95,111,114, 95,110,101,119, + 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,110,107, 32, 61, 32,101, +114,114, 95,111,114, 95,110,101,119, 32,111,114, 32,115,110,107, 10, 32, 32, 32, + 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10, 32, 32, 32, 32,101,110, +100, 10,101,110,100, 10, 10, 45, 45, 32, 99,114,101, 97,116,101,115, 32, 97, 32, +102,105,108,101, 32,115,105,110,107, 10,102,117,110, 99,116,105,111,110, 32,115, +105,110,107, 46,102,105,108,101, 40,104, 97,110,100,108,101, 44, 32,105,111, 95, +101,114,114, 41, 10, 32, 32, 32, 32,105,102, 32,104, 97,110,100,108,101, 32,116, +104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,102, +117,110, 99,116,105,111,110, 40, 99,104,117,110,107, 44, 32,101,114,114, 41, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32, 99, +104,117,110,107, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,104, 97,110,100,108,101, 58, 99,108,111,115,101, 40, 41, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116, +117,114,110, 32, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108, +115,101, 32,114,101,116,117,114,110, 32,104, 97,110,100,108,101, 58,119,114,105, +116,101, 40, 99,104,117,110,107, 41, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, + 32, 32,101,110,100, 10, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114, +110, 32,115,105,110,107, 46,101,114,114,111,114, 40,105,111, 95,101,114,114, 32, +111,114, 32, 34,117,110, 97, 98,108,101, 32,116,111, 32,111,112,101,110, 32,102, +105,108,101, 34, 41, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 99,114, +101, 97,116,101,115, 32, 97, 32,115,105,110,107, 32,116,104, 97,116, 32,100,105, +115, 99, 97,114,100,115, 32,100, 97,116, 97, 10,108,111, 99, 97,108, 32,102,117, +110, 99,116,105,111,110, 32,110,117,108,108, 40, 41, 10, 32, 32, 32, 32,114,101, +116,117,114,110, 32, 49, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, + 32,115,105,110,107, 46,110,117,108,108, 40, 41, 10, 32, 32, 32, 32,114,101,116, +117,114,110, 32,110,117,108,108, 10,101,110,100, 10, 10, 45, 45, 32, 99,114,101, + 97,116,101,115, 32, 97, 32,115,105,110,107, 32,116,104, 97,116, 32,106,117,115, +116, 32,114,101,116,117,114,110,115, 32, 97,110, 32,101,114,114,111,114, 10,102, +117,110, 99,116,105,111,110, 32,115,105,110,107, 46,101,114,114,111,114, 40,101, +114,114, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116, +105,111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, + 32,110,105,108, 44, 32,101,114,114, 10, 32, 32, 32, 32,101,110,100, 10,101,110, +100, 10, 10, 45, 45, 32, 99,104, 97,105,110,115, 32, 97, 32,115,105,110,107, 32, +119,105,116,104, 32,111,110,101, 32,111,114, 32,115,101,118,101,114, 97,108, 32, +102,105,108,116,101,114, 40,115, 41, 10,102,117,110, 99,116,105,111,110, 32,115, +105,110,107, 46, 99,104, 97,105,110, 40,102, 44, 32,115,110,107, 44, 32, 46, 46, + 46, 41, 10, 32, 32, 32, 32,105,102, 32, 46, 46, 46, 32,116,104,101,110, 10, 32, + 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, 97,114,103,115, 32, 61, 32, +123, 32,102, 44, 32,115,110,107, 44, 32, 46, 46, 46, 32,125, 10, 32, 32, 32, 32, + 32, 32, 32, 32,115,110,107, 32, 61, 32,116, 97, 98,108,101, 46,114,101,109,111, +118,101, 40, 97,114,103,115, 44, 32, 35, 97,114,103,115, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32,102, 32, 61, 32,102,105,108,116,101,114, 46, 99,104, 97,105,110, + 40,117,110,112, 97, 99,107, 40, 97,114,103,115, 41, 41, 10, 32, 32, 32, 32,101, +110,100, 10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115,115,101,114,116, 40,102, + 32, 97,110,100, 32,115,110,107, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, + 32,102,117,110, 99,116,105,111,110, 40, 99,104,117,110,107, 44, 32,101,114,114, + 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104,117,110,107, 32,126, + 61, 32, 34, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,108,111, 99, 97,108, 32,102,105,108,116,101,114,101,100, 32, 61, 32,102, + 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +108,111, 99, 97,108, 32,100,111,110,101, 32, 61, 32, 99,104,117,110,107, 32, 97, +110,100, 32, 34, 34, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,119,104, +105,108,101, 32,116,114,117,101, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,116, 44, 32,115, +110,107,101,114,114, 32, 61, 32,115,110,107, 40,102,105,108,116,101,114,101,100, + 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,105,102, 32,110,111,116, 32,114,101,116, 32,116,104,101,110, 32,114, +101,116,117,114,110, 32,110,105,108, 44, 32,115,110,107,101,114,114, 32,101,110, +100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, + 32,102,105,108,116,101,114,101,100, 32, 61, 61, 32,100,111,110,101, 32,116,104, +101,110, 32,114,101,116,117,114,110, 32, 49, 32,101,110,100, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,102,105,108,116,101,114,101,100, + 32, 61, 32,102, 40,100,111,110,101, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32, +114,101,116,117,114,110, 32, 49, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, + 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 10, 45, 45, 32,112,117,109,112,115, 32,111,110,101, 32, 99,104, -117,110,107, 32,102,114,111,109, 32,116,104,101, 32,115,111,117,114, 99,101, 32, -116,111, 32,116,104,101, 32,115,105,110,107, 10,102,117,110, 99,116,105,111,110, - 32,112,117,109,112, 46,115,116,101,112, 40,115,114, 99, 44, 32,115,110,107, 41, - 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104,117,110,107, 44, 32,115,114, - 99, 95,101,114,114, 32, 61, 32,115,114, 99, 40, 41, 10, 32, 32, 32, 32,108,111, - 99, 97,108, 32,114,101,116, 44, 32,115,110,107, 95,101,114,114, 32, 61, 32,115, -110,107, 40, 99,104,117,110,107, 44, 32,115,114, 99, 95,101,114,114, 41, 10, 32, - 32, 32, 32,105,102, 32, 99,104,117,110,107, 32, 97,110,100, 32,114,101,116, 32, -116,104,101,110, 32,114,101,116,117,114,110, 32, 49, 10, 32, 32, 32, 32,101,108, -115,101, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,115,114, 99, 95,101, -114,114, 32,111,114, 32,115,110,107, 95,101,114,114, 32,101,110,100, 10,101,110, -100, 10, 10, 45, 45, 32,112,117,109,112,115, 32, 97,108,108, 32,100, 97,116, 97, - 32,102,114,111,109, 32, 97, 32,115,111,117,114, 99,101, 32,116,111, 32, 97, 32, -115,105,110,107, 44, 32,117,115,105,110,103, 32, 97, 32,115,116,101,112, 32,102, -117,110, 99,116,105,111,110, 10,102,117,110, 99,116,105,111,110, 32,112,117,109, -112, 46, 97,108,108, 40,115,114, 99, 44, 32,115,110,107, 44, 32,115,116,101,112, - 41, 10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115,115,101,114,116, 40,115,114, - 99, 32, 97,110,100, 32,115,110,107, 41, 10, 32, 32, 32, 32,115,116,101,112, 32, - 61, 32,115,116,101,112, 32,111,114, 32,112,117,109,112, 46,115,116,101,112, 10, - 32, 32, 32, 32,119,104,105,108,101, 32,116,114,117,101, 32,100,111, 10, 32, 32, - 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,116, 44, 32,101,114,114, - 32, 61, 32,115,116,101,112, 40,115,114, 99, 44, 32,115,110,107, 41, 10, 32, 32, - 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,101,116, 32,116,104,101, -110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114, - 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114, -114, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,114, -101,116,117,114,110, 32, 49, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, -101,110,100, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, + 45, 45, 45, 10, 45, 45, 32, 80,117,109,112, 32,115,116,117,102,102, 10, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32,112, +117,109,112,115, 32,111,110,101, 32, 99,104,117,110,107, 32,102,114,111,109, 32, +116,104,101, 32,115,111,117,114, 99,101, 32,116,111, 32,116,104,101, 32,115,105, +110,107, 10,102,117,110, 99,116,105,111,110, 32,112,117,109,112, 46,115,116,101, +112, 40,115,114, 99, 44, 32,115,110,107, 41, 10, 32, 32, 32, 32,108,111, 99, 97, +108, 32, 99,104,117,110,107, 44, 32,115,114, 99, 95,101,114,114, 32, 61, 32,115, +114, 99, 40, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,116, 44, 32, +115,110,107, 95,101,114,114, 32, 61, 32,115,110,107, 40, 99,104,117,110,107, 44, + 32,115,114, 99, 95,101,114,114, 41, 10, 32, 32, 32, 32,105,102, 32, 99,104,117, +110,107, 32, 97,110,100, 32,114,101,116, 32,116,104,101,110, 32,114,101,116,117, +114,110, 32, 49, 10, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, + 32,110,105,108, 44, 32,115,114, 99, 95,101,114,114, 32,111,114, 32,115,110,107, + 95,101,114,114, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32,112,117,109, +112,115, 32, 97,108,108, 32,100, 97,116, 97, 32,102,114,111,109, 32, 97, 32,115, +111,117,114, 99,101, 32,116,111, 32, 97, 32,115,105,110,107, 44, 32,117,115,105, +110,103, 32, 97, 32,115,116,101,112, 32,102,117,110, 99,116,105,111,110, 10,102, +117,110, 99,116,105,111,110, 32,112,117,109,112, 46, 97,108,108, 40,115,114, 99, + 44, 32,115,110,107, 44, 32,115,116,101,112, 41, 10, 32, 32, 32, 32, 98, 97,115, +101, 46, 97,115,115,101,114,116, 40,115,114, 99, 32, 97,110,100, 32,115,110,107, + 41, 10, 32, 32, 32, 32,115,116,101,112, 32, 61, 32,115,116,101,112, 32,111,114, + 32,112,117,109,112, 46,115,116,101,112, 10, 32, 32, 32, 32,119,104,105,108,101, + 32,116,114,117,101, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, + 97,108, 32,114,101,116, 44, 32,101,114,114, 32, 61, 32,115,116,101,112, 40,115, +114, 99, 44, 32,115,110,107, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, +110,111,116, 32,114,101,116, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104,101,110, 32,114,101,116, +117,114,110, 32,110,105,108, 44, 32,101,114,114, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32, 49, 32,101, +110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,101, +110,100, 10,101,110,100, 10, 10,114,101,116,117,114,110, 32, 95, 77, 10, }; - if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"ltn12.lua")==0) lua_call(L, 0, 0); + if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"ltn12.lua")==0) lua_call(L, 0, LUA_MULTRET); } diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/lua.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/lua.h deleted file mode 100644 index a280df84..00000000 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/lua.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef LUA_WRAP_H -#define LUA_WRAP_H - -#define LUA_COMPAT_ALL -#include -#include -#include - -#if LUA_VERSION_NUM > 501 -# define luaL_reg luaL_Reg -# define luaL_putchar(B, c) luaL_addchar(B, c) -# define luaL_typerror(L, n, t) luax_typerror(L, n, t) - -extern int luax_typerror(lua_State *L, int narg, const char *type); -#endif - -#endif // LUA_WRAP_H diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/luasocket.c b/love/src/jni/love/src/libraries/luasocket/libluasocket/luasocket.c index a60090e7..7d9c8023 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/luasocket.c +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/luasocket.c @@ -10,8 +10,6 @@ * involved in setting up both client and server connections. The provided * IO routines, however, follow the Lua style, being very similar to the * standard Lua read and write functions. -* -* RCS ID: $Id: luasocket.c,v 1.53 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ /*=========================================================================*\ @@ -19,10 +17,7 @@ \*=========================================================================*/ #include "lua.h" #include "lauxlib.h" - -#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501) -#include "compat-5.1.h" -#endif +#include "compat.h" /*=========================================================================*\ * LuaSocket includes @@ -37,8 +32,6 @@ #include "udp.h" #include "select.h" -extern void luax_register(lua_State *L, const char *name, const luaL_Reg *l); - /*-------------------------------------------------------------------------*\ * Internal function prototypes \*-------------------------------------------------------------------------*/ @@ -49,7 +42,7 @@ static int base_open(lua_State *L); /*-------------------------------------------------------------------------*\ * Modules and functions \*-------------------------------------------------------------------------*/ -static const luaL_reg mod[] = { +static const luaL_Reg mod[] = { {"auxiliar", auxiliar_open}, {"except", except_open}, {"timeout", timeout_open}, @@ -61,7 +54,7 @@ static const luaL_reg mod[] = { {NULL, NULL} }; -static luaL_reg func[] = { +static luaL_Reg func[] = { {"skip", global_skip}, {"__unload", global_unload}, {NULL, NULL} @@ -71,7 +64,7 @@ static luaL_reg func[] = { * Skip a few arguments \*-------------------------------------------------------------------------*/ static int global_skip(lua_State *L) { - int amount = (int) luaL_checknumber(L, 1); + int amount = luaL_checkinteger(L, 1); int ret = lua_gettop(L) - amount - 1; return ret >= 0 ? ret : 0; } @@ -91,7 +84,8 @@ static int global_unload(lua_State *L) { static int base_open(lua_State *L) { if (socket_open()) { /* export functions (and leave namespace table on top of stack) */ - luax_register(L, "socket", func); + lua_newtable(L); + luaL_setfuncs(L, func, 0); #ifdef LUASOCKET_DEBUG lua_pushstring(L, "_DEBUG"); lua_pushboolean(L, 1); @@ -112,7 +106,7 @@ static int base_open(lua_State *L) { /*-------------------------------------------------------------------------*\ * Initializes all library modules. \*-------------------------------------------------------------------------*/ -int LUASOCKET_API luaopen_socket_core(lua_State *L) { +LUASOCKET_API int luaopen_socket_core(lua_State *L) { int i; base_open(L); for (i = 0; mod[i].name; i++) mod[i].func(L); diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/luasocket.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/luasocket.h index 67270abb..3957c59f 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/luasocket.h +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/luasocket.h @@ -5,23 +5,24 @@ * Networking support for the Lua language * Diego Nehab * 9/11/1999 -* -* RCS ID: $Id: luasocket.h,v 1.25 2007/06/11 23:44:54 diego Exp $ \*=========================================================================*/ #include "lua.h" /*-------------------------------------------------------------------------*\ * Current socket library version \*-------------------------------------------------------------------------*/ -#define LUASOCKET_VERSION "LuaSocket 2.0.2" -#define LUASOCKET_COPYRIGHT "Copyright (C) 2004-2007 Diego Nehab" -#define LUASOCKET_AUTHORS "Diego Nehab" +#define LUASOCKET_VERSION "LuaSocket 3.0-rc1" +#define LUASOCKET_COPYRIGHT "Copyright (C) 1999-2013 Diego Nehab" /*-------------------------------------------------------------------------*\ * This macro prefixes all exported API functions \*-------------------------------------------------------------------------*/ #ifndef LUASOCKET_API -#define LUASOCKET_API extern +#if defined(WIN32) || defined(_WIN32) +# define LUASOCKET_API __declspec(dllexport) +#else +# define LUASOCKET_API __attribute__((visibility("default"))) +#endif #endif /*-------------------------------------------------------------------------*\ diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/makefile b/love/src/jni/love/src/libraries/luasocket/libluasocket/makefile new file mode 100644 index 00000000..2ffd7d9d --- /dev/null +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/makefile @@ -0,0 +1,438 @@ +# luasocket src/makefile +# +# Definitions in this section can be overriden on the command line or in the +# environment. +# +# These are equivalent: +# +# export PLAT=linux DEBUG=DEBUG LUAV=5.2 prefix=/sw +# make +# +# and +# +# make PLAT=linux DEBUG=DEBUG LUAV=5.2 prefix=/sw + +# PLAT: linux macosx win32 mingw +# platform to build for +PLAT?=linux + +# LUAV: 5.1 5.2 +# lua version to build against +LUAV?=5.1 + +# MYCFLAGS: to be set by user if needed +MYCFLAGS?= + +# MYLDFLAGS: to be set by user if needed +MYLDFLAGS?= + +# DEBUG: NODEBUG DEBUG +# debug mode causes luasocket to collect and returns timing information useful +# for testing and debugging luasocket itself +DEBUG?=NODEBUG + +# where lua headers are found for macosx builds +# LUAINC_macosx: +# /opt/local/include +LUAINC_macosx_base?=/opt/local/include +LUAINC_macosx?=$(LUAINC_macosx_base)/lua/$(LUAV) +# FIXME default should this default to fink or to macports? +# What happens when more than one Lua version is installed? +LUAPREFIX_macosx?=/opt/local +CDIR_macosx?=lib/lua/$(LUAV) +LDIR_macosx?=share/lua/$(LUAV) + +# LUAINC_linux: +# /usr/include/lua$(LUAV) +# /usr/local/include +# /usr/local/include/lua$(LUAV) +# where lua headers are found for linux builds +LUAINC_linux_base?=/usr/include +LUAINC_linux?=$(LUAINC_linux_base)/lua/$(LUAV) +LUAPREFIX_linux?=/usr/local +CDIR_linux?=lib/lua/$(LUAV) +LDIR_linux?=share/lua/$(LUAV) + +# LUAINC_freebsd: +# /usr/local/include/lua$(LUAV) +# where lua headers are found for freebsd builds +LUAINC_freebsd_base?=/usr/local/include/ +LUAINC_freebsd?=$(LUAINC_freebsd_base)/lua$(LUAV) +LUAPREFIX_freebsd?=/usr/local/ +CDIR_freebsd?=lib/lua/$(LUAV) +LDIR_freebsd?=share/lua/$(LUAV) + +# where lua headers are found for mingw builds +# LUAINC_mingw: +# /opt/local/include +LUAINC_mingw_base?=/usr/include +LUAINC_mingw?=$(LUAINC_mingw_base)/lua/$(LUAV) +LUALIB_mingw_base?=/usr/bin +LUALIB_mingw?=$(LUALIB_mingw_base)/lua/$(LUAV)/lua$(subst .,,$(LUAV)).dll +LUAPREFIX_mingw?=/usr +CDIR_mingw?=lua/$(LUAV) +LDIR_mingw?=lua/$(LUAV)/lua + + +# LUAINC_win32: +# LUALIB_win32: +# where lua headers and libraries are found for win32 builds +LUAPREFIX_win32?= +LUAINC_win32?=$(LUAPREFIX_win32)/include/lua/$(LUAV) +PLATFORM_win32?=Release +CDIR_win32?=bin/lua/$(LUAV)/$(PLATFORM_win32) +LDIR_win32?=bin/lua/$(LUAV)/$(PLATFORM_win32)/lua +LUALIB_win32?=$(LUAPREFIX_win32)/lib/lua/$(LUAV)/$(PLATFORM_win32) +LUALIBNAME_win32?=lua$(subst .,,$(LUAV)).lib + + +# LUAINC_solaris: +LUAINC_solaris_base?=/usr/include +LUAINC_solaris?=$(LUAINC_solaris_base)/lua/$(LUAV) +LUAPREFIX_solaris?=/usr/local +CDIR_solaris?=lib/lua/$(LUAV) +LDIR_solaris?=share/lua/$(LUAV) + +# prefix: /usr/local /usr /opt/local /sw +# the top of the default install tree +prefix?=$(LUAPREFIX_$(PLAT)) + +CDIR?=$(CDIR_$(PLAT)) +LDIR?=$(LDIR_$(PLAT)) + +# DESTDIR: (no default) +# used by package managers to install into a temporary destination +DESTDIR= + +#------ +# Definitions below can be overridden on the make command line, but +# shouldn't have to be. + + +#------ +# Install directories +# + +INSTALL_DIR=install -d +INSTALL_DATA=install -m644 +INSTALL_EXEC=install +INSTALL_TOP=$(DESTDIR)$(prefix) + +INSTALL_TOP_LDIR=$(INSTALL_TOP)/$(LDIR) +INSTALL_TOP_CDIR=$(INSTALL_TOP)/$(CDIR) + +INSTALL_SOCKET_LDIR=$(INSTALL_TOP_LDIR)/socket +INSTALL_SOCKET_CDIR=$(INSTALL_TOP_CDIR)/socket +INSTALL_MIME_LDIR=$(INSTALL_TOP_LDIR)/mime +INSTALL_MIME_CDIR=$(INSTALL_TOP_CDIR)/mime + +print: + @echo PLAT=$(PLAT) + @echo LUAV=$(LUAV) + @echo DEBUG=$(DEBUG) + @echo prefix=$(prefix) + @echo LUAINC_$(PLAT)=$(LUAINC_$(PLAT)) + @echo LUALIB_$(PLAT)=$(LUALIB_$(PLAT)) + @echo INSTALL_TOP_CDIR=$(INSTALL_TOP_CDIR) + @echo INSTALL_TOP_LDIR=$(INSTALL_TOP_LDIR) + @echo CFLAGS=$(CFLAGS) + @echo LDFLAGS=$(LDFLAGS) + +#------ +# Supported platforms +# +PLATS= macosx linux win32 mingw solaris + +#------ +# Compiler and linker settings +# for Mac OS X +SO_macosx=so +O_macosx=o +CC_macosx=gcc +DEF_macosx= -DLUASOCKET_$(DEBUG) -DUNIX_HAS_SUN_LEN \ + -DLUASOCKET_API='__attribute__((visibility("default")))' \ + -DUNIX_API='__attribute__((visibility("default")))' \ + -DMIME_API='__attribute__((visibility("default")))' +CFLAGS_macosx= -I$(LUAINC) $(DEF) -Wall -O2 -fno-common \ + -fvisibility=hidden +LDFLAGS_macosx= -bundle -undefined dynamic_lookup -o +LD_macosx= export MACOSX_DEPLOYMENT_TARGET="10.3"; gcc +SOCKET_macosx=usocket.o + +#------ +# Compiler and linker settings +# for Linux +SO_linux=so +O_linux=o +CC_linux=gcc +DEF_linux=-DLUASOCKET_$(DEBUG) \ + -DLUASOCKET_API='__attribute__((visibility("default")))' \ + -DUNIX_API='__attribute__((visibility("default")))' \ + -DMIME_API='__attribute__((visibility("default")))' +CFLAGS_linux= -I$(LUAINC) $(DEF) -Wall -Wshadow -Wextra \ + -Wimplicit -O2 -ggdb3 -fpic -fvisibility=hidden +LDFLAGS_linux=-O -shared -fpic -o +LD_linux=gcc +SOCKET_linux=usocket.o + +#------ +# Compiler and linker settings +# for FreeBSD +SO_freebsd=so +O_freebsd=o +CC_freebsd=gcc +DEF_freebsd=-DLUASOCKET_$(DEBUG) \ + -DLUASOCKET_API='__attribute__((visibility("default")))' \ + -DUNIX_API='__attribute__((visibility("default")))' \ + -DMIME_API='__attribute__((visibility("default")))' +CFLAGS_freebsd= -I$(LUAINC) $(DEF) -Wall -Wshadow -Wextra \ + -Wimplicit -O2 -ggdb3 -fpic -fvisibility=hidden +LDFLAGS_freebsd=-O -shared -fpic -o +LD_freebsd=gcc +SOCKET_freebsd=usocket.o + +#------ +# Compiler and linker settings +# for Solaris +SO_solaris=so +O_solaris=o +CC_solaris=gcc +DEF_solaris=-DLUASOCKET_$(DEBUG) \ + -DLUASOCKET_API='__attribute__((visibility("default")))' \ + -DUNIX_API='__attribute__((visibility("default")))' \ + -DMIME_API='__attribute__((visibility("default")))' +CFLAGS_solaris=-I$(LUAINC) $(DEF) -Wall -Wshadow -Wextra \ + -Wimplicit -O2 -ggdb3 -fpic -fvisibility=hidden +LDFLAGS_solaris=-lnsl -lsocket -lresolv -O -shared -fpic -o +LD_solaris=gcc +SOCKET_solaris=usocket.o + +#------ +# Compiler and linker settings +# for MingW +SO_mingw=dll +O_mingw=o +CC_mingw=gcc +DEF_mingw= -DLUASOCKET_INET_PTON -DLUASOCKET_$(DEBUG) \ + -DWINVER=0x0501 -DLUASOCKET_API='__declspec(dllexport)' \ + -DMIME_API='__declspec(dllexport)' +CFLAGS_mingw= -I$(LUAINC) $(DEF) -Wall -O2 -fno-common \ + -fvisibility=hidden +LDFLAGS_mingw= $(LUALIB) -shared -Wl,-s -lws2_32 -o +LD_mingw=gcc +SOCKET_mingw=wsocket.o + + +#------ +# Compiler and linker settings +# for Win32 +SO_win32=dll +O_win32=obj +CC_win32=cl +DEF_win32= //D "WIN32" //D "NDEBUG" //D "_WINDOWS" //D "_USRDLL" \ + //D "LUASOCKET_API=__declspec(dllexport)" //D "_CRT_SECURE_NO_WARNINGS" \ + //D "_WINDLL" //D "MIME_API=__declspec(dllexport)" \ + //D "LUASOCKET_$(DEBUG)" +CFLAGS_win32=//I "$(LUAINC)" $(DEF) //O2 //Ot //MD //W3 //nologo +LDFLAGS_win32= //nologo //link //NOLOGO //DLL //INCREMENTAL:NO \ + //MANIFEST //MANIFESTFILE:"intermediate.manifest" \ + //MANIFESTUAC:"level='asInvoker' uiAccess='false'" \ + //SUBSYSTEM:WINDOWS //OPT:REF //OPT:ICF //DYNAMICBASE:NO \ + //MACHINE:X86 /LIBPATH:"$(shell cmd //c echo $(LUALIB))" \ + $(LUALIBNAME_win32) ws2_32.lib //OUT: +LD_win32=cl +SOCKET_win32=wsocket.obj + +.SUFFIXES: .obj + +.c.obj: + $(CC) $(CFLAGS) //Fo"$@" //c $< + +#------ +# Output file names +# +SO=$(SO_$(PLAT)) +O=$(O_$(PLAT)) +SOCKET_V=3.0-rc1 +MIME_V=1.0.3 +SOCKET_SO=socket-$(SOCKET_V).$(SO) +MIME_SO=mime-$(MIME_V).$(SO) +UNIX_SO=unix.$(SO) +SERIAL_SO=serial.$(SO) +SOCKET=$(SOCKET_$(PLAT)) + +#------ +# Settings selected for platform +# +CC=$(CC_$(PLAT)) +DEF=$(DEF_$(PLAT)) +CFLAGS=$(MYCFLAGS) $(CFLAGS_$(PLAT)) +LDFLAGS=$(MYLDFLAGS) $(LDFLAGS_$(PLAT)) +LD=$(LD_$(PLAT)) +LUAINC= $(LUAINC_$(PLAT)) +LUALIB= $(LUALIB_$(PLAT)) + +#------ +# Modules belonging to socket-core +# +SOCKET_OBJS= \ + luasocket.$(O) \ + timeout.$(O) \ + buffer.$(O) \ + io.$(O) \ + auxiliar.$(O) \ + compat.$(O) \ + options.$(O) \ + inet.$(O) \ + $(SOCKET) \ + except.$(O) \ + select.$(O) \ + tcp.$(O) \ + udp.$(O) + +#------ +# Modules belonging mime-core +# +MIME_OBJS= \ + mime.$(O) \ + compat.$(O) + +#------ +# Modules belonging unix (local domain sockets) +# +UNIX_OBJS=\ + buffer.$(O) \ + auxiliar.$(O) \ + options.$(O) \ + timeout.$(O) \ + io.$(O) \ + usocket.$(O) \ + unixtcp.$(O) \ + unixudp.$(O) \ + compat.$(O) \ + unix.$(O) + +#------ +# Modules belonging to serial (device streams) +# +SERIAL_OBJS=\ + buffer.$(O) \ + auxiliar.$(O) \ + options.$(O) \ + timeout.$(O) \ + io.$(O) \ + usocket.$(O) \ + serial.$(O) + +#------ +# Files to install +# +TO_SOCKET_LDIR= \ + http.lua \ + url.lua \ + tp.lua \ + ftp.lua \ + headers.lua \ + smtp.lua + +TO_TOP_LDIR= \ + ltn12.lua \ + socket.lua \ + mime.lua + +#------ +# Targets +# +default: $(PLAT) + + +freebsd: + $(MAKE) all-unix PLAT=freebsd + +macosx: + $(MAKE) all-unix PLAT=macosx + +win32: + $(MAKE) all PLAT=win32 + +linux: + $(MAKE) all-unix PLAT=linux + +mingw: + $(MAKE) all PLAT=mingw + +solaris: + $(MAKE) all-unix PLAT=solaris + +none: + @echo "Please run" + @echo " make PLATFORM" + @echo "where PLATFORM is one of these:" + @echo " $(PLATS)" + +all: $(SOCKET_SO) $(MIME_SO) + +$(SOCKET_SO): $(SOCKET_OBJS) + $(LD) $(SOCKET_OBJS) $(LDFLAGS)$@ + +$(MIME_SO): $(MIME_OBJS) + $(LD) $(MIME_OBJS) $(LDFLAGS)$@ + +all-unix: all $(UNIX_SO) $(SERIAL_SO) + +$(UNIX_SO): $(UNIX_OBJS) + $(LD) $(UNIX_OBJS) $(LDFLAGS)$@ + +$(SERIAL_SO): $(SERIAL_OBJS) + $(LD) $(SERIAL_OBJS) $(LDFLAGS)$@ + +install: + $(INSTALL_DIR) $(INSTALL_TOP_LDIR) + $(INSTALL_DATA) $(TO_TOP_LDIR) $(INSTALL_TOP_LDIR) + $(INSTALL_DIR) $(INSTALL_SOCKET_LDIR) + $(INSTALL_DATA) $(TO_SOCKET_LDIR) $(INSTALL_SOCKET_LDIR) + $(INSTALL_DIR) $(INSTALL_SOCKET_CDIR) + $(INSTALL_EXEC) $(SOCKET_SO) $(INSTALL_SOCKET_CDIR)/core.$(SO) + $(INSTALL_DIR) $(INSTALL_MIME_CDIR) + $(INSTALL_EXEC) $(MIME_SO) $(INSTALL_MIME_CDIR)/core.$(SO) + +install-unix: install + $(INSTALL_EXEC) $(UNIX_SO) $(INSTALL_SOCKET_CDIR)/$(UNIX_SO) + $(INSTALL_EXEC) $(SERIAL_SO) $(INSTALL_SOCKET_CDIR)/$(SERIAL_SO) + +local: + $(MAKE) install INSTALL_TOP_CDIR=.. INSTALL_TOP_LDIR=.. + +clean: + rm -f $(SOCKET_SO) $(SOCKET_OBJS) $(SERIAL_OBJS) + rm -f $(MIME_SO) $(UNIX_SO) $(SERIAL_SO) $(MIME_OBJS) $(UNIX_OBJS) + +.PHONY: all $(PLATS) default clean echo none + +#------ +# List of dependencies +# +compat.$(O): compat.c compat.h +auxiliar.$(O): auxiliar.c auxiliar.h +buffer.$(O): buffer.c buffer.h io.h timeout.h +except.$(O): except.c except.h +inet.$(O): inet.c inet.h socket.h io.h timeout.h usocket.h +io.$(O): io.c io.h timeout.h +luasocket.$(O): luasocket.c luasocket.h auxiliar.h except.h \ + timeout.h buffer.h io.h inet.h socket.h usocket.h tcp.h \ + udp.h select.h +mime.$(O): mime.c mime.h +options.$(O): options.c auxiliar.h options.h socket.h io.h \ + timeout.h usocket.h inet.h +select.$(O): select.c socket.h io.h timeout.h usocket.h select.h +serial.$(O): serial.c auxiliar.h socket.h io.h timeout.h usocket.h \ + options.h unix.h buffer.h +tcp.$(O): tcp.c auxiliar.h socket.h io.h timeout.h usocket.h \ + inet.h options.h tcp.h buffer.h +timeout.$(O): timeout.c auxiliar.h timeout.h +udp.$(O): udp.c auxiliar.h socket.h io.h timeout.h usocket.h \ + inet.h options.h udp.h +unix.$(O): unix.c auxiliar.h socket.h io.h timeout.h usocket.h \ + options.h unix.h buffer.h +usocket.$(O): usocket.c socket.h io.h timeout.h usocket.h +wsocket.$(O): wsocket.c socket.h io.h timeout.h usocket.h diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/mbox.lua b/love/src/jni/love/src/libraries/luasocket/libluasocket/mbox.lua new file mode 100644 index 00000000..ed9e7814 --- /dev/null +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/mbox.lua @@ -0,0 +1,92 @@ +local _M = {} + +if module then + mbox = _M +end + +function _M.split_message(message_s) + local message = {} + message_s = string.gsub(message_s, "\r\n", "\n") + string.gsub(message_s, "^(.-\n)\n", function (h) message.headers = h end) + string.gsub(message_s, "^.-\n\n(.*)", function (b) message.body = b end) + if not message.body then + string.gsub(message_s, "^\n(.*)", function (b) message.body = b end) + end + if not message.headers and not message.body then + message.headers = message_s + end + return message.headers or "", message.body or "" +end + +function _M.split_headers(headers_s) + local headers = {} + headers_s = string.gsub(headers_s, "\r\n", "\n") + headers_s = string.gsub(headers_s, "\n[ ]+", " ") + string.gsub("\n" .. headers_s, "\n([^\n]+)", function (h) table.insert(headers, h) end) + return headers +end + +function _M.parse_header(header_s) + header_s = string.gsub(header_s, "\n[ ]+", " ") + header_s = string.gsub(header_s, "\n+", "") + local _, __, name, value = string.find(header_s, "([^%s:]-):%s*(.*)") + return name, value +end + +function _M.parse_headers(headers_s) + local headers_t = _M.split_headers(headers_s) + local headers = {} + for i = 1, #headers_t do + local name, value = _M.parse_header(headers_t[i]) + if name then + name = string.lower(name) + if headers[name] then + headers[name] = headers[name] .. ", " .. value + else headers[name] = value end + end + end + return headers +end + +function _M.parse_from(from) + local _, __, name, address = string.find(from, "^%s*(.-)%s*%<(.-)%>") + if not address then + _, __, address = string.find(from, "%s*(.+)%s*") + end + name = name or "" + address = address or "" + if name == "" then name = address end + name = string.gsub(name, '"', "") + return name, address +end + +function _M.split_mbox(mbox_s) + local mbox = {} + mbox_s = string.gsub(mbox_s, "\r\n", "\n") .."\n\nFrom \n" + local nj, i, j = 1, 1, 1 + while 1 do + i, nj = string.find(mbox_s, "\n\nFrom .-\n", j) + if not i then break end + local message = string.sub(mbox_s, j, i-1) + table.insert(mbox, message) + j = nj+1 + end + return mbox +end + +function _M.parse(mbox_s) + local mbox = _M.split_mbox(mbox_s) + for i = 1, #mbox do + mbox[i] = _M.parse_message(mbox[i]) + end + return mbox +end + +function _M.parse_message(message_s) + local message = {} + message.headers, message.body = _M.split_message(message_s) + message.headers = _M.parse_headers(message.headers) + return message +end + +return _M diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/mbox.lua.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/mbox.lua.h new file mode 100644 index 00000000..f3edca97 --- /dev/null +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/mbox.lua.h @@ -0,0 +1,144 @@ +/* code automatically generated by bin2c -- DO NOT EDIT */ +{ +/* #include'ing this file in a C program is equivalent to calling + if (luaL_loadfile(L,"mbox.lua")==0) lua_call(L, 0, LUA_MULTRET); +*/ +/* mbox.lua */ +static const unsigned char B1[]={ +108,111, 99, 97,108, 32, 95, 77, 32, 61, 32,123,125, 10, 10,105,102, 32,109,111, +100,117,108,101, 32,116,104,101,110, 10, 32, 32, 32, 32,109, 98,111,120, 32, 61, + 32, 95, 77, 10,101,110,100, 32, 10, 10,102,117,110, 99,116,105,111,110, 32, 95, + 77, 46,115,112,108,105,116, 95,109,101,115,115, 97,103,101, 40,109,101,115,115, + 97,103,101, 95,115, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,109,101,115, +115, 97,103,101, 32, 61, 32,123,125, 10, 32, 32, 32, 32,109,101,115,115, 97,103, +101, 95,115, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,109,101, +115,115, 97,103,101, 95,115, 44, 32, 34, 92,114, 92,110, 34, 44, 32, 34, 92,110, + 34, 41, 10, 32, 32, 32, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,109, +101,115,115, 97,103,101, 95,115, 44, 32, 34, 94, 40, 46, 45, 92,110, 41, 92,110, + 34, 44, 32,102,117,110, 99,116,105,111,110, 32, 40,104, 41, 32,109,101,115,115, + 97,103,101, 46,104,101, 97,100,101,114,115, 32, 61, 32,104, 32,101,110,100, 41, + 10, 32, 32, 32, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,109,101,115, +115, 97,103,101, 95,115, 44, 32, 34, 94, 46, 45, 92,110, 92,110, 40, 46, 42, 41, + 34, 44, 32,102,117,110, 99,116,105,111,110, 32, 40, 98, 41, 32,109,101,115,115, + 97,103,101, 46, 98,111,100,121, 32, 61, 32, 98, 32,101,110,100, 41, 10, 32, 32, + 32, 32,105,102, 32,110,111,116, 32,109,101,115,115, 97,103,101, 46, 98,111,100, +121, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,116,114,105,110, +103, 46,103,115,117, 98, 40,109,101,115,115, 97,103,101, 95,115, 44, 32, 34, 94, + 92,110, 40, 46, 42, 41, 34, 44, 32,102,117,110, 99,116,105,111,110, 32, 40, 98, + 41, 32,109,101,115,115, 97,103,101, 46, 98,111,100,121, 32, 61, 32, 98, 32,101, +110,100, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,105,102, 32,110, +111,116, 32,109,101,115,115, 97,103,101, 46,104,101, 97,100,101,114,115, 32, 97, +110,100, 32,110,111,116, 32,109,101,115,115, 97,103,101, 46, 98,111,100,121, 32, +116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,109,101,115,115, 97,103,101, + 46,104,101, 97,100,101,114,115, 32, 61, 32,109,101,115,115, 97,103,101, 95,115, + 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, +109,101,115,115, 97,103,101, 46,104,101, 97,100,101,114,115, 32,111,114, 32, 34, + 34, 44, 32,109,101,115,115, 97,103,101, 46, 98,111,100,121, 32,111,114, 32, 34, + 34, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32, 95, 77, 46,115, +112,108,105,116, 95,104,101, 97,100,101,114,115, 40,104,101, 97,100,101,114,115, + 95,115, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104,101, 97,100,101,114, +115, 32, 61, 32,123,125, 10, 32, 32, 32, 32,104,101, 97,100,101,114,115, 95,115, + 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,104,101, 97,100,101, +114,115, 95,115, 44, 32, 34, 92,114, 92,110, 34, 44, 32, 34, 92,110, 34, 41, 10, + 32, 32, 32, 32,104,101, 97,100,101,114,115, 95,115, 32, 61, 32,115,116,114,105, +110,103, 46,103,115,117, 98, 40,104,101, 97,100,101,114,115, 95,115, 44, 32, 34, + 92,110, 91, 32, 93, 43, 34, 44, 32, 34, 32, 34, 41, 10, 32, 32, 32, 32,115,116, +114,105,110,103, 46,103,115,117, 98, 40, 34, 92,110, 34, 32, 46, 46, 32,104,101, + 97,100,101,114,115, 95,115, 44, 32, 34, 92,110, 40, 91, 94, 92,110, 93, 43, 41, + 34, 44, 32,102,117,110, 99,116,105,111,110, 32, 40,104, 41, 32,116, 97, 98,108, +101, 46,105,110,115,101,114,116, 40,104,101, 97,100,101,114,115, 44, 32,104, 41, + 32,101,110,100, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,104,101, 97, +100,101,114,115, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32, 95, + 77, 46,112, 97,114,115,101, 95,104,101, 97,100,101,114, 40,104,101, 97,100,101, +114, 95,115, 41, 10, 32, 32, 32, 32,104,101, 97,100,101,114, 95,115, 32, 61, 32, +115,116,114,105,110,103, 46,103,115,117, 98, 40,104,101, 97,100,101,114, 95,115, + 44, 32, 34, 92,110, 91, 32, 93, 43, 34, 44, 32, 34, 32, 34, 41, 10, 32, 32, 32, + 32,104,101, 97,100,101,114, 95,115, 32, 61, 32,115,116,114,105,110,103, 46,103, +115,117, 98, 40,104,101, 97,100,101,114, 95,115, 44, 32, 34, 92,110, 43, 34, 44, + 32, 34, 34, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 95, 44, 32, 95, 95, + 44, 32,110, 97,109,101, 44, 32,118, 97,108,117,101, 32, 61, 32,115,116,114,105, +110,103, 46,102,105,110,100, 40,104,101, 97,100,101,114, 95,115, 44, 32, 34, 40, + 91, 94, 37,115, 58, 93, 45, 41, 58, 37,115, 42, 40, 46, 42, 41, 34, 41, 10, 32, + 32, 32, 32,114,101,116,117,114,110, 32,110, 97,109,101, 44, 32,118, 97,108,117, +101, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32, 95, 77, 46,112, + 97,114,115,101, 95,104,101, 97,100,101,114,115, 40,104,101, 97,100,101,114,115, + 95,115, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104,101, 97,100,101,114, +115, 95,116, 32, 61, 32, 95, 77, 46,115,112,108,105,116, 95,104,101, 97,100,101, +114,115, 40,104,101, 97,100,101,114,115, 95,115, 41, 10, 32, 32, 32, 32,108,111, + 99, 97,108, 32,104,101, 97,100,101,114,115, 32, 61, 32,123,125, 10, 32, 32, 32, + 32,102,111,114, 32,105, 32, 61, 32, 49, 44, 32, 35,104,101, 97,100,101,114,115, + 95,116, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, +110, 97,109,101, 44, 32,118, 97,108,117,101, 32, 61, 32, 95, 77, 46,112, 97,114, +115,101, 95,104,101, 97,100,101,114, 40,104,101, 97,100,101,114,115, 95,116, 91, +105, 93, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110, 97,109,101, 32, +116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,110, 97,109, +101, 32, 61, 32,115,116,114,105,110,103, 46,108,111,119,101,114, 40,110, 97,109, +101, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,104,101, + 97,100,101,114,115, 91,110, 97,109,101, 93, 32,116,104,101,110, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,104,101, 97,100,101,114,115, + 91,110, 97,109,101, 93, 32, 61, 32,104,101, 97,100,101,114,115, 91,110, 97,109, +101, 93, 32, 46, 46, 32, 34, 44, 32, 34, 32, 46, 46, 32,118, 97,108,117,101, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,104,101, 97, +100,101,114,115, 91,110, 97,109,101, 93, 32, 61, 32,118, 97,108,117,101, 32,101, +110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,101, +110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,104,101, 97,100,101,114, +115, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32, 95, 77, 46,112, + 97,114,115,101, 95,102,114,111,109, 40,102,114,111,109, 41, 10, 32, 32, 32, 32, +108,111, 99, 97,108, 32, 95, 44, 32, 95, 95, 44, 32,110, 97,109,101, 44, 32, 97, +100,100,114,101,115,115, 32, 61, 32,115,116,114,105,110,103, 46,102,105,110,100, + 40,102,114,111,109, 44, 32, 34, 94, 37,115, 42, 40, 46, 45, 41, 37,115, 42, 37, + 60, 40, 46, 45, 41, 37, 62, 34, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, + 32, 97,100,100,114,101,115,115, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 95, 44, 32, 95, 95, 44, 32, 97,100,100,114,101,115,115, 32, 61, 32,115, +116,114,105,110,103, 46,102,105,110,100, 40,102,114,111,109, 44, 32, 34, 37,115, + 42, 40, 46, 43, 41, 37,115, 42, 34, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, + 32, 32, 32,110, 97,109,101, 32, 61, 32,110, 97,109,101, 32,111,114, 32, 34, 34, + 10, 32, 32, 32, 32, 97,100,100,114,101,115,115, 32, 61, 32, 97,100,100,114,101, +115,115, 32,111,114, 32, 34, 34, 10, 32, 32, 32, 32,105,102, 32,110, 97,109,101, + 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 32,110, 97,109,101, 32, 61, 32, 97, +100,100,114,101,115,115, 32,101,110,100, 10, 32, 32, 32, 32,110, 97,109,101, 32, + 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,110, 97,109,101, 44, 32, + 39, 34, 39, 44, 32, 34, 34, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, +110, 97,109,101, 44, 32, 97,100,100,114,101,115,115, 10,101,110,100, 10, 10,102, +117,110, 99,116,105,111,110, 32, 95, 77, 46,115,112,108,105,116, 95,109, 98,111, +120, 40,109, 98,111,120, 95,115, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, +109, 98,111,120, 32, 61, 32,123,125, 10, 32, 32, 32, 32,109, 98,111,120, 95,115, + 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,109, 98,111,120, 95, +115, 44, 32, 34, 92,114, 92,110, 34, 44, 32, 34, 92,110, 34, 41, 32, 46, 46, 34, + 92,110, 92,110, 70,114,111,109, 32, 92,110, 34, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,110,106, 44, 32,105, 44, 32,106, 32, 61, 32, 49, 44, 32, 49, 44, 32, + 49, 10, 32, 32, 32, 32,119,104,105,108,101, 32, 49, 32,100,111, 10, 32, 32, 32, + 32, 32, 32, 32, 32,105, 44, 32,110,106, 32, 61, 32,115,116,114,105,110,103, 46, +102,105,110,100, 40,109, 98,111,120, 95,115, 44, 32, 34, 92,110, 92,110, 70,114, +111,109, 32, 46, 45, 92,110, 34, 44, 32,106, 41, 10, 32, 32, 32, 32, 32, 32, 32, + 32,105,102, 32,110,111,116, 32,105, 32,116,104,101,110, 32, 98,114,101, 97,107, + 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,109, +101,115,115, 97,103,101, 32, 61, 32,115,116,114,105,110,103, 46,115,117, 98, 40, +109, 98,111,120, 95,115, 44, 32,106, 44, 32,105, 45, 49, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32,116, 97, 98,108,101, 46,105,110,115,101,114,116, 40,109, 98,111, +120, 44, 32,109,101,115,115, 97,103,101, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, +106, 32, 61, 32,110,106, 43, 49, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, + 32,114,101,116,117,114,110, 32,109, 98,111,120, 10,101,110,100, 10, 10,102,117, +110, 99,116,105,111,110, 32, 95, 77, 46,112, 97,114,115,101, 40,109, 98,111,120, + 95,115, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,109, 98,111,120, 32, 61, + 32, 95, 77, 46,115,112,108,105,116, 95,109, 98,111,120, 40,109, 98,111,120, 95, +115, 41, 10, 32, 32, 32, 32,102,111,114, 32,105, 32, 61, 32, 49, 44, 32, 35,109, + 98,111,120, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32,109, 98,111,120, 91, +105, 93, 32, 61, 32, 95, 77, 46,112, 97,114,115,101, 95,109,101,115,115, 97,103, +101, 40,109, 98,111,120, 91,105, 93, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, + 32, 32, 32,114,101,116,117,114,110, 32,109, 98,111,120, 10,101,110,100, 10, 10, +102,117,110, 99,116,105,111,110, 32, 95, 77, 46,112, 97,114,115,101, 95,109,101, +115,115, 97,103,101, 40,109,101,115,115, 97,103,101, 95,115, 41, 10, 32, 32, 32, + 32,108,111, 99, 97,108, 32,109,101,115,115, 97,103,101, 32, 61, 32,123,125, 10, + 32, 32, 32, 32,109,101,115,115, 97,103,101, 46,104,101, 97,100,101,114,115, 44, + 32,109,101,115,115, 97,103,101, 46, 98,111,100,121, 32, 61, 32, 95, 77, 46,115, +112,108,105,116, 95,109,101,115,115, 97,103,101, 40,109,101,115,115, 97,103,101, + 95,115, 41, 10, 32, 32, 32, 32,109,101,115,115, 97,103,101, 46,104,101, 97,100, +101,114,115, 32, 61, 32, 95, 77, 46,112, 97,114,115,101, 95,104,101, 97,100,101, +114,115, 40,109,101,115,115, 97,103,101, 46,104,101, 97,100,101,114,115, 41, 10, + 32, 32, 32, 32,114,101,116,117,114,110, 32,109,101,115,115, 97,103,101, 10,101, +110,100, 10, 10,114,101,116,117,114,110, 32, 95, 77, 10, +}; + + if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"mbox.lua")==0) lua_call(L, 0, LUA_MULTRET); +} diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/mime.c b/love/src/jni/love/src/libraries/luasocket/libluasocket/mime.c index 66098911..ed441046 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/mime.c +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/mime.c @@ -1,22 +1,15 @@ /*=========================================================================*\ * MIME support functions * LuaSocket toolkit -* -* RCS ID: $Id: mime.c,v 1.28 2005/11/20 07:20:23 diego Exp $ \*=========================================================================*/ #include #include "lua.h" #include "lauxlib.h" - -#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501) -#include "compat-5.1.h" -#endif +#include "compat.h" #include "mime.h" -extern void luax_register(lua_State *L, const char *name, const luaL_Reg *l); - /*=========================================================================*\ * Don't want to trust escape character constants \*=========================================================================*/ @@ -37,20 +30,20 @@ static int mime_global_eol(lua_State *L); static int mime_global_dot(lua_State *L); static size_t dot(int c, size_t state, luaL_Buffer *buffer); -static void b64setup(UC *b64unbase); +static void b64setup(UC *base); static size_t b64encode(UC c, UC *input, size_t size, luaL_Buffer *buffer); static size_t b64pad(const UC *input, size_t size, luaL_Buffer *buffer); static size_t b64decode(UC c, UC *input, size_t size, luaL_Buffer *buffer); -static void qpsetup(UC *qpclass, UC *qpunbase); +static void qpsetup(UC *class, UC *unbase); static void qpquote(UC c, luaL_Buffer *buffer); static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer); -static size_t qpencode(UC c, UC *input, size_t size, +static size_t qpencode(UC c, UC *input, size_t size, const char *marker, luaL_Buffer *buffer); static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer); /* code support functions */ -static luaL_reg func[] = { +static luaL_Reg func[] = { { "dot", mime_global_dot }, { "b64", mime_global_b64 }, { "eol", mime_global_eol }, @@ -85,7 +78,8 @@ static UC b64unbase[256]; \*-------------------------------------------------------------------------*/ MIME_API int luaopen_mime_core(lua_State *L) { - luax_register(L, "mime", func); + lua_newtable(L); + luaL_setfuncs(L, func, 0); /* make version string available to scripts */ lua_pushstring(L, "_VERSION"); lua_pushstring(L, MIME_VERSION); @@ -102,15 +96,15 @@ MIME_API int luaopen_mime_core(lua_State *L) /*-------------------------------------------------------------------------*\ * Incrementaly breaks a string into lines. The string can have CRLF breaks. * A, n = wrp(l, B, length) -* A is a copy of B, broken into lines of at most 'length' bytes. -* 'l' is how many bytes are left for the first line of B. -* 'n' is the number of bytes left in the last line of A. +* A is a copy of B, broken into lines of at most 'length' bytes. +* 'l' is how many bytes are left for the first line of B. +* 'n' is the number of bytes left in the last line of A. \*-------------------------------------------------------------------------*/ static int mime_global_wrp(lua_State *L) { size_t size = 0; int left = (int) luaL_checknumber(L, 1); - const UC *input = (UC *) luaL_optlstring(L, 2, NULL, &size); + const UC *input = (const UC *) luaL_optlstring(L, 2, NULL, &size); const UC *last = input + size; int length = (int) luaL_optnumber(L, 3, 76); luaL_Buffer buffer; @@ -122,7 +116,7 @@ static int mime_global_wrp(lua_State *L) else lua_pushnil(L); lua_pushnumber(L, length); return 2; - } + } luaL_buffinit(L, &buffer); while (input < last) { switch (*input) { @@ -137,7 +131,7 @@ static int mime_global_wrp(lua_State *L) left = length; luaL_addstring(&buffer, CRLF); } - luaL_putchar(&buffer, *input); + luaL_addchar(&buffer, *input); left--; break; } @@ -149,22 +143,22 @@ static int mime_global_wrp(lua_State *L) } /*-------------------------------------------------------------------------*\ -* Fill base64 decode map. +* Fill base64 decode map. \*-------------------------------------------------------------------------*/ -static void b64setup(UC *b64unbase) +static void b64setup(UC *unbase) { int i; - for (i = 0; i <= 255; i++) b64unbase[i] = (UC) 255; - for (i = 0; i < 64; i++) b64unbase[b64base[i]] = (UC) i; - b64unbase['='] = 0; + for (i = 0; i <= 255; i++) unbase[i] = (UC) 255; + for (i = 0; i < 64; i++) unbase[b64base[i]] = (UC) i; + unbase['='] = 0; } /*-------------------------------------------------------------------------*\ -* Acumulates bytes in input buffer until 3 bytes are available. +* Acumulates bytes in input buffer until 3 bytes are available. * Translate the 3 bytes into Base64 form and append to buffer. * Returns new number of bytes in buffer. \*-------------------------------------------------------------------------*/ -static size_t b64encode(UC c, UC *input, size_t size, +static size_t b64encode(UC c, UC *input, size_t size, luaL_Buffer *buffer) { input[size++] = c; @@ -173,7 +167,7 @@ static size_t b64encode(UC c, UC *input, size_t size, unsigned long value = 0; value += input[0]; value <<= 8; value += input[1]; value <<= 8; - value += input[2]; + value += input[2]; code[3] = b64base[value & 0x3f]; value >>= 6; code[2] = b64base[value & 0x3f]; value >>= 6; code[1] = b64base[value & 0x3f]; value >>= 6; @@ -185,11 +179,11 @@ static size_t b64encode(UC c, UC *input, size_t size, } /*-------------------------------------------------------------------------*\ -* Encodes the Base64 last 1 or 2 bytes and adds padding '=' +* Encodes the Base64 last 1 or 2 bytes and adds padding '=' * Result, if any, is appended to buffer. * Returns 0. \*-------------------------------------------------------------------------*/ -static size_t b64pad(const UC *input, size_t size, +static size_t b64pad(const UC *input, size_t size, luaL_Buffer *buffer) { unsigned long value = 0; @@ -202,7 +196,7 @@ static size_t b64pad(const UC *input, size_t size, luaL_addlstring(buffer, (char *) code, 4); break; case 2: - value = input[0]; value <<= 8; + value = input[0]; value <<= 8; value |= input[1]; value <<= 2; code[2] = b64base[value & 0x3f]; value >>= 6; code[1] = b64base[value & 0x3f]; value >>= 6; @@ -216,11 +210,11 @@ static size_t b64pad(const UC *input, size_t size, } /*-------------------------------------------------------------------------*\ -* Acumulates bytes in input buffer until 4 bytes are available. +* Acumulates bytes in input buffer until 4 bytes are available. * Translate the 4 bytes from Base64 form and append to buffer. * Returns new number of bytes in buffer. \*-------------------------------------------------------------------------*/ -static size_t b64decode(UC c, UC *input, size_t size, +static size_t b64decode(UC c, UC *input, size_t size, luaL_Buffer *buffer) { /* ignore invalid characters */ @@ -238,7 +232,7 @@ static size_t b64decode(UC c, UC *input, size_t size, decoded[1] = (UC) (value & 0xff); value >>= 8; decoded[0] = (UC) value; /* take care of paddding */ - valid = (input[2] == '=') ? 1 : (input[3] == '=') ? 2 : 3; + valid = (input[2] == '=') ? 1 : (input[3] == '=') ? 2 : 3; luaL_addlstring(buffer, (char *) decoded, valid); return 0; /* need more data */ @@ -250,7 +244,7 @@ static size_t b64decode(UC c, UC *input, size_t size, * A, B = b64(C, D) * A is the encoded version of the largest prefix of C .. D that is * divisible by 3. B has the remaining bytes of C .. D, *without* encoding. -* The easiest thing would be to concatenate the two strings and +* The easiest thing would be to concatenate the two strings and * encode the result, but we can't afford that or Lua would dupplicate * every chunk we received. \*-------------------------------------------------------------------------*/ @@ -258,7 +252,7 @@ static int mime_global_b64(lua_State *L) { UC atom[3]; size_t isize = 0, asize = 0; - const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize); + const UC *input = (const UC *) luaL_optlstring(L, 1, NULL, &isize); const UC *last = input + isize; luaL_Buffer buffer; /* end-of-input blackhole */ @@ -267,22 +261,27 @@ static int mime_global_b64(lua_State *L) lua_pushnil(L); return 2; } + /* make sure we don't confuse buffer stuff with arguments */ + lua_settop(L, 2); /* process first part of the input */ luaL_buffinit(L, &buffer); - while (input < last) + while (input < last) asize = b64encode(*input++, atom, asize, &buffer); - input = (UC *) luaL_optlstring(L, 2, NULL, &isize); + input = (const UC *) luaL_optlstring(L, 2, NULL, &isize); /* if second part is nil, we are done */ if (!input) { + size_t osize = 0; asize = b64pad(atom, asize, &buffer); luaL_pushresult(&buffer); - if (!(*lua_tostring(L, -1))) lua_pushnil(L); + /* if the output is empty and the input is nil, return nil */ + lua_tolstring(L, -1, &osize); + if (osize == 0) lua_pushnil(L); lua_pushnil(L); return 2; } /* otherwise process the second part */ last = input + isize; - while (input < last) + while (input < last) asize = b64encode(*input++, atom, asize, &buffer); luaL_pushresult(&buffer); lua_pushlstring(L, (char *) atom, asize); @@ -299,7 +298,7 @@ static int mime_global_unb64(lua_State *L) { UC atom[4]; size_t isize = 0, asize = 0; - const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize); + const UC *input = (const UC *) luaL_optlstring(L, 1, NULL, &isize); const UC *last = input + isize; luaL_Buffer buffer; /* end-of-input blackhole */ @@ -308,21 +307,26 @@ static int mime_global_unb64(lua_State *L) lua_pushnil(L); return 2; } + /* make sure we don't confuse buffer stuff with arguments */ + lua_settop(L, 2); /* process first part of the input */ luaL_buffinit(L, &buffer); - while (input < last) + while (input < last) asize = b64decode(*input++, atom, asize, &buffer); - input = (UC *) luaL_optlstring(L, 2, NULL, &isize); + input = (const UC *) luaL_optlstring(L, 2, NULL, &isize); /* if second is nil, we are done */ if (!input) { + size_t osize = 0; luaL_pushresult(&buffer); - if (!(*lua_tostring(L, -1))) lua_pushnil(L); + /* if the output is empty and the input is nil, return nil */ + lua_tolstring(L, -1, &osize); + if (osize == 0) lua_pushnil(L); lua_pushnil(L); return 2; } /* otherwise, process the rest of the input */ last = input + isize; - while (input < last) + while (input < last) asize = b64decode(*input++, atom, asize, &buffer); luaL_pushresult(&buffer); lua_pushlstring(L, (char *) atom, asize); @@ -338,31 +342,31 @@ static int mime_global_unb64(lua_State *L) * 9 and 32 can be plain, unless in the end of a line, where must be =XX * encoded lines must be no longer than 76 not counting CRLF * soft line-break are =CRLF -* To encode one byte, we need to see the next two. +* To encode one byte, we need to see the next two. * Worst case is when we see a space, and wonder if a CRLF is comming \*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*\ * Split quoted-printable characters into classes * Precompute reverse map for encoding \*-------------------------------------------------------------------------*/ -static void qpsetup(UC *qpclass, UC *qpunbase) +static void qpsetup(UC *cl, UC *unbase) { int i; - for (i = 0; i < 256; i++) qpclass[i] = QP_QUOTED; - for (i = 33; i <= 60; i++) qpclass[i] = QP_PLAIN; - for (i = 62; i <= 126; i++) qpclass[i] = QP_PLAIN; - qpclass['\t'] = QP_IF_LAST; - qpclass[' '] = QP_IF_LAST; - qpclass['\r'] = QP_CR; - for (i = 0; i < 256; i++) qpunbase[i] = 255; - qpunbase['0'] = 0; qpunbase['1'] = 1; qpunbase['2'] = 2; - qpunbase['3'] = 3; qpunbase['4'] = 4; qpunbase['5'] = 5; - qpunbase['6'] = 6; qpunbase['7'] = 7; qpunbase['8'] = 8; - qpunbase['9'] = 9; qpunbase['A'] = 10; qpunbase['a'] = 10; - qpunbase['B'] = 11; qpunbase['b'] = 11; qpunbase['C'] = 12; - qpunbase['c'] = 12; qpunbase['D'] = 13; qpunbase['d'] = 13; - qpunbase['E'] = 14; qpunbase['e'] = 14; qpunbase['F'] = 15; - qpunbase['f'] = 15; + for (i = 0; i < 256; i++) cl[i] = QP_QUOTED; + for (i = 33; i <= 60; i++) cl[i] = QP_PLAIN; + for (i = 62; i <= 126; i++) cl[i] = QP_PLAIN; + cl['\t'] = QP_IF_LAST; + cl[' '] = QP_IF_LAST; + cl['\r'] = QP_CR; + for (i = 0; i < 256; i++) unbase[i] = 255; + unbase['0'] = 0; unbase['1'] = 1; unbase['2'] = 2; + unbase['3'] = 3; unbase['4'] = 4; unbase['5'] = 5; + unbase['6'] = 6; unbase['7'] = 7; unbase['8'] = 8; + unbase['9'] = 9; unbase['A'] = 10; unbase['a'] = 10; + unbase['B'] = 11; unbase['b'] = 11; unbase['C'] = 12; + unbase['c'] = 12; unbase['D'] = 13; unbase['d'] = 13; + unbase['E'] = 14; unbase['e'] = 14; unbase['F'] = 15; + unbase['f'] = 15; } /*-------------------------------------------------------------------------*\ @@ -370,16 +374,16 @@ static void qpsetup(UC *qpclass, UC *qpunbase) \*-------------------------------------------------------------------------*/ static void qpquote(UC c, luaL_Buffer *buffer) { - luaL_putchar(buffer, '='); - luaL_putchar(buffer, qpbase[c >> 4]); - luaL_putchar(buffer, qpbase[c & 0x0F]); + luaL_addchar(buffer, '='); + luaL_addchar(buffer, qpbase[c >> 4]); + luaL_addchar(buffer, qpbase[c & 0x0F]); } /*-------------------------------------------------------------------------*\ * Accumulate characters until we are sure about how to deal with them. -* Once we are sure, output to the buffer, in the correct form. +* Once we are sure, output to the buffer, in the correct form. \*-------------------------------------------------------------------------*/ -static size_t qpencode(UC c, UC *input, size_t size, +static size_t qpencode(UC c, UC *input, size_t size, const char *marker, luaL_Buffer *buffer) { input[size++] = c; @@ -402,7 +406,7 @@ static size_t qpencode(UC c, UC *input, size_t size, qpquote(input[0], buffer); luaL_addstring(buffer, marker); return 0; - } else luaL_putchar(buffer, input[0]); + } else luaL_addchar(buffer, input[0]); break; /* might have to be quoted always */ case QP_QUOTED: @@ -410,7 +414,7 @@ static size_t qpencode(UC c, UC *input, size_t size, break; /* might never have to be quoted */ default: - luaL_putchar(buffer, input[0]); + luaL_addchar(buffer, input[0]); break; } input[0] = input[1]; input[1] = input[2]; @@ -420,13 +424,13 @@ static size_t qpencode(UC c, UC *input, size_t size, } /*-------------------------------------------------------------------------*\ -* Deal with the final characters +* Deal with the final characters \*-------------------------------------------------------------------------*/ static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer) { size_t i; for (i = 0; i < size; i++) { - if (qpclass[input[i]] == QP_PLAIN) luaL_putchar(buffer, input[i]); + if (qpclass[input[i]] == QP_PLAIN) luaL_addchar(buffer, input[i]); else qpquote(input[i], buffer); } if (size > 0) luaL_addstring(buffer, EQCRLF); @@ -437,8 +441,8 @@ static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer) * Incrementally converts a string to quoted-printable * A, B = qp(C, D, marker) * Marker is the text to be used to replace CRLF sequences found in A. -* A is the encoded version of the largest prefix of C .. D that -* can be encoded without doubts. +* A is the encoded version of the largest prefix of C .. D that +* can be encoded without doubts. * B has the remaining bytes of C .. D, *without* encoding. \*-------------------------------------------------------------------------*/ static int mime_global_qp(lua_State *L) @@ -446,7 +450,7 @@ static int mime_global_qp(lua_State *L) size_t asize = 0, isize = 0; UC atom[3]; - const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize); + const UC *input = (const UC *) luaL_optlstring(L, 1, NULL, &isize); const UC *last = input + isize; const char *marker = luaL_optstring(L, 3, CRLF); luaL_Buffer buffer; @@ -456,11 +460,13 @@ static int mime_global_qp(lua_State *L) lua_pushnil(L); return 2; } + /* make sure we don't confuse buffer stuff with arguments */ + lua_settop(L, 3); /* process first part of input */ luaL_buffinit(L, &buffer); while (input < last) asize = qpencode(*input++, atom, asize, marker, &buffer); - input = (UC *) luaL_optlstring(L, 2, NULL, &isize); + input = (const UC *) luaL_optlstring(L, 2, NULL, &isize); /* if second part is nil, we are done */ if (!input) { asize = qppad(atom, asize, &buffer); @@ -480,7 +486,7 @@ static int mime_global_qp(lua_State *L) /*-------------------------------------------------------------------------*\ * Accumulate characters until we are sure about how to deal with them. -* Once we are sure, output the to the buffer, in the correct form. +* Once we are sure, output the to the buffer, in the correct form. \*-------------------------------------------------------------------------*/ static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer) { int d; @@ -488,23 +494,23 @@ static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer) { /* deal with all characters we can deal */ switch (input[0]) { /* if we have an escape character */ - case '=': - if (size < 3) return size; + case '=': + if (size < 3) return size; /* eliminate soft line break */ if (input[1] == '\r' && input[2] == '\n') return 0; /* decode quoted representation */ c = qpunbase[input[1]]; d = qpunbase[input[2]]; /* if it is an invalid, do not decode */ if (c > 15 || d > 15) luaL_addlstring(buffer, (char *)input, 3); - else luaL_putchar(buffer, (c << 4) + d); + else luaL_addchar(buffer, (char) ((c << 4) + d)); return 0; case '\r': - if (size < 2) return size; + if (size < 2) return size; if (input[1] == '\n') luaL_addlstring(buffer, (char *)input, 2); return 0; default: if (input[0] == '\t' || (input[0] > 31 && input[0] < 127)) - luaL_putchar(buffer, input[0]); + luaL_addchar(buffer, input[0]); return 0; } } @@ -512,15 +518,15 @@ static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer) { /*-------------------------------------------------------------------------*\ * Incrementally decodes a string in quoted-printable * A, B = qp(C, D) -* A is the decoded version of the largest prefix of C .. D that -* can be decoded without doubts. +* A is the decoded version of the largest prefix of C .. D that +* can be decoded without doubts. * B has the remaining bytes of C .. D, *without* decoding. \*-------------------------------------------------------------------------*/ static int mime_global_unqp(lua_State *L) { size_t asize = 0, isize = 0; UC atom[3]; - const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize); + const UC *input = (const UC *) luaL_optlstring(L, 1, NULL, &isize); const UC *last = input + isize; luaL_Buffer buffer; /* end-of-input blackhole */ @@ -529,18 +535,20 @@ static int mime_global_unqp(lua_State *L) lua_pushnil(L); return 2; } + /* make sure we don't confuse buffer stuff with arguments */ + lua_settop(L, 2); /* process first part of input */ luaL_buffinit(L, &buffer); while (input < last) asize = qpdecode(*input++, atom, asize, &buffer); - input = (UC *) luaL_optlstring(L, 2, NULL, &isize); + input = (const UC *) luaL_optlstring(L, 2, NULL, &isize); /* if second part is nil, we are done */ if (!input) { luaL_pushresult(&buffer); if (!(*lua_tostring(L, -1))) lua_pushnil(L); lua_pushnil(L); return 2; - } + } /* otherwise process rest of input */ last = input + isize; while (input < last) @@ -553,9 +561,9 @@ static int mime_global_unqp(lua_State *L) /*-------------------------------------------------------------------------*\ * Incrementally breaks a quoted-printed string into lines * A, n = qpwrp(l, B, length) -* A is a copy of B, broken into lines of at most 'length' bytes. -* 'l' is how many bytes are left for the first line of B. -* 'n' is the number of bytes left in the last line of A. +* A is a copy of B, broken into lines of at most 'length' bytes. +* 'l' is how many bytes are left for the first line of B. +* 'n' is the number of bytes left in the last line of A. * There are two complications: lines can't be broken in the middle * of an encoded =XX, and there might be line breaks already \*-------------------------------------------------------------------------*/ @@ -563,7 +571,7 @@ static int mime_global_qpwrp(lua_State *L) { size_t size = 0; int left = (int) luaL_checknumber(L, 1); - const UC *input = (UC *) luaL_optlstring(L, 2, NULL, &size); + const UC *input = (const UC *) luaL_optlstring(L, 2, NULL, &size); const UC *last = input + size; int length = (int) luaL_optnumber(L, 3, 76); luaL_Buffer buffer; @@ -588,16 +596,16 @@ static int mime_global_qpwrp(lua_State *L) if (left <= 3) { left = length; luaL_addstring(&buffer, EQCRLF); - } - luaL_putchar(&buffer, *input); + } + luaL_addchar(&buffer, *input); left--; break; - default: + default: if (left <= 1) { left = length; luaL_addstring(&buffer, EQCRLF); } - luaL_putchar(&buffer, *input); + luaL_addchar(&buffer, *input); left--; break; } @@ -620,7 +628,7 @@ static int mime_global_qpwrp(lua_State *L) * last is the previous character \*-------------------------------------------------------------------------*/ #define eolcandidate(c) (c == '\r' || c == '\n') -static int eolprocess(int c, int last, const char *marker, +static int eolprocess(int c, int last, const char *marker, luaL_Buffer *buffer) { if (eolcandidate(c)) { @@ -632,21 +640,21 @@ static int eolprocess(int c, int last, const char *marker, return c; } } else { - luaL_putchar(buffer, c); + luaL_addchar(buffer, (char) c); return 0; } } /*-------------------------------------------------------------------------*\ -* Converts a string to uniform EOL convention. +* Converts a string to uniform EOL convention. * A, n = eol(o, B, marker) * A is the converted version of the largest prefix of B that can be -* converted unambiguously. 'o' is the context returned by the previous +* converted unambiguously. 'o' is the context returned by the previous * call. 'n' is the new context. \*-------------------------------------------------------------------------*/ static int mime_global_eol(lua_State *L) { - int ctx = (int) luaL_checknumber(L, 1); + int ctx = luaL_checkinteger(L, 1); size_t isize = 0; const char *input = luaL_optlstring(L, 2, NULL, &isize); const char *last = input + isize; @@ -668,19 +676,19 @@ static int mime_global_eol(lua_State *L) } /*-------------------------------------------------------------------------*\ -* Takes one byte and stuff it if needed. +* Takes one byte and stuff it if needed. \*-------------------------------------------------------------------------*/ static size_t dot(int c, size_t state, luaL_Buffer *buffer) { - luaL_putchar(buffer, c); + luaL_addchar(buffer, (char) c); switch (c) { - case '\r': + case '\r': return 1; - case '\n': - return (state == 1)? 2: 0; - case '.': - if (state == 2) - luaL_putchar(buffer, '.'); + case '\n': + return (state == 1)? 2: 0; + case '.': + if (state == 2) + luaL_addchar(buffer, '.'); default: return 0; } @@ -704,10 +712,10 @@ static int mime_global_dot(lua_State *L) } /* process all input */ luaL_buffinit(L, &buffer); - while (input < last) + while (input < last) state = dot(*input++, state, &buffer); luaL_pushresult(&buffer); - lua_pushnumber(L, state); + lua_pushnumber(L, (lua_Number) state); return 2; } diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/mime.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/mime.h index 85ee2a39..99968a55 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/mime.h +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/mime.h @@ -7,16 +7,14 @@ * This module provides functions to implement transfer content encodings * and formatting conforming to RFC 2045. It is used by mime.lua, which * provide a higher level interface to this functionality. -* -* RCS ID: $Id: mime.h,v 1.15 2007/06/11 23:44:54 diego Exp $ \*=========================================================================*/ #include "lua.h" /*-------------------------------------------------------------------------*\ * Current MIME library version \*-------------------------------------------------------------------------*/ -#define MIME_VERSION "MIME 1.0.2" -#define MIME_COPYRIGHT "Copyright (C) 2004-2007 Diego Nehab" +#define MIME_VERSION "MIME 1.0.3" +#define MIME_COPYRIGHT "Copyright (C) 2004-2013 Diego Nehab" #define MIME_AUTHORS "Diego Nehab" /*-------------------------------------------------------------------------*\ diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/mime.lua b/love/src/jni/love/src/libraries/luasocket/libluasocket/mime.lua index 169eda29..642cd9ca 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/mime.lua +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/mime.lua @@ -2,7 +2,6 @@ -- MIME support for the Lua language. -- Author: Diego Nehab -- Conforming to RFCs 2045-2049 --- RCS ID: $Id: mime.lua,v 1.29 2007/06/11 23:44:54 diego Exp $ ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- @@ -13,12 +12,14 @@ local ltn12 = require("ltn12") local mime = require("mime.core") local io = require("io") local string = require("string") -module("mime") +local _M = mime -- encode, decode and wrap algorithm tables -encodet = {} -decodet = {} -wrapt = {} +local encodet, decodet, wrapt = {},{},{} + +_M.encodet = encodet +_M.decodet = decodet +_M.wrapt = wrapt -- creates a function that chooses a filter by name from a given table local function choose(table) @@ -35,21 +36,21 @@ end -- define the encoding filters encodet['base64'] = function() - return ltn12.filter.cycle(b64, "") + return ltn12.filter.cycle(_M.b64, "") end encodet['quoted-printable'] = function(mode) - return ltn12.filter.cycle(qp, "", + return ltn12.filter.cycle(_M.qp, "", (mode == "binary") and "=0D=0A" or "\r\n") end -- define the decoding filters decodet['base64'] = function() - return ltn12.filter.cycle(unb64, "") + return ltn12.filter.cycle(_M.unb64, "") end decodet['quoted-printable'] = function() - return ltn12.filter.cycle(unqp, "") + return ltn12.filter.cycle(_M.unqp, "") end local function format(chunk) @@ -62,26 +63,28 @@ end -- define the line-wrap filters wrapt['text'] = function(length) length = length or 76 - return ltn12.filter.cycle(wrp, length, length) + return ltn12.filter.cycle(_M.wrp, length, length) end wrapt['base64'] = wrapt['text'] wrapt['default'] = wrapt['text'] wrapt['quoted-printable'] = function() - return ltn12.filter.cycle(qpwrp, 76, 76) + return ltn12.filter.cycle(_M.qpwrp, 76, 76) end -- function that choose the encoding, decoding or wrap algorithm -encode = choose(encodet) -decode = choose(decodet) -wrap = choose(wrapt) +_M.encode = choose(encodet) +_M.decode = choose(decodet) +_M.wrap = choose(wrapt) -- define the end-of-line normalization filter -function normalize(marker) - return ltn12.filter.cycle(eol, 0, marker) +function _M.normalize(marker) + return ltn12.filter.cycle(_M.eol, 0, marker) end -- high level stuffing filter -function stuff() - return ltn12.filter.cycle(dot, 2) +function _M.stuff() + return ltn12.filter.cycle(_M.dot, 2) end + +return _M \ No newline at end of file diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/mime.lua.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/mime.lua.h index c758dcd5..78a14cb2 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/mime.lua.h +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/mime.lua.h @@ -1,7 +1,7 @@ /* code automatically generated by bin2c -- DO NOT EDIT */ { /* #include'ing this file in a C program is equivalent to calling - if (luaL_loadfile(L,"mime.lua")==0) lua_call(L, 0, 0); + if (luaL_loadfile(L,"mime.lua")==0) lua_call(L, 0, LUA_MULTRET); */ /* mime.lua */ static const unsigned char B1[]={ @@ -13,94 +13,95 @@ static const unsigned char B1[]={ 101, 32, 76,117, 97, 32,108, 97,110,103,117, 97,103,101, 46, 10, 45, 45, 32, 65, 117,116,104,111,114, 58, 32, 68,105,101,103,111, 32, 78,101,104, 97, 98, 10, 45, 45, 32, 67,111,110,102,111,114,109,105,110,103, 32,116,111, 32, 82, 70, 67,115, - 32, 50, 48, 52, 53, 45, 50, 48, 52, 57, 10, 45, 45, 32, 82, 67, 83, 32, 73, 68, - 58, 32, 36, 73,100, 58, 32,109,105,109,101, 46,108,117, 97, 44,118, 32, 49, 46, - 50, 57, 32, 50, 48, 48, 55, 47, 48, 54, 47, 49, 49, 32, 50, 51, 58, 52, 52, 58, - 53, 52, 32,100,105,101,103,111, 32, 69,120,112, 32, 36, 10, 45, 45, 45, 45, 45, + 32, 50, 48, 52, 53, 45, 50, 48, 52, 57, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97, -114,101, 32,109,111,100,117,108,101, 32, 97,110,100, 32,105,109,112,111,114,116, - 32,100,101,112,101,110,100,101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97,114,101, 32,109, +111,100,117,108,101, 32, 97,110,100, 32,105,109,112,111,114,116, 32,100,101,112, +101,110,100,101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32, 98, 97, -115,101, 32, 61, 32, 95, 71, 10,108,111, 99, 97,108, 32,108,116,110, 49, 50, 32, - 61, 32,114,101,113,117,105,114,101, 40, 34,108,116,110, 49, 50, 34, 41, 10,108, -111, 99, 97,108, 32,109,105,109,101, 32, 61, 32,114,101,113,117,105,114,101, 40, - 34,109,105,109,101, 46, 99,111,114,101, 34, 41, 10,108,111, 99, 97,108, 32,105, -111, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,105,111, 34, 41, 10,108,111, - 99, 97,108, 32,115,116,114,105,110,103, 32, 61, 32,114,101,113,117,105,114,101, - 40, 34,115,116,114,105,110,103, 34, 41, 10,109,111,100,117,108,101, 40, 34,109, -105,109,101, 34, 41, 10, 10, 45, 45, 32,101,110, 99,111,100,101, 44, 32,100,101, - 99,111,100,101, 32, 97,110,100, 32,119,114, 97,112, 32, 97,108,103,111,114,105, -116,104,109, 32,116, 97, 98,108,101,115, 10,101,110, 99,111,100,101,116, 32, 61, - 32,123,125, 10,100,101, 99,111,100,101,116, 32, 61, 32,123,125, 10,119,114, 97, -112,116, 32, 61, 32,123,125, 10, 10, 45, 45, 32, 99,114,101, 97,116,101,115, 32, - 97, 32,102,117,110, 99,116,105,111,110, 32,116,104, 97,116, 32, 99,104,111,111, -115,101,115, 32, 97, 32,102,105,108,116,101,114, 32, 98,121, 32,110, 97,109,101, - 32,102,114,111,109, 32, 97, 32,103,105,118,101,110, 32,116, 97, 98,108,101, 10, -108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32, 99,104,111,111,115, -101, 40,116, 97, 98,108,101, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, -102,117,110, 99,116,105,111,110, 40,110, 97,109,101, 44, 32,111,112,116, 49, 44, - 32,111,112,116, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 98, 97, -115,101, 46,116,121,112,101, 40,110, 97,109,101, 41, 32,126, 61, 32, 34,115,116, -114,105,110,103, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32,110, 97,109,101, 44, 32,111,112,116, 49, 44, 32,111,112,116, 50, 32, - 61, 32, 34,100,101,102, 97,117,108,116, 34, 44, 32,110, 97,109,101, 44, 32,111, -112,116, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, - 32, 32, 32, 32,108,111, 99, 97,108, 32,102, 32, 61, 32,116, 97, 98,108,101, 91, -110, 97,109,101, 32,111,114, 32, 34,110,105,108, 34, 93, 10, 32, 32, 32, 32, 32, - 32, 32, 32,105,102, 32,110,111,116, 32,102, 32,116,104,101,110, 32, 10, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115,101, 46,101,114,114,111,114, - 40, 34,117,110,107,110,111,119,110, 32,107,101,121, 32, 40, 34, 32, 46, 46, 32, - 98, 97,115,101, 46,116,111,115,116,114,105,110,103, 40,110, 97,109,101, 41, 32, - 46, 46, 32, 34, 41, 34, 44, 32, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101, -108,115,101, 32,114,101,116,117,114,110, 32,102, 40,111,112,116, 49, 44, 32,111, -112,116, 50, 41, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, - 10, 10, 45, 45, 32,100,101,102,105,110,101, 32,116,104,101, 32,101,110, 99,111, -100,105,110,103, 32,102,105,108,116,101,114,115, 10,101,110, 99,111,100,101,116, - 91, 39, 98, 97,115,101, 54, 52, 39, 93, 32, 61, 32,102,117,110, 99,116,105,111, -110, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,108,116,110, 49, 50, - 46,102,105,108,116,101,114, 46, 99,121, 99,108,101, 40, 98, 54, 52, 44, 32, 34, - 34, 41, 10,101,110,100, 10, 10,101,110, 99,111,100,101,116, 91, 39,113,117,111, -116,101,100, 45,112,114,105,110,116, 97, 98,108,101, 39, 93, 32, 61, 32,102,117, -110, 99,116,105,111,110, 40,109,111,100,101, 41, 10, 32, 32, 32, 32,114,101,116, -117,114,110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99, -108,101, 40,113,112, 44, 32, 34, 34, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, -109,111,100,101, 32, 61, 61, 32, 34, 98,105,110, 97,114,121, 34, 41, 32, 97,110, -100, 32, 34, 61, 48, 68, 61, 48, 65, 34, 32,111,114, 32, 34, 92,114, 92,110, 34, - 41, 10,101,110,100, 10, 10, 45, 45, 32,100,101,102,105,110,101, 32,116,104,101, - 32,100,101, 99,111,100,105,110,103, 32,102,105,108,116,101,114,115, 10,100,101, + 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32, 98, 97,115,101, 32, 61, + 32, 95, 71, 10,108,111, 99, 97,108, 32,108,116,110, 49, 50, 32, 61, 32,114,101, +113,117,105,114,101, 40, 34,108,116,110, 49, 50, 34, 41, 10,108,111, 99, 97,108, + 32,109,105,109,101, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,109,105,109, +101, 46, 99,111,114,101, 34, 41, 10,108,111, 99, 97,108, 32,105,111, 32, 61, 32, +114,101,113,117,105,114,101, 40, 34,105,111, 34, 41, 10,108,111, 99, 97,108, 32, +115,116,114,105,110,103, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,116, +114,105,110,103, 34, 41, 10,108,111, 99, 97,108, 32, 95, 77, 32, 61, 32,109,105, +109,101, 10, 10, 45, 45, 32,101,110, 99,111,100,101, 44, 32,100,101, 99,111,100, +101, 32, 97,110,100, 32,119,114, 97,112, 32, 97,108,103,111,114,105,116,104,109, + 32,116, 97, 98,108,101,115, 10,108,111, 99, 97,108, 32,101,110, 99,111,100,101, +116, 44, 32,100,101, 99,111,100,101,116, 44, 32,119,114, 97,112,116, 32, 61, 32, +123,125, 44,123,125, 44,123,125, 10, 10, 95, 77, 46,101,110, 99,111,100,101,116, + 32, 61, 32,101,110, 99,111,100,101,116, 10, 95, 77, 46,100,101, 99,111,100,101, +116, 32, 61, 32,100,101, 99,111,100,101,116, 10, 95, 77, 46,119,114, 97,112,116, + 32, 32, 32, 61, 32,119,114, 97,112,116, 32, 32, 10, 10, 45, 45, 32, 99,114,101, + 97,116,101,115, 32, 97, 32,102,117,110, 99,116,105,111,110, 32,116,104, 97,116, + 32, 99,104,111,111,115,101,115, 32, 97, 32,102,105,108,116,101,114, 32, 98,121, + 32,110, 97,109,101, 32,102,114,111,109, 32, 97, 32,103,105,118,101,110, 32,116, + 97, 98,108,101, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32, + 99,104,111,111,115,101, 40,116, 97, 98,108,101, 41, 10, 32, 32, 32, 32,114,101, +116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40,110, 97,109,101, 44, 32, +111,112,116, 49, 44, 32,111,112,116, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, +105,102, 32, 98, 97,115,101, 46,116,121,112,101, 40,110, 97,109,101, 41, 32,126, + 61, 32, 34,115,116,114,105,110,103, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32,110, 97,109,101, 44, 32,111,112,116, 49, 44, 32, +111,112,116, 50, 32, 61, 32, 34,100,101,102, 97,117,108,116, 34, 44, 32,110, 97, +109,101, 44, 32,111,112,116, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, + 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,102, 32, 61, 32,116, + 97, 98,108,101, 91,110, 97,109,101, 32,111,114, 32, 34,110,105,108, 34, 93, 10, + 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,102, 32,116,104,101, +110, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115,101, 46, +101,114,114,111,114, 40, 34,117,110,107,110,111,119,110, 32,107,101,121, 32, 40, + 34, 32, 46, 46, 32, 98, 97,115,101, 46,116,111,115,116,114,105,110,103, 40,110, + 97,109,101, 41, 32, 46, 46, 32, 34, 41, 34, 44, 32, 51, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,102, 40,111,112, +116, 49, 44, 32,111,112,116, 50, 41, 32,101,110,100, 10, 32, 32, 32, 32,101,110, +100, 10,101,110,100, 10, 10, 45, 45, 32,100,101,102,105,110,101, 32,116,104,101, + 32,101,110, 99,111,100,105,110,103, 32,102,105,108,116,101,114,115, 10,101,110, 99,111,100,101,116, 91, 39, 98, 97,115,101, 54, 52, 39, 93, 32, 61, 32,102,117, 110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, -108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99,108,101, 40,117, -110, 98, 54, 52, 44, 32, 34, 34, 41, 10,101,110,100, 10, 10,100,101, 99,111,100, -101,116, 91, 39,113,117,111,116,101,100, 45,112,114,105,110,116, 97, 98,108,101, - 39, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32, -114,101,116,117,114,110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, - 99,121, 99,108,101, 40,117,110,113,112, 44, 32, 34, 34, 41, 10,101,110,100, 10, - 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,102,111,114,109, - 97,116, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32,105,102, 32, 99,104,117, -110,107, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99, -104,117,110,107, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 32,114,101,116,117, -114,110, 32, 34, 39, 39, 34, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, - 32,114,101,116,117,114,110, 32,115,116,114,105,110,103, 46,108,101,110, 40, 99, -104,117,110,107, 41, 32,101,110,100, 10, 32, 32, 32, 32,101,108,115,101, 32,114, -101,116,117,114,110, 32, 34,110,105,108, 34, 32,101,110,100, 10,101,110,100, 10, - 10, 45, 45, 32,100,101,102,105,110,101, 32,116,104,101, 32,108,105,110,101, 45, -119,114, 97,112, 32,102,105,108,116,101,114,115, 10,119,114, 97,112,116, 91, 39, -116,101,120,116, 39, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40,108,101, -110,103,116,104, 41, 10, 32, 32, 32, 32,108,101,110,103,116,104, 32, 61, 32,108, -101,110,103,116,104, 32,111,114, 32, 55, 54, 10, 32, 32, 32, 32,114,101,116,117, -114,110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99,108, -101, 40,119,114,112, 44, 32,108,101,110,103,116,104, 44, 32,108,101,110,103,116, +108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99,108,101, 40, 95, + 77, 46, 98, 54, 52, 44, 32, 34, 34, 41, 10,101,110,100, 10, 10,101,110, 99,111, +100,101,116, 91, 39,113,117,111,116,101,100, 45,112,114,105,110,116, 97, 98,108, +101, 39, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40,109,111,100,101, 41, + 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,108,116,110, 49, 50, 46,102,105, +108,116,101,114, 46, 99,121, 99,108,101, 40, 95, 77, 46,113,112, 44, 32, 34, 34, + 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40,109,111,100,101, 32, 61, 61, 32, 34, + 98,105,110, 97,114,121, 34, 41, 32, 97,110,100, 32, 34, 61, 48, 68, 61, 48, 65, + 34, 32,111,114, 32, 34, 92,114, 92,110, 34, 41, 10,101,110,100, 10, 10, 45, 45, + 32,100,101,102,105,110,101, 32,116,104,101, 32,100,101, 99,111,100,105,110,103, + 32,102,105,108,116,101,114,115, 10,100,101, 99,111,100,101,116, 91, 39, 98, 97, +115,101, 54, 52, 39, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 10, + 32, 32, 32, 32,114,101,116,117,114,110, 32,108,116,110, 49, 50, 46,102,105,108, +116,101,114, 46, 99,121, 99,108,101, 40, 95, 77, 46,117,110, 98, 54, 52, 44, 32, + 34, 34, 41, 10,101,110,100, 10, 10,100,101, 99,111,100,101,116, 91, 39,113,117, +111,116,101,100, 45,112,114,105,110,116, 97, 98,108,101, 39, 93, 32, 61, 32,102, +117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, + 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99,108,101, 40, + 95, 77, 46,117,110,113,112, 44, 32, 34, 34, 41, 10,101,110,100, 10, 10,108,111, + 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,102,111,114,109, 97,116, 40, + 99,104,117,110,107, 41, 10, 32, 32, 32, 32,105,102, 32, 99,104,117,110,107, 32, +116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104,117,110, +107, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, + 34, 39, 39, 34, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,114,101, +116,117,114,110, 32,115,116,114,105,110,103, 46,108,101,110, 40, 99,104,117,110, +107, 41, 32,101,110,100, 10, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117, +114,110, 32, 34,110,105,108, 34, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, + 32,100,101,102,105,110,101, 32,116,104,101, 32,108,105,110,101, 45,119,114, 97, +112, 32,102,105,108,116,101,114,115, 10,119,114, 97,112,116, 91, 39,116,101,120, +116, 39, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40,108,101,110,103,116, +104, 41, 10, 32, 32, 32, 32,108,101,110,103,116,104, 32, 61, 32,108,101,110,103, +116,104, 32,111,114, 32, 55, 54, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, +108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99,108,101, 40, 95, + 77, 46,119,114,112, 44, 32,108,101,110,103,116,104, 44, 32,108,101,110,103,116, 104, 41, 10,101,110,100, 10,119,114, 97,112,116, 91, 39, 98, 97,115,101, 54, 52, 39, 93, 32, 61, 32,119,114, 97,112,116, 91, 39,116,101,120,116, 39, 93, 10,119, 114, 97,112,116, 91, 39,100,101,102, 97,117,108,116, 39, 93, 32, 61, 32,119,114, @@ -108,26 +109,28 @@ static const unsigned char B1[]={ 113,117,111,116,101,100, 45,112,114,105,110,116, 97, 98,108,101, 39, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32,114,101,116,117, 114,110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99,108, -101, 40,113,112,119,114,112, 44, 32, 55, 54, 44, 32, 55, 54, 41, 10,101,110,100, - 10, 10, 45, 45, 32,102,117,110, 99,116,105,111,110, 32,116,104, 97,116, 32, 99, -104,111,111,115,101, 32,116,104,101, 32,101,110, 99,111,100,105,110,103, 44, 32, -100,101, 99,111,100,105,110,103, 32,111,114, 32,119,114, 97,112, 32, 97,108,103, -111,114,105,116,104,109, 10,101,110, 99,111,100,101, 32, 61, 32, 99,104,111,111, -115,101, 40,101,110, 99,111,100,101,116, 41, 10,100,101, 99,111,100,101, 32, 61, - 32, 99,104,111,111,115,101, 40,100,101, 99,111,100,101,116, 41, 10,119,114, 97, -112, 32, 61, 32, 99,104,111,111,115,101, 40,119,114, 97,112,116, 41, 10, 10, 45, - 45, 32,100,101,102,105,110,101, 32,116,104,101, 32,101,110,100, 45,111,102, 45, -108,105,110,101, 32,110,111,114,109, 97,108,105,122, 97,116,105,111,110, 32,102, -105,108,116,101,114, 10,102,117,110, 99,116,105,111,110, 32,110,111,114,109, 97, -108,105,122,101, 40,109, 97,114,107,101,114, 41, 10, 32, 32, 32, 32,114,101,116, -117,114,110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99, -108,101, 40,101,111,108, 44, 32, 48, 44, 32,109, 97,114,107,101,114, 41, 10,101, -110,100, 10, 10, 45, 45, 32,104,105,103,104, 32,108,101,118,101,108, 32,115,116, -117,102,102,105,110,103, 32,102,105,108,116,101,114, 10,102,117,110, 99,116,105, -111,110, 32,115,116,117,102,102, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114, -110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99,108,101, - 40,100,111,116, 44, 32, 50, 41, 10,101,110,100, 10, +101, 40, 95, 77, 46,113,112,119,114,112, 44, 32, 55, 54, 44, 32, 55, 54, 41, 10, +101,110,100, 10, 10, 45, 45, 32,102,117,110, 99,116,105,111,110, 32,116,104, 97, +116, 32, 99,104,111,111,115,101, 32,116,104,101, 32,101,110, 99,111,100,105,110, +103, 44, 32,100,101, 99,111,100,105,110,103, 32,111,114, 32,119,114, 97,112, 32, + 97,108,103,111,114,105,116,104,109, 10, 95, 77, 46,101,110, 99,111,100,101, 32, + 61, 32, 99,104,111,111,115,101, 40,101,110, 99,111,100,101,116, 41, 10, 95, 77, + 46,100,101, 99,111,100,101, 32, 61, 32, 99,104,111,111,115,101, 40,100,101, 99, +111,100,101,116, 41, 10, 95, 77, 46,119,114, 97,112, 32, 61, 32, 99,104,111,111, +115,101, 40,119,114, 97,112,116, 41, 10, 10, 45, 45, 32,100,101,102,105,110,101, + 32,116,104,101, 32,101,110,100, 45,111,102, 45,108,105,110,101, 32,110,111,114, +109, 97,108,105,122, 97,116,105,111,110, 32,102,105,108,116,101,114, 10,102,117, +110, 99,116,105,111,110, 32, 95, 77, 46,110,111,114,109, 97,108,105,122,101, 40, +109, 97,114,107,101,114, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,108, +116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99,108,101, 40, 95, 77, + 46,101,111,108, 44, 32, 48, 44, 32,109, 97,114,107,101,114, 41, 10,101,110,100, + 10, 10, 45, 45, 32,104,105,103,104, 32,108,101,118,101,108, 32,115,116,117,102, +102,105,110,103, 32,102,105,108,116,101,114, 10,102,117,110, 99,116,105,111,110, + 32, 95, 77, 46,115,116,117,102,102, 40, 41, 10, 32, 32, 32, 32,114,101,116,117, +114,110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99,108, +101, 40, 95, 77, 46,100,111,116, 44, 32, 50, 41, 10,101,110,100, 10, 10,114,101, +116,117,114,110, 32, 95, 77, }; - if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"mime.lua")==0) lua_call(L, 0, 0); + if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"mime.lua")==0) lua_call(L, 0, LUA_MULTRET); } diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/options.c b/love/src/jni/love/src/libraries/luasocket/libluasocket/options.c index 5da3c518..20f4c280 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/options.c +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/options.c @@ -1,10 +1,8 @@ /*=========================================================================*\ -* Common option interface +* Common option interface * LuaSocket toolkit -* -* RCS ID: $Id: options.c,v 1.6 2005/11/20 07:20:23 diego Exp $ \*=========================================================================*/ -#include +#include #include "lauxlib.h" @@ -17,9 +15,15 @@ * Internal functions prototypes \*=========================================================================*/ static int opt_setmembership(lua_State *L, p_socket ps, int level, int name); +static int opt_ip6_setmembership(lua_State *L, p_socket ps, int level, int name); static int opt_setboolean(lua_State *L, p_socket ps, int level, int name); -static int opt_set(lua_State *L, p_socket ps, int level, int name, +static int opt_getboolean(lua_State *L, p_socket ps, int level, int name); +static int opt_setint(lua_State *L, p_socket ps, int level, int name); +static int opt_getint(lua_State *L, p_socket ps, int level, int name); +static int opt_set(lua_State *L, p_socket ps, int level, int name, void *val, int len); +static int opt_get(lua_State *L, p_socket ps, int level, int name, + void *val, int* len); /*=========================================================================*\ * Exported functions @@ -40,96 +44,277 @@ int opt_meth_setoption(lua_State *L, p_opt opt, p_socket ps) return opt->func(L, ps); } -/* enables reuse of local address */ -int opt_reuseaddr(lua_State *L, p_socket ps) +int opt_meth_getoption(lua_State *L, p_opt opt, p_socket ps) { - return opt_setboolean(L, ps, SOL_SOCKET, SO_REUSEADDR); + const char *name = luaL_checkstring(L, 2); /* obj, name, ... */ + while (opt->name && strcmp(name, opt->name)) + opt++; + if (!opt->func) { + char msg[45]; + sprintf(msg, "unsupported option `%.35s'", name); + luaL_argerror(L, 2, msg); + } + return opt->func(L, ps); +} + +/* enables reuse of local address */ +int opt_set_reuseaddr(lua_State *L, p_socket ps) +{ + return opt_setboolean(L, ps, SOL_SOCKET, SO_REUSEADDR); +} + +int opt_get_reuseaddr(lua_State *L, p_socket ps) +{ + return opt_getboolean(L, ps, SOL_SOCKET, SO_REUSEADDR); +} + +/* enables reuse of local port */ +int opt_set_reuseport(lua_State *L, p_socket ps) +{ + return opt_setboolean(L, ps, SOL_SOCKET, SO_REUSEPORT); +} + +int opt_get_reuseport(lua_State *L, p_socket ps) +{ + return opt_getboolean(L, ps, SOL_SOCKET, SO_REUSEPORT); } /* disables the Naggle algorithm */ -int opt_tcp_nodelay(lua_State *L, p_socket ps) +int opt_set_tcp_nodelay(lua_State *L, p_socket ps) { - return opt_setboolean(L, ps, IPPROTO_TCP, TCP_NODELAY); + return opt_setboolean(L, ps, IPPROTO_TCP, TCP_NODELAY); } -int opt_keepalive(lua_State *L, p_socket ps) +int opt_get_tcp_nodelay(lua_State *L, p_socket ps) { - return opt_setboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE); + return opt_getboolean(L, ps, IPPROTO_TCP, TCP_NODELAY); } -int opt_dontroute(lua_State *L, p_socket ps) +int opt_set_keepalive(lua_State *L, p_socket ps) +{ + return opt_setboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE); +} + +int opt_get_keepalive(lua_State *L, p_socket ps) +{ + return opt_getboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE); +} + +int opt_set_dontroute(lua_State *L, p_socket ps) { return opt_setboolean(L, ps, SOL_SOCKET, SO_DONTROUTE); } -int opt_broadcast(lua_State *L, p_socket ps) +int opt_get_dontroute(lua_State *L, p_socket ps) +{ + return opt_getboolean(L, ps, SOL_SOCKET, SO_DONTROUTE); +} + +int opt_set_broadcast(lua_State *L, p_socket ps) { return opt_setboolean(L, ps, SOL_SOCKET, SO_BROADCAST); } -int opt_ip_multicast_loop(lua_State *L, p_socket ps) +int opt_get_broadcast(lua_State *L, p_socket ps) +{ + return opt_getboolean(L, ps, SOL_SOCKET, SO_BROADCAST); +} + +int opt_set_ip6_unicast_hops(lua_State *L, p_socket ps) +{ + return opt_setint(L, ps, IPPROTO_IPV6, IPV6_UNICAST_HOPS); +} + +int opt_get_ip6_unicast_hops(lua_State *L, p_socket ps) +{ + return opt_getint(L, ps, IPPROTO_IPV6, IPV6_UNICAST_HOPS); +} + +int opt_set_ip6_multicast_hops(lua_State *L, p_socket ps) +{ + return opt_setint(L, ps, IPPROTO_IPV6, IPV6_MULTICAST_HOPS); +} + +int opt_get_ip6_multicast_hops(lua_State *L, p_socket ps) +{ + return opt_getint(L, ps, IPPROTO_IPV6, IPV6_MULTICAST_HOPS); +} + +int opt_set_ip_multicast_loop(lua_State *L, p_socket ps) { return opt_setboolean(L, ps, IPPROTO_IP, IP_MULTICAST_LOOP); } -int opt_linger(lua_State *L, p_socket ps) +int opt_get_ip_multicast_loop(lua_State *L, p_socket ps) +{ + return opt_getboolean(L, ps, IPPROTO_IP, IP_MULTICAST_LOOP); +} + +int opt_set_ip6_multicast_loop(lua_State *L, p_socket ps) +{ + return opt_setboolean(L, ps, IPPROTO_IPV6, IPV6_MULTICAST_LOOP); +} + +int opt_get_ip6_multicast_loop(lua_State *L, p_socket ps) +{ + return opt_getboolean(L, ps, IPPROTO_IPV6, IPV6_MULTICAST_LOOP); +} + +int opt_set_linger(lua_State *L, p_socket ps) { struct linger li; /* obj, name, table */ - if (!lua_istable(L, 3)) luaL_typerror(L, 3, lua_typename(L, LUA_TTABLE)); + if (!lua_istable(L, 3)) auxiliar_typeerror(L,3,lua_typename(L, LUA_TTABLE)); lua_pushstring(L, "on"); lua_gettable(L, 3); - if (!lua_isboolean(L, -1)) + if (!lua_isboolean(L, -1)) luaL_argerror(L, 3, "boolean 'on' field expected"); li.l_onoff = (u_short) lua_toboolean(L, -1); lua_pushstring(L, "timeout"); lua_gettable(L, 3); - if (!lua_isnumber(L, -1)) + if (!lua_isnumber(L, -1)) luaL_argerror(L, 3, "number 'timeout' field expected"); li.l_linger = (u_short) lua_tonumber(L, -1); return opt_set(L, ps, SOL_SOCKET, SO_LINGER, (char *) &li, sizeof(li)); } -int opt_ip_multicast_ttl(lua_State *L, p_socket ps) +int opt_get_linger(lua_State *L, p_socket ps) { - int val = (int) luaL_checknumber(L, 3); /* obj, name, int */ - return opt_set(L, ps, SOL_SOCKET, SO_LINGER, (char *) &val, sizeof(val)); + struct linger li; /* obj, name */ + int len = sizeof(li); + int err = opt_get(L, ps, SOL_SOCKET, SO_LINGER, (char *) &li, &len); + if (err) + return err; + lua_newtable(L); + lua_pushboolean(L, li.l_onoff); + lua_setfield(L, -2, "on"); + lua_pushinteger(L, li.l_linger); + lua_setfield(L, -2, "timeout"); + return 1; } -int opt_ip_add_membership(lua_State *L, p_socket ps) +int opt_set_ip_multicast_ttl(lua_State *L, p_socket ps) +{ + return opt_setint(L, ps, IPPROTO_IP, IP_MULTICAST_TTL); +} + +int opt_set_ip_multicast_if(lua_State *L, p_socket ps) +{ + const char *address = luaL_checkstring(L, 3); /* obj, name, ip */ + struct in_addr val; + val.s_addr = htonl(INADDR_ANY); + if (strcmp(address, "*") && !inet_aton(address, &val)) + luaL_argerror(L, 3, "ip expected"); + return opt_set(L, ps, IPPROTO_IP, IP_MULTICAST_IF, + (char *) &val, sizeof(val)); +} + +int opt_get_ip_multicast_if(lua_State *L, p_socket ps) +{ + struct in_addr val; + socklen_t len = sizeof(val); + if (getsockopt(*ps, IPPROTO_IP, IP_MULTICAST_IF, (char *) &val, &len) < 0) { + lua_pushnil(L); + lua_pushstring(L, "getsockopt failed"); + return 2; + } + lua_pushstring(L, inet_ntoa(val)); + return 1; +} + +int opt_set_ip_add_membership(lua_State *L, p_socket ps) { return opt_setmembership(L, ps, IPPROTO_IP, IP_ADD_MEMBERSHIP); } -int opt_ip_drop_membersip(lua_State *L, p_socket ps) +int opt_set_ip_drop_membersip(lua_State *L, p_socket ps) { return opt_setmembership(L, ps, IPPROTO_IP, IP_DROP_MEMBERSHIP); } +int opt_set_ip6_add_membership(lua_State *L, p_socket ps) +{ + return opt_ip6_setmembership(L, ps, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP); +} + +int opt_set_ip6_drop_membersip(lua_State *L, p_socket ps) +{ + return opt_ip6_setmembership(L, ps, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP); +} + +int opt_get_ip6_v6only(lua_State *L, p_socket ps) +{ + return opt_getboolean(L, ps, IPPROTO_IPV6, IPV6_V6ONLY); +} + +int opt_set_ip6_v6only(lua_State *L, p_socket ps) +{ + return opt_setboolean(L, ps, IPPROTO_IPV6, IPV6_V6ONLY); +} + /*=========================================================================*\ * Auxiliar functions \*=========================================================================*/ static int opt_setmembership(lua_State *L, p_socket ps, int level, int name) { struct ip_mreq val; /* obj, name, table */ - if (!lua_istable(L, 3)) luaL_typerror(L, 3, lua_typename(L, LUA_TTABLE)); + if (!lua_istable(L, 3)) auxiliar_typeerror(L,3,lua_typename(L, LUA_TTABLE)); lua_pushstring(L, "multiaddr"); lua_gettable(L, 3); - if (!lua_isstring(L, -1)) + if (!lua_isstring(L, -1)) luaL_argerror(L, 3, "string 'multiaddr' field expected"); - if (!inet_aton(lua_tostring(L, -1), &val.imr_multiaddr)) + if (!inet_aton(lua_tostring(L, -1), &val.imr_multiaddr)) luaL_argerror(L, 3, "invalid 'multiaddr' ip address"); lua_pushstring(L, "interface"); lua_gettable(L, 3); - if (!lua_isstring(L, -1)) + if (!lua_isstring(L, -1)) luaL_argerror(L, 3, "string 'interface' field expected"); val.imr_interface.s_addr = htonl(INADDR_ANY); if (strcmp(lua_tostring(L, -1), "*") && - !inet_aton(lua_tostring(L, -1), &val.imr_interface)) + !inet_aton(lua_tostring(L, -1), &val.imr_interface)) luaL_argerror(L, 3, "invalid 'interface' ip address"); return opt_set(L, ps, level, name, (char *) &val, sizeof(val)); } -static +static int opt_ip6_setmembership(lua_State *L, p_socket ps, int level, int name) +{ + struct ipv6_mreq val; /* obj, opt-name, table */ + memset(&val, 0, sizeof(val)); + if (!lua_istable(L, 3)) auxiliar_typeerror(L,3,lua_typename(L, LUA_TTABLE)); + lua_pushstring(L, "multiaddr"); + lua_gettable(L, 3); + if (!lua_isstring(L, -1)) + luaL_argerror(L, 3, "string 'multiaddr' field expected"); + if (!inet_pton(AF_INET6, lua_tostring(L, -1), &val.ipv6mr_multiaddr)) + luaL_argerror(L, 3, "invalid 'multiaddr' ip address"); + lua_pushstring(L, "interface"); + lua_gettable(L, 3); + /* By default we listen to interface on default route + * (sigh). However, interface= can override it. We should + * support either number, or name for it. Waiting for + * windows port of if_nametoindex */ + if (!lua_isnil(L, -1)) { + if (lua_isnumber(L, -1)) { + val.ipv6mr_interface = (unsigned int) lua_tonumber(L, -1); + } else + luaL_argerror(L, -1, "number 'interface' field expected"); + } + return opt_set(L, ps, level, name, (char *) &val, sizeof(val)); +} + +static +int opt_get(lua_State *L, p_socket ps, int level, int name, void *val, int* len) +{ + socklen_t socklen = *len; + if (getsockopt(*ps, level, name, (char *) val, &socklen) < 0) { + lua_pushnil(L); + lua_pushstring(L, "getsockopt failed"); + return 2; + } + *len = socklen; + return 0; +} + +static int opt_set(lua_State *L, p_socket ps, int level, int name, void *val, int len) { if (setsockopt(*ps, level, name, (char *) val, len) < 0) { @@ -141,9 +326,49 @@ int opt_set(lua_State *L, p_socket ps, int level, int name, void *val, int len) return 1; } +static int opt_getboolean(lua_State *L, p_socket ps, int level, int name) +{ + int val = 0; + int len = sizeof(val); + int err = opt_get(L, ps, level, name, (char *) &val, &len); + if (err) + return err; + lua_pushboolean(L, val); + return 1; +} + +int opt_get_error(lua_State *L, p_socket ps) +{ + int val = 0; + socklen_t len = sizeof(val); + if (getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *) &val, &len) < 0) { + lua_pushnil(L); + lua_pushstring(L, "getsockopt failed"); + return 2; + } + lua_pushstring(L, socket_strerror(val)); + return 1; +} + static int opt_setboolean(lua_State *L, p_socket ps, int level, int name) { int val = auxiliar_checkboolean(L, 3); /* obj, name, bool */ return opt_set(L, ps, level, name, (char *) &val, sizeof(val)); } +static int opt_getint(lua_State *L, p_socket ps, int level, int name) +{ + int val = 0; + int len = sizeof(val); + int err = opt_get(L, ps, level, name, (char *) &val, &len); + if (err) + return err; + lua_pushnumber(L, val); + return 1; +} + +static int opt_setint(lua_State *L, p_socket ps, int level, int name) +{ + int val = (int) lua_tonumber(L, 3); /* obj, name, int */ + return opt_set(L, ps, level, name, (char *) &val, sizeof(val)); +} diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/options.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/options.h index 4981cf2a..19ba0dfc 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/options.h +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/options.h @@ -6,8 +6,6 @@ * * This module provides a common interface to socket options, used mainly by * modules UDP and TCP. -* -* RCS ID: $Id: options.h,v 1.4 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ #include "lua.h" @@ -20,20 +18,45 @@ typedef struct t_opt { } t_opt; typedef t_opt *p_opt; -/* supported options */ -int opt_dontroute(lua_State *L, p_socket ps); -int opt_broadcast(lua_State *L, p_socket ps); -int opt_reuseaddr(lua_State *L, p_socket ps); -int opt_tcp_nodelay(lua_State *L, p_socket ps); -int opt_keepalive(lua_State *L, p_socket ps); -int opt_linger(lua_State *L, p_socket ps); -int opt_reuseaddr(lua_State *L, p_socket ps); -int opt_ip_multicast_ttl(lua_State *L, p_socket ps); -int opt_ip_multicast_loop(lua_State *L, p_socket ps); -int opt_ip_add_membership(lua_State *L, p_socket ps); -int opt_ip_drop_membersip(lua_State *L, p_socket ps); +/* supported options for setoption */ +int opt_set_dontroute(lua_State *L, p_socket ps); +int opt_set_broadcast(lua_State *L, p_socket ps); +int opt_set_tcp_nodelay(lua_State *L, p_socket ps); +int opt_set_keepalive(lua_State *L, p_socket ps); +int opt_set_linger(lua_State *L, p_socket ps); +int opt_set_reuseaddr(lua_State *L, p_socket ps); +int opt_set_reuseport(lua_State *L, p_socket ps); +int opt_set_ip_multicast_if(lua_State *L, p_socket ps); +int opt_set_ip_multicast_ttl(lua_State *L, p_socket ps); +int opt_set_ip_multicast_loop(lua_State *L, p_socket ps); +int opt_set_ip_add_membership(lua_State *L, p_socket ps); +int opt_set_ip_drop_membersip(lua_State *L, p_socket ps); +int opt_set_ip6_unicast_hops(lua_State *L, p_socket ps); +int opt_set_ip6_multicast_hops(lua_State *L, p_socket ps); +int opt_set_ip6_multicast_loop(lua_State *L, p_socket ps); +int opt_set_ip6_add_membership(lua_State *L, p_socket ps); +int opt_set_ip6_drop_membersip(lua_State *L, p_socket ps); +int opt_set_ip6_v6only(lua_State *L, p_socket ps); + +/* supported options for getoption */ +int opt_get_dontroute(lua_State *L, p_socket ps); +int opt_get_broadcast(lua_State *L, p_socket ps); +int opt_get_reuseaddr(lua_State *L, p_socket ps); +int opt_get_reuseport(lua_State *L, p_socket ps); +int opt_get_tcp_nodelay(lua_State *L, p_socket ps); +int opt_get_keepalive(lua_State *L, p_socket ps); +int opt_get_linger(lua_State *L, p_socket ps); +int opt_get_ip_multicast_loop(lua_State *L, p_socket ps); +int opt_get_ip_multicast_if(lua_State *L, p_socket ps); +int opt_get_error(lua_State *L, p_socket ps); +int opt_get_ip6_multicast_loop(lua_State *L, p_socket ps); +int opt_get_ip6_multicast_hops(lua_State *L, p_socket ps); +int opt_get_ip6_unicast_hops(lua_State *L, p_socket ps); +int opt_get_ip6_v6only(lua_State *L, p_socket ps); +int opt_get_reuseport(lua_State *L, p_socket ps); /* invokes the appropriate option handler */ int opt_meth_setoption(lua_State *L, p_opt opt, p_socket ps); +int opt_meth_getoption(lua_State *L, p_opt opt, p_socket ps); #endif diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/pierror.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/pierror.h new file mode 100644 index 00000000..cb773ab7 --- /dev/null +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/pierror.h @@ -0,0 +1,28 @@ +#ifndef PIERROR_H +#define PIERROR_H +/*=========================================================================*\ +* Error messages +* Defines platform independent error messages +\*=========================================================================*/ + +#define PIE_HOST_NOT_FOUND "host not found" +#define PIE_ADDRINUSE "address already in use" +#define PIE_ISCONN "already connected" +#define PIE_ACCESS "permission denied" +#define PIE_CONNREFUSED "connection refused" +#define PIE_CONNABORTED "closed" +#define PIE_CONNRESET "closed" +#define PIE_TIMEDOUT "timeout" +#define PIE_AGAIN "temporary failure in name resolution" +#define PIE_BADFLAGS "invalid value for ai_flags" +#define PIE_BADHINTS "invalid value for hints" +#define PIE_FAIL "non-recoverable failure in name resolution" +#define PIE_FAMILY "ai_family not supported" +#define PIE_MEMORY "memory allocation failure" +#define PIE_NONAME "host or service not provided, or not known" +#define PIE_OVERFLOW "argument buffer overflow" +#define PIE_PROTOCOL "resolved protocol is unknown" +#define PIE_SERVICE "service not supported for socket type" +#define PIE_SOCKTYPE "ai_socktype not supported" + +#endif diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/pre.lua b/love/src/jni/love/src/libraries/luasocket/libluasocket/pre.lua deleted file mode 100644 index fd6ebb15..00000000 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/pre.lua +++ /dev/null @@ -1 +0,0 @@ -if not socket then error("No socket.") end diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/select.c b/love/src/jni/love/src/libraries/luasocket/libluasocket/select.c index 73848ce2..9d133b7a 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/select.c +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/select.c @@ -1,35 +1,32 @@ /*=========================================================================*\ * Select implementation * LuaSocket toolkit -* -* RCS ID: $Id: select.c,v 1.22 2005/11/20 07:20:23 diego Exp $ \*=========================================================================*/ #include #include "lua.h" #include "lauxlib.h" +#include "compat.h" #include "socket.h" #include "timeout.h" #include "select.h" -extern void luax_register(lua_State *L, const char *name, const luaL_Reg *l); - /*=========================================================================*\ * Internal function prototypes. \*=========================================================================*/ static t_socket getfd(lua_State *L); static int dirty(lua_State *L); -static t_socket collect_fd(lua_State *L, int tab, t_socket max_fd, - int itab, fd_set *set); +static void collect_fd(lua_State *L, int tab, int itab, + fd_set *set, t_socket *max_fd); static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set); -static void return_fd(lua_State *L, fd_set *set, t_socket max_fd, +static void return_fd(lua_State *L, fd_set *set, t_socket max_fd, int itab, int tab, int start); static void make_assoc(lua_State *L, int tab); static int global_select(lua_State *L); /* functions in library namespace */ -static luaL_reg func[] = { +static luaL_Reg func[] = { {"select", global_select}, {NULL, NULL} }; @@ -41,7 +38,13 @@ static luaL_reg func[] = { * Initializes module \*-------------------------------------------------------------------------*/ int select_open(lua_State *L) { - luax_register(L, NULL, func); + lua_pushstring(L, "_SETSIZE"); + lua_pushinteger(L, FD_SETSIZE); + lua_rawset(L, -3); + lua_pushstring(L, "_SOCKETINVALID"); + lua_pushinteger(L, SOCKET_INVALID); + lua_rawset(L, -3); + luaL_setfuncs(L, func, 0); return 0; } @@ -53,7 +56,7 @@ int select_open(lua_State *L) { \*-------------------------------------------------------------------------*/ static int global_select(lua_State *L) { int rtab, wtab, itab, ret, ndirty; - t_socket max_fd; + t_socket max_fd = SOCKET_INVALID; fd_set rset, wset; t_timeout tm; double t = luaL_optnumber(L, 3, -1); @@ -62,12 +65,12 @@ static int global_select(lua_State *L) { lua_newtable(L); itab = lua_gettop(L); lua_newtable(L); rtab = lua_gettop(L); lua_newtable(L); wtab = lua_gettop(L); - max_fd = collect_fd(L, 1, SOCKET_INVALID, itab, &rset); + collect_fd(L, 1, itab, &rset, &max_fd); + collect_fd(L, 2, itab, &wset, &max_fd); ndirty = check_dirty(L, 1, rtab, &rset); t = ndirty > 0? 0.0: t; timeout_init(&tm, t, -1); timeout_markstart(&tm); - max_fd = collect_fd(L, 2, max_fd, itab, &wset); ret = socket_select(max_fd+1, &rset, &wset, NULL, &tm); if (ret > 0 || ndirty > 0) { return_fd(L, &rset, max_fd+1, itab, rtab, ndirty); @@ -79,7 +82,7 @@ static int global_select(lua_State *L) { lua_pushstring(L, "timeout"); return 3; } else { - lua_pushstring(L, "error"); + luaL_error(L, "select failed"); return 3; } } @@ -94,9 +97,11 @@ static t_socket getfd(lua_State *L) { if (!lua_isnil(L, -1)) { lua_pushvalue(L, -2); lua_call(L, 1, 1); - if (lua_isnumber(L, -1)) - fd = (t_socket) lua_tonumber(L, -1); - } + if (lua_isnumber(L, -1)) { + double numfd = lua_tonumber(L, -1); + fd = (numfd >= 0.0)? (t_socket) numfd: SOCKET_INVALID; + } + } lua_pop(L, 1); return fd; } @@ -109,17 +114,19 @@ static int dirty(lua_State *L) { lua_pushvalue(L, -2); lua_call(L, 1, 1); is = lua_toboolean(L, -1); - } + } lua_pop(L, 1); return is; } -static t_socket collect_fd(lua_State *L, int tab, t_socket max_fd, - int itab, fd_set *set) { - int i = 1; - if (lua_isnil(L, tab)) - return max_fd; - while (1) { +static void collect_fd(lua_State *L, int tab, int itab, + fd_set *set, t_socket *max_fd) { + int i = 1, n = 0; + /* nil is the same as an empty table */ + if (lua_isnil(L, tab)) return; + /* otherwise we need it to be a table */ + luaL_checktype(L, tab, LUA_TTABLE); + for ( ;; ) { t_socket fd; lua_pushnumber(L, i); lua_gettable(L, tab); @@ -127,26 +134,37 @@ static t_socket collect_fd(lua_State *L, int tab, t_socket max_fd, lua_pop(L, 1); break; } + /* getfd figures out if this is a socket */ fd = getfd(L); if (fd != SOCKET_INVALID) { + /* make sure we don't overflow the fd_set */ +#ifdef _WIN32 + if (n >= FD_SETSIZE) + luaL_argerror(L, tab, "too many sockets"); +#else + if (fd >= FD_SETSIZE) + luaL_argerror(L, tab, "descriptor too large for set size"); +#endif FD_SET(fd, set); - if (max_fd == SOCKET_INVALID || max_fd < fd) - max_fd = fd; - lua_pushnumber(L, fd); + n++; + /* keep track of the largest descriptor so far */ + if (*max_fd == SOCKET_INVALID || *max_fd < fd) + *max_fd = fd; + /* make sure we can map back from descriptor to the object */ + lua_pushnumber(L, (lua_Number) fd); lua_pushvalue(L, -2); lua_settable(L, itab); } lua_pop(L, 1); i = i + 1; } - return max_fd; } static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set) { int ndirty = 0, i = 1; - if (lua_isnil(L, tab)) + if (lua_isnil(L, tab)) return 0; - while (1) { + for ( ;; ) { t_socket fd; lua_pushnumber(L, i); lua_gettable(L, tab); @@ -167,13 +185,13 @@ static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set) { return ndirty; } -static void return_fd(lua_State *L, fd_set *set, t_socket max_fd, +static void return_fd(lua_State *L, fd_set *set, t_socket max_fd, int itab, int tab, int start) { t_socket fd; for (fd = 0; fd < max_fd; fd++) { if (FD_ISSET(fd, set)) { lua_pushnumber(L, ++start); - lua_pushnumber(L, fd); + lua_pushnumber(L, (lua_Number) fd); lua_gettable(L, itab); lua_settable(L, tab); } @@ -183,7 +201,7 @@ static void return_fd(lua_State *L, fd_set *set, t_socket max_fd, static void make_assoc(lua_State *L, int tab) { int i = 1, atab; lua_newtable(L); atab = lua_gettop(L); - while (1) { + for ( ;; ) { lua_pushnumber(L, i); lua_gettable(L, tab); if (!lua_isnil(L, -1)) { diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/select.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/select.h index aa3db4ad..87502003 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/select.h +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/select.h @@ -8,8 +8,6 @@ * method getfd() which returns the descriptor to be passed to the * underlying select function. Another method, dirty(), should return * true if there is data ready for reading (required for buffered input). -* -* RCS ID: $Id: select.h,v 1.7 2004/06/16 01:02:07 diego Exp $ \*=========================================================================*/ int select_open(lua_State *L); diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/serial.c b/love/src/jni/love/src/libraries/luasocket/libluasocket/serial.c new file mode 100644 index 00000000..4088de53 --- /dev/null +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/serial.c @@ -0,0 +1,173 @@ +/*=========================================================================*\ +* Serial stream +* LuaSocket toolkit +\*=========================================================================*/ +#include + +#include "lua.h" +#include "lauxlib.h" +#include "luasocket.h" + +#include "auxiliar.h" +#include "socket.h" +#include "options.h" +#include "unix.h" +#include + +/* +Reuses userdata definition from unix.h, since it is useful for all +stream-like objects. + +If we stored the serial path for use in error messages or userdata +printing, we might need our own userdata definition. + +Group usage is semi-inherited from unix.c, but unnecessary since we +have only one object type. +*/ + +/*=========================================================================*\ +* Internal function prototypes +\*=========================================================================*/ +static int global_create(lua_State *L); +static int meth_send(lua_State *L); +static int meth_receive(lua_State *L); +static int meth_close(lua_State *L); +static int meth_settimeout(lua_State *L); +static int meth_getfd(lua_State *L); +static int meth_setfd(lua_State *L); +static int meth_dirty(lua_State *L); +static int meth_getstats(lua_State *L); +static int meth_setstats(lua_State *L); + +/* serial object methods */ +static luaL_Reg serial_methods[] = { + {"__gc", meth_close}, + {"__tostring", auxiliar_tostring}, + {"close", meth_close}, + {"dirty", meth_dirty}, + {"getfd", meth_getfd}, + {"getstats", meth_getstats}, + {"setstats", meth_setstats}, + {"receive", meth_receive}, + {"send", meth_send}, + {"setfd", meth_setfd}, + {"settimeout", meth_settimeout}, + {NULL, NULL} +}; + +/*-------------------------------------------------------------------------*\ +* Initializes module +\*-------------------------------------------------------------------------*/ +LUASOCKET_API int luaopen_socket_serial(lua_State *L) { + /* create classes */ + auxiliar_newclass(L, "serial{client}", serial_methods); + /* create class groups */ + auxiliar_add2group(L, "serial{client}", "serial{any}"); + lua_pushcfunction(L, global_create); + return 1; +} + +/*=========================================================================*\ +* Lua methods +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Just call buffered IO methods +\*-------------------------------------------------------------------------*/ +static int meth_send(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkclass(L, "serial{client}", 1); + return buffer_meth_send(L, &un->buf); +} + +static int meth_receive(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkclass(L, "serial{client}", 1); + return buffer_meth_receive(L, &un->buf); +} + +static int meth_getstats(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkclass(L, "serial{client}", 1); + return buffer_meth_getstats(L, &un->buf); +} + +static int meth_setstats(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkclass(L, "serial{client}", 1); + return buffer_meth_setstats(L, &un->buf); +} + +/*-------------------------------------------------------------------------*\ +* Select support methods +\*-------------------------------------------------------------------------*/ +static int meth_getfd(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1); + lua_pushnumber(L, (int) un->sock); + return 1; +} + +/* this is very dangerous, but can be handy for those that are brave enough */ +static int meth_setfd(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1); + un->sock = (t_socket) luaL_checknumber(L, 2); + return 0; +} + +static int meth_dirty(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1); + lua_pushboolean(L, !buffer_isempty(&un->buf)); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Closes socket used by object +\*-------------------------------------------------------------------------*/ +static int meth_close(lua_State *L) +{ + p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1); + socket_destroy(&un->sock); + lua_pushnumber(L, 1); + return 1; +} + + +/*-------------------------------------------------------------------------*\ +* Just call tm methods +\*-------------------------------------------------------------------------*/ +static int meth_settimeout(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1); + return timeout_meth_settimeout(L, &un->tm); +} + +/*=========================================================================*\ +* Library functions +\*=========================================================================*/ + + +/*-------------------------------------------------------------------------*\ +* Creates a serial object +\*-------------------------------------------------------------------------*/ +static int global_create(lua_State *L) { + const char* path = luaL_checkstring(L, 1); + + /* allocate unix object */ + p_unix un = (p_unix) lua_newuserdata(L, sizeof(t_unix)); + + /* open serial device */ + t_socket sock = open(path, O_NOCTTY|O_RDWR); + + /*printf("open %s on %d\n", path, sock);*/ + + if (sock < 0) { + lua_pushnil(L); + lua_pushstring(L, socket_strerror(errno)); + lua_pushnumber(L, errno); + return 3; + } + /* set its type as client object */ + auxiliar_setclass(L, "serial{client}", -1); + /* initialize remaining structure fields */ + socket_setnonblocking(&sock); + un->sock = sock; + io_init(&un->io, (p_send) socket_write, (p_recv) socket_read, + (p_error) socket_ioerror, &un->sock); + timeout_init(&un->tm, -1, -1); + buffer_init(&un->buf, &un->io, &un->tm); + return 1; +} diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/smtp.lua b/love/src/jni/love/src/libraries/luasocket/libluasocket/smtp.lua index 8f3cfcff..018be7f6 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/smtp.lua +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/smtp.lua @@ -2,7 +2,6 @@ -- SMTP client support for the Lua language. -- LuaSocket toolkit. -- Author: Diego Nehab --- RCS ID: $Id: smtp.lua,v 1.46 2007/03/12 04:08:40 diego Exp $ ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- @@ -16,23 +15,26 @@ local os = require("os") local socket = require("socket") local tp = require("socket.tp") local ltn12 = require("ltn12") +local headers = require("socket.headers") local mime = require("mime") -module("socket.smtp") + +socket.smtp = {} +local _M = socket.smtp ----------------------------------------------------------------------------- -- Program constants ----------------------------------------------------------------------------- -- timeout for connection -TIMEOUT = 60 +_M.TIMEOUT = 60 -- default server used to send e-mails -SERVER = "localhost" +_M.SERVER = "localhost" -- default port -PORT = 25 +_M.PORT = 25 -- domain used in HELO command and default sendmail -- If we are under a CGI, try to get from environment -DOMAIN = os.getenv("SERVER_NAME") or "localhost" +_M.DOMAIN = os.getenv("SERVER_NAME") or "localhost" -- default time zone (means we don't know) -ZONE = "-0000" +_M.ZONE = "-0000" --------------------------------------------------------------------------- -- Low level SMTP API @@ -41,7 +43,7 @@ local metat = { __index = {} } function metat.__index:greet(domain) self.try(self.tp:check("2..")) - self.try(self.tp:command("EHLO", domain or DOMAIN)) + self.try(self.tp:command("EHLO", domain or _M.DOMAIN)) return socket.skip(1, self.try(self.tp:check("2.."))) end @@ -75,9 +77,9 @@ end function metat.__index:login(user, password) self.try(self.tp:command("AUTH", "LOGIN")) self.try(self.tp:check("3..")) - self.try(self.tp:command(mime.b64(user))) + self.try(self.tp:send(mime.b64(user) .. "\r\n")) self.try(self.tp:check("3..")) - self.try(self.tp:command(mime.b64(password))) + self.try(self.tp:send(mime.b64(password) .. "\r\n")) return self.try(self.tp:check("2..")) end @@ -111,9 +113,9 @@ function metat.__index:send(mailt) self:data(ltn12.source.chain(mailt.source, mime.stuff()), mailt.step) end -function open(server, port, create) - local tp = socket.try(tp.connect(server or SERVER, port or PORT, - TIMEOUT, create)) +function _M.open(server, port, create) + local tp = socket.try(tp.connect(server or _M.SERVER, port or _M.PORT, + _M.TIMEOUT, create)) local s = base.setmetatable({tp = tp}, metat) -- make sure tp is closed if we get an exception s.try = socket.newtry(function() @@ -146,10 +148,11 @@ end local send_message -- yield the headers all at once, it's faster -local function send_headers(headers) +local function send_headers(tosend) + local canonic = headers.canonic local h = "\r\n" - for i,v in base.pairs(headers) do - h = i .. ': ' .. v .. "\r\n" .. h + for f,v in base.pairs(tosend) do + h = (canonic[f] or f) .. ': ' .. v .. "\r\n" .. h end coroutine.yield(h) end @@ -220,14 +223,14 @@ end local function adjust_headers(mesgt) local lower = lower_headers(mesgt.headers) lower["date"] = lower["date"] or - os.date("!%a, %d %b %Y %H:%M:%S ") .. (mesgt.zone or ZONE) + os.date("!%a, %d %b %Y %H:%M:%S ") .. (mesgt.zone or _M.ZONE) lower["x-mailer"] = lower["x-mailer"] or socket._VERSION - -- this can't be overriden + -- this can't be overridden lower["mime-version"] = "1.0" return lower end -function message(mesgt) +function _M.message(mesgt) mesgt.headers = adjust_headers(mesgt) -- create and return message source local co = coroutine.create(function() send_message(mesgt) end) @@ -241,11 +244,13 @@ end --------------------------------------------------------------------------- -- High level SMTP API ----------------------------------------------------------------------------- -send = socket.protect(function(mailt) - local s = open(mailt.server, mailt.port, mailt.create) +_M.send = socket.protect(function(mailt) + local s = _M.open(mailt.server, mailt.port, mailt.create) local ext = s:greet(mailt.domain) s:auth(mailt.user, mailt.password, ext) s:send(mailt) s:quit() return s:close() end) + +return _M \ No newline at end of file diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/smtp.lua.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/smtp.lua.h index e8d7f987..2faf479c 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/smtp.lua.h +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/smtp.lua.h @@ -1,7 +1,7 @@ /* code automatically generated by bin2c -- DO NOT EDIT */ { /* #include'ing this file in a C program is equivalent to calling - if (luaL_loadfile(L,"smtp.lua")==0) lua_call(L, 0, 0); + if (luaL_loadfile(L,"smtp.lua")==0) lua_call(L, 0, LUA_MULTRET); */ /* smtp.lua */ static const unsigned char B1[]={ @@ -13,291 +13,321 @@ static const unsigned char B1[]={ 32,102,111,114, 32,116,104,101, 32, 76,117, 97, 32,108, 97,110,103,117, 97,103, 101, 46, 10, 45, 45, 32, 76,117, 97, 83,111, 99,107,101,116, 32,116,111,111,108, 107,105,116, 46, 10, 45, 45, 32, 65,117,116,104,111,114, 58, 32, 68,105,101,103, -111, 32, 78,101,104, 97, 98, 10, 45, 45, 32, 82, 67, 83, 32, 73, 68, 58, 32, 36, - 73,100, 58, 32,115,109,116,112, 46,108,117, 97, 44,118, 32, 49, 46, 52, 54, 32, - 50, 48, 48, 55, 47, 48, 51, 47, 49, 50, 32, 48, 52, 58, 48, 56, 58, 52, 48, 32, -100,105,101,103,111, 32, 69,120,112, 32, 36, 10, 45, 45, 45, 45, 45, 45, 45, 45, +111, 32, 78,101,104, 97, 98, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97,114,101, 32, -109,111,100,117,108,101, 32, 97,110,100, 32,105,109,112,111,114,116, 32,100,101, -112,101,110,100,101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97,114,101, 32,109,111,100,117, +108,101, 32, 97,110,100, 32,105,109,112,111,114,116, 32,100,101,112,101,110,100, +101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32, 98, 97,115,101, 32, - 61, 32, 95, 71, 10,108,111, 99, 97,108, 32, 99,111,114,111,117,116,105,110,101, - 32, 61, 32,114,101,113,117,105,114,101, 40, 34, 99,111,114,111,117,116,105,110, -101, 34, 41, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, 32, 61, 32,114, -101,113,117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10,108,111, 99, - 97,108, 32,109, 97,116,104, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,109, - 97,116,104, 34, 41, 10,108,111, 99, 97,108, 32,111,115, 32, 61, 32,114,101,113, -117,105,114,101, 40, 34,111,115, 34, 41, 10,108,111, 99, 97,108, 32,115,111, 99, -107,101,116, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,111, 99,107,101, -116, 34, 41, 10,108,111, 99, 97,108, 32,116,112, 32, 61, 32,114,101,113,117,105, -114,101, 40, 34,115,111, 99,107,101,116, 46,116,112, 34, 41, 10,108,111, 99, 97, -108, 32,108,116,110, 49, 50, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,108, -116,110, 49, 50, 34, 41, 10,108,111, 99, 97,108, 32,109,105,109,101, 32, 61, 32, -114,101,113,117,105,114,101, 40, 34,109,105,109,101, 34, 41, 10,109,111,100,117, -108,101, 40, 34,115,111, 99,107,101,116, 46,115,109,116,112, 34, 41, 10, 10, 45, + 45, 45, 45, 45, 10,108,111, 99, 97,108, 32, 98, 97,115,101, 32, 61, 32, 95, 71, + 10,108,111, 99, 97,108, 32, 99,111,114,111,117,116,105,110,101, 32, 61, 32,114, +101,113,117,105,114,101, 40, 34, 99,111,114,111,117,116,105,110,101, 34, 41, 10, +108,111, 99, 97,108, 32,115,116,114,105,110,103, 32, 61, 32,114,101,113,117,105, +114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10,108,111, 99, 97,108, 32,109, + 97,116,104, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,109, 97,116,104, 34, + 41, 10,108,111, 99, 97,108, 32,111,115, 32, 61, 32,114,101,113,117,105,114,101, + 40, 34,111,115, 34, 41, 10,108,111, 99, 97,108, 32,115,111, 99,107,101,116, 32, + 61, 32,114,101,113,117,105,114,101, 40, 34,115,111, 99,107,101,116, 34, 41, 10, +108,111, 99, 97,108, 32,116,112, 32, 61, 32,114,101,113,117,105,114,101, 40, 34, +115,111, 99,107,101,116, 46,116,112, 34, 41, 10,108,111, 99, 97,108, 32,108,116, +110, 49, 50, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,108,116,110, 49, 50, + 34, 41, 10,108,111, 99, 97,108, 32,104,101, 97,100,101,114,115, 32, 61, 32,114, +101,113,117,105,114,101, 40, 34,115,111, 99,107,101,116, 46,104,101, 97,100,101, +114,115, 34, 41, 10,108,111, 99, 97,108, 32,109,105,109,101, 32, 61, 32,114,101, +113,117,105,114,101, 40, 34,109,105,109,101, 34, 41, 10, 10,115,111, 99,107,101, +116, 46,115,109,116,112, 32, 61, 32,123,125, 10,108,111, 99, 97,108, 32, 95, 77, + 32, 61, 32,115,111, 99,107,101,116, 46,115,109,116,112, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, - 80,114,111,103,114, 97,109, 32, 99,111,110,115,116, 97,110,116,115, 10, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 80,114,111, +103,114, 97,109, 32, 99,111,110,115,116, 97,110,116,115, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32,116, -105,109,101,111,117,116, 32,102,111,114, 32, 99,111,110,110,101, 99,116,105,111, -110, 10, 84, 73, 77, 69, 79, 85, 84, 32, 61, 32, 54, 48, 10, 45, 45, 32,100,101, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32,116,105,109,101, +111,117,116, 32,102,111,114, 32, 99,111,110,110,101, 99,116,105,111,110, 10, 95, + 77, 46, 84, 73, 77, 69, 79, 85, 84, 32, 61, 32, 54, 48, 10, 45, 45, 32,100,101, 102, 97,117,108,116, 32,115,101,114,118,101,114, 32,117,115,101,100, 32,116,111, - 32,115,101,110,100, 32,101, 45,109, 97,105,108,115, 10, 83, 69, 82, 86, 69, 82, - 32, 61, 32, 34,108,111, 99, 97,108,104,111,115,116, 34, 10, 45, 45, 32,100,101, -102, 97,117,108,116, 32,112,111,114,116, 10, 80, 79, 82, 84, 32, 61, 32, 50, 53, - 10, 45, 45, 32,100,111,109, 97,105,110, 32,117,115,101,100, 32,105,110, 32, 72, - 69, 76, 79, 32, 99,111,109,109, 97,110,100, 32, 97,110,100, 32,100,101,102, 97, -117,108,116, 32,115,101,110,100,109, 97,105,108, 10, 45, 45, 32, 73,102, 32,119, -101, 32, 97,114,101, 32,117,110,100,101,114, 32, 97, 32, 67, 71, 73, 44, 32,116, -114,121, 32,116,111, 32,103,101,116, 32,102,114,111,109, 32,101,110,118,105,114, -111,110,109,101,110,116, 10, 68, 79, 77, 65, 73, 78, 32, 61, 32,111,115, 46,103, -101,116,101,110,118, 40, 34, 83, 69, 82, 86, 69, 82, 95, 78, 65, 77, 69, 34, 41, - 32,111,114, 32, 34,108,111, 99, 97,108,104,111,115,116, 34, 10, 45, 45, 32,100, -101,102, 97,117,108,116, 32,116,105,109,101, 32,122,111,110,101, 32, 40,109,101, - 97,110,115, 32,119,101, 32,100,111,110, 39,116, 32,107,110,111,119, 41, 10, 90, - 79, 78, 69, 32, 61, 32, 34, 45, 48, 48, 48, 48, 34, 10, 10, 45, 45, 45, 45, 45, + 32,115,101,110,100, 32,101, 45,109, 97,105,108,115, 10, 95, 77, 46, 83, 69, 82, + 86, 69, 82, 32, 61, 32, 34,108,111, 99, 97,108,104,111,115,116, 34, 10, 45, 45, + 32,100,101,102, 97,117,108,116, 32,112,111,114,116, 10, 95, 77, 46, 80, 79, 82, + 84, 32, 61, 32, 50, 53, 10, 45, 45, 32,100,111,109, 97,105,110, 32,117,115,101, +100, 32,105,110, 32, 72, 69, 76, 79, 32, 99,111,109,109, 97,110,100, 32, 97,110, +100, 32,100,101,102, 97,117,108,116, 32,115,101,110,100,109, 97,105,108, 10, 45, + 45, 32, 73,102, 32,119,101, 32, 97,114,101, 32,117,110,100,101,114, 32, 97, 32, + 67, 71, 73, 44, 32,116,114,121, 32,116,111, 32,103,101,116, 32,102,114,111,109, + 32,101,110,118,105,114,111,110,109,101,110,116, 10, 95, 77, 46, 68, 79, 77, 65, + 73, 78, 32, 61, 32,111,115, 46,103,101,116,101,110,118, 40, 34, 83, 69, 82, 86, + 69, 82, 95, 78, 65, 77, 69, 34, 41, 32,111,114, 32, 34,108,111, 99, 97,108,104, +111,115,116, 34, 10, 45, 45, 32,100,101,102, 97,117,108,116, 32,116,105,109,101, + 32,122,111,110,101, 32, 40,109,101, 97,110,115, 32,119,101, 32,100,111,110, 39, +116, 32,107,110,111,119, 41, 10, 95, 77, 46, 90, 79, 78, 69, 32, 61, 32, 34, 45, + 48, 48, 48, 48, 34, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 76,111,119, 32,108,101, -118,101,108, 32, 83, 77, 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 10, 45, 45, 32, 76,111,119, 32,108,101,118,101,108, 32, 83, 77, 84, 80, + 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,109,101,116, - 97,116, 32, 61, 32,123, 32, 95, 95,105,110,100,101,120, 32, 61, 32,123,125, 32, -125, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95, -105,110,100,101,120, 58,103,114,101,101,116, 40,100,111,109, 97,105,110, 41, 10, - 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, - 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10, 32, 32, 32, 32,115, -101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, - 97,110,100, 40, 34, 69, 72, 76, 79, 34, 44, 32,100,111,109, 97,105,110, 32,111, -114, 32, 68, 79, 77, 65, 73, 78, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114, -110, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 49, 44, 32,115,101,108, -102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, - 34, 50, 46, 46, 34, 41, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105, -111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,109, 97,105, -108, 40,102,114,111,109, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, - 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34, 77, 65, - 73, 76, 34, 44, 32, 34, 70, 82, 79, 77, 58, 34, 32, 46, 46, 32,102,114,111,109, - 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,116, -114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, - 46, 34, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109, -101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,114, 99,112,116, 40,116,111, - 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46, -116,112, 58, 99,111,109,109, 97,110,100, 40, 34, 82, 67, 80, 84, 34, 44, 32, 34, - 84, 79, 58, 34, 32, 46, 46, 32,116,111, 41, 41, 10, 32, 32, 32, 32,114,101,116, -117,114,110, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, - 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10,101,110,100, 10, 10, -102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100, -101,120, 58,100, 97,116, 97, 40,115,114, 99, 44, 32,115,116,101,112, 41, 10, 32, + 45, 45, 10,108,111, 99, 97,108, 32,109,101,116, 97,116, 32, 61, 32,123, 32, 95, + 95,105,110,100,101,120, 32, 61, 32,123,125, 32,125, 10, 10,102,117,110, 99,116, +105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,103,114, +101,101,116, 40,100,111,109, 97,105,110, 41, 10, 32, 32, 32, 32,115,101,108,102, + 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, + 50, 46, 46, 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40, +115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34, 69, 72, 76, + 79, 34, 44, 32,100,111,109, 97,105,110, 32,111,114, 32, 95, 77, 46, 68, 79, 77, + 65, 73, 78, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,111, 99, +107,101,116, 46,115,107,105,112, 40, 49, 44, 32,115,101,108,102, 46,116,114,121, + 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, + 41, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101, +116, 97,116, 46, 95, 95,105,110,100,101,120, 58,109, 97,105,108, 40,102,114,111, +109, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, + 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34, 77, 65, 73, 76, 34, 44, 32, + 34, 70, 82, 79, 77, 58, 34, 32, 46, 46, 32,102,114,111,109, 41, 41, 10, 32, 32, + 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,116,114,121, 40,115,101, +108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10, +101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, + 95, 95,105,110,100,101,120, 58,114, 99,112,116, 40,116,111, 41, 10, 32, 32, 32, + 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,111, +109,109, 97,110,100, 40, 34, 82, 67, 80, 84, 34, 44, 32, 34, 84, 79, 58, 34, 32, + 46, 46, 32,116,111, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115, +101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99, +107, 40, 34, 50, 46, 46, 34, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116, +105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,100, 97, +116, 97, 40,115,114, 99, 44, 32,115,116,101,112, 41, 10, 32, 32, 32, 32,115,101, +108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97, +110,100, 40, 34, 68, 65, 84, 65, 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, + 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, + 51, 46, 46, 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40, +115,101,108,102, 46,116,112, 58,115,111,117,114, 99,101, 40,115,114, 99, 44, 32, +115,116,101,112, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40, +115,101,108,102, 46,116,112, 58,115,101,110,100, 40, 34, 92,114, 92,110, 46, 92, +114, 92,110, 34, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101, +108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, + 40, 34, 50, 46, 46, 34, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105, +111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,113,117,105, +116, 40, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108, +102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34, 81, 85, 73, 84, 34, 41, + 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,116,114, +121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, + 34, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101, +116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 99,108,111,115,101, 40, 41, 10, + 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,116,112, 58, 99, +108,111,115,101, 40, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, + 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,108,111,103,105,110, + 40,117,115,101,114, 44, 32,112, 97,115,115,119,111,114,100, 41, 10, 32, 32, 32, + 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,111, +109,109, 97,110,100, 40, 34, 65, 85, 84, 72, 34, 44, 32, 34, 76, 79, 71, 73, 78, + 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108, +102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 51, 46, 46, 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, - 99,111,109,109, 97,110,100, 40, 34, 68, 65, 84, 65, 34, 41, 41, 10, 32, 32, 32, - 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104, -101, 99,107, 40, 34, 51, 46, 46, 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, - 46,116,114,121, 40,115,101,108,102, 46,116,112, 58,115,111,117,114, 99,101, 40, -115,114, 99, 44, 32,115,116,101,112, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, - 46,116,114,121, 40,115,101,108,102, 46,116,112, 58,115,101,110,100, 40, 34, 92, -114, 92,110, 46, 92,114, 92,110, 34, 41, 41, 10, 32, 32, 32, 32,114,101,116,117, +115,101,110,100, 40,109,105,109,101, 46, 98, 54, 52, 40,117,115,101,114, 41, 32, + 46, 46, 32, 34, 92,114, 92,110, 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, + 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, + 51, 46, 46, 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40, +115,101,108,102, 46,116,112, 58,115,101,110,100, 40,109,105,109,101, 46, 98, 54, + 52, 40,112, 97,115,115,119,111,114,100, 41, 32, 46, 46, 32, 34, 92,114, 92,110, + 34, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46, +116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, + 46, 46, 34, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32, +109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,112,108, 97,105,110, 40, +117,115,101,114, 44, 32,112, 97,115,115,119,111,114,100, 41, 10, 32, 32, 32, 32, +108,111, 99, 97,108, 32, 97,117,116,104, 32, 61, 32, 34, 80, 76, 65, 73, 78, 32, + 34, 32, 46, 46, 32,109,105,109,101, 46, 98, 54, 52, 40, 34, 92, 48, 34, 32, 46, + 46, 32,117,115,101,114, 32, 46, 46, 32, 34, 92, 48, 34, 32, 46, 46, 32,112, 97, +115,115,119,111,114,100, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, + 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34, 65, 85, + 84, 72, 34, 44, 32, 97,117,116,104, 41, 41, 10, 32, 32, 32, 32,114,101,116,117, 114,110, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10,101,110,100, 10, 10,102, 117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101, -120, 58,113,117,105,116, 40, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114, -121, 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34, 81, - 85, 73, 84, 34, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101, -108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, - 40, 34, 50, 46, 46, 34, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105, -111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 99,108,111, -115,101, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, - 46,116,112, 58, 99,108,111,115,101, 40, 41, 10,101,110,100, 10, 10,102,117,110, - 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58, -108,111,103,105,110, 40,117,115,101,114, 44, 32,112, 97,115,115,119,111,114,100, - 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46, -116,112, 58, 99,111,109,109, 97,110,100, 40, 34, 65, 85, 84, 72, 34, 44, 32, 34, - 76, 79, 71, 73, 78, 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114, -121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 51, 46, 46, - 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108, -102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40,109,105,109,101, 46, 98, 54, - 52, 40,117,115,101,114, 41, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116, -114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 51, 46, - 46, 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101, -108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40,109,105,109,101, 46, 98, - 54, 52, 40,112, 97,115,115,119,111,114,100, 41, 41, 41, 10, 32, 32, 32, 32,114, -101,116,117,114,110, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46, -116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10,101,110,100, - 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105, -110,100,101,120, 58,112,108, 97,105,110, 40,117,115,101,114, 44, 32,112, 97,115, -115,119,111,114,100, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 97,117,116, -104, 32, 61, 32, 34, 80, 76, 65, 73, 78, 32, 34, 32, 46, 46, 32,109,105,109,101, - 46, 98, 54, 52, 40, 34, 92, 48, 34, 32, 46, 46, 32,117,115,101,114, 32, 46, 46, - 32, 34, 92, 48, 34, 32, 46, 46, 32,112, 97,115,115,119,111,114,100, 41, 10, 32, - 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, - 99,111,109,109, 97,110,100, 40, 34, 65, 85, 84, 72, 34, 44, 32, 97,117,116,104, - 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,116, -114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, - 46, 34, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109, -101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 97,117,116,104, 40,117,115, -101,114, 44, 32,112, 97,115,115,119,111,114,100, 44, 32,101,120,116, 41, 10, 32, - 32, 32, 32,105,102, 32,110,111,116, 32,117,115,101,114, 32,111,114, 32,110,111, -116, 32,112, 97,115,115,119,111,114,100, 32,116,104,101,110, 32,114,101,116,117, -114,110, 32, 49, 32,101,110,100, 10, 32, 32, 32, 32,105,102, 32,115,116,114,105, -110,103, 46,102,105,110,100, 40,101,120,116, 44, 32, 34, 65, 85, 84, 72, 91, 94, - 92,110, 93, 43, 76, 79, 71, 73, 78, 34, 41, 32,116,104,101,110, 10, 32, 32, 32, - 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 58,108,111,103, -105,110, 40,117,115,101,114, 44, 32,112, 97,115,115,119,111,114,100, 41, 10, 32, - 32, 32, 32,101,108,115,101,105,102, 32,115,116,114,105,110,103, 46,102,105,110, -100, 40,101,120,116, 44, 32, 34, 65, 85, 84, 72, 91, 94, 92,110, 93, 43, 80, 76, - 65, 73, 78, 34, 41, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,114, -101,116,117,114,110, 32,115,101,108,102, 58,112,108, 97,105,110, 40,117,115,101, -114, 44, 32,112, 97,115,115,119,111,114,100, 41, 10, 32, 32, 32, 32,101,108,115, -101, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,110, -105,108, 44, 32, 34, 97,117,116,104,101,110,116,105, 99, 97,116,105,111,110, 32, -110,111,116, 32,115,117,112,112,111,114,116,101,100, 34, 41, 10, 32, 32, 32, 32, -101,110,100, 10,101,110,100, 10, 10, 45, 45, 32,115,101,110,100, 32,109,101,115, -115, 97,103,101, 32,111,114, 32,116,104,114,111,119, 32, 97,110, 32,101,120, 99, -101,112,116,105,111,110, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97, -116, 46, 95, 95,105,110,100,101,120, 58,115,101,110,100, 40,109, 97,105,108,116, - 41, 10, 32, 32, 32, 32,115,101,108,102, 58,109, 97,105,108, 40,109, 97,105,108, -116, 46,102,114,111,109, 41, 10, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46, -116,121,112,101, 40,109, 97,105,108,116, 46,114, 99,112,116, 41, 32, 61, 61, 32, - 34,116, 97, 98,108,101, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, - 32,102,111,114, 32,105, 44,118, 32,105,110, 32, 98, 97,115,101, 46,105,112, 97, -105,114,115, 40,109, 97,105,108,116, 46,114, 99,112,116, 41, 32,100,111, 10, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 58,114, 99,112,116, - 40,118, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, -101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 58,114, 99, -112,116, 40,109, 97,105,108,116, 46,114, 99,112,116, 41, 10, 32, 32, 32, 32,101, -110,100, 10, 32, 32, 32, 32,115,101,108,102, 58,100, 97,116, 97, 40,108,116,110, - 49, 50, 46,115,111,117,114, 99,101, 46, 99,104, 97,105,110, 40,109, 97,105,108, -116, 46,115,111,117,114, 99,101, 44, 32,109,105,109,101, 46,115,116,117,102,102, - 40, 41, 41, 44, 32,109, 97,105,108,116, 46,115,116,101,112, 41, 10,101,110,100, - 10, 10,102,117,110, 99,116,105,111,110, 32,111,112,101,110, 40,115,101,114,118, -101,114, 44, 32,112,111,114,116, 44, 32, 99,114,101, 97,116,101, 41, 10, 32, 32, - 32, 32,108,111, 99, 97,108, 32,116,112, 32, 61, 32,115,111, 99,107,101,116, 46, -116,114,121, 40,116,112, 46, 99,111,110,110,101, 99,116, 40,115,101,114,118,101, -114, 32,111,114, 32, 83, 69, 82, 86, 69, 82, 44, 32,112,111,114,116, 32,111,114, - 32, 80, 79, 82, 84, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 84, 73, 77, 69, 79, - 85, 84, 44, 32, 99,114,101, 97,116,101, 41, 41, 10, 32, 32, 32, 32,108,111, 99, - 97,108, 32,115, 32, 61, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97,116, - 97, 98,108,101, 40,123,116,112, 32, 61, 32,116,112,125, 44, 32,109,101,116, 97, -116, 41, 10, 32, 32, 32, 32, 45, 45, 32,109, 97,107,101, 32,115,117,114,101, 32, -116,112, 32,105,115, 32, 99,108,111,115,101,100, 32,105,102, 32,119,101, 32,103, -101,116, 32, 97,110, 32,101,120, 99,101,112,116,105,111,110, 10, 32, 32, 32, 32, -115, 46,116,114,121, 32, 61, 32,115,111, 99,107,101,116, 46,110,101,119,116,114, -121, 40,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, - 32,115, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,101,110,100, 41, 10, - 32, 32, 32, 32,114,101,116,117,114,110, 32,115, 10,101,110,100, 10, 10, 45, 45, - 32, 99,111,110,118,101,114,116, 32,104,101, 97,100,101,114,115, 32,116,111, 32, -108,111,119,101,114, 99, 97,115,101, 10,108,111, 99, 97,108, 32,102,117,110, 99, -116,105,111,110, 32,108,111,119,101,114, 95,104,101, 97,100,101,114,115, 40,104, -101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,108,111, -119,101,114, 32, 61, 32,123,125, 10, 32, 32, 32, 32,102,111,114, 32,105, 44,118, - 32,105,110, 32, 98, 97,115,101, 46,112, 97,105,114,115, 40,104,101, 97,100,101, -114,115, 32,111,114, 32,108,111,119,101,114, 41, 32,100,111, 10, 32, 32, 32, 32, - 32, 32, 32, 32,108,111,119,101,114, 91,115,116,114,105,110,103, 46,108,111,119, -101,114, 40,105, 41, 93, 32, 61, 32,118, 10, 32, 32, 32, 32,101,110,100, 10, 32, - 32, 32, 32,114,101,116,117,114,110, 32,108,111,119,101,114, 10,101,110,100, 10, - 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +120, 58, 97,117,116,104, 40,117,115,101,114, 44, 32,112, 97,115,115,119,111,114, +100, 44, 32,101,120,116, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,117, +115,101,114, 32,111,114, 32,110,111,116, 32,112, 97,115,115,119,111,114,100, 32, +116,104,101,110, 32,114,101,116,117,114,110, 32, 49, 32,101,110,100, 10, 32, 32, + 32, 32,105,102, 32,115,116,114,105,110,103, 46,102,105,110,100, 40,101,120,116, + 44, 32, 34, 65, 85, 84, 72, 91, 94, 92,110, 93, 43, 76, 79, 71, 73, 78, 34, 41, + 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, + 32,115,101,108,102, 58,108,111,103,105,110, 40,117,115,101,114, 44, 32,112, 97, +115,115,119,111,114,100, 41, 10, 32, 32, 32, 32,101,108,115,101,105,102, 32,115, +116,114,105,110,103, 46,102,105,110,100, 40,101,120,116, 44, 32, 34, 65, 85, 84, + 72, 91, 94, 92,110, 93, 43, 80, 76, 65, 73, 78, 34, 41, 32,116,104,101,110, 10, + 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 58, +112,108, 97,105,110, 40,117,115,101,114, 44, 32,112, 97,115,115,119,111,114,100, + 41, 10, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,115, +101,108,102, 46,116,114,121, 40,110,105,108, 44, 32, 34, 97,117,116,104,101,110, +116,105, 99, 97,116,105,111,110, 32,110,111,116, 32,115,117,112,112,111,114,116, +101,100, 34, 41, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, + 32,115,101,110,100, 32,109,101,115,115, 97,103,101, 32,111,114, 32,116,104,114, +111,119, 32, 97,110, 32,101,120, 99,101,112,116,105,111,110, 10,102,117,110, 99, +116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,115, +101,110,100, 40,109, 97,105,108,116, 41, 10, 32, 32, 32, 32,115,101,108,102, 58, +109, 97,105,108, 40,109, 97,105,108,116, 46,102,114,111,109, 41, 10, 32, 32, 32, + 32,105,102, 32, 98, 97,115,101, 46,116,121,112,101, 40,109, 97,105,108,116, 46, +114, 99,112,116, 41, 32, 61, 61, 32, 34,116, 97, 98,108,101, 34, 32,116,104,101, +110, 10, 32, 32, 32, 32, 32, 32, 32, 32,102,111,114, 32,105, 44,118, 32,105,110, + 32, 98, 97,115,101, 46,105,112, 97,105,114,115, 40,109, 97,105,108,116, 46,114, + 99,112,116, 41, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +115,101,108,102, 58,114, 99,112,116, 40,118, 41, 10, 32, 32, 32, 32, 32, 32, 32, + 32,101,110,100, 10, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, + 32, 32,115,101,108,102, 58,114, 99,112,116, 40,109, 97,105,108,116, 46,114, 99, +112,116, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,115,101,108,102, + 58,100, 97,116, 97, 40,108,116,110, 49, 50, 46,115,111,117,114, 99,101, 46, 99, +104, 97,105,110, 40,109, 97,105,108,116, 46,115,111,117,114, 99,101, 44, 32,109, +105,109,101, 46,115,116,117,102,102, 40, 41, 41, 44, 32,109, 97,105,108,116, 46, +115,116,101,112, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32, + 95, 77, 46,111,112,101,110, 40,115,101,114,118,101,114, 44, 32,112,111,114,116, + 44, 32, 99,114,101, 97,116,101, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, +116,112, 32, 61, 32,115,111, 99,107,101,116, 46,116,114,121, 40,116,112, 46, 99, +111,110,110,101, 99,116, 40,115,101,114,118,101,114, 32,111,114, 32, 95, 77, 46, + 83, 69, 82, 86, 69, 82, 44, 32,112,111,114,116, 32,111,114, 32, 95, 77, 46, 80, + 79, 82, 84, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 77, 46, 84, 73, 77, 69, + 79, 85, 84, 44, 32, 99,114,101, 97,116,101, 41, 41, 10, 32, 32, 32, 32,108,111, + 99, 97,108, 32,115, 32, 61, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97, +116, 97, 98,108,101, 40,123,116,112, 32, 61, 32,116,112,125, 44, 32,109,101,116, + 97,116, 41, 10, 32, 32, 32, 32, 45, 45, 32,109, 97,107,101, 32,115,117,114,101, + 32,116,112, 32,105,115, 32, 99,108,111,115,101,100, 32,105,102, 32,119,101, 32, +103,101,116, 32, 97,110, 32,101,120, 99,101,112,116,105,111,110, 10, 32, 32, 32, + 32,115, 46,116,114,121, 32, 61, 32,115,111, 99,107,101,116, 46,110,101,119,116, +114,121, 40,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, + 32, 32,115, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,101,110,100, 41, + 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115, 10,101,110,100, 10, 10, 45, + 45, 32, 99,111,110,118,101,114,116, 32,104,101, 97,100,101,114,115, 32,116,111, + 32,108,111,119,101,114, 99, 97,115,101, 10,108,111, 99, 97,108, 32,102,117,110, + 99,116,105,111,110, 32,108,111,119,101,114, 95,104,101, 97,100,101,114,115, 40, +104,101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,108, +111,119,101,114, 32, 61, 32,123,125, 10, 32, 32, 32, 32,102,111,114, 32,105, 44, +118, 32,105,110, 32, 98, 97,115,101, 46,112, 97,105,114,115, 40,104,101, 97,100, +101,114,115, 32,111,114, 32,108,111,119,101,114, 41, 32,100,111, 10, 32, 32, 32, + 32, 32, 32, 32, 32,108,111,119,101,114, 91,115,116,114,105,110,103, 46,108,111, +119,101,114, 40,105, 41, 93, 32, 61, 32,118, 10, 32, 32, 32, 32,101,110,100, 10, + 32, 32, 32, 32,114,101,116,117,114,110, 32,108,111,119,101,114, 10,101,110,100, + 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, - 77,117,108,116,105,112, 97,114,116, 32,109,101,115,115, 97,103,101, 32,115,111, -117,114, 99,101, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, + 32, 77,117,108,116,105,112, 97,114,116, 32,109,101,115,115, 97,103,101, 32,115, +111,117,114, 99,101, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 10, 45, 45, 32,114,101,116,117,114,110,115, 32, 97, 32,104,111,112,101, -102,117,108,108,121, 32,117,110,105,113,117,101, 32,109,105,109,101, 32, 98,111, -117,110,100, 97,114,121, 10,108,111, 99, 97,108, 32,115,101,113,110,111, 32, 61, - 32, 48, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,110,101, -119, 98,111,117,110,100, 97,114,121, 40, 41, 10, 32, 32, 32, 32,115,101,113,110, -111, 32, 61, 32,115,101,113,110,111, 32, 43, 32, 49, 10, 32, 32, 32, 32,114,101, -116,117,114,110, 32,115,116,114,105,110,103, 46,102,111,114,109, 97,116, 40, 39, - 37,115, 37, 48, 53,100, 61, 61, 37, 48, 53,117, 39, 44, 32,111,115, 46,100, 97, -116,101, 40, 39, 37,100, 37,109, 37, 89, 37, 72, 37, 77, 37, 83, 39, 41, 44, 10, - 32, 32, 32, 32, 32, 32, 32, 32,109, 97,116,104, 46,114, 97,110,100,111,109, 40, - 48, 44, 32, 57, 57, 57, 57, 57, 41, 44, 32,115,101,113,110,111, 41, 10,101,110, -100, 10, 10, 45, 45, 32,115,101,110,100, 95,109,101,115,115, 97,103,101, 32,102, -111,114,119, 97,114,100, 32,100,101, 99,108, 97,114, 97,116,105,111,110, 10,108, -111, 99, 97,108, 32,115,101,110,100, 95,109,101,115,115, 97,103,101, 10, 10, 45, - 45, 32,121,105,101,108,100, 32,116,104,101, 32,104,101, 97,100,101,114,115, 32, - 97,108,108, 32, 97,116, 32,111,110, 99,101, 44, 32,105,116, 39,115, 32,102, 97, -115,116,101,114, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32, -115,101,110,100, 95,104,101, 97,100,101,114,115, 40,104,101, 97,100,101,114,115, - 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104, 32, 61, 32, 34, 92,114, 92, -110, 34, 10, 32, 32, 32, 32,102,111,114, 32,105, 44,118, 32,105,110, 32, 98, 97, -115,101, 46,112, 97,105,114,115, 40,104,101, 97,100,101,114,115, 41, 32,100,111, - 10, 32, 32, 32, 32, 32, 32, 32, 32,104, 32, 61, 32,105, 32, 46, 46, 32, 39, 58, - 32, 39, 32, 46, 46, 32,118, 32, 46, 46, 32, 34, 92,114, 92,110, 34, 32, 46, 46, - 32,104, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 99,111,114,111,117, -116,105,110,101, 46,121,105,101,108,100, 40,104, 41, 10,101,110,100, 10, 10, 45, - 45, 32,121,105,101,108,100, 32,109,117,108,116,105,112, 97,114,116, 32,109,101, -115,115, 97,103,101, 32, 98,111,100,121, 32,102,114,111,109, 32, 97, 32,109,117, -108,116,105,112, 97,114,116, 32,109,101,115,115, 97,103,101, 32,116, 97, 98,108, -101, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,115,101,110, -100, 95,109,117,108,116,105,112, 97,114,116, 40,109,101,115,103,116, 41, 10, 32, - 32, 32, 32, 45, 45, 32,109, 97,107,101, 32,115,117,114,101, 32,119,101, 32,104, - 97,118,101, 32,111,117,114, 32, 98,111,117,110,100, 97,114,121, 32, 97,110,100, - 32,115,101,110,100, 32,104,101, 97,100,101,114,115, 10, 32, 32, 32, 32,108,111, - 99, 97,108, 32, 98,100, 32, 61, 32,110,101,119, 98,111,117,110,100, 97,114,121, - 40, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104,101, 97,100,101,114,115, - 32, 61, 32,108,111,119,101,114, 95,104,101, 97,100,101,114,115, 40,109,101,115, -103,116, 46,104,101, 97,100,101,114,115, 32,111,114, 32,123,125, 41, 10, 32, 32, - 32, 32,104,101, 97,100,101,114,115, 91, 39, 99,111,110,116,101,110,116, 45,116, -121,112,101, 39, 93, 32, 61, 32,104,101, 97,100,101,114,115, 91, 39, 99,111,110, -116,101,110,116, 45,116,121,112,101, 39, 93, 32,111,114, 32, 39,109,117,108,116, -105,112, 97,114,116, 47,109,105,120,101,100, 39, 10, 32, 32, 32, 32,104,101, 97, -100,101,114,115, 91, 39, 99,111,110,116,101,110,116, 45,116,121,112,101, 39, 93, - 32, 61, 32,104,101, 97,100,101,114,115, 91, 39, 99,111,110,116,101,110,116, 45, -116,121,112,101, 39, 93, 32, 46, 46, 10, 32, 32, 32, 32, 32, 32, 32, 32, 39, 59, - 32, 98,111,117,110,100, 97,114,121, 61, 34, 39, 32, 46, 46, 32, 32, 98,100, 32, - 46, 46, 32, 39, 34, 39, 10, 32, 32, 32, 32,115,101,110,100, 95,104,101, 97,100, -101,114,115, 40,104,101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32, 45, 45, 32, -115,101,110,100, 32,112,114,101, 97,109, 98,108,101, 10, 32, 32, 32, 32,105,102, - 32,109,101,115,103,116, 46, 98,111,100,121, 46,112,114,101, 97,109, 98,108,101, - 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99,111,114,111,117,116, -105,110,101, 46,121,105,101,108,100, 40,109,101,115,103,116, 46, 98,111,100,121, - 46,112,114,101, 97,109, 98,108,101, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99, + 45, 45, 45, 10, 45, 45, 32,114,101,116,117,114,110,115, 32, 97, 32,104,111,112, +101,102,117,108,108,121, 32,117,110,105,113,117,101, 32,109,105,109,101, 32, 98, +111,117,110,100, 97,114,121, 10,108,111, 99, 97,108, 32,115,101,113,110,111, 32, + 61, 32, 48, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,110, +101,119, 98,111,117,110,100, 97,114,121, 40, 41, 10, 32, 32, 32, 32,115,101,113, +110,111, 32, 61, 32,115,101,113,110,111, 32, 43, 32, 49, 10, 32, 32, 32, 32,114, +101,116,117,114,110, 32,115,116,114,105,110,103, 46,102,111,114,109, 97,116, 40, + 39, 37,115, 37, 48, 53,100, 61, 61, 37, 48, 53,117, 39, 44, 32,111,115, 46,100, + 97,116,101, 40, 39, 37,100, 37,109, 37, 89, 37, 72, 37, 77, 37, 83, 39, 41, 44, + 10, 32, 32, 32, 32, 32, 32, 32, 32,109, 97,116,104, 46,114, 97,110,100,111,109, + 40, 48, 44, 32, 57, 57, 57, 57, 57, 41, 44, 32,115,101,113,110,111, 41, 10,101, +110,100, 10, 10, 45, 45, 32,115,101,110,100, 95,109,101,115,115, 97,103,101, 32, +102,111,114,119, 97,114,100, 32,100,101, 99,108, 97,114, 97,116,105,111,110, 10, +108,111, 99, 97,108, 32,115,101,110,100, 95,109,101,115,115, 97,103,101, 10, 10, + 45, 45, 32,121,105,101,108,100, 32,116,104,101, 32,104,101, 97,100,101,114,115, + 32, 97,108,108, 32, 97,116, 32,111,110, 99,101, 44, 32,105,116, 39,115, 32,102, + 97,115,116,101,114, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, + 32,115,101,110,100, 95,104,101, 97,100,101,114,115, 40,116,111,115,101,110,100, + 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99, 97,110,111,110,105, 99, 32, + 61, 32,104,101, 97,100,101,114,115, 46, 99, 97,110,111,110,105, 99, 10, 32, 32, + 32, 32,108,111, 99, 97,108, 32,104, 32, 61, 32, 34, 92,114, 92,110, 34, 10, 32, + 32, 32, 32,102,111,114, 32,102, 44,118, 32,105,110, 32, 98, 97,115,101, 46,112, + 97,105,114,115, 40,116,111,115,101,110,100, 41, 32,100,111, 10, 32, 32, 32, 32, + 32, 32, 32, 32,104, 32, 61, 32, 40, 99, 97,110,111,110,105, 99, 91,102, 93, 32, +111,114, 32,102, 41, 32, 46, 46, 32, 39, 58, 32, 39, 32, 46, 46, 32,118, 32, 46, + 46, 32, 34, 92,114, 92,110, 34, 32, 46, 46, 32,104, 10, 32, 32, 32, 32,101,110, +100, 10, 32, 32, 32, 32, 99,111,114,111,117,116,105,110,101, 46,121,105,101,108, +100, 40,104, 41, 10,101,110,100, 10, 10, 45, 45, 32,121,105,101,108,100, 32,109, +117,108,116,105,112, 97,114,116, 32,109,101,115,115, 97,103,101, 32, 98,111,100, +121, 32,102,114,111,109, 32, 97, 32,109,117,108,116,105,112, 97,114,116, 32,109, +101,115,115, 97,103,101, 32,116, 97, 98,108,101, 10,108,111, 99, 97,108, 32,102, +117,110, 99,116,105,111,110, 32,115,101,110,100, 95,109,117,108,116,105,112, 97, +114,116, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32, 45, 45, 32,109, 97,107, +101, 32,115,117,114,101, 32,119,101, 32,104, 97,118,101, 32,111,117,114, 32, 98, +111,117,110,100, 97,114,121, 32, 97,110,100, 32,115,101,110,100, 32,104,101, 97, +100,101,114,115, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 98,100, 32, 61, 32, +110,101,119, 98,111,117,110,100, 97,114,121, 40, 41, 10, 32, 32, 32, 32,108,111, + 99, 97,108, 32,104,101, 97,100,101,114,115, 32, 61, 32,108,111,119,101,114, 95, +104,101, 97,100,101,114,115, 40,109,101,115,103,116, 46,104,101, 97,100,101,114, +115, 32,111,114, 32,123,125, 41, 10, 32, 32, 32, 32,104,101, 97,100,101,114,115, + 91, 39, 99,111,110,116,101,110,116, 45,116,121,112,101, 39, 93, 32, 61, 32,104, +101, 97,100,101,114,115, 91, 39, 99,111,110,116,101,110,116, 45,116,121,112,101, + 39, 93, 32,111,114, 32, 39,109,117,108,116,105,112, 97,114,116, 47,109,105,120, +101,100, 39, 10, 32, 32, 32, 32,104,101, 97,100,101,114,115, 91, 39, 99,111,110, +116,101,110,116, 45,116,121,112,101, 39, 93, 32, 61, 32,104,101, 97,100,101,114, +115, 91, 39, 99,111,110,116,101,110,116, 45,116,121,112,101, 39, 93, 32, 46, 46, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 39, 59, 32, 98,111,117,110,100, 97,114,121, + 61, 34, 39, 32, 46, 46, 32, 32, 98,100, 32, 46, 46, 32, 39, 34, 39, 10, 32, 32, + 32, 32,115,101,110,100, 95,104,101, 97,100,101,114,115, 40,104,101, 97,100,101, +114,115, 41, 10, 32, 32, 32, 32, 45, 45, 32,115,101,110,100, 32,112,114,101, 97, +109, 98,108,101, 10, 32, 32, 32, 32,105,102, 32,109,101,115,103,116, 46, 98,111, +100,121, 46,112,114,101, 97,109, 98,108,101, 32,116,104,101,110, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 99,111,114,111,117,116,105,110,101, 46,121,105,101,108,100, + 40,109,101,115,103,116, 46, 98,111,100,121, 46,112,114,101, 97,109, 98,108,101, + 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99,111,114,111,117,116,105,110,101, 46, +121,105,101,108,100, 40, 34, 92,114, 92,110, 34, 41, 10, 32, 32, 32, 32,101,110, +100, 10, 32, 32, 32, 32, 45, 45, 32,115,101,110,100, 32,101, 97, 99,104, 32,112, + 97,114,116, 32,115,101,112, 97,114, 97,116,101,100, 32, 98,121, 32, 97, 32, 98, +111,117,110,100, 97,114,121, 10, 32, 32, 32, 32,102,111,114, 32,105, 44, 32,109, + 32,105,110, 32, 98, 97,115,101, 46,105,112, 97,105,114,115, 40,109,101,115,103, +116, 46, 98,111,100,121, 41, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99, 111,114,111,117,116,105,110,101, 46,121,105,101,108,100, 40, 34, 92,114, 92,110, - 34, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, 32,115,101, -110,100, 32,101, 97, 99,104, 32,112, 97,114,116, 32,115,101,112, 97,114, 97,116, -101,100, 32, 98,121, 32, 97, 32, 98,111,117,110,100, 97,114,121, 10, 32, 32, 32, - 32,102,111,114, 32,105, 44, 32,109, 32,105,110, 32, 98, 97,115,101, 46,105,112, - 97,105,114,115, 40,109,101,115,103,116, 46, 98,111,100,121, 41, 32,100,111, 10, - 32, 32, 32, 32, 32, 32, 32, 32, 99,111,114,111,117,116,105,110,101, 46,121,105, -101,108,100, 40, 34, 92,114, 92,110, 45, 45, 34, 32, 46, 46, 32, 98,100, 32, 46, - 46, 32, 34, 92,114, 92,110, 34, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101, -110,100, 95,109,101,115,115, 97,103,101, 40,109, 41, 10, 32, 32, 32, 32,101,110, -100, 10, 32, 32, 32, 32, 45, 45, 32,115,101,110,100, 32,108, 97,115,116, 32, 98, -111,117,110,100, 97,114,121, 10, 32, 32, 32, 32, 99,111,114,111,117,116,105,110, -101, 46,121,105,101,108,100, 40, 34, 92,114, 92,110, 45, 45, 34, 32, 46, 46, 32, - 98,100, 32, 46, 46, 32, 34, 45, 45, 92,114, 92,110, 92,114, 92,110, 34, 41, 10, - 32, 32, 32, 32, 45, 45, 32,115,101,110,100, 32,101,112,105,108,111,103,117,101, - 10, 32, 32, 32, 32,105,102, 32,109,101,115,103,116, 46, 98,111,100,121, 46,101, -112,105,108,111,103,117,101, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, - 32, 99,111,114,111,117,116,105,110,101, 46,121,105,101,108,100, 40,109,101,115, -103,116, 46, 98,111,100,121, 46,101,112,105,108,111,103,117,101, 41, 10, 32, 32, - 32, 32, 32, 32, 32, 32, 99,111,114,111,117,116,105,110,101, 46,121,105,101,108, -100, 40, 34, 92,114, 92,110, 34, 41, 10, 32, 32, 32, 32,101,110,100, 10,101,110, + 45, 45, 34, 32, 46, 46, 32, 98,100, 32, 46, 46, 32, 34, 92,114, 92,110, 34, 41, + 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,110,100, 95,109,101,115,115, 97,103, +101, 40,109, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, 32, +115,101,110,100, 32,108, 97,115,116, 32, 98,111,117,110,100, 97,114,121, 10, 32, + 32, 32, 32, 99,111,114,111,117,116,105,110,101, 46,121,105,101,108,100, 40, 34, + 92,114, 92,110, 45, 45, 34, 32, 46, 46, 32, 98,100, 32, 46, 46, 32, 34, 45, 45, + 92,114, 92,110, 92,114, 92,110, 34, 41, 10, 32, 32, 32, 32, 45, 45, 32,115,101, +110,100, 32,101,112,105,108,111,103,117,101, 10, 32, 32, 32, 32,105,102, 32,109, +101,115,103,116, 46, 98,111,100,121, 46,101,112,105,108,111,103,117,101, 32,116, +104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99,111,114,111,117,116,105,110, +101, 46,121,105,101,108,100, 40,109,101,115,103,116, 46, 98,111,100,121, 46,101, +112,105,108,111,103,117,101, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99,111,114, +111,117,116,105,110,101, 46,121,105,101,108,100, 40, 34, 92,114, 92,110, 34, 41, + 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32,121,105,101, +108,100, 32,109,101,115,115, 97,103,101, 32, 98,111,100,121, 32,102,114,111,109, + 32, 97, 32,115,111,117,114, 99,101, 10,108,111, 99, 97,108, 32,102,117,110, 99, +116,105,111,110, 32,115,101,110,100, 95,115,111,117,114, 99,101, 40,109,101,115, +103,116, 41, 10, 32, 32, 32, 32, 45, 45, 32,109, 97,107,101, 32,115,117,114,101, + 32,119,101, 32,104, 97,118,101, 32, 97, 32, 99,111,110,116,101,110,116, 45,116, +121,112,101, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104,101, 97,100,101,114, +115, 32, 61, 32,108,111,119,101,114, 95,104,101, 97,100,101,114,115, 40,109,101, +115,103,116, 46,104,101, 97,100,101,114,115, 32,111,114, 32,123,125, 41, 10, 32, + 32, 32, 32,104,101, 97,100,101,114,115, 91, 39, 99,111,110,116,101,110,116, 45, +116,121,112,101, 39, 93, 32, 61, 32,104,101, 97,100,101,114,115, 91, 39, 99,111, +110,116,101,110,116, 45,116,121,112,101, 39, 93, 32,111,114, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 39,116,101,120,116, 47,112,108, 97,105,110, 59, 32, 99,104, 97, +114,115,101,116, 61, 34,105,115,111, 45, 56, 56, 53, 57, 45, 49, 34, 39, 10, 32, + 32, 32, 32,115,101,110,100, 95,104,101, 97,100,101,114,115, 40,104,101, 97,100, +101,114,115, 41, 10, 32, 32, 32, 32, 45, 45, 32,115,101,110,100, 32, 98,111,100, +121, 32,102,114,111,109, 32,115,111,117,114, 99,101, 10, 32, 32, 32, 32,119,104, +105,108,101, 32,116,114,117,101, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, +108,111, 99, 97,108, 32, 99,104,117,110,107, 44, 32,101,114,114, 32, 61, 32,109, +101,115,103,116, 46, 98,111,100,121, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, +105,102, 32,101,114,114, 32,116,104,101,110, 32, 99,111,114,111,117,116,105,110, +101, 46,121,105,101,108,100, 40,110,105,108, 44, 32,101,114,114, 41, 10, 32, 32, + 32, 32, 32, 32, 32, 32,101,108,115,101,105,102, 32, 99,104,117,110,107, 32,116, +104,101,110, 32, 99,111,114,111,117,116,105,110,101, 46,121,105,101,108,100, 40, + 99,104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32, + 98,114,101, 97,107, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 10,101,110, 100, 10, 10, 45, 45, 32,121,105,101,108,100, 32,109,101,115,115, 97,103,101, 32, - 98,111,100,121, 32,102,114,111,109, 32, 97, 32,115,111,117,114, 99,101, 10,108, + 98,111,100,121, 32,102,114,111,109, 32, 97, 32,115,116,114,105,110,103, 10,108, 111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,115,101,110,100, 95,115, -111,117,114, 99,101, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32, 45, 45, 32, +116,114,105,110,103, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32, 45, 45, 32, 109, 97,107,101, 32,115,117,114,101, 32,119,101, 32,104, 97,118,101, 32, 97, 32, 99,111,110,116,101,110,116, 45,116,121,112,101, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104,101, 97,100,101,114,115, 32, 61, 32,108,111,119,101,114, 95,104, @@ -309,102 +339,77 @@ static const unsigned char B1[]={ 108, 97,105,110, 59, 32, 99,104, 97,114,115,101,116, 61, 34,105,115,111, 45, 56, 56, 53, 57, 45, 49, 34, 39, 10, 32, 32, 32, 32,115,101,110,100, 95,104,101, 97, 100,101,114,115, 40,104,101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32, 45, 45, - 32,115,101,110,100, 32, 98,111,100,121, 32,102,114,111,109, 32,115,111,117,114, - 99,101, 10, 32, 32, 32, 32,119,104,105,108,101, 32,116,114,117,101, 32,100,111, - 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104,117,110,107, - 44, 32,101,114,114, 32, 61, 32,109,101,115,103,116, 46, 98,111,100,121, 40, 41, - 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104,101,110, - 32, 99,111,114,111,117,116,105,110,101, 46,121,105,101,108,100, 40,110,105,108, - 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101,105, -102, 32, 99,104,117,110,107, 32,116,104,101,110, 32, 99,111,114,111,117,116,105, -110,101, 46,121,105,101,108,100, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32, - 32, 32, 32, 32,101,108,115,101, 32, 98,114,101, 97,107, 32,101,110,100, 10, 32, - 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32,121,105,101,108,100, - 32,109,101,115,115, 97,103,101, 32, 98,111,100,121, 32,102,114,111,109, 32, 97, - 32,115,116,114,105,110,103, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105, -111,110, 32,115,101,110,100, 95,115,116,114,105,110,103, 40,109,101,115,103,116, - 41, 10, 32, 32, 32, 32, 45, 45, 32,109, 97,107,101, 32,115,117,114,101, 32,119, -101, 32,104, 97,118,101, 32, 97, 32, 99,111,110,116,101,110,116, 45,116,121,112, -101, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104,101, 97,100,101,114,115, 32, - 61, 32,108,111,119,101,114, 95,104,101, 97,100,101,114,115, 40,109,101,115,103, -116, 46,104,101, 97,100,101,114,115, 32,111,114, 32,123,125, 41, 10, 32, 32, 32, - 32,104,101, 97,100,101,114,115, 91, 39, 99,111,110,116,101,110,116, 45,116,121, -112,101, 39, 93, 32, 61, 32,104,101, 97,100,101,114,115, 91, 39, 99,111,110,116, -101,110,116, 45,116,121,112,101, 39, 93, 32,111,114, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 39,116,101,120,116, 47,112,108, 97,105,110, 59, 32, 99,104, 97,114,115, -101,116, 61, 34,105,115,111, 45, 56, 56, 53, 57, 45, 49, 34, 39, 10, 32, 32, 32, - 32,115,101,110,100, 95,104,101, 97,100,101,114,115, 40,104,101, 97,100,101,114, -115, 41, 10, 32, 32, 32, 32, 45, 45, 32,115,101,110,100, 32, 98,111,100,121, 32, -102,114,111,109, 32,115,116,114,105,110,103, 10, 32, 32, 32, 32, 99,111,114,111, -117,116,105,110,101, 46,121,105,101,108,100, 40,109,101,115,103,116, 46, 98,111, -100,121, 41, 10,101,110,100, 10, 10, 45, 45, 32,109,101,115,115, 97,103,101, 32, -115,111,117,114, 99,101, 10,102,117,110, 99,116,105,111,110, 32,115,101,110,100, - 95,109,101,115,115, 97,103,101, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32, -105,102, 32, 98, 97,115,101, 46,116,121,112,101, 40,109,101,115,103,116, 46, 98, -111,100,121, 41, 32, 61, 61, 32, 34,116, 97, 98,108,101, 34, 32,116,104,101,110, - 32,115,101,110,100, 95,109,117,108,116,105,112, 97,114,116, 40,109,101,115,103, -116, 41, 10, 32, 32, 32, 32,101,108,115,101,105,102, 32, 98, 97,115,101, 46,116, + 32,115,101,110,100, 32, 98,111,100,121, 32,102,114,111,109, 32,115,116,114,105, +110,103, 10, 32, 32, 32, 32, 99,111,114,111,117,116,105,110,101, 46,121,105,101, +108,100, 40,109,101,115,103,116, 46, 98,111,100,121, 41, 10,101,110,100, 10, 10, + 45, 45, 32,109,101,115,115, 97,103,101, 32,115,111,117,114, 99,101, 10,102,117, +110, 99,116,105,111,110, 32,115,101,110,100, 95,109,101,115,115, 97,103,101, 40, +109,101,115,103,116, 41, 10, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46,116, 121,112,101, 40,109,101,115,103,116, 46, 98,111,100,121, 41, 32, 61, 61, 32, 34, -102,117,110, 99,116,105,111,110, 34, 32,116,104,101,110, 32,115,101,110,100, 95, -115,111,117,114, 99,101, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32,101,108, -115,101, 32,115,101,110,100, 95,115,116,114,105,110,103, 40,109,101,115,103,116, - 41, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32,115,101,116, 32,100,101, -102, 97,117,108, 32,104,101, 97,100,101,114,115, 10,108,111, 99, 97,108, 32,102, -117,110, 99,116,105,111,110, 32, 97,100,106,117,115,116, 95,104,101, 97,100,101, -114,115, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, -108,111,119,101,114, 32, 61, 32,108,111,119,101,114, 95,104,101, 97,100,101,114, -115, 40,109,101,115,103,116, 46,104,101, 97,100,101,114,115, 41, 10, 32, 32, 32, - 32,108,111,119,101,114, 91, 34,100, 97,116,101, 34, 93, 32, 61, 32,108,111,119, -101,114, 91, 34,100, 97,116,101, 34, 93, 32,111,114, 10, 32, 32, 32, 32, 32, 32, - 32, 32,111,115, 46,100, 97,116,101, 40, 34, 33, 37, 97, 44, 32, 37,100, 32, 37, - 98, 32, 37, 89, 32, 37, 72, 58, 37, 77, 58, 37, 83, 32, 34, 41, 32, 46, 46, 32, - 40,109,101,115,103,116, 46,122,111,110,101, 32,111,114, 32, 90, 79, 78, 69, 41, - 10, 32, 32, 32, 32,108,111,119,101,114, 91, 34,120, 45,109, 97,105,108,101,114, - 34, 93, 32, 61, 32,108,111,119,101,114, 91, 34,120, 45,109, 97,105,108,101,114, - 34, 93, 32,111,114, 32,115,111, 99,107,101,116, 46, 95, 86, 69, 82, 83, 73, 79, - 78, 10, 32, 32, 32, 32, 45, 45, 32,116,104,105,115, 32, 99, 97,110, 39,116, 32, - 98,101, 32,111,118,101,114,114,105,100,101,110, 10, 32, 32, 32, 32,108,111,119, -101,114, 91, 34,109,105,109,101, 45,118,101,114,115,105,111,110, 34, 93, 32, 61, - 32, 34, 49, 46, 48, 34, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,108,111, -119,101,114, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101, -115,115, 97,103,101, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32,109,101,115, -103,116, 46,104,101, 97,100,101,114,115, 32, 61, 32, 97,100,106,117,115,116, 95, -104,101, 97,100,101,114,115, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32, 45, - 45, 32, 99,114,101, 97,116,101, 32, 97,110,100, 32,114,101,116,117,114,110, 32, -109,101,115,115, 97,103,101, 32,115,111,117,114, 99,101, 10, 32, 32, 32, 32,108, -111, 99, 97,108, 32, 99,111, 32, 61, 32, 99,111,114,111,117,116,105,110,101, 46, - 99,114,101, 97,116,101, 40,102,117,110, 99,116,105,111,110, 40, 41, 32,115,101, -110,100, 95,109,101,115,115, 97,103,101, 40,109,101,115,103,116, 41, 32,101,110, -100, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105, -111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,114, -101,116, 44, 32, 97, 44, 32, 98, 32, 61, 32, 99,111,114,111,117,116,105,110,101, - 46,114,101,115,117,109,101, 40, 99,111, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, -105,102, 32,114,101,116, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 97, - 44, 32, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,114,101,116, -117,114,110, 32,110,105,108, 44, 32, 97, 32,101,110,100, 10, 32, 32, 32, 32,101, -110,100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +116, 97, 98,108,101, 34, 32,116,104,101,110, 32,115,101,110,100, 95,109,117,108, +116,105,112, 97,114,116, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32,101,108, +115,101,105,102, 32, 98, 97,115,101, 46,116,121,112,101, 40,109,101,115,103,116, + 46, 98,111,100,121, 41, 32, 61, 61, 32, 34,102,117,110, 99,116,105,111,110, 34, + 32,116,104,101,110, 32,115,101,110,100, 95,115,111,117,114, 99,101, 40,109,101, +115,103,116, 41, 10, 32, 32, 32, 32,101,108,115,101, 32,115,101,110,100, 95,115, +116,114,105,110,103, 40,109,101,115,103,116, 41, 32,101,110,100, 10,101,110,100, + 10, 10, 45, 45, 32,115,101,116, 32,100,101,102, 97,117,108, 32,104,101, 97,100, +101,114,115, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32, 97, +100,106,117,115,116, 95,104,101, 97,100,101,114,115, 40,109,101,115,103,116, 41, + 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,108,111,119,101,114, 32, 61, 32,108, +111,119,101,114, 95,104,101, 97,100,101,114,115, 40,109,101,115,103,116, 46,104, +101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32,108,111,119,101,114, 91, 34,100, + 97,116,101, 34, 93, 32, 61, 32,108,111,119,101,114, 91, 34,100, 97,116,101, 34, + 93, 32,111,114, 10, 32, 32, 32, 32, 32, 32, 32, 32,111,115, 46,100, 97,116,101, + 40, 34, 33, 37, 97, 44, 32, 37,100, 32, 37, 98, 32, 37, 89, 32, 37, 72, 58, 37, + 77, 58, 37, 83, 32, 34, 41, 32, 46, 46, 32, 40,109,101,115,103,116, 46,122,111, +110,101, 32,111,114, 32, 95, 77, 46, 90, 79, 78, 69, 41, 10, 32, 32, 32, 32,108, +111,119,101,114, 91, 34,120, 45,109, 97,105,108,101,114, 34, 93, 32, 61, 32,108, +111,119,101,114, 91, 34,120, 45,109, 97,105,108,101,114, 34, 93, 32,111,114, 32, +115,111, 99,107,101,116, 46, 95, 86, 69, 82, 83, 73, 79, 78, 10, 32, 32, 32, 32, + 45, 45, 32,116,104,105,115, 32, 99, 97,110, 39,116, 32, 98,101, 32,111,118,101, +114,114,105,100,101,110, 10, 32, 32, 32, 32,108,111,119,101,114, 91, 34,109,105, +109,101, 45,118,101,114,115,105,111,110, 34, 93, 32, 61, 32, 34, 49, 46, 48, 34, + 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,108,111,119,101,114, 10,101,110, +100, 10, 10,102,117,110, 99,116,105,111,110, 32, 95, 77, 46,109,101,115,115, 97, +103,101, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32,109,101,115,103,116, 46, +104,101, 97,100,101,114,115, 32, 61, 32, 97,100,106,117,115,116, 95,104,101, 97, +100,101,114,115, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32, 45, 45, 32, 99, +114,101, 97,116,101, 32, 97,110,100, 32,114,101,116,117,114,110, 32,109,101,115, +115, 97,103,101, 32,115,111,117,114, 99,101, 10, 32, 32, 32, 32,108,111, 99, 97, +108, 32, 99,111, 32, 61, 32, 99,111,114,111,117,116,105,110,101, 46, 99,114,101, + 97,116,101, 40,102,117,110, 99,116,105,111,110, 40, 41, 32,115,101,110,100, 95, +109,101,115,115, 97,103,101, 40,109,101,115,103,116, 41, 32,101,110,100, 41, 10, + 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, + 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,116, 44, + 32, 97, 44, 32, 98, 32, 61, 32, 99,111,114,111,117,116,105,110,101, 46,114,101, +115,117,109,101, 40, 99,111, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, +114,101,116, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 97, 44, 32, 98, + 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, + 32,110,105,108, 44, 32, 97, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 10, +101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 10, 45, 45, 32, 72,105,103,104, 32,108,101,118,101,108, 32, 83, 77, - 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 10, 45, 45, 32, 72,105,103,104, 32,108,101,118,101,108, 32, 83, 77, 84, 80, 32, + 65, 80, 73, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 10,115,101,110,100, 32, 61, 32,115,111, 99,107,101,116, 46,112, + 45, 10, 95, 77, 46,115,101,110,100, 32, 61, 32,115,111, 99,107,101,116, 46,112, 114,111,116,101, 99,116, 40,102,117,110, 99,116,105,111,110, 40,109, 97,105,108, -116, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115, 32, 61, 32,111,112,101, -110, 40,109, 97,105,108,116, 46,115,101,114,118,101,114, 44, 32,109, 97,105,108, -116, 46,112,111,114,116, 44, 32,109, 97,105,108,116, 46, 99,114,101, 97,116,101, - 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,101,120,116, 32, 61, 32,115, 58, -103,114,101,101,116, 40,109, 97,105,108,116, 46,100,111,109, 97,105,110, 41, 10, - 32, 32, 32, 32,115, 58, 97,117,116,104, 40,109, 97,105,108,116, 46,117,115,101, -114, 44, 32,109, 97,105,108,116, 46,112, 97,115,115,119,111,114,100, 44, 32,101, -120,116, 41, 10, 32, 32, 32, 32,115, 58,115,101,110,100, 40,109, 97,105,108,116, - 41, 10, 32, 32, 32, 32,115, 58,113,117,105,116, 40, 41, 10, 32, 32, 32, 32,114, -101,116,117,114,110, 32,115, 58, 99,108,111,115,101, 40, 41, 10,101,110,100, 41, - 10, +116, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115, 32, 61, 32, 95, 77, 46, +111,112,101,110, 40,109, 97,105,108,116, 46,115,101,114,118,101,114, 44, 32,109, + 97,105,108,116, 46,112,111,114,116, 44, 32,109, 97,105,108,116, 46, 99,114,101, + 97,116,101, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,101,120,116, 32, 61, + 32,115, 58,103,114,101,101,116, 40,109, 97,105,108,116, 46,100,111,109, 97,105, +110, 41, 10, 32, 32, 32, 32,115, 58, 97,117,116,104, 40,109, 97,105,108,116, 46, +117,115,101,114, 44, 32,109, 97,105,108,116, 46,112, 97,115,115,119,111,114,100, + 44, 32,101,120,116, 41, 10, 32, 32, 32, 32,115, 58,115,101,110,100, 40,109, 97, +105,108,116, 41, 10, 32, 32, 32, 32,115, 58,113,117,105,116, 40, 41, 10, 32, 32, + 32, 32,114,101,116,117,114,110, 32,115, 58, 99,108,111,115,101, 40, 41, 10,101, +110,100, 41, 10, 10,114,101,116,117,114,110, 32, 95, 77, }; - if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"smtp.lua")==0) lua_call(L, 0, 0); + if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"smtp.lua")==0) lua_call(L, 0, LUA_MULTRET); } diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/socket.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/socket.h index 656c7f5d..63573de5 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/socket.h +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/socket.h @@ -8,8 +8,6 @@ * differences. Also, not all *nix platforms behave the same. This module * (and the associated usocket.h and wsocket.h) factor these differences and * creates a interface compatible with the io.h module. -* -* RCS ID: $Id: socket.h,v 1.20 2005/11/20 07:20:23 diego Exp $ \*=========================================================================*/ #include "io.h" @@ -61,6 +59,7 @@ int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *addr_len, p_timeout tm); const char *socket_hoststrerror(int err); +const char *socket_gaistrerror(int err); const char *socket_strerror(int err); /* these are perfect to use with the io abstraction module @@ -68,6 +67,9 @@ const char *socket_strerror(int err); int socket_send(p_socket ps, const char *data, size_t count, size_t *sent, p_timeout tm); int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm); +int socket_write(p_socket ps, const char *data, size_t count, + size_t *sent, p_timeout tm); +int socket_read(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm); const char *socket_ioerror(p_socket ps, int err); int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp); diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/socket.lua b/love/src/jni/love/src/libraries/luasocket/libluasocket/socket.lua index 211adcd1..d1c0b164 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/socket.lua +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/socket.lua @@ -1,7 +1,6 @@ ----------------------------------------------------------------------------- -- LuaSocket helper module -- Author: Diego Nehab --- RCS ID: $Id: socket.lua,v 1.22 2005/11/22 08:33:29 diego Exp $ ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- @@ -11,37 +10,52 @@ local base = _G local string = require("string") local math = require("math") local socket = require("socket.core") -module("socket") + +local _M = socket ----------------------------------------------------------------------------- -- Exported auxiliar functions ----------------------------------------------------------------------------- -function connect(address, port, laddress, lport) - local sock, err = socket.tcp() - if not sock then return nil, err end - if laddress then - local res, err = sock:bind(laddress, lport, -1) - if not res then return nil, err end +function _M.connect4(address, port, laddress, lport) + return socket.connect(address, port, laddress, lport, "inet") +end + +function _M.connect6(address, port, laddress, lport) + return socket.connect(address, port, laddress, lport, "inet6") +end + +function _M.bind(host, port, backlog) + if host == "*" then host = "0.0.0.0" end + local addrinfo, err = socket.dns.getaddrinfo(host); + if not addrinfo then return nil, err end + local sock, res + err = "no info on address" + for i, alt in base.ipairs(addrinfo) do + if alt.family == "inet" then + sock, err = socket.tcp4() + else + sock, err = socket.tcp6() + end + if not sock then return nil, err end + sock:setoption("reuseaddr", true) + res, err = sock:bind(alt.addr, port) + if not res then + sock:close() + else + res, err = sock:listen(backlog) + if not res then + sock:close() + else + return sock + end + end end - local res, err = sock:connect(address, port) - if not res then return nil, err end - return sock + return nil, err end -function bind(host, port, backlog) - local sock, err = socket.tcp() - if not sock then return nil, err end - sock:setoption("reuseaddr", true) - local res, err = sock:bind(host, port) - if not res then return nil, err end - res, err = sock:listen(backlog) - if not res then return nil, err end - return sock -end +_M.try = _M.newtry() -try = newtry() - -function choose(table) +function _M.choose(table) return function(name, opt1, opt2) if base.type(name) ~= "string" then name, opt1, opt2 = "default", name, opt1 @@ -56,10 +70,11 @@ end -- Socket sources and sinks, conforming to LTN12 ----------------------------------------------------------------------------- -- create namespaces inside LuaSocket namespace -sourcet = {} -sinkt = {} +local sourcet, sinkt = {}, {} +_M.sourcet = sourcet +_M.sinkt = sinkt -BLOCKSIZE = 2048 +_M.BLOCKSIZE = 2048 sinkt["close-when-done"] = function(sock) return base.setmetatable({ @@ -89,7 +104,7 @@ end sinkt["default"] = sinkt["keep-open"] -sink = choose(sinkt) +_M.sink = _M.choose(sinkt) sourcet["by-length"] = function(sock, length) return base.setmetatable({ @@ -129,5 +144,6 @@ end sourcet["default"] = sourcet["until-closed"] -source = choose(sourcet) +_M.source = _M.choose(sourcet) +return _M diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/socket.lua.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/socket.lua.h index 6dcaad05..f99e58ec 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/socket.lua.h +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/socket.lua.h @@ -1,7 +1,7 @@ /* code automatically generated by bin2c -- DO NOT EDIT */ { /* #include'ing this file in a C program is equivalent to calling - if (luaL_loadfile(L,"socket.lua")==0) lua_call(L, 0, 0); + if (luaL_loadfile(L,"socket.lua")==0) lua_call(L, 0, LUA_MULTRET); */ /* socket.lua */ static const unsigned char B1[]={ @@ -11,205 +11,224 @@ static const unsigned char B1[]={ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 76,117, 97, 83,111, 99,107,101,116, 32,104,101,108,112,101,114, 32,109,111, 100,117,108,101, 10, 45, 45, 32, 65,117,116,104,111,114, 58, 32, 68,105,101,103, -111, 32, 78,101,104, 97, 98, 10, 45, 45, 32, 82, 67, 83, 32, 73, 68, 58, 32, 36, - 73,100, 58, 32,115,111, 99,107,101,116, 46,108,117, 97, 44,118, 32, 49, 46, 50, - 50, 32, 50, 48, 48, 53, 47, 49, 49, 47, 50, 50, 32, 48, 56, 58, 51, 51, 58, 50, - 57, 32,100,105,101,103,111, 32, 69,120,112, 32, 36, 10, 45, 45, 45, 45, 45, 45, +111, 32, 78,101,104, 97, 98, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97,114, -101, 32,109,111,100,117,108,101, 32, 97,110,100, 32,105,109,112,111,114,116, 32, -100,101,112,101,110,100,101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97,114,101, 32,109,111,100,117, +108,101, 32, 97,110,100, 32,105,109,112,111,114,116, 32,100,101,112,101,110,100, +101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32, 98, 97,115, -101, 32, 61, 32, 95, 71, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, 32, - 61, 32,114,101,113,117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10, -108,111, 99, 97,108, 32,109, 97,116,104, 32, 61, 32,114,101,113,117,105,114,101, - 40, 34,109, 97,116,104, 34, 41, 10,108,111, 99, 97,108, 32,115,111, 99,107,101, -116, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,111, 99,107,101,116, 46, - 99,111,114,101, 34, 41, 10,109,111,100,117,108,101, 40, 34,115,111, 99,107,101, -116, 34, 41, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 10,108,111, 99, 97,108, 32, 98, 97,115,101, 32, 61, 32, 95, 71, + 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, 32, 61, 32,114,101,113,117, +105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10,108,111, 99, 97,108, 32, +109, 97,116,104, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,109, 97,116,104, + 34, 41, 10,108,111, 99, 97,108, 32,115,111, 99,107,101,116, 32, 61, 32,114,101, +113,117,105,114,101, 40, 34,115,111, 99,107,101,116, 46, 99,111,114,101, 34, 41, + 10, 10,108,111, 99, 97,108, 32, 95, 77, 32, 61, 32,115,111, 99,107,101,116, 10, + 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, + 45, 32, 69,120,112,111,114,116,101,100, 32, 97,117,120,105,108,105, 97,114, 32, +102,117,110, 99,116,105,111,110,115, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 10, 45, 45, 32, 69,120,112,111,114,116,101,100, 32, 97,117,120,105,108, -105, 97,114, 32,102,117,110, 99,116,105,111,110,115, 10, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,102,117,110, 99,116,105,111,110, - 32, 99,111,110,110,101, 99,116, 40, 97,100,100,114,101,115,115, 44, 32,112,111, + 45, 45, 45, 45, 45, 45, 45, 10,102,117,110, 99,116,105,111,110, 32, 95, 77, 46, + 99,111,110,110,101, 99,116, 52, 40, 97,100,100,114,101,115,115, 44, 32,112,111, 114,116, 44, 32,108, 97,100,100,114,101,115,115, 44, 32,108,112,111,114,116, 41, - 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,111, 99,107, 44, 32,101,114,114, - 32, 61, 32,115,111, 99,107,101,116, 46,116, 99,112, 40, 41, 10, 32, 32, 32, 32, -105,102, 32,110,111,116, 32,115,111, 99,107, 32,116,104,101,110, 32,114,101,116, -117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, - 32,105,102, 32,108, 97,100,100,114,101,115,115, 32,116,104,101,110, 10, 32, 32, - 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,115, 44, 32,101,114,114, - 32, 61, 32,115,111, 99,107, 58, 98,105,110,100, 40,108, 97,100,100,114,101,115, -115, 44, 32,108,112,111,114,116, 44, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, - 32, 32,105,102, 32,110,111,116, 32,114,101,115, 32,116,104,101,110, 32,114,101, + 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,111, 99,107,101,116, 46, 99, +111,110,110,101, 99,116, 40, 97,100,100,114,101,115,115, 44, 32,112,111,114,116, + 44, 32,108, 97,100,100,114,101,115,115, 44, 32,108,112,111,114,116, 44, 32, 34, +105,110,101,116, 34, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, + 32, 95, 77, 46, 99,111,110,110,101, 99,116, 54, 40, 97,100,100,114,101,115,115, + 44, 32,112,111,114,116, 44, 32,108, 97,100,100,114,101,115,115, 44, 32,108,112, +111,114,116, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,111, 99,107, +101,116, 46, 99,111,110,110,101, 99,116, 40, 97,100,100,114,101,115,115, 44, 32, +112,111,114,116, 44, 32,108, 97,100,100,114,101,115,115, 44, 32,108,112,111,114, +116, 44, 32, 34,105,110,101,116, 54, 34, 41, 10,101,110,100, 10, 10,102,117,110, + 99,116,105,111,110, 32, 95, 77, 46, 98,105,110,100, 40,104,111,115,116, 44, 32, +112,111,114,116, 44, 32, 98, 97, 99,107,108,111,103, 41, 10, 32, 32, 32, 32,105, +102, 32,104,111,115,116, 32, 61, 61, 32, 34, 42, 34, 32,116,104,101,110, 32,104, +111,115,116, 32, 61, 32, 34, 48, 46, 48, 46, 48, 46, 48, 34, 32,101,110,100, 10, + 32, 32, 32, 32,108,111, 99, 97,108, 32, 97,100,100,114,105,110,102,111, 44, 32, +101,114,114, 32, 61, 32,115,111, 99,107,101,116, 46,100,110,115, 46,103,101,116, + 97,100,100,114,105,110,102,111, 40,104,111,115,116, 41, 59, 10, 32, 32, 32, 32, +105,102, 32,110,111,116, 32, 97,100,100,114,105,110,102,111, 32,116,104,101,110, + 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, + 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,111, 99,107, 44, 32,114,101,115, + 10, 32, 32, 32, 32,101,114,114, 32, 61, 32, 34,110,111, 32,105,110,102,111, 32, +111,110, 32, 97,100,100,114,101,115,115, 34, 10, 32, 32, 32, 32,102,111,114, 32, +105, 44, 32, 97,108,116, 32,105,110, 32, 98, 97,115,101, 46,105,112, 97,105,114, +115, 40, 97,100,100,114,105,110,102,111, 41, 32,100,111, 10, 32, 32, 32, 32, 32, + 32, 32, 32,105,102, 32, 97,108,116, 46,102, 97,109,105,108,121, 32, 61, 61, 32, + 34,105,110,101,116, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,115,111, 99,107, 44, 32,101,114,114, 32, 61, 32,115,111, 99,107, +101,116, 46,116, 99,112, 52, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108, +115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,111, 99,107, 44, + 32,101,114,114, 32, 61, 32,115,111, 99,107,101,116, 46,116, 99,112, 54, 40, 41, + 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, + 32,105,102, 32,110,111,116, 32,115,111, 99,107, 32,116,104,101,110, 32,114,101, 116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, - 32, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,115, 44, - 32,101,114,114, 32, 61, 32,115,111, 99,107, 58, 99,111,110,110,101, 99,116, 40, - 97,100,100,114,101,115,115, 44, 32,112,111,114,116, 41, 10, 32, 32, 32, 32,105, -102, 32,110,111,116, 32,114,101,115, 32,116,104,101,110, 32,114,101,116,117,114, -110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, 32,114, -101,116,117,114,110, 32,115,111, 99,107, 10,101,110,100, 10, 10,102,117,110, 99, -116,105,111,110, 32, 98,105,110,100, 40,104,111,115,116, 44, 32,112,111,114,116, - 44, 32, 98, 97, 99,107,108,111,103, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, - 32,115,111, 99,107, 44, 32,101,114,114, 32, 61, 32,115,111, 99,107,101,116, 46, -116, 99,112, 40, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,115,111, 99, -107, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101, -114,114, 32,101,110,100, 10, 32, 32, 32, 32,115,111, 99,107, 58,115,101,116,111, -112,116,105,111,110, 40, 34,114,101,117,115,101, 97,100,100,114, 34, 44, 32,116, -114,117,101, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,115, 44, 32, -101,114,114, 32, 61, 32,115,111, 99,107, 58, 98,105,110,100, 40,104,111,115,116, - 44, 32,112,111,114,116, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114, -101,115, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32, -101,114,114, 32,101,110,100, 10, 32, 32, 32, 32,114,101,115, 44, 32,101,114,114, - 32, 61, 32,115,111, 99,107, 58,108,105,115,116,101,110, 40, 98, 97, 99,107,108, -111,103, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,101,115, 32,116, -104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 32, -101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,111, 99,107, 10, -101,110,100, 10, 10,116,114,121, 32, 61, 32,110,101,119,116,114,121, 40, 41, 10, - 10,102,117,110, 99,116,105,111,110, 32, 99,104,111,111,115,101, 40,116, 97, 98, -108,101, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116, -105,111,110, 40,110, 97,109,101, 44, 32,111,112,116, 49, 44, 32,111,112,116, 50, - 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46,116,121, -112,101, 40,110, 97,109,101, 41, 32,126, 61, 32, 34,115,116,114,105,110,103, 34, - 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,110, 97, -109,101, 44, 32,111,112,116, 49, 44, 32,111,112,116, 50, 32, 61, 32, 34,100,101, -102, 97,117,108,116, 34, 44, 32,110, 97,109,101, 44, 32,111,112,116, 49, 10, 32, - 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,108, -111, 99, 97,108, 32,102, 32, 61, 32,116, 97, 98,108,101, 91,110, 97,109,101, 32, -111,114, 32, 34,110,105,108, 34, 93, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, - 32,110,111,116, 32,102, 32,116,104,101,110, 32, 98, 97,115,101, 46,101,114,114, -111,114, 40, 34,117,110,107,110,111,119,110, 32,107,101,121, 32, 40, 34, 46, 46, - 32, 98, 97,115,101, 46,116,111,115,116,114,105,110,103, 40,110, 97,109,101, 41, - 32, 46, 46, 34, 41, 34, 44, 32, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101, -108,115,101, 32,114,101,116,117,114,110, 32,102, 40,111,112,116, 49, 44, 32,111, -112,116, 50, 41, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, - 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, - 45, 45, 32, 83,111, 99,107,101,116, 32,115,111,117,114, 99,101,115, 32, 97,110, -100, 32,115,105,110,107,115, 44, 32, 99,111,110,102,111,114,109,105,110,103, 32, -116,111, 32, 76, 84, 78, 49, 50, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 32, 32, 32, 32, 32, 32,115,111, 99,107, 58,115,101,116,111,112,116,105,111,110, + 40, 34,114,101,117,115,101, 97,100,100,114, 34, 44, 32,116,114,117,101, 41, 10, + 32, 32, 32, 32, 32, 32, 32, 32,114,101,115, 44, 32,101,114,114, 32, 61, 32,115, +111, 99,107, 58, 98,105,110,100, 40, 97,108,116, 46, 97,100,100,114, 44, 32,112, +111,114,116, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32, +114,101,115, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32,115,111, 99,107, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, + 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114, +101,115, 44, 32,101,114,114, 32, 61, 32,115,111, 99,107, 58,108,105,115,116,101, +110, 40, 98, 97, 99,107,108,111,103, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,105,102, 32,110,111,116, 32,114,101,115, 32,116,104,101,110, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,111, 99,107, 58, + 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32,114,101,116,117,114,110, 32,115,111, 99,107, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, + 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, +110,105,108, 44, 32,101,114,114, 10,101,110,100, 10, 10, 95, 77, 46,116,114,121, + 32, 61, 32, 95, 77, 46,110,101,119,116,114,121, 40, 41, 10, 10,102,117,110, 99, +116,105,111,110, 32, 95, 77, 46, 99,104,111,111,115,101, 40,116, 97, 98,108,101, + 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111, +110, 40,110, 97,109,101, 44, 32,111,112,116, 49, 44, 32,111,112,116, 50, 41, 10, + 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46,116,121,112,101, + 40,110, 97,109,101, 41, 32,126, 61, 32, 34,115,116,114,105,110,103, 34, 32,116, +104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,110, 97,109,101, + 44, 32,111,112,116, 49, 44, 32,111,112,116, 50, 32, 61, 32, 34,100,101,102, 97, +117,108,116, 34, 44, 32,110, 97,109,101, 44, 32,111,112,116, 49, 10, 32, 32, 32, + 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, + 97,108, 32,102, 32, 61, 32,116, 97, 98,108,101, 91,110, 97,109,101, 32,111,114, + 32, 34,110,105,108, 34, 93, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110, +111,116, 32,102, 32,116,104,101,110, 32, 98, 97,115,101, 46,101,114,114,111,114, + 40, 34,117,110,107,110,111,119,110, 32,107,101,121, 32, 40, 34, 46, 46, 32, 98, + 97,115,101, 46,116,111,115,116,114,105,110,103, 40,110, 97,109,101, 41, 32, 46, + 46, 34, 41, 34, 44, 32, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115, +101, 32,114,101,116,117,114,110, 32,102, 40,111,112,116, 49, 44, 32,111,112,116, + 50, 41, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 99,114,101, 97,116,101, 32,110, 97,109, -101,115,112, 97, 99,101,115, 32,105,110,115,105,100,101, 32, 76,117, 97, 83,111, - 99,107,101,116, 32,110, 97,109,101,115,112, 97, 99,101, 10,115,111,117,114, 99, -101,116, 32, 61, 32,123,125, 10,115,105,110,107,116, 32, 61, 32,123,125, 10, 10, - 66, 76, 79, 67, 75, 83, 73, 90, 69, 32, 61, 32, 50, 48, 52, 56, 10, 10,115,105, -110,107,116, 91, 34, 99,108,111,115,101, 45,119,104,101,110, 45,100,111,110,101, - 34, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40,115,111, 99,107, 41, 10, - 32, 32, 32, 32,114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109, -101,116, 97,116, 97, 98,108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103, -101,116,102,100, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101, -116,117,114,110, 32,115,111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101,110, -100, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32,102, -117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99, -107, 58,100,105,114,116,121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, 44, - 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, 32, -102,117,110, 99,116,105,111,110, 40,115,101,108,102, 44, 32, 99,104,117,110,107, - 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105, -102, 32,110,111,116, 32, 99,104,117,110,107, 32,116,104,101,110, 10, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,111, 99,107, 58, 99,108, -111,115,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32,114,101,116,117,114,110, 32, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58, -115,101,110,100, 40, 99,104,117,110,107, 41, 32,101,110,100, 10, 32, 32, 32, 32, - 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,125, 41, 10,101,110,100, 10, 10, -115,105,110,107,116, 91, 34,107,101,101,112, 45,111,112,101,110, 34, 93, 32, 61, - 32,102,117,110, 99,116,105,111,110, 40,115,111, 99,107, 41, 10, 32, 32, 32, 32, -114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97,116, - 97, 98,108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103,101,116,102,100, - 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,110, - 32,115,111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101,110,100, 44, 10, 32, - 32, 32, 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32,102,117,110, 99,116, -105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58,100,105, -114,116,121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, 44, 32,123, 10, 32, - 32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, 32,102,117,110, 99, -116,105,111,110, 40,115,101,108,102, 44, 32, 99,104,117,110,107, 44, 32,101,114, -114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104, -117,110,107, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,115,111, 99,107, - 58,115,101,110,100, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32, 49, 32,101, -110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,125, - 41, 10,101,110,100, 10, 10,115,105,110,107,116, 91, 34,100,101,102, 97,117,108, -116, 34, 93, 32, 61, 32,115,105,110,107,116, 91, 34,107,101,101,112, 45,111,112, -101,110, 34, 93, 10, 10,115,105,110,107, 32, 61, 32, 99,104,111,111,115,101, 40, -115,105,110,107,116, 41, 10, 10,115,111,117,114, 99,101,116, 91, 34, 98,121, 45, -108,101,110,103,116,104, 34, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, -115,111, 99,107, 44, 32,108,101,110,103,116,104, 41, 10, 32, 32, 32, 32,114,101, -116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97,116, 97, 98, -108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103,101,116,102,100, 32, 61, - 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115, -111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101,110,100, 44, 10, 32, 32, 32, - 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32,102,117,110, 99,116,105,111, -110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58,100,105,114,116, -121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, 44, 32,123, 10, 32, 32, 32, - 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, 32,102,117,110, 99,116,105, -111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, -108,101,110,103,116,104, 32, 60, 61, 32, 48, 32,116,104,101,110, 32,114,101,116, -117,114,110, 32,110,105,108, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32,108,111, 99, 97,108, 32,115,105,122,101, 32, 61, 32,109, 97,116, -104, 46,109,105,110, 40,115,111, 99,107,101,116, 46, 66, 76, 79, 67, 75, 83, 73, - 90, 69, 44, 32,108,101,110,103,116,104, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104,117,110,107, 44, 32,101,114,114, - 32, 61, 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40,115,105,122,101, - 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114, - 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114, -114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,101, -110,103,116,104, 32, 61, 32,108,101,110,103,116,104, 32, 45, 32,115,116,114,105, -110,103, 46,108,101,110, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 99,104,117,110,107, 10, 32, - 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,125, 41, 10,101,110, -100, 10, 10,115,111,117,114, 99,101,116, 91, 34,117,110,116,105,108, 45, 99,108, -111,115,101,100, 34, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40,115,111, - 99,107, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,100,111,110,101, 10, 32, - 32, 32, 32,114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,101, -116, 97,116, 97, 98,108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103,101, -116,102,100, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116, -117,114,110, 32,115,111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101,110,100, - 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32,102,117, -110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99,107, - 58,100,105,114,116,121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, 44, 32, -123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, 32,102, -117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32,105,102, 32,100,111,110,101, 32,116,104,101,110, 32,114,101,116,117,114, -110, 32,110,105,108, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32,108,111, 99, 97,108, 32, 99,104,117,110,107, 44, 32,101,114,114, 44, 32, -112, 97,114,116,105, 97,108, 32, 61, 32,115,111, 99,107, 58,114,101, 99,101,105, -118,101, 40,115,111, 99,107,101,116, 46, 66, 76, 79, 67, 75, 83, 73, 90, 69, 41, - 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32, -101,114,114, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 99,104,117,110, -107, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101,105,102, - 32,101,114,114, 32, 61, 61, 32, 34, 99,108,111,115,101,100, 34, 32,116,104,101, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, + 32, 83,111, 99,107,101,116, 32,115,111,117,114, 99,101,115, 32, 97,110,100, 32, +115,105,110,107,115, 44, 32, 99,111,110,102,111,114,109,105,110,103, 32,116,111, + 32, 76, 84, 78, 49, 50, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 10, 45, 45, 32, 99,114,101, 97,116,101, 32,110, 97,109,101,115, +112, 97, 99,101,115, 32,105,110,115,105,100,101, 32, 76,117, 97, 83,111, 99,107, +101,116, 32,110, 97,109,101,115,112, 97, 99,101, 10,108,111, 99, 97,108, 32,115, +111,117,114, 99,101,116, 44, 32,115,105,110,107,116, 32, 61, 32,123,125, 44, 32, +123,125, 10, 95, 77, 46,115,111,117,114, 99,101,116, 32, 61, 32,115,111,117,114, + 99,101,116, 10, 95, 77, 46,115,105,110,107,116, 32, 61, 32,115,105,110,107,116, + 10, 10, 95, 77, 46, 66, 76, 79, 67, 75, 83, 73, 90, 69, 32, 61, 32, 50, 48, 52, + 56, 10, 10,115,105,110,107,116, 91, 34, 99,108,111,115,101, 45,119,104,101,110, + 45,100,111,110,101, 34, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40,115, +111, 99,107, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 98, 97,115,101, + 46,115,101,116,109,101,116, 97,116, 97, 98,108,101, 40,123, 10, 32, 32, 32, 32, + 32, 32, 32, 32,103,101,116,102,100, 32, 61, 32,102,117,110, 99,116,105,111,110, + 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58,103,101,116,102,100, + 40, 41, 32,101,110,100, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,100,105,114,116, +121, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114, +110, 32,115,111, 99,107, 58,100,105,114,116,121, 40, 41, 32,101,110,100, 10, 32, + 32, 32, 32,125, 44, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97, +108,108, 32, 61, 32,102,117,110, 99,116,105,111,110, 40,115,101,108,102, 44, 32, + 99,104,117,110,107, 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,105,102, 32,110,111,116, 32, 99,104,117,110,107, 32,116,104,101, 110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,111, 99,107, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32,100,111,110,101, 32, 61, 32, 49, 10, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,112, - 97,114,116,105, 97,108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101, -108,115,101, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 32, -101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, -125, 41, 10,101,110,100, 10, 10, 10,115,111,117,114, 99,101,116, 91, 34,100,101, -102, 97,117,108,116, 34, 93, 32, 61, 32,115,111,117,114, 99,101,116, 91, 34,117, -110,116,105,108, 45, 99,108,111,115,101,100, 34, 93, 10, 10,115,111,117,114, 99, -101, 32, 61, 32, 99,104,111,111,115,101, 40,115,111,117,114, 99,101,116, 41, 10, - 10, + 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32, +115,111, 99,107, 58,115,101,110,100, 40, 99,104,117,110,107, 41, 32,101,110,100, + 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,125, 41, 10, +101,110,100, 10, 10,115,105,110,107,116, 91, 34,107,101,101,112, 45,111,112,101, +110, 34, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40,115,111, 99,107, 41, + 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116, +109,101,116, 97,116, 97, 98,108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, +103,101,116,102,100, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114, +101,116,117,114,110, 32,115,111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101, +110,100, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32, +102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, + 99,107, 58,100,105,114,116,121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, + 44, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, + 32,102,117,110, 99,116,105,111,110, 40,115,101,108,102, 44, 32, 99,104,117,110, +107, 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +105,102, 32, 99,104,117,110,107, 32,116,104,101,110, 32,114,101,116,117,114,110, + 32,115,111, 99,107, 58,115,101,110,100, 40, 99,104,117,110,107, 41, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114, +110, 32, 49, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, + 32, 32, 32, 32,125, 41, 10,101,110,100, 10, 10,115,105,110,107,116, 91, 34,100, +101,102, 97,117,108,116, 34, 93, 32, 61, 32,115,105,110,107,116, 91, 34,107,101, +101,112, 45,111,112,101,110, 34, 93, 10, 10, 95, 77, 46,115,105,110,107, 32, 61, + 32, 95, 77, 46, 99,104,111,111,115,101, 40,115,105,110,107,116, 41, 10, 10,115, +111,117,114, 99,101,116, 91, 34, 98,121, 45,108,101,110,103,116,104, 34, 93, 32, + 61, 32,102,117,110, 99,116,105,111,110, 40,115,111, 99,107, 44, 32,108,101,110, +103,116,104, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 98, 97,115,101, + 46,115,101,116,109,101,116, 97,116, 97, 98,108,101, 40,123, 10, 32, 32, 32, 32, + 32, 32, 32, 32,103,101,116,102,100, 32, 61, 32,102,117,110, 99,116,105,111,110, + 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58,103,101,116,102,100, + 40, 41, 32,101,110,100, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,100,105,114,116, +121, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114, +110, 32,115,111, 99,107, 58,100,105,114,116,121, 40, 41, 32,101,110,100, 10, 32, + 32, 32, 32,125, 44, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97, +108,108, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,108,101,110,103,116,104, 32, 60, 61, + 32, 48, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 32,101, +110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, + 32,115,105,122,101, 32, 61, 32,109, 97,116,104, 46,109,105,110, 40,115,111, 99, +107,101,116, 46, 66, 76, 79, 67, 75, 83, 73, 90, 69, 44, 32,108,101,110,103,116, +104, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, + 32, 99,104,117,110,107, 44, 32,101,114,114, 32, 61, 32,115,111, 99,107, 58,114, +101, 99,101,105,118,101, 40,115,105,122,101, 41, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104,101,110, 32,114,101,116, +117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32,108,101,110,103,116,104, 32, 61, 32,108,101, +110,103,116,104, 32, 45, 32,115,116,114,105,110,103, 46,108,101,110, 40, 99,104, +117,110,107, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116, +117,114,110, 32, 99,104,117,110,107, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110, +100, 10, 32, 32, 32, 32,125, 41, 10,101,110,100, 10, 10,115,111,117,114, 99,101, +116, 91, 34,117,110,116,105,108, 45, 99,108,111,115,101,100, 34, 93, 32, 61, 32, +102,117,110, 99,116,105,111,110, 40,115,111, 99,107, 41, 10, 32, 32, 32, 32,108, +111, 99, 97,108, 32,100,111,110,101, 10, 32, 32, 32, 32,114,101,116,117,114,110, + 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97,116, 97, 98,108,101, 40,123, + 10, 32, 32, 32, 32, 32, 32, 32, 32,103,101,116,102,100, 32, 61, 32,102,117,110, + 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58, +103,101,116,102,100, 40, 41, 32,101,110,100, 44, 10, 32, 32, 32, 32, 32, 32, 32, + 32,100,105,114,116,121, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32, +114,101,116,117,114,110, 32,115,111, 99,107, 58,100,105,114,116,121, 40, 41, 32, +101,110,100, 10, 32, 32, 32, 32,125, 44, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 95, 95, 99, 97,108,108, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,100,111,110,101, + 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 32,101,110,100, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99, +104,117,110,107, 44, 32,101,114,114, 44, 32,112, 97,114,116,105, 97,108, 32, 61, + 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40,115,111, 99,107,101,116, + 46, 66, 76, 79, 67, 75, 83, 73, 90, 69, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,105,102, 32,110,111,116, 32,101,114,114, 32,116,104,101,110, 32, +114,101,116,117,114,110, 32, 99,104,117,110,107, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,101,108,115,101,105,102, 32,101,114,114, 32, 61, 61, 32, 34, + 99,108,111,115,101,100, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32,115,111, 99,107, 58, 99,108,111,115,101, 40, + 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,100,111, +110,101, 32, 61, 32, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,114,101,116,117,114,110, 32,112, 97,114,116,105, 97,108, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114, +110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, 32, 32, + 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,125, 41, 10,101,110,100, 10, 10, 10, +115,111,117,114, 99,101,116, 91, 34,100,101,102, 97,117,108,116, 34, 93, 32, 61, + 32,115,111,117,114, 99,101,116, 91, 34,117,110,116,105,108, 45, 99,108,111,115, +101,100, 34, 93, 10, 10, 95, 77, 46,115,111,117,114, 99,101, 32, 61, 32, 95, 77, + 46, 99,104,111,111,115,101, 40,115,111,117,114, 99,101,116, 41, 10, 10,114,101, +116,117,114,110, 32, 95, 77, 10, }; - if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"socket.lua")==0) lua_call(L, 0, 0); + if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"socket.lua")==0) lua_call(L, 0, LUA_MULTRET); } diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/tcp.c b/love/src/jni/love/src/libraries/luasocket/libluasocket/tcp.c index 7e26b080..ef9ee6f9 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/tcp.c +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/tcp.c @@ -1,13 +1,12 @@ /*=========================================================================*\ -* TCP object +* TCP object * LuaSocket toolkit -* -* RCS ID: $Id: tcp.c,v 1.41 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ -#include +#include #include "lua.h" #include "lauxlib.h" +#include "compat.h" #include "auxiliar.h" #include "socket.h" @@ -15,14 +14,16 @@ #include "options.h" #include "tcp.h" -extern void luax_register(lua_State *L, const char *name, const luaL_Reg *l); - /*=========================================================================*\ * Internal function prototypes \*=========================================================================*/ static int global_create(lua_State *L); +static int global_create4(lua_State *L); +static int global_create6(lua_State *L); +static int global_connect(lua_State *L); static int meth_connect(lua_State *L); static int meth_listen(lua_State *L); +static int meth_getfamily(lua_State *L); static int meth_bind(lua_State *L); static int meth_send(lua_State *L); static int meth_getstats(lua_State *L); @@ -33,14 +34,16 @@ static int meth_shutdown(lua_State *L); static int meth_receive(lua_State *L); static int meth_accept(lua_State *L); static int meth_close(lua_State *L); +static int meth_getoption(lua_State *L); static int meth_setoption(lua_State *L); +static int meth_gettimeout(lua_State *L); static int meth_settimeout(lua_State *L); static int meth_getfd(lua_State *L); static int meth_setfd(lua_State *L); static int meth_dirty(lua_State *L); /* tcp object methods */ -static luaL_reg tcp[] = { +static luaL_Reg tcp_methods[] = { {"__gc", meth_close}, {"__tostring", auxiliar_tostring}, {"accept", meth_accept}, @@ -48,7 +51,9 @@ static luaL_reg tcp[] = { {"close", meth_close}, {"connect", meth_connect}, {"dirty", meth_dirty}, + {"getfamily", meth_getfamily}, {"getfd", meth_getfd}, + {"getoption", meth_getoption}, {"getpeername", meth_getpeername}, {"getsockname", meth_getsockname}, {"getstats", meth_getstats}, @@ -61,22 +66,38 @@ static luaL_reg tcp[] = { {"setpeername", meth_connect}, {"setsockname", meth_bind}, {"settimeout", meth_settimeout}, + {"gettimeout", meth_gettimeout}, {"shutdown", meth_shutdown}, {NULL, NULL} }; /* socket option handlers */ -static t_opt opt[] = { - {"keepalive", opt_keepalive}, - {"reuseaddr", opt_reuseaddr}, - {"tcp-nodelay", opt_tcp_nodelay}, - {"linger", opt_linger}, +static t_opt optget[] = { + {"keepalive", opt_get_keepalive}, + {"reuseaddr", opt_get_reuseaddr}, + {"reuseport", opt_get_reuseport}, + {"tcp-nodelay", opt_get_tcp_nodelay}, + {"linger", opt_get_linger}, + {"error", opt_get_error}, + {NULL, NULL} +}; + +static t_opt optset[] = { + {"keepalive", opt_set_keepalive}, + {"reuseaddr", opt_set_reuseaddr}, + {"reuseport", opt_set_reuseport}, + {"tcp-nodelay", opt_set_tcp_nodelay}, + {"ipv6-v6only", opt_set_ip6_v6only}, + {"linger", opt_set_linger}, {NULL, NULL} }; /* functions in library namespace */ -static luaL_reg func[] = { +static luaL_Reg func[] = { {"tcp", global_create}, + {"tcp4", global_create4}, + {"tcp6", global_create6}, + {"connect", global_connect}, {NULL, NULL} }; @@ -86,15 +107,15 @@ static luaL_reg func[] = { int tcp_open(lua_State *L) { /* create classes */ - auxiliar_newclass(L, "tcp{master}", tcp); - auxiliar_newclass(L, "tcp{client}", tcp); - auxiliar_newclass(L, "tcp{server}", tcp); + auxiliar_newclass(L, "tcp{master}", tcp_methods); + auxiliar_newclass(L, "tcp{client}", tcp_methods); + auxiliar_newclass(L, "tcp{server}", tcp_methods); /* create class groups */ auxiliar_add2group(L, "tcp{master}", "tcp{any}"); auxiliar_add2group(L, "tcp{client}", "tcp{any}"); auxiliar_add2group(L, "tcp{server}", "tcp{any}"); /* define library functions */ - luax_register(L, NULL, func); + luaL_setfuncs(L, func, 0); return 0; } @@ -127,10 +148,16 @@ static int meth_setstats(lua_State *L) { /*-------------------------------------------------------------------------*\ * Just call option handler \*-------------------------------------------------------------------------*/ +static int meth_getoption(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); + return opt_meth_getoption(L, optget, &tcp->sock); +} + static int meth_setoption(lua_State *L) { p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); - return opt_meth_setoption(L, opt, &tcp->sock); + return opt_meth_setoption(L, optset, &tcp->sock); } /*-------------------------------------------------------------------------*\ @@ -147,7 +174,7 @@ static int meth_getfd(lua_State *L) static int meth_setfd(lua_State *L) { p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); - tcp->sock = (t_socket) luaL_checknumber(L, 2); + tcp->sock = (t_socket) luaL_checknumber(L, 2); return 0; } @@ -159,43 +186,50 @@ static int meth_dirty(lua_State *L) } /*-------------------------------------------------------------------------*\ -* Waits for and returns a client object attempting connection to the -* server object +* Waits for and returns a client object attempting connection to the +* server object \*-------------------------------------------------------------------------*/ static int meth_accept(lua_State *L) { p_tcp server = (p_tcp) auxiliar_checkclass(L, "tcp{server}", 1); p_timeout tm = timeout_markstart(&server->tm); t_socket sock; - int err = socket_accept(&server->sock, &sock, NULL, NULL, tm); + const char *err = inet_tryaccept(&server->sock, server->family, &sock, tm); /* if successful, push client socket */ - if (err == IO_DONE) { + if (err == NULL) { p_tcp clnt = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); auxiliar_setclass(L, "tcp{client}", -1); /* initialize structure fields */ + memset(clnt, 0, sizeof(t_tcp)); socket_setnonblocking(&sock); clnt->sock = sock; - io_init(&clnt->io, (p_send) socket_send, (p_recv) socket_recv, + io_init(&clnt->io, (p_send) socket_send, (p_recv) socket_recv, (p_error) socket_ioerror, &clnt->sock); timeout_init(&clnt->tm, -1, -1); buffer_init(&clnt->buf, &clnt->io, &clnt->tm); + clnt->family = server->family; return 1; } else { - lua_pushnil(L); - lua_pushstring(L, socket_strerror(err)); + lua_pushnil(L); + lua_pushstring(L, err); return 2; } } /*-------------------------------------------------------------------------*\ -* Binds an object to an address +* Binds an object to an address \*-------------------------------------------------------------------------*/ -static int meth_bind(lua_State *L) -{ +static int meth_bind(lua_State *L) { p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{master}", 1); const char *address = luaL_checkstring(L, 2); - unsigned short port = (unsigned short) luaL_checknumber(L, 3); - const char *err = inet_trybind(&tcp->sock, address, port); + const char *port = luaL_checkstring(L, 3); + const char *err; + struct addrinfo bindhints; + memset(&bindhints, 0, sizeof(bindhints)); + bindhints.ai_socktype = SOCK_STREAM; + bindhints.ai_family = tcp->family; + bindhints.ai_flags = AI_PASSIVE; + err = inet_trybind(&tcp->sock, &tcp->family, address, port, &bindhints); if (err) { lua_pushnil(L); lua_pushstring(L, err); @@ -208,13 +242,19 @@ static int meth_bind(lua_State *L) /*-------------------------------------------------------------------------*\ * Turns a master tcp object into a client object. \*-------------------------------------------------------------------------*/ -static int meth_connect(lua_State *L) -{ +static int meth_connect(lua_State *L) { p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); const char *address = luaL_checkstring(L, 2); - unsigned short port = (unsigned short) luaL_checknumber(L, 3); - p_timeout tm = timeout_markstart(&tcp->tm); - const char *err = inet_tryconnect(&tcp->sock, address, port, tm); + const char *port = luaL_checkstring(L, 3); + struct addrinfo connecthints; + const char *err; + memset(&connecthints, 0, sizeof(connecthints)); + connecthints.ai_socktype = SOCK_STREAM; + /* make sure we try to connect only to the same family */ + connecthints.ai_family = tcp->family; + timeout_markstart(&tcp->tm); + err = inet_tryconnect(&tcp->sock, &tcp->family, address, port, + &tcp->tm, &connecthints); /* have to set the class even if it failed due to non-blocking connects */ auxiliar_setclass(L, "tcp{client}", 1); if (err) { @@ -222,13 +262,12 @@ static int meth_connect(lua_State *L) lua_pushstring(L, err); return 2; } - /* turn master object into a client object */ lua_pushnumber(L, 1); return 1; } /*-------------------------------------------------------------------------*\ -* Closes socket used by object +* Closes socket used by object \*-------------------------------------------------------------------------*/ static int meth_close(lua_State *L) { @@ -238,6 +277,24 @@ static int meth_close(lua_State *L) return 1; } +/*-------------------------------------------------------------------------*\ +* Returns family as string +\*-------------------------------------------------------------------------*/ +static int meth_getfamily(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); + if (tcp->family == AF_INET6) { + lua_pushliteral(L, "inet6"); + return 1; + } else if (tcp->family == AF_INET) { + lua_pushliteral(L, "inet4"); + return 1; + } else { + lua_pushliteral(L, "inet4"); + return 1; + } +} + /*-------------------------------------------------------------------------*\ * Puts the sockt in listen mode \*-------------------------------------------------------------------------*/ @@ -262,27 +319,13 @@ static int meth_listen(lua_State *L) \*-------------------------------------------------------------------------*/ static int meth_shutdown(lua_State *L) { + /* SHUT_RD, SHUT_WR, SHUT_RDWR have the value 0, 1, 2, so we can use method index directly */ + static const char* methods[] = { "receive", "send", "both", NULL }; p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1); - const char *how = luaL_optstring(L, 2, "both"); - switch (how[0]) { - case 'b': - if (strcmp(how, "both")) goto error; - socket_shutdown(&tcp->sock, 2); - break; - case 's': - if (strcmp(how, "send")) goto error; - socket_shutdown(&tcp->sock, 1); - break; - case 'r': - if (strcmp(how, "receive")) goto error; - socket_shutdown(&tcp->sock, 0); - break; - } + int how = luaL_checkoption(L, 2, "both", methods); + socket_shutdown(&tcp->sock, how); lua_pushnumber(L, 1); return 1; -error: - luaL_argerror(L, 2, "invalid shutdown method"); - return 0; } /*-------------------------------------------------------------------------*\ @@ -291,13 +334,13 @@ error: static int meth_getpeername(lua_State *L) { p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); - return inet_meth_getpeername(L, &tcp->sock); + return inet_meth_getpeername(L, &tcp->sock, tcp->family); } static int meth_getsockname(lua_State *L) { p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); - return inet_meth_getsockname(L, &tcp->sock); + return inet_meth_getsockname(L, &tcp->sock, tcp->family); } /*-------------------------------------------------------------------------*\ @@ -309,33 +352,100 @@ static int meth_settimeout(lua_State *L) return timeout_meth_settimeout(L, &tcp->tm); } +static int meth_gettimeout(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); + return timeout_meth_gettimeout(L, &tcp->tm); +} + /*=========================================================================*\ * Library functions \*=========================================================================*/ /*-------------------------------------------------------------------------*\ -* Creates a master tcp object +* Creates a master tcp object \*-------------------------------------------------------------------------*/ -static int global_create(lua_State *L) -{ - t_socket sock; - const char *err = inet_trycreate(&sock, SOCK_STREAM); - /* try to allocate a system socket */ - if (!err) { - /* allocate tcp object */ - p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); - /* set its type as master object */ - auxiliar_setclass(L, "tcp{master}", -1); - /* initialize remaining structure fields */ - socket_setnonblocking(&sock); - tcp->sock = sock; - io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv, - (p_error) socket_ioerror, &tcp->sock); - timeout_init(&tcp->tm, -1, -1); - buffer_init(&tcp->buf, &tcp->io, &tcp->tm); - return 1; - } else { +static int tcp_create(lua_State *L, int family) { + p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); + memset(tcp, 0, sizeof(t_tcp)); + /* set its type as master object */ + auxiliar_setclass(L, "tcp{master}", -1); + /* if family is AF_UNSPEC, we leave the socket invalid and + * store AF_UNSPEC into family. This will allow it to later be + * replaced with an AF_INET6 or AF_INET socket upon first use. */ + tcp->sock = SOCKET_INVALID; + tcp->family = family; + io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv, + (p_error) socket_ioerror, &tcp->sock); + timeout_init(&tcp->tm, -1, -1); + buffer_init(&tcp->buf, &tcp->io, &tcp->tm); + if (family != AF_UNSPEC) { + const char *err = inet_trycreate(&tcp->sock, family, SOCK_STREAM, 0); + if (err != NULL) { + lua_pushnil(L); + lua_pushstring(L, err); + return 2; + } + socket_setnonblocking(&tcp->sock); + } + return 1; +} + +static int global_create(lua_State *L) { + return tcp_create(L, AF_UNSPEC); +} + +static int global_create4(lua_State *L) { + return tcp_create(L, AF_INET); +} + +static int global_create6(lua_State *L) { + return tcp_create(L, AF_INET6); +} + +static int global_connect(lua_State *L) { + const char *remoteaddr = luaL_checkstring(L, 1); + const char *remoteserv = luaL_checkstring(L, 2); + const char *localaddr = luaL_optstring(L, 3, NULL); + const char *localserv = luaL_optstring(L, 4, "0"); + int family = inet_optfamily(L, 5, "unspec"); + p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); + struct addrinfo bindhints, connecthints; + const char *err = NULL; + /* initialize tcp structure */ + memset(tcp, 0, sizeof(t_tcp)); + io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv, + (p_error) socket_ioerror, &tcp->sock); + timeout_init(&tcp->tm, -1, -1); + buffer_init(&tcp->buf, &tcp->io, &tcp->tm); + tcp->sock = SOCKET_INVALID; + tcp->family = AF_UNSPEC; + /* allow user to pick local address and port */ + memset(&bindhints, 0, sizeof(bindhints)); + bindhints.ai_socktype = SOCK_STREAM; + bindhints.ai_family = family; + bindhints.ai_flags = AI_PASSIVE; + if (localaddr) { + err = inet_trybind(&tcp->sock, &tcp->family, localaddr, + localserv, &bindhints); + if (err) { + lua_pushnil(L); + lua_pushstring(L, err); + return 2; + } + } + /* try to connect to remote address and port */ + memset(&connecthints, 0, sizeof(connecthints)); + connecthints.ai_socktype = SOCK_STREAM; + /* make sure we try to connect only to the same family */ + connecthints.ai_family = tcp->family; + err = inet_tryconnect(&tcp->sock, &tcp->family, remoteaddr, remoteserv, + &tcp->tm, &connecthints); + if (err) { + socket_destroy(&tcp->sock); lua_pushnil(L); lua_pushstring(L, err); return 2; } + auxiliar_setclass(L, "tcp{client}", -1); + return 1; } diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/tcp.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/tcp.h index 511357f3..eded6203 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/tcp.h +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/tcp.h @@ -13,8 +13,6 @@ * objects are tcp objects bound to some local address. Client objects are * tcp objects either connected to some address or returned by the accept * method of a server object. -* -* RCS ID: $Id: tcp.h,v 1.7 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ #include "lua.h" @@ -27,6 +25,7 @@ typedef struct t_tcp_ { t_io io; t_buffer buf; t_timeout tm; + int family; } t_tcp; typedef t_tcp *p_tcp; diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/timeout.c b/love/src/jni/love/src/libraries/luasocket/libluasocket/timeout.c index 8db087f4..5a601d54 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/timeout.c +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/timeout.c @@ -1,13 +1,14 @@ /*=========================================================================*\ * Timeout management functions * LuaSocket toolkit -* -* RCS ID: $Id: timeout.c,v 1.30 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ #include +#include +#include #include "lua.h" #include "lauxlib.h" +#include "compat.h" #include "auxiliar.h" #include "timeout.h" @@ -27,15 +28,13 @@ #define MAX(x, y) ((x) > (y) ? x : y) #endif -extern void luax_register(lua_State *L, const char *name, const luaL_Reg *l); - /*=========================================================================*\ * Internal function prototypes \*=========================================================================*/ static int timeout_lua_gettime(lua_State *L); static int timeout_lua_sleep(lua_State *L); -static luaL_reg func[] = { +static luaL_Reg func[] = { { "gettime", timeout_lua_gettime }, { "sleep", timeout_lua_sleep }, { NULL, NULL } @@ -54,7 +53,7 @@ void timeout_init(p_timeout tm, double block, double total) { /*-------------------------------------------------------------------------*\ * Determines how much time we have left for the next system call, -* if the previous call was successful +* if the previous call was successful * Input * tm: timeout control structure * Returns @@ -109,7 +108,7 @@ double timeout_getretry(p_timeout tm) { } /*-------------------------------------------------------------------------*\ -* Marks the operation start time in structure +* Marks the operation start time in structure * Input * tm: timeout control structure \*-------------------------------------------------------------------------*/ @@ -119,7 +118,7 @@ p_timeout timeout_markstart(p_timeout tm) { } /*-------------------------------------------------------------------------*\ -* Gets time in s, relative to January 1, 1970 (UTC) +* Gets time in s, relative to January 1, 1970 (UTC) * Returns * time in s. \*-------------------------------------------------------------------------*/ @@ -146,7 +145,7 @@ double timeout_gettime(void) { * Initializes module \*-------------------------------------------------------------------------*/ int timeout_open(lua_State *L) { - luax_register(L, NULL, func); + luaL_setfuncs(L, func, 0); return 0; } @@ -161,7 +160,7 @@ int timeout_meth_settimeout(lua_State *L, p_timeout tm) { const char *mode = luaL_optstring(L, 3, "b"); switch (*mode) { case 'b': - tm->block = t; + tm->block = t; break; case 'r': case 't': tm->total = t; @@ -174,6 +173,16 @@ int timeout_meth_settimeout(lua_State *L, p_timeout tm) { return 1; } +/*-------------------------------------------------------------------------*\ +* Gets timeout values for IO operations +* Lua Output: block, total +\*-------------------------------------------------------------------------*/ +int timeout_meth_gettimeout(lua_State *L, p_timeout tm) { + lua_pushnumber(L, tm->block); + lua_pushnumber(L, tm->total); + return 2; +} + /*=========================================================================*\ * Test support functions \*=========================================================================*/ @@ -189,13 +198,23 @@ static int timeout_lua_gettime(lua_State *L) /*-------------------------------------------------------------------------*\ * Sleep for n seconds. \*-------------------------------------------------------------------------*/ +#ifdef _WIN32 int timeout_lua_sleep(lua_State *L) { double n = luaL_checknumber(L, 1); -#ifdef _WIN32 - Sleep((int)(n*1000)); + if (n < 0.0) n = 0.0; + if (n < DBL_MAX/1000.0) n *= 1000.0; + if (n > INT_MAX) n = INT_MAX; + Sleep((int)n); + return 0; +} #else +int timeout_lua_sleep(lua_State *L) +{ + double n = luaL_checknumber(L, 1); struct timespec t, r; + if (n < 0.0) n = 0.0; + if (n > INT_MAX) n = INT_MAX; t.tv_sec = (int) n; n -= t.tv_sec; t.tv_nsec = (int) (n * 1000000000); @@ -204,6 +223,6 @@ int timeout_lua_sleep(lua_State *L) t.tv_sec = r.tv_sec; t.tv_nsec = r.tv_nsec; } -#endif return 0; } +#endif diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/timeout.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/timeout.h index d2d89641..af902318 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/timeout.h +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/timeout.h @@ -3,8 +3,6 @@ /*=========================================================================*\ * Timeout management functions * LuaSocket toolkit -* -* RCS ID: $Id: timeout.h,v 1.14 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ #include "lua.h" @@ -24,6 +22,7 @@ p_timeout timeout_markstart(p_timeout tm); double timeout_getstart(p_timeout tm); double timeout_gettime(void); int timeout_meth_settimeout(lua_State *L, p_timeout tm); +int timeout_meth_gettimeout(lua_State *L, p_timeout tm); #define timeout_iszero(tm) ((tm)->block == 0.0) diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/tp.lua b/love/src/jni/love/src/libraries/luasocket/libluasocket/tp.lua index 06838694..b8ebc56d 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/tp.lua +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/tp.lua @@ -2,7 +2,6 @@ -- Unified SMTP/FTP subsystem -- LuaSocket toolkit. -- Author: Diego Nehab --- RCS ID: $Id: tp.lua,v 1.22 2006/03/14 09:04:15 diego Exp $ ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- @@ -12,12 +11,14 @@ local base = _G local string = require("string") local socket = require("socket") local ltn12 = require("ltn12") -module("socket.tp") + +socket.tp = {} +local _M = socket.tp ----------------------------------------------------------------------------- -- Program constants ----------------------------------------------------------------------------- -TIMEOUT = 60 +_M.TIMEOUT = 60 ----------------------------------------------------------------------------- -- Implementation @@ -45,6 +46,14 @@ end -- metatable for sock object local metat = { __index = {} } +function metat.__index:getpeername() + return self.c:getpeername() +end + +function metat.__index:getsockname() + return self.c:getpeername() +end + function metat.__index:check(ok) local code, reply = get_reply(self.c) if not code then return nil, reply end @@ -64,6 +73,7 @@ function metat.__index:check(ok) end function metat.__index:command(cmd, arg) + cmd = string.upper(cmd) if arg then return self.c:send(cmd .. " " .. arg.. "\r\n") else @@ -72,7 +82,7 @@ function metat.__index:command(cmd, arg) end function metat.__index:sink(snk, pat) - local chunk, err = c:receive(pat) + local chunk, err = self.c:receive(pat) return snk(chunk, err) end @@ -105,14 +115,14 @@ end -- closes the underlying c function metat.__index:close() self.c:close() - return 1 + return 1 end -- connect with server and return c object -function connect(host, port, timeout, create) +function _M.connect(host, port, timeout, create) local c, e = (create or socket.tcp)() if not c then return nil, e end - c:settimeout(timeout or TIMEOUT) + c:settimeout(timeout or _M.TIMEOUT) local r, e = c:connect(host, port) if not r then c:close() @@ -121,3 +131,4 @@ function connect(host, port, timeout, create) return base.setmetatable({c = c}, metat) end +return _M diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/tp.lua.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/tp.lua.h index efec651a..cde8b648 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/tp.lua.h +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/tp.lua.h @@ -1,7 +1,7 @@ /* code automatically generated by bin2c -- DO NOT EDIT */ { /* #include'ing this file in a C program is equivalent to calling - if (luaL_loadfile(L,"tp.lua")==0) lua_call(L, 0, 0); + if (luaL_loadfile(L,"tp.lua")==0) lua_call(L, 0, LUA_MULTRET); */ /* tp.lua */ static const unsigned char B1[]={ @@ -12,181 +12,189 @@ static const unsigned char B1[]={ 32, 85,110,105,102,105,101,100, 32, 83, 77, 84, 80, 47, 70, 84, 80, 32,115,117, 98,115,121,115,116,101,109, 10, 45, 45, 32, 76,117, 97, 83,111, 99,107,101,116, 32,116,111,111,108,107,105,116, 46, 10, 45, 45, 32, 65,117,116,104,111,114, 58, - 32, 68,105,101,103,111, 32, 78,101,104, 97, 98, 10, 45, 45, 32, 82, 67, 83, 32, - 73, 68, 58, 32, 36, 73,100, 58, 32,116,112, 46,108,117, 97, 44,118, 32, 49, 46, - 50, 50, 32, 50, 48, 48, 54, 47, 48, 51, 47, 49, 52, 32, 48, 57, 58, 48, 52, 58, - 49, 53, 32,100,105,101,103,111, 32, 69,120,112, 32, 36, 10, 45, 45, 45, 45, 45, + 32, 68,105,101,103,111, 32, 78,101,104, 97, 98, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97, -114,101, 32,109,111,100,117,108,101, 32, 97,110,100, 32,105,109,112,111,114,116, - 32,100,101,112,101,110,100,101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97,114,101, + 32,109,111,100,117,108,101, 32, 97,110,100, 32,105,109,112,111,114,116, 32,100, +101,112,101,110,100,101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32, 98, 97, -115,101, 32, 61, 32, 95, 71, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, - 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, - 10,108,111, 99, 97,108, 32,115,111, 99,107,101,116, 32, 61, 32,114,101,113,117, -105,114,101, 40, 34,115,111, 99,107,101,116, 34, 41, 10,108,111, 99, 97,108, 32, -108,116,110, 49, 50, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,108,116,110, - 49, 50, 34, 41, 10,109,111,100,117,108,101, 40, 34,115,111, 99,107,101,116, 46, -116,112, 34, 41, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32, 98, 97,115,101, + 32, 61, 32, 95, 71, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, 32, 61, + 32,114,101,113,117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10,108, +111, 99, 97,108, 32,115,111, 99,107,101,116, 32, 61, 32,114,101,113,117,105,114, +101, 40, 34,115,111, 99,107,101,116, 34, 41, 10,108,111, 99, 97,108, 32,108,116, +110, 49, 50, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,108,116,110, 49, 50, + 34, 41, 10, 10,115,111, 99,107,101,116, 46,116,112, 32, 61, 32,123,125, 10,108, +111, 99, 97,108, 32, 95, 77, 32, 61, 32,115,111, 99,107,101,116, 46,116,112, 10, + 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, + 45, 32, 80,114,111,103,114, 97,109, 32, 99,111,110,115,116, 97,110,116,115, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 10, 45, 45, 32, 80,114,111,103,114, 97,109, 32, 99,111,110,115,116, - 97,110,116,115, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 95, 77, + 46, 84, 73, 77, 69, 79, 85, 84, 32, 61, 32, 54, 48, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 10, 84, 73, 77, 69, 79, 85, 84, 32, 61, 32, 54, 48, 10, 10, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 73,109,112,108, +101,109,101,110,116, 97,116,105,111,110, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 73,109, -112,108,101,109,101,110,116, 97,116,105,111,110, 10, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32,103,101,116,115, 32,115, -101,114,118,101,114, 32,114,101,112,108,121, 32, 40,119,111,114,107,115, 32,102, -111,114, 32, 83, 77, 84, 80, 32, 97,110,100, 32, 70, 84, 80, 41, 10,108,111, 99, - 97,108, 32,102,117,110, 99,116,105,111,110, 32,103,101,116, 95,114,101,112,108, -121, 40, 99, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,111,100,101, 44, - 32, 99,117,114,114,101,110,116, 44, 32,115,101,112, 10, 32, 32, 32, 32,108,111, - 99, 97,108, 32,108,105,110,101, 44, 32,101,114,114, 32, 61, 32, 99, 58,114,101, - 99,101,105,118,101, 40, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101, -112,108,121, 32, 61, 32,108,105,110,101, 10, 32, 32, 32, 32,105,102, 32,101,114, -114, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101, -114,114, 32,101,110,100, 10, 32, 32, 32, 32, 99,111,100,101, 44, 32,115,101,112, - 32, 61, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 50, 44, 32,115,116, -114,105,110,103, 46,102,105,110,100, 40,108,105,110,101, 44, 32, 34, 94, 40, 37, -100, 37,100, 37,100, 41, 40, 46, 63, 41, 34, 41, 41, 10, 32, 32, 32, 32,105,102, - 32,110,111,116, 32, 99,111,100,101, 32,116,104,101,110, 32,114,101,116,117,114, -110, 32,110,105,108, 44, 32, 34,105,110,118, 97,108,105,100, 32,115,101,114,118, -101,114, 32,114,101,112,108,121, 34, 32,101,110,100, 10, 32, 32, 32, 32,105,102, - 32,115,101,112, 32, 61, 61, 32, 34, 45, 34, 32,116,104,101,110, 32, 45, 45, 32, -114,101,112,108,121, 32,105,115, 32,109,117,108,116,105,108,105,110,101, 10, 32, - 32, 32, 32, 32, 32, 32, 32,114,101,112,101, 97,116, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32,108,105,110,101, 44, 32,101,114,114, 32, 61, 32, 99, 58, -114,101, 99,101,105,118,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32,105,102, 32,101,114,114, 32,116,104,101,110, 32,114,101,116,117,114,110, - 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 99,117,114,114,101,110,116, 44, 32,115,101,112, 32, 61, + 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32,103,101,116,115, 32,115,101,114, +118,101,114, 32,114,101,112,108,121, 32, 40,119,111,114,107,115, 32,102,111,114, + 32, 83, 77, 84, 80, 32, 97,110,100, 32, 70, 84, 80, 41, 10,108,111, 99, 97,108, + 32,102,117,110, 99,116,105,111,110, 32,103,101,116, 95,114,101,112,108,121, 40, + 99, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,111,100,101, 44, 32, 99, +117,114,114,101,110,116, 44, 32,115,101,112, 10, 32, 32, 32, 32,108,111, 99, 97, +108, 32,108,105,110,101, 44, 32,101,114,114, 32, 61, 32, 99, 58,114,101, 99,101, +105,118,101, 40, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,112,108, +121, 32, 61, 32,108,105,110,101, 10, 32, 32, 32, 32,105,102, 32,101,114,114, 32, +116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, + 32,101,110,100, 10, 32, 32, 32, 32, 99,111,100,101, 44, 32,115,101,112, 32, 61, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 50, 44, 32,115,116,114,105, 110,103, 46,102,105,110,100, 40,108,105,110,101, 44, 32, 34, 94, 40, 37,100, 37, -100, 37,100, 41, 40, 46, 63, 41, 34, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32,114,101,112,108,121, 32, 61, 32,114,101,112,108,121, 32, 46, 46, - 32, 34, 92,110, 34, 32, 46, 46, 32,108,105,110,101, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 45, 45, 32,114,101,112,108,121, 32,101,110,100,115, 32,119,105,116,104, - 32,115, 97,109,101, 32, 99,111,100,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,117, -110,116,105,108, 32, 99,111,100,101, 32, 61, 61, 32, 99,117,114,114,101,110,116, - 32, 97,110,100, 32,115,101,112, 32, 61, 61, 32, 34, 32, 34, 10, 32, 32, 32, 32, -101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 99,111,100,101, 44, - 32,114,101,112,108,121, 10,101,110,100, 10, 10, 45, 45, 32,109,101,116, 97,116, - 97, 98,108,101, 32,102,111,114, 32,115,111, 99,107, 32,111, 98,106,101, 99,116, - 10,108,111, 99, 97,108, 32,109,101,116, 97,116, 32, 61, 32,123, 32, 95, 95,105, -110,100,101,120, 32, 61, 32,123,125, 32,125, 10, 10,102,117,110, 99,116,105,111, -110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 99,104,101, 99, -107, 40,111,107, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,111,100,101, - 44, 32,114,101,112,108,121, 32, 61, 32,103,101,116, 95,114,101,112,108,121, 40, -115,101,108,102, 46, 99, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32, 99, -111,100,101, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, - 32,114,101,112,108,121, 32,101,110,100, 10, 32, 32, 32, 32,105,102, 32, 98, 97, -115,101, 46,116,121,112,101, 40,111,107, 41, 32,126, 61, 32, 34,102,117,110, 99, -116,105,111,110, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,105, -102, 32, 98, 97,115,101, 46,116,121,112,101, 40,111,107, 41, 32, 61, 61, 32, 34, -116, 97, 98,108,101, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32,102,111,114, 32,105, 44, 32,118, 32,105,110, 32, 98, 97,115,101, - 46,105,112, 97,105,114,115, 40,111,107, 41, 32,100,111, 10, 32, 32, 32, 32, 32, +100, 37,100, 41, 40, 46, 63, 41, 34, 41, 41, 10, 32, 32, 32, 32,105,102, 32,110, +111,116, 32, 99,111,100,101, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, +110,105,108, 44, 32, 34,105,110,118, 97,108,105,100, 32,115,101,114,118,101,114, + 32,114,101,112,108,121, 34, 32,101,110,100, 10, 32, 32, 32, 32,105,102, 32,115, +101,112, 32, 61, 61, 32, 34, 45, 34, 32,116,104,101,110, 32, 45, 45, 32,114,101, +112,108,121, 32,105,115, 32,109,117,108,116,105,108,105,110,101, 10, 32, 32, 32, + 32, 32, 32, 32, 32,114,101,112,101, 97,116, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,108,105,110,101, 44, 32,101,114,114, 32, 61, 32, 99, 58,114,101, + 99,101,105,118,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +105,102, 32,101,114,114, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110, +105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 99,117,114,114,101,110,116, 44, 32,115,101,112, 32, 61, 32,115, +111, 99,107,101,116, 46,115,107,105,112, 40, 50, 44, 32,115,116,114,105,110,103, + 46,102,105,110,100, 40,108,105,110,101, 44, 32, 34, 94, 40, 37,100, 37,100, 37, +100, 41, 40, 46, 63, 41, 34, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,114,101,112,108,121, 32, 61, 32,114,101,112,108,121, 32, 46, 46, 32, 34, + 92,110, 34, 32, 46, 46, 32,108,105,110,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 45, 45, 32,114,101,112,108,121, 32,101,110,100,115, 32,119,105,116,104, 32,115, + 97,109,101, 32, 99,111,100,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,117,110,116, +105,108, 32, 99,111,100,101, 32, 61, 61, 32, 99,117,114,114,101,110,116, 32, 97, +110,100, 32,115,101,112, 32, 61, 61, 32, 34, 32, 34, 10, 32, 32, 32, 32,101,110, +100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 99,111,100,101, 44, 32,114, +101,112,108,121, 10,101,110,100, 10, 10, 45, 45, 32,109,101,116, 97,116, 97, 98, +108,101, 32,102,111,114, 32,115,111, 99,107, 32,111, 98,106,101, 99,116, 10,108, +111, 99, 97,108, 32,109,101,116, 97,116, 32, 61, 32,123, 32, 95, 95,105,110,100, +101,120, 32, 61, 32,123,125, 32,125, 10, 10,102,117,110, 99,116,105,111,110, 32, +109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,103,101,116,112,101,101, +114,110, 97,109,101, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115, +101,108,102, 46, 99, 58,103,101,116,112,101,101,114,110, 97,109,101, 40, 41, 10, +101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, + 95, 95,105,110,100,101,120, 58,103,101,116,115,111, 99,107,110, 97,109,101, 40, + 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46, 99, 58, +103,101,116,112,101,101,114,110, 97,109,101, 40, 41, 10,101,110,100, 10, 10,102, +117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101, +120, 58, 99,104,101, 99,107, 40,111,107, 41, 10, 32, 32, 32, 32,108,111, 99, 97, +108, 32, 99,111,100,101, 44, 32,114,101,112,108,121, 32, 61, 32,103,101,116, 95, +114,101,112,108,121, 40,115,101,108,102, 46, 99, 41, 10, 32, 32, 32, 32,105,102, + 32,110,111,116, 32, 99,111,100,101, 32,116,104,101,110, 32,114,101,116,117,114, +110, 32,110,105,108, 44, 32,114,101,112,108,121, 32,101,110,100, 10, 32, 32, 32, + 32,105,102, 32, 98, 97,115,101, 46,116,121,112,101, 40,111,107, 41, 32,126, 61, + 32, 34,102,117,110, 99,116,105,111,110, 34, 32,116,104,101,110, 10, 32, 32, 32, + 32, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46,116,121,112,101, 40,111,107, + 41, 32, 61, 61, 32, 34,116, 97, 98,108,101, 34, 32,116,104,101,110, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,102,111,114, 32,105, 44, 32,118, 32,105, +110, 32, 98, 97,115,101, 46,105,112, 97,105,114,115, 40,111,107, 41, 32,100,111, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, +115,116,114,105,110,103, 46,102,105,110,100, 40, 99,111,100,101, 44, 32,118, 41, + 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 98, 97,115,101, 46,116,111, +110,117,109, 98,101,114, 40, 99,111,100,101, 41, 44, 32,114,101,112,108,121, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32, +114,101,112,108,121, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,115,116,114,105,110,103, - 46,102,105,110,100, 40, 99,111,100,101, 44, 32,118, 41, 32,116,104,101,110, 10, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, -114,101,116,117,114,110, 32, 98, 97,115,101, 46,116,111,110,117,109, 98,101,114, - 40, 99,111,100,101, 41, 44, 32,114,101,112,108,121, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,114,101,112,108,121, 10, - 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32,105,102, 32,115,116,114,105,110,103, 46,102,105,110,100, 40, - 99,111,100,101, 44, 32,111,107, 41, 32,116,104,101,110, 32,114,101,116,117,114, -110, 32, 98, 97,115,101, 46,116,111,110,117,109, 98,101,114, 40, 99,111,100,101, - 41, 44, 32,114,101,112,108,121, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32,101,108,115,101, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,114,101, -112,108,121, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, - 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,111,107, 40, 98, - 97,115,101, 46,116,111,110,117,109, 98,101,114, 40, 99,111,100,101, 41, 44, 32, -114,101,112,108,121, 41, 32,101,110,100, 10,101,110,100, 10, 10,102,117,110, 99, -116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 99, -111,109,109, 97,110,100, 40, 99,109,100, 44, 32, 97,114,103, 41, 10, 32, 32, 32, - 32,105,102, 32, 97,114,103, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, - 32,114,101,116,117,114,110, 32,115,101,108,102, 46, 99, 58,115,101,110,100, 40, - 99,109,100, 32, 46, 46, 32, 34, 32, 34, 32, 46, 46, 32, 97,114,103, 46, 46, 32, - 34, 92,114, 92,110, 34, 41, 10, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, - 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46, 99, 58,115, -101,110,100, 40, 99,109,100, 32, 46, 46, 32, 34, 92,114, 92,110, 34, 41, 10, 32, - 32, 32, 32,101,110,100, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, - 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,115,105,110,107, 40, -115,110,107, 44, 32,112, 97,116, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, - 99,104,117,110,107, 44, 32,101,114,114, 32, 61, 32, 99, 58,114,101, 99,101,105, -118,101, 40,112, 97,116, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115, -110,107, 40, 99,104,117,110,107, 44, 32,101,114,114, 41, 10,101,110,100, 10, 10, -102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100, -101,120, 58,115,101,110,100, 40,100, 97,116, 97, 41, 10, 32, 32, 32, 32,114,101, -116,117,114,110, 32,115,101,108,102, 46, 99, 58,115,101,110,100, 40,100, 97,116, - 97, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, - 97,116, 46, 95, 95,105,110,100,101,120, 58,114,101, 99,101,105,118,101, 40,112, - 97,116, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46, - 99, 58,114,101, 99,101,105,118,101, 40,112, 97,116, 41, 10,101,110,100, 10, 10, -102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100, -101,120, 58,103,101,116,102,100, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114, -110, 32,115,101,108,102, 46, 99, 58,103,101,116,102,100, 40, 41, 10,101,110,100, + 46,102,105,110,100, 40, 99,111,100,101, 44, 32,111,107, 41, 32,116,104,101,110, + 32,114,101,116,117,114,110, 32, 98, 97,115,101, 46,116,111,110,117,109, 98,101, +114, 40, 99,111,100,101, 41, 44, 32,114,101,112,108,121, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,110, +105,108, 44, 32,114,101,112,108,121, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, + 32, 32,101,110,100, 10, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114, +110, 32,111,107, 40, 98, 97,115,101, 46,116,111,110,117,109, 98,101,114, 40, 99, +111,100,101, 41, 44, 32,114,101,112,108,121, 41, 32,101,110,100, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105, -110,100,101,120, 58,100,105,114,116,121, 40, 41, 10, 32, 32, 32, 32,114,101,116, -117,114,110, 32,115,101,108,102, 46, 99, 58,100,105,114,116,121, 40, 41, 10,101, -110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, - 95,105,110,100,101,120, 58,103,101,116, 99,111,110,116,114,111,108, 40, 41, 10, - 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46, 99, 10,101,110, +110,100,101,120, 58, 99,111,109,109, 97,110,100, 40, 99,109,100, 44, 32, 97,114, +103, 41, 10, 32, 32, 32, 32, 99,109,100, 32, 61, 32,115,116,114,105,110,103, 46, +117,112,112,101,114, 40, 99,109,100, 41, 10, 32, 32, 32, 32,105,102, 32, 97,114, +103, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114, +110, 32,115,101,108,102, 46, 99, 58,115,101,110,100, 40, 99,109,100, 32, 46, 46, + 32, 34, 32, 34, 32, 46, 46, 32, 97,114,103, 46, 46, 32, 34, 92,114, 92,110, 34, + 41, 10, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,114, +101,116,117,114,110, 32,115,101,108,102, 46, 99, 58,115,101,110,100, 40, 99,109, +100, 32, 46, 46, 32, 34, 92,114, 92,110, 34, 41, 10, 32, 32, 32, 32,101,110,100, + 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, + 46, 95, 95,105,110,100,101,120, 58,115,105,110,107, 40,115,110,107, 44, 32,112, + 97,116, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104,117,110,107, 44, + 32,101,114,114, 32, 61, 32,115,101,108,102, 46, 99, 58,114,101, 99,101,105,118, +101, 40,112, 97,116, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,110, +107, 40, 99,104,117,110,107, 44, 32,101,114,114, 41, 10,101,110,100, 10, 10,102, +117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101, +120, 58,115,101,110,100, 40,100, 97,116, 97, 41, 10, 32, 32, 32, 32,114,101,116, +117,114,110, 32,115,101,108,102, 46, 99, 58,115,101,110,100, 40,100, 97,116, 97, + 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97, +116, 46, 95, 95,105,110,100,101,120, 58,114,101, 99,101,105,118,101, 40,112, 97, +116, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46, 99, + 58,114,101, 99,101,105,118,101, 40,112, 97,116, 41, 10,101,110,100, 10, 10,102, +117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101, +120, 58,103,101,116,102,100, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, + 32,115,101,108,102, 46, 99, 58,103,101,116,102,100, 40, 41, 10,101,110,100, 10, + 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110, +100,101,120, 58,100,105,114,116,121, 40, 41, 10, 32, 32, 32, 32,114,101,116,117, +114,110, 32,115,101,108,102, 46, 99, 58,100,105,114,116,121, 40, 41, 10,101,110, 100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95, -105,110,100,101,120, 58,115,111,117,114, 99,101, 40,115,111,117,114, 99,101, 44, - 32,115,116,101,112, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,105,110, -107, 32, 61, 32,115,111, 99,107,101,116, 46,115,105,110,107, 40, 34,107,101,101, -112, 45,111,112,101,110, 34, 44, 32,115,101,108,102, 46, 99, 41, 10, 32, 32, 32, - 32,108,111, 99, 97,108, 32,114,101,116, 44, 32,101,114,114, 32, 61, 32,108,116, -110, 49, 50, 46,112,117,109,112, 46, 97,108,108, 40,115,111,117,114, 99,101, 44, - 32,115,105,110,107, 44, 32,115,116,101,112, 32,111,114, 32,108,116,110, 49, 50, - 46,112,117,109,112, 46,115,116,101,112, 41, 10, 32, 32, 32, 32,114,101,116,117, -114,110, 32,114,101,116, 44, 32,101,114,114, 10,101,110,100, 10, 10, 45, 45, 32, - 99,108,111,115,101,115, 32,116,104,101, 32,117,110,100,101,114,108,121,105,110, -103, 32, 99, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, - 95,105,110,100,101,120, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,115, -101,108,102, 46, 99, 58, 99,108,111,115,101, 40, 41, 10, 9,114,101,116,117,114, -110, 32, 49, 10,101,110,100, 10, 10, 45, 45, 32, 99,111,110,110,101, 99,116, 32, -119,105,116,104, 32,115,101,114,118,101,114, 32, 97,110,100, 32,114,101,116,117, -114,110, 32, 99, 32,111, 98,106,101, 99,116, 10,102,117,110, 99,116,105,111,110, - 32, 99,111,110,110,101, 99,116, 40,104,111,115,116, 44, 32,112,111,114,116, 44, - 32,116,105,109,101,111,117,116, 44, 32, 99,114,101, 97,116,101, 41, 10, 32, 32, - 32, 32,108,111, 99, 97,108, 32, 99, 44, 32,101, 32, 61, 32, 40, 99,114,101, 97, -116,101, 32,111,114, 32,115,111, 99,107,101,116, 46,116, 99,112, 41, 40, 41, 10, - 32, 32, 32, 32,105,102, 32,110,111,116, 32, 99, 32,116,104,101,110, 32,114,101, -116,117,114,110, 32,110,105,108, 44, 32,101, 32,101,110,100, 10, 32, 32, 32, 32, - 99, 58,115,101,116,116,105,109,101,111,117,116, 40,116,105,109,101,111,117,116, - 32,111,114, 32, 84, 73, 77, 69, 79, 85, 84, 41, 10, 32, 32, 32, 32,108,111, 99, - 97,108, 32,114, 44, 32,101, 32, 61, 32, 99, 58, 99,111,110,110,101, 99,116, 40, -104,111,115,116, 44, 32,112,111,114,116, 41, 10, 32, 32, 32, 32,105,102, 32,110, -111,116, 32,114, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99, 58, - 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117, -114,110, 32,110,105,108, 44, 32,101, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, - 32, 32,114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,101,116, - 97,116, 97, 98,108,101, 40,123, 99, 32, 61, 32, 99,125, 44, 32,109,101,116, 97, -116, 41, 10,101,110,100, 10, 10, +105,110,100,101,120, 58,103,101,116, 99,111,110,116,114,111,108, 40, 41, 10, 32, + 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46, 99, 10,101,110,100, + 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105, +110,100,101,120, 58,115,111,117,114, 99,101, 40,115,111,117,114, 99,101, 44, 32, +115,116,101,112, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,105,110,107, + 32, 61, 32,115,111, 99,107,101,116, 46,115,105,110,107, 40, 34,107,101,101,112, + 45,111,112,101,110, 34, 44, 32,115,101,108,102, 46, 99, 41, 10, 32, 32, 32, 32, +108,111, 99, 97,108, 32,114,101,116, 44, 32,101,114,114, 32, 61, 32,108,116,110, + 49, 50, 46,112,117,109,112, 46, 97,108,108, 40,115,111,117,114, 99,101, 44, 32, +115,105,110,107, 44, 32,115,116,101,112, 32,111,114, 32,108,116,110, 49, 50, 46, +112,117,109,112, 46,115,116,101,112, 41, 10, 32, 32, 32, 32,114,101,116,117,114, +110, 32,114,101,116, 44, 32,101,114,114, 10,101,110,100, 10, 10, 45, 45, 32, 99, +108,111,115,101,115, 32,116,104,101, 32,117,110,100,101,114,108,121,105,110,103, + 32, 99, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95, +105,110,100,101,120, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,115,101, +108,102, 46, 99, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,114,101,116, +117,114,110, 32, 49, 10,101,110,100, 10, 10, 45, 45, 32, 99,111,110,110,101, 99, +116, 32,119,105,116,104, 32,115,101,114,118,101,114, 32, 97,110,100, 32,114,101, +116,117,114,110, 32, 99, 32,111, 98,106,101, 99,116, 10,102,117,110, 99,116,105, +111,110, 32, 95, 77, 46, 99,111,110,110,101, 99,116, 40,104,111,115,116, 44, 32, +112,111,114,116, 44, 32,116,105,109,101,111,117,116, 44, 32, 99,114,101, 97,116, +101, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99, 44, 32,101, 32, 61, 32, + 40, 99,114,101, 97,116,101, 32,111,114, 32,115,111, 99,107,101,116, 46,116, 99, +112, 41, 40, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32, 99, 32,116,104, +101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101, 32,101,110,100, + 10, 32, 32, 32, 32, 99, 58,115,101,116,116,105,109,101,111,117,116, 40,116,105, +109,101,111,117,116, 32,111,114, 32, 95, 77, 46, 84, 73, 77, 69, 79, 85, 84, 41, + 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,114, 44, 32,101, 32, 61, 32, 99, 58, + 99,111,110,110,101, 99,116, 40,104,111,115,116, 44, 32,112,111,114,116, 41, 10, + 32, 32, 32, 32,105,102, 32,110,111,116, 32,114, 32,116,104,101,110, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 99, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101, 10, 32, 32, + 32, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 98, 97,115, +101, 46,115,101,116,109,101,116, 97,116, 97, 98,108,101, 40,123, 99, 32, 61, 32, + 99,125, 44, 32,109,101,116, 97,116, 41, 10,101,110,100, 10, 10,114,101,116,117, +114,110, 32, 95, 77, 10, }; - if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"tp.lua")==0) lua_call(L, 0, 0); + if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"tp.lua")==0) lua_call(L, 0, LUA_MULTRET); } diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/udp.c b/love/src/jni/love/src/libraries/luasocket/libluasocket/udp.c index 640c459e..ec972526 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/udp.c +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/udp.c @@ -1,13 +1,13 @@ /*=========================================================================*\ -* UDP object +* UDP object * LuaSocket toolkit -* -* RCS ID: $Id: udp.c,v 1.29 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ -#include +#include +#include #include "lua.h" #include "lauxlib.h" +#include "compat.h" #include "auxiliar.h" #include "socket.h" @@ -18,38 +18,42 @@ /* min and max macros */ #ifndef MIN #define MIN(x, y) ((x) < (y) ? x : y) -#endif +#endif #ifndef MAX #define MAX(x, y) ((x) > (y) ? x : y) -#endif - -extern void luax_register(lua_State *L, const char *name, const luaL_Reg *l); +#endif /*=========================================================================*\ * Internal function prototypes \*=========================================================================*/ static int global_create(lua_State *L); +static int global_create4(lua_State *L); +static int global_create6(lua_State *L); static int meth_send(lua_State *L); static int meth_sendto(lua_State *L); static int meth_receive(lua_State *L); static int meth_receivefrom(lua_State *L); +static int meth_getfamily(lua_State *L); static int meth_getsockname(lua_State *L); static int meth_getpeername(lua_State *L); +static int meth_gettimeout(lua_State *L); static int meth_setsockname(lua_State *L); static int meth_setpeername(lua_State *L); static int meth_close(lua_State *L); static int meth_setoption(lua_State *L); +static int meth_getoption(lua_State *L); static int meth_settimeout(lua_State *L); static int meth_getfd(lua_State *L); static int meth_setfd(lua_State *L); static int meth_dirty(lua_State *L); /* udp object methods */ -static luaL_reg udp[] = { +static luaL_Reg udp_methods[] = { {"__gc", meth_close}, {"__tostring", auxiliar_tostring}, {"close", meth_close}, {"dirty", meth_dirty}, + {"getfamily", meth_getfamily}, {"getfd", meth_getfd}, {"getpeername", meth_getpeername}, {"getsockname", meth_getsockname}, @@ -59,52 +63,83 @@ static luaL_reg udp[] = { {"sendto", meth_sendto}, {"setfd", meth_setfd}, {"setoption", meth_setoption}, + {"getoption", meth_getoption}, {"setpeername", meth_setpeername}, {"setsockname", meth_setsockname}, {"settimeout", meth_settimeout}, + {"gettimeout", meth_gettimeout}, {NULL, NULL} }; -/* socket options */ -static t_opt opt[] = { - {"dontroute", opt_dontroute}, - {"broadcast", opt_broadcast}, - {"reuseaddr", opt_reuseaddr}, - {"ip-multicast-ttl", opt_ip_multicast_ttl}, - {"ip-multicast-loop", opt_ip_multicast_loop}, - {"ip-add-membership", opt_ip_add_membership}, - {"ip-drop-membership", opt_ip_drop_membersip}, - {NULL, NULL} +/* socket options for setoption */ +static t_opt optset[] = { + {"dontroute", opt_set_dontroute}, + {"broadcast", opt_set_broadcast}, + {"reuseaddr", opt_set_reuseaddr}, + {"reuseport", opt_set_reuseport}, + {"ip-multicast-if", opt_set_ip_multicast_if}, + {"ip-multicast-ttl", opt_set_ip_multicast_ttl}, + {"ip-multicast-loop", opt_set_ip_multicast_loop}, + {"ip-add-membership", opt_set_ip_add_membership}, + {"ip-drop-membership", opt_set_ip_drop_membersip}, + {"ipv6-unicast-hops", opt_set_ip6_unicast_hops}, + {"ipv6-multicast-hops", opt_set_ip6_unicast_hops}, + {"ipv6-multicast-loop", opt_set_ip6_multicast_loop}, + {"ipv6-add-membership", opt_set_ip6_add_membership}, + {"ipv6-drop-membership", opt_set_ip6_drop_membersip}, + {"ipv6-v6only", opt_set_ip6_v6only}, + {NULL, NULL} +}; + +/* socket options for getoption */ +static t_opt optget[] = { + {"dontroute", opt_get_dontroute}, + {"broadcast", opt_get_broadcast}, + {"reuseaddr", opt_get_reuseaddr}, + {"reuseport", opt_get_reuseport}, + {"ip-multicast-if", opt_get_ip_multicast_if}, + {"ip-multicast-loop", opt_get_ip_multicast_loop}, + {"error", opt_get_error}, + {"ipv6-unicast-hops", opt_get_ip6_unicast_hops}, + {"ipv6-multicast-hops", opt_get_ip6_unicast_hops}, + {"ipv6-multicast-loop", opt_get_ip6_multicast_loop}, + {"ipv6-v6only", opt_get_ip6_v6only}, + {NULL, NULL} }; /* functions in library namespace */ -static luaL_reg func[] = { +static luaL_Reg func[] = { {"udp", global_create}, + {"udp4", global_create4}, + {"udp6", global_create6}, {NULL, NULL} }; /*-------------------------------------------------------------------------*\ * Initializes module \*-------------------------------------------------------------------------*/ -int udp_open(lua_State *L) -{ +int udp_open(lua_State *L) { /* create classes */ - auxiliar_newclass(L, "udp{connected}", udp); - auxiliar_newclass(L, "udp{unconnected}", udp); + auxiliar_newclass(L, "udp{connected}", udp_methods); + auxiliar_newclass(L, "udp{unconnected}", udp_methods); /* create class groups */ auxiliar_add2group(L, "udp{connected}", "udp{any}"); auxiliar_add2group(L, "udp{unconnected}", "udp{any}"); auxiliar_add2group(L, "udp{connected}", "select{able}"); auxiliar_add2group(L, "udp{unconnected}", "select{able}"); /* define library functions */ - luax_register(L, NULL, func); + luaL_setfuncs(L, func, 0); + /* export default UDP size */ + lua_pushliteral(L, "_DATAGRAMSIZE"); + lua_pushinteger(L, UDP_DATAGRAMSIZE); + lua_rawset(L, -3); return 0; } /*=========================================================================*\ * Lua methods \*=========================================================================*/ -const char *udp_strerror(int err) { +static const char *udp_strerror(int err) { /* a 'closed' error on an unconnected means the target address was not * accepted by the transport layer */ if (err == IO_CLOSED) return "refused"; @@ -127,7 +162,7 @@ static int meth_send(lua_State *L) { lua_pushstring(L, udp_strerror(err)); return 2; } - lua_pushnumber(L, sent); + lua_pushnumber(L, (lua_Number) sent); return 1; } @@ -139,24 +174,31 @@ static int meth_sendto(lua_State *L) { size_t count, sent = 0; const char *data = luaL_checklstring(L, 2, &count); const char *ip = luaL_checkstring(L, 3); - unsigned short port = (unsigned short) luaL_checknumber(L, 4); + const char *port = luaL_checkstring(L, 4); p_timeout tm = &udp->tm; - struct sockaddr_in addr; int err; - memset(&addr, 0, sizeof(addr)); - if (!inet_aton(ip, &addr.sin_addr)) - luaL_argerror(L, 3, "invalid ip address"); - addr.sin_family = AF_INET; - addr.sin_port = htons(port); + struct addrinfo aihint; + struct addrinfo *ai; + memset(&aihint, 0, sizeof(aihint)); + aihint.ai_family = udp->family; + aihint.ai_socktype = SOCK_DGRAM; + aihint.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV; + err = getaddrinfo(ip, port, &aihint, &ai); + if (err) { + lua_pushnil(L); + lua_pushstring(L, gai_strerror(err)); + return 2; + } timeout_markstart(tm); - err = socket_sendto(&udp->sock, data, count, &sent, - (SA *) &addr, sizeof(addr), tm); + err = socket_sendto(&udp->sock, data, count, &sent, ai->ai_addr, + (socklen_t) ai->ai_addrlen, tm); + freeaddrinfo(ai); if (err != IO_DONE) { lua_pushnil(L); lua_pushstring(L, udp_strerror(err)); return 2; } - lua_pushnumber(L, sent); + lua_pushnumber(L, (lua_Number) sent); return 1; } @@ -165,19 +207,27 @@ static int meth_sendto(lua_State *L) { \*-------------------------------------------------------------------------*/ static int meth_receive(lua_State *L) { p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); - char buffer[UDP_DATAGRAMSIZE]; - size_t got, count = (size_t) luaL_optnumber(L, 2, sizeof(buffer)); + char buf[UDP_DATAGRAMSIZE]; + size_t got, wanted = (size_t) luaL_optnumber(L, 2, sizeof(buf)); + char *dgram = wanted > sizeof(buf)? (char *) malloc(wanted): buf; int err; p_timeout tm = &udp->tm; - count = MIN(count, sizeof(buffer)); timeout_markstart(tm); - err = socket_recv(&udp->sock, buffer, count, &got, tm); - if (err != IO_DONE) { + if (!dgram) { lua_pushnil(L); - lua_pushstring(L, udp_strerror(err)); + lua_pushliteral(L, "out of memory"); return 2; } - lua_pushlstring(L, buffer, got); + err = socket_recv(&udp->sock, dgram, wanted, &got, tm); + /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */ + if (err != IO_DONE && err != IO_CLOSED) { + lua_pushnil(L); + lua_pushstring(L, udp_strerror(err)); + if (wanted > sizeof(buf)) free(dgram); + return 2; + } + lua_pushlstring(L, dgram, got); + if (wanted > sizeof(buf)) free(dgram); return 1; } @@ -186,26 +236,57 @@ static int meth_receive(lua_State *L) { \*-------------------------------------------------------------------------*/ static int meth_receivefrom(lua_State *L) { p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1); - struct sockaddr_in addr; + char buf[UDP_DATAGRAMSIZE]; + size_t got, wanted = (size_t) luaL_optnumber(L, 2, sizeof(buf)); + char *dgram = wanted > sizeof(buf)? (char *) malloc(wanted): buf; + struct sockaddr_storage addr; socklen_t addr_len = sizeof(addr); - char buffer[UDP_DATAGRAMSIZE]; - size_t got, count = (size_t) luaL_optnumber(L, 2, sizeof(buffer)); + char addrstr[INET6_ADDRSTRLEN]; + char portstr[6]; int err; p_timeout tm = &udp->tm; timeout_markstart(tm); - count = MIN(count, sizeof(buffer)); - err = socket_recvfrom(&udp->sock, buffer, count, &got, - (SA *) &addr, &addr_len, tm); - if (err == IO_DONE) { - lua_pushlstring(L, buffer, got); - lua_pushstring(L, inet_ntoa(addr.sin_addr)); - lua_pushnumber(L, ntohs(addr.sin_port)); - return 3; - } else { + if (!dgram) { + lua_pushnil(L); + lua_pushliteral(L, "out of memory"); + return 2; + } + err = socket_recvfrom(&udp->sock, dgram, wanted, &got, (SA *) &addr, + &addr_len, tm); + /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */ + if (err != IO_DONE && err != IO_CLOSED) { lua_pushnil(L); lua_pushstring(L, udp_strerror(err)); + if (wanted > sizeof(buf)) free(dgram); return 2; } + err = getnameinfo((struct sockaddr *)&addr, addr_len, addrstr, + INET6_ADDRSTRLEN, portstr, 6, NI_NUMERICHOST | NI_NUMERICSERV); + if (err) { + lua_pushnil(L); + lua_pushstring(L, gai_strerror(err)); + if (wanted > sizeof(buf)) free(dgram); + return 2; + } + lua_pushlstring(L, dgram, got); + lua_pushstring(L, addrstr); + lua_pushinteger(L, (int) strtol(portstr, (char **) NULL, 10)); + if (wanted > sizeof(buf)) free(dgram); + return 3; +} + +/*-------------------------------------------------------------------------*\ +* Returns family as string +\*-------------------------------------------------------------------------*/ +static int meth_getfamily(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); + if (udp->family == AF_INET6) { + lua_pushliteral(L, "inet6"); + return 1; + } else { + lua_pushliteral(L, "inet4"); + return 1; + } } /*-------------------------------------------------------------------------*\ @@ -236,12 +317,12 @@ static int meth_dirty(lua_State *L) { \*-------------------------------------------------------------------------*/ static int meth_getpeername(lua_State *L) { p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{connected}", 1); - return inet_meth_getpeername(L, &udp->sock); + return inet_meth_getpeername(L, &udp->sock, udp->family); } static int meth_getsockname(lua_State *L) { p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); - return inet_meth_getsockname(L, &udp->sock); + return inet_meth_getsockname(L, &udp->sock, udp->family); } /*-------------------------------------------------------------------------*\ @@ -249,7 +330,15 @@ static int meth_getsockname(lua_State *L) { \*-------------------------------------------------------------------------*/ static int meth_setoption(lua_State *L) { p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); - return opt_meth_setoption(L, opt, &udp->sock); + return opt_meth_setoption(L, optset, &udp->sock); +} + +/*-------------------------------------------------------------------------*\ +* Just call option handler +\*-------------------------------------------------------------------------*/ +static int meth_getoption(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); + return opt_meth_getoption(L, optget, &udp->sock); } /*-------------------------------------------------------------------------*\ @@ -260,32 +349,47 @@ static int meth_settimeout(lua_State *L) { return timeout_meth_settimeout(L, &udp->tm); } +static int meth_gettimeout(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); + return timeout_meth_gettimeout(L, &udp->tm); +} + /*-------------------------------------------------------------------------*\ * Turns a master udp object into a client object. \*-------------------------------------------------------------------------*/ static int meth_setpeername(lua_State *L) { p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); p_timeout tm = &udp->tm; - const char *address = luaL_checkstring(L, 2); + const char *address = luaL_checkstring(L, 2); int connecting = strcmp(address, "*"); - unsigned short port = connecting ? - (unsigned short) luaL_checknumber(L, 3) : - (unsigned short) luaL_optnumber(L, 3, 0); - const char *err = inet_tryconnect(&udp->sock, address, port, tm); - if (err) { - lua_pushnil(L); - lua_pushstring(L, err); - return 2; + const char *port = connecting? luaL_checkstring(L, 3): "0"; + struct addrinfo connecthints; + const char *err; + memset(&connecthints, 0, sizeof(connecthints)); + connecthints.ai_socktype = SOCK_DGRAM; + /* make sure we try to connect only to the same family */ + connecthints.ai_family = udp->family; + if (connecting) { + err = inet_tryconnect(&udp->sock, &udp->family, address, + port, tm, &connecthints); + if (err) { + lua_pushnil(L); + lua_pushstring(L, err); + return 2; + } + auxiliar_setclass(L, "udp{connected}", 1); + } else { + /* we ignore possible errors because Mac OS X always + * returns EAFNOSUPPORT */ + inet_trydisconnect(&udp->sock, udp->family, tm); + auxiliar_setclass(L, "udp{unconnected}", 1); } - /* change class to connected or unconnected depending on address */ - if (connecting) auxiliar_setclass(L, "udp{connected}", 1); - else auxiliar_setclass(L, "udp{unconnected}", 1); lua_pushnumber(L, 1); return 1; } /*-------------------------------------------------------------------------*\ -* Closes socket used by object +* Closes socket used by object \*-------------------------------------------------------------------------*/ static int meth_close(lua_State *L) { p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); @@ -300,8 +404,14 @@ static int meth_close(lua_State *L) { static int meth_setsockname(lua_State *L) { p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1); const char *address = luaL_checkstring(L, 2); - unsigned short port = (unsigned short) luaL_checknumber(L, 3); - const char *err = inet_trybind(&udp->sock, address, port); + const char *port = luaL_checkstring(L, 3); + const char *err; + struct addrinfo bindhints; + memset(&bindhints, 0, sizeof(bindhints)); + bindhints.ai_socktype = SOCK_DGRAM; + bindhints.ai_family = udp->family; + bindhints.ai_flags = AI_PASSIVE; + err = inet_trybind(&udp->sock, &udp->family, address, port, &bindhints); if (err) { lua_pushnil(L); lua_pushstring(L, err); @@ -315,24 +425,38 @@ static int meth_setsockname(lua_State *L) { * Library functions \*=========================================================================*/ /*-------------------------------------------------------------------------*\ -* Creates a master udp object +* Creates a master udp object \*-------------------------------------------------------------------------*/ -static int global_create(lua_State *L) { - t_socket sock; - const char *err = inet_trycreate(&sock, SOCK_DGRAM); - /* try to allocate a system socket */ - if (!err) { - /* allocate tcp object */ - p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp)); - auxiliar_setclass(L, "udp{unconnected}", -1); - /* initialize remaining structure fields */ - socket_setnonblocking(&sock); - udp->sock = sock; - timeout_init(&udp->tm, -1, -1); - return 1; - } else { - lua_pushnil(L); - lua_pushstring(L, err); - return 2; +static int udp_create(lua_State *L, int family) { + /* allocate udp object */ + p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp)); + auxiliar_setclass(L, "udp{unconnected}", -1); + /* if family is AF_UNSPEC, we leave the socket invalid and + * store AF_UNSPEC into family. This will allow it to later be + * replaced with an AF_INET6 or AF_INET socket upon first use. */ + udp->sock = SOCKET_INVALID; + timeout_init(&udp->tm, -1, -1); + udp->family = family; + if (family != AF_UNSPEC) { + const char *err = inet_trycreate(&udp->sock, family, SOCK_DGRAM, 0); + if (err != NULL) { + lua_pushnil(L); + lua_pushstring(L, err); + return 2; + } + socket_setnonblocking(&udp->sock); } + return 1; +} + +static int global_create(lua_State *L) { + return udp_create(L, AF_UNSPEC); +} + +static int global_create4(lua_State *L) { + return udp_create(L, AF_INET); +} + +static int global_create6(lua_State *L) { + return udp_create(L, AF_INET6); } diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/udp.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/udp.h index 28017121..be9b6a55 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/udp.h +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/udp.h @@ -8,23 +8,21 @@ * (AF_INET, SOCK_DGRAM). * * Two classes are defined: connected and unconnected. UDP objects are -* originally unconnected. They can be "connected" to a given address +* originally unconnected. They can be "connected" to a given address * with a call to the setpeername function. The same function can be used to * break the connection. -* -* RCS ID: $Id: udp.h,v 1.10 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ #include "lua.h" #include "timeout.h" #include "socket.h" -/* can't be larger than wsocket.c MAXCHUNK!!! */ #define UDP_DATAGRAMSIZE 8192 typedef struct t_udp_ { t_socket sock; t_timeout tm; + int family; } t_udp; typedef t_udp *p_udp; diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/unix.c b/love/src/jni/love/src/libraries/luasocket/libluasocket/unix.c index fb12903d..2009c193 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/unix.c +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/unix.c @@ -1,363 +1,30 @@ /*=========================================================================*\ -* Unix domain socket +* Unix domain socket * LuaSocket toolkit -* -* RCS ID: $Id: unix.c,v 1.13 2006/03/13 07:16:39 diego Exp $ \*=========================================================================*/ -#include - #include "lua.h" #include "lauxlib.h" -#include "auxiliar.h" -#include "socket.h" -#include "options.h" -#include "unix.h" -#include +#include "unixtcp.h" +#include "unixudp.h" -extern void luax_register(lua_State *L, const char *name, const luaL_Reg *l); -extern int luax_c_insistglobal(lua_State *L, const char *k); - -/*=========================================================================*\ -* Internal function prototypes -\*=========================================================================*/ -static int global_create(lua_State *L); -static int meth_connect(lua_State *L); -static int meth_listen(lua_State *L); -static int meth_bind(lua_State *L); -static int meth_send(lua_State *L); -static int meth_shutdown(lua_State *L); -static int meth_receive(lua_State *L); -static int meth_accept(lua_State *L); -static int meth_close(lua_State *L); -static int meth_setoption(lua_State *L); -static int meth_settimeout(lua_State *L); -static int meth_getfd(lua_State *L); -static int meth_setfd(lua_State *L); -static int meth_dirty(lua_State *L); -static int meth_getstats(lua_State *L); -static int meth_setstats(lua_State *L); - -static const char *unix_tryconnect(p_unix un, const char *path); -static const char *unix_trybind(p_unix un, const char *path); - -/* unix object methods */ -static luaL_reg un[] = { - {"__gc", meth_close}, - {"__tostring", auxiliar_tostring}, - {"accept", meth_accept}, - {"bind", meth_bind}, - {"close", meth_close}, - {"connect", meth_connect}, - {"dirty", meth_dirty}, - {"getfd", meth_getfd}, - {"getstats", meth_getstats}, - {"setstats", meth_setstats}, - {"listen", meth_listen}, - {"receive", meth_receive}, - {"send", meth_send}, - {"setfd", meth_setfd}, - {"setoption", meth_setoption}, - {"setpeername", meth_connect}, - {"setsockname", meth_bind}, - {"settimeout", meth_settimeout}, - {"shutdown", meth_shutdown}, - {NULL, NULL} +/*-------------------------------------------------------------------------*\ +* Modules and functions +\*-------------------------------------------------------------------------*/ +static const luaL_Reg mod[] = { + {"tcp", unixtcp_open}, + {"udp", unixudp_open}, + {NULL, NULL} }; -/* socket option handlers */ -static t_opt opt[] = { - {"keepalive", opt_keepalive}, - {"reuseaddr", opt_reuseaddr}, - {"linger", opt_linger}, - {NULL, NULL} -}; - -/* our socket creation function */ -static luaL_reg func[] = { - {"unix", global_create}, - {NULL, NULL} -}; - - /*-------------------------------------------------------------------------*\ * Initializes module \*-------------------------------------------------------------------------*/ -int luaopen_socket_unix(lua_State *L) { - /* create classes */ - auxiliar_newclass(L, "unix{master}", un); - auxiliar_newclass(L, "unix{client}", un); - auxiliar_newclass(L, "unix{server}", un); - /* create class groups */ - auxiliar_add2group(L, "unix{master}", "unix{any}"); - auxiliar_add2group(L, "unix{client}", "unix{any}"); - auxiliar_add2group(L, "unix{server}", "unix{any}"); - /* make sure the function ends up in the package table */ - lua_pushcfunction(L, global_create); - - luax_c_insistglobal(L, "socket"); - lua_pushstring(L, "unix"); - lua_pushvalue(L, -3); - lua_settable(L, -3); - - /* return the function instead of the 'socket' table */ - return 1; -} - -/*=========================================================================*\ -* Lua methods -\*=========================================================================*/ -/*-------------------------------------------------------------------------*\ -* Just call buffered IO methods -\*-------------------------------------------------------------------------*/ -static int meth_send(lua_State *L) { - p_unix un = (p_unix) auxiliar_checkclass(L, "unix{client}", 1); - return buffer_meth_send(L, &un->buf); -} - -static int meth_receive(lua_State *L) { - p_unix un = (p_unix) auxiliar_checkclass(L, "unix{client}", 1); - return buffer_meth_receive(L, &un->buf); -} - -static int meth_getstats(lua_State *L) { - p_unix un = (p_unix) auxiliar_checkclass(L, "unix{client}", 1); - return buffer_meth_getstats(L, &un->buf); -} - -static int meth_setstats(lua_State *L) { - p_unix un = (p_unix) auxiliar_checkclass(L, "unix{client}", 1); - return buffer_meth_setstats(L, &un->buf); -} - -/*-------------------------------------------------------------------------*\ -* Just call option handler -\*-------------------------------------------------------------------------*/ -static int meth_setoption(lua_State *L) { - p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); - return opt_meth_setoption(L, opt, &un->sock); -} - -/*-------------------------------------------------------------------------*\ -* Select support methods -\*-------------------------------------------------------------------------*/ -static int meth_getfd(lua_State *L) { - p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); - lua_pushnumber(L, (int) un->sock); - return 1; -} - -/* this is very dangerous, but can be handy for those that are brave enough */ -static int meth_setfd(lua_State *L) { - p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); - un->sock = (t_socket) luaL_checknumber(L, 2); - return 0; -} - -static int meth_dirty(lua_State *L) { - p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); - lua_pushboolean(L, !buffer_isempty(&un->buf)); - return 1; -} - -/*-------------------------------------------------------------------------*\ -* Waits for and returns a client object attempting connection to the -* server object -\*-------------------------------------------------------------------------*/ -static int meth_accept(lua_State *L) { - p_unix server = (p_unix) auxiliar_checkclass(L, "unix{server}", 1); - p_timeout tm = timeout_markstart(&server->tm); - t_socket sock; - int err = socket_accept(&server->sock, &sock, NULL, NULL, tm); - /* if successful, push client socket */ - if (err == IO_DONE) { - p_unix clnt = (p_unix) lua_newuserdata(L, sizeof(t_unix)); - auxiliar_setclass(L, "unix{client}", -1); - /* initialize structure fields */ - socket_setnonblocking(&sock); - clnt->sock = sock; - io_init(&clnt->io, (p_send)socket_send, (p_recv)socket_recv, - (p_error) socket_ioerror, &clnt->sock); - timeout_init(&clnt->tm, -1, -1); - buffer_init(&clnt->buf, &clnt->io, &clnt->tm); - return 1; - } else { - lua_pushnil(L); - lua_pushstring(L, socket_strerror(err)); - return 2; - } -} - -/*-------------------------------------------------------------------------*\ -* Binds an object to an address -\*-------------------------------------------------------------------------*/ -static const char *unix_trybind(p_unix un, const char *path) { - struct sockaddr_un local; - size_t len = strlen(path); - int err; - if (len >= sizeof(local.sun_path)) return "path too long"; - memset(&local, 0, sizeof(local)); - strcpy(local.sun_path, path); - local.sun_family = AF_UNIX; -#ifdef UNIX_HAS_SUN_LEN - local.sun_len = sizeof(local.sun_family) + sizeof(local.sun_len) - + len + 1; - err = socket_bind(&un->sock, (SA *) &local, local.sun_len); - -#else - err = socket_bind(&un->sock, (SA *) &local, - sizeof(local.sun_family) + len); -#endif - if (err != IO_DONE) socket_destroy(&un->sock); - return socket_strerror(err); -} - -static int meth_bind(lua_State *L) { - p_unix un = (p_unix) auxiliar_checkclass(L, "unix{master}", 1); - const char *path = luaL_checkstring(L, 2); - const char *err = unix_trybind(un, path); - if (err) { - lua_pushnil(L); - lua_pushstring(L, err); - return 2; - } - lua_pushnumber(L, 1); - return 1; -} - -/*-------------------------------------------------------------------------*\ -* Turns a master unix object into a client object. -\*-------------------------------------------------------------------------*/ -static const char *unix_tryconnect(p_unix un, const char *path) +int luaopen_socket_unix(lua_State *L) { - struct sockaddr_un remote; - int err; - size_t len = strlen(path); - if (len >= sizeof(remote.sun_path)) return "path too long"; - memset(&remote, 0, sizeof(remote)); - strcpy(remote.sun_path, path); - remote.sun_family = AF_UNIX; - timeout_markstart(&un->tm); -#ifdef UNIX_HAS_SUN_LEN - remote.sun_len = sizeof(remote.sun_family) + sizeof(remote.sun_len) - + len + 1; - err = socket_connect(&un->sock, (SA *) &remote, remote.sun_len, &un->tm); -#else - err = socket_connect(&un->sock, (SA *) &remote, - sizeof(remote.sun_family) + len, &un->tm); -#endif - if (err != IO_DONE) socket_destroy(&un->sock); - return socket_strerror(err); + int i; + lua_newtable(L); + for (i = 0; mod[i].name; i++) mod[i].func(L); + return 1; } -static int meth_connect(lua_State *L) -{ - p_unix un = (p_unix) auxiliar_checkclass(L, "unix{master}", 1); - const char *path = luaL_checkstring(L, 2); - const char *err = unix_tryconnect(un, path); - if (err) { - lua_pushnil(L); - lua_pushstring(L, err); - return 2; - } - /* turn master object into a client object */ - auxiliar_setclass(L, "unix{client}", 1); - lua_pushnumber(L, 1); - return 1; -} - -/*-------------------------------------------------------------------------*\ -* Closes socket used by object -\*-------------------------------------------------------------------------*/ -static int meth_close(lua_State *L) -{ - p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); - socket_destroy(&un->sock); - lua_pushnumber(L, 1); - return 1; -} - -/*-------------------------------------------------------------------------*\ -* Puts the sockt in listen mode -\*-------------------------------------------------------------------------*/ -static int meth_listen(lua_State *L) -{ - p_unix un = (p_unix) auxiliar_checkclass(L, "unix{master}", 1); - int backlog = (int) luaL_optnumber(L, 2, 32); - int err = socket_listen(&un->sock, backlog); - if (err != IO_DONE) { - lua_pushnil(L); - lua_pushstring(L, socket_strerror(err)); - return 2; - } - /* turn master object into a server object */ - auxiliar_setclass(L, "unix{server}", 1); - lua_pushnumber(L, 1); - return 1; -} - -/*-------------------------------------------------------------------------*\ -* Shuts the connection down partially -\*-------------------------------------------------------------------------*/ -static int meth_shutdown(lua_State *L) -{ - p_unix un = (p_unix) auxiliar_checkclass(L, "unix{client}", 1); - const char *how = luaL_optstring(L, 2, "both"); - switch (how[0]) { - case 'b': - if (strcmp(how, "both")) goto error; - socket_shutdown(&un->sock, 2); - break; - case 's': - if (strcmp(how, "send")) goto error; - socket_shutdown(&un->sock, 1); - break; - case 'r': - if (strcmp(how, "receive")) goto error; - socket_shutdown(&un->sock, 0); - break; - } - lua_pushnumber(L, 1); - return 1; -error: - luaL_argerror(L, 2, "invalid shutdown method"); - return 0; -} - -/*-------------------------------------------------------------------------*\ -* Just call tm methods -\*-------------------------------------------------------------------------*/ -static int meth_settimeout(lua_State *L) { - p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); - return timeout_meth_settimeout(L, &un->tm); -} - -/*=========================================================================*\ -* Library functions -\*=========================================================================*/ -/*-------------------------------------------------------------------------*\ -* Creates a master unix object -\*-------------------------------------------------------------------------*/ -static int global_create(lua_State *L) { - t_socket sock; - int err = socket_create(&sock, AF_UNIX, SOCK_STREAM, 0); - /* try to allocate a system socket */ - if (err == IO_DONE) { - /* allocate unix object */ - p_unix un = (p_unix) lua_newuserdata(L, sizeof(t_unix)); - /* set its type as master object */ - auxiliar_setclass(L, "unix{master}", -1); - /* initialize remaining structure fields */ - socket_setnonblocking(&sock); - un->sock = sock; - io_init(&un->io, (p_send) socket_send, (p_recv) socket_recv, - (p_error) socket_ioerror, &un->sock); - timeout_init(&un->tm, -1, -1); - buffer_init(&un->buf, &un->io, &un->tm); - return 1; - } else { - lua_pushnil(L); - lua_pushstring(L, socket_strerror(err)); - return 2; - } -} diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/unix.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/unix.h index 32b7380f..8cc7a793 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/unix.h +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/unix.h @@ -6,8 +6,6 @@ * * This module is just an example of how to extend LuaSocket with a new * domain. -* -* RCS ID: $Id: unix.h,v 1.9 2006/03/13 07:16:39 diego Exp $ \*=========================================================================*/ #include "lua.h" @@ -15,6 +13,10 @@ #include "timeout.h" #include "socket.h" +#ifndef UNIX_API +#define UNIX_API extern +#endif + typedef struct t_unix_ { t_socket sock; t_io io; @@ -23,6 +25,6 @@ typedef struct t_unix_ { } t_unix; typedef t_unix *p_unix; -int luaopen_socket_unix(lua_State *L); +UNIX_API int luaopen_socket_unix(lua_State *L); #endif /* UNIX_H */ diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/unixtcp.c b/love/src/jni/love/src/libraries/luasocket/libluasocket/unixtcp.c new file mode 100644 index 00000000..747ef5f9 --- /dev/null +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/unixtcp.c @@ -0,0 +1,357 @@ +/*=========================================================================*\ +* Unix domain socket tcp sub module +* LuaSocket toolkit +\*=========================================================================*/ +#include + +#include "lua.h" +#include "lauxlib.h" +#include "compat.h" + +#include "auxiliar.h" +#include "socket.h" +#include "options.h" +#include "unixtcp.h" +#include + +/*=========================================================================*\ +* Internal function prototypes +\*=========================================================================*/ +static int global_create(lua_State *L); +static int meth_connect(lua_State *L); +static int meth_listen(lua_State *L); +static int meth_bind(lua_State *L); +static int meth_send(lua_State *L); +static int meth_shutdown(lua_State *L); +static int meth_receive(lua_State *L); +static int meth_accept(lua_State *L); +static int meth_close(lua_State *L); +static int meth_setoption(lua_State *L); +static int meth_settimeout(lua_State *L); +static int meth_getfd(lua_State *L); +static int meth_setfd(lua_State *L); +static int meth_dirty(lua_State *L); +static int meth_getstats(lua_State *L); +static int meth_setstats(lua_State *L); +static int meth_getsockname(lua_State *L); + +static const char *unixtcp_tryconnect(p_unix un, const char *path); +static const char *unixtcp_trybind(p_unix un, const char *path); + +/* unixtcp object methods */ +static luaL_Reg unixtcp_methods[] = { + {"__gc", meth_close}, + {"__tostring", auxiliar_tostring}, + {"accept", meth_accept}, + {"bind", meth_bind}, + {"close", meth_close}, + {"connect", meth_connect}, + {"dirty", meth_dirty}, + {"getfd", meth_getfd}, + {"getstats", meth_getstats}, + {"setstats", meth_setstats}, + {"listen", meth_listen}, + {"receive", meth_receive}, + {"send", meth_send}, + {"setfd", meth_setfd}, + {"setoption", meth_setoption}, + {"setpeername", meth_connect}, + {"setsockname", meth_bind}, + {"getsockname", meth_getsockname}, + {"settimeout", meth_settimeout}, + {"shutdown", meth_shutdown}, + {NULL, NULL} +}; + +/* socket option handlers */ +static t_opt optset[] = { + {"keepalive", opt_set_keepalive}, + {"reuseaddr", opt_set_reuseaddr}, + {"linger", opt_set_linger}, + {NULL, NULL} +}; + +/* functions in library namespace */ +static luaL_Reg func[] = { + {"tcp", global_create}, + {NULL, NULL} +}; + +/*-------------------------------------------------------------------------*\ +* Initializes module +\*-------------------------------------------------------------------------*/ +int unixtcp_open(lua_State *L) +{ + /* create classes */ + auxiliar_newclass(L, "unixtcp{master}", unixtcp_methods); + auxiliar_newclass(L, "unixtcp{client}", unixtcp_methods); + auxiliar_newclass(L, "unixtcp{server}", unixtcp_methods); + + /* create class groups */ + auxiliar_add2group(L, "unixtcp{master}", "unixtcp{any}"); + auxiliar_add2group(L, "unixtcp{client}", "unixtcp{any}"); + auxiliar_add2group(L, "unixtcp{server}", "unixtcp{any}"); + + luaL_setfuncs(L, func, 0); + return 0; +} + +/*=========================================================================*\ +* Lua methods +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Just call buffered IO methods +\*-------------------------------------------------------------------------*/ +static int meth_send(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkclass(L, "unixtcp{client}", 1); + return buffer_meth_send(L, &un->buf); +} + +static int meth_receive(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkclass(L, "unixtcp{client}", 1); + return buffer_meth_receive(L, &un->buf); +} + +static int meth_getstats(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkclass(L, "unixtcp{client}", 1); + return buffer_meth_getstats(L, &un->buf); +} + +static int meth_setstats(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkclass(L, "unixtcp{client}", 1); + return buffer_meth_setstats(L, &un->buf); +} + +/*-------------------------------------------------------------------------*\ +* Just call option handler +\*-------------------------------------------------------------------------*/ +static int meth_setoption(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkgroup(L, "unixtcp{any}", 1); + return opt_meth_setoption(L, optset, &un->sock); +} + +/*-------------------------------------------------------------------------*\ +* Select support methods +\*-------------------------------------------------------------------------*/ +static int meth_getfd(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkgroup(L, "unixtcp{any}", 1); + lua_pushnumber(L, (int) un->sock); + return 1; +} + +/* this is very dangerous, but can be handy for those that are brave enough */ +static int meth_setfd(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkgroup(L, "unixtcp{any}", 1); + un->sock = (t_socket) luaL_checknumber(L, 2); + return 0; +} + +static int meth_dirty(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkgroup(L, "unixtcp{any}", 1); + lua_pushboolean(L, !buffer_isempty(&un->buf)); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Waits for and returns a client object attempting connection to the +* server object +\*-------------------------------------------------------------------------*/ +static int meth_accept(lua_State *L) { + p_unix server = (p_unix) auxiliar_checkclass(L, "unixtcp{server}", 1); + p_timeout tm = timeout_markstart(&server->tm); + t_socket sock; + int err = socket_accept(&server->sock, &sock, NULL, NULL, tm); + /* if successful, push client socket */ + if (err == IO_DONE) { + p_unix clnt = (p_unix) lua_newuserdata(L, sizeof(t_unix)); + auxiliar_setclass(L, "unixtcp{client}", -1); + /* initialize structure fields */ + socket_setnonblocking(&sock); + clnt->sock = sock; + io_init(&clnt->io, (p_send)socket_send, (p_recv)socket_recv, + (p_error) socket_ioerror, &clnt->sock); + timeout_init(&clnt->tm, -1, -1); + buffer_init(&clnt->buf, &clnt->io, &clnt->tm); + return 1; + } else { + lua_pushnil(L); + lua_pushstring(L, socket_strerror(err)); + return 2; + } +} + +/*-------------------------------------------------------------------------*\ +* Binds an object to an address +\*-------------------------------------------------------------------------*/ +static const char *unixtcp_trybind(p_unix un, const char *path) { + struct sockaddr_un local; + size_t len = strlen(path); + int err; + if (len >= sizeof(local.sun_path)) return "path too long"; + memset(&local, 0, sizeof(local)); + strcpy(local.sun_path, path); + local.sun_family = AF_UNIX; +#ifdef UNIX_HAS_SUN_LEN + local.sun_len = sizeof(local.sun_family) + sizeof(local.sun_len) + + len + 1; + err = socket_bind(&un->sock, (SA *) &local, local.sun_len); + +#else + err = socket_bind(&un->sock, (SA *) &local, + sizeof(local.sun_family) + len); +#endif + if (err != IO_DONE) socket_destroy(&un->sock); + return socket_strerror(err); +} + +static int meth_bind(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkclass(L, "unixtcp{master}", 1); + const char *path = luaL_checkstring(L, 2); + const char *err = unixtcp_trybind(un, path); + if (err) { + lua_pushnil(L); + lua_pushstring(L, err); + return 2; + } + lua_pushnumber(L, 1); + return 1; +} + +static int meth_getsockname(lua_State *L) +{ + p_unix un = (p_unix) auxiliar_checkgroup(L, "unixtcp{any}", 1); + struct sockaddr_un peer = {0}; + socklen_t peer_len = sizeof(peer); + + if (getsockname(un->sock, (SA *) &peer, &peer_len) < 0) { + lua_pushnil(L); + lua_pushstring(L, socket_strerror(errno)); + return 2; + } + + lua_pushstring(L, peer.sun_path); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Turns a master unixtcp object into a client object. +\*-------------------------------------------------------------------------*/ +static const char *unixtcp_tryconnect(p_unix un, const char *path) +{ + struct sockaddr_un remote; + int err; + size_t len = strlen(path); + if (len >= sizeof(remote.sun_path)) return "path too long"; + memset(&remote, 0, sizeof(remote)); + strcpy(remote.sun_path, path); + remote.sun_family = AF_UNIX; + timeout_markstart(&un->tm); +#ifdef UNIX_HAS_SUN_LEN + remote.sun_len = sizeof(remote.sun_family) + sizeof(remote.sun_len) + + len + 1; + err = socket_connect(&un->sock, (SA *) &remote, remote.sun_len, &un->tm); +#else + err = socket_connect(&un->sock, (SA *) &remote, + sizeof(remote.sun_family) + len, &un->tm); +#endif + if (err != IO_DONE) socket_destroy(&un->sock); + return socket_strerror(err); +} + +static int meth_connect(lua_State *L) +{ + p_unix un = (p_unix) auxiliar_checkclass(L, "unixtcp{master}", 1); + const char *path = luaL_checkstring(L, 2); + const char *err = unixtcp_tryconnect(un, path); + if (err) { + lua_pushnil(L); + lua_pushstring(L, err); + return 2; + } + /* turn master object into a client object */ + auxiliar_setclass(L, "unixtcp{client}", 1); + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Closes socket used by object +\*-------------------------------------------------------------------------*/ +static int meth_close(lua_State *L) +{ + p_unix un = (p_unix) auxiliar_checkgroup(L, "unixtcp{any}", 1); + socket_destroy(&un->sock); + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Puts the sockt in listen mode +\*-------------------------------------------------------------------------*/ +static int meth_listen(lua_State *L) +{ + p_unix un = (p_unix) auxiliar_checkclass(L, "unixtcp{master}", 1); + int backlog = (int) luaL_optnumber(L, 2, 32); + int err = socket_listen(&un->sock, backlog); + if (err != IO_DONE) { + lua_pushnil(L); + lua_pushstring(L, socket_strerror(err)); + return 2; + } + /* turn master object into a server object */ + auxiliar_setclass(L, "unixtcp{server}", 1); + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Shuts the connection down partially +\*-------------------------------------------------------------------------*/ +static int meth_shutdown(lua_State *L) +{ + /* SHUT_RD, SHUT_WR, SHUT_RDWR have the value 0, 1, 2, so we can use method index directly */ + static const char* methods[] = { "receive", "send", "both", NULL }; + p_unix tcp = (p_unix) auxiliar_checkclass(L, "unixtcp{client}", 1); + int how = luaL_checkoption(L, 2, "both", methods); + socket_shutdown(&tcp->sock, how); + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Just call tm methods +\*-------------------------------------------------------------------------*/ +static int meth_settimeout(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkgroup(L, "unixtcp{any}", 1); + return timeout_meth_settimeout(L, &un->tm); +} + +/*=========================================================================*\ +* Library functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Creates a master unixtcp object +\*-------------------------------------------------------------------------*/ +static int global_create(lua_State *L) { + t_socket sock; + int err = socket_create(&sock, AF_UNIX, SOCK_STREAM, 0); + /* try to allocate a system socket */ + if (err == IO_DONE) { + /* allocate unixtcp object */ + p_unix un = (p_unix) lua_newuserdata(L, sizeof(t_unix)); + /* set its type as master object */ + auxiliar_setclass(L, "unixtcp{master}", -1); + /* initialize remaining structure fields */ + socket_setnonblocking(&sock); + un->sock = sock; + io_init(&un->io, (p_send) socket_send, (p_recv) socket_recv, + (p_error) socket_ioerror, &un->sock); + timeout_init(&un->tm, -1, -1); + buffer_init(&un->buf, &un->io, &un->tm); + return 1; + } else { + lua_pushnil(L); + lua_pushstring(L, socket_strerror(err)); + return 2; + } +} diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/unixtcp.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/unixtcp.h new file mode 100644 index 00000000..0eababce --- /dev/null +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/unixtcp.h @@ -0,0 +1,21 @@ +#ifndef UNIXTCP_H +#define UNIXTCP_H +/*=========================================================================*\ +* UNIX TCP object +* LuaSocket toolkit +* +* The unixtcp.h module is basicly a glue that puts together modules buffer.h, +* timeout.h socket.h and inet.h to provide the LuaSocket UNIX TCP (AF_UNIX, +* SOCK_STREAM) support. +* +* Three classes are defined: master, client and server. The master class is +* a newly created unixtcp object, that has not been bound or connected. Server +* objects are unixtcp objects bound to some local address. Client objects are +* unixtcp objects either connected to some address or returned by the accept +* method of a server object. +\*=========================================================================*/ +#include "unix.h" + +int unixtcp_open(lua_State *L); + +#endif /* UNIXTCP_H */ diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/unixudp.c b/love/src/jni/love/src/libraries/luasocket/libluasocket/unixudp.c new file mode 100644 index 00000000..0e0a19ab --- /dev/null +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/unixudp.c @@ -0,0 +1,407 @@ +/*=========================================================================*\ +* Unix domain socket udp submodule +* LuaSocket toolkit +\*=========================================================================*/ +#include +#include + +#include "lua.h" +#include "lauxlib.h" +#include "compat.h" + +#include "auxiliar.h" +#include "socket.h" +#include "options.h" +#include "unix.h" +#include + +#define UNIXUDP_DATAGRAMSIZE 8192 + +/*=========================================================================*\ +* Internal function prototypes +\*=========================================================================*/ +static int global_create(lua_State *L); +static int meth_connect(lua_State *L); +static int meth_bind(lua_State *L); +static int meth_send(lua_State *L); +static int meth_receive(lua_State *L); +static int meth_close(lua_State *L); +static int meth_setoption(lua_State *L); +static int meth_settimeout(lua_State *L); +static int meth_gettimeout(lua_State *L); +static int meth_getfd(lua_State *L); +static int meth_setfd(lua_State *L); +static int meth_dirty(lua_State *L); +static int meth_receivefrom(lua_State *L); +static int meth_sendto(lua_State *L); +static int meth_getsockname(lua_State *L); + +static const char *unixudp_tryconnect(p_unix un, const char *path); +static const char *unixudp_trybind(p_unix un, const char *path); + +/* unixudp object methods */ +static luaL_Reg unixudp_methods[] = { + {"__gc", meth_close}, + {"__tostring", auxiliar_tostring}, + {"bind", meth_bind}, + {"close", meth_close}, + {"connect", meth_connect}, + {"dirty", meth_dirty}, + {"getfd", meth_getfd}, + {"send", meth_send}, + {"sendto", meth_sendto}, + {"receive", meth_receive}, + {"receivefrom", meth_receivefrom}, + {"setfd", meth_setfd}, + {"setoption", meth_setoption}, + {"setpeername", meth_connect}, + {"setsockname", meth_bind}, + {"getsockname", meth_getsockname}, + {"settimeout", meth_settimeout}, + {"gettimeout", meth_gettimeout}, + {NULL, NULL} +}; + +/* socket option handlers */ +static t_opt optset[] = { + {"reuseaddr", opt_set_reuseaddr}, + {NULL, NULL} +}; + +/* functions in library namespace */ +static luaL_Reg func[] = { + {"udp", global_create}, + {NULL, NULL} +}; + +/*-------------------------------------------------------------------------*\ +* Initializes module +\*-------------------------------------------------------------------------*/ +int unixudp_open(lua_State *L) +{ + /* create classes */ + auxiliar_newclass(L, "unixudp{connected}", unixudp_methods); + auxiliar_newclass(L, "unixudp{unconnected}", unixudp_methods); + /* create class groups */ + auxiliar_add2group(L, "unixudp{connected}", "unixudp{any}"); + auxiliar_add2group(L, "unixudp{unconnected}", "unixudp{any}"); + auxiliar_add2group(L, "unixudp{connected}", "select{able}"); + auxiliar_add2group(L, "unixudp{unconnected}", "select{able}"); + + luaL_setfuncs(L, func, 0); + return 0; +} + +/*=========================================================================*\ +* Lua methods +\*=========================================================================*/ +static const char *unixudp_strerror(int err) +{ + /* a 'closed' error on an unconnected means the target address was not + * accepted by the transport layer */ + if (err == IO_CLOSED) return "refused"; + else return socket_strerror(err); +} + +static int meth_send(lua_State *L) +{ + p_unix un = (p_unix) auxiliar_checkclass(L, "unixudp{connected}", 1); + p_timeout tm = &un->tm; + size_t count, sent = 0; + int err; + const char *data = luaL_checklstring(L, 2, &count); + timeout_markstart(tm); + err = socket_send(&un->sock, data, count, &sent, tm); + if (err != IO_DONE) { + lua_pushnil(L); + lua_pushstring(L, unixudp_strerror(err)); + return 2; + } + lua_pushnumber(L, (lua_Number) sent); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Send data through unconnected unixudp socket +\*-------------------------------------------------------------------------*/ +static int meth_sendto(lua_State *L) +{ + p_unix un = (p_unix) auxiliar_checkclass(L, "unixudp{unconnected}", 1); + size_t count, sent = 0; + const char *data = luaL_checklstring(L, 2, &count); + const char *path = luaL_checkstring(L, 3); + p_timeout tm = &un->tm; + int err; + struct sockaddr_un remote; + size_t len = strlen(path); + + if (len >= sizeof(remote.sun_path)) { + lua_pushnil(L); + lua_pushstring(L, "path too long"); + return 2; + } + + memset(&remote, 0, sizeof(remote)); + strcpy(remote.sun_path, path); + remote.sun_family = AF_UNIX; + timeout_markstart(tm); +#ifdef UNIX_HAS_SUN_LEN + remote.sun_len = sizeof(remote.sun_family) + sizeof(remote.sun_len) + + len + 1; + err = socket_sendto(&un->sock, data, count, &sent, (SA *) &remote, remote.sun_len, tm); +#else + err = socket_sendto(&un->sock, data, count, &sent, (SA *) &remote, + sizeof(remote.sun_family) + len, tm); +#endif + if (err != IO_DONE) { + lua_pushnil(L); + lua_pushstring(L, unixudp_strerror(err)); + return 2; + } + lua_pushnumber(L, (lua_Number) sent); + return 1; +} + +static int meth_receive(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkgroup(L, "unixudp{any}", 1); + char buf[UNIXUDP_DATAGRAMSIZE]; + size_t got, wanted = (size_t) luaL_optnumber(L, 2, sizeof(buf)); + char *dgram = wanted > sizeof(buf)? (char *) malloc(wanted): buf; + int err; + p_timeout tm = &un->tm; + timeout_markstart(tm); + if (!dgram) { + lua_pushnil(L); + lua_pushliteral(L, "out of memory"); + return 2; + } + err = socket_recv(&un->sock, dgram, wanted, &got, tm); + /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */ + if (err != IO_DONE && err != IO_CLOSED) { + lua_pushnil(L); + lua_pushstring(L, unixudp_strerror(err)); + if (wanted > sizeof(buf)) free(dgram); + return 2; + } + lua_pushlstring(L, dgram, got); + if (wanted > sizeof(buf)) free(dgram); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Receives data and sender from a UDP socket +\*-------------------------------------------------------------------------*/ +static int meth_receivefrom(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkclass(L, "unixudp{unconnected}", 1); + char buf[UNIXUDP_DATAGRAMSIZE]; + size_t got, wanted = (size_t) luaL_optnumber(L, 2, sizeof(buf)); + char *dgram = wanted > sizeof(buf)? (char *) malloc(wanted): buf; + struct sockaddr_un addr; + socklen_t addr_len = sizeof(addr); + int err; + p_timeout tm = &un->tm; + timeout_markstart(tm); + if (!dgram) { + lua_pushnil(L); + lua_pushliteral(L, "out of memory"); + return 2; + } + err = socket_recvfrom(&un->sock, dgram, wanted, &got, (SA *) &addr, + &addr_len, tm); + /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */ + if (err != IO_DONE && err != IO_CLOSED) { + lua_pushnil(L); + lua_pushstring(L, unixudp_strerror(err)); + if (wanted > sizeof(buf)) free(dgram); + return 2; + } + + lua_pushlstring(L, dgram, got); + /* the path may be empty, when client send without bind */ + lua_pushstring(L, addr.sun_path); + if (wanted > sizeof(buf)) free(dgram); + return 2; +} + +/*-------------------------------------------------------------------------*\ +* Just call option handler +\*-------------------------------------------------------------------------*/ +static int meth_setoption(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkgroup(L, "unixudp{any}", 1); + return opt_meth_setoption(L, optset, &un->sock); +} + +/*-------------------------------------------------------------------------*\ +* Select support methods +\*-------------------------------------------------------------------------*/ +static int meth_getfd(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkgroup(L, "unixudp{any}", 1); + lua_pushnumber(L, (int) un->sock); + return 1; +} + +/* this is very dangerous, but can be handy for those that are brave enough */ +static int meth_setfd(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkgroup(L, "unixudp{any}", 1); + un->sock = (t_socket) luaL_checknumber(L, 2); + return 0; +} + +static int meth_dirty(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkgroup(L, "unixudp{any}", 1); + (void) un; + lua_pushboolean(L, 0); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Binds an object to an address +\*-------------------------------------------------------------------------*/ +static const char *unixudp_trybind(p_unix un, const char *path) { + struct sockaddr_un local; + size_t len = strlen(path); + int err; + if (len >= sizeof(local.sun_path)) return "path too long"; + memset(&local, 0, sizeof(local)); + strcpy(local.sun_path, path); + local.sun_family = AF_UNIX; +#ifdef UNIX_HAS_SUN_LEN + local.sun_len = sizeof(local.sun_family) + sizeof(local.sun_len) + + len + 1; + err = socket_bind(&un->sock, (SA *) &local, local.sun_len); + +#else + err = socket_bind(&un->sock, (SA *) &local, + sizeof(local.sun_family) + len); +#endif + if (err != IO_DONE) socket_destroy(&un->sock); + return socket_strerror(err); +} + +static int meth_bind(lua_State *L) +{ + p_unix un = (p_unix) auxiliar_checkclass(L, "unixudp{unconnected}", 1); + const char *path = luaL_checkstring(L, 2); + const char *err = unixudp_trybind(un, path); + if (err) { + lua_pushnil(L); + lua_pushstring(L, err); + return 2; + } + lua_pushnumber(L, 1); + return 1; +} + +static int meth_getsockname(lua_State *L) +{ + p_unix un = (p_unix) auxiliar_checkgroup(L, "unixudp{any}", 1); + struct sockaddr_un peer = {0}; + socklen_t peer_len = sizeof(peer); + + if (getsockname(un->sock, (SA *) &peer, &peer_len) < 0) { + lua_pushnil(L); + lua_pushstring(L, socket_strerror(errno)); + return 2; + } + + lua_pushstring(L, peer.sun_path); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Turns a master unixudp object into a client object. +\*-------------------------------------------------------------------------*/ +static const char *unixudp_tryconnect(p_unix un, const char *path) +{ + struct sockaddr_un remote; + int err; + size_t len = strlen(path); + if (len >= sizeof(remote.sun_path)) return "path too long"; + memset(&remote, 0, sizeof(remote)); + strcpy(remote.sun_path, path); + remote.sun_family = AF_UNIX; + timeout_markstart(&un->tm); +#ifdef UNIX_HAS_SUN_LEN + remote.sun_len = sizeof(remote.sun_family) + sizeof(remote.sun_len) + + len + 1; + err = socket_connect(&un->sock, (SA *) &remote, remote.sun_len, &un->tm); +#else + err = socket_connect(&un->sock, (SA *) &remote, + sizeof(remote.sun_family) + len, &un->tm); +#endif + if (err != IO_DONE) socket_destroy(&un->sock); + return socket_strerror(err); +} + +static int meth_connect(lua_State *L) +{ + p_unix un = (p_unix) auxiliar_checkgroup(L, "unixudp{any}", 1); + const char *path = luaL_checkstring(L, 2); + const char *err = unixudp_tryconnect(un, path); + if (err) { + lua_pushnil(L); + lua_pushstring(L, err); + return 2; + } + /* turn unconnected object into a connected object */ + auxiliar_setclass(L, "unixudp{connected}", 1); + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Closes socket used by object +\*-------------------------------------------------------------------------*/ +static int meth_close(lua_State *L) +{ + p_unix un = (p_unix) auxiliar_checkgroup(L, "unixudp{any}", 1); + socket_destroy(&un->sock); + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Just call tm methods +\*-------------------------------------------------------------------------*/ +static int meth_settimeout(lua_State *L) +{ + p_unix un = (p_unix) auxiliar_checkgroup(L, "unixudp{any}", 1); + return timeout_meth_settimeout(L, &un->tm); +} + +static int meth_gettimeout(lua_State *L) +{ + p_unix un = (p_unix) auxiliar_checkgroup(L, "unixudp{any}", 1); + return timeout_meth_gettimeout(L, &un->tm); +} + +/*=========================================================================*\ +* Library functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Creates a master unixudp object +\*-------------------------------------------------------------------------*/ +static int global_create(lua_State *L) +{ + t_socket sock; + int err = socket_create(&sock, AF_UNIX, SOCK_DGRAM, 0); + /* try to allocate a system socket */ + if (err == IO_DONE) { + /* allocate unixudp object */ + p_unix un = (p_unix) lua_newuserdata(L, sizeof(t_unix)); + /* set its type as master object */ + auxiliar_setclass(L, "unixudp{unconnected}", -1); + /* initialize remaining structure fields */ + socket_setnonblocking(&sock); + un->sock = sock; + io_init(&un->io, (p_send) socket_send, (p_recv) socket_recv, + (p_error) socket_ioerror, &un->sock); + timeout_init(&un->tm, -1, -1); + buffer_init(&un->buf, &un->io, &un->tm); + return 1; + } else { + lua_pushnil(L); + lua_pushstring(L, socket_strerror(err)); + return 2; + } +} diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/unixudp.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/unixudp.h new file mode 100644 index 00000000..ccfdc075 --- /dev/null +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/unixudp.h @@ -0,0 +1,20 @@ +#ifndef UNIXUDP_H +#define UNIXUDP_H +/*=========================================================================*\ +* UDP object +* LuaSocket toolkit +* +* The udp.h module provides LuaSocket with support for UDP protocol +* (AF_INET, SOCK_DGRAM). +* +* Two classes are defined: connected and unconnected. UDP objects are +* originally unconnected. They can be "connected" to a given address +* with a call to the setpeername function. The same function can be used to +* break the connection. +\*=========================================================================*/ + +#include "unix.h" + +int unixudp_open(lua_State *L); + +#endif /* UNIXUDP_H */ diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/url.lua b/love/src/jni/love/src/libraries/luasocket/libluasocket/url.lua index 0e31d8af..3f1359c8 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/url.lua +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/url.lua @@ -2,7 +2,6 @@ -- URI parsing, composition and relative URL resolution -- LuaSocket toolkit. -- Author: Diego Nehab --- RCS ID: $Id: url.lua,v 1.38 2006/04/03 04:45:42 diego Exp $ ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- @@ -11,12 +10,15 @@ local string = require("string") local base = _G local table = require("table") -module("socket.url") +local socket = require("socket") + +socket.url = {} +local _M = socket.url ----------------------------------------------------------------------------- -- Module version ----------------------------------------------------------------------------- -_VERSION = "URL 1.0.1" +_M._VERSION = "URL 1.0.3" ----------------------------------------------------------------------------- -- Encodes a string into its escaped hexadecimal representation @@ -25,10 +27,10 @@ _VERSION = "URL 1.0.1" -- Returns -- escaped representation of string binary ----------------------------------------------------------------------------- -function escape(s) - return string.gsub(s, "([^A-Za-z0-9_])", function(c) +function _M.escape(s) + return (string.gsub(s, "([^A-Za-z0-9_])", function(c) return string.format("%%%02x", string.byte(c)) - end) + end)) end ----------------------------------------------------------------------------- @@ -40,38 +42,38 @@ end -- escaped representation of string binary ----------------------------------------------------------------------------- local function make_set(t) - local s = {} - for i,v in base.ipairs(t) do - s[t[i]] = 1 - end - return s + local s = {} + for i,v in base.ipairs(t) do + s[t[i]] = 1 + end + return s end --- these are allowed withing a path segment, along with alphanum +-- these are allowed within a path segment, along with alphanum -- other characters must be escaped local segment_set = make_set { "-", "_", ".", "!", "~", "*", "'", "(", - ")", ":", "@", "&", "=", "+", "$", ",", + ")", ":", "@", "&", "=", "+", "$", ",", } local function protect_segment(s) - return string.gsub(s, "([^A-Za-z0-9_])", function (c) - if segment_set[c] then return c - else return string.format("%%%02x", string.byte(c)) end - end) + return string.gsub(s, "([^A-Za-z0-9_])", function (c) + if segment_set[c] then return c + else return string.format("%%%02x", string.byte(c)) end + end) end ----------------------------------------------------------------------------- --- Encodes a string into its escaped hexadecimal representation +-- Unencodes a escaped hexadecimal string into its binary representation -- Input --- s: binary string to be encoded +-- s: escaped hexadecimal string to be unencoded -- Returns --- escaped representation of string binary +-- unescaped binary representation of escaped hexadecimal binary ----------------------------------------------------------------------------- -function unescape(s) - return string.gsub(s, "%%(%x%x)", function(hex) +function _M.unescape(s) + return (string.gsub(s, "%%(%x%x)", function(hex) return string.char(base.tonumber(hex, 16)) - end) + end)) end ----------------------------------------------------------------------------- @@ -121,7 +123,7 @@ end -- Obs: -- the leading '/' in {/} is considered part of ----------------------------------------------------------------------------- -function parse(url, default) +function _M.parse(url, default) -- initialize default parameters local parsed = {} for i,v in base.pairs(default or parsed) do parsed[i] = v end @@ -142,7 +144,7 @@ function parse(url, default) parsed.authority = n return "" end) - -- get query stringing + -- get query string url = string.gsub(url, "%?(.*)", function(q) parsed.query = q return "" @@ -158,9 +160,12 @@ function parse(url, default) if not authority then return parsed end authority = string.gsub(authority,"^([^@]*)@", function(u) parsed.userinfo = u; return "" end) - authority = string.gsub(authority, ":([^:]*)$", + authority = string.gsub(authority, ":([^:%]]*)$", function(p) parsed.port = p; return "" end) - if authority ~= "" then parsed.host = authority end + if authority ~= "" then + -- IPv6? + parsed.host = string.match(authority, "^%[(.+)%]$") or authority + end local userinfo = parsed.userinfo if not userinfo then return parsed end userinfo = string.gsub(userinfo, ":([^:]*)$", @@ -177,24 +182,27 @@ end -- Returns -- a stringing with the corresponding URL ----------------------------------------------------------------------------- -function build(parsed) - local ppath = parse_path(parsed.path or "") - local url = build_path(ppath) +function _M.build(parsed) + local ppath = _M.parse_path(parsed.path or "") + local url = _M.build_path(ppath) if parsed.params then url = url .. ";" .. parsed.params end if parsed.query then url = url .. "?" .. parsed.query end - local authority = parsed.authority - if parsed.host then - authority = parsed.host - if parsed.port then authority = authority .. ":" .. parsed.port end - local userinfo = parsed.userinfo - if parsed.user then - userinfo = parsed.user - if parsed.password then - userinfo = userinfo .. ":" .. parsed.password - end - end - if userinfo then authority = userinfo .. "@" .. authority end - end + local authority = parsed.authority + if parsed.host then + authority = parsed.host + if string.find(authority, ":") then -- IPv6? + authority = "[" .. authority .. "]" + end + if parsed.port then authority = authority .. ":" .. parsed.port end + local userinfo = parsed.userinfo + if parsed.user then + userinfo = parsed.user + if parsed.password then + userinfo = userinfo .. ":" .. parsed.password + end + end + if userinfo then authority = userinfo .. "@" .. authority end + end if authority then url = "//" .. authority .. url end if parsed.scheme then url = parsed.scheme .. ":" .. url end if parsed.fragment then url = url .. "#" .. parsed.fragment end @@ -210,14 +218,15 @@ end -- Returns -- corresponding absolute url ----------------------------------------------------------------------------- -function absolute(base_url, relative_url) +function _M.absolute(base_url, relative_url) + local base_parsed if base.type(base_url) == "table" then base_parsed = base_url - base_url = build(base_parsed) + base_url = _M.build(base_parsed) else - base_parsed = parse(base_url) + base_parsed = _M.parse(base_url) end - local relative_parsed = parse(relative_url) + local relative_parsed = _M.parse(relative_url) if not base_parsed then return relative_url elseif not relative_parsed then return base_url elseif relative_parsed.scheme then return relative_url @@ -238,7 +247,7 @@ function absolute(base_url, relative_url) relative_parsed.path) end end - return build(relative_parsed) + return _M.build(relative_parsed) end end @@ -249,17 +258,17 @@ end -- Returns -- segment: a table with one entry per segment ----------------------------------------------------------------------------- -function parse_path(path) - local parsed = {} - path = path or "" - --path = string.gsub(path, "%s", "") - string.gsub(path, "([^/]+)", function (s) table.insert(parsed, s) end) - for i = 1, table.getn(parsed) do - parsed[i] = unescape(parsed[i]) - end - if string.sub(path, 1, 1) == "/" then parsed.is_absolute = 1 end - if string.sub(path, -1, -1) == "/" then parsed.is_directory = 1 end - return parsed +function _M.parse_path(path) + local parsed = {} + path = path or "" + --path = string.gsub(path, "%s", "") + string.gsub(path, "([^/]+)", function (s) table.insert(parsed, s) end) + for i = 1, #parsed do + parsed[i] = _M.unescape(parsed[i]) + end + if string.sub(path, 1, 1) == "/" then parsed.is_absolute = 1 end + if string.sub(path, -1, -1) == "/" then parsed.is_directory = 1 end + return parsed end ----------------------------------------------------------------------------- @@ -270,28 +279,30 @@ end -- Returns -- path: corresponding path stringing ----------------------------------------------------------------------------- -function build_path(parsed, unsafe) - local path = "" - local n = table.getn(parsed) - if unsafe then - for i = 1, n-1 do - path = path .. parsed[i] - path = path .. "/" - end - if n > 0 then - path = path .. parsed[n] - if parsed.is_directory then path = path .. "/" end - end - else - for i = 1, n-1 do - path = path .. protect_segment(parsed[i]) - path = path .. "/" - end - if n > 0 then - path = path .. protect_segment(parsed[n]) - if parsed.is_directory then path = path .. "/" end - end - end - if parsed.is_absolute then path = "/" .. path end - return path +function _M.build_path(parsed, unsafe) + local path = "" + local n = #parsed + if unsafe then + for i = 1, n-1 do + path = path .. parsed[i] + path = path .. "/" + end + if n > 0 then + path = path .. parsed[n] + if parsed.is_directory then path = path .. "/" end + end + else + for i = 1, n-1 do + path = path .. protect_segment(parsed[i]) + path = path .. "/" + end + if n > 0 then + path = path .. protect_segment(parsed[n]) + if parsed.is_directory then path = path .. "/" end + end + end + if parsed.is_absolute then path = "/" .. path end + return path end + +return _M diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/url.lua.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/url.lua.h index 59916b37..25147214 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/url.lua.h +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/url.lua.h @@ -1,7 +1,7 @@ /* code automatically generated by bin2c -- DO NOT EDIT */ { /* #include'ing this file in a C program is equivalent to calling - if (luaL_loadfile(L,"url.lua")==0) lua_call(L, 0, 0); + if (luaL_loadfile(L,"url.lua")==0) lua_call(L, 0, LUA_MULTRET); */ /* url.lua */ static const unsigned char B1[]={ @@ -14,525 +14,554 @@ static const unsigned char B1[]={ 82, 76, 32,114,101,115,111,108,117,116,105,111,110, 10, 45, 45, 32, 76,117, 97, 83,111, 99,107,101,116, 32,116,111,111,108,107,105,116, 46, 10, 45, 45, 32, 65, 117,116,104,111,114, 58, 32, 68,105,101,103,111, 32, 78,101,104, 97, 98, 10, 45, - 45, 32, 82, 67, 83, 32, 73, 68, 58, 32, 36, 73,100, 58, 32,117,114,108, 46,108, -117, 97, 44,118, 32, 49, 46, 51, 56, 32, 50, 48, 48, 54, 47, 48, 52, 47, 48, 51, - 32, 48, 52, 58, 52, 53, 58, 52, 50, 32,100,105,101,103,111, 32, 69,120,112, 32, - 36, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68, +101, 99,108, 97,114,101, 32,109,111,100,117,108,101, 10, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,115,116, +114,105,110,103, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,116,114,105, +110,103, 34, 41, 10,108,111, 99, 97,108, 32, 98, 97,115,101, 32, 61, 32, 95, 71, + 10,108,111, 99, 97,108, 32,116, 97, 98,108,101, 32, 61, 32,114,101,113,117,105, +114,101, 40, 34,116, 97, 98,108,101, 34, 41, 10,108,111, 99, 97,108, 32,115,111, + 99,107,101,116, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,111, 99,107, +101,116, 34, 41, 10, 10,115,111, 99,107,101,116, 46,117,114,108, 32, 61, 32,123, +125, 10,108,111, 99, 97,108, 32, 95, 77, 32, 61, 32,115,111, 99,107,101,116, 46, +117,114,108, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 10, 45, 45, 32, 77,111,100,117,108,101, 32,118,101,114,115,105,111,110, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, - 45, 32, 68,101, 99,108, 97,114,101, 32,109,111,100,117,108,101, 10, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 95, + 77, 46, 95, 86, 69, 82, 83, 73, 79, 78, 32, 61, 32, 34, 85, 82, 76, 32, 49, 46, + 48, 46, 51, 34, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, - 32,115,116,114,105,110,103, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115, -116,114,105,110,103, 34, 41, 10,108,111, 99, 97,108, 32, 98, 97,115,101, 32, 61, - 32, 95, 71, 10,108,111, 99, 97,108, 32,116, 97, 98,108,101, 32, 61, 32,114,101, -113,117,105,114,101, 40, 34,116, 97, 98,108,101, 34, 41, 10,109,111,100,117,108, -101, 40, 34,115,111, 99,107,101,116, 46,117,114,108, 34, 41, 10, 10, 45, 45, 45, + 45, 45, 45, 10, 45, 45, 32, 69,110, 99,111,100,101,115, 32, 97, 32,115,116,114, +105,110,103, 32,105,110,116,111, 32,105,116,115, 32,101,115, 99, 97,112,101,100, + 32,104,101,120, 97,100,101, 99,105,109, 97,108, 32,114,101,112,114,101,115,101, +110,116, 97,116,105,111,110, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, + 32, 32,115, 58, 32, 98,105,110, 97,114,121, 32,115,116,114,105,110,103, 32,116, +111, 32, 98,101, 32,101,110, 99,111,100,101,100, 10, 45, 45, 32, 82,101,116,117, +114,110,115, 10, 45, 45, 32, 32, 32,101,115, 99, 97,112,101,100, 32,114,101,112, +114,101,115,101,110,116, 97,116,105,111,110, 32,111,102, 32,115,116,114,105,110, +103, 32, 98,105,110, 97,114,121, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 77,111, -100,117,108,101, 32,118,101,114,115,105,111,110, 10, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 10,102,117,110, 99,116,105,111,110, 32, 95, 77, 46,101, +115, 99, 97,112,101, 40,115, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, + 40,115,116,114,105,110,103, 46,103,115,117, 98, 40,115, 44, 32, 34, 40, 91, 94, + 65, 45, 90, 97, 45,122, 48, 45, 57, 95, 93, 41, 34, 44, 32,102,117,110, 99,116, +105,111,110, 40, 99, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114, +110, 32,115,116,114,105,110,103, 46,102,111,114,109, 97,116, 40, 34, 37, 37, 37, + 48, 50,120, 34, 44, 32,115,116,114,105,110,103, 46, 98,121,116,101, 40, 99, 41, + 41, 10, 32, 32, 32, 32,101,110,100, 41, 41, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 95, 86, 69, 82, 83, 73, 79, 78, 32, - 61, 32, 34, 85, 82, 76, 32, 49, 46, 48, 46, 49, 34, 10, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 80,114, +111,116,101, 99,116,115, 32, 97, 32,112, 97,116,104, 32,115,101,103,109,101,110, +116, 44, 32,116,111, 32,112,114,101,118,101,110,116, 32,105,116, 32,102,114,111, +109, 32,105,110,116,101,114,102,101,114,105,110,103, 32,119,105,116,104, 32,116, +104,101, 10, 45, 45, 32,117,114,108, 32,112, 97,114,115,105,110,103, 46, 10, 45, + 45, 32, 73,110,112,117,116, 10, 45, 45, 32, 32, 32,115, 58, 32, 98,105,110, 97, +114,121, 32,115,116,114,105,110,103, 32,116,111, 32, 98,101, 32,101,110, 99,111, +100,101,100, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32, 32, 32, +101,115, 99, 97,112,101,100, 32,114,101,112,114,101,115,101,110,116, 97,116,105, +111,110, 32,111,102, 32,115,116,114,105,110,103, 32, 98,105,110, 97,114,121, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 69,110, 99,111, -100,101,115, 32, 97, 32,115,116,114,105,110,103, 32,105,110,116,111, 32,105,116, -115, 32,101,115, 99, 97,112,101,100, 32,104,101,120, 97,100,101, 99,105,109, 97, -108, 32,114,101,112,114,101,115,101,110,116, 97,116,105,111,110, 10, 45, 45, 32, - 73,110,112,117,116, 10, 45, 45, 32, 32, 32,115, 58, 32, 98,105,110, 97,114,121, - 32,115,116,114,105,110,103, 32,116,111, 32, 98,101, 32,101,110, 99,111,100,101, -100, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32, 32, 32,101,115, - 99, 97,112,101,100, 32,114,101,112,114,101,115,101,110,116, 97,116,105,111,110, - 32,111,102, 32,115,116,114,105,110,103, 32, 98,105,110, 97,114,121, 10, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, + 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,109, 97,107,101, 95,115,101, +116, 40,116, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115, 32, 61, 32,123, +125, 10, 32, 32, 32, 32,102,111,114, 32,105, 44,118, 32,105,110, 32, 98, 97,115, +101, 46,105,112, 97,105,114,115, 40,116, 41, 32,100,111, 10, 32, 32, 32, 32, 32, + 32, 32, 32,115, 91,116, 91,105, 93, 93, 32, 61, 32, 49, 10, 32, 32, 32, 32,101, +110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115, 10,101,110,100, 10, + 10, 45, 45, 32,116,104,101,115,101, 32, 97,114,101, 32, 97,108,108,111,119,101, +100, 32,119,105,116,104,105,110,103, 32, 97, 32,112, 97,116,104, 32,115,101,103, +109,101,110,116, 44, 32, 97,108,111,110,103, 32,119,105,116,104, 32, 97,108,112, +104, 97,110,117,109, 10, 45, 45, 32,111,116,104,101,114, 32, 99,104, 97,114, 97, + 99,116,101,114,115, 32,109,117,115,116, 32, 98,101, 32,101,115, 99, 97,112,101, +100, 10,108,111, 99, 97,108, 32,115,101,103,109,101,110,116, 95,115,101,116, 32, + 61, 32,109, 97,107,101, 95,115,101,116, 32,123, 10, 32, 32, 32, 32, 34, 45, 34, + 44, 32, 34, 95, 34, 44, 32, 34, 46, 34, 44, 32, 34, 33, 34, 44, 32, 34,126, 34, + 44, 32, 34, 42, 34, 44, 32, 34, 39, 34, 44, 32, 34, 40, 34, 44, 10, 32, 32, 32, + 32, 34, 41, 34, 44, 32, 34, 58, 34, 44, 32, 34, 64, 34, 44, 32, 34, 38, 34, 44, + 32, 34, 61, 34, 44, 32, 34, 43, 34, 44, 32, 34, 36, 34, 44, 32, 34, 44, 34, 44, + 10,125, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,112, +114,111,116,101, 99,116, 95,115,101,103,109,101,110,116, 40,115, 41, 10, 32, 32, + 32, 32,114,101,116,117,114,110, 32,115,116,114,105,110,103, 46,103,115,117, 98, + 40,115, 44, 32, 34, 40, 91, 94, 65, 45, 90, 97, 45,122, 48, 45, 57, 95, 93, 41, + 34, 44, 32,102,117,110, 99,116,105,111,110, 32, 40, 99, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32,105,102, 32,115,101,103,109,101,110,116, 95,115,101,116, 91, 99, + 93, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 99, 10, 32, 32, 32, 32, + 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,115,116,114,105, +110,103, 46,102,111,114,109, 97,116, 40, 34, 37, 37, 37, 48, 50,120, 34, 44, 32, +115,116,114,105,110,103, 46, 98,121,116,101, 40, 99, 41, 41, 32,101,110,100, 10, + 32, 32, 32, 32,101,110,100, 41, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,102,117,110, 99, -116,105,111,110, 32,101,115, 99, 97,112,101, 40,115, 41, 10, 32, 32, 32, 32,114, -101,116,117,114,110, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,115, 44, - 32, 34, 40, 91, 94, 65, 45, 90, 97, 45,122, 48, 45, 57, 95, 93, 41, 34, 44, 32, -102,117,110, 99,116,105,111,110, 40, 99, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, -114,101,116,117,114,110, 32,115,116,114,105,110,103, 46,102,111,114,109, 97,116, - 40, 34, 37, 37, 37, 48, 50,120, 34, 44, 32,115,116,114,105,110,103, 46, 98,121, -116,101, 40, 99, 41, 41, 10, 32, 32, 32, 32,101,110,100, 41, 10,101,110,100, 10, - 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, - 45, 32, 80,114,111,116,101, 99,116,115, 32, 97, 32,112, 97,116,104, 32,115,101, -103,109,101,110,116, 44, 32,116,111, 32,112,114,101,118,101,110,116, 32,105,116, - 32,102,114,111,109, 32,105,110,116,101,114,102,101,114,105,110,103, 32,119,105, -116,104, 32,116,104,101, 10, 45, 45, 32,117,114,108, 32,112, 97,114,115,105,110, -103, 46, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, 32, 32,115, 58, 32, - 98,105,110, 97,114,121, 32,115,116,114,105,110,103, 32,116,111, 32, 98,101, 32, -101,110, 99,111,100,101,100, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, - 45, 32, 32, 32,101,115, 99, 97,112,101,100, 32,114,101,112,114,101,115,101,110, -116, 97,116,105,111,110, 32,111,102, 32,115,116,114,105,110,103, 32, 98,105,110, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 85,110,101,110, 99, +111,100,101,115, 32, 97, 32,101,115, 99, 97,112,101,100, 32,104,101,120, 97,100, +101, 99,105,109, 97,108, 32,115,116,114,105,110,103, 32,105,110,116,111, 32,105, +116,115, 32, 98,105,110, 97,114,121, 32,114,101,112,114,101,115,101,110,116, 97, +116,105,111,110, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, 32, 32,115, + 58, 32,101,115, 99, 97,112,101,100, 32,104,101,120, 97,100,101, 99,105,109, 97, +108, 32,115,116,114,105,110,103, 32,116,111, 32, 98,101, 32,117,110,101,110, 99, +111,100,101,100, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32, 32, + 32,117,110,101,115, 99, 97,112,101,100, 32, 98,105,110, 97,114,121, 32,114,101, +112,114,101,115,101,110,116, 97,116,105,111,110, 32,111,102, 32,101,115, 99, 97, +112,101,100, 32,104,101,120, 97,100,101, 99,105,109, 97,108, 32, 32, 98,105,110, 97,114,121, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,109, 97,107, -101, 95,115,101,116, 40,116, 41, 10, 9,108,111, 99, 97,108, 32,115, 32, 61, 32, -123,125, 10, 9,102,111,114, 32,105, 44,118, 32,105,110, 32, 98, 97,115,101, 46, -105,112, 97,105,114,115, 40,116, 41, 32,100,111, 10, 9, 9,115, 91,116, 91,105, - 93, 93, 32, 61, 32, 49, 10, 9,101,110,100, 10, 9,114,101,116,117,114,110, 32, -115, 10,101,110,100, 10, 10, 45, 45, 32,116,104,101,115,101, 32, 97,114,101, 32, - 97,108,108,111,119,101,100, 32,119,105,116,104,105,110,103, 32, 97, 32,112, 97, -116,104, 32,115,101,103,109,101,110,116, 44, 32, 97,108,111,110,103, 32,119,105, -116,104, 32, 97,108,112,104, 97,110,117,109, 10, 45, 45, 32,111,116,104,101,114, - 32, 99,104, 97,114, 97, 99,116,101,114,115, 32,109,117,115,116, 32, 98,101, 32, -101,115, 99, 97,112,101,100, 10,108,111, 99, 97,108, 32,115,101,103,109,101,110, -116, 95,115,101,116, 32, 61, 32,109, 97,107,101, 95,115,101,116, 32,123, 10, 32, - 32, 32, 32, 34, 45, 34, 44, 32, 34, 95, 34, 44, 32, 34, 46, 34, 44, 32, 34, 33, - 34, 44, 32, 34,126, 34, 44, 32, 34, 42, 34, 44, 32, 34, 39, 34, 44, 32, 34, 40, - 34, 44, 10, 9, 34, 41, 34, 44, 32, 34, 58, 34, 44, 32, 34, 64, 34, 44, 32, 34, - 38, 34, 44, 32, 34, 61, 34, 44, 32, 34, 43, 34, 44, 32, 34, 36, 34, 44, 32, 34, - 44, 34, 44, 10,125, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111, -110, 32,112,114,111,116,101, 99,116, 95,115,101,103,109,101,110,116, 40,115, 41, - 10, 9,114,101,116,117,114,110, 32,115,116,114,105,110,103, 46,103,115,117, 98, - 40,115, 44, 32, 34, 40, 91, 94, 65, 45, 90, 97, 45,122, 48, 45, 57, 95, 93, 41, - 34, 44, 32,102,117,110, 99,116,105,111,110, 32, 40, 99, 41, 10, 9, 9,105,102, - 32,115,101,103,109,101,110,116, 95,115,101,116, 91, 99, 93, 32,116,104,101,110, - 32,114,101,116,117,114,110, 32, 99, 10, 9, 9,101,108,115,101, 32,114,101,116, -117,114,110, 32,115,116,114,105,110,103, 46,102,111,114,109, 97,116, 40, 34, 37, - 37, 37, 48, 50,120, 34, 44, 32,115,116,114,105,110,103, 46, 98,121,116,101, 40, - 99, 41, 41, 32,101,110,100, 10, 9,101,110,100, 41, 10,101,110,100, 10, 10, 45, + 45, 10,102,117,110, 99,116,105,111,110, 32, 95, 77, 46,117,110,101,115, 99, 97, +112,101, 40,115, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 40,115,116, +114,105,110,103, 46,103,115,117, 98, 40,115, 44, 32, 34, 37, 37, 40, 37,120, 37, +120, 41, 34, 44, 32,102,117,110, 99,116,105,111,110, 40,104,101,120, 41, 10, 32, + 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,116,114,105,110,103, + 46, 99,104, 97,114, 40, 98, 97,115,101, 46,116,111,110,117,109, 98,101,114, 40, +104,101,120, 44, 32, 49, 54, 41, 41, 10, 32, 32, 32, 32,101,110,100, 41, 41, 10, +101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, - 69,110, 99,111,100,101,115, 32, 97, 32,115,116,114,105,110,103, 32,105,110,116, -111, 32,105,116,115, 32,101,115, 99, 97,112,101,100, 32,104,101,120, 97,100,101, - 99,105,109, 97,108, 32,114,101,112,114,101,115,101,110,116, 97,116,105,111,110, - 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, 32, 32,115, 58, 32, 98,105, -110, 97,114,121, 32,115,116,114,105,110,103, 32,116,111, 32, 98,101, 32,101,110, - 99,111,100,101,100, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32, - 32, 32,101,115, 99, 97,112,101,100, 32,114,101,112,114,101,115,101,110,116, 97, -116,105,111,110, 32,111,102, 32,115,116,114,105,110,103, 32, 98,105,110, 97,114, -121, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, -102,117,110, 99,116,105,111,110, 32,117,110,101,115, 99, 97,112,101, 40,115, 41, - 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,116,114,105,110,103, 46,103, -115,117, 98, 40,115, 44, 32, 34, 37, 37, 40, 37,120, 37,120, 41, 34, 44, 32,102, -117,110, 99,116,105,111,110, 40,104,101,120, 41, 10, 32, 32, 32, 32, 32, 32, 32, - 32,114,101,116,117,114,110, 32,115,116,114,105,110,103, 46, 99,104, 97,114, 40, - 98, 97,115,101, 46,116,111,110,117,109, 98,101,114, 40,104,101,120, 44, 32, 49, - 54, 41, 41, 10, 32, 32, 32, 32,101,110,100, 41, 10,101,110,100, 10, 10, 45, 45, + 45, 45, 10, 45, 45, 32, 66,117,105,108,100,115, 32, 97, 32,112, 97,116,104, 32, +102,114,111,109, 32, 97, 32, 98, 97,115,101, 32,112, 97,116,104, 32, 97,110,100, + 32, 97, 32,114,101,108, 97,116,105,118,101, 32,112, 97,116,104, 10, 45, 45, 32, + 73,110,112,117,116, 10, 45, 45, 32, 32, 32, 98, 97,115,101, 95,112, 97,116,104, + 10, 45, 45, 32, 32, 32,114,101,108, 97,116,105,118,101, 95,112, 97,116,104, 10, + 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32, 32, 32, 99,111,114,114, +101,115,112,111,110,100,105,110,103, 32, 97, 98,115,111,108,117,116,101, 32,112, + 97,116,104, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 66, -117,105,108,100,115, 32, 97, 32,112, 97,116,104, 32,102,114,111,109, 32, 97, 32, - 98, 97,115,101, 32,112, 97,116,104, 32, 97,110,100, 32, 97, 32,114,101,108, 97, -116,105,118,101, 32,112, 97,116,104, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, - 45, 32, 32, 32, 98, 97,115,101, 95,112, 97,116,104, 10, 45, 45, 32, 32, 32,114, -101,108, 97,116,105,118,101, 95,112, 97,116,104, 10, 45, 45, 32, 82,101,116,117, -114,110,115, 10, 45, 45, 32, 32, 32, 99,111,114,114,101,115,112,111,110,100,105, -110,103, 32, 97, 98,115,111,108,117,116,101, 32,112, 97,116,104, 10, 45, 45, 45, + 45, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32, 97, 98,115, +111,108,117,116,101, 95,112, 97,116,104, 40, 98, 97,115,101, 95,112, 97,116,104, + 44, 32,114,101,108, 97,116,105,118,101, 95,112, 97,116,104, 41, 10, 32, 32, 32, + 32,105,102, 32,115,116,114,105,110,103, 46,115,117, 98, 40,114,101,108, 97,116, +105,118,101, 95,112, 97,116,104, 44, 32, 49, 44, 32, 49, 41, 32, 61, 61, 32, 34, + 47, 34, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,114,101,108, 97,116, +105,118,101, 95,112, 97,116,104, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,112, 97,116,104, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, + 98, 40, 98, 97,115,101, 95,112, 97,116,104, 44, 32, 34, 91, 94, 47, 93, 42, 36, + 34, 44, 32, 34, 34, 41, 10, 32, 32, 32, 32,112, 97,116,104, 32, 61, 32,112, 97, +116,104, 32, 46, 46, 32,114,101,108, 97,116,105,118,101, 95,112, 97,116,104, 10, + 32, 32, 32, 32,112, 97,116,104, 32, 61, 32,115,116,114,105,110,103, 46,103,115, +117, 98, 40,112, 97,116,104, 44, 32, 34, 40, 91, 94, 47, 93, 42, 37, 46, 47, 41, + 34, 44, 32,102,117,110, 99,116,105,111,110, 32, 40,115, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32,105,102, 32,115, 32,126, 61, 32, 34, 46, 47, 34, 32,116,104,101, +110, 32,114,101,116,117,114,110, 32,115, 32,101,108,115,101, 32,114,101,116,117, +114,110, 32, 34, 34, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 41, 10, 32, + 32, 32, 32,112, 97,116,104, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, + 98, 40,112, 97,116,104, 44, 32, 34, 47, 37, 46, 36, 34, 44, 32, 34, 47, 34, 41, + 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,100,117, 99,101,100, 10, 32, + 32, 32, 32,119,104,105,108,101, 32,114,101,100,117, 99,101,100, 32,126, 61, 32, +112, 97,116,104, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,100,117, + 99,101,100, 32, 61, 32,112, 97,116,104, 10, 32, 32, 32, 32, 32, 32, 32, 32,112, + 97,116,104, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,114,101, +100,117, 99,101,100, 44, 32, 34, 40, 91, 94, 47, 93, 42, 47, 37, 46, 37, 46, 47, + 41, 34, 44, 32,102,117,110, 99,116,105,111,110, 32, 40,115, 41, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,115, 32,126, 61, 32, 34, 46, 46, + 47, 46, 46, 47, 34, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 34, 34, + 32,101,108,115,101, 32,114,101,116,117,114,110, 32,115, 32,101,110,100, 10, 32, + 32, 32, 32, 32, 32, 32, 32,101,110,100, 41, 10, 32, 32, 32, 32,101,110,100, 10, + 32, 32, 32, 32,112, 97,116,104, 32, 61, 32,115,116,114,105,110,103, 46,103,115, +117, 98, 40,114,101,100,117, 99,101,100, 44, 32, 34, 40, 91, 94, 47, 93, 42, 47, + 37, 46, 37, 46, 41, 36, 34, 44, 32,102,117,110, 99,116,105,111,110, 32, 40,115, + 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,115, 32,126, 61, 32, 34, 46, + 46, 47, 46, 46, 34, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 34, 34, + 32,101,108,115,101, 32,114,101,116,117,114,110, 32,115, 32,101,110,100, 10, 32, + 32, 32, 32,101,110,100, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,112, + 97,116,104, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, - 32,102,117,110, 99,116,105,111,110, 32, 97, 98,115,111,108,117,116,101, 95,112, - 97,116,104, 40, 98, 97,115,101, 95,112, 97,116,104, 44, 32,114,101,108, 97,116, -105,118,101, 95,112, 97,116,104, 41, 10, 32, 32, 32, 32,105,102, 32,115,116,114, -105,110,103, 46,115,117, 98, 40,114,101,108, 97,116,105,118,101, 95,112, 97,116, -104, 44, 32, 49, 44, 32, 49, 41, 32, 61, 61, 32, 34, 47, 34, 32,116,104,101,110, - 32,114,101,116,117,114,110, 32,114,101,108, 97,116,105,118,101, 95,112, 97,116, -104, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112, 97,116,104, - 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, 98, 97,115,101, 95, -112, 97,116,104, 44, 32, 34, 91, 94, 47, 93, 42, 36, 34, 44, 32, 34, 34, 41, 10, - 32, 32, 32, 32,112, 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46, 46, 32,114, -101,108, 97,116,105,118,101, 95,112, 97,116,104, 10, 32, 32, 32, 32,112, 97,116, -104, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,112, 97,116,104, - 44, 32, 34, 40, 91, 94, 47, 93, 42, 37, 46, 47, 41, 34, 44, 32,102,117,110, 99, -116,105,111,110, 32, 40,115, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, -115, 32,126, 61, 32, 34, 46, 47, 34, 32,116,104,101,110, 32,114,101,116,117,114, -110, 32,115, 32,101,108,115,101, 32,114,101,116,117,114,110, 32, 34, 34, 32,101, -110,100, 10, 32, 32, 32, 32,101,110,100, 41, 10, 32, 32, 32, 32,112, 97,116,104, - 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,112, 97,116,104, 44, - 32, 34, 47, 37, 46, 36, 34, 44, 32, 34, 47, 34, 41, 10, 32, 32, 32, 32,108,111, - 99, 97,108, 32,114,101,100,117, 99,101,100, 10, 32, 32, 32, 32,119,104,105,108, -101, 32,114,101,100,117, 99,101,100, 32,126, 61, 32,112, 97,116,104, 32,100,111, - 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,100,117, 99,101,100, 32, 61, 32,112, - 97,116,104, 10, 32, 32, 32, 32, 32, 32, 32, 32,112, 97,116,104, 32, 61, 32,115, -116,114,105,110,103, 46,103,115,117, 98, 40,114,101,100,117, 99,101,100, 44, 32, - 34, 40, 91, 94, 47, 93, 42, 47, 37, 46, 37, 46, 47, 41, 34, 44, 32,102,117,110, - 99,116,105,111,110, 32, 40,115, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32,105,102, 32,115, 32,126, 61, 32, 34, 46, 46, 47, 46, 46, 47, 34, 32,116, -104,101,110, 32,114,101,116,117,114,110, 32, 34, 34, 32,101,108,115,101, 32,114, -101,116,117,114,110, 32,115, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, -101,110,100, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,112, 97,116, -104, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,114,101,100,117, - 99,101,100, 44, 32, 34, 40, 91, 94, 47, 93, 42, 47, 37, 46, 37, 46, 41, 36, 34, - 44, 32,102,117,110, 99,116,105,111,110, 32, 40,115, 41, 10, 32, 32, 32, 32, 32, - 32, 32, 32,105,102, 32,115, 32,126, 61, 32, 34, 46, 46, 47, 46, 46, 34, 32,116, -104,101,110, 32,114,101,116,117,114,110, 32, 34, 34, 32,101,108,115,101, 32,114, -101,116,117,114,110, 32,115, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 41, - 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,112, 97,116,104, 10,101,110,100, - 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 80, 97,114,115,101,115, 32, 97, 32,117, +114,108, 32, 97,110,100, 32,114,101,116,117,114,110,115, 32, 97, 32,116, 97, 98, +108,101, 32,119,105,116,104, 32, 97,108,108, 32,105,116,115, 32,112, 97,114,116, +115, 32, 97, 99, 99,111,114,100,105,110,103, 32,116,111, 32, 82, 70, 67, 32, 50, + 51, 57, 54, 10, 45, 45, 32, 84,104,101, 32,102,111,108,108,111,119,105,110,103, + 32,103,114, 97,109,109, 97,114, 32,100,101,115, 99,114,105, 98,101,115, 32,116, +104,101, 32,110, 97,109,101,115, 32,103,105,118,101,110, 32,116,111, 32,116,104, +101, 32, 85, 82, 76, 32,112, 97,114,116,115, 10, 45, 45, 32, 60,117,114,108, 62, + 32, 58, 58, 61, 32, 60,115, 99,104,101,109,101, 62, 58, 47, 47, 60, 97,117,116, +104,111,114,105,116,121, 62, 47, 60,112, 97,116,104, 62, 59, 60,112, 97,114, 97, +109,115, 62, 63, 60,113,117,101,114,121, 62, 35, 60,102,114, 97,103,109,101,110, +116, 62, 10, 45, 45, 32, 60, 97,117,116,104,111,114,105,116,121, 62, 32, 58, 58, + 61, 32, 60,117,115,101,114,105,110,102,111, 62, 64, 60,104,111,115,116, 62, 58, + 60,112,111,114,116, 62, 10, 45, 45, 32, 60,117,115,101,114,105,110,102,111, 62, + 32, 58, 58, 61, 32, 60,117,115,101,114, 62, 91, 58, 60,112, 97,115,115,119,111, +114,100, 62, 93, 10, 45, 45, 32, 60,112, 97,116,104, 62, 32, 58, 58, 32, 61, 32, +123, 60,115,101,103,109,101,110,116, 62, 47,125, 60,115,101,103,109,101,110,116, + 62, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, 32, 32,117,114,108, 58, + 32,117,110,105,102,111,114,109, 32,114,101,115,111,117,114, 99,101, 32,108,111, + 99, 97,116,111,114, 32,111,102, 32,114,101,113,117,101,115,116, 10, 45, 45, 32, + 32, 32,100,101,102, 97,117,108,116, 58, 32,116, 97, 98,108,101, 32,119,105,116, +104, 32,100,101,102, 97,117,108,116, 32,118, 97,108,117,101,115, 32,102,111,114, + 32,101, 97, 99,104, 32,102,105,101,108,100, 10, 45, 45, 32, 82,101,116,117,114, +110,115, 10, 45, 45, 32, 32, 32,116, 97, 98,108,101, 32,119,105,116,104, 32,116, +104,101, 32,102,111,108,108,111,119,105,110,103, 32,102,105,101,108,100,115, 44, + 32,119,104,101,114,101, 32, 82, 70, 67, 32,110, 97,109,105,110,103, 32, 99,111, +110,118,101,110,116,105,111,110,115, 32,104, 97,118,101, 10, 45, 45, 32, 32, 32, + 98,101,101,110, 32,112,114,101,115,101,114,118,101,100, 58, 10, 45, 45, 32, 32, + 32, 32, 32,115, 99,104,101,109,101, 44, 32, 97,117,116,104,111,114,105,116,121, + 44, 32,117,115,101,114,105,110,102,111, 44, 32,117,115,101,114, 44, 32,112, 97, +115,115,119,111,114,100, 44, 32,104,111,115,116, 44, 32,112,111,114,116, 44, 10, + 45, 45, 32, 32, 32, 32, 32,112, 97,116,104, 44, 32,112, 97,114, 97,109,115, 44, + 32,113,117,101,114,121, 44, 32,102,114, 97,103,109,101,110,116, 10, 45, 45, 32, + 79, 98,115, 58, 10, 45, 45, 32, 32, 32,116,104,101, 32,108,101, 97,100,105,110, +103, 32, 39, 47, 39, 32,105,110, 32,123, 47, 60,112, 97,116,104, 62,125, 32,105, +115, 32, 99,111,110,115,105,100,101,114,101,100, 32,112, 97,114,116, 32,111,102, + 32, 60,112, 97,116,104, 62, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, - 45, 45, 32, 80, 97,114,115,101,115, 32, 97, 32,117,114,108, 32, 97,110,100, 32, -114,101,116,117,114,110,115, 32, 97, 32,116, 97, 98,108,101, 32,119,105,116,104, - 32, 97,108,108, 32,105,116,115, 32,112, 97,114,116,115, 32, 97, 99, 99,111,114, -100,105,110,103, 32,116,111, 32, 82, 70, 67, 32, 50, 51, 57, 54, 10, 45, 45, 32, - 84,104,101, 32,102,111,108,108,111,119,105,110,103, 32,103,114, 97,109,109, 97, -114, 32,100,101,115, 99,114,105, 98,101,115, 32,116,104,101, 32,110, 97,109,101, -115, 32,103,105,118,101,110, 32,116,111, 32,116,104,101, 32, 85, 82, 76, 32,112, - 97,114,116,115, 10, 45, 45, 32, 60,117,114,108, 62, 32, 58, 58, 61, 32, 60,115, - 99,104,101,109,101, 62, 58, 47, 47, 60, 97,117,116,104,111,114,105,116,121, 62, - 47, 60,112, 97,116,104, 62, 59, 60,112, 97,114, 97,109,115, 62, 63, 60,113,117, -101,114,121, 62, 35, 60,102,114, 97,103,109,101,110,116, 62, 10, 45, 45, 32, 60, - 97,117,116,104,111,114,105,116,121, 62, 32, 58, 58, 61, 32, 60,117,115,101,114, -105,110,102,111, 62, 64, 60,104,111,115,116, 62, 58, 60,112,111,114,116, 62, 10, - 45, 45, 32, 60,117,115,101,114,105,110,102,111, 62, 32, 58, 58, 61, 32, 60,117, -115,101,114, 62, 91, 58, 60,112, 97,115,115,119,111,114,100, 62, 93, 10, 45, 45, - 32, 60,112, 97,116,104, 62, 32, 58, 58, 32, 61, 32,123, 60,115,101,103,109,101, -110,116, 62, 47,125, 60,115,101,103,109,101,110,116, 62, 10, 45, 45, 32, 73,110, -112,117,116, 10, 45, 45, 32, 32, 32,117,114,108, 58, 32,117,110,105,102,111,114, -109, 32,114,101,115,111,117,114, 99,101, 32,108,111, 99, 97,116,111,114, 32,111, -102, 32,114,101,113,117,101,115,116, 10, 45, 45, 32, 32, 32,100,101,102, 97,117, -108,116, 58, 32,116, 97, 98,108,101, 32,119,105,116,104, 32,100,101,102, 97,117, -108,116, 32,118, 97,108,117,101,115, 32,102,111,114, 32,101, 97, 99,104, 32,102, -105,101,108,100, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32, 32, - 32,116, 97, 98,108,101, 32,119,105,116,104, 32,116,104,101, 32,102,111,108,108, -111,119,105,110,103, 32,102,105,101,108,100,115, 44, 32,119,104,101,114,101, 32, - 82, 70, 67, 32,110, 97,109,105,110,103, 32, 99,111,110,118,101,110,116,105,111, -110,115, 32,104, 97,118,101, 10, 45, 45, 32, 32, 32, 98,101,101,110, 32,112,114, -101,115,101,114,118,101,100, 58, 10, 45, 45, 32, 32, 32, 32, 32,115, 99,104,101, -109,101, 44, 32, 97,117,116,104,111,114,105,116,121, 44, 32,117,115,101,114,105, -110,102,111, 44, 32,117,115,101,114, 44, 32,112, 97,115,115,119,111,114,100, 44, - 32,104,111,115,116, 44, 32,112,111,114,116, 44, 10, 45, 45, 32, 32, 32, 32, 32, -112, 97,116,104, 44, 32,112, 97,114, 97,109,115, 44, 32,113,117,101,114,121, 44, - 32,102,114, 97,103,109,101,110,116, 10, 45, 45, 32, 79, 98,115, 58, 10, 45, 45, - 32, 32, 32,116,104,101, 32,108,101, 97,100,105,110,103, 32, 39, 47, 39, 32,105, -110, 32,123, 47, 60,112, 97,116,104, 62,125, 32,105,115, 32, 99,111,110,115,105, -100,101,114,101,100, 32,112, 97,114,116, 32,111,102, 32, 60,112, 97,116,104, 62, - 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,102, -117,110, 99,116,105,111,110, 32,112, 97,114,115,101, 40,117,114,108, 44, 32,100, -101,102, 97,117,108,116, 41, 10, 32, 32, 32, 32, 45, 45, 32,105,110,105,116,105, - 97,108,105,122,101, 32,100,101,102, 97,117,108,116, 32,112, 97,114, 97,109,101, -116,101,114,115, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112, 97,114,115,101, -100, 32, 61, 32,123,125, 10, 32, 32, 32, 32,102,111,114, 32,105, 44,118, 32,105, -110, 32, 98, 97,115,101, 46,112, 97,105,114,115, 40,100,101,102, 97,117,108,116, - 32,111,114, 32,112, 97,114,115,101,100, 41, 32,100,111, 32,112, 97,114,115,101, -100, 91,105, 93, 32, 61, 32,118, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, 32, -101,109,112,116,121, 32,117,114,108, 32,105,115, 32,112, 97,114,115,101,100, 32, -116,111, 32,110,105,108, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,117,114, -108, 32,111,114, 32,117,114,108, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 32, -114,101,116,117,114,110, 32,110,105,108, 44, 32, 34,105,110,118, 97,108,105,100, - 32,117,114,108, 34, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, 32,114,101,109, -111,118,101, 32,119,104,105,116,101,115,112, 97, 99,101, 10, 32, 32, 32, 32, 45, - 45, 32,117,114,108, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, -117,114,108, 44, 32, 34, 37,115, 34, 44, 32, 34, 34, 41, 10, 32, 32, 32, 32, 45, - 45, 32,103,101,116, 32,102,114, 97,103,109,101,110,116, 10, 32, 32, 32, 32,117, -114,108, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,117,114,108, - 44, 32, 34, 35, 40, 46, 42, 41, 36, 34, 44, 32,102,117,110, 99,116,105,111,110, - 40,102, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,112, 97,114,115,101,100, 46,102, -114, 97,103,109,101,110,116, 32, 61, 32,102, 10, 32, 32, 32, 32, 32, 32, 32, 32, -114,101,116,117,114,110, 32, 34, 34, 10, 32, 32, 32, 32,101,110,100, 41, 10, 32, - 32, 32, 32, 45, 45, 32,103,101,116, 32,115, 99,104,101,109,101, 10, 32, 32, 32, - 32,117,114,108, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,117, -114,108, 44, 32, 34, 94, 40, 91, 37,119, 93, 91, 37,119, 37, 43, 37, 45, 37, 46, - 93, 42, 41, 37, 58, 34, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,102,117,110, 99, -116,105,111,110, 40,115, 41, 32,112, 97,114,115,101,100, 46,115, 99,104,101,109, -101, 32, 61, 32,115, 59, 32,114,101,116,117,114,110, 32, 34, 34, 32,101,110,100, - 41, 10, 32, 32, 32, 32, 45, 45, 32,103,101,116, 32, 97,117,116,104,111,114,105, -116,121, 10, 32, 32, 32, 32,117,114,108, 32, 61, 32,115,116,114,105,110,103, 46, -103,115,117, 98, 40,117,114,108, 44, 32, 34, 94, 47, 47, 40, 91, 94, 47, 93, 42, - 41, 34, 44, 32,102,117,110, 99,116,105,111,110, 40,110, 41, 10, 32, 32, 32, 32, - 32, 32, 32, 32,112, 97,114,115,101,100, 46, 97,117,116,104,111,114,105,116,121, - 32, 61, 32,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, - 34, 34, 10, 32, 32, 32, 32,101,110,100, 41, 10, 32, 32, 32, 32, 45, 45, 32,103, -101,116, 32,113,117,101,114,121, 32,115,116,114,105,110,103,105,110,103, 10, 32, - 32, 32, 32,117,114,108, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, - 40,117,114,108, 44, 32, 34, 37, 63, 40, 46, 42, 41, 34, 44, 32,102,117,110, 99, -116,105,111,110, 40,113, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,112, 97,114,115, -101,100, 46,113,117,101,114,121, 32, 61, 32,113, 10, 32, 32, 32, 32, 32, 32, 32, - 32,114,101,116,117,114,110, 32, 34, 34, 10, 32, 32, 32, 32,101,110,100, 41, 10, - 32, 32, 32, 32, 45, 45, 32,103,101,116, 32,112, 97,114, 97,109,115, 10, 32, 32, - 32, 32,117,114,108, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, -117,114,108, 44, 32, 34, 37, 59, 40, 46, 42, 41, 34, 44, 32,102,117,110, 99,116, -105,111,110, 40,112, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,112, 97,114,115,101, -100, 46,112, 97,114, 97,109,115, 32, 61, 32,112, 10, 32, 32, 32, 32, 32, 32, 32, - 32,114,101,116,117,114,110, 32, 34, 34, 10, 32, 32, 32, 32,101,110,100, 41, 10, - 32, 32, 32, 32, 45, 45, 32,112, 97,116,104, 32,105,115, 32,119,104, 97,116,101, -118,101,114, 32,119, 97,115, 32,108,101,102,116, 10, 32, 32, 32, 32,105,102, 32, -117,114,108, 32,126, 61, 32, 34, 34, 32,116,104,101,110, 32,112, 97,114,115,101, -100, 46,112, 97,116,104, 32, 61, 32,117,114,108, 32,101,110,100, 10, 32, 32, 32, - 32,108,111, 99, 97,108, 32, 97,117,116,104,111,114,105,116,121, 32, 61, 32,112, - 97,114,115,101,100, 46, 97,117,116,104,111,114,105,116,121, 10, 32, 32, 32, 32, -105,102, 32,110,111,116, 32, 97,117,116,104,111,114,105,116,121, 32,116,104,101, -110, 32,114,101,116,117,114,110, 32,112, 97,114,115,101,100, 32,101,110,100, 10, - 32, 32, 32, 32, 97,117,116,104,111,114,105,116,121, 32, 61, 32,115,116,114,105, -110,103, 46,103,115,117, 98, 40, 97,117,116,104,111,114,105,116,121, 44, 34, 94, - 40, 91, 94, 64, 93, 42, 41, 64, 34, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,102, -117,110, 99,116,105,111,110, 40,117, 41, 32,112, 97,114,115,101,100, 46,117,115, -101,114,105,110,102,111, 32, 61, 32,117, 59, 32,114,101,116,117,114,110, 32, 34, - 34, 32,101,110,100, 41, 10, 32, 32, 32, 32, 97,117,116,104,111,114,105,116,121, + 45, 45, 45, 45, 45, 10,102,117,110, 99,116,105,111,110, 32, 95, 77, 46,112, 97, +114,115,101, 40,117,114,108, 44, 32,100,101,102, 97,117,108,116, 41, 10, 32, 32, + 32, 32, 45, 45, 32,105,110,105,116,105, 97,108,105,122,101, 32,100,101,102, 97, +117,108,116, 32,112, 97,114, 97,109,101,116,101,114,115, 10, 32, 32, 32, 32,108, +111, 99, 97,108, 32,112, 97,114,115,101,100, 32, 61, 32,123,125, 10, 32, 32, 32, + 32,102,111,114, 32,105, 44,118, 32,105,110, 32, 98, 97,115,101, 46,112, 97,105, +114,115, 40,100,101,102, 97,117,108,116, 32,111,114, 32,112, 97,114,115,101,100, + 41, 32,100,111, 32,112, 97,114,115,101,100, 91,105, 93, 32, 61, 32,118, 32,101, +110,100, 10, 32, 32, 32, 32, 45, 45, 32,101,109,112,116,121, 32,117,114,108, 32, +105,115, 32,112, 97,114,115,101,100, 32,116,111, 32,110,105,108, 10, 32, 32, 32, + 32,105,102, 32,110,111,116, 32,117,114,108, 32,111,114, 32,117,114,108, 32, 61, + 61, 32, 34, 34, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, + 44, 32, 34,105,110,118, 97,108,105,100, 32,117,114,108, 34, 32,101,110,100, 10, + 32, 32, 32, 32, 45, 45, 32,114,101,109,111,118,101, 32,119,104,105,116,101,115, +112, 97, 99,101, 10, 32, 32, 32, 32, 45, 45, 32,117,114,108, 32, 61, 32,115,116, +114,105,110,103, 46,103,115,117, 98, 40,117,114,108, 44, 32, 34, 37,115, 34, 44, + 32, 34, 34, 41, 10, 32, 32, 32, 32, 45, 45, 32,103,101,116, 32,102,114, 97,103, +109,101,110,116, 10, 32, 32, 32, 32,117,114,108, 32, 61, 32,115,116,114,105,110, +103, 46,103,115,117, 98, 40,117,114,108, 44, 32, 34, 35, 40, 46, 42, 41, 36, 34, + 44, 32,102,117,110, 99,116,105,111,110, 40,102, 41, 10, 32, 32, 32, 32, 32, 32, + 32, 32,112, 97,114,115,101,100, 46,102,114, 97,103,109,101,110,116, 32, 61, 32, +102, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 34, 34, 10, + 32, 32, 32, 32,101,110,100, 41, 10, 32, 32, 32, 32, 45, 45, 32,103,101,116, 32, +115, 99,104,101,109,101, 10, 32, 32, 32, 32,117,114,108, 32, 61, 32,115,116,114, +105,110,103, 46,103,115,117, 98, 40,117,114,108, 44, 32, 34, 94, 40, 91, 37,119, + 93, 91, 37,119, 37, 43, 37, 45, 37, 46, 93, 42, 41, 37, 58, 34, 44, 10, 32, 32, + 32, 32, 32, 32, 32, 32,102,117,110, 99,116,105,111,110, 40,115, 41, 32,112, 97, +114,115,101,100, 46,115, 99,104,101,109,101, 32, 61, 32,115, 59, 32,114,101,116, +117,114,110, 32, 34, 34, 32,101,110,100, 41, 10, 32, 32, 32, 32, 45, 45, 32,103, +101,116, 32, 97,117,116,104,111,114,105,116,121, 10, 32, 32, 32, 32,117,114,108, + 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,117,114,108, 44, 32, + 34, 94, 47, 47, 40, 91, 94, 47, 93, 42, 41, 34, 44, 32,102,117,110, 99,116,105, +111,110, 40,110, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,112, 97,114,115,101,100, + 46, 97,117,116,104,111,114,105,116,121, 32, 61, 32,110, 10, 32, 32, 32, 32, 32, + 32, 32, 32,114,101,116,117,114,110, 32, 34, 34, 10, 32, 32, 32, 32,101,110,100, + 41, 10, 32, 32, 32, 32, 45, 45, 32,103,101,116, 32,113,117,101,114,121, 32,115, +116,114,105,110,103, 10, 32, 32, 32, 32,117,114,108, 32, 61, 32,115,116,114,105, +110,103, 46,103,115,117, 98, 40,117,114,108, 44, 32, 34, 37, 63, 40, 46, 42, 41, + 34, 44, 32,102,117,110, 99,116,105,111,110, 40,113, 41, 10, 32, 32, 32, 32, 32, + 32, 32, 32,112, 97,114,115,101,100, 46,113,117,101,114,121, 32, 61, 32,113, 10, + 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 34, 34, 10, 32, 32, + 32, 32,101,110,100, 41, 10, 32, 32, 32, 32, 45, 45, 32,103,101,116, 32,112, 97, +114, 97,109,115, 10, 32, 32, 32, 32,117,114,108, 32, 61, 32,115,116,114,105,110, +103, 46,103,115,117, 98, 40,117,114,108, 44, 32, 34, 37, 59, 40, 46, 42, 41, 34, + 44, 32,102,117,110, 99,116,105,111,110, 40,112, 41, 10, 32, 32, 32, 32, 32, 32, + 32, 32,112, 97,114,115,101,100, 46,112, 97,114, 97,109,115, 32, 61, 32,112, 10, + 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 34, 34, 10, 32, 32, + 32, 32,101,110,100, 41, 10, 32, 32, 32, 32, 45, 45, 32,112, 97,116,104, 32,105, +115, 32,119,104, 97,116,101,118,101,114, 32,119, 97,115, 32,108,101,102,116, 10, + 32, 32, 32, 32,105,102, 32,117,114,108, 32,126, 61, 32, 34, 34, 32,116,104,101, +110, 32,112, 97,114,115,101,100, 46,112, 97,116,104, 32, 61, 32,117,114,108, 32, +101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 97,117,116,104,111,114, +105,116,121, 32, 61, 32,112, 97,114,115,101,100, 46, 97,117,116,104,111,114,105, +116,121, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32, 97,117,116,104,111,114, +105,116,121, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,112, 97,114,115, +101,100, 32,101,110,100, 10, 32, 32, 32, 32, 97,117,116,104,111,114,105,116,121, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, 97,117,116,104,111, -114,105,116,121, 44, 32, 34, 58, 40, 91, 94, 58, 93, 42, 41, 36, 34, 44, 10, 32, - 32, 32, 32, 32, 32, 32, 32,102,117,110, 99,116,105,111,110, 40,112, 41, 32,112, - 97,114,115,101,100, 46,112,111,114,116, 32, 61, 32,112, 59, 32,114,101,116,117, -114,110, 32, 34, 34, 32,101,110,100, 41, 10, 32, 32, 32, 32,105,102, 32, 97,117, -116,104,111,114,105,116,121, 32,126, 61, 32, 34, 34, 32,116,104,101,110, 32,112, - 97,114,115,101,100, 46,104,111,115,116, 32, 61, 32, 97,117,116,104,111,114,105, -116,121, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,117,115,101, -114,105,110,102,111, 32, 61, 32,112, 97,114,115,101,100, 46,117,115,101,114,105, -110,102,111, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,117,115,101,114,105, -110,102,111, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,112, 97,114,115, -101,100, 32,101,110,100, 10, 32, 32, 32, 32,117,115,101,114,105,110,102,111, 32, - 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,117,115,101,114,105,110, -102,111, 44, 32, 34, 58, 40, 91, 94, 58, 93, 42, 41, 36, 34, 44, 10, 32, 32, 32, - 32, 32, 32, 32, 32,102,117,110, 99,116,105,111,110, 40,112, 41, 32,112, 97,114, -115,101,100, 46,112, 97,115,115,119,111,114,100, 32, 61, 32,112, 59, 32,114,101, -116,117,114,110, 32, 34, 34, 32,101,110,100, 41, 10, 32, 32, 32, 32,112, 97,114, -115,101,100, 46,117,115,101,114, 32, 61, 32,117,115,101,114,105,110,102,111, 10, - 32, 32, 32, 32,114,101,116,117,114,110, 32,112, 97,114,115,101,100, 10,101,110, -100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +114,105,116,121, 44, 34, 94, 40, 91, 94, 64, 93, 42, 41, 64, 34, 44, 10, 32, 32, + 32, 32, 32, 32, 32, 32,102,117,110, 99,116,105,111,110, 40,117, 41, 32,112, 97, +114,115,101,100, 46,117,115,101,114,105,110,102,111, 32, 61, 32,117, 59, 32,114, +101,116,117,114,110, 32, 34, 34, 32,101,110,100, 41, 10, 32, 32, 32, 32, 97,117, +116,104,111,114,105,116,121, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, + 98, 40, 97,117,116,104,111,114,105,116,121, 44, 32, 34, 58, 40, 91, 94, 58, 37, + 93, 93, 42, 41, 36, 34, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,102,117,110, 99, +116,105,111,110, 40,112, 41, 32,112, 97,114,115,101,100, 46,112,111,114,116, 32, + 61, 32,112, 59, 32,114,101,116,117,114,110, 32, 34, 34, 32,101,110,100, 41, 10, + 32, 32, 32, 32,105,102, 32, 97,117,116,104,111,114,105,116,121, 32,126, 61, 32, + 34, 34, 32,116,104,101,110, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32, + 73, 80,118, 54, 63, 10, 32, 32, 32, 32, 32, 32, 32, 32,112, 97,114,115,101,100, + 46,104,111,115,116, 32, 61, 32,115,116,114,105,110,103, 46,109, 97,116, 99,104, + 40, 97,117,116,104,111,114,105,116,121, 44, 32, 34, 94, 37, 91, 40, 46, 43, 41, + 37, 93, 36, 34, 41, 32,111,114, 32, 97,117,116,104,111,114,105,116,121, 32, 10, + 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,117,115, +101,114,105,110,102,111, 32, 61, 32,112, 97,114,115,101,100, 46,117,115,101,114, +105,110,102,111, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,117,115,101,114, +105,110,102,111, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,112, 97,114, +115,101,100, 32,101,110,100, 10, 32, 32, 32, 32,117,115,101,114,105,110,102,111, + 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,117,115,101,114,105, +110,102,111, 44, 32, 34, 58, 40, 91, 94, 58, 93, 42, 41, 36, 34, 44, 10, 32, 32, + 32, 32, 32, 32, 32, 32,102,117,110, 99,116,105,111,110, 40,112, 41, 32,112, 97, +114,115,101,100, 46,112, 97,115,115,119,111,114,100, 32, 61, 32,112, 59, 32,114, +101,116,117,114,110, 32, 34, 34, 32,101,110,100, 41, 10, 32, 32, 32, 32,112, 97, +114,115,101,100, 46,117,115,101,114, 32, 61, 32,117,115,101,114,105,110,102,111, + 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,112, 97,114,115,101,100, 10,101, +110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 10, 45, 45, 32, 82,101, 98,117,105,108,100,115, 32, 97, 32,112, 97,114,115,101, -100, 32, 85, 82, 76, 32,102,114,111,109, 32,105,116,115, 32, 99,111,109,112,111, -110,101,110,116,115, 46, 10, 45, 45, 32, 67,111,109,112,111,110,101,110,116,115, - 32, 97,114,101, 32,112,114,111,116,101, 99,116,101,100, 32,105,102, 32, 97,110, -121, 32,114,101,115,101,114,118,101,100, 32,111,114, 32,117,110, 97,108,108,111, -119,101,100, 32, 99,104, 97,114, 97, 99,116,101,114,115, 32, 97,114,101, 32,102, -111,117,110,100, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, 32, 32,112, - 97,114,115,101,100, 58, 32,112, 97,114,115,101,100, 32, 85, 82, 76, 44, 32, 97, -115, 32,114,101,116,117,114,110,101,100, 32, 98,121, 32,112, 97,114,115,101, 10, - 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32, 32, 32, 97, 32,115,116, -114,105,110,103,105,110,103, 32,119,105,116,104, 32,116,104,101, 32, 99,111,114, -114,101,115,112,111,110,100,105,110,103, 32, 85, 82, 76, 10, 45, 45, 45, 45, 45, + 45, 10, 45, 45, 32, 82,101, 98,117,105,108,100,115, 32, 97, 32,112, 97,114,115, +101,100, 32, 85, 82, 76, 32,102,114,111,109, 32,105,116,115, 32, 99,111,109,112, +111,110,101,110,116,115, 46, 10, 45, 45, 32, 67,111,109,112,111,110,101,110,116, +115, 32, 97,114,101, 32,112,114,111,116,101, 99,116,101,100, 32,105,102, 32, 97, +110,121, 32,114,101,115,101,114,118,101,100, 32,111,114, 32,117,110, 97,108,108, +111,119,101,100, 32, 99,104, 97,114, 97, 99,116,101,114,115, 32, 97,114,101, 32, +102,111,117,110,100, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, 32, 32, +112, 97,114,115,101,100, 58, 32,112, 97,114,115,101,100, 32, 85, 82, 76, 44, 32, + 97,115, 32,114,101,116,117,114,110,101,100, 32, 98,121, 32,112, 97,114,115,101, + 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32, 32, 32, 97, 32,115, +116,114,105,110,103,105,110,103, 32,119,105,116,104, 32,116,104,101, 32, 99,111, +114,114,101,115,112,111,110,100,105,110,103, 32, 85, 82, 76, 10, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,102,117,110, 99,116,105, +111,110, 32, 95, 77, 46, 98,117,105,108,100, 40,112, 97,114,115,101,100, 41, 10, + 32, 32, 32, 32,108,111, 99, 97,108, 32,112,112, 97,116,104, 32, 61, 32, 95, 77, + 46,112, 97,114,115,101, 95,112, 97,116,104, 40,112, 97,114,115,101,100, 46,112, + 97,116,104, 32,111,114, 32, 34, 34, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, + 32,117,114,108, 32, 61, 32, 95, 77, 46, 98,117,105,108,100, 95,112, 97,116,104, + 40,112,112, 97,116,104, 41, 10, 32, 32, 32, 32,105,102, 32,112, 97,114,115,101, +100, 46,112, 97,114, 97,109,115, 32,116,104,101,110, 32,117,114,108, 32, 61, 32, +117,114,108, 32, 46, 46, 32, 34, 59, 34, 32, 46, 46, 32,112, 97,114,115,101,100, + 46,112, 97,114, 97,109,115, 32,101,110,100, 10, 32, 32, 32, 32,105,102, 32,112, + 97,114,115,101,100, 46,113,117,101,114,121, 32,116,104,101,110, 32,117,114,108, + 32, 61, 32,117,114,108, 32, 46, 46, 32, 34, 63, 34, 32, 46, 46, 32,112, 97,114, +115,101,100, 46,113,117,101,114,121, 32,101,110,100, 10, 32, 32, 32, 32,108,111, + 99, 97,108, 32, 97,117,116,104,111,114,105,116,121, 32, 61, 32,112, 97,114,115, +101,100, 46, 97,117,116,104,111,114,105,116,121, 10, 32, 32, 32, 32,105,102, 32, +112, 97,114,115,101,100, 46,104,111,115,116, 32,116,104,101,110, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 97,117,116,104,111,114,105,116,121, 32, 61, 32,112, 97,114, +115,101,100, 46,104,111,115,116, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, +115,116,114,105,110,103, 46,102,105,110,100, 40, 97,117,116,104,111,114,105,116, +121, 44, 32, 34, 58, 34, 41, 32,116,104,101,110, 32, 45, 45, 32, 73, 80,118, 54, + 63, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 97,117,116,104,111,114, +105,116,121, 32, 61, 32, 34, 91, 34, 32, 46, 46, 32, 97,117,116,104,111,114,105, +116,121, 32, 46, 46, 32, 34, 93, 34, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110, +100, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,112, 97,114,115,101,100, 46, +112,111,114,116, 32,116,104,101,110, 32, 97,117,116,104,111,114,105,116,121, 32, + 61, 32, 97,117,116,104,111,114,105,116,121, 32, 46, 46, 32, 34, 58, 34, 32, 46, + 46, 32,112, 97,114,115,101,100, 46,112,111,114,116, 32,101,110,100, 10, 32, 32, + 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,117,115,101,114,105,110,102,111, + 32, 61, 32,112, 97,114,115,101,100, 46,117,115,101,114,105,110,102,111, 10, 32, + 32, 32, 32, 32, 32, 32, 32,105,102, 32,112, 97,114,115,101,100, 46,117,115,101, +114, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,117, +115,101,114,105,110,102,111, 32, 61, 32,112, 97,114,115,101,100, 46,117,115,101, +114, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,112, 97,114, +115,101,100, 46,112, 97,115,115,119,111,114,100, 32,116,104,101,110, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,117,115,101,114,105,110, +102,111, 32, 61, 32,117,115,101,114,105,110,102,111, 32, 46, 46, 32, 34, 58, 34, + 32, 46, 46, 32,112, 97,114,115,101,100, 46,112, 97,115,115,119,111,114,100, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, + 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,117, +115,101,114,105,110,102,111, 32,116,104,101,110, 32, 97,117,116,104,111,114,105, +116,121, 32, 61, 32,117,115,101,114,105,110,102,111, 32, 46, 46, 32, 34, 64, 34, + 32, 46, 46, 32, 97,117,116,104,111,114,105,116,121, 32,101,110,100, 10, 32, 32, + 32, 32,101,110,100, 10, 32, 32, 32, 32,105,102, 32, 97,117,116,104,111,114,105, +116,121, 32,116,104,101,110, 32,117,114,108, 32, 61, 32, 34, 47, 47, 34, 32, 46, + 46, 32, 97,117,116,104,111,114,105,116,121, 32, 46, 46, 32,117,114,108, 32,101, +110,100, 10, 32, 32, 32, 32,105,102, 32,112, 97,114,115,101,100, 46,115, 99,104, +101,109,101, 32,116,104,101,110, 32,117,114,108, 32, 61, 32,112, 97,114,115,101, +100, 46,115, 99,104,101,109,101, 32, 46, 46, 32, 34, 58, 34, 32, 46, 46, 32,117, +114,108, 32,101,110,100, 10, 32, 32, 32, 32,105,102, 32,112, 97,114,115,101,100, + 46,102,114, 97,103,109,101,110,116, 32,116,104,101,110, 32,117,114,108, 32, 61, + 32,117,114,108, 32, 46, 46, 32, 34, 35, 34, 32, 46, 46, 32,112, 97,114,115,101, +100, 46,102,114, 97,103,109,101,110,116, 32,101,110,100, 10, 32, 32, 32, 32, 45, + 45, 32,117,114,108, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, +117,114,108, 44, 32, 34, 37,115, 34, 44, 32, 34, 34, 41, 10, 32, 32, 32, 32,114, +101,116,117,114,110, 32,117,114,108, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 66,117,105,108, +100,115, 32, 97, 32, 97, 98,115,111,108,117,116,101, 32, 85, 82, 76, 32,102,114, +111,109, 32, 97, 32, 98, 97,115,101, 32, 97,110,100, 32, 97, 32,114,101,108, 97, +116,105,118,101, 32, 85, 82, 76, 32, 97, 99, 99,111,114,100,105,110,103, 32,116, +111, 32, 82, 70, 67, 32, 50, 51, 57, 54, 10, 45, 45, 32, 73,110,112,117,116, 10, + 45, 45, 32, 32, 32, 98, 97,115,101, 95,117,114,108, 10, 45, 45, 32, 32, 32,114, +101,108, 97,116,105,118,101, 95,117,114,108, 10, 45, 45, 32, 82,101,116,117,114, +110,115, 10, 45, 45, 32, 32, 32, 99,111,114,114,101,115,112,111,110,100,105,110, +103, 32, 97, 98,115,111,108,117,116,101, 32,117,114,108, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,102,117,110, 99,116,105,111, -110, 32, 98,117,105,108,100, 40,112, 97,114,115,101,100, 41, 10, 32, 32, 32, 32, -108,111, 99, 97,108, 32,112,112, 97,116,104, 32, 61, 32,112, 97,114,115,101, 95, -112, 97,116,104, 40,112, 97,114,115,101,100, 46,112, 97,116,104, 32,111,114, 32, - 34, 34, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,117,114,108, 32, 61, 32, - 98,117,105,108,100, 95,112, 97,116,104, 40,112,112, 97,116,104, 41, 10, 32, 32, - 32, 32,105,102, 32,112, 97,114,115,101,100, 46,112, 97,114, 97,109,115, 32,116, -104,101,110, 32,117,114,108, 32, 61, 32,117,114,108, 32, 46, 46, 32, 34, 59, 34, - 32, 46, 46, 32,112, 97,114,115,101,100, 46,112, 97,114, 97,109,115, 32,101,110, -100, 10, 32, 32, 32, 32,105,102, 32,112, 97,114,115,101,100, 46,113,117,101,114, -121, 32,116,104,101,110, 32,117,114,108, 32, 61, 32,117,114,108, 32, 46, 46, 32, - 34, 63, 34, 32, 46, 46, 32,112, 97,114,115,101,100, 46,113,117,101,114,121, 32, -101,110,100, 10, 9,108,111, 99, 97,108, 32, 97,117,116,104,111,114,105,116,121, - 32, 61, 32,112, 97,114,115,101,100, 46, 97,117,116,104,111,114,105,116,121, 10, - 9,105,102, 32,112, 97,114,115,101,100, 46,104,111,115,116, 32,116,104,101,110, - 10, 9, 9, 97,117,116,104,111,114,105,116,121, 32, 61, 32,112, 97,114,115,101, -100, 46,104,111,115,116, 10, 9, 9,105,102, 32,112, 97,114,115,101,100, 46,112, -111,114,116, 32,116,104,101,110, 32, 97,117,116,104,111,114,105,116,121, 32, 61, - 32, 97,117,116,104,111,114,105,116,121, 32, 46, 46, 32, 34, 58, 34, 32, 46, 46, - 32,112, 97,114,115,101,100, 46,112,111,114,116, 32,101,110,100, 10, 9, 9,108, -111, 99, 97,108, 32,117,115,101,114,105,110,102,111, 32, 61, 32,112, 97,114,115, -101,100, 46,117,115,101,114,105,110,102,111, 10, 9, 9,105,102, 32,112, 97,114, -115,101,100, 46,117,115,101,114, 32,116,104,101,110, 10, 9, 9, 9,117,115,101, -114,105,110,102,111, 32, 61, 32,112, 97,114,115,101,100, 46,117,115,101,114, 10, - 9, 9, 9,105,102, 32,112, 97,114,115,101,100, 46,112, 97,115,115,119,111,114, -100, 32,116,104,101,110, 10, 9, 9, 9, 9,117,115,101,114,105,110,102,111, 32, - 61, 32,117,115,101,114,105,110,102,111, 32, 46, 46, 32, 34, 58, 34, 32, 46, 46, - 32,112, 97,114,115,101,100, 46,112, 97,115,115,119,111,114,100, 10, 9, 9, 9, -101,110,100, 10, 9, 9,101,110,100, 10, 9, 9,105,102, 32,117,115,101,114,105, -110,102,111, 32,116,104,101,110, 32, 97,117,116,104,111,114,105,116,121, 32, 61, - 32,117,115,101,114,105,110,102,111, 32, 46, 46, 32, 34, 64, 34, 32, 46, 46, 32, - 97,117,116,104,111,114,105,116,121, 32,101,110,100, 10, 9,101,110,100, 10, 32, - 32, 32, 32,105,102, 32, 97,117,116,104,111,114,105,116,121, 32,116,104,101,110, - 32,117,114,108, 32, 61, 32, 34, 47, 47, 34, 32, 46, 46, 32, 97,117,116,104,111, -114,105,116,121, 32, 46, 46, 32,117,114,108, 32,101,110,100, 10, 32, 32, 32, 32, -105,102, 32,112, 97,114,115,101,100, 46,115, 99,104,101,109,101, 32,116,104,101, -110, 32,117,114,108, 32, 61, 32,112, 97,114,115,101,100, 46,115, 99,104,101,109, -101, 32, 46, 46, 32, 34, 58, 34, 32, 46, 46, 32,117,114,108, 32,101,110,100, 10, - 32, 32, 32, 32,105,102, 32,112, 97,114,115,101,100, 46,102,114, 97,103,109,101, -110,116, 32,116,104,101,110, 32,117,114,108, 32, 61, 32,117,114,108, 32, 46, 46, - 32, 34, 35, 34, 32, 46, 46, 32,112, 97,114,115,101,100, 46,102,114, 97,103,109, -101,110,116, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, 32,117,114,108, 32, 61, - 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,117,114,108, 44, 32, 34, 37, -115, 34, 44, 32, 34, 34, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,117, -114,108, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 10, 45, 45, 32, 66,117,105,108,100,115, 32, 97, 32, 97, 98, -115,111,108,117,116,101, 32, 85, 82, 76, 32,102,114,111,109, 32, 97, 32, 98, 97, -115,101, 32, 97,110,100, 32, 97, 32,114,101,108, 97,116,105,118,101, 32, 85, 82, - 76, 32, 97, 99, 99,111,114,100,105,110,103, 32,116,111, 32, 82, 70, 67, 32, 50, - 51, 57, 54, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, 32, 32, 98, 97, -115,101, 95,117,114,108, 10, 45, 45, 32, 32, 32,114,101,108, 97,116,105,118,101, - 95,117,114,108, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32, 32, - 32, 99,111,114,114,101,115,112,111,110,100,105,110,103, 32, 97, 98,115,111,108, -117,116,101, 32,117,114,108, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 10,102,117,110, 99,116,105,111,110, 32, 97, 98,115,111,108, -117,116,101, 40, 98, 97,115,101, 95,117,114,108, 44, 32,114,101,108, 97,116,105, -118,101, 95,117,114,108, 41, 10, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46, -116,121,112,101, 40, 98, 97,115,101, 95,117,114,108, 41, 32, 61, 61, 32, 34,116, - 97, 98,108,101, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, - 97,115,101, 95,112, 97,114,115,101,100, 32, 61, 32, 98, 97,115,101, 95,117,114, -108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115,101, 95,117,114,108, 32, 61, - 32, 98,117,105,108,100, 40, 98, 97,115,101, 95,112, 97,114,115,101,100, 41, 10, - 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115, -101, 95,112, 97,114,115,101,100, 32, 61, 32,112, 97,114,115,101, 40, 98, 97,115, -101, 95,117,114,108, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,108, -111, 99, 97,108, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, - 32, 61, 32,112, 97,114,115,101, 40,114,101,108, 97,116,105,118,101, 95,117,114, -108, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32, 98, 97,115,101, 95,112, - 97,114,115,101,100, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,114,101, -108, 97,116,105,118,101, 95,117,114,108, 10, 32, 32, 32, 32,101,108,115,101,105, -102, 32,110,111,116, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101, -100, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 98, 97,115,101, 95,117, -114,108, 10, 32, 32, 32, 32,101,108,115,101,105,102, 32,114,101,108, 97,116,105, -118,101, 95,112, 97,114,115,101,100, 46,115, 99,104,101,109,101, 32,116,104,101, -110, 32,114,101,116,117,114,110, 32,114,101,108, 97,116,105,118,101, 95,117,114, -108, 10, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,114, -101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 46,115, 99,104,101,109, -101, 32, 61, 32, 98, 97,115,101, 95,112, 97,114,115,101,100, 46,115, 99,104,101, -109,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,101, -108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 46, 97,117,116,104,111,114, -105,116,121, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 46, 97,117,116, -104,111,114,105,116,121, 32, 61, 32, 98, 97,115,101, 95,112, 97,114,115,101,100, - 46, 97,117,116,104,111,114,105,116,121, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32,105,102, 32,110,111,116, 32,114,101,108, 97,116,105,118,101, 95,112, - 97,114,115,101,100, 46,112, 97,116,104, 32,116,104,101,110, 10, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,108, 97,116,105,118,101, - 95,112, 97,114,115,101,100, 46,112, 97,116,104, 32, 61, 32, 98, 97,115,101, 95, -112, 97,114,115,101,100, 46,112, 97,116,104, 10, 32, 32, 32, 32, 32, 32, 32, 32, +110, 32, 95, 77, 46, 97, 98,115,111,108,117,116,101, 40, 98, 97,115,101, 95,117, +114,108, 44, 32,114,101,108, 97,116,105,118,101, 95,117,114,108, 41, 10, 32, 32, + 32, 32,108,111, 99, 97,108, 32, 98, 97,115,101, 95,112, 97,114,115,101,100, 10, + 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46,116,121,112,101, 40, 98, 97,115, +101, 95,117,114,108, 41, 32, 61, 61, 32, 34,116, 97, 98,108,101, 34, 32,116,104, +101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115,101, 95,112, 97,114,115, +101,100, 32, 61, 32, 98, 97,115,101, 95,117,114,108, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 98, 97,115,101, 95,117,114,108, 32, 61, 32, 95, 77, 46, 98,117,105,108, +100, 40, 98, 97,115,101, 95,112, 97,114,115,101,100, 41, 10, 32, 32, 32, 32,101, +108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115,101, 95,112, 97,114, +115,101,100, 32, 61, 32, 95, 77, 46,112, 97,114,115,101, 40, 98, 97,115,101, 95, +117,114,108, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 32, 61, + 32, 95, 77, 46,112, 97,114,115,101, 40,114,101,108, 97,116,105,118,101, 95,117, +114,108, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32, 98, 97,115,101, 95, +112, 97,114,115,101,100, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,114, +101,108, 97,116,105,118,101, 95,117,114,108, 10, 32, 32, 32, 32,101,108,115,101, +105,102, 32,110,111,116, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115, +101,100, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 98, 97,115,101, 95, +117,114,108, 10, 32, 32, 32, 32,101,108,115,101,105,102, 32,114,101,108, 97,116, +105,118,101, 95,112, 97,114,115,101,100, 46,115, 99,104,101,109,101, 32,116,104, +101,110, 32,114,101,116,117,114,110, 32,114,101,108, 97,116,105,118,101, 95,117, +114,108, 10, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, +114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 46,115, 99,104,101, +109,101, 32, 61, 32, 98, 97,115,101, 95,112, 97,114,115,101,100, 46,115, 99,104, +101,109,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114, +101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 46, 97,117,116,104,111, +114,105,116,121, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 46, 97,117, +116,104,111,114,105,116,121, 32, 61, 32, 98, 97,115,101, 95,112, 97,114,115,101, +100, 46, 97,117,116,104,111,114,105,116,121, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,101,108, 97,116,105,118,101, 95, +112, 97,114,115,101,100, 46,112, 97,116,104, 32,116,104,101,110, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,108, 97,116,105,118, +101, 95,112, 97,114,115,101,100, 46,112, 97,116,104, 32, 61, 32, 98, 97,115,101, + 95,112, 97,114,115,101,100, 46,112, 97,116,104, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,101,108, 97, +116,105,118,101, 95,112, 97,114,115,101,100, 46,112, 97,114, 97,109,115, 32,116, +104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 46, +112, 97,114, 97,109,115, 32, 61, 32, 98, 97,115,101, 95,112, 97,114,115,101,100, + 46,112, 97,114, 97,109,115, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,101,108, 97,116, -105,118,101, 95,112, 97,114,115,101,100, 46,112, 97,114, 97,109,115, 32,116,104, -101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 46,112, - 97,114, 97,109,115, 32, 61, 32, 98, 97,115,101, 95,112, 97,114,115,101,100, 46, -112, 97,114, 97,109,115, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,101,108, 97,116,105, -118,101, 95,112, 97,114,115,101,100, 46,113,117,101,114,121, 32,116,104,101,110, - 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, - 46,113,117,101,114,121, 32, 61, 32, 98, 97,115,101, 95,112, 97,114,115,101,100, - 46,113,117,101,114,121, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32,101,108,115,101, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114, -115,101,100, 46,112, 97,116,104, 32, 61, 32, 97, 98,115,111,108,117,116,101, 95, -112, 97,116,104, 40, 98, 97,115,101, 95,112, 97,114,115,101,100, 46,112, 97,116, -104, 32,111,114, 32, 34, 34, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +105,118,101, 95,112, 97,114,115,101,100, 46,113,117,101,114,121, 32,116,104,101, +110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101, +100, 46,113,117,101,114,121, 32, 61, 32, 98, 97,115,101, 95,112, 97,114,115,101, +100, 46,113,117,101,114,121, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,101,108,115,101, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,108, 97,116,105,118,101, 95,112, 97, -114,115,101,100, 46,112, 97,116,104, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, - 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 98,117,105,108,100, 40, -114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 41, 10, 32, 32, 32, - 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +114,115,101,100, 46,112, 97,116,104, 32, 61, 32, 97, 98,115,111,108,117,116,101, + 95,112, 97,116,104, 40, 98, 97,115,101, 95,112, 97,114,115,101,100, 46,112, 97, +116,104, 32,111,114, 32, 34, 34, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,108, 97,116,105,118,101, 95,112, + 97,114,115,101,100, 46,112, 97,116,104, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, + 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 95, 77, 46, 98,117, +105,108,100, 40,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 41, + 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 66,114,101, 97,107,115, 32, 97, 32, -112, 97,116,104, 32,105,110,116,111, 32,105,116,115, 32,115,101,103,109,101,110, -116,115, 44, 32,117,110,101,115, 99, 97,112,105,110,103, 32,116,104,101, 32,115, -101,103,109,101,110,116,115, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, - 32, 32,112, 97,116,104, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, - 32, 32, 32,115,101,103,109,101,110,116, 58, 32, 97, 32,116, 97, 98,108,101, 32, -119,105,116,104, 32,111,110,101, 32,101,110,116,114,121, 32,112,101,114, 32,115, -101,103,109,101,110,116, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 66,114,101, 97,107, +115, 32, 97, 32,112, 97,116,104, 32,105,110,116,111, 32,105,116,115, 32,115,101, +103,109,101,110,116,115, 44, 32,117,110,101,115, 99, 97,112,105,110,103, 32,116, +104,101, 32,115,101,103,109,101,110,116,115, 10, 45, 45, 32, 73,110,112,117,116, + 10, 45, 45, 32, 32, 32,112, 97,116,104, 10, 45, 45, 32, 82,101,116,117,114,110, +115, 10, 45, 45, 32, 32, 32,115,101,103,109,101,110,116, 58, 32, 97, 32,116, 97, + 98,108,101, 32,119,105,116,104, 32,111,110,101, 32,101,110,116,114,121, 32,112, +101,114, 32,115,101,103,109,101,110,116, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 10,102,117,110, 99,116,105,111,110, 32,112, 97,114,115,101, 95, -112, 97,116,104, 40,112, 97,116,104, 41, 10, 9,108,111, 99, 97,108, 32,112, 97, -114,115,101,100, 32, 61, 32,123,125, 10, 9,112, 97,116,104, 32, 61, 32,112, 97, -116,104, 32,111,114, 32, 34, 34, 10, 9, 45, 45,112, 97,116,104, 32, 61, 32,115, -116,114,105,110,103, 46,103,115,117, 98, 40,112, 97,116,104, 44, 32, 34, 37,115, - 34, 44, 32, 34, 34, 41, 10, 9,115,116,114,105,110,103, 46,103,115,117, 98, 40, -112, 97,116,104, 44, 32, 34, 40, 91, 94, 47, 93, 43, 41, 34, 44, 32,102,117,110, - 99,116,105,111,110, 32, 40,115, 41, 32,116, 97, 98,108,101, 46,105,110,115,101, -114,116, 40,112, 97,114,115,101,100, 44, 32,115, 41, 32,101,110,100, 41, 10, 9, -102,111,114, 32,105, 32, 61, 32, 49, 44, 32,116, 97, 98,108,101, 46,103,101,116, -110, 40,112, 97,114,115,101,100, 41, 32,100,111, 10, 9, 9,112, 97,114,115,101, -100, 91,105, 93, 32, 61, 32,117,110,101,115, 99, 97,112,101, 40,112, 97,114,115, -101,100, 91,105, 93, 41, 10, 9,101,110,100, 10, 9,105,102, 32,115,116,114,105, -110,103, 46,115,117, 98, 40,112, 97,116,104, 44, 32, 49, 44, 32, 49, 41, 32, 61, - 61, 32, 34, 47, 34, 32,116,104,101,110, 32,112, 97,114,115,101,100, 46,105,115, - 95, 97, 98,115,111,108,117,116,101, 32, 61, 32, 49, 32,101,110,100, 10, 9,105, -102, 32,115,116,114,105,110,103, 46,115,117, 98, 40,112, 97,116,104, 44, 32, 45, - 49, 44, 32, 45, 49, 41, 32, 61, 61, 32, 34, 47, 34, 32,116,104,101,110, 32,112, - 97,114,115,101,100, 46,105,115, 95,100,105,114,101, 99,116,111,114,121, 32, 61, - 32, 49, 32,101,110,100, 10, 9,114,101,116,117,114,110, 32,112, 97,114,115,101, -100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 10,102,117,110, 99,116,105,111,110, 32, 95, 77, + 46,112, 97,114,115,101, 95,112, 97,116,104, 40,112, 97,116,104, 41, 10, 32, 32, + 32, 32,108,111, 99, 97,108, 32,112, 97,114,115,101,100, 32, 61, 32,123,125, 10, + 32, 32, 32, 32,112, 97,116,104, 32, 61, 32,112, 97,116,104, 32,111,114, 32, 34, + 34, 10, 32, 32, 32, 32, 45, 45,112, 97,116,104, 32, 61, 32,115,116,114,105,110, +103, 46,103,115,117, 98, 40,112, 97,116,104, 44, 32, 34, 37,115, 34, 44, 32, 34, + 34, 41, 10, 32, 32, 32, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,112, + 97,116,104, 44, 32, 34, 40, 91, 94, 47, 93, 43, 41, 34, 44, 32,102,117,110, 99, +116,105,111,110, 32, 40,115, 41, 32,116, 97, 98,108,101, 46,105,110,115,101,114, +116, 40,112, 97,114,115,101,100, 44, 32,115, 41, 32,101,110,100, 41, 10, 32, 32, + 32, 32,102,111,114, 32,105, 32, 61, 32, 49, 44, 32, 35,112, 97,114,115,101,100, + 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32,112, 97,114,115,101,100, 91,105, + 93, 32, 61, 32, 95, 77, 46,117,110,101,115, 99, 97,112,101, 40,112, 97,114,115, +101,100, 91,105, 93, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,105, +102, 32,115,116,114,105,110,103, 46,115,117, 98, 40,112, 97,116,104, 44, 32, 49, + 44, 32, 49, 41, 32, 61, 61, 32, 34, 47, 34, 32,116,104,101,110, 32,112, 97,114, +115,101,100, 46,105,115, 95, 97, 98,115,111,108,117,116,101, 32, 61, 32, 49, 32, +101,110,100, 10, 32, 32, 32, 32,105,102, 32,115,116,114,105,110,103, 46,115,117, + 98, 40,112, 97,116,104, 44, 32, 45, 49, 44, 32, 45, 49, 41, 32, 61, 61, 32, 34, + 47, 34, 32,116,104,101,110, 32,112, 97,114,115,101,100, 46,105,115, 95,100,105, +114,101, 99,116,111,114,121, 32, 61, 32, 49, 32,101,110,100, 10, 32, 32, 32, 32, +114,101,116,117,114,110, 32,112, 97,114,115,101,100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 10, 45, 45, 32, 66,117,105,108,100,115, 32, 97, 32,112, 97,116, -104, 32, 99,111,109,112,111,110,101,110,116, 32,102,114,111,109, 32,105,116,115, - 32,115,101,103,109,101,110,116,115, 44, 32,101,115, 99, 97,112,105,110,103, 32, -112,114,111,116,101, 99,116,101,100, 32, 99,104, 97,114, 97, 99,116,101,114,115, - 46, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, 32, 32,112, 97,114,115, -101,100, 58, 32,112, 97,116,104, 32,115,101,103,109,101,110,116,115, 10, 45, 45, - 32, 32, 32,117,110,115, 97,102,101, 58, 32,105,102, 32,116,114,117,101, 44, 32, -115,101,103,109,101,110,116,115, 32, 97,114,101, 32,110,111,116, 32,112,114,111, -116,101, 99,116,101,100, 32, 98,101,102,111,114,101, 32,112, 97,116,104, 32,105, -115, 32, 98,117,105,108,116, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, - 45, 32, 32, 32,112, 97,116,104, 58, 32, 99,111,114,114,101,115,112,111,110,100, -105,110,103, 32,112, 97,116,104, 32,115,116,114,105,110,103,105,110,103, 10, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, + 66,117,105,108,100,115, 32, 97, 32,112, 97,116,104, 32, 99,111,109,112,111,110, +101,110,116, 32,102,114,111,109, 32,105,116,115, 32,115,101,103,109,101,110,116, +115, 44, 32,101,115, 99, 97,112,105,110,103, 32,112,114,111,116,101, 99,116,101, +100, 32, 99,104, 97,114, 97, 99,116,101,114,115, 46, 10, 45, 45, 32, 73,110,112, +117,116, 10, 45, 45, 32, 32, 32,112, 97,114,115,101,100, 58, 32,112, 97,116,104, + 32,115,101,103,109,101,110,116,115, 10, 45, 45, 32, 32, 32,117,110,115, 97,102, +101, 58, 32,105,102, 32,116,114,117,101, 44, 32,115,101,103,109,101,110,116,115, + 32, 97,114,101, 32,110,111,116, 32,112,114,111,116,101, 99,116,101,100, 32, 98, +101,102,111,114,101, 32,112, 97,116,104, 32,105,115, 32, 98,117,105,108,116, 10, + 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32, 32, 32,112, 97,116,104, + 58, 32, 99,111,114,114,101,115,112,111,110,100,105,110,103, 32,112, 97,116,104, + 32,115,116,114,105,110,103,105,110,103, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,102,117,110, - 99,116,105,111,110, 32, 98,117,105,108,100, 95,112, 97,116,104, 40,112, 97,114, -115,101,100, 44, 32,117,110,115, 97,102,101, 41, 10, 9,108,111, 99, 97,108, 32, -112, 97,116,104, 32, 61, 32, 34, 34, 10, 9,108,111, 99, 97,108, 32,110, 32, 61, - 32,116, 97, 98,108,101, 46,103,101,116,110, 40,112, 97,114,115,101,100, 41, 10, - 9,105,102, 32,117,110,115, 97,102,101, 32,116,104,101,110, 10, 9, 9,102,111, -114, 32,105, 32, 61, 32, 49, 44, 32,110, 45, 49, 32,100,111, 10, 9, 9, 9,112, - 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46, 46, 32,112, 97,114,115,101,100, - 91,105, 93, 10, 9, 9, 9,112, 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46, - 46, 32, 34, 47, 34, 10, 9, 9,101,110,100, 10, 9, 9,105,102, 32,110, 32, 62, - 32, 48, 32,116,104,101,110, 10, 9, 9, 9,112, 97,116,104, 32, 61, 32,112, 97, -116,104, 32, 46, 46, 32,112, 97,114,115,101,100, 91,110, 93, 10, 9, 9, 9,105, -102, 32,112, 97,114,115,101,100, 46,105,115, 95,100,105,114,101, 99,116,111,114, -121, 32,116,104,101,110, 32,112, 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46, - 46, 32, 34, 47, 34, 32,101,110,100, 10, 9, 9,101,110,100, 10, 9,101,108,115, -101, 10, 9, 9,102,111,114, 32,105, 32, 61, 32, 49, 44, 32,110, 45, 49, 32,100, -111, 10, 9, 9, 9,112, 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46, 46, 32, -112,114,111,116,101, 99,116, 95,115,101,103,109,101,110,116, 40,112, 97,114,115, -101,100, 91,105, 93, 41, 10, 9, 9, 9,112, 97,116,104, 32, 61, 32,112, 97,116, -104, 32, 46, 46, 32, 34, 47, 34, 10, 9, 9,101,110,100, 10, 9, 9,105,102, 32, -110, 32, 62, 32, 48, 32,116,104,101,110, 10, 9, 9, 9,112, 97,116,104, 32, 61, - 32,112, 97,116,104, 32, 46, 46, 32,112,114,111,116,101, 99,116, 95,115,101,103, -109,101,110,116, 40,112, 97,114,115,101,100, 91,110, 93, 41, 10, 9, 9, 9,105, -102, 32,112, 97,114,115,101,100, 46,105,115, 95,100,105,114,101, 99,116,111,114, -121, 32,116,104,101,110, 32,112, 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46, - 46, 32, 34, 47, 34, 32,101,110,100, 10, 9, 9,101,110,100, 10, 9,101,110,100, - 10, 9,105,102, 32,112, 97,114,115,101,100, 46,105,115, 95, 97, 98,115,111,108, -117,116,101, 32,116,104,101,110, 32,112, 97,116,104, 32, 61, 32, 34, 47, 34, 32, - 46, 46, 32,112, 97,116,104, 32,101,110,100, 10, 9,114,101,116,117,114,110, 32, -112, 97,116,104, 10,101,110,100, 10, + 45, 45, 45, 45, 45, 45, 45, 45, 10,102,117,110, 99,116,105,111,110, 32, 95, 77, + 46, 98,117,105,108,100, 95,112, 97,116,104, 40,112, 97,114,115,101,100, 44, 32, +117,110,115, 97,102,101, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112, 97, +116,104, 32, 61, 32, 34, 34, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,110, 32, + 61, 32, 35,112, 97,114,115,101,100, 10, 32, 32, 32, 32,105,102, 32,117,110,115, + 97,102,101, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,102,111,114, + 32,105, 32, 61, 32, 49, 44, 32,110, 45, 49, 32,100,111, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,112, 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46, + 46, 32,112, 97,114,115,101,100, 91,105, 93, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,112, 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46, 46, 32, 34, + 47, 34, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, + 32, 32, 32,105,102, 32,110, 32, 62, 32, 48, 32,116,104,101,110, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32,112, 97,116,104, 32, 61, 32,112, 97,116,104, + 32, 46, 46, 32,112, 97,114,115,101,100, 91,110, 93, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,105,102, 32,112, 97,114,115,101,100, 46,105,115, 95,100, +105,114,101, 99,116,111,114,121, 32,116,104,101,110, 32,112, 97,116,104, 32, 61, + 32,112, 97,116,104, 32, 46, 46, 32, 34, 47, 34, 32,101,110,100, 10, 32, 32, 32, + 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, + 32, 32, 32, 32, 32, 32,102,111,114, 32,105, 32, 61, 32, 49, 44, 32,110, 45, 49, + 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,112, 97,116,104, + 32, 61, 32,112, 97,116,104, 32, 46, 46, 32,112,114,111,116,101, 99,116, 95,115, +101,103,109,101,110,116, 40,112, 97,114,115,101,100, 91,105, 93, 41, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,112, 97,116,104, 32, 61, 32,112, 97,116, +104, 32, 46, 46, 32, 34, 47, 34, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, + 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110, 32, 62, 32, 48, 32,116,104, +101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,112, 97,116,104, 32, + 61, 32,112, 97,116,104, 32, 46, 46, 32,112,114,111,116,101, 99,116, 95,115,101, +103,109,101,110,116, 40,112, 97,114,115,101,100, 91,110, 93, 41, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,112, 97,114,115,101,100, 46,105, +115, 95,100,105,114,101, 99,116,111,114,121, 32,116,104,101,110, 32,112, 97,116, +104, 32, 61, 32,112, 97,116,104, 32, 46, 46, 32, 34, 47, 34, 32,101,110,100, 10, + 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 10, + 32, 32, 32, 32,105,102, 32,112, 97,114,115,101,100, 46,105,115, 95, 97, 98,115, +111,108,117,116,101, 32,116,104,101,110, 32,112, 97,116,104, 32, 61, 32, 34, 47, + 34, 32, 46, 46, 32,112, 97,116,104, 32,101,110,100, 10, 32, 32, 32, 32,114,101, +116,117,114,110, 32,112, 97,116,104, 10,101,110,100, 10, 10,114,101,116,117,114, +110, 32, 95, 77, 10, }; - if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"url.lua")==0) lua_call(L, 0, 0); + if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"url.lua")==0) lua_call(L, 0, LUA_MULTRET); } diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/usocket.c b/love/src/jni/love/src/libraries/luasocket/libluasocket/usocket.c index 70c6e1e3..8adc5738 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/usocket.c +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/usocket.c @@ -4,19 +4,18 @@ * * The code is now interrupt-safe. * The penalty of calling select to avoid busy-wait is only paid when -* the I/O call fail in the first place. -* -* RCS ID: $Id: usocket.c,v 1.38 2007/10/13 23:55:20 diego Exp $ +* the I/O call fail in the first place. \*=========================================================================*/ -#include +#include #include #include "socket.h" +#include "pierror.h" /*-------------------------------------------------------------------------*\ * Wait for readable/writable/connected socket with timeout \*-------------------------------------------------------------------------*/ -#ifdef SOCKET_POLL +#ifndef SOCKET_SELECT #include #define WAITFD_R POLLIN @@ -30,9 +29,9 @@ int socket_waitfd(p_socket ps, int sw, p_timeout tm) { pfd.revents = 0; if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */ do { - int t = (int)(timeout_getretry(tm)*1e3); - ret = poll(&pfd, 1, t >= 0? t: -1); - } while (ret == -1 && errno == EINTR); + int t = (int)(timeout_getretry(tm)*1e3); + ret = poll(&pfd, 1, t >= 0? t: -1); + } while (ret == -1 && errno == EINTR); if (ret == -1) return errno; if (ret == 0) return IO_TIMEOUT; if (sw == WAITFD_C && (pfd.revents & (POLLIN|POLLERR))) return IO_CLOSED; @@ -49,6 +48,7 @@ int socket_waitfd(p_socket ps, int sw, p_timeout tm) { fd_set rfds, wfds, *rp, *wp; struct timeval tv, *tp; double t; + if (*ps >= FD_SETSIZE) return EINVAL; if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */ do { /* must set bits within loop, because select may have modifed them */ @@ -73,7 +73,7 @@ int socket_waitfd(p_socket ps, int sw, p_timeout tm) { /*-------------------------------------------------------------------------*\ -* Initializes module +* Initializes module \*-------------------------------------------------------------------------*/ int socket_open(void) { /* instals a handler to ignore sigpipe or it will crash us */ @@ -82,7 +82,7 @@ int socket_open(void) { } /*-------------------------------------------------------------------------*\ -* Close module +* Close module \*-------------------------------------------------------------------------*/ int socket_close(void) { return 1; @@ -93,7 +93,6 @@ int socket_close(void) { \*-------------------------------------------------------------------------*/ void socket_destroy(p_socket ps) { if (*ps != SOCKET_INVALID) { - socket_setblocking(ps); close(*ps); *ps = SOCKET_INVALID; } @@ -102,7 +101,7 @@ void socket_destroy(p_socket ps) { /*-------------------------------------------------------------------------*\ * Select with timeout control \*-------------------------------------------------------------------------*/ -int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds, +int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds, p_timeout tm) { int ret; do { @@ -121,8 +120,8 @@ int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds, \*-------------------------------------------------------------------------*/ int socket_create(p_socket ps, int domain, int type, int protocol) { *ps = socket(domain, type, protocol); - if (*ps != SOCKET_INVALID) return IO_DONE; - else return errno; + if (*ps != SOCKET_INVALID) return IO_DONE; + else return errno; } /*-------------------------------------------------------------------------*\ @@ -131,29 +130,25 @@ int socket_create(p_socket ps, int domain, int type, int protocol) { int socket_bind(p_socket ps, SA *addr, socklen_t len) { int err = IO_DONE; socket_setblocking(ps); - if (bind(*ps, addr, len) < 0) err = errno; + if (bind(*ps, addr, len) < 0) err = errno; socket_setnonblocking(ps); return err; } /*-------------------------------------------------------------------------*\ -* +* \*-------------------------------------------------------------------------*/ int socket_listen(p_socket ps, int backlog) { - int err = IO_DONE; - socket_setblocking(ps); - if (listen(*ps, backlog)) err = errno; - socket_setnonblocking(ps); + int err = IO_DONE; + if (listen(*ps, backlog)) err = errno; return err; } /*-------------------------------------------------------------------------*\ -* +* \*-------------------------------------------------------------------------*/ void socket_shutdown(p_socket ps, int how) { - socket_setblocking(ps); shutdown(*ps, how); - socket_setnonblocking(ps); } /*-------------------------------------------------------------------------*\ @@ -167,7 +162,7 @@ int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) { do if (connect(*ps, addr, len) == 0) return IO_DONE; while ((err = errno) == EINTR); /* if connection failed immediately, return error code */ - if (err != EINPROGRESS && err != EAGAIN) return err; + if (err != EINPROGRESS && err != EAGAIN) return err; /* zero timeout case optimization */ if (timeout_iszero(tm)) return IO_TIMEOUT; /* wait until we have the result of the connection attempt or timeout */ @@ -182,11 +177,7 @@ int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) { * Accept with timeout \*-------------------------------------------------------------------------*/ int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, p_timeout tm) { - SA daddr; - socklen_t dlen = sizeof(daddr); - if (*ps == SOCKET_INVALID) return IO_CLOSED; - if (!addr) addr = &daddr; - if (!len) len = &dlen; + if (*ps == SOCKET_INVALID) return IO_CLOSED; for ( ;; ) { int err; if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) return IO_DONE; @@ -202,7 +193,7 @@ int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, p_timeout /*-------------------------------------------------------------------------*\ * Send with timeout \*-------------------------------------------------------------------------*/ -int socket_send(p_socket ps, const char *data, size_t count, +int socket_send(p_socket ps, const char *data, size_t count, size_t *sent, p_timeout tm) { int err; @@ -213,14 +204,15 @@ int socket_send(p_socket ps, const char *data, size_t count, for ( ;; ) { long put = (long) send(*ps, data, count, 0); /* if we sent anything, we are done */ - if (put > 0) { + if (put >= 0) { *sent = put; return IO_DONE; } err = errno; - /* send can't really return 0, but EPIPE means the connection was - closed */ - if (put == 0 || err == EPIPE) return IO_CLOSED; + /* EPIPE means the connection was closed */ + if (err == EPIPE) return IO_CLOSED; + /* EPROTOTYPE means the connection is being closed (on Yosemite!)*/ + if (err == EPROTOTYPE) continue; /* we call was interrupted, just try again */ if (err == EINTR) continue; /* if failed fatal reason, report error */ @@ -235,20 +227,21 @@ int socket_send(p_socket ps, const char *data, size_t count, /*-------------------------------------------------------------------------*\ * Sendto with timeout \*-------------------------------------------------------------------------*/ -int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, +int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, SA *addr, socklen_t len, p_timeout tm) { int err; *sent = 0; if (*ps == SOCKET_INVALID) return IO_CLOSED; for ( ;; ) { - long put = (long) sendto(*ps, data, count, 0, addr, len); - if (put > 0) { + long put = (long) sendto(*ps, data, count, 0, addr, len); + if (put >= 0) { *sent = put; return IO_DONE; } err = errno; - if (put == 0 || err == EPIPE) return IO_CLOSED; + if (err == EPIPE) return IO_CLOSED; + if (err == EPROTOTYPE) continue; if (err == EINTR) continue; if (err != EAGAIN) return err; if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; @@ -272,8 +265,8 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm err = errno; if (taken == 0) return IO_CLOSED; if (err == EINTR) continue; - if (err != EAGAIN) return err; - if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; + if (err != EAGAIN) return err; + if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; } return IO_UNKNOWN; } @@ -281,7 +274,7 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm /*-------------------------------------------------------------------------*\ * Recvfrom with timeout \*-------------------------------------------------------------------------*/ -int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, +int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, SA *addr, socklen_t *len, p_timeout tm) { int err; *got = 0; @@ -295,8 +288,70 @@ int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, err = errno; if (taken == 0) return IO_CLOSED; if (err == EINTR) continue; - if (err != EAGAIN) return err; - if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; + if (err != EAGAIN) return err; + if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; + } + return IO_UNKNOWN; +} + + +/*-------------------------------------------------------------------------*\ +* Write with timeout +* +* socket_read and socket_write are cut-n-paste of socket_send and socket_recv, +* with send/recv replaced with write/read. We can't just use write/read +* in the socket version, because behaviour when size is zero is different. +\*-------------------------------------------------------------------------*/ +int socket_write(p_socket ps, const char *data, size_t count, + size_t *sent, p_timeout tm) +{ + int err; + *sent = 0; + /* avoid making system calls on closed sockets */ + if (*ps == SOCKET_INVALID) return IO_CLOSED; + /* loop until we send something or we give up on error */ + for ( ;; ) { + long put = (long) write(*ps, data, count); + /* if we sent anything, we are done */ + if (put >= 0) { + *sent = put; + return IO_DONE; + } + err = errno; + /* EPIPE means the connection was closed */ + if (err == EPIPE) return IO_CLOSED; + /* EPROTOTYPE means the connection is being closed (on Yosemite!)*/ + if (err == EPROTOTYPE) continue; + /* we call was interrupted, just try again */ + if (err == EINTR) continue; + /* if failed fatal reason, report error */ + if (err != EAGAIN) return err; + /* wait until we can send something or we timeout */ + if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; + } + /* can't reach here */ + return IO_UNKNOWN; +} + +/*-------------------------------------------------------------------------*\ +* Read with timeout +* See note for socket_write +\*-------------------------------------------------------------------------*/ +int socket_read(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) { + int err; + *got = 0; + if (*ps == SOCKET_INVALID) return IO_CLOSED; + for ( ;; ) { + long taken = (long) read(*ps, data, count); + if (taken > 0) { + *got = taken; + return IO_DONE; + } + err = errno; + if (taken == 0) return IO_CLOSED; + if (err == EINTR) continue; + if (err != EAGAIN) return err; + if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; } return IO_UNKNOWN; } @@ -320,7 +375,7 @@ void socket_setnonblocking(p_socket ps) { } /*-------------------------------------------------------------------------*\ -* DNS helpers +* DNS helpers \*-------------------------------------------------------------------------*/ int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) { *hp = gethostbyaddr(addr, len, AF_INET); @@ -345,7 +400,7 @@ int socket_gethostbyname(const char *addr, struct hostent **hp) { const char *socket_hoststrerror(int err) { if (err <= 0) return io_strerror(err); switch (err) { - case HOST_NOT_FOUND: return "host not found"; + case HOST_NOT_FOUND: return PIE_HOST_NOT_FOUND; default: return hstrerror(err); } } @@ -353,18 +408,44 @@ const char *socket_hoststrerror(int err) { const char *socket_strerror(int err) { if (err <= 0) return io_strerror(err); switch (err) { - case EADDRINUSE: return "address already in use"; - case EISCONN: return "already connected"; - case EACCES: return "permission denied"; - case ECONNREFUSED: return "connection refused"; - case ECONNABORTED: return "closed"; - case ECONNRESET: return "closed"; - case ETIMEDOUT: return "timeout"; - default: return strerror(errno); + case EADDRINUSE: return PIE_ADDRINUSE; + case EISCONN: return PIE_ISCONN; + case EACCES: return PIE_ACCESS; + case ECONNREFUSED: return PIE_CONNREFUSED; + case ECONNABORTED: return PIE_CONNABORTED; + case ECONNRESET: return PIE_CONNRESET; + case ETIMEDOUT: return PIE_TIMEDOUT; + default: { + return strerror(err); + } } } const char *socket_ioerror(p_socket ps, int err) { (void) ps; return socket_strerror(err); -} +} + +const char *socket_gaistrerror(int err) { + if (err == 0) return NULL; + switch (err) { + case EAI_AGAIN: return PIE_AGAIN; + case EAI_BADFLAGS: return PIE_BADFLAGS; +#ifdef EAI_BADHINTS + case EAI_BADHINTS: return PIE_BADHINTS; +#endif + case EAI_FAIL: return PIE_FAIL; + case EAI_FAMILY: return PIE_FAMILY; + case EAI_MEMORY: return PIE_MEMORY; + case EAI_NONAME: return PIE_NONAME; + case EAI_OVERFLOW: return PIE_OVERFLOW; +#ifdef EAI_PROTOCOL + case EAI_PROTOCOL: return PIE_PROTOCOL; +#endif + case EAI_SERVICE: return PIE_SERVICE; + case EAI_SOCKTYPE: return PIE_SOCKTYPE; + case EAI_SYSTEM: return strerror(errno); + default: return gai_strerror(err); + } +} + diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/usocket.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/usocket.h index f2a89aa0..45f2f99f 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/usocket.h +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/usocket.h @@ -3,8 +3,6 @@ /*=========================================================================*\ * Socket compatibilization module for Unix * LuaSocket toolkit -* -* RCS ID: $Id: usocket.h,v 1.7 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ /*=========================================================================*\ @@ -31,9 +29,30 @@ #include /* TCP options (nagle algorithm disable) */ #include +#include + +#ifndef SO_REUSEPORT +#define SO_REUSEPORT SO_REUSEADDR +#endif + +/* Some platforms use IPV6_JOIN_GROUP instead if + * IPV6_ADD_MEMBERSHIP. The semantics are same, though. */ +#ifndef IPV6_ADD_MEMBERSHIP +#ifdef IPV6_JOIN_GROUP +#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP +#endif /* IPV6_JOIN_GROUP */ +#endif /* !IPV6_ADD_MEMBERSHIP */ + +/* Same with IPV6_DROP_MEMBERSHIP / IPV6_LEAVE_GROUP. */ +#ifndef IPV6_DROP_MEMBERSHIP +#ifdef IPV6_LEAVE_GROUP +#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP +#endif /* IPV6_LEAVE_GROUP */ +#endif /* !IPV6_DROP_MEMBERSHIP */ typedef int t_socket; typedef t_socket *p_socket; +typedef struct sockaddr_storage t_sockaddr_storage; #define SOCKET_INVALID (-1) diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/wsocket.c b/love/src/jni/love/src/libraries/luasocket/libluasocket/wsocket.c index 60225651..8ecb0fc7 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/wsocket.c +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/wsocket.c @@ -3,35 +3,34 @@ * LuaSocket toolkit * * The penalty of calling select to avoid busy-wait is only paid when -* the I/O call fail in the first place. -* -* RCS ID: $Id: wsocket.c,v 1.36 2007/06/11 23:44:54 diego Exp $ +* the I/O call fail in the first place. \*=========================================================================*/ #include #include "socket.h" +#include "pierror.h" /* WinSock doesn't have a strerror... */ static const char *wstrerror(int err); /*-------------------------------------------------------------------------*\ -* Initializes module +* Initializes module \*-------------------------------------------------------------------------*/ int socket_open(void) { WSADATA wsaData; - WORD wVersionRequested = MAKEWORD(2, 0); + WORD wVersionRequested = MAKEWORD(2, 0); int err = WSAStartup(wVersionRequested, &wsaData ); if (err != 0) return 0; if ((LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) && (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)) { WSACleanup(); - return 0; + return 0; } return 1; } /*-------------------------------------------------------------------------*\ -* Close module +* Close module \*-------------------------------------------------------------------------*/ int socket_close(void) { WSACleanup(); @@ -52,10 +51,10 @@ int socket_waitfd(p_socket ps, int sw, p_timeout tm) { struct timeval tv, *tp = NULL; double t; if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */ - if (sw & WAITFD_R) { - FD_ZERO(&rfds); - FD_SET(*ps, &rfds); - rp = &rfds; + if (sw & WAITFD_R) { + FD_ZERO(&rfds); + FD_SET(*ps, &rfds); + rp = &rfds; } if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; } if (sw & WAITFD_C) { FD_ZERO(&efds); FD_SET(*ps, &efds); ep = &efds; } @@ -74,9 +73,9 @@ int socket_waitfd(p_socket ps, int sw, p_timeout tm) { /*-------------------------------------------------------------------------*\ * Select with int timeout in ms \*-------------------------------------------------------------------------*/ -int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds, +int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds, p_timeout tm) { - struct timeval tv; + struct timeval tv; double t = timeout_get(tm); tv.tv_sec = (int) t; tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6); @@ -98,7 +97,7 @@ void socket_destroy(p_socket ps) { } /*-------------------------------------------------------------------------*\ -* +* \*-------------------------------------------------------------------------*/ void socket_shutdown(p_socket ps, int how) { socket_setblocking(ps); @@ -136,10 +135,10 @@ int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) { /* give windows time to set the error (yes, disgusting) */ Sleep(10); /* find out why we failed */ - getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *)&err, &len); + getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *)&err, &len); /* we KNOW there was an error. if 'why' is 0, we will return * "unknown error", but it's not really our fault */ - return err > 0? err: IO_UNKNOWN; + return err > 0? err: IO_UNKNOWN; } else return err; } @@ -156,7 +155,7 @@ int socket_bind(p_socket ps, SA *addr, socklen_t len) { } /*-------------------------------------------------------------------------*\ -* +* \*-------------------------------------------------------------------------*/ int socket_listen(p_socket ps, int backlog) { int err = IO_DONE; @@ -169,35 +168,29 @@ int socket_listen(p_socket ps, int backlog) { /*-------------------------------------------------------------------------*\ * Accept with timeout \*-------------------------------------------------------------------------*/ -int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, +int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, p_timeout tm) { - SA daddr; - socklen_t dlen = sizeof(daddr); if (*ps == SOCKET_INVALID) return IO_CLOSED; - if (!addr) addr = &daddr; - if (!len) len = &dlen; for ( ;; ) { int err; /* try to get client socket */ if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) return IO_DONE; /* find out why we failed */ - err = WSAGetLastError(); + err = WSAGetLastError(); /* if we failed because there was no connectoin, keep trying */ if (err != WSAEWOULDBLOCK && err != WSAECONNABORTED) return err; /* call select to avoid busy wait */ if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; - } - /* can't reach here */ - return IO_UNKNOWN; + } } /*-------------------------------------------------------------------------*\ * Send with timeout -* On windows, if you try to send 10MB, the OS will buffer EVERYTHING -* this can take an awful lot of time and we will end up blocked. +* On windows, if you try to send 10MB, the OS will buffer EVERYTHING +* this can take an awful lot of time and we will end up blocked. * Therefore, whoever calls this function should not pass a huge buffer. \*-------------------------------------------------------------------------*/ -int socket_send(p_socket ps, const char *data, size_t count, +int socket_send(p_socket ps, const char *data, size_t count, size_t *sent, p_timeout tm) { int err; @@ -207,27 +200,25 @@ int socket_send(p_socket ps, const char *data, size_t count, /* loop until we send something or we give up on error */ for ( ;; ) { /* try to send something */ - int put = send(*ps, data, (int) count, 0); + int put = send(*ps, data, (int) count, 0); /* if we sent something, we are done */ if (put > 0) { *sent = put; return IO_DONE; } /* deal with failure */ - err = WSAGetLastError(); + err = WSAGetLastError(); /* we can only proceed if there was no serious error */ if (err != WSAEWOULDBLOCK) return err; /* avoid busy wait */ if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; - } - /* can't reach here */ - return IO_UNKNOWN; + } } /*-------------------------------------------------------------------------*\ * Sendto with timeout \*-------------------------------------------------------------------------*/ -int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, +int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, SA *addr, socklen_t len, p_timeout tm) { int err; @@ -239,18 +230,19 @@ int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, *sent = put; return IO_DONE; } - err = WSAGetLastError(); + err = WSAGetLastError(); if (err != WSAEWOULDBLOCK) return err; if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; - } - return IO_UNKNOWN; + } } /*-------------------------------------------------------------------------*\ * Receive with timeout \*-------------------------------------------------------------------------*/ -int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) { - int err; +int socket_recv(p_socket ps, char *data, size_t count, size_t *got, + p_timeout tm) +{ + int err, prev = IO_DONE; *got = 0; if (*ps == SOCKET_INVALID) return IO_CLOSED; for ( ;; ) { @@ -261,18 +253,25 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm } if (taken == 0) return IO_CLOSED; err = WSAGetLastError(); - if (err != WSAEWOULDBLOCK) return err; + /* On UDP, a connreset simply means the previous send failed. + * So we try again. + * On TCP, it means our socket is now useless, so the error passes. + * (We will loop again, exiting because the same error will happen) */ + if (err != WSAEWOULDBLOCK) { + if (err != WSAECONNRESET || prev == WSAECONNRESET) return err; + prev = err; + } if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; } - return IO_UNKNOWN; } /*-------------------------------------------------------------------------*\ * Recvfrom with timeout \*-------------------------------------------------------------------------*/ -int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, - SA *addr, socklen_t *len, p_timeout tm) { - int err; +int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, + SA *addr, socklen_t *len, p_timeout tm) +{ + int err, prev = IO_DONE; *got = 0; if (*ps == SOCKET_INVALID) return IO_CLOSED; for ( ;; ) { @@ -283,10 +282,16 @@ int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, } if (taken == 0) return IO_CLOSED; err = WSAGetLastError(); - if (err != WSAEWOULDBLOCK) return err; + /* On UDP, a connreset simply means the previous send failed. + * So we try again. + * On TCP, it means our socket is now useless, so the error passes. + * (We will loop again, exiting because the same error will happen) */ + if (err != WSAEWOULDBLOCK) { + if (err != WSAECONNRESET || prev == WSAECONNRESET) return err; + prev = err; + } if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; } - return IO_UNKNOWN; } /*-------------------------------------------------------------------------*\ @@ -306,7 +311,7 @@ void socket_setnonblocking(p_socket ps) { } /*-------------------------------------------------------------------------*\ -* DNS helpers +* DNS helpers \*-------------------------------------------------------------------------*/ int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) { *hp = gethostbyaddr(addr, len, AF_INET); @@ -326,34 +331,34 @@ int socket_gethostbyname(const char *addr, struct hostent **hp) { const char *socket_hoststrerror(int err) { if (err <= 0) return io_strerror(err); switch (err) { - case WSAHOST_NOT_FOUND: return "host not found"; - default: return wstrerror(err); + case WSAHOST_NOT_FOUND: return PIE_HOST_NOT_FOUND; + default: return wstrerror(err); } } const char *socket_strerror(int err) { if (err <= 0) return io_strerror(err); switch (err) { - case WSAEADDRINUSE: return "address already in use"; - case WSAECONNREFUSED: return "connection refused"; - case WSAEISCONN: return "already connected"; - case WSAEACCES: return "permission denied"; - case WSAECONNABORTED: return "closed"; - case WSAECONNRESET: return "closed"; - case WSAETIMEDOUT: return "timeout"; + case WSAEADDRINUSE: return PIE_ADDRINUSE; + case WSAECONNREFUSED : return PIE_CONNREFUSED; + case WSAEISCONN: return PIE_ISCONN; + case WSAEACCES: return PIE_ACCESS; + case WSAECONNABORTED: return PIE_CONNABORTED; + case WSAECONNRESET: return PIE_CONNRESET; + case WSAETIMEDOUT: return PIE_TIMEDOUT; default: return wstrerror(err); } } const char *socket_ioerror(p_socket ps, int err) { - (void) ps; - return socket_strerror(err); + (void) ps; + return socket_strerror(err); } static const char *wstrerror(int err) { switch (err) { case WSAEINTR: return "Interrupted function call"; - case WSAEACCES: return "Permission denied"; + case WSAEACCES: return PIE_ACCESS; // "Permission denied"; case WSAEFAULT: return "Bad address"; case WSAEINVAL: return "Invalid argument"; case WSAEMFILE: return "Too many open files"; @@ -366,36 +371,63 @@ static const char *wstrerror(int err) { case WSAEPROTOTYPE: return "Protocol wrong type for socket"; case WSAENOPROTOOPT: return "Bad protocol option"; case WSAEPROTONOSUPPORT: return "Protocol not supported"; - case WSAESOCKTNOSUPPORT: return "Socket type not supported"; + case WSAESOCKTNOSUPPORT: return PIE_SOCKTYPE; // "Socket type not supported"; case WSAEOPNOTSUPP: return "Operation not supported"; case WSAEPFNOSUPPORT: return "Protocol family not supported"; - case WSAEAFNOSUPPORT: - return "Address family not supported by protocol family"; - case WSAEADDRINUSE: return "Address already in use"; + case WSAEAFNOSUPPORT: return PIE_FAMILY; // "Address family not supported by protocol family"; + case WSAEADDRINUSE: return PIE_ADDRINUSE; // "Address already in use"; case WSAEADDRNOTAVAIL: return "Cannot assign requested address"; case WSAENETDOWN: return "Network is down"; case WSAENETUNREACH: return "Network is unreachable"; case WSAENETRESET: return "Network dropped connection on reset"; case WSAECONNABORTED: return "Software caused connection abort"; - case WSAECONNRESET: return "Connection reset by peer"; + case WSAECONNRESET: return PIE_CONNRESET; // "Connection reset by peer"; case WSAENOBUFS: return "No buffer space available"; - case WSAEISCONN: return "Socket is already connected"; + case WSAEISCONN: return PIE_ISCONN; // "Socket is already connected"; case WSAENOTCONN: return "Socket is not connected"; case WSAESHUTDOWN: return "Cannot send after socket shutdown"; - case WSAETIMEDOUT: return "Connection timed out"; - case WSAECONNREFUSED: return "Connection refused"; + case WSAETIMEDOUT: return PIE_TIMEDOUT; // "Connection timed out"; + case WSAECONNREFUSED: return PIE_CONNREFUSED; // "Connection refused"; case WSAEHOSTDOWN: return "Host is down"; case WSAEHOSTUNREACH: return "No route to host"; case WSAEPROCLIM: return "Too many processes"; case WSASYSNOTREADY: return "Network subsystem is unavailable"; case WSAVERNOTSUPPORTED: return "Winsock.dll version out of range"; - case WSANOTINITIALISED: + case WSANOTINITIALISED: return "Successful WSAStartup not yet performed"; case WSAEDISCON: return "Graceful shutdown in progress"; - case WSAHOST_NOT_FOUND: return "Host not found"; + case WSAHOST_NOT_FOUND: return PIE_HOST_NOT_FOUND; // "Host not found"; case WSATRY_AGAIN: return "Nonauthoritative host not found"; - case WSANO_RECOVERY: return "Nonrecoverable name lookup error"; + case WSANO_RECOVERY: return PIE_FAIL; // "Nonrecoverable name lookup error"; case WSANO_DATA: return "Valid name, no data record of requested type"; default: return "Unknown error"; } } + +const char *socket_gaistrerror(int err) { + if (err == 0) return NULL; + switch (err) { + case EAI_AGAIN: return PIE_AGAIN; + case EAI_BADFLAGS: return PIE_BADFLAGS; +#ifdef EAI_BADHINTS + case EAI_BADHINTS: return PIE_BADHINTS; +#endif + case EAI_FAIL: return PIE_FAIL; + case EAI_FAMILY: return PIE_FAMILY; + case EAI_MEMORY: return PIE_MEMORY; + case EAI_NONAME: return PIE_NONAME; +#ifdef EAI_OVERFLOW + case EAI_OVERFLOW: return PIE_OVERFLOW; +#endif +#ifdef EAI_PROTOCOL + case EAI_PROTOCOL: return PIE_PROTOCOL; +#endif + case EAI_SERVICE: return PIE_SERVICE; + case EAI_SOCKTYPE: return PIE_SOCKTYPE; +#ifdef EAI_SYSTEM + case EAI_SYSTEM: return strerror(errno); +#endif + default: return gai_strerror(err); + } +} + diff --git a/love/src/jni/love/src/libraries/luasocket/libluasocket/wsocket.h b/love/src/jni/love/src/libraries/luasocket/libluasocket/wsocket.h index b5366836..39866402 100644 --- a/love/src/jni/love/src/libraries/luasocket/libluasocket/wsocket.h +++ b/love/src/jni/love/src/libraries/luasocket/libluasocket/wsocket.h @@ -3,19 +3,31 @@ /*=========================================================================*\ * Socket compatibilization module for Win32 * LuaSocket toolkit -* -* RCS ID: $Id: wsocket.h,v 1.4 2005/10/07 04:40:59 diego Exp $ \*=========================================================================*/ /*=========================================================================*\ * WinSock include files \*=========================================================================*/ -#include +#include +#include typedef int socklen_t; +typedef SOCKADDR_STORAGE t_sockaddr_storage; typedef SOCKET t_socket; typedef t_socket *p_socket; +#ifndef IPV6_V6ONLY +#define IPV6_V6ONLY 27 +#endif + #define SOCKET_INVALID (INVALID_SOCKET) +#ifndef SO_REUSEPORT +#define SO_REUSEPORT SO_REUSEADDR +#endif + +#ifndef AI_NUMERICSERV +#define AI_NUMERICSERV (0) +#endif + #endif /* WSOCKET_H */ diff --git a/love/src/jni/love/src/libraries/luasocket/luasocket.cpp b/love/src/jni/love/src/libraries/luasocket/luasocket.cpp index 15b793a7..88a99e63 100644 --- a/love/src/jni/love/src/libraries/luasocket/luasocket.cpp +++ b/love/src/jni/love/src/libraries/luasocket/luasocket.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -55,6 +55,8 @@ int __open(lua_State * L) PRELOAD("socket.smtp", __open_luasocket_smtp); PRELOAD("socket.tp", __open_luasocket_tp) PRELOAD("socket.url", __open_luasocket_url) + PRELOAD("socket.headers", __open_luasocket_headers) + PRELOAD("mbox", __open_luasocket_mbox) // No need to register garbage collector function. @@ -64,56 +66,60 @@ int __open(lua_State * L) int __open_luasocket_socket(lua_State * L) { #include "libluasocket/socket.lua.h" - lua_getglobal(L, "socket"); return 1; } int __open_luasocket_ftp(lua_State * L) { #include "libluasocket/ftp.lua.h" - lua_getglobal(L, "socket.ftp"); return 1; } int __open_luasocket_http(lua_State * L) { #include "libluasocket/http.lua.h" - lua_getglobal(L, "socket.http"); return 1; } int __open_luasocket_ltn12(lua_State * L) { #include "libluasocket/ltn12.lua.h" - lua_getglobal(L, "ltn12"); return 1; } int __open_luasocket_mime(lua_State * L) { #include "libluasocket/mime.lua.h" - lua_getglobal(L, "mime"); return 1; } int __open_luasocket_smtp(lua_State * L) { #include "libluasocket/smtp.lua.h" - lua_getglobal(L, "socket.smtp"); return 1; } int __open_luasocket_tp(lua_State * L) { #include "libluasocket/tp.lua.h" - lua_getglobal(L, "socket.tp"); return 1; } int __open_luasocket_url(lua_State * L) { #include "libluasocket/url.lua.h" - lua_getglobal(L, "socket.url"); + return 1; +} + +int __open_luasocket_headers(lua_State * L) +{ + #include "libluasocket/headers.lua.h" + return 1; +} + +int __open_luasocket_mbox(lua_State * L) +{ + #include "libluasocket/mbox.lua.h" return 1; } diff --git a/love/src/jni/love/src/libraries/luasocket/luasocket.h b/love/src/jni/love/src/libraries/luasocket/luasocket.h index d674b6df..e322f8ac 100644 --- a/love/src/jni/love/src/libraries/luasocket/luasocket.h +++ b/love/src/jni/love/src/libraries/luasocket/luasocket.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -42,6 +42,8 @@ int __open_luasocket_mime(lua_State * L); int __open_luasocket_smtp(lua_State * L); int __open_luasocket_tp(lua_State * L); int __open_luasocket_url(lua_State * L); +int __open_luasocket_headers(lua_State * L); +int __open_luasocket_mbox(lua_State * L); } // luasocket } // love diff --git a/love/src/jni/love/src/libraries/lz4/lz4.c b/love/src/jni/love/src/libraries/lz4/lz4.c index 08cf6b5c..213b0851 100755 --- a/love/src/jni/love/src/libraries/lz4/lz4.c +++ b/love/src/jni/love/src/libraries/lz4/lz4.c @@ -1,6 +1,6 @@ /* LZ4 - Fast LZ compression algorithm - Copyright (C) 2011-2015, Yann Collet. + Copyright (C) 2011-2017, Yann Collet. BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) @@ -28,20 +28,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. You can contact the author at : - - LZ4 source repository : https://github.com/Cyan4973/lz4 - - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c + - LZ4 homepage : http://www.lz4.org + - LZ4 source repository : https://github.com/lz4/lz4 */ -/************************************** +/*-************************************ * Tuning parameters **************************************/ /* - * HEAPMODE : + * LZ4_HEAPMODE : * Select how default compression functions will allocate memory for their hash table, * in memory stack (0:default, fastest), or in memory heap (1:requires malloc()). */ -#define HEAPMODE 0 +#ifndef LZ4_HEAPMODE +# define LZ4_HEAPMODE 0 +#endif /* * ACCELERATION_DEFAULT : @@ -50,9 +52,30 @@ #define ACCELERATION_DEFAULT 1 -/************************************** +/*-************************************ * CPU Feature Detection **************************************/ +/* LZ4_FORCE_MEMORY_ACCESS + * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. + * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. + * The below switch allow to select different access method for improved performance. + * Method 0 (default) : use `memcpy()`. Safe and portable. + * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). + * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. + * Method 2 : direct access. This method is portable but violate C standard. + * It can generate buggy code on targets which assembly generation depends on alignment. + * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) + * See https://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details. + * Prefer these methods in priority order (0 > 1 > 2) + */ +#ifndef LZ4_FORCE_MEMORY_ACCESS /* can be defined externally */ +# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) +# define LZ4_FORCE_MEMORY_ACCESS 2 +# elif defined(__INTEL_COMPILER) || defined(__GNUC__) +# define LZ4_FORCE_MEMORY_ACCESS 1 +# endif +#endif + /* * LZ4_FORCE_SW_BITCOUNT * Define this parameter if your target system or compiler does not support hardware bit count @@ -62,34 +85,62 @@ #endif -/************************************** -* Includes + +/*-************************************ +* Dependency **************************************/ #include "lz4.h" +/* see also "memory routines" below */ -/************************************** +/*-************************************ * Compiler Options **************************************/ #ifdef _MSC_VER /* Visual Studio */ -# define FORCE_INLINE static __forceinline # include # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ # pragma warning(disable : 4293) /* disable: C4293: too large shift (32-bits) */ -#else -# if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ -# if defined(__GNUC__) || defined(__clang__) -# define FORCE_INLINE static inline __attribute__((always_inline)) -# else -# define FORCE_INLINE static inline -# endif -# else -# define FORCE_INLINE static -# endif /* __STDC_VERSION__ */ #endif /* _MSC_VER */ -/* LZ4_GCC_VERSION is defined into lz4.h */ -#if (LZ4_GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__) +#ifndef LZ4_FORCE_INLINE +# ifdef _MSC_VER /* Visual Studio */ +# define LZ4_FORCE_INLINE static __forceinline +# else +# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ +# ifdef __GNUC__ +# define LZ4_FORCE_INLINE static inline __attribute__((always_inline)) +# else +# define LZ4_FORCE_INLINE static inline +# endif +# else +# define LZ4_FORCE_INLINE static +# endif /* __STDC_VERSION__ */ +# endif /* _MSC_VER */ +#endif /* LZ4_FORCE_INLINE */ + +/* LZ4_FORCE_O2_GCC_PPC64LE and LZ4_FORCE_O2_INLINE_GCC_PPC64LE + * Gcc on ppc64le generates an unrolled SIMDized loop for LZ4_wildCopy, + * together with a simple 8-byte copy loop as a fall-back path. + * However, this optimization hurts the decompression speed by >30%, + * because the execution does not go to the optimized loop + * for typical compressible data, and all of the preamble checks + * before going to the fall-back path become useless overhead. + * This optimization happens only with the -O3 flag, and -O2 generates + * a simple 8-byte copy loop. + * With gcc on ppc64le, all of the LZ4_decompress_* and LZ4_wildCopy + * functions are annotated with __attribute__((optimize("O2"))), + * and also LZ4_wildCopy is forcibly inlined, so that the O2 attribute + * of LZ4_wildCopy does not affect the compression speed. + */ +#if defined(__PPC64__) && defined(__LITTLE_ENDIAN__) && defined(__GNUC__) +# define LZ4_FORCE_O2_GCC_PPC64LE __attribute__((optimize("O2"))) +# define LZ4_FORCE_O2_INLINE_GCC_PPC64LE __attribute__((optimize("O2"))) LZ4_FORCE_INLINE +#else +# define LZ4_FORCE_O2_GCC_PPC64LE +# define LZ4_FORCE_O2_INLINE_GCC_PPC64LE static +#endif + +#if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__) # define expect(expr,value) (__builtin_expect ((expr),(value)) ) #else # define expect(expr,value) (expr) @@ -99,7 +150,7 @@ #define unlikely(expr) expect((expr) != 0, 0) -/************************************** +/*-************************************ * Memory routines **************************************/ #include /* malloc, calloc, free */ @@ -109,54 +160,100 @@ #define MEM_INIT memset -/************************************** +/*-************************************ * Basic Types **************************************/ -#if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ +#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) # include typedef uint8_t BYTE; typedef uint16_t U16; typedef uint32_t U32; typedef int32_t S32; typedef uint64_t U64; + typedef uintptr_t uptrval; #else typedef unsigned char BYTE; typedef unsigned short U16; typedef unsigned int U32; typedef signed int S32; typedef unsigned long long U64; + typedef size_t uptrval; /* generally true, except OpenVMS-64 */ #endif +#if defined(__x86_64__) + typedef U64 reg_t; /* 64-bits in x32 mode */ +#else + typedef size_t reg_t; /* 32-bits in x32 mode */ +#endif -/************************************** +/*-************************************ * Reading and writing into memory **************************************/ -#define STEPSIZE sizeof(size_t) - -static unsigned LZ4_64bits(void) { return sizeof(void*)==8; } - static unsigned LZ4_isLittleEndian(void) { - const union { U32 i; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ + const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ return one.c[0]; } +#if defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS==2) +/* lie to the compiler about data alignment; use with caution */ + +static U16 LZ4_read16(const void* memPtr) { return *(const U16*) memPtr; } +static U32 LZ4_read32(const void* memPtr) { return *(const U32*) memPtr; } +static reg_t LZ4_read_ARCH(const void* memPtr) { return *(const reg_t*) memPtr; } + +static void LZ4_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; } +static void LZ4_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; } + +#elif defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS==1) + +/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ +/* currently only defined for gcc and icc */ +typedef union { U16 u16; U32 u32; reg_t uArch; } __attribute__((packed)) unalign; + +static U16 LZ4_read16(const void* ptr) { return ((const unalign*)ptr)->u16; } +static U32 LZ4_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } +static reg_t LZ4_read_ARCH(const void* ptr) { return ((const unalign*)ptr)->uArch; } + +static void LZ4_write16(void* memPtr, U16 value) { ((unalign*)memPtr)->u16 = value; } +static void LZ4_write32(void* memPtr, U32 value) { ((unalign*)memPtr)->u32 = value; } + +#else /* safe and portable access through memcpy() */ + static U16 LZ4_read16(const void* memPtr) { - U16 val16; - memcpy(&val16, memPtr, 2); - return val16; + U16 val; memcpy(&val, memPtr, sizeof(val)); return val; } +static U32 LZ4_read32(const void* memPtr) +{ + U32 val; memcpy(&val, memPtr, sizeof(val)); return val; +} + +static reg_t LZ4_read_ARCH(const void* memPtr) +{ + reg_t val; memcpy(&val, memPtr, sizeof(val)); return val; +} + +static void LZ4_write16(void* memPtr, U16 value) +{ + memcpy(memPtr, &value, sizeof(value)); +} + +static void LZ4_write32(void* memPtr, U32 value) +{ + memcpy(memPtr, &value, sizeof(value)); +} + +#endif /* LZ4_FORCE_MEMORY_ACCESS */ + + static U16 LZ4_readLE16(const void* memPtr) { - if (LZ4_isLittleEndian()) - { + if (LZ4_isLittleEndian()) { return LZ4_read16(memPtr); - } - else - { + } else { const BYTE* p = (const BYTE*)memPtr; return (U16)((U16)p[0] + (p[1]<<8)); } @@ -164,63 +261,40 @@ static U16 LZ4_readLE16(const void* memPtr) static void LZ4_writeLE16(void* memPtr, U16 value) { - if (LZ4_isLittleEndian()) - { - memcpy(memPtr, &value, 2); - } - else - { + if (LZ4_isLittleEndian()) { + LZ4_write16(memPtr, value); + } else { BYTE* p = (BYTE*)memPtr; p[0] = (BYTE) value; p[1] = (BYTE)(value>>8); } } -static U32 LZ4_read32(const void* memPtr) +static void LZ4_copy8(void* dst, const void* src) { - U32 val32; - memcpy(&val32, memPtr, 4); - return val32; + memcpy(dst,src,8); } -static U64 LZ4_read64(const void* memPtr) -{ - U64 val64; - memcpy(&val64, memPtr, 8); - return val64; -} - -static size_t LZ4_read_ARCH(const void* p) -{ - if (LZ4_64bits()) - return (size_t)LZ4_read64(p); - else - return (size_t)LZ4_read32(p); -} - - -static void LZ4_copy4(void* dstPtr, const void* srcPtr) { memcpy(dstPtr, srcPtr, 4); } - -static void LZ4_copy8(void* dstPtr, const void* srcPtr) { memcpy(dstPtr, srcPtr, 8); } - -/* customized version of memcpy, which may overwrite up to 7 bytes beyond dstEnd */ -static void LZ4_wildCopy(void* dstPtr, const void* srcPtr, void* dstEnd) +/* customized variant of memcpy, which can overwrite up to 8 bytes beyond dstEnd */ +LZ4_FORCE_O2_INLINE_GCC_PPC64LE +void LZ4_wildCopy(void* dstPtr, const void* srcPtr, void* dstEnd) { BYTE* d = (BYTE*)dstPtr; const BYTE* s = (const BYTE*)srcPtr; - BYTE* e = (BYTE*)dstEnd; + BYTE* const e = (BYTE*)dstEnd; + do { LZ4_copy8(d,s); d+=8; s+=8; } while (d=1) +# include +#else +# ifndef assert +# define assert(condition) ((void)0) +# endif +#endif + +#define LZ4_STATIC_ASSERT(c) { enum { LZ4_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */ + +#if defined(LZ4_DEBUG) && (LZ4_DEBUG>=2) +# include +static int g_debuglog_enable = 1; +# define DEBUGLOG(l, ...) { \ + if ((g_debuglog_enable) && (l<=LZ4_DEBUG)) { \ + fprintf(stderr, __FILE__ ": "); \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, " \n"); \ + } } +#else +# define DEBUGLOG(l, ...) {} /* disabled */ +#endif -/************************************** +/*-************************************ * Common functions **************************************/ -static unsigned LZ4_NbCommonBytes (register size_t val) +static unsigned LZ4_NbCommonBytes (reg_t val) { - if (LZ4_isLittleEndian()) - { - if (LZ4_64bits()) - { + if (LZ4_isLittleEndian()) { + if (sizeof(val)==8) { # if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r = 0; _BitScanForward64( &r, (U64)val ); return (int)(r>>3); -# elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && !defined(LZ4_FORCE_SW_BITCOUNT) +# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_ctzll((U64)val) >> 3); # else - static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 }; + static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, + 0, 3, 1, 3, 1, 4, 2, 7, + 0, 2, 3, 6, 1, 5, 3, 5, + 1, 3, 4, 4, 2, 5, 6, 7, + 7, 0, 1, 2, 3, 3, 4, 6, + 2, 6, 5, 5, 3, 4, 5, 6, + 7, 1, 2, 4, 6, 4, 4, 5, + 7, 2, 6, 5, 7, 6, 7, 7 }; return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58]; # endif - } - else /* 32 bits */ - { + } else /* 32 bits */ { # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r; _BitScanForward( &r, (U32)val ); return (int)(r>>3); -# elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && !defined(LZ4_FORCE_SW_BITCOUNT) +# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_ctz((U32)val) >> 3); # else - static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 }; + static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, + 3, 2, 2, 1, 3, 2, 0, 1, + 3, 3, 1, 2, 2, 2, 2, 0, + 3, 1, 2, 0, 1, 0, 1, 1 }; return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27]; # endif } - } - else /* Big Endian CPU */ - { - if (LZ4_64bits()) - { + } else /* Big Endian CPU */ { + if (sizeof(val)==8) { /* 64-bits */ # if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r = 0; _BitScanReverse64( &r, val ); return (unsigned)(r>>3); -# elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && !defined(LZ4_FORCE_SW_BITCOUNT) +# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_clzll((U64)val) >> 3); # else + static const U32 by32 = sizeof(val)*4; /* 32 on 64 bits (goal), 16 on 32 bits. + Just to avoid some static analyzer complaining about shift by 32 on 32-bits target. + Note that this code path is never triggered in 32-bits mode. */ unsigned r; - if (!(val>>32)) { r=4; } else { r=0; val>>=32; } + if (!(val>>by32)) { r=4; } else { r=0; val>>=by32; } if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; } r += (!val); return r; # endif - } - else /* 32 bits */ - { + } else /* 32 bits */ { # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r = 0; _BitScanReverse( &r, (unsigned long)val ); return (unsigned)(r>>3); -# elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && !defined(LZ4_FORCE_SW_BITCOUNT) +# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_clz((U32)val) >> 3); # else unsigned r; @@ -312,19 +411,28 @@ static unsigned LZ4_NbCommonBytes (register size_t val) } } -static unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLimit) +#define STEPSIZE sizeof(reg_t) +LZ4_FORCE_INLINE +unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLimit) { const BYTE* const pStart = pIn; - while (likely(pIn compression run slower on incompressible data */ -/************************************** +/*-************************************ * Local Structures and types **************************************/ -typedef struct { - U32 hashTable[HASH_SIZE_U32]; - U32 currentOffset; - U32 initCheck; - const BYTE* dictionary; - BYTE* bufferStart; /* obsolete, used for slideInputBuffer */ - U32 dictSize; -} LZ4_stream_t_internal; - typedef enum { notLimited = 0, limitedOutput = 1 } limitedOutput_directive; typedef enum { byPtr, byU32, byU16 } tableType_t; @@ -365,44 +460,43 @@ typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive; typedef enum { full = 0, partial = 1 } earlyEnd_directive; -/************************************** +/*-************************************ * Local Utils **************************************/ int LZ4_versionNumber (void) { return LZ4_VERSION_NUMBER; } +const char* LZ4_versionString(void) { return LZ4_VERSION_STRING; } int LZ4_compressBound(int isize) { return LZ4_COMPRESSBOUND(isize); } int LZ4_sizeofState() { return LZ4_STREAMSIZE; } - -/******************************** +/*-****************************** * Compression functions ********************************/ - -static U32 LZ4_hashSequence(U32 sequence, tableType_t const tableType) +static U32 LZ4_hash4(U32 sequence, tableType_t const tableType) { if (tableType == byU16) - return (((sequence) * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1))); + return ((sequence * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1))); else - return (((sequence) * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG)); + return ((sequence * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG)); } -static const U64 prime5bytes = 889523592379ULL; -static U32 LZ4_hashSequence64(size_t sequence, tableType_t const tableType) +static U32 LZ4_hash5(U64 sequence, tableType_t const tableType) { + static const U64 prime5bytes = 889523592379ULL; + static const U64 prime8bytes = 11400714785074694791ULL; const U32 hashLog = (tableType == byU16) ? LZ4_HASHLOG+1 : LZ4_HASHLOG; - const U32 hashMask = (1<> (40 - hashLog)) & hashMask; + if (LZ4_isLittleEndian()) + return (U32)(((sequence << 24) * prime5bytes) >> (64 - hashLog)); + else + return (U32)(((sequence >> 24) * prime8bytes) >> (64 - hashLog)); } -static U32 LZ4_hashSequenceT(size_t sequence, tableType_t const tableType) +LZ4_FORCE_INLINE U32 LZ4_hashPosition(const void* const p, tableType_t const tableType) { - if (LZ4_64bits()) - return LZ4_hashSequence64(sequence, tableType); - return LZ4_hashSequence((U32)sequence, tableType); + if ((sizeof(reg_t)==8) && (tableType != byU16)) return LZ4_hash5(LZ4_read_ARCH(p), tableType); + return LZ4_hash4(LZ4_read32(p), tableType); } -static U32 LZ4_hashPosition(const void* p, tableType_t tableType) { return LZ4_hashSequenceT(LZ4_read_ARCH(p), tableType); } - static void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableType_t const tableType, const BYTE* srcBase) { switch (tableType) @@ -413,27 +507,30 @@ static void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableTy } } -static void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) +LZ4_FORCE_INLINE void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) { - U32 h = LZ4_hashPosition(p, tableType); + U32 const h = LZ4_hashPosition(p, tableType); LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase); } static const BYTE* LZ4_getPositionOnHash(U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase) { if (tableType == byPtr) { const BYTE** hashTable = (const BYTE**) tableBase; return hashTable[h]; } - if (tableType == byU32) { U32* hashTable = (U32*) tableBase; return hashTable[h] + srcBase; } - { U16* hashTable = (U16*) tableBase; return hashTable[h] + srcBase; } /* default, to ensure a return */ + if (tableType == byU32) { const U32* const hashTable = (U32*) tableBase; return hashTable[h] + srcBase; } + { const U16* const hashTable = (U16*) tableBase; return hashTable[h] + srcBase; } /* default, to ensure a return */ } -static const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) +LZ4_FORCE_INLINE const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) { - U32 h = LZ4_hashPosition(p, tableType); + U32 const h = LZ4_hashPosition(p, tableType); return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase); } -FORCE_INLINE int LZ4_compress_generic( - void* const ctx, + +/** LZ4_compress_generic() : + inlined, to ensure branches are decided at compilation time */ +LZ4_FORCE_INLINE int LZ4_compress_generic( + LZ4_stream_t_internal* const cctx, const char* const source, char* const dest, const int inputSize, @@ -444,15 +541,13 @@ FORCE_INLINE int LZ4_compress_generic( const dictIssue_directive dictIssue, const U32 acceleration) { - LZ4_stream_t_internal* const dictPtr = (LZ4_stream_t_internal*)ctx; - const BYTE* ip = (const BYTE*) source; const BYTE* base; const BYTE* lowLimit; - const BYTE* const lowRefLimit = ip - dictPtr->dictSize; - const BYTE* const dictionary = dictPtr->dictionary; - const BYTE* const dictEnd = dictionary + dictPtr->dictSize; - const size_t dictDelta = dictEnd - (const BYTE*)source; + const BYTE* const lowRefLimit = ip - cctx->dictSize; + const BYTE* const dictionary = cctx->dictionary; + const BYTE* const dictEnd = dictionary + cctx->dictSize; + const ptrdiff_t dictDelta = dictEnd - (const BYTE*)source; const BYTE* anchor = (const BYTE*) source; const BYTE* const iend = ip + inputSize; const BYTE* const mflimit = iend - MFLIMIT; @@ -462,10 +557,9 @@ FORCE_INLINE int LZ4_compress_generic( BYTE* const olimit = op + maxOutputSize; U32 forwardH; - size_t refDelta=0; /* Init conditions */ - if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size, too large (or negative) */ + if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported inputSize, too large (or negative) */ switch(dict) { case noDict: @@ -474,11 +568,11 @@ FORCE_INLINE int LZ4_compress_generic( lowLimit = (const BYTE*)source; break; case withPrefix64k: - base = (const BYTE*)source - dictPtr->currentOffset; - lowLimit = (const BYTE*)source - dictPtr->dictSize; + base = (const BYTE*)source - cctx->currentOffset; + lowLimit = (const BYTE*)source - cctx->dictSize; break; case usingExtDict: - base = (const BYTE*)source - dictPtr->currentOffset; + base = (const BYTE*)source - cctx->currentOffset; lowLimit = (const BYTE*)source; break; } @@ -486,44 +580,38 @@ FORCE_INLINE int LZ4_compress_generic( if (inputSizehashTable, tableType, base); ip++; forwardH = LZ4_hashPosition(ip, tableType); /* Main Loop */ - for ( ; ; ) - { + for ( ; ; ) { + ptrdiff_t refDelta = 0; const BYTE* match; BYTE* token; - { - const BYTE* forwardIp = ip; + + /* Find a match */ + { const BYTE* forwardIp = ip; unsigned step = 1; unsigned searchMatchNb = acceleration << LZ4_skipTrigger; - - /* Find a match */ do { - U32 h = forwardH; + U32 const h = forwardH; ip = forwardIp; forwardIp += step; step = (searchMatchNb++ >> LZ4_skipTrigger); if (unlikely(forwardIp > mflimit)) goto _last_literals; - match = LZ4_getPositionOnHash(h, ctx, tableType, base); - if (dict==usingExtDict) - { - if (match<(const BYTE*)source) - { + match = LZ4_getPositionOnHash(h, cctx->hashTable, tableType, base); + if (dict==usingExtDict) { + if (match < (const BYTE*)source) { refDelta = dictDelta; lowLimit = dictionary; - } - else - { + } else { refDelta = 0; lowLimit = (const BYTE*)source; - } - } + } } forwardH = LZ4_hashPosition(forwardIp, tableType); - LZ4_putPositionOnHash(ip, h, ctx, tableType, base); + LZ4_putPositionOnHash(ip, h, cctx->hashTable, tableType, base); } while ( ((dictIssue==dictSmall) ? (match < lowRefLimit) : 0) || ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip)) @@ -531,18 +619,17 @@ FORCE_INLINE int LZ4_compress_generic( } /* Catch up */ - while ((ip>anchor) && (match+refDelta > lowLimit) && (unlikely(ip[-1]==match[refDelta-1]))) { ip--; match--; } + while (((ip>anchor) & (match+refDelta > lowLimit)) && (unlikely(ip[-1]==match[refDelta-1]))) { ip--; match--; } - { - /* Encode Literal length */ - unsigned litLength = (unsigned)(ip - anchor); + /* Encode Literals */ + { unsigned const litLength = (unsigned)(ip - anchor); token = op++; - if ((outputLimited) && (unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength/255) > olimit))) - return 0; /* Check output limit */ - if (litLength>=RUN_MASK) - { + if ((outputLimited) && /* Check output buffer overflow */ + (unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength/255) > olimit))) + return 0; + if (litLength >= RUN_MASK) { int len = (int)litLength-RUN_MASK; - *token=(RUN_MASK<= 255 ; len-=255) *op++ = 255; *op++ = (BYTE)len; } @@ -558,41 +645,41 @@ _next_match: LZ4_writeLE16(op, (U16)(ip-match)); op+=2; /* Encode MatchLength */ - { - unsigned matchLength; + { unsigned matchCode; - if ((dict==usingExtDict) && (lowLimit==dictionary)) - { + if ((dict==usingExtDict) && (lowLimit==dictionary)) { const BYTE* limit; match += refDelta; limit = ip + (dictEnd-match); if (limit > matchlimit) limit = matchlimit; - matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, limit); - ip += MINMATCH + matchLength; - if (ip==limit) - { - unsigned more = LZ4_count(ip, (const BYTE*)source, matchlimit); - matchLength += more; + matchCode = LZ4_count(ip+MINMATCH, match+MINMATCH, limit); + ip += MINMATCH + matchCode; + if (ip==limit) { + unsigned const more = LZ4_count(ip, (const BYTE*)source, matchlimit); + matchCode += more; ip += more; } - } - else - { - matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit); - ip += MINMATCH + matchLength; + } else { + matchCode = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit); + ip += MINMATCH + matchCode; } - if ((outputLimited) && (unlikely(op + (1 + LASTLITERALS) + (matchLength>>8) > olimit))) - return 0; /* Check output limit */ - if (matchLength>=ML_MASK) - { + if ( outputLimited && /* Check output buffer overflow */ + (unlikely(op + (1 + LASTLITERALS) + (matchCode>>8) > olimit)) ) + return 0; + if (matchCode >= ML_MASK) { *token += ML_MASK; - matchLength -= ML_MASK; - for (; matchLength >= 510 ; matchLength-=510) { *op++ = 255; *op++ = 255; } - if (matchLength >= 255) { matchLength-=255; *op++ = 255; } - *op++ = (BYTE)matchLength; - } - else *token += (BYTE)(matchLength); + matchCode -= ML_MASK; + LZ4_write32(op, 0xFFFFFFFF); + while (matchCode >= 4*255) { + op+=4; + LZ4_write32(op, 0xFFFFFFFF); + matchCode -= 4*255; + } + op += matchCode / 255; + *op++ = (BYTE)(matchCode % 255); + } else + *token += (BYTE)(matchCode); } anchor = ip; @@ -601,24 +688,19 @@ _next_match: if (ip > mflimit) break; /* Fill table */ - LZ4_putPosition(ip-2, ctx, tableType, base); + LZ4_putPosition(ip-2, cctx->hashTable, tableType, base); /* Test next position */ - match = LZ4_getPosition(ip, ctx, tableType, base); - if (dict==usingExtDict) - { - if (match<(const BYTE*)source) - { + match = LZ4_getPosition(ip, cctx->hashTable, tableType, base); + if (dict==usingExtDict) { + if (match < (const BYTE*)source) { refDelta = dictDelta; lowLimit = dictionary; - } - else - { + } else { refDelta = 0; lowLimit = (const BYTE*)source; - } - } - LZ4_putPosition(ip, ctx, tableType, base); + } } + LZ4_putPosition(ip, cctx->hashTable, tableType, base); if ( ((dictIssue==dictSmall) ? (match>=lowRefLimit) : 1) && (match+MAX_DISTANCE>=ip) && (LZ4_read32(match+refDelta)==LZ4_read32(ip)) ) @@ -630,19 +712,16 @@ _next_match: _last_literals: /* Encode Last Literals */ - { - const size_t lastRun = (size_t)(iend - anchor); - if ((outputLimited) && ((op - (BYTE*)dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) - return 0; /* Check output limit */ - if (lastRun >= RUN_MASK) - { + { size_t const lastRun = (size_t)(iend - anchor); + if ( (outputLimited) && /* Check output buffer overflow */ + ((op - (BYTE*)dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize) ) + return 0; + if (lastRun >= RUN_MASK) { size_t accumulator = lastRun - RUN_MASK; *op++ = RUN_MASK << ML_BITS; for(; accumulator >= 255 ; accumulator-=255) *op++ = 255; *op++ = (BYTE) accumulator; - } - else - { + } else { *op++ = (BYTE)(lastRun<internal_donotuse; LZ4_resetStream((LZ4_stream_t*)state); if (acceleration < 1) acceleration = ACCELERATION_DEFAULT; - if (maxOutputSize >= LZ4_compressBound(inputSize)) - { + if (maxOutputSize >= LZ4_compressBound(inputSize)) { if (inputSize < LZ4_64Klimit) - return LZ4_compress_generic(state, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue, acceleration); + return LZ4_compress_generic(ctx, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue, acceleration); else - return LZ4_compress_generic(state, source, dest, inputSize, 0, notLimited, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue, acceleration); - } - else - { + return LZ4_compress_generic(ctx, source, dest, inputSize, 0, notLimited, (sizeof(void*)==8) ? byU32 : byPtr, noDict, noDictIssue, acceleration); + } else { if (inputSize < LZ4_64Klimit) - return LZ4_compress_generic(state, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration); + return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration); else - return LZ4_compress_generic(state, source, dest, inputSize, maxOutputSize, limitedOutput, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue, acceleration); + return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput, (sizeof(void*)==8) ? byU32 : byPtr, noDict, noDictIssue, acceleration); } } int LZ4_compress_fast(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) { -#if (HEAPMODE) +#if (LZ4_HEAPMODE) void* ctxPtr = ALLOCATOR(1, sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */ #else LZ4_stream_t ctx; - void* ctxPtr = &ctx; + void* const ctxPtr = &ctx; #endif - int result = LZ4_compress_fast_extState(ctxPtr, source, dest, inputSize, maxOutputSize, acceleration); + int const result = LZ4_compress_fast_extState(ctxPtr, source, dest, inputSize, maxOutputSize, acceleration); -#if (HEAPMODE) +#if (LZ4_HEAPMODE) FREEMEM(ctxPtr); #endif return result; @@ -705,22 +782,21 @@ int LZ4_compress_default(const char* source, char* dest, int inputSize, int maxO int LZ4_compress_fast_force(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) { LZ4_stream_t ctx; - LZ4_resetStream(&ctx); if (inputSize < LZ4_64Klimit) - return LZ4_compress_generic(&ctx, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration); + return LZ4_compress_generic(&ctx.internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration); else - return LZ4_compress_generic(&ctx, source, dest, inputSize, maxOutputSize, limitedOutput, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue, acceleration); + return LZ4_compress_generic(&ctx.internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, sizeof(void*)==8 ? byU32 : byPtr, noDict, noDictIssue, acceleration); } -/******************************** -* destSize variant +/*-****************************** +* *_destSize() variant ********************************/ static int LZ4_compress_destSize_generic( - void* const ctx, + LZ4_stream_t_internal* const ctx, const char* const src, char* const dst, int* const srcSizePtr, @@ -752,32 +828,30 @@ static int LZ4_compress_destSize_generic( /* First Byte */ *srcSizePtr = 0; - LZ4_putPosition(ip, ctx, tableType, base); + LZ4_putPosition(ip, ctx->hashTable, tableType, base); ip++; forwardH = LZ4_hashPosition(ip, tableType); /* Main Loop */ - for ( ; ; ) - { + for ( ; ; ) { const BYTE* match; BYTE* token; - { - const BYTE* forwardIp = ip; + + /* Find a match */ + { const BYTE* forwardIp = ip; unsigned step = 1; unsigned searchMatchNb = 1 << LZ4_skipTrigger; - /* Find a match */ do { U32 h = forwardH; ip = forwardIp; forwardIp += step; step = (searchMatchNb++ >> LZ4_skipTrigger); - if (unlikely(forwardIp > mflimit)) - goto _last_literals; + if (unlikely(forwardIp > mflimit)) goto _last_literals; - match = LZ4_getPositionOnHash(h, ctx, tableType, base); + match = LZ4_getPositionOnHash(h, ctx->hashTable, tableType, base); forwardH = LZ4_hashPosition(forwardIp, tableType); - LZ4_putPositionOnHash(ip, h, ctx, tableType, base); + LZ4_putPositionOnHash(ip, h, ctx->hashTable, tableType, base); } while ( ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip)) || (LZ4_read32(match) != LZ4_read32(ip)) ); @@ -786,18 +860,15 @@ static int LZ4_compress_destSize_generic( /* Catch up */ while ((ip>anchor) && (match > lowLimit) && (unlikely(ip[-1]==match[-1]))) { ip--; match--; } - { - /* Encode Literal length */ - unsigned litLength = (unsigned)(ip - anchor); + /* Encode Literal length */ + { unsigned litLength = (unsigned)(ip - anchor); token = op++; - if (op + ((litLength+240)/255) + litLength > oMaxLit) - { + if (op + ((litLength+240)/255) + litLength > oMaxLit) { /* Not enough space for a last match */ op--; goto _last_literals; } - if (litLength>=RUN_MASK) - { + if (litLength>=RUN_MASK) { unsigned len = litLength - RUN_MASK; *token=(RUN_MASK<= 255 ; len-=255) *op++ = 255; @@ -815,21 +886,15 @@ _next_match: LZ4_writeLE16(op, (U16)(ip-match)); op+=2; /* Encode MatchLength */ - { - size_t matchLength; + { size_t matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit); - matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit); - - if (op + ((matchLength+240)/255) > oMaxMatch) - { + if (op + ((matchLength+240)/255) > oMaxMatch) { /* Match description too long : reduce it */ matchLength = (15-1) + (oMaxMatch-op) * 255; } - //printf("offset %5i, matchLength%5i \n", (int)(ip-match), matchLength + MINMATCH); ip += MINMATCH + matchLength; - if (matchLength>=ML_MASK) - { + if (matchLength>=ML_MASK) { *token += ML_MASK; matchLength -= ML_MASK; while (matchLength >= 255) { matchLength-=255; *op++ = 255; } @@ -845,11 +910,11 @@ _next_match: if (op > oMaxSeq) break; /* Fill table */ - LZ4_putPosition(ip-2, ctx, tableType, base); + LZ4_putPosition(ip-2, ctx->hashTable, tableType, base); /* Test next position */ - match = LZ4_getPosition(ip, ctx, tableType, base); - LZ4_putPosition(ip, ctx, tableType, base); + match = LZ4_getPosition(ip, ctx->hashTable, tableType, base); + LZ4_putPosition(ip, ctx->hashTable, tableType, base); if ( (match+MAX_DISTANCE>=ip) && (LZ4_read32(match)==LZ4_read32(ip)) ) { token=op++; *token=0; goto _next_match; } @@ -860,25 +925,20 @@ _next_match: _last_literals: /* Encode Last Literals */ - { - size_t lastRunSize = (size_t)(iend - anchor); - if (op + 1 /* token */ + ((lastRunSize+240)/255) /* litLength */ + lastRunSize /* literals */ > oend) - { + { size_t lastRunSize = (size_t)(iend - anchor); + if (op + 1 /* token */ + ((lastRunSize+240)/255) /* litLength */ + lastRunSize /* literals */ > oend) { /* adapt lastRunSize to fill 'dst' */ lastRunSize = (oend-op) - 1; lastRunSize -= (lastRunSize+240)/255; } ip = anchor + lastRunSize; - if (lastRunSize >= RUN_MASK) - { + if (lastRunSize >= RUN_MASK) { size_t accumulator = lastRunSize - RUN_MASK; *op++ = RUN_MASK << ML_BITS; for(; accumulator >= 255 ; accumulator-=255) *op++ = 255; *op++ = (BYTE) accumulator; - } - else - { + } else { *op++ = (BYTE)(lastRunSize<= LZ4_compressBound(*srcSizePtr)) /* compression success is guaranteed */ - { + if (targetDstSize >= LZ4_compressBound(*srcSizePtr)) { /* compression success is guaranteed */ return LZ4_compress_fast_extState(state, src, dst, *srcSizePtr, targetDstSize, 1); - } - else - { + } else { if (*srcSizePtr < LZ4_64Klimit) - return LZ4_compress_destSize_generic(state, src, dst, srcSizePtr, targetDstSize, byU16); + return LZ4_compress_destSize_generic(&state->internal_donotuse, src, dst, srcSizePtr, targetDstSize, byU16); else - return LZ4_compress_destSize_generic(state, src, dst, srcSizePtr, targetDstSize, LZ4_64bits() ? byU32 : byPtr); + return LZ4_compress_destSize_generic(&state->internal_donotuse, src, dst, srcSizePtr, targetDstSize, sizeof(void*)==8 ? byU32 : byPtr); } } int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targetDstSize) { -#if (HEAPMODE) - void* ctx = ALLOCATOR(1, sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */ +#if (LZ4_HEAPMODE) + LZ4_stream_t* ctx = (LZ4_stream_t*)ALLOCATOR(1, sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */ #else LZ4_stream_t ctxBody; - void* ctx = &ctxBody; + LZ4_stream_t* ctx = &ctxBody; #endif int result = LZ4_compress_destSize_extState(ctx, src, dst, srcSizePtr, targetDstSize); -#if (HEAPMODE) +#if (LZ4_HEAPMODE) FREEMEM(ctx); #endif return result; @@ -928,7 +985,7 @@ int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targe -/******************************** +/*-****************************** * Streaming functions ********************************/ @@ -942,20 +999,22 @@ LZ4_stream_t* LZ4_createStream(void) void LZ4_resetStream (LZ4_stream_t* LZ4_stream) { + DEBUGLOG(4, "LZ4_resetStream"); MEM_INIT(LZ4_stream, 0, sizeof(LZ4_stream_t)); } int LZ4_freeStream (LZ4_stream_t* LZ4_stream) { + if (!LZ4_stream) return 0; /* support free on NULL */ FREEMEM(LZ4_stream); return (0); } -#define HASH_UNIT sizeof(size_t) +#define HASH_UNIT sizeof(reg_t) int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize) { - LZ4_stream_t_internal* dict = (LZ4_stream_t_internal*) LZ4_dict; + LZ4_stream_t_internal* dict = &LZ4_dict->internal_donotuse; const BYTE* p = (const BYTE*)dictionary; const BYTE* const dictEnd = p + dictSize; const BYTE* base; @@ -963,8 +1022,7 @@ int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize) if ((dict->initCheck) || (dict->currentOffset > 1 GB)) /* Uninitialized structure, or reuse overflow */ LZ4_resetStream(LZ4_dict); - if (dictSize < (int)HASH_UNIT) - { + if (dictSize < (int)HASH_UNIT) { dict->dictionary = NULL; dict->dictSize = 0; return 0; @@ -977,8 +1035,7 @@ int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize) dict->dictSize = (U32)(dictEnd - p); dict->currentOffset += dict->dictSize; - while (p <= dictEnd-HASH_UNIT) - { + while (p <= dictEnd-HASH_UNIT) { LZ4_putPosition(p, dict->hashTable, byU32, base); p+=3; } @@ -990,14 +1047,12 @@ int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize) static void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, const BYTE* src) { if ((LZ4_dict->currentOffset > 0x80000000) || - ((size_t)LZ4_dict->currentOffset > (size_t)src)) /* address space overflow */ - { + ((uptrval)LZ4_dict->currentOffset > (uptrval)src)) { /* address space overflow */ /* rescale hash table */ - U32 delta = LZ4_dict->currentOffset - 64 KB; + U32 const delta = LZ4_dict->currentOffset - 64 KB; const BYTE* dictEnd = LZ4_dict->dictionary + LZ4_dict->dictSize; int i; - for (i=0; ihashTable[i] < delta) LZ4_dict->hashTable[i]=0; else LZ4_dict->hashTable[i] -= delta; } @@ -1010,7 +1065,7 @@ static void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, const BYTE* src) int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) { - LZ4_stream_t_internal* streamPtr = (LZ4_stream_t_internal*)LZ4_stream; + LZ4_stream_t_internal* streamPtr = &LZ4_stream->internal_donotuse; const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize; const BYTE* smallest = (const BYTE*) source; @@ -1020,10 +1075,8 @@ int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream, const char* source, ch if (acceleration < 1) acceleration = ACCELERATION_DEFAULT; /* Check overlapping input/dictionary space */ - { - const BYTE* sourceEnd = (const BYTE*) source + inputSize; - if ((sourceEnd > streamPtr->dictionary) && (sourceEnd < dictEnd)) - { + { const BYTE* sourceEnd = (const BYTE*) source + inputSize; + if ((sourceEnd > streamPtr->dictionary) && (sourceEnd < dictEnd)) { streamPtr->dictSize = (U32)(dictEnd - sourceEnd); if (streamPtr->dictSize > 64 KB) streamPtr->dictSize = 64 KB; if (streamPtr->dictSize < 4) streamPtr->dictSize = 0; @@ -1032,25 +1085,23 @@ int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream, const char* source, ch } /* prefix mode : source data follows dictionary */ - if (dictEnd == (const BYTE*)source) - { + if (dictEnd == (const BYTE*)source) { int result; if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) - result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, dictSmall, acceleration); + result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, dictSmall, acceleration); else - result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, noDictIssue, acceleration); + result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, noDictIssue, acceleration); streamPtr->dictSize += (U32)inputSize; streamPtr->currentOffset += (U32)inputSize; return result; } /* external dictionary mode */ - { - int result; + { int result; if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) - result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, dictSmall, acceleration); + result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, dictSmall, acceleration); else - result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, noDictIssue, acceleration); + result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, noDictIssue, acceleration); streamPtr->dictionary = (const BYTE*)source; streamPtr->dictSize = (U32)inputSize; streamPtr->currentOffset += (U32)inputSize; @@ -1062,15 +1113,15 @@ int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream, const char* source, ch /* Hidden debug function, to force external dictionary mode */ int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* dest, int inputSize) { - LZ4_stream_t_internal* streamPtr = (LZ4_stream_t_internal*)LZ4_dict; + LZ4_stream_t_internal* streamPtr = &LZ4_dict->internal_donotuse; int result; const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize; const BYTE* smallest = dictEnd; if (smallest > (const BYTE*) source) smallest = (const BYTE*) source; - LZ4_renormDictT((LZ4_stream_t_internal*)LZ4_dict, smallest); + LZ4_renormDictT(streamPtr, smallest); - result = LZ4_compress_generic(LZ4_dict, source, dest, inputSize, 0, notLimited, byU32, usingExtDict, noDictIssue, 1); + result = LZ4_compress_generic(streamPtr, source, dest, inputSize, 0, notLimited, byU32, usingExtDict, noDictIssue, 1); streamPtr->dictionary = (const BYTE*)source; streamPtr->dictSize = (U32)inputSize; @@ -1080,10 +1131,17 @@ int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* } +/*! LZ4_saveDict() : + * If previously compressed data block is not guaranteed to remain available at its memory location, + * save it into a safer place (char* safeBuffer). + * Note : you don't need to call LZ4_loadDict() afterwards, + * dictionary is immediately usable, you can therefore call LZ4_compress_fast_continue(). + * Return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error. + */ int LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize) { - LZ4_stream_t_internal* dict = (LZ4_stream_t_internal*) LZ4_dict; - const BYTE* previousDictEnd = dict->dictionary + dict->dictSize; + LZ4_stream_t_internal* const dict = &LZ4_dict->internal_donotuse; + const BYTE* const previousDictEnd = dict->dictionary + dict->dictSize; if ((U32)dictSize > 64 KB) dictSize = 64 KB; /* useless to define a dictionary > 64 KB */ if ((U32)dictSize > dict->dictSize) dictSize = dict->dictSize; @@ -1098,88 +1156,98 @@ int LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize) -/******************************* +/*-***************************** * Decompression functions *******************************/ -/* - * This generic decompression function cover all use cases. - * It shall be instantiated several times, using different sets of directives - * Note that it is essential this generic function is really inlined, - * in order to remove useless branches during compilation optimization. +/*! LZ4_decompress_generic() : + * This generic decompression function covers all use cases. + * It shall be instantiated several times, using different sets of directives. + * Note that it is important for performance that this function really get inlined, + * in order to remove useless branches during compilation optimization. */ -FORCE_INLINE int LZ4_decompress_generic( - const char* const source, - char* const dest, - int inputSize, - int outputSize, /* If endOnInput==endOnInputSize, this value is the max size of Output Buffer. */ +LZ4_FORCE_O2_GCC_PPC64LE +LZ4_FORCE_INLINE int LZ4_decompress_generic( + const char* const src, + char* const dst, + int srcSize, + int outputSize, /* If endOnInput==endOnInputSize, this value is `dstCapacity` */ int endOnInput, /* endOnOutputSize, endOnInputSize */ int partialDecoding, /* full, partial */ int targetOutputSize, /* only used if partialDecoding==partial */ int dict, /* noDict, withPrefix64k, usingExtDict */ - const BYTE* const lowPrefix, /* == dest if dict == noDict */ + const BYTE* const lowPrefix, /* always <= dst, == dst when no prefix */ const BYTE* const dictStart, /* only if dict==usingExtDict */ const size_t dictSize /* note : = 0 if noDict */ ) { - /* Local Variables */ - const BYTE* ip = (const BYTE*) source; - const BYTE* const iend = ip + inputSize; + const BYTE* ip = (const BYTE*) src; + const BYTE* const iend = ip + srcSize; - BYTE* op = (BYTE*) dest; + BYTE* op = (BYTE*) dst; BYTE* const oend = op + outputSize; BYTE* cpy; BYTE* oexit = op + targetOutputSize; - const BYTE* const lowLimit = lowPrefix - dictSize; const BYTE* const dictEnd = (const BYTE*)dictStart + dictSize; - const size_t dec32table[] = {4, 1, 2, 1, 4, 4, 4, 4}; - const size_t dec64table[] = {0, 0, 0, (size_t)-1, 0, 1, 2, 3}; + const unsigned inc32table[8] = {0, 1, 2, 1, 0, 4, 4, 4}; + const int dec64table[8] = {0, 0, 0, -1, -4, 1, 2, 3}; const int safeDecode = (endOnInput==endOnInputSize); const int checkOffset = ((safeDecode) && (dictSize < (int)(64 KB))); /* Special cases */ - if ((partialDecoding) && (oexit> oend-MFLIMIT)) oexit = oend-MFLIMIT; /* targetOutputSize too high => decode everything */ - if ((endOnInput) && (unlikely(outputSize==0))) return ((inputSize==1) && (*ip==0)) ? 0 : -1; /* Empty output buffer */ + if ((partialDecoding) && (oexit > oend-MFLIMIT)) oexit = oend-MFLIMIT; /* targetOutputSize too high => just decode everything */ + if ((endOnInput) && (unlikely(outputSize==0))) return ((srcSize==1) && (*ip==0)) ? 0 : -1; /* Empty output buffer */ if ((!endOnInput) && (unlikely(outputSize==0))) return (*ip==0?1:-1); - - /* Main Loop */ - while (1) - { - unsigned token; + /* Main Loop : decode sequences */ + while (1) { size_t length; const BYTE* match; + size_t offset; - /* get literal length */ - token = *ip++; - if ((length=(token>>ML_BITS)) == RUN_MASK) - { + unsigned const token = *ip++; + + /* shortcut for common case : + * in most circumstances, we expect to decode small matches (<= 18 bytes) separated by few literals (<= 14 bytes). + * this shortcut was tested on x86 and x64, where it improves decoding speed. + * it has not yet been benchmarked on ARM, Power, mips, etc. */ + if (((ip + 14 /*maxLL*/ + 2 /*offset*/ <= iend) + & (op + 14 /*maxLL*/ + 18 /*maxML*/ <= oend)) + & ((token < (15<> ML_BITS; + size_t const off = LZ4_readLE16(ip+ll); + const BYTE* const matchPtr = op + ll - off; /* pointer underflow risk ? */ + if ((off >= 18) /* do not deal with overlapping matches */ & (matchPtr >= lowPrefix)) { + size_t const ml = (token & ML_MASK) + MINMATCH; + memcpy(op, ip, 16); op += ll; ip += ll + 2 /*offset*/; + memcpy(op, matchPtr, 18); op += ml; + continue; + } + } + + /* decode literal length */ + if ((length=(token>>ML_BITS)) == RUN_MASK) { unsigned s; - do - { + do { s = *ip++; length += s; - } - while (likely((endOnInput)?ip(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) ) - || ((!endOnInput) && (cpy>oend-COPYLENGTH))) + if ( ((endOnInput) && ((cpy>(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) ) + || ((!endOnInput) && (cpy>oend-WILDCOPYLENGTH)) ) { - if (partialDecoding) - { + if (partialDecoding) { if (cpy > oend) goto _output_error; /* Error : write attempt beyond end of output buffer */ if ((endOnInput) && (ip+length > iend)) goto _output_error; /* Error : read attempt beyond end of input buffer */ - } - else - { + } else { if ((!endOnInput) && (cpy != oend)) goto _output_error; /* Error : block decoding must stop exactly there */ if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) goto _output_error; /* Error : input must be consumed */ } @@ -1192,130 +1260,111 @@ FORCE_INLINE int LZ4_decompress_generic( ip += length; op = cpy; /* get offset */ - match = cpy - LZ4_readLE16(ip); ip+=2; - if ((checkOffset) && (unlikely(match < lowLimit))) goto _output_error; /* Error : offset outside destination buffer */ + offset = LZ4_readLE16(ip); ip+=2; + match = op - offset; + if ((checkOffset) && (unlikely(match + dictSize < lowPrefix))) goto _output_error; /* Error : offset outside buffers */ + LZ4_write32(op, (U32)offset); /* costs ~1%; silence an msan warning when offset==0 */ /* get matchlength */ length = token & ML_MASK; - if (length == ML_MASK) - { + if (length == ML_MASK) { unsigned s; - do - { - if ((endOnInput) && (ip > iend-LASTLITERALS)) goto _output_error; + do { s = *ip++; + if ((endOnInput) && (ip > iend-LASTLITERALS)) goto _output_error; length += s; } while (s==255); - if ((safeDecode) && unlikely((size_t)(op+length)<(size_t)op)) goto _output_error; /* overflow detection */ + if ((safeDecode) && unlikely((uptrval)(op)+length<(uptrval)op)) goto _output_error; /* overflow detection */ } length += MINMATCH; /* check external dictionary */ - if ((dict==usingExtDict) && (match < lowPrefix)) - { + if ((dict==usingExtDict) && (match < lowPrefix)) { if (unlikely(op+length > oend-LASTLITERALS)) goto _output_error; /* doesn't respect parsing restriction */ - if (length <= (size_t)(lowPrefix-match)) - { + if (length <= (size_t)(lowPrefix-match)) { /* match can be copied as a single segment from external dictionary */ - match = dictEnd - (lowPrefix-match); - memmove(op, match, length); op += length; - } - else - { - /* match encompass external dictionary and current segment */ - size_t copySize = (size_t)(lowPrefix-match); + memmove(op, dictEnd - (lowPrefix-match), length); + op += length; + } else { + /* match encompass external dictionary and current block */ + size_t const copySize = (size_t)(lowPrefix-match); + size_t const restSize = length - copySize; memcpy(op, dictEnd - copySize, copySize); op += copySize; - copySize = length - copySize; - if (copySize > (size_t)(op-lowPrefix)) /* overlap within current segment */ - { - BYTE* const endOfMatch = op + copySize; + if (restSize > (size_t)(op-lowPrefix)) { /* overlap copy */ + BYTE* const endOfMatch = op + restSize; const BYTE* copyFrom = lowPrefix; while (op < endOfMatch) *op++ = *copyFrom++; - } - else - { - memcpy(op, lowPrefix, copySize); - op += copySize; - } - } + } else { + memcpy(op, lowPrefix, restSize); + op += restSize; + } } continue; } - /* copy repeated sequence */ + /* copy match within block */ cpy = op + length; - if (unlikely((op-match)<8)) - { - const size_t dec64 = dec64table[op-match]; + if (unlikely(offset<8)) { op[0] = match[0]; op[1] = match[1]; op[2] = match[2]; op[3] = match[3]; - match += dec32table[op-match]; - LZ4_copy4(op+4, match); - op += 8; match -= dec64; - } else { LZ4_copy8(op, match); op+=8; match+=8; } + match += inc32table[offset]; + memcpy(op+4, match, 4); + match -= dec64table[offset]; + } else { LZ4_copy8(op, match); match+=8; } + op += 8; - if (unlikely(cpy>oend-12)) - { - if (cpy > oend-LASTLITERALS) goto _output_error; /* Error : last LASTLITERALS bytes must be literals */ - if (op < oend-8) - { - LZ4_wildCopy(op, match, oend-8); - match += (oend-8) - op; - op = oend-8; + if (unlikely(cpy>oend-12)) { + BYTE* const oCopyLimit = oend-(WILDCOPYLENGTH-1); + if (cpy > oend-LASTLITERALS) goto _output_error; /* Error : last LASTLITERALS bytes must be literals (uncompressed) */ + if (op < oCopyLimit) { + LZ4_wildCopy(op, match, oCopyLimit); + match += oCopyLimit - op; + op = oCopyLimit; } while (op16) LZ4_wildCopy(op+8, match+8, cpy); } - else - LZ4_wildCopy(op, match, cpy); - op=cpy; /* correction */ + op = cpy; /* correction */ } /* end of decoding */ if (endOnInput) - return (int) (((char*)op)-dest); /* Nb of output bytes decoded */ + return (int) (((char*)op)-dst); /* Nb of output bytes decoded */ else - return (int) (((const char*)ip)-source); /* Nb of input bytes read */ + return (int) (((const char*)ip)-src); /* Nb of input bytes read */ /* Overflow error detected */ _output_error: - return (int) (-(((const char*)ip)-source))-1; + return (int) (-(((const char*)ip)-src))-1; } +LZ4_FORCE_O2_GCC_PPC64LE int LZ4_decompress_safe(const char* source, char* dest, int compressedSize, int maxDecompressedSize) { return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, endOnInputSize, full, 0, noDict, (BYTE*)dest, NULL, 0); } +LZ4_FORCE_O2_GCC_PPC64LE int LZ4_decompress_safe_partial(const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize) { return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, endOnInputSize, partial, targetOutputSize, noDict, (BYTE*)dest, NULL, 0); } +LZ4_FORCE_O2_GCC_PPC64LE int LZ4_decompress_fast(const char* source, char* dest, int originalSize) { return LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, withPrefix64k, (BYTE*)(dest - 64 KB), NULL, 64 KB); } -/* streaming decompression functions */ +/*===== streaming decompression functions =====*/ -typedef struct -{ - const BYTE* externalDict; - size_t extDictSize; - const BYTE* prefixEnd; - size_t prefixSize; -} LZ4_streamDecode_t_internal; - -/* - * If you prefer dynamic allocation methods, - * LZ4_createStreamDecode() - * provides a pointer (void*) towards an initialized LZ4_streamDecode_t structure. - */ LZ4_streamDecode_t* LZ4_createStreamDecode(void) { LZ4_streamDecode_t* lz4s = (LZ4_streamDecode_t*) ALLOCATOR(1, sizeof(LZ4_streamDecode_t)); @@ -1324,20 +1373,21 @@ LZ4_streamDecode_t* LZ4_createStreamDecode(void) int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream) { + if (!LZ4_stream) return 0; /* support free on NULL */ FREEMEM(LZ4_stream); return 0; } -/* - * LZ4_setStreamDecode - * Use this function to instruct where to find the dictionary +/*! + * LZ4_setStreamDecode() : + * Use this function to instruct where to find the dictionary. * This function is not necessary if previous data is still available where it was decoded. * Loading a size of 0 is allowed (same effect as no dictionary). * Return : 1 if OK, 0 if error */ int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize) { - LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode; + LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse; lz4sd->prefixSize = (size_t) dictSize; lz4sd->prefixEnd = (const BYTE*) dictionary + dictSize; lz4sd->externalDict = NULL; @@ -1352,22 +1402,20 @@ int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dicti If it's not possible, save the relevant part of decoded data into a safe buffer, and indicate where it stands using LZ4_setStreamDecode() */ +LZ4_FORCE_O2_GCC_PPC64LE int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxOutputSize) { - LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode; + LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse; int result; - if (lz4sd->prefixEnd == (BYTE*)dest) - { + if (lz4sd->prefixEnd == (BYTE*)dest) { result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize); if (result <= 0) return result; lz4sd->prefixSize += result; lz4sd->prefixEnd += result; - } - else - { + } else { lz4sd->extDictSize = lz4sd->prefixSize; lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize; result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, @@ -1381,24 +1429,22 @@ int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const ch return result; } +LZ4_FORCE_O2_GCC_PPC64LE int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize) { - LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode; + LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse; int result; - if (lz4sd->prefixEnd == (BYTE*)dest) - { + if (lz4sd->prefixEnd == (BYTE*)dest) { result = LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize); if (result <= 0) return result; lz4sd->prefixSize += originalSize; lz4sd->prefixEnd += originalSize; - } - else - { + } else { lz4sd->extDictSize = lz4sd->prefixSize; - lz4sd->externalDict = (BYTE*)dest - lz4sd->extDictSize; + lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize; result = LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize); @@ -1418,12 +1464,12 @@ Advanced decoding functions : the dictionary must be explicitly provided within parameters */ -FORCE_INLINE int LZ4_decompress_usingDict_generic(const char* source, char* dest, int compressedSize, int maxOutputSize, int safe, const char* dictStart, int dictSize) +LZ4_FORCE_O2_GCC_PPC64LE +LZ4_FORCE_INLINE int LZ4_decompress_usingDict_generic(const char* source, char* dest, int compressedSize, int maxOutputSize, int safe, const char* dictStart, int dictSize) { if (dictSize==0) return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest, NULL, 0); - if (dictStart+dictSize == dest) - { + if (dictStart+dictSize == dest) { if (dictSize >= (int)(64 KB - 1)) return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, withPrefix64k, (BYTE*)dest-64 KB, NULL, 0); return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest-dictSize, NULL, 0); @@ -1431,24 +1477,27 @@ FORCE_INLINE int LZ4_decompress_usingDict_generic(const char* source, char* dest return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, usingExtDict, (BYTE*)dest, (const BYTE*)dictStart, dictSize); } +LZ4_FORCE_O2_GCC_PPC64LE int LZ4_decompress_safe_usingDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize) { return LZ4_decompress_usingDict_generic(source, dest, compressedSize, maxOutputSize, 1, dictStart, dictSize); } +LZ4_FORCE_O2_GCC_PPC64LE int LZ4_decompress_fast_usingDict(const char* source, char* dest, int originalSize, const char* dictStart, int dictSize) { return LZ4_decompress_usingDict_generic(source, dest, 0, originalSize, 0, dictStart, dictSize); } /* debug function */ +LZ4_FORCE_O2_GCC_PPC64LE int LZ4_decompress_safe_forceExtDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize) { return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, usingExtDict, (BYTE*)dest, (const BYTE*)dictStart, dictSize); } -/*************************************************** +/*=************************************************* * Obsolete Functions ***************************************************/ /* obsolete compression functions */ @@ -1473,29 +1522,29 @@ int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int LZ4_sizeofStreamState() { return LZ4_STREAMSIZE; } -static void LZ4_init(LZ4_stream_t_internal* lz4ds, BYTE* base) +static void LZ4_init(LZ4_stream_t* lz4ds, BYTE* base) { - MEM_INIT(lz4ds, 0, LZ4_STREAMSIZE); - lz4ds->bufferStart = base; + MEM_INIT(lz4ds, 0, sizeof(LZ4_stream_t)); + lz4ds->internal_donotuse.bufferStart = base; } int LZ4_resetStreamState(void* state, char* inputBuffer) { - if ((((size_t)state) & 3) != 0) return 1; /* Error : pointer is not aligned on 4-bytes boundary */ - LZ4_init((LZ4_stream_t_internal*)state, (BYTE*)inputBuffer); + if ((((uptrval)state) & 3) != 0) return 1; /* Error : pointer is not aligned on 4-bytes boundary */ + LZ4_init((LZ4_stream_t*)state, (BYTE*)inputBuffer); return 0; } void* LZ4_create (char* inputBuffer) { - void* lz4ds = ALLOCATOR(8, LZ4_STREAMSIZE_U64); - LZ4_init ((LZ4_stream_t_internal*)lz4ds, (BYTE*)inputBuffer); + LZ4_stream_t* lz4ds = (LZ4_stream_t*)ALLOCATOR(8, sizeof(LZ4_stream_t)); + LZ4_init (lz4ds, (BYTE*)inputBuffer); return lz4ds; } char* LZ4_slideInputBuffer (void* LZ4_Data) { - LZ4_stream_t_internal* ctx = (LZ4_stream_t_internal*)LZ4_Data; + LZ4_stream_t_internal* ctx = &((LZ4_stream_t*)LZ4_Data)->internal_donotuse; int dictSize = LZ4_saveDict((LZ4_stream_t*)LZ4_Data, (char*)ctx->bufferStart, 64 KB); return (char*)(ctx->bufferStart + dictSize); } @@ -1513,4 +1562,3 @@ int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int origin } #endif /* LZ4_COMMONDEFS_ONLY */ - diff --git a/love/src/jni/love/src/libraries/lz4/lz4.h b/love/src/jni/love/src/libraries/lz4/lz4.h index 99c6ebb0..3cf6c8dc 100755 --- a/love/src/jni/love/src/libraries/lz4/lz4.h +++ b/love/src/jni/love/src/libraries/lz4/lz4.h @@ -1,7 +1,7 @@ /* - LZ4 - Fast LZ compression algorithm - Header File - Copyright (C) 2011-2015, Yann Collet. + * LZ4 - Fast LZ compression algorithm + * Header File + * Copyright (C) 2011-2017, Yann Collet. BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) @@ -29,83 +29,134 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. You can contact the author at : - - LZ4 source repository : https://github.com/Cyan4973/lz4 - - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c + - LZ4 homepage : http://www.lz4.org + - LZ4 source repository : https://github.com/lz4/lz4 */ -#pragma once - #if defined (__cplusplus) extern "C" { #endif -/* - * lz4.h provides block compression functions, and gives full buffer control to programmer. - * If you need to generate inter-operable compressed data (respecting LZ4 frame specification), - * and can let the library handle its own memory, please use lz4frame.h instead. +#ifndef LZ4_H_2983827168210 +#define LZ4_H_2983827168210 + +/* --- Dependency --- */ +#include /* size_t */ + + +/** + Introduction + + LZ4 is lossless compression algorithm, providing compression speed at 400 MB/s per core, + scalable with multi-cores CPU. It features an extremely fast decoder, with speed in + multiple GB/s per core, typically reaching RAM speed limits on multi-core systems. + + The LZ4 compression library provides in-memory compression and decompression functions. + Compression can be done in: + - a single step (described as Simple Functions) + - a single step, reusing a context (described in Advanced Functions) + - unbounded multiple steps (described as Streaming compression) + + lz4.h provides block compression functions. It gives full buffer control to user. + Decompressing an lz4-compressed block also requires metadata (such as compressed size). + Each application is free to encode such metadata in whichever way it wants. + + An additional format, called LZ4 frame specification (doc/lz4_Frame_format.md), + take care of encoding standard metadata alongside LZ4-compressed blocks. + If your application requires interoperability, it's recommended to use it. + A library is provided to take care of it, see lz4frame.h. */ -/************************************** -* Version -**************************************/ -#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */ -#define LZ4_VERSION_MINOR 7 /* for new (non-breaking) interface capabilities */ -#define LZ4_VERSION_RELEASE 0 /* for tweaks, bug-fixes, or development */ -#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE) -int LZ4_versionNumber (void); +/*^*************************************************************** +* Export parameters +*****************************************************************/ +/* +* LZ4_DLL_EXPORT : +* Enable exporting of functions when building a Windows DLL +* LZ4LIB_VISIBILITY : +* Control library symbols visibility. +*/ +#ifndef LZ4LIB_VISIBILITY +# if defined(__GNUC__) && (__GNUC__ >= 4) +# define LZ4LIB_VISIBILITY __attribute__ ((visibility ("default"))) +# else +# define LZ4LIB_VISIBILITY +# endif +#endif +#if defined(LZ4_DLL_EXPORT) && (LZ4_DLL_EXPORT==1) +# define LZ4LIB_API __declspec(dllexport) LZ4LIB_VISIBILITY +#elif defined(LZ4_DLL_IMPORT) && (LZ4_DLL_IMPORT==1) +# define LZ4LIB_API __declspec(dllimport) LZ4LIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ +#else +# define LZ4LIB_API LZ4LIB_VISIBILITY +#endif -/************************************** +/*------ Version ------*/ +#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */ +#define LZ4_VERSION_MINOR 8 /* for new (non-breaking) interface capabilities */ +#define LZ4_VERSION_RELEASE 0 /* for tweaks, bug-fixes, or development */ + +#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE) + +#define LZ4_LIB_VERSION LZ4_VERSION_MAJOR.LZ4_VERSION_MINOR.LZ4_VERSION_RELEASE +#define LZ4_QUOTE(str) #str +#define LZ4_EXPAND_AND_QUOTE(str) LZ4_QUOTE(str) +#define LZ4_VERSION_STRING LZ4_EXPAND_AND_QUOTE(LZ4_LIB_VERSION) + +LZ4LIB_API int LZ4_versionNumber (void); /**< library version number; to be used when checking dll version */ +LZ4LIB_API const char* LZ4_versionString (void); /**< library version string; to be used when checking dll version */ + + +/*-************************************ * Tuning parameter **************************************/ -/* +/*! * LZ4_MEMORY_USAGE : * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) * Increasing memory usage improves compression ratio * Reduced memory usage can improve speed, due to cache effect * Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */ -#define LZ4_MEMORY_USAGE 14 +#ifndef LZ4_MEMORY_USAGE +# define LZ4_MEMORY_USAGE 14 +#endif - -/************************************** +/*-************************************ * Simple Functions **************************************/ - -int LZ4_compress_default(const char* source, char* dest, int sourceSize, int maxDestSize); -int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, int maxDecompressedSize); - -/* -LZ4_compress_default() : - Compresses 'sourceSize' bytes from buffer 'source' - into already allocated 'dest' buffer of size 'maxDestSize'. - Compression is guaranteed to succeed if 'maxDestSize' >= LZ4_compressBound(sourceSize). +/*! LZ4_compress_default() : + Compresses 'srcSize' bytes from buffer 'src' + into already allocated 'dst' buffer of size 'dstCapacity'. + Compression is guaranteed to succeed if 'dstCapacity' >= LZ4_compressBound(srcSize). It also runs faster, so it's a recommended setting. - If the function cannot compress 'source' into a more limited 'dest' budget, + If the function cannot compress 'src' into a limited 'dst' budget, compression stops *immediately*, and the function result is zero. - As a consequence, 'dest' content is not valid. - This function never writes outside 'dest' buffer, nor read outside 'source' buffer. - sourceSize : Max supported value is LZ4_MAX_INPUT_VALUE - maxDestSize : full or partial size of buffer 'dest' (which must be already allocated) - return : the number of bytes written into buffer 'dest' (necessarily <= maxOutputSize) - or 0 if compression fails + As a consequence, 'dst' content is not valid. + This function never writes outside 'dst' buffer, nor read outside 'source' buffer. + srcSize : supported max value is LZ4_MAX_INPUT_VALUE + dstCapacity : full or partial size of buffer 'dst' (which must be already allocated) + return : the number of bytes written into buffer 'dst' (necessarily <= dstCapacity) + or 0 if compression fails */ +LZ4LIB_API int LZ4_compress_default(const char* src, char* dst, int srcSize, int dstCapacity); -LZ4_decompress_safe() : - compressedSize : is the precise full size of the compressed block. - maxDecompressedSize : is the size of destination buffer, which must be already allocated. - return : the number of bytes decompressed into destination buffer (necessarily <= maxDecompressedSize) - If destination buffer is not large enough, decoding will stop and output an error code (<0). +/*! LZ4_decompress_safe() : + compressedSize : is the exact complete size of the compressed block. + dstCapacity : is the size of destination buffer, which must be already allocated. + return : the number of bytes decompressed into destination buffer (necessarily <= dstCapacity) + If destination buffer is not large enough, decoding will stop and output an error code (negative value). If the source stream is detected malformed, the function will stop decoding and return a negative result. This function is protected against buffer overflow exploits, including malicious data packets. It never writes outside output buffer, nor reads outside input buffer. */ +LZ4LIB_API int LZ4_decompress_safe (const char* src, char* dst, int compressedSize, int dstCapacity); -/************************************** +/*-************************************ * Advanced Functions **************************************/ #define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */ #define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16) -/* +/*! LZ4_compressBound() : Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible) This function is primarily useful for memory allocation purposes (destination buffer size). @@ -115,9 +166,9 @@ LZ4_compressBound() : return : maximum output size in a "worst case" scenario or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE) */ -int LZ4_compressBound(int inputSize); +LZ4LIB_API int LZ4_compressBound(int inputSize); -/* +/*! LZ4_compress_fast() : Same as LZ4_compress_default(), but allows to select an "acceleration" factor. The larger the acceleration value, the faster the algorithm, but also the lesser the compression. @@ -125,195 +176,268 @@ LZ4_compress_fast() : An acceleration value of "1" is the same as regular LZ4_compress_default() Values <= 0 will be replaced by ACCELERATION_DEFAULT (see lz4.c), which is 1. */ -int LZ4_compress_fast (const char* source, char* dest, int sourceSize, int maxDestSize, int acceleration); +LZ4LIB_API int LZ4_compress_fast (const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); -/* +/*! LZ4_compress_fast_extState() : Same compression function, just using an externally allocated memory space to store compression state. Use LZ4_sizeofState() to know how much memory must be allocated, and allocate it on 8-bytes boundaries (using malloc() typically). Then, provide it as 'void* state' to compression function. */ -int LZ4_sizeofState(void); -int LZ4_compress_fast_extState (void* state, const char* source, char* dest, int inputSize, int maxDestSize, int acceleration); +LZ4LIB_API int LZ4_sizeofState(void); +LZ4LIB_API int LZ4_compress_fast_extState (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); -/* +/*! LZ4_compress_destSize() : - Reverse the logic, by compressing as much data as possible from 'source' buffer - into already allocated buffer 'dest' of size 'targetDestSize'. - This function either compresses the entire 'source' content into 'dest' if it's large enough, - or fill 'dest' buffer completely with as much data as possible from 'source'. - *sourceSizePtr : will be modified to indicate how many bytes where read from 'source' to fill 'dest'. - New value is necessarily <= old value. - return : Nb bytes written into 'dest' (necessarily <= targetDestSize) - or 0 if compression fails + Reverse the logic : compresses as much data as possible from 'src' buffer + into already allocated buffer 'dst' of size 'targetDestSize'. + This function either compresses the entire 'src' content into 'dst' if it's large enough, + or fill 'dst' buffer completely with as much data as possible from 'src'. + *srcSizePtr : will be modified to indicate how many bytes where read from 'src' to fill 'dst'. + New value is necessarily <= old value. + return : Nb bytes written into 'dst' (necessarily <= targetDestSize) + or 0 if compression fails */ -int LZ4_compress_destSize (const char* source, char* dest, int* sourceSizePtr, int targetDestSize); +LZ4LIB_API int LZ4_compress_destSize (const char* src, char* dst, int* srcSizePtr, int targetDstSize); -/* -LZ4_decompress_fast() : - originalSize : is the original and therefore uncompressed size +/*! +LZ4_decompress_fast() : (unsafe!!) + originalSize : is the original uncompressed size return : the number of bytes read from the source buffer (in other words, the compressed size) If the source stream is detected malformed, the function will stop decoding and return a negative result. - Destination buffer must be already allocated. Its size must be a minimum of 'originalSize' bytes. - note : This function fully respect memory boundaries for properly formed compressed data. + Destination buffer must be already allocated. Its size must be >= 'originalSize' bytes. + note : This function respects memory boundaries for *properly formed* compressed data. It is a bit faster than LZ4_decompress_safe(). However, it does not provide any protection against intentionally modified data stream (malicious input). Use this function in trusted environment only (data to decode comes from a trusted source). */ -int LZ4_decompress_fast (const char* source, char* dest, int originalSize); +LZ4LIB_API int LZ4_decompress_fast (const char* src, char* dst, int originalSize); -/* +/*! LZ4_decompress_safe_partial() : - This function decompress a compressed block of size 'compressedSize' at position 'source' - into destination buffer 'dest' of size 'maxDecompressedSize'. - The function tries to stop decompressing operation as soon as 'targetOutputSize' has been reached, - reducing decompression time. - return : the number of bytes decoded in the destination buffer (necessarily <= maxDecompressedSize) - Note : this number can be < 'targetOutputSize' should the compressed block to decode be smaller. + This function decompress a compressed block of size 'srcSize' at position 'src' + into destination buffer 'dst' of size 'dstCapacity'. + The function will decompress a minimum of 'targetOutputSize' bytes, and stop after that. + However, it's not accurate, and may write more than 'targetOutputSize' (but <= dstCapacity). + @return : the number of bytes decoded in the destination buffer (necessarily <= dstCapacity) + Note : this number can be < 'targetOutputSize' should the compressed block contain less data. Always control how many bytes were decoded. If the source stream is detected malformed, the function will stop decoding and return a negative result. - This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets + This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets. */ -int LZ4_decompress_safe_partial (const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize); +LZ4LIB_API int LZ4_decompress_safe_partial (const char* src, char* dst, int srcSize, int targetOutputSize, int dstCapacity); -/*********************************************** +/*-********************************************* * Streaming Compression Functions ***********************************************/ -#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4) -#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(long long)) -/* - * LZ4_stream_t - * information structure to track an LZ4 stream. - * important : init this structure content before first use ! - * note : only allocated directly the structure if you are statically linking LZ4 - * If you are using liblz4 as a DLL, please use below construction methods instead. +typedef union LZ4_stream_u LZ4_stream_t; /* incomplete type (defined later) */ + +/*! LZ4_createStream() and LZ4_freeStream() : + * LZ4_createStream() will allocate and initialize an `LZ4_stream_t` structure. + * LZ4_freeStream() releases its memory. */ -typedef struct { long long table[LZ4_STREAMSIZE_U64]; } LZ4_stream_t; +LZ4LIB_API LZ4_stream_t* LZ4_createStream(void); +LZ4LIB_API int LZ4_freeStream (LZ4_stream_t* streamPtr); -/* - * LZ4_resetStream - * Use this function to init an allocated LZ4_stream_t structure +/*! LZ4_resetStream() : + * An LZ4_stream_t structure can be allocated once and re-used multiple times. + * Use this function to start compressing a new stream. */ -void LZ4_resetStream (LZ4_stream_t* streamPtr); +LZ4LIB_API void LZ4_resetStream (LZ4_stream_t* streamPtr); -/* - * LZ4_createStream will allocate and initialize an LZ4_stream_t structure - * LZ4_freeStream releases its memory. - * In the context of a DLL (liblz4), please use these methods rather than the static struct. - * They are more future proof, in case of a change of LZ4_stream_t size. +/*! LZ4_loadDict() : + * Use this function to load a static dictionary into LZ4_stream_t. + * Any previous data will be forgotten, only 'dictionary' will remain in memory. + * Loading a size of 0 is allowed, and is the same as reset. + * @return : dictionary size, in bytes (necessarily <= 64 KB) */ -LZ4_stream_t* LZ4_createStream(void); -int LZ4_freeStream (LZ4_stream_t* streamPtr); +LZ4LIB_API int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize); -/* - * LZ4_loadDict - * Use this function to load a static dictionary into LZ4_stream. - * Any previous data will be forgotten, only 'dictionary' will remain in memory. - * Loading a size of 0 is allowed. - * Return : dictionary size, in bytes (necessarily <= 64 KB) +/*! LZ4_compress_fast_continue() : + * Compress content into 'src' using data from previously compressed blocks, improving compression ratio. + * 'dst' buffer must be already allocated. + * If dstCapacity >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster. + * + * Important : Up to 64KB of previously compressed data is assumed to remain present and unmodified in memory ! + * Special 1 : If input buffer is a double-buffer, it can have any size, including < 64 KB. + * Special 2 : If input buffer is a ring-buffer, it can have any size, including < 64 KB. + * + * @return : size of compressed block + * or 0 if there is an error (typically, compressed data cannot fit into 'dst') + * After an error, the stream status is invalid, it can only be reset or freed. */ -int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize); +LZ4LIB_API int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); -/* - * LZ4_compress_fast_continue - * Compress buffer content 'src', using data from previously compressed blocks as dictionary to improve compression ratio. - * Important : Previous data blocks are assumed to still be present and unmodified ! - * 'dst' buffer must be already allocated. - * If maxDstSize >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster. - * If not, and if compressed data cannot fit into 'dst' buffer size, compression stops, and function returns a zero. +/*! LZ4_saveDict() : + * If previously compressed data block is not guaranteed to remain available at its current memory location, + * save it into a safer place (char* safeBuffer). + * Note : it's not necessary to call LZ4_loadDict() after LZ4_saveDict(), dictionary is immediately usable. + * @return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error. */ -int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int maxDstSize, int acceleration); - -/* - * LZ4_saveDict - * If previously compressed data block is not guaranteed to remain available at its memory location - * save it into a safer place (char* safeBuffer) - * Note : you don't need to call LZ4_loadDict() afterwards, - * dictionary is immediately usable, you can therefore call LZ4_compress_fast_continue() - * Return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error - */ -int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int dictSize); +LZ4LIB_API int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int dictSize); -/************************************************ +/*-********************************************** * Streaming Decompression Functions +* Bufferless synchronous API ************************************************/ +typedef union LZ4_streamDecode_u LZ4_streamDecode_t; /* incomplete type (defined later) */ +/*! LZ4_createStreamDecode() and LZ4_freeStreamDecode() : + * creation / destruction of streaming decompression tracking structure. + * A tracking structure can be re-used multiple times sequentially. */ +LZ4LIB_API LZ4_streamDecode_t* LZ4_createStreamDecode(void); +LZ4LIB_API int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream); + +/*! LZ4_setStreamDecode() : + * An LZ4_streamDecode_t structure can be allocated once and re-used multiple times. + * Use this function to start decompression of a new stream of blocks. + * A dictionary can optionnally be set. Use NULL or size 0 for a simple reset order. + * @return : 1 if OK, 0 if error + */ +LZ4LIB_API int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize); + +/*! LZ4_decompress_*_continue() : + * These decoding functions allow decompression of consecutive blocks in "streaming" mode. + * A block is an unsplittable entity, it must be presented entirely to a decompression function. + * Decompression functions only accept one block at a time. + * Previously decoded blocks *must* remain available at the memory position where they were decoded (up to 64 KB). + * + * Special : if application sets a ring buffer for decompression, it must respect one of the following conditions : + * - Exactly same size as encoding buffer, with same update rule (block boundaries at same positions) + * In which case, the decoding & encoding ring buffer can have any size, including very small ones ( < 64 KB). + * - Larger than encoding buffer, by a minimum of maxBlockSize more bytes. + * maxBlockSize is implementation dependent. It's the maximum size of any single block. + * In which case, encoding and decoding buffers do not need to be synchronized, + * and encoding ring buffer can have any size, including small ones ( < 64 KB). + * - _At least_ 64 KB + 8 bytes + maxBlockSize. + * In which case, encoding and decoding buffers do not need to be synchronized, + * and encoding ring buffer can have any size, including larger than decoding buffer. + * Whenever these conditions are not possible, save the last 64KB of decoded data into a safe buffer, + * and indicate where it is saved using LZ4_setStreamDecode() before decompressing next block. +*/ +LZ4LIB_API int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* src, char* dst, int srcSize, int dstCapacity); +LZ4LIB_API int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* src, char* dst, int originalSize); + + +/*! LZ4_decompress_*_usingDict() : + * These decoding functions work the same as + * a combination of LZ4_setStreamDecode() followed by LZ4_decompress_*_continue() + * They are stand-alone, and don't need an LZ4_streamDecode_t structure. + */ +LZ4LIB_API int LZ4_decompress_safe_usingDict (const char* src, char* dst, int srcSize, int dstCapcity, const char* dictStart, int dictSize); +LZ4LIB_API int LZ4_decompress_fast_usingDict (const char* src, char* dst, int originalSize, const char* dictStart, int dictSize); + + +/*^********************************************** + * !!!!!! STATIC LINKING ONLY !!!!!! + ***********************************************/ +/*-************************************ + * Private definitions + ************************************** + * Do not use these definitions. + * They are exposed to allow static allocation of `LZ4_stream_t` and `LZ4_streamDecode_t`. + * Using these definitions will expose code to API and/or ABI break in future versions of the library. + **************************************/ +#define LZ4_HASHLOG (LZ4_MEMORY_USAGE-2) +#define LZ4_HASHTABLESIZE (1 << LZ4_MEMORY_USAGE) +#define LZ4_HASH_SIZE_U32 (1 << LZ4_HASHLOG) /* required as macro for static allocation */ + +#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +#include + +typedef struct { + uint32_t hashTable[LZ4_HASH_SIZE_U32]; + uint32_t currentOffset; + uint32_t initCheck; + const uint8_t* dictionary; + uint8_t* bufferStart; /* obsolete, used for slideInputBuffer */ + uint32_t dictSize; +} LZ4_stream_t_internal; + +typedef struct { + const uint8_t* externalDict; + size_t extDictSize; + const uint8_t* prefixEnd; + size_t prefixSize; +} LZ4_streamDecode_t_internal; + +#else + +typedef struct { + unsigned int hashTable[LZ4_HASH_SIZE_U32]; + unsigned int currentOffset; + unsigned int initCheck; + const unsigned char* dictionary; + unsigned char* bufferStart; /* obsolete, used for slideInputBuffer */ + unsigned int dictSize; +} LZ4_stream_t_internal; + +typedef struct { + const unsigned char* externalDict; + size_t extDictSize; + const unsigned char* prefixEnd; + size_t prefixSize; +} LZ4_streamDecode_t_internal; + +#endif + +/*! + * LZ4_stream_t : + * information structure to track an LZ4 stream. + * init this structure before first use. + * note : only use in association with static linking ! + * this definition is not API/ABI safe, + * it may change in a future version ! + */ +#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4) +#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(unsigned long long)) +union LZ4_stream_u { + unsigned long long table[LZ4_STREAMSIZE_U64]; + LZ4_stream_t_internal internal_donotuse; +} ; /* previously typedef'd to LZ4_stream_t */ + + +/*! + * LZ4_streamDecode_t : + * information structure to track an LZ4 stream during decompression. + * init this structure using LZ4_setStreamDecode (or memset()) before first use + * note : only use in association with static linking ! + * this definition is not API/ABI safe, + * and may change in a future version ! + */ #define LZ4_STREAMDECODESIZE_U64 4 #define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long)) -typedef struct { unsigned long long table[LZ4_STREAMDECODESIZE_U64]; } LZ4_streamDecode_t; -/* - * LZ4_streamDecode_t - * information structure to track an LZ4 stream. - * init this structure content using LZ4_setStreamDecode or memset() before first use ! - * - * In the context of a DLL (liblz4) please prefer usage of construction methods below. - * They are more future proof, in case of a change of LZ4_streamDecode_t size in the future. - * LZ4_createStreamDecode will allocate and initialize an LZ4_streamDecode_t structure - * LZ4_freeStreamDecode releases its memory. - */ -LZ4_streamDecode_t* LZ4_createStreamDecode(void); -int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream); - -/* - * LZ4_setStreamDecode - * Use this function to instruct where to find the dictionary. - * Setting a size of 0 is allowed (same effect as reset). - * Return : 1 if OK, 0 if error - */ -int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize); - -/* -*_continue() : - These decoding functions allow decompression of multiple blocks in "streaming" mode. - Previously decoded blocks *must* remain available at the memory position where they were decoded (up to 64 KB) - In the case of a ring buffers, decoding buffer must be either : - - Exactly same size as encoding buffer, with same update rule (block boundaries at same positions) - In which case, the decoding & encoding ring buffer can have any size, including very small ones ( < 64 KB). - - Larger than encoding buffer, by a minimum of maxBlockSize more bytes. - maxBlockSize is implementation dependent. It's the maximum size you intend to compress into a single block. - In which case, encoding and decoding buffers do not need to be synchronized, - and encoding ring buffer can have any size, including small ones ( < 64 KB). - - _At least_ 64 KB + 8 bytes + maxBlockSize. - In which case, encoding and decoding buffers do not need to be synchronized, - and encoding ring buffer can have any size, including larger than decoding buffer. - Whenever these conditions are not possible, save the last 64KB of decoded data into a safe buffer, - and indicate where it is saved using LZ4_setStreamDecode() -*/ -int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxDecompressedSize); -int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize); +union LZ4_streamDecode_u { + unsigned long long table[LZ4_STREAMDECODESIZE_U64]; + LZ4_streamDecode_t_internal internal_donotuse; +} ; /* previously typedef'd to LZ4_streamDecode_t */ -/* -Advanced decoding functions : -*_usingDict() : - These decoding functions work the same as - a combination of LZ4_setStreamDecode() followed by LZ4_decompress_x_continue() - They are stand-alone. They don't need nor update an LZ4_streamDecode_t structure. -*/ -int LZ4_decompress_safe_usingDict (const char* source, char* dest, int compressedSize, int maxDecompressedSize, const char* dictStart, int dictSize); -int LZ4_decompress_fast_usingDict (const char* source, char* dest, int originalSize, const char* dictStart, int dictSize); - - - -/************************************** +/*-************************************ * Obsolete Functions **************************************/ -/* Deprecate Warnings */ -/* Should these warnings messages be a problem, + +/*! Deprecation warnings + Should deprecation warnings be a problem, it is generally possible to disable them, - with -Wno-deprecated-declarations for gcc - or _CRT_SECURE_NO_WARNINGS in Visual for example. - You can also define LZ4_DEPRECATE_WARNING_DEFBLOCK. */ -#ifndef LZ4_DEPRECATE_WARNING_DEFBLOCK -# define LZ4_DEPRECATE_WARNING_DEFBLOCK + typically with -Wno-deprecated-declarations for gcc + or _CRT_SECURE_NO_WARNINGS in Visual. + Otherwise, it's also possible to define LZ4_DISABLE_DEPRECATE_WARNINGS */ +#ifdef LZ4_DISABLE_DEPRECATE_WARNINGS +# define LZ4_DEPRECATED(message) /* disable deprecation warnings */ +#else # define LZ4_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) -# if (LZ4_GCC_VERSION >= 405) || defined(__clang__) +# if defined(__clang__) /* clang doesn't handle mixed C++11 and CNU attributes */ +# define LZ4_DEPRECATED(message) __attribute__((deprecated(message))) +# elif defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */ +# define LZ4_DEPRECATED(message) [[deprecated(message)]] +# elif (LZ4_GCC_VERSION >= 405) # define LZ4_DEPRECATED(message) __attribute__((deprecated(message))) # elif (LZ4_GCC_VERSION >= 301) # define LZ4_DEPRECATED(message) __attribute__((deprecated)) @@ -323,36 +447,31 @@ int LZ4_decompress_fast_usingDict (const char* source, char* dest, int originalS # pragma message("WARNING: You need to implement LZ4_DEPRECATED for this compiler") # define LZ4_DEPRECATED(message) # endif -#endif /* LZ4_DEPRECATE_WARNING_DEFBLOCK */ +#endif /* LZ4_DISABLE_DEPRECATE_WARNINGS */ /* Obsolete compression functions */ -/* These functions are planned to start generate warnings by r131 approximately */ -int LZ4_compress (const char* source, char* dest, int sourceSize); -int LZ4_compress_limitedOutput (const char* source, char* dest, int sourceSize, int maxOutputSize); -int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize); -int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize); -int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize); -int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_compress_default() instead") int LZ4_compress (const char* source, char* dest, int sourceSize); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_compress_default() instead") int LZ4_compress_limitedOutput (const char* source, char* dest, int sourceSize, int maxOutputSize); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize); /* Obsolete decompression functions */ -/* These function names are completely deprecated and must no longer be used. - They are only provided here for compatibility with older programs. - - LZ4_uncompress is the same as LZ4_decompress_fast - - LZ4_uncompress_unknownOutputSize is the same as LZ4_decompress_safe - These function prototypes are now disabled; uncomment them only if you really need them. - It is highly recommended to stop using these prototypes and migrate to maintained ones */ -/* int LZ4_uncompress (const char* source, char* dest, int outputSize); */ -/* int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize); */ +LZ4LIB_API LZ4_DEPRECATED("use LZ4_decompress_fast() instead") int LZ4_uncompress (const char* source, char* dest, int outputSize); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_decompress_safe() instead") int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize); /* Obsolete streaming functions; use new streaming interface whenever possible */ -LZ4_DEPRECATED("use LZ4_createStream() instead") void* LZ4_create (char* inputBuffer); -LZ4_DEPRECATED("use LZ4_createStream() instead") int LZ4_sizeofStreamState(void); -LZ4_DEPRECATED("use LZ4_resetStream() instead") int LZ4_resetStreamState(void* state, char* inputBuffer); -LZ4_DEPRECATED("use LZ4_saveDict() instead") char* LZ4_slideInputBuffer (void* state); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_createStream() instead") void* LZ4_create (char* inputBuffer); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_createStream() instead") int LZ4_sizeofStreamState(void); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_resetStream() instead") int LZ4_resetStreamState(void* state, char* inputBuffer); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_saveDict() instead") char* LZ4_slideInputBuffer (void* state); /* Obsolete streaming decoding functions */ -LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") int LZ4_decompress_safe_withPrefix64k (const char* src, char* dst, int compressedSize, int maxDstSize); -LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") int LZ4_decompress_fast_withPrefix64k (const char* src, char* dst, int originalSize); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") int LZ4_decompress_safe_withPrefix64k (const char* src, char* dst, int compressedSize, int maxDstSize); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") int LZ4_decompress_fast_withPrefix64k (const char* src, char* dst, int originalSize); + +#endif /* LZ4_H_2983827168210 */ #if defined (__cplusplus) diff --git a/love/src/jni/love/src/libraries/lz4/lz4hc.c b/love/src/jni/love/src/libraries/lz4/lz4hc.c index a22ab2b2..60690a03 100755 --- a/love/src/jni/love/src/libraries/lz4/lz4hc.c +++ b/love/src/jni/love/src/libraries/lz4/lz4hc.c @@ -1,6 +1,6 @@ /* LZ4 HC - High Compression Mode of LZ4 - Copyright (C) 2011-2015, Yann Collet. + Copyright (C) 2011-2017, Yann Collet. BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) @@ -28,83 +28,53 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. You can contact the author at : - - LZ4 source repository : https://github.com/Cyan4973/lz4 + - LZ4 source repository : https://github.com/lz4/lz4 - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c */ +/* note : lz4hc is not an independent module, it requires lz4.h/lz4.c for proper compilation */ - -/************************************** +/* ************************************* * Tuning Parameter -**************************************/ -static const int LZ4HC_compressionLevel_default = 9; +***************************************/ + +/*! HEAPMODE : + * Select how default compression function will allocate workplace memory, + * in stack (0:fastest), or in heap (1:requires malloc()). + * Since workplace is rather large, heap mode is recommended. + */ +#ifndef LZ4HC_HEAPMODE +# define LZ4HC_HEAPMODE 1 +#endif -/************************************** -* Includes -**************************************/ +/*=== Dependency ===*/ +#define LZ4_HC_STATIC_LINKING_ONLY #include "lz4hc.h" -/************************************** -* Local Compiler Options -**************************************/ +/*=== Common LZ4 definitions ===*/ #if defined(__GNUC__) # pragma GCC diagnostic ignored "-Wunused-function" #endif - #if defined (__clang__) # pragma clang diagnostic ignored "-Wunused-function" #endif - -/************************************** -* Common LZ4 definition -**************************************/ #define LZ4_COMMONDEFS_ONLY -#include "lz4.c" +#include "lz4.c" /* LZ4_count, constants, mem */ -/************************************** -* Local Constants -**************************************/ -#define DICTIONARY_LOGSIZE 16 -#define MAXD (1<> ((MINMATCH*8)-HASH_LOG)) -//#define DELTANEXTU16(p) chainTable[(p) & MAXD_MASK] /* flexible, MAXD dependent */ -#define DELTANEXTU16(p) chainTable[(U16)(p)] /* faster */ +/*=== Macros ===*/ +#define MIN(a,b) ( (a) < (b) ? (a) : (b) ) +#define MAX(a,b) ( (a) > (b) ? (a) : (b) ) +#define HASH_FUNCTION(i) (((i) * 2654435761U) >> ((MINMATCH*8)-LZ4HC_HASH_LOG)) +#define DELTANEXTMAXD(p) chainTable[(p) & LZ4HC_MAXD_MASK] /* flexible, LZ4HC_MAXD dependent */ +#define DELTANEXTU16(table, pos) table[(U16)(pos)] /* faster */ static U32 LZ4HC_hashPtr(const void* ptr) { return HASH_FUNCTION(LZ4_read32(ptr)); } @@ -113,7 +83,7 @@ static U32 LZ4HC_hashPtr(const void* ptr) { return HASH_FUNCTION(LZ4_read32(ptr) /************************************** * HC Compression **************************************/ -static void LZ4HC_init (LZ4HC_Data_Structure* hc4, const BYTE* start) +static void LZ4HC_init (LZ4HC_CCtx_internal* hc4, const BYTE* start) { MEM_INIT((void*)hc4->hashTable, 0, sizeof(hc4->hashTable)); MEM_INIT(hc4->chainTable, 0xFF, sizeof(hc4->chainTable)); @@ -127,84 +97,94 @@ static void LZ4HC_init (LZ4HC_Data_Structure* hc4, const BYTE* start) /* Update chains up to ip (excluded) */ -FORCE_INLINE void LZ4HC_Insert (LZ4HC_Data_Structure* hc4, const BYTE* ip) +LZ4_FORCE_INLINE void LZ4HC_Insert (LZ4HC_CCtx_internal* hc4, const BYTE* ip) { - U16* chainTable = hc4->chainTable; - U32* HashTable = hc4->hashTable; + U16* const chainTable = hc4->chainTable; + U32* const hashTable = hc4->hashTable; const BYTE* const base = hc4->base; - const U32 target = (U32)(ip - base); + U32 const target = (U32)(ip - base); U32 idx = hc4->nextToUpdate; - while(idx < target) - { - U32 h = LZ4HC_hashPtr(base+idx); - size_t delta = idx - HashTable[h]; + while (idx < target) { + U32 const h = LZ4HC_hashPtr(base+idx); + size_t delta = idx - hashTable[h]; if (delta>MAX_DISTANCE) delta = MAX_DISTANCE; - DELTANEXTU16(idx) = (U16)delta; - HashTable[h] = idx; + DELTANEXTU16(chainTable, idx) = (U16)delta; + hashTable[h] = idx; idx++; } hc4->nextToUpdate = target; } - -FORCE_INLINE int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4, /* Index table will be updated */ - const BYTE* ip, const BYTE* const iLimit, - const BYTE** matchpos, - const int maxNbAttempts) +/** LZ4HC_countBack() : + * @return : negative value, nb of common bytes before ip/match */ +LZ4_FORCE_INLINE +int LZ4HC_countBack(const BYTE* const ip, const BYTE* const match, + const BYTE* const iMin, const BYTE* const mMin) { - U16* const chainTable = hc4->chainTable; - U32* const HashTable = hc4->hashTable; - const BYTE* const base = hc4->base; - const BYTE* const dictBase = hc4->dictBase; - const U32 dictLimit = hc4->dictLimit; - const U32 lowLimit = (hc4->lowLimit + 64 KB > (U32)(ip-base)) ? hc4->lowLimit : (U32)(ip - base) - (64 KB - 1); - U32 matchIndex; - const BYTE* match; - int nbAttempts=maxNbAttempts; - size_t ml=0; - - /* HC4 match finder */ - LZ4HC_Insert(hc4, ip); - matchIndex = HashTable[LZ4HC_hashPtr(ip)]; - - while ((matchIndex>=lowLimit) && (nbAttempts)) - { - nbAttempts--; - if (matchIndex >= dictLimit) - { - match = base + matchIndex; - if (*(match+ml) == *(ip+ml) - && (LZ4_read32(match) == LZ4_read32(ip))) - { - size_t mlt = LZ4_count(ip+MINMATCH, match+MINMATCH, iLimit) + MINMATCH; - if (mlt > ml) { ml = mlt; *matchpos = match; } - } - } - else - { - match = dictBase + matchIndex; - if (LZ4_read32(match) == LZ4_read32(ip)) - { - size_t mlt; - const BYTE* vLimit = ip + (dictLimit - matchIndex); - if (vLimit > iLimit) vLimit = iLimit; - mlt = LZ4_count(ip+MINMATCH, match+MINMATCH, vLimit) + MINMATCH; - if ((ip+mlt == vLimit) && (vLimit < iLimit)) - mlt += LZ4_count(ip+mlt, base+dictLimit, iLimit); - if (mlt > ml) { ml = mlt; *matchpos = base + matchIndex; } /* virtual matchpos */ - } - } - matchIndex -= DELTANEXTU16(matchIndex); - } - - return (int)ml; + int back=0; + while ( (ip+back > iMin) + && (match+back > mMin) + && (ip[back-1] == match[back-1])) + back--; + return back; } +/* LZ4HC_countPattern() : + * pattern32 must be a sample of repetitive pattern of length 1, 2 or 4 (but not 3!) */ +static unsigned LZ4HC_countPattern(const BYTE* ip, const BYTE* const iEnd, U32 const pattern32) +{ + const BYTE* const iStart = ip; + reg_t const pattern = (sizeof(pattern)==8) ? (reg_t)pattern32 + (((reg_t)pattern32) << 32) : pattern32; -FORCE_INLINE int LZ4HC_InsertAndGetWiderMatch ( - LZ4HC_Data_Structure* hc4, + while (likely(ip < iEnd-(sizeof(pattern)-1))) { + reg_t const diff = LZ4_read_ARCH(ip) ^ pattern; + if (!diff) { ip+=sizeof(pattern); continue; } + ip += LZ4_NbCommonBytes(diff); + return (unsigned)(ip - iStart); + } + + if (LZ4_isLittleEndian()) { + reg_t patternByte = pattern; + while ((ip>= 8; + } + } else { /* big endian */ + U32 bitOffset = (sizeof(pattern)*8) - 8; + while (ip < iEnd) { + BYTE const byte = (BYTE)(pattern >> bitOffset); + if (*ip != byte) break; + ip ++; bitOffset -= 8; + } + } + + return (unsigned)(ip - iStart); +} + +/* LZ4HC_reverseCountPattern() : + * pattern must be a sample of repetitive pattern of length 1, 2 or 4 (but not 3!) + * read using natural platform endianess */ +static unsigned LZ4HC_reverseCountPattern(const BYTE* ip, const BYTE* const iLow, U32 pattern) +{ + const BYTE* const iStart = ip; + + while (likely(ip >= iLow+4)) { + if (LZ4_read32(ip-4) != pattern) break; + ip -= 4; + } + { const BYTE* bytePtr = (const BYTE*)(&pattern) + 3; /* works for any endianess */ + while (likely(ip>iLow)) { + if (ip[-1] != *bytePtr) break; + ip--; bytePtr--; + } } + return (unsigned)(iStart - ip); +} + +typedef enum { rep_untested, rep_not, rep_confirmed } repeat_state_e; + +LZ4_FORCE_INLINE int LZ4HC_InsertAndGetWiderMatch ( + LZ4HC_CCtx_internal* hc4, const BYTE* const ip, const BYTE* const iLowLimit, const BYTE* const iHighLimit, @@ -218,97 +198,167 @@ FORCE_INLINE int LZ4HC_InsertAndGetWiderMatch ( const BYTE* const base = hc4->base; const U32 dictLimit = hc4->dictLimit; const BYTE* const lowPrefixPtr = base + dictLimit; - const U32 lowLimit = (hc4->lowLimit + 64 KB > (U32)(ip-base)) ? hc4->lowLimit : (U32)(ip - base) - (64 KB - 1); + const U32 lowLimit = (hc4->lowLimit + 64 KB > (U32)(ip-base)) ? hc4->lowLimit : (U32)(ip - base) - MAX_DISTANCE; const BYTE* const dictBase = hc4->dictBase; - U32 matchIndex; + int const delta = (int)(ip-iLowLimit); int nbAttempts = maxNbAttempts; - int delta = (int)(ip-iLowLimit); - + U32 const pattern = LZ4_read32(ip); + U32 matchIndex; + repeat_state_e repeat = rep_untested; + size_t srcPatternLength = 0; + DEBUGLOG(7, "LZ4HC_InsertAndGetWiderMatch"); /* First Match */ LZ4HC_Insert(hc4, ip); matchIndex = HashTable[LZ4HC_hashPtr(ip)]; + DEBUGLOG(7, "First match at index %u / %u (lowLimit)", + matchIndex, lowLimit); - while ((matchIndex>=lowLimit) && (nbAttempts)) - { + while ((matchIndex>=lowLimit) && (nbAttempts)) { + DEBUGLOG(7, "remaining attempts : %i", nbAttempts); nbAttempts--; - if (matchIndex >= dictLimit) - { - const BYTE* matchPtr = base + matchIndex; - if (*(iLowLimit + longest) == *(matchPtr - delta + longest)) - if (LZ4_read32(matchPtr) == LZ4_read32(ip)) - { + if (matchIndex >= dictLimit) { + const BYTE* const matchPtr = base + matchIndex; + if (*(iLowLimit + longest) == *(matchPtr - delta + longest)) { + if (LZ4_read32(matchPtr) == pattern) { int mlt = MINMATCH + LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, iHighLimit); + #if 0 + /* more generic but unfortunately slower on clang */ + int const back = LZ4HC_countBack(ip, matchPtr, iLowLimit, lowPrefixPtr); + #else int back = 0; - - while ((ip+back>iLowLimit) - && (matchPtr+back > lowPrefixPtr) - && (ip[back-1] == matchPtr[back-1])) + while ( (ip+back > iLowLimit) + && (matchPtr+back > lowPrefixPtr) + && (ip[back-1] == matchPtr[back-1])) { back--; - + } + #endif mlt -= back; - if (mlt > longest) - { - longest = (int)mlt; + if (mlt > longest) { + longest = mlt; *matchpos = matchPtr+back; *startpos = ip+back; - } - } - } - else - { - const BYTE* matchPtr = dictBase + matchIndex; - if (LZ4_read32(matchPtr) == LZ4_read32(ip)) - { - size_t mlt; - int back=0; + } } + } + } else { /* matchIndex < dictLimit */ + const BYTE* const matchPtr = dictBase + matchIndex; + if (LZ4_read32(matchPtr) == pattern) { + int mlt; + int back = 0; const BYTE* vLimit = ip + (dictLimit - matchIndex); if (vLimit > iHighLimit) vLimit = iHighLimit; mlt = LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, vLimit) + MINMATCH; if ((ip+mlt == vLimit) && (vLimit < iHighLimit)) mlt += LZ4_count(ip+mlt, base+dictLimit, iHighLimit); - while ((ip+back > iLowLimit) && (matchIndex+back > lowLimit) && (ip[back-1] == matchPtr[back-1])) back--; + while ( (ip+back > iLowLimit) + && (matchIndex+back > lowLimit) + && (ip[back-1] == matchPtr[back-1])) + back--; mlt -= back; - if ((int)mlt > longest) { longest = (int)mlt; *matchpos = base + matchIndex + back; *startpos = ip+back; } - } - } - matchIndex -= DELTANEXTU16(matchIndex); - } + if (mlt > longest) { + longest = mlt; + *matchpos = base + matchIndex + back; + *startpos = ip + back; + } } } + + { U32 const nextOffset = DELTANEXTU16(chainTable, matchIndex); + matchIndex -= nextOffset; + if (nextOffset==1) { + /* may be a repeated pattern */ + if (repeat == rep_untested) { + if ( ((pattern & 0xFFFF) == (pattern >> 16)) + & ((pattern & 0xFF) == (pattern >> 24)) ) { + repeat = rep_confirmed; + srcPatternLength = LZ4HC_countPattern(ip+4, iHighLimit, pattern) + 4; + } else { + repeat = rep_not; + } } + if ( (repeat == rep_confirmed) + && (matchIndex >= dictLimit) ) { /* same segment only */ + const BYTE* const matchPtr = base + matchIndex; + if (LZ4_read32(matchPtr) == pattern) { /* good candidate */ + size_t const forwardPatternLength = LZ4HC_countPattern(matchPtr+sizeof(pattern), iHighLimit, pattern) + sizeof(pattern); + const BYTE* const maxLowPtr = (lowPrefixPtr + MAX_DISTANCE >= ip) ? lowPrefixPtr : ip - MAX_DISTANCE; + size_t const backLength = LZ4HC_reverseCountPattern(matchPtr, maxLowPtr, pattern); + size_t const currentSegmentLength = backLength + forwardPatternLength; + + if ( (currentSegmentLength >= srcPatternLength) /* current pattern segment large enough to contain full srcPatternLength */ + && (forwardPatternLength <= srcPatternLength) ) { /* haven't reached this position yet */ + matchIndex += (U32)forwardPatternLength - (U32)srcPatternLength; /* best position, full pattern, might be followed by more match */ + } else { + matchIndex -= (U32)backLength; /* let's go to farthest segment position, will find a match of length currentSegmentLength + maybe some back */ + } + } } } } + } /* while ((matchIndex>=lowLimit) && (nbAttempts)) */ return longest; } +LZ4_FORCE_INLINE +int LZ4HC_InsertAndFindBestMatch(LZ4HC_CCtx_internal* const hc4, /* Index table will be updated */ + const BYTE* const ip, const BYTE* const iLimit, + const BYTE** matchpos, + const int maxNbAttempts) +{ + const BYTE* uselessPtr = ip; + /* note : LZ4HC_InsertAndGetWiderMatch() is able to modify the starting position of a match (*startpos), + * but this won't be the case here, as we define iLowLimit==ip, + * so LZ4HC_InsertAndGetWiderMatch() won't be allowed to search past ip */ + return LZ4HC_InsertAndGetWiderMatch(hc4, ip, ip, iLimit, MINMATCH-1, matchpos, &uselessPtr, maxNbAttempts); +} -typedef enum { noLimit = 0, limitedOutput = 1 } limitedOutput_directive; -#define LZ4HC_DEBUG 0 -#if LZ4HC_DEBUG -static unsigned debug = 0; -#endif -FORCE_INLINE int LZ4HC_encodeSequence ( +typedef enum { + noLimit = 0, + limitedOutput = 1, + limitedDestSize = 2, +} limitedOutput_directive; + +/* LZ4HC_encodeSequence() : + * @return : 0 if ok, + * 1 if buffer issue detected */ +LZ4_FORCE_INLINE int LZ4HC_encodeSequence ( const BYTE** ip, BYTE** op, const BYTE** anchor, int matchLength, const BYTE* const match, - limitedOutput_directive limitedOutputBuffer, + limitedOutput_directive limit, BYTE* oend) { - int length; - BYTE* token; + size_t length; + BYTE* const token = (*op)++; -#if LZ4HC_DEBUG - if (debug) printf("literal : %u -- match : %u -- offset : %u\n", (U32)(*ip - *anchor), (U32)matchLength, (U32)(*ip-match)); +#if defined(LZ4_DEBUG) && (LZ4_DEBUG >= 2) + static const BYTE* start = NULL; + static U32 totalCost = 0; + U32 const pos = (start==NULL) ? 0 : (U32)(*anchor - start); + U32 const ll = (U32)(*ip - *anchor); + U32 const llAdd = (ll>=15) ? ((ll-15) / 255) + 1 : 0; + U32 const mlAdd = (matchLength>=19) ? ((matchLength-19) / 255) + 1 : 0; + U32 const cost = 1 + llAdd + ll + 2 + mlAdd; + if (start==NULL) start = *anchor; /* only works for single segment */ + //g_debuglog_enable = (pos >= 2228) & (pos <= 2262); + DEBUGLOG(2, "pos:%7u -- literals:%3u, match:%4i, offset:%5u, cost:%3u + %u", + pos, + (U32)(*ip - *anchor), matchLength, (U32)(*ip-match), + cost, totalCost); + totalCost += cost; #endif /* Encode Literal length */ - length = (int)(*ip - *anchor); - token = (*op)++; - if ((limitedOutputBuffer) && ((*op + (length>>8) + length + (2 + 1 + LASTLITERALS)) > oend)) return 1; /* Check output limit */ - if (length>=(int)RUN_MASK) { int len; *token=(RUN_MASK< 254 ; len-=255) *(*op)++ = 255; *(*op)++ = (BYTE)len; } - else *token = (BYTE)(length<> 8) + length + (2 + 1 + LASTLITERALS)) > oend)) return 1; /* Check output limit */ + if (length >= RUN_MASK) { + size_t len = length - RUN_MASK; + *token = (RUN_MASK << ML_BITS); + for(; len >= 255 ; len -= 255) *(*op)++ = 255; + *(*op)++ = (BYTE)len; + } else { + *token = (BYTE)(length << ML_BITS); + } /* Copy Literals */ LZ4_wildCopy(*op, *anchor, (*op) + length); @@ -318,10 +368,18 @@ FORCE_INLINE int LZ4HC_encodeSequence ( LZ4_writeLE16(*op, (U16)(*ip-match)); *op += 2; /* Encode MatchLength */ - length = (int)(matchLength-MINMATCH); - if ((limitedOutputBuffer) && (*op + (length>>8) + (1 + LASTLITERALS) > oend)) return 1; /* Check output limit */ - if (length>=(int)ML_MASK) { *token+=ML_MASK; length-=ML_MASK; for(; length > 509 ; length-=510) { *(*op)++ = 255; *(*op)++ = 255; } if (length > 254) { length-=255; *(*op)++ = 255; } *(*op)++ = (BYTE)length; } - else *token += (BYTE)(length); + assert(matchLength >= MINMATCH); + length = (size_t)(matchLength - MINMATCH); + if ((limit) && (*op + (length >> 8) + (1 + LASTLITERALS) > oend)) return 1; /* Check output limit */ + if (length >= ML_MASK) { + *token += ML_MASK; + length -= ML_MASK; + for(; length >= 510 ; length -= 510) { *(*op)++ = 255; *(*op)++ = 255; } + if (length >= 255) { length -= 255; *(*op)++ = 255; } + *(*op)++ = (BYTE)length; + } else { + *token += (BYTE)(length); + } /* Prepare next loop */ *ip += matchLength; @@ -330,51 +388,53 @@ FORCE_INLINE int LZ4HC_encodeSequence ( return 0; } +/* btopt */ +#include "lz4opt.h" -static int LZ4HC_compress_generic ( - void* ctxvoid, - const char* source, - char* dest, - int inputSize, - int maxOutputSize, - int compressionLevel, + +static int LZ4HC_compress_hashChain ( + LZ4HC_CCtx_internal* const ctx, + const char* const source, + char* const dest, + int* srcSizePtr, + int const maxOutputSize, + unsigned maxNbAttempts, limitedOutput_directive limit ) { - LZ4HC_Data_Structure* ctx = (LZ4HC_Data_Structure*) ctxvoid; + const int inputSize = *srcSizePtr; + const BYTE* ip = (const BYTE*) source; const BYTE* anchor = ip; const BYTE* const iend = ip + inputSize; const BYTE* const mflimit = iend - MFLIMIT; const BYTE* const matchlimit = (iend - LASTLITERALS); + BYTE* optr = (BYTE*) dest; BYTE* op = (BYTE*) dest; - BYTE* const oend = op + maxOutputSize; + BYTE* oend = op + maxOutputSize; - unsigned maxNbAttempts; int ml, ml2, ml3, ml0; - const BYTE* ref=NULL; - const BYTE* start2=NULL; - const BYTE* ref2=NULL; - const BYTE* start3=NULL; - const BYTE* ref3=NULL; + const BYTE* ref = NULL; + const BYTE* start2 = NULL; + const BYTE* ref2 = NULL; + const BYTE* start3 = NULL; + const BYTE* ref3 = NULL; const BYTE* start0; const BYTE* ref0; - /* init */ - if (compressionLevel > g_maxCompressionLevel) compressionLevel = g_maxCompressionLevel; - if (compressionLevel < 1) compressionLevel = LZ4HC_compressionLevel_default; - maxNbAttempts = 1 << (compressionLevel-1); - ctx->end += inputSize; + *srcSizePtr = 0; + if (limit == limitedDestSize && maxOutputSize < 1) return 0; /* Impossible to store anything */ + if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size, too large (or negative) */ - ip++; + if (limit == limitedDestSize) oend -= LASTLITERALS; /* Hack for support limitations LZ4 decompressor */ + if (inputSize < LZ4_minLength) goto _last_literals; /* Input too small, no compression (all literals) */ /* Main Loop */ - while (ip < mflimit) - { - ml = LZ4HC_InsertAndFindBestMatch (ctx, ip, matchlimit, (&ref), maxNbAttempts); - if (!ml) { ip++; continue; } + while (ip < mflimit) { + ml = LZ4HC_InsertAndFindBestMatch (ctx, ip, matchlimit, &ref, maxNbAttempts); + if (ml ml1, and - * ip1+3 <= ip2 (usually < ip1+ml1) - */ - if ((start2 - ip) < OPTIMAL_ML) - { + /* At this stage, we have : + * ml2 > ml1, and + * ip1+3 <= ip2 (usually < ip1+ml1) */ + if ((start2 - ip) < OPTIMAL_ML) { int correction; int new_ml = ml; if (new_ml > OPTIMAL_ML) new_ml = OPTIMAL_ML; if (ip+new_ml > start2 + ml2 - MINMATCH) new_ml = (int)(start2 - ip) + ml2 - MINMATCH; correction = new_ml - (int)(start2 - ip); - if (correction > 0) - { + if (correction > 0) { start2 += correction; ref2 += correction; ml2 -= correction; @@ -435,38 +489,37 @@ _Search3: if (start2 + ml2 < mflimit) ml3 = LZ4HC_InsertAndGetWiderMatch(ctx, start2 + ml2 - 3, start2, matchlimit, ml2, &ref3, &start3, maxNbAttempts); - else ml3 = ml2; + else + ml3 = ml2; - if (ml3 == ml2) /* No better match : 2 sequences to encode */ - { + if (ml3 == ml2) { /* No better match : 2 sequences to encode */ /* ip & ref are known; Now for ml */ if (start2 < ip+ml) ml = (int)(start2 - ip); /* Now, encode 2 sequences */ - if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0; + optr = op; + if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) goto _dest_overflow; ip = start2; - if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml2, ref2, limit, oend)) return 0; + optr = op; + if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml2, ref2, limit, oend)) goto _dest_overflow; continue; } - if (start3 < ip+ml+3) /* Not enough space for match 2 : remove it */ - { - if (start3 >= (ip+ml)) /* can write Seq1 immediately ==> Seq2 is removed, so Seq3 becomes Seq1 */ - { - if (start2 < ip+ml) - { + if (start3 < ip+ml+3) { /* Not enough space for match 2 : remove it */ + if (start3 >= (ip+ml)) { /* can write Seq1 immediately ==> Seq2 is removed, so Seq3 becomes Seq1 */ + if (start2 < ip+ml) { int correction = (int)(ip+ml - start2); start2 += correction; ref2 += correction; ml2 -= correction; - if (ml2 < MINMATCH) - { + if (ml2 < MINMATCH) { start2 = start3; ref2 = ref3; ml2 = ml3; } } - if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0; + optr = op; + if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) goto _dest_overflow; ip = start3; ref = ref3; ml = ml3; @@ -487,27 +540,23 @@ _Search3: * OK, now we have 3 ascending matches; let's write at least the first one * ip & ref are known; Now for ml */ - if (start2 < ip+ml) - { - if ((start2 - ip) < (int)ML_MASK) - { + if (start2 < ip+ml) { + if ((start2 - ip) < (int)ML_MASK) { int correction; if (ml > OPTIMAL_ML) ml = OPTIMAL_ML; if (ip + ml > start2 + ml2 - MINMATCH) ml = (int)(start2 - ip) + ml2 - MINMATCH; correction = ml - (int)(start2 - ip); - if (correction > 0) - { + if (correction > 0) { start2 += correction; ref2 += correction; ml2 -= correction; } - } - else - { + } else { ml = (int)(start2 - ip); } } - if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0; + optr = op; + if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) goto _dest_overflow; ip = start2; ref = ref2; @@ -520,37 +569,110 @@ _Search3: goto _Search3; } +_last_literals: /* Encode Last Literals */ - { - int lastRun = (int)(iend - anchor); - if ((limit) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) return 0; /* Check output limit */ - if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK< 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; } - else *op++ = (BYTE)(lastRun< oend)) { + if (limit == limitedOutput) return 0; /* Check output limit */ + /* adapt lastRunSize to fill 'dest' */ + lastRunSize = (size_t)(oend - op) - 1; + litLength = (lastRunSize + 255 - RUN_MASK) / 255; + lastRunSize -= litLength; + } + ip = anchor + lastRunSize; + + if (lastRunSize >= RUN_MASK) { + size_t accumulator = lastRunSize - RUN_MASK; + *op++ = (RUN_MASK << ML_BITS); + for(; accumulator >= 255 ; accumulator -= 255) *op++ = 255; + *op++ = (BYTE) accumulator; + } else { + *op++ = (BYTE)(lastRunSize << ML_BITS); + } + memcpy(op, anchor, lastRunSize); + op += lastRunSize; } /* End */ + *srcSizePtr = (int) (((const char*)ip) - source); return (int) (((char*)op)-dest); + +_dest_overflow: + if (limit == limitedDestSize) { + op = optr; /* restore correct out pointer */ + goto _last_literals; + } + return 0; } -int LZ4_sizeofStateHC(void) { return sizeof(LZ4HC_Data_Structure); } - -int LZ4_compress_HC_extStateHC (void* state, const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel) +static int LZ4HC_compress_generic ( + LZ4HC_CCtx_internal* const ctx, + const char* const src, + char* const dst, + int* const srcSizePtr, + int const dstCapacity, + int cLevel, + limitedOutput_directive limit + ) { + ctx->end += *srcSizePtr; + if (cLevel < 1) cLevel = LZ4HC_CLEVEL_DEFAULT; /* note : convention is different from lz4frame, maybe something to review */ + if (cLevel > 9) { + if (limit == limitedDestSize) cLevel = 10; + switch (cLevel) { + case 10: + return LZ4HC_compress_hashChain(ctx, src, dst, srcSizePtr, dstCapacity, 1<<12, limit); + case 11: + return LZ4HC_compress_optimal(ctx, src, dst, *srcSizePtr, dstCapacity, limit, 512, 128, 0); + default: + /* fall-through */ + case 12: + return LZ4HC_compress_optimal(ctx, src, dst, *srcSizePtr, dstCapacity, limit, 1<<13, LZ4_OPT_NUM, 1); + } + } + return LZ4HC_compress_hashChain(ctx, src, dst, srcSizePtr, dstCapacity, 1 << (cLevel-1), limit); /* levels 1-9 */ +} + + +int LZ4_sizeofStateHC(void) { return sizeof(LZ4_streamHC_t); } + +int LZ4_compress_HC_extStateHC (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int compressionLevel) +{ + LZ4HC_CCtx_internal* const ctx = &((LZ4_streamHC_t*)state)->internal_donotuse; if (((size_t)(state)&(sizeof(void*)-1)) != 0) return 0; /* Error : state is not aligned for pointers (32 or 64 bits) */ - LZ4HC_init ((LZ4HC_Data_Structure*)state, (const BYTE*)src); - if (maxDstSize < LZ4_compressBound(srcSize)) - return LZ4HC_compress_generic (state, src, dst, srcSize, maxDstSize, compressionLevel, limitedOutput); + LZ4HC_init (ctx, (const BYTE*)src); + if (dstCapacity < LZ4_compressBound(srcSize)) + return LZ4HC_compress_generic (ctx, src, dst, &srcSize, dstCapacity, compressionLevel, limitedOutput); else - return LZ4HC_compress_generic (state, src, dst, srcSize, maxDstSize, compressionLevel, noLimit); + return LZ4HC_compress_generic (ctx, src, dst, &srcSize, dstCapacity, compressionLevel, noLimit); } -int LZ4_compress_HC(const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel) +int LZ4_compress_HC(const char* src, char* dst, int srcSize, int dstCapacity, int compressionLevel) { - LZ4HC_Data_Structure state; - return LZ4_compress_HC_extStateHC(&state, src, dst, srcSize, maxDstSize, compressionLevel); +#if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1 + LZ4_streamHC_t* const statePtr = (LZ4_streamHC_t*)malloc(sizeof(LZ4_streamHC_t)); +#else + LZ4_streamHC_t state; + LZ4_streamHC_t* const statePtr = &state; +#endif + int const cSize = LZ4_compress_HC_extStateHC(statePtr, src, dst, srcSize, dstCapacity, compressionLevel); +#if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1 + free(statePtr); +#endif + return cSize; +} + +/* LZ4_compress_HC_destSize() : + * only compatible with Hash Chain match finder */ +int LZ4_compress_HC_destSize(void* LZ4HC_Data, const char* source, char* dest, int* sourceSizePtr, int targetDestSize, int cLevel) +{ + LZ4HC_CCtx_internal* const ctx = &((LZ4_streamHC_t*)LZ4HC_Data)->internal_donotuse; + LZ4HC_init(ctx, (const BYTE*) source); + return LZ4HC_compress_generic(ctx, source, dest, sourceSizePtr, targetDestSize, cLevel, limitedDestSize); } @@ -560,38 +682,48 @@ int LZ4_compress_HC(const char* src, char* dst, int srcSize, int maxDstSize, int **************************************/ /* allocation */ LZ4_streamHC_t* LZ4_createStreamHC(void) { return (LZ4_streamHC_t*)malloc(sizeof(LZ4_streamHC_t)); } -int LZ4_freeStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr) { free(LZ4_streamHCPtr); return 0; } +int LZ4_freeStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr) { + if (!LZ4_streamHCPtr) return 0; /* support free on NULL */ + free(LZ4_streamHCPtr); + return 0; +} /* initialization */ void LZ4_resetStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel) { - LZ4_STATIC_ASSERT(sizeof(LZ4HC_Data_Structure) <= sizeof(LZ4_streamHC_t)); /* if compilation fails here, LZ4_STREAMHCSIZE must be increased */ - ((LZ4HC_Data_Structure*)LZ4_streamHCPtr)->base = NULL; - ((LZ4HC_Data_Structure*)LZ4_streamHCPtr)->compressionLevel = (unsigned)compressionLevel; + LZ4_STATIC_ASSERT(sizeof(LZ4HC_CCtx_internal) <= sizeof(size_t) * LZ4_STREAMHCSIZE_SIZET); /* if compilation fails here, LZ4_STREAMHCSIZE must be increased */ + LZ4_streamHCPtr->internal_donotuse.base = NULL; + LZ4_setCompressionLevel(LZ4_streamHCPtr, compressionLevel); +} + +void LZ4_setCompressionLevel(LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel) +{ + if (compressionLevel < 1) compressionLevel = 1; + if (compressionLevel > LZ4HC_CLEVEL_MAX) compressionLevel = LZ4HC_CLEVEL_MAX; + LZ4_streamHCPtr->internal_donotuse.compressionLevel = compressionLevel; } int LZ4_loadDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, const char* dictionary, int dictSize) { - LZ4HC_Data_Structure* ctxPtr = (LZ4HC_Data_Structure*) LZ4_streamHCPtr; - if (dictSize > 64 KB) - { + LZ4HC_CCtx_internal* const ctxPtr = &LZ4_streamHCPtr->internal_donotuse; + if (dictSize > 64 KB) { dictionary += dictSize - 64 KB; dictSize = 64 KB; } LZ4HC_init (ctxPtr, (const BYTE*)dictionary); - if (dictSize >= 4) LZ4HC_Insert (ctxPtr, (const BYTE*)dictionary +(dictSize-3)); ctxPtr->end = (const BYTE*)dictionary + dictSize; + if (dictSize >= 4) LZ4HC_Insert (ctxPtr, ctxPtr->end-3); return dictSize; } /* compression */ -static void LZ4HC_setExternalDict(LZ4HC_Data_Structure* ctxPtr, const BYTE* newBlock) +static void LZ4HC_setExternalDict(LZ4HC_CCtx_internal* ctxPtr, const BYTE* newBlock) { - if (ctxPtr->end >= ctxPtr->base + 4) - LZ4HC_Insert (ctxPtr, ctxPtr->end-3); /* Referencing remaining dictionary content */ + if (ctxPtr->end >= ctxPtr->base + 4) LZ4HC_Insert (ctxPtr, ctxPtr->end-3); /* Referencing remaining dictionary content */ + /* Only one memory segment for extDict, so any previous extDict is lost at this stage */ ctxPtr->lowLimit = ctxPtr->dictLimit; ctxPtr->dictLimit = (U32)(ctxPtr->end - ctxPtr->base); @@ -601,64 +733,65 @@ static void LZ4HC_setExternalDict(LZ4HC_Data_Structure* ctxPtr, const BYTE* newB ctxPtr->nextToUpdate = ctxPtr->dictLimit; /* match referencing will resume from there */ } -static int LZ4_compressHC_continue_generic (LZ4HC_Data_Structure* ctxPtr, - const char* source, char* dest, - int inputSize, int maxOutputSize, limitedOutput_directive limit) +static int LZ4_compressHC_continue_generic (LZ4_streamHC_t* LZ4_streamHCPtr, + const char* src, char* dst, + int* srcSizePtr, int dstCapacity, + limitedOutput_directive limit) { + LZ4HC_CCtx_internal* const ctxPtr = &LZ4_streamHCPtr->internal_donotuse; /* auto-init if forgotten */ - if (ctxPtr->base == NULL) - LZ4HC_init (ctxPtr, (const BYTE*) source); + if (ctxPtr->base == NULL) LZ4HC_init (ctxPtr, (const BYTE*) src); /* Check overflow */ - if ((size_t)(ctxPtr->end - ctxPtr->base) > 2 GB) - { + if ((size_t)(ctxPtr->end - ctxPtr->base) > 2 GB) { size_t dictSize = (size_t)(ctxPtr->end - ctxPtr->base) - ctxPtr->dictLimit; if (dictSize > 64 KB) dictSize = 64 KB; - - LZ4_loadDictHC((LZ4_streamHC_t*)ctxPtr, (const char*)(ctxPtr->end) - dictSize, (int)dictSize); + LZ4_loadDictHC(LZ4_streamHCPtr, (const char*)(ctxPtr->end) - dictSize, (int)dictSize); } /* Check if blocks follow each other */ - if ((const BYTE*)source != ctxPtr->end) - LZ4HC_setExternalDict(ctxPtr, (const BYTE*)source); + if ((const BYTE*)src != ctxPtr->end) LZ4HC_setExternalDict(ctxPtr, (const BYTE*)src); /* Check overlapping input/dictionary space */ - { - const BYTE* sourceEnd = (const BYTE*) source + inputSize; - const BYTE* dictBegin = ctxPtr->dictBase + ctxPtr->lowLimit; - const BYTE* dictEnd = ctxPtr->dictBase + ctxPtr->dictLimit; - if ((sourceEnd > dictBegin) && ((const BYTE*)source < dictEnd)) - { + { const BYTE* sourceEnd = (const BYTE*) src + *srcSizePtr; + const BYTE* const dictBegin = ctxPtr->dictBase + ctxPtr->lowLimit; + const BYTE* const dictEnd = ctxPtr->dictBase + ctxPtr->dictLimit; + if ((sourceEnd > dictBegin) && ((const BYTE*)src < dictEnd)) { if (sourceEnd > dictEnd) sourceEnd = dictEnd; ctxPtr->lowLimit = (U32)(sourceEnd - ctxPtr->dictBase); if (ctxPtr->dictLimit - ctxPtr->lowLimit < 4) ctxPtr->lowLimit = ctxPtr->dictLimit; } } - return LZ4HC_compress_generic (ctxPtr, source, dest, inputSize, maxOutputSize, ctxPtr->compressionLevel, limit); + return LZ4HC_compress_generic (ctxPtr, src, dst, srcSizePtr, dstCapacity, ctxPtr->compressionLevel, limit); } -int LZ4_compress_HC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize, int maxOutputSize) +int LZ4_compress_HC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* src, char* dst, int srcSize, int dstCapacity) { - if (maxOutputSize < LZ4_compressBound(inputSize)) - return LZ4_compressHC_continue_generic ((LZ4HC_Data_Structure*)LZ4_streamHCPtr, source, dest, inputSize, maxOutputSize, limitedOutput); + if (dstCapacity < LZ4_compressBound(srcSize)) + return LZ4_compressHC_continue_generic (LZ4_streamHCPtr, src, dst, &srcSize, dstCapacity, limitedOutput); else - return LZ4_compressHC_continue_generic ((LZ4HC_Data_Structure*)LZ4_streamHCPtr, source, dest, inputSize, maxOutputSize, noLimit); + return LZ4_compressHC_continue_generic (LZ4_streamHCPtr, src, dst, &srcSize, dstCapacity, noLimit); } +int LZ4_compress_HC_continue_destSize (LZ4_streamHC_t* LZ4_streamHCPtr, const char* src, char* dst, int* srcSizePtr, int targetDestSize) +{ + return LZ4_compressHC_continue_generic(LZ4_streamHCPtr, src, dst, srcSizePtr, targetDestSize, limitedDestSize); +} + + /* dictionary saving */ int LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, int dictSize) { - LZ4HC_Data_Structure* streamPtr = (LZ4HC_Data_Structure*)LZ4_streamHCPtr; - int prefixSize = (int)(streamPtr->end - (streamPtr->base + streamPtr->dictLimit)); + LZ4HC_CCtx_internal* const streamPtr = &LZ4_streamHCPtr->internal_donotuse; + int const prefixSize = (int)(streamPtr->end - (streamPtr->base + streamPtr->dictLimit)); if (dictSize > 64 KB) dictSize = 64 KB; if (dictSize < 4) dictSize = 0; if (dictSize > prefixSize) dictSize = prefixSize; memmove(safeBuffer, streamPtr->end - dictSize, dictSize); - { - U32 endIndex = (U32)(streamPtr->end - streamPtr->base); + { U32 const endIndex = (U32)(streamPtr->end - streamPtr->base); streamPtr->end = (const BYTE*)safeBuffer + dictSize; streamPtr->base = streamPtr->end - endIndex; streamPtr->dictLimit = endIndex - dictSize; @@ -672,8 +805,8 @@ int LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, int dictS /*********************************** * Deprecated Functions ***********************************/ +/* These functions currently generate deprecation warnings */ /* Deprecated compression functions */ -/* These functions are planned to start generate warnings by r131 approximately */ int LZ4_compressHC(const char* src, char* dst, int srcSize) { return LZ4_compress_HC (src, dst, srcSize, LZ4_compressBound(srcSize), 0); } int LZ4_compressHC_limitedOutput(const char* src, char* dst, int srcSize, int maxDstSize) { return LZ4_compress_HC(src, dst, srcSize, maxDstSize, 0); } int LZ4_compressHC2(const char* src, char* dst, int srcSize, int cLevel) { return LZ4_compress_HC (src, dst, srcSize, LZ4_compressBound(srcSize), cLevel); } @@ -687,44 +820,45 @@ int LZ4_compressHC_limitedOutput_continue (LZ4_streamHC_t* ctx, const char* src, /* Deprecated streaming functions */ -/* These functions currently generate deprecation warnings */ int LZ4_sizeofStreamStateHC(void) { return LZ4_STREAMHCSIZE; } int LZ4_resetStreamStateHC(void* state, char* inputBuffer) { + LZ4HC_CCtx_internal *ctx = &((LZ4_streamHC_t*)state)->internal_donotuse; if ((((size_t)state) & (sizeof(void*)-1)) != 0) return 1; /* Error : pointer is not aligned for pointer (32 or 64 bits) */ - LZ4HC_init((LZ4HC_Data_Structure*)state, (const BYTE*)inputBuffer); - ((LZ4HC_Data_Structure*)state)->inputBuffer = (BYTE*)inputBuffer; + LZ4HC_init(ctx, (const BYTE*)inputBuffer); + ctx->inputBuffer = (BYTE*)inputBuffer; return 0; } void* LZ4_createHC (char* inputBuffer) { - void* hc4 = ALLOCATOR(1, sizeof(LZ4HC_Data_Structure)); - LZ4HC_init ((LZ4HC_Data_Structure*)hc4, (const BYTE*)inputBuffer); - ((LZ4HC_Data_Structure*)hc4)->inputBuffer = (BYTE*)inputBuffer; + LZ4_streamHC_t* hc4 = (LZ4_streamHC_t*)ALLOCATOR(1, sizeof(LZ4_streamHC_t)); + if (hc4 == NULL) return NULL; /* not enough memory */ + LZ4HC_init (&hc4->internal_donotuse, (const BYTE*)inputBuffer); + hc4->internal_donotuse.inputBuffer = (BYTE*)inputBuffer; return hc4; } -int LZ4_freeHC (void* LZ4HC_Data) -{ +int LZ4_freeHC (void* LZ4HC_Data) { + if (!LZ4HC_Data) return 0; /* support free on NULL */ FREEMEM(LZ4HC_Data); - return (0); + return 0; } -int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel) +int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* src, char* dst, int srcSize, int cLevel) { - return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, 0, compressionLevel, noLimit); + return LZ4HC_compress_generic (&((LZ4_streamHC_t*)LZ4HC_Data)->internal_donotuse, src, dst, &srcSize, 0, cLevel, noLimit); } -int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel) +int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* src, char* dst, int srcSize, int dstCapacity, int cLevel) { - return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, maxOutputSize, compressionLevel, limitedOutput); + return LZ4HC_compress_generic (&((LZ4_streamHC_t*)LZ4HC_Data)->internal_donotuse, src, dst, &srcSize, dstCapacity, cLevel, limitedOutput); } char* LZ4_slideInputBufferHC(void* LZ4HC_Data) { - LZ4HC_Data_Structure* hc4 = (LZ4HC_Data_Structure*)LZ4HC_Data; - int dictSize = LZ4_saveDictHC((LZ4_streamHC_t*)LZ4HC_Data, (char*)(hc4->inputBuffer), 64 KB); + LZ4HC_CCtx_internal* const hc4 = &((LZ4_streamHC_t*)LZ4HC_Data)->internal_donotuse; + int const dictSize = LZ4_saveDictHC((LZ4_streamHC_t*)LZ4HC_Data, (char*)(hc4->inputBuffer), 64 KB); return (char*)(hc4->inputBuffer + dictSize); } diff --git a/love/src/jni/love/src/libraries/lz4/lz4hc.h b/love/src/jni/love/src/libraries/lz4/lz4hc.h index 431f7c87..d7910623 100755 --- a/love/src/jni/love/src/libraries/lz4/lz4hc.h +++ b/love/src/jni/love/src/libraries/lz4/lz4hc.h @@ -1,7 +1,7 @@ /* LZ4 HC - High Compression Mode of LZ4 Header File - Copyright (C) 2011-2015, Yann Collet. + Copyright (C) 2011-2017, Yann Collet. BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) Redistribution and use in source and binary forms, with or without @@ -28,162 +28,245 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. You can contact the author at : - - LZ4 source repository : https://github.com/Cyan4973/lz4 + - LZ4 source repository : https://github.com/lz4/lz4 - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c */ -#pragma once - +#ifndef LZ4_HC_H_19834876238432 +#define LZ4_HC_H_19834876238432 #if defined (__cplusplus) extern "C" { #endif -/***************************** -* Includes -*****************************/ -#include /* size_t */ +/* --- Dependency --- */ +/* note : lz4hc requires lz4.h/lz4.c for compilation */ +#include "lz4.h" /* stddef, LZ4LIB_API, LZ4_DEPRECATED */ -/************************************** -* Block Compression -**************************************/ -int LZ4_compress_HC (const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel); -/* -LZ4_compress_HC : - Destination buffer 'dst' must be already allocated. - Compression completion is guaranteed if 'dst' buffer is sized to handle worst circumstances (data not compressible) - Worst size evaluation is provided by function LZ4_compressBound() (see "lz4.h") - srcSize : Max supported value is LZ4_MAX_INPUT_SIZE (see "lz4.h") - compressionLevel : Recommended values are between 4 and 9, although any value between 0 and 16 will work. - 0 means "use default value" (see lz4hc.c). - Values >16 behave the same as 16. - return : the number of bytes written into buffer 'dst' - or 0 if compression fails. -*/ +/* --- Useful constants --- */ +#define LZ4HC_CLEVEL_MIN 3 +#define LZ4HC_CLEVEL_DEFAULT 9 +#define LZ4HC_CLEVEL_OPT_MIN 11 +#define LZ4HC_CLEVEL_MAX 12 + + +/*-************************************ + * Block Compression + **************************************/ +/*! LZ4_compress_HC() : + * Compress data from `src` into `dst`, using the more powerful but slower "HC" algorithm. + * `dst` must be already allocated. + * Compression is guaranteed to succeed if `dstCapacity >= LZ4_compressBound(srcSize)` (see "lz4.h") + * Max supported `srcSize` value is LZ4_MAX_INPUT_SIZE (see "lz4.h") + * `compressionLevel` : any value between 1 and LZ4HC_CLEVEL_MAX will work. + * Values > LZ4HC_CLEVEL_MAX behave the same as LZ4HC_CLEVEL_MAX. + * @return : the number of bytes written into 'dst' + * or 0 if compression fails. + */ +LZ4LIB_API int LZ4_compress_HC (const char* src, char* dst, int srcSize, int dstCapacity, int compressionLevel); /* Note : - Decompression functions are provided within LZ4 source code (see "lz4.h") (BSD license) -*/ + * Decompression functions are provided within "lz4.h" (BSD license) + */ -int LZ4_sizeofStateHC(void); -int LZ4_compress_HC_extStateHC(void* state, const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel); -/* -LZ4_compress_HC_extStateHC() : - Use this function if you prefer to manually allocate memory for compression tables. - To know how much memory must be allocated for the compression tables, use : - int LZ4_sizeofStateHC(); - - Allocated memory must be aligned on 8-bytes boundaries (which a normal malloc() will do properly). - - The allocated memory can then be provided to the compression functions using 'void* state' parameter. - LZ4_compress_HC_extStateHC() is equivalent to previously described function. - It just uses externally allocated memory for stateHC. -*/ +/*! LZ4_compress_HC_extStateHC() : + * Same as LZ4_compress_HC(), but using an externally allocated memory segment for `state`. + * `state` size is provided by LZ4_sizeofStateHC(). + * Memory segment must be aligned on 8-bytes boundaries (which a normal malloc() should do properly). + */ +LZ4LIB_API int LZ4_sizeofStateHC(void); +LZ4LIB_API int LZ4_compress_HC_extStateHC(void* state, const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel); -/************************************** -* Streaming Compression -**************************************/ -#define LZ4_STREAMHCSIZE 262192 -#define LZ4_STREAMHCSIZE_SIZET (LZ4_STREAMHCSIZE / sizeof(size_t)) -typedef struct { size_t table[LZ4_STREAMHCSIZE_SIZET]; } LZ4_streamHC_t; -/* - LZ4_streamHC_t - This structure allows static allocation of LZ4 HC streaming state. - State must then be initialized using LZ4_resetStreamHC() before first use. +/*-************************************ + * Streaming Compression + * Bufferless synchronous API + **************************************/ + typedef union LZ4_streamHC_u LZ4_streamHC_t; /* incomplete type (defined later) */ - Static allocation should only be used in combination with static linking. - If you want to use LZ4 as a DLL, please use construction functions below, which are future-proof. -*/ +/*! LZ4_createStreamHC() and LZ4_freeStreamHC() : + * These functions create and release memory for LZ4 HC streaming state. + * Newly created states are automatically initialized. + * Existing states can be re-used several times, using LZ4_resetStreamHC(). + * These methods are API and ABI stable, they can be used in combination with a DLL. + */ +LZ4LIB_API LZ4_streamHC_t* LZ4_createStreamHC(void); +LZ4LIB_API int LZ4_freeStreamHC (LZ4_streamHC_t* streamHCPtr); +LZ4LIB_API void LZ4_resetStreamHC (LZ4_streamHC_t* streamHCPtr, int compressionLevel); +LZ4LIB_API int LZ4_loadDictHC (LZ4_streamHC_t* streamHCPtr, const char* dictionary, int dictSize); -LZ4_streamHC_t* LZ4_createStreamHC(void); -int LZ4_freeStreamHC (LZ4_streamHC_t* streamHCPtr); -/* - These functions create and release memory for LZ4 HC streaming state. - Newly created states are already initialized. - Existing state space can be re-used anytime using LZ4_resetStreamHC(). - If you use LZ4 as a DLL, use these functions instead of static structure allocation, - to avoid size mismatch between different versions. -*/ +LZ4LIB_API int LZ4_compress_HC_continue (LZ4_streamHC_t* streamHCPtr, const char* src, char* dst, int srcSize, int maxDstSize); -void LZ4_resetStreamHC (LZ4_streamHC_t* streamHCPtr, int compressionLevel); -int LZ4_loadDictHC (LZ4_streamHC_t* streamHCPtr, const char* dictionary, int dictSize); - -int LZ4_compress_HC_continue (LZ4_streamHC_t* streamHCPtr, const char* src, char* dst, int srcSize, int maxDstSize); - -int LZ4_saveDictHC (LZ4_streamHC_t* streamHCPtr, char* safeBuffer, int maxDictSize); +LZ4LIB_API int LZ4_saveDictHC (LZ4_streamHC_t* streamHCPtr, char* safeBuffer, int maxDictSize); /* These functions compress data in successive blocks of any size, using previous blocks as dictionary. One key assumption is that previous blocks (up to 64 KB) remain read-accessible while compressing next blocks. - There is an exception for ring buffers, which can be smaller 64 KB. - Such case is automatically detected and correctly handled by LZ4_compress_HC_continue(). + There is an exception for ring buffers, which can be smaller than 64 KB. + Ring buffers scenario is automatically detected and handled by LZ4_compress_HC_continue(). Before starting compression, state must be properly initialized, using LZ4_resetStreamHC(). A first "fictional block" can then be designated as initial dictionary, using LZ4_loadDictHC() (Optional). Then, use LZ4_compress_HC_continue() to compress each successive block. - It works like LZ4_compress_HC(), but use previous memory blocks as dictionary to improve compression. Previous memory blocks (including initial dictionary when present) must remain accessible and unmodified during compression. - As a reminder, size 'dst' buffer to handle worst cases, using LZ4_compressBound(), to ensure success of compression operation. + 'dst' buffer should be sized to handle worst case scenarios (see LZ4_compressBound()), to ensure operation success. + Because in case of failure, the API does not guarantee context recovery, and context will have to be reset. + If `dst` buffer budget cannot be >= LZ4_compressBound(), consider using LZ4_compress_HC_continue_destSize() instead. - If, for any reason, previous data blocks can't be preserved unmodified in memory during next compression block, - you must save it to a safer memory space, using LZ4_saveDictHC(). + If, for any reason, previous data block can't be preserved unmodified in memory for next compression block, + you can save it to a more stable memory space, using LZ4_saveDictHC(). Return value of LZ4_saveDictHC() is the size of dictionary effectively saved into 'safeBuffer'. */ +/*-************************************************************** + * PRIVATE DEFINITIONS : + * Do not use these definitions. + * They are exposed to allow static allocation of `LZ4_streamHC_t`. + * Using these definitions makes the code vulnerable to potential API break when upgrading LZ4 + ****************************************************************/ +#define LZ4HC_DICTIONARY_LOGSIZE 16 +#define LZ4HC_MAXD (1<= 199901L) /* C99 */) +#include + +typedef struct +{ + uint32_t hashTable[LZ4HC_HASHTABLESIZE]; + uint16_t chainTable[LZ4HC_MAXD]; + const uint8_t* end; /* next block here to continue on current prefix */ + const uint8_t* base; /* All index relative to this position */ + const uint8_t* dictBase; /* alternate base for extDict */ + uint8_t* inputBuffer; /* deprecated */ + uint32_t dictLimit; /* below that point, need extDict */ + uint32_t lowLimit; /* below that point, no more dict */ + uint32_t nextToUpdate; /* index from which to continue dictionary update */ + int compressionLevel; +} LZ4HC_CCtx_internal; + +#else + +typedef struct +{ + unsigned int hashTable[LZ4HC_HASHTABLESIZE]; + unsigned short chainTable[LZ4HC_MAXD]; + const unsigned char* end; /* next block here to continue on current prefix */ + const unsigned char* base; /* All index relative to this position */ + const unsigned char* dictBase; /* alternate base for extDict */ + unsigned char* inputBuffer; /* deprecated */ + unsigned int dictLimit; /* below that point, need extDict */ + unsigned int lowLimit; /* below that point, no more dict */ + unsigned int nextToUpdate; /* index from which to continue dictionary update */ + int compressionLevel; +} LZ4HC_CCtx_internal; + +#endif + +#define LZ4_STREAMHCSIZE (4*LZ4HC_HASHTABLESIZE + 2*LZ4HC_MAXD + 56) /* 262200 */ +#define LZ4_STREAMHCSIZE_SIZET (LZ4_STREAMHCSIZE / sizeof(size_t)) +union LZ4_streamHC_u { + size_t table[LZ4_STREAMHCSIZE_SIZET]; + LZ4HC_CCtx_internal internal_donotuse; +}; /* previously typedef'd to LZ4_streamHC_t */ +/* + LZ4_streamHC_t : + This structure allows static allocation of LZ4 HC streaming state. + State must be initialized using LZ4_resetStreamHC() before first use. + + Static allocation shall only be used in combination with static linking. + When invoking LZ4 from a DLL, use create/free functions instead, which are API and ABI stable. +*/ + + +/*-************************************ * Deprecated Functions **************************************/ -/* Deprecate Warnings */ -/* Should these warnings messages be a problem, - it is generally possible to disable them, - with -Wno-deprecated-declarations for gcc - or _CRT_SECURE_NO_WARNINGS in Visual for example. - You can also define LZ4_DEPRECATE_WARNING_DEFBLOCK. */ -#ifndef LZ4_DEPRECATE_WARNING_DEFBLOCK -# define LZ4_DEPRECATE_WARNING_DEFBLOCK -# define LZ4_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) -# if (LZ4_GCC_VERSION >= 405) || defined(__clang__) -# define LZ4_DEPRECATED(message) __attribute__((deprecated(message))) -# elif (LZ4_GCC_VERSION >= 301) -# define LZ4_DEPRECATED(message) __attribute__((deprecated)) -# elif defined(_MSC_VER) -# define LZ4_DEPRECATED(message) __declspec(deprecated(message)) -# else -# pragma message("WARNING: You need to implement LZ4_DEPRECATED for this compiler") -# define LZ4_DEPRECATED(message) -# endif -#endif // LZ4_DEPRECATE_WARNING_DEFBLOCK +/* see lz4.h LZ4_DISABLE_DEPRECATE_WARNINGS to turn off deprecation warnings */ -/* compression functions */ -/* these functions are planned to trigger warning messages by r131 approximately */ -int LZ4_compressHC (const char* source, char* dest, int inputSize); -int LZ4_compressHC_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize); -int LZ4_compressHC2 (const char* source, char* dest, int inputSize, int compressionLevel); -int LZ4_compressHC2_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel); -int LZ4_compressHC_withStateHC (void* state, const char* source, char* dest, int inputSize); -int LZ4_compressHC_limitedOutput_withStateHC (void* state, const char* source, char* dest, int inputSize, int maxOutputSize); -int LZ4_compressHC2_withStateHC (void* state, const char* source, char* dest, int inputSize, int compressionLevel); -int LZ4_compressHC2_limitedOutput_withStateHC(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel); -int LZ4_compressHC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize); -int LZ4_compressHC_limitedOutput_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize, int maxOutputSize); +/* deprecated compression functions */ +LZ4LIB_API LZ4_DEPRECATED("use LZ4_compress_HC() instead") int LZ4_compressHC (const char* source, char* dest, int inputSize); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_compress_HC() instead") int LZ4_compressHC_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_compress_HC() instead") int LZ4_compressHC2 (const char* source, char* dest, int inputSize, int compressionLevel); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_compress_HC() instead") int LZ4_compressHC2_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") int LZ4_compressHC_withStateHC (void* state, const char* source, char* dest, int inputSize); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") int LZ4_compressHC_limitedOutput_withStateHC (void* state, const char* source, char* dest, int inputSize, int maxOutputSize); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") int LZ4_compressHC2_withStateHC (void* state, const char* source, char* dest, int inputSize, int compressionLevel); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") int LZ4_compressHC2_limitedOutput_withStateHC(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") int LZ4_compressHC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") int LZ4_compressHC_limitedOutput_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize, int maxOutputSize); -/* Streaming functions following the older model; should no longer be used */ -LZ4_DEPRECATED("use LZ4_createStreamHC() instead") void* LZ4_createHC (char* inputBuffer); -LZ4_DEPRECATED("use LZ4_saveDictHC() instead") char* LZ4_slideInputBufferHC (void* LZ4HC_Data); -LZ4_DEPRECATED("use LZ4_freeStreamHC() instead") int LZ4_freeHC (void* LZ4HC_Data); -LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel); -LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel); -LZ4_DEPRECATED("use LZ4_createStreamHC() instead") int LZ4_sizeofStreamStateHC(void); -LZ4_DEPRECATED("use LZ4_resetStreamHC() instead") int LZ4_resetStreamStateHC(void* state, char* inputBuffer); +/* Deprecated Streaming functions using older model; should no longer be used */ +LZ4LIB_API LZ4_DEPRECATED("use LZ4_createStreamHC() instead") void* LZ4_createHC (char* inputBuffer); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_saveDictHC() instead") char* LZ4_slideInputBufferHC (void* LZ4HC_Data); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_freeStreamHC() instead") int LZ4_freeHC (void* LZ4HC_Data); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_createStreamHC() instead") int LZ4_sizeofStreamStateHC(void); +LZ4LIB_API LZ4_DEPRECATED("use LZ4_resetStreamHC() instead") int LZ4_resetStreamStateHC(void* state, char* inputBuffer); #if defined (__cplusplus) } #endif + +#endif /* LZ4_HC_H_19834876238432 */ + + +/*-************************************************** + * !!!!! STATIC LINKING ONLY !!!!! + * Following definitions are considered experimental. + * They should not be linked from DLL, + * as there is no guarantee of API stability yet. + * Prototypes will be promoted to "stable" status + * after successfull usage in real-life scenarios. + ***************************************************/ +#ifdef LZ4_HC_STATIC_LINKING_ONLY /* protection macro */ +#ifndef LZ4_HC_SLO_098092834 +#define LZ4_HC_SLO_098092834 + +/*! LZ4_compress_HC_destSize() : v1.8.0 (experimental) + * Will try to compress as much data from `src` as possible + * that can fit into `targetDstSize` budget. + * Result is provided in 2 parts : + * @return : the number of bytes written into 'dst' + * or 0 if compression fails. + * `srcSizePtr` : value will be updated to indicate how much bytes were read from `src` + */ +int LZ4_compress_HC_destSize(void* LZ4HC_Data, + const char* src, char* dst, + int* srcSizePtr, int targetDstSize, + int compressionLevel); + +/*! LZ4_compress_HC_continue_destSize() : v1.8.0 (experimental) + * Similar as LZ4_compress_HC_continue(), + * but will read a variable nb of bytes from `src` + * to fit into `targetDstSize` budget. + * Result is provided in 2 parts : + * @return : the number of bytes written into 'dst' + * or 0 if compression fails. + * `srcSizePtr` : value will be updated to indicate how much bytes were read from `src`. + */ +int LZ4_compress_HC_continue_destSize(LZ4_streamHC_t* LZ4_streamHCPtr, + const char* src, char* dst, + int* srcSizePtr, int targetDstSize); + +/*! LZ4_setCompressionLevel() : v1.8.0 (experimental) + * It's possible to change compression level between 2 invocations of LZ4_compress_HC_continue*() + */ +void LZ4_setCompressionLevel(LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel); + + + +#endif /* LZ4_HC_SLO_098092834 */ +#endif /* LZ4_HC_STATIC_LINKING_ONLY */ diff --git a/love/src/jni/love/src/libraries/lz4/lz4opt.h b/love/src/jni/love/src/libraries/lz4/lz4opt.h new file mode 100755 index 00000000..9917851e --- /dev/null +++ b/love/src/jni/love/src/libraries/lz4/lz4opt.h @@ -0,0 +1,329 @@ +/* + lz4opt.h - Optimal Mode of LZ4 + Copyright (C) 2015-2017, Przemyslaw Skibinski + Note : this file is intended to be included within lz4hc.c + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - LZ4 source repository : https://github.com/lz4/lz4 + - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c +*/ + +#define LZ4_OPT_NUM (1<<12) + +typedef struct { + int price; + int off; + int mlen; + int litlen; +} LZ4HC_optimal_t; + + +/* price in bytes */ +LZ4_FORCE_INLINE int LZ4HC_literalsPrice(int const litlen) +{ + int price = litlen; + if (litlen >= (int)RUN_MASK) + price += 1 + (litlen-RUN_MASK)/255; + return price; +} + + +/* requires mlen >= MINMATCH */ +LZ4_FORCE_INLINE int LZ4HC_sequencePrice(int litlen, int mlen) +{ + int price = 1 + 2 ; /* token + 16-bit offset */ + + price += LZ4HC_literalsPrice(litlen); + + if (mlen >= (int)(ML_MASK+MINMATCH)) + price += 1 + (mlen-(ML_MASK+MINMATCH))/255; + + return price; +} + + +/*-************************************* +* Match finder +***************************************/ +typedef struct { + int off; + int len; +} LZ4HC_match_t; + +LZ4_FORCE_INLINE +LZ4HC_match_t LZ4HC_FindLongerMatch(LZ4HC_CCtx_internal* const ctx, + const BYTE* ip, const BYTE* const iHighLimit, + int minLen, int nbSearches) +{ + LZ4HC_match_t match = { 0 , 0 }; + const BYTE* matchPtr = NULL; + /* note : LZ4HC_InsertAndGetWiderMatch() is able to modify the starting position of a match (*startpos), + * but this won't be the case here, as we define iLowLimit==ip, + * so LZ4HC_InsertAndGetWiderMatch() won't be allowed to search past ip */ + int const matchLength = LZ4HC_InsertAndGetWiderMatch(ctx, ip, ip, iHighLimit, minLen, &matchPtr, &ip, nbSearches); + if (matchLength <= minLen) return match; + match.len = matchLength; + match.off = (int)(ip-matchPtr); + return match; +} + + +static int LZ4HC_compress_optimal ( + LZ4HC_CCtx_internal* ctx, + const char* const source, + char* dst, + int inputSize, + int dstCapacity, + limitedOutput_directive limit, + int const nbSearches, + size_t sufficient_len, + int const fullUpdate + ) +{ +#define TRAILING_LITERALS 3 + LZ4HC_optimal_t opt[LZ4_OPT_NUM + TRAILING_LITERALS]; /* this uses a bit too much stack memory to my taste ... */ + + const BYTE* ip = (const BYTE*) source; + const BYTE* anchor = ip; + const BYTE* const iend = ip + inputSize; + const BYTE* const mflimit = iend - MFLIMIT; + const BYTE* const matchlimit = iend - LASTLITERALS; + BYTE* op = (BYTE*) dst; + BYTE* const oend = op + dstCapacity; + + /* init */ + DEBUGLOG(5, "LZ4HC_compress_optimal"); + if (sufficient_len >= LZ4_OPT_NUM) sufficient_len = LZ4_OPT_NUM-1; + + /* Main Loop */ + assert(ip - anchor < LZ4_MAX_INPUT_SIZE); + while (ip < mflimit) { + int const llen = (int)(ip - anchor); + int best_mlen, best_off; + int cur, last_match_pos = 0; + + LZ4HC_match_t const firstMatch = LZ4HC_FindLongerMatch(ctx, ip, matchlimit, MINMATCH-1, nbSearches); + if (firstMatch.len==0) { ip++; continue; } + + if ((size_t)firstMatch.len > sufficient_len) { + /* good enough solution : immediate encoding */ + int const firstML = firstMatch.len; + const BYTE* const matchPos = ip - firstMatch.off; + if ( LZ4HC_encodeSequence(&ip, &op, &anchor, firstML, matchPos, limit, oend) ) /* updates ip, op and anchor */ + return 0; /* error */ + continue; + } + + /* set prices for first positions (literals) */ + { int rPos; + for (rPos = 0 ; rPos < MINMATCH ; rPos++) { + int const cost = LZ4HC_literalsPrice(llen + rPos); + opt[rPos].mlen = 1; + opt[rPos].off = 0; + opt[rPos].litlen = llen + rPos; + opt[rPos].price = cost; + DEBUGLOG(7, "rPos:%3i => price:%3i (litlen=%i) -- initial setup", + rPos, cost, opt[rPos].litlen); + } } + /* set prices using initial match */ + { int mlen = MINMATCH; + int const matchML = firstMatch.len; /* necessarily < sufficient_len < LZ4_OPT_NUM */ + int const offset = firstMatch.off; + assert(matchML < LZ4_OPT_NUM); + for ( ; mlen <= matchML ; mlen++) { + int const cost = LZ4HC_sequencePrice(llen, mlen); + opt[mlen].mlen = mlen; + opt[mlen].off = offset; + opt[mlen].litlen = llen; + opt[mlen].price = cost; + DEBUGLOG(7, "rPos:%3i => price:%3i (matchlen=%i) -- initial setup", + mlen, cost, mlen); + } } + last_match_pos = firstMatch.len; + { int addLit; + for (addLit = 1; addLit <= TRAILING_LITERALS; addLit ++) { + opt[last_match_pos+addLit].mlen = 1; /* literal */ + opt[last_match_pos+addLit].off = 0; + opt[last_match_pos+addLit].litlen = addLit; + opt[last_match_pos+addLit].price = opt[last_match_pos].price + LZ4HC_literalsPrice(addLit); + DEBUGLOG(7, "rPos:%3i => price:%3i (litlen=%i) -- initial setup", + last_match_pos+addLit, opt[last_match_pos+addLit].price, addLit); + } } + + /* check further positions */ + for (cur = 1; cur < last_match_pos; cur++) { + const BYTE* const curPtr = ip + cur; + LZ4HC_match_t newMatch; + + if (curPtr >= mflimit) break; + DEBUGLOG(7, "rPos:%u[%u] vs [%u]%u", + cur, opt[cur].price, opt[cur+1].price, cur+1); + if (fullUpdate) { + /* not useful to search here if next position has same (or lower) cost */ + if ( (opt[cur+1].price <= opt[cur].price) + /* in some cases, next position has same cost, but cost rises sharply after, so a small match would still be beneficial */ + && (opt[cur+MINMATCH].price < opt[cur].price + 3/*min seq price*/) ) + continue; + } else { + /* not useful to search here if next position has same (or lower) cost */ + if (opt[cur+1].price <= opt[cur].price) continue; + } + + DEBUGLOG(7, "search at rPos:%u", cur); + if (fullUpdate) + newMatch = LZ4HC_FindLongerMatch(ctx, curPtr, matchlimit, MINMATCH-1, nbSearches); + else + /* only test matches of minimum length; slightly faster, but misses a few bytes */ + newMatch = LZ4HC_FindLongerMatch(ctx, curPtr, matchlimit, last_match_pos - cur, nbSearches); + if (!newMatch.len) continue; + + if ( ((size_t)newMatch.len > sufficient_len) + || (newMatch.len + cur >= LZ4_OPT_NUM) ) { + /* immediate encoding */ + best_mlen = newMatch.len; + best_off = newMatch.off; + last_match_pos = cur + 1; + goto encode; + } + + /* before match : set price with literals at beginning */ + { int const baseLitlen = opt[cur].litlen; + int litlen; + for (litlen = 1; litlen < MINMATCH; litlen++) { + int const price = opt[cur].price - LZ4HC_literalsPrice(baseLitlen) + LZ4HC_literalsPrice(baseLitlen+litlen); + int const pos = cur + litlen; + if (price < opt[pos].price) { + opt[pos].mlen = 1; /* literal */ + opt[pos].off = 0; + opt[pos].litlen = baseLitlen+litlen; + opt[pos].price = price; + DEBUGLOG(7, "rPos:%3i => price:%3i (litlen=%i)", + pos, price, opt[pos].litlen); + } } } + + /* set prices using match at position = cur */ + { int const matchML = newMatch.len; + int ml = MINMATCH; + + assert(cur + newMatch.len < LZ4_OPT_NUM); + for ( ; ml <= matchML ; ml++) { + int const pos = cur + ml; + int const offset = newMatch.off; + int price; + int ll; + DEBUGLOG(7, "testing price rPos %i (last_match_pos=%i)", + pos, last_match_pos); + if (opt[cur].mlen == 1) { + ll = opt[cur].litlen; + price = ((cur > ll) ? opt[cur - ll].price : 0) + + LZ4HC_sequencePrice(ll, ml); + } else { + ll = 0; + price = opt[cur].price + LZ4HC_sequencePrice(0, ml); + } + + if (pos > last_match_pos+TRAILING_LITERALS || price <= opt[pos].price) { + DEBUGLOG(7, "rPos:%3i => price:%3i (matchlen=%i)", + pos, price, ml); + assert(pos < LZ4_OPT_NUM); + if ( (ml == matchML) /* last pos of last match */ + && (last_match_pos < pos) ) + last_match_pos = pos; + opt[pos].mlen = ml; + opt[pos].off = offset; + opt[pos].litlen = ll; + opt[pos].price = price; + } } } + /* complete following positions with literals */ + { int addLit; + for (addLit = 1; addLit <= TRAILING_LITERALS; addLit ++) { + opt[last_match_pos+addLit].mlen = 1; /* literal */ + opt[last_match_pos+addLit].off = 0; + opt[last_match_pos+addLit].litlen = addLit; + opt[last_match_pos+addLit].price = opt[last_match_pos].price + LZ4HC_literalsPrice(addLit); + DEBUGLOG(7, "rPos:%3i => price:%3i (litlen=%i)", last_match_pos+addLit, opt[last_match_pos+addLit].price, addLit); + } } + } /* for (cur = 1; cur <= last_match_pos; cur++) */ + + best_mlen = opt[last_match_pos].mlen; + best_off = opt[last_match_pos].off; + cur = last_match_pos - best_mlen; + +encode: /* cur, last_match_pos, best_mlen, best_off must be set */ + assert(cur < LZ4_OPT_NUM); + assert(last_match_pos >= 1); /* == 1 when only one candidate */ + DEBUGLOG(6, "reverse traversal, looking for shortest path") + DEBUGLOG(6, "last_match_pos = %i", last_match_pos); + { int candidate_pos = cur; + int selected_matchLength = best_mlen; + int selected_offset = best_off; + while (1) { /* from end to beginning */ + int const next_matchLength = opt[candidate_pos].mlen; /* can be 1, means literal */ + int const next_offset = opt[candidate_pos].off; + DEBUGLOG(6, "pos %i: sequence length %i", candidate_pos, selected_matchLength); + opt[candidate_pos].mlen = selected_matchLength; + opt[candidate_pos].off = selected_offset; + selected_matchLength = next_matchLength; + selected_offset = next_offset; + if (next_matchLength > candidate_pos) break; /* last match elected, first match to encode */ + assert(next_matchLength > 0); /* can be 1, means literal */ + candidate_pos -= next_matchLength; + } } + + /* encode all recorded sequences in order */ + { int rPos = 0; /* relative position (to ip) */ + while (rPos < last_match_pos) { + int const ml = opt[rPos].mlen; + int const offset = opt[rPos].off; + if (ml == 1) { ip++; rPos++; continue; } /* literal; note: can end up with several literals, in which case, skip them */ + rPos += ml; + assert(ml >= MINMATCH); + assert((offset >= 1) && (offset <= MAX_DISTANCE)); + if ( LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ip - offset, limit, oend) ) /* updates ip, op and anchor */ + return 0; /* error */ + } } + } /* while (ip < mflimit) */ + + /* Encode Last Literals */ + { int lastRun = (int)(iend - anchor); + if ( (limit) + && (((char*)op - dst) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)dstCapacity)) + return 0; /* Check output limit */ + if (lastRun >= (int)RUN_MASK) { + *op++=(RUN_MASK< 254 ; lastRun-=255) *op++ = 255; + *op++ = (BYTE) lastRun; + } else *op++ = (BYTE)(lastRun< // ptrdiff_t on osx #include #include +#include #if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) #include // ldexp @@ -649,12 +585,14 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1]; #define STBI__X86_TARGET #endif -#if defined(__GNUC__) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) && !defined(__SSE2__) && !defined(STBI_NO_SIMD) -// NOTE: not clear do we actually need this for the 64-bit path? +#if defined(__GNUC__) && defined(STBI__X86_TARGET) && !defined(__SSE2__) && !defined(STBI_NO_SIMD) // gcc doesn't support sse2 intrinsics unless you compile with -msse2, -// (but compiling with -msse2 allows the compiler to use SSE2 everywhere; -// this is just broken and gcc are jerks for not fixing it properly -// http://www.virtualdub.org/blog/pivot/entry.php?id=363 ) +// which in turn means it gets to use SSE2 everywhere. This is unfortunate, +// but previous attempts to provide the SSE2 functions with runtime +// detection caused numerous issues. The way architecture extensions are +// exposed in GCC/Clang is, sadly, not really suited for one-file libs. +// New behavior: if compiled with -msse2, we use SSE2 without any +// detection; if not, we don't use it at all. #define STBI_NO_SIMD #endif @@ -702,7 +640,7 @@ static int stbi__cpuid3(void) #define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name -static int stbi__sse2_available() +static int stbi__sse2_available(void) { int info3 = stbi__cpuid3(); return ((info3 >> 26) & 1) != 0; @@ -710,22 +648,12 @@ static int stbi__sse2_available() #else // assume GCC-style if not VC++ #define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) -static int stbi__sse2_available() +static int stbi__sse2_available(void) { -#if defined(STBI__X64_TARGET) - // on x64, SSE2 can be assumed to be available. + // If we're even attempting to compile this on GCC/Clang, that means + // -msse2 is on, which means the compiler is allowed to use SSE2 + // instructions at will, and so are we. return 1; -#elif defined(LOVE_STBI_SSE2_OVERRIDE) - return 1; -#else -# warning "stb_image compiled without SSE2 support, define LOVE_STBI_SSE2_OVERRIDE to force SSE2 support" - // __builtin_cpu_supports is buggy on GCC 5 and above, causing problems if - // referenced in a shared object, giving missing __cpu_model hidden symbol errors. - // To get around that, just assume that SSE2 is not available on x86. - // - // See https://github.com/nothings/stb/issues/280 for more information. - return 0; -#endif } #endif #endif @@ -833,57 +761,70 @@ static void stbi__rewind(stbi__context *s) s->img_buffer_end = s->img_buffer_original_end; } +enum +{ + STBI_ORDER_RGB, + STBI_ORDER_BGR +}; + +typedef struct +{ + int bits_per_channel; + int num_channels; + int channel_order; +} stbi__result_info; + #ifndef STBI_NO_JPEG static int stbi__jpeg_test(stbi__context *s); -static stbi_uc *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_PNG static int stbi__png_test(stbi__context *s); -static stbi_uc *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_BMP static int stbi__bmp_test(stbi__context *s); -static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_TGA static int stbi__tga_test(stbi__context *s); -static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_PSD static int stbi__psd_test(stbi__context *s); -static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc); static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_HDR static int stbi__hdr_test(stbi__context *s); -static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_PIC static int stbi__pic_test(stbi__context *s); -static stbi_uc *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static void *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_GIF static int stbi__gif_test(stbi__context *s); -static stbi_uc *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp); #endif #ifndef STBI_NO_PNM static int stbi__pnm_test(stbi__context *s); -static stbi_uc *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp); +static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp); #endif @@ -906,6 +847,77 @@ static void *stbi__malloc(size_t size) return STBI_MALLOC(size); } +// stb_image uses ints pervasively, including for offset calculations. +// therefore the largest decoded image size we can support with the +// current code, even on 64-bit targets, is INT_MAX. this is not a +// significant limitation for the intended use case. +// +// we do, however, need to make sure our size calculations don't +// overflow. hence a few helper functions for size calculations that +// multiply integers together, making sure that they're non-negative +// and no overflow occurs. + +// return 1 if the sum is valid, 0 on overflow. +// negative terms are considered invalid. +static int stbi__addsizes_valid(int a, int b) +{ + if (b < 0) return 0; + // now 0 <= b <= INT_MAX, hence also + // 0 <= INT_MAX - b <= INTMAX. + // And "a + b <= INT_MAX" (which might overflow) is the + // same as a <= INT_MAX - b (no overflow) + return a <= INT_MAX - b; +} + +// returns 1 if the product is valid, 0 on overflow. +// negative factors are considered invalid. +static int stbi__mul2sizes_valid(int a, int b) +{ + if (a < 0 || b < 0) return 0; + if (b == 0) return 1; // mul-by-0 is always safe + // portable way to check for no overflows in a*b + return a <= INT_MAX/b; +} + +// returns 1 if "a*b + add" has no negative terms/factors and doesn't overflow +static int stbi__mad2sizes_valid(int a, int b, int add) +{ + return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a*b, add); +} + +// returns 1 if "a*b*c + add" has no negative terms/factors and doesn't overflow +static int stbi__mad3sizes_valid(int a, int b, int c, int add) +{ + return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && + stbi__addsizes_valid(a*b*c, add); +} + +// returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow +static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add) +{ + return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && + stbi__mul2sizes_valid(a*b*c, d) && stbi__addsizes_valid(a*b*c*d, add); +} + +// mallocs with size overflow checking +static void *stbi__malloc_mad2(int a, int b, int add) +{ + if (!stbi__mad2sizes_valid(a, b, add)) return NULL; + return stbi__malloc(a*b + add); +} + +static void *stbi__malloc_mad3(int a, int b, int c, int add) +{ + if (!stbi__mad3sizes_valid(a, b, c, add)) return NULL; + return stbi__malloc(a*b*c + add); +} + +static void *stbi__malloc_mad4(int a, int b, int c, int d, int add) +{ + if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL; + return stbi__malloc(a*b*c*d + add); +} + // stbi__err - error // stbi__errpf - error returning pointer to float // stbi__errpuc - error returning pointer to unsigned char @@ -941,33 +953,38 @@ STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip) stbi__vertically_flip_on_load = flag_true_if_should_flip; } -static unsigned char *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp) +static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) { + memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields + ri->bits_per_channel = 8; // default is 8 so most paths don't have to be changed + ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order + ri->num_channels = 0; + #ifndef STBI_NO_JPEG - if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp); + if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri); #endif #ifndef STBI_NO_PNG - if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp); + if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp, ri); #endif #ifndef STBI_NO_BMP - if (stbi__bmp_test(s)) return stbi__bmp_load(s,x,y,comp,req_comp); + if (stbi__bmp_test(s)) return stbi__bmp_load(s,x,y,comp,req_comp, ri); #endif #ifndef STBI_NO_GIF - if (stbi__gif_test(s)) return stbi__gif_load(s,x,y,comp,req_comp); + if (stbi__gif_test(s)) return stbi__gif_load(s,x,y,comp,req_comp, ri); #endif #ifndef STBI_NO_PSD - if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp); + if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp, ri, bpc); #endif #ifndef STBI_NO_PIC - if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp); + if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp, ri); #endif #ifndef STBI_NO_PNM - if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp); + if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp, ri); #endif #ifndef STBI_NO_HDR if (stbi__hdr_test(s)) { - float *hdr = stbi__hdr_load(s, x,y,comp,req_comp); + float *hdr = stbi__hdr_load(s, x,y,comp,req_comp, ri); return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); } #endif @@ -975,56 +992,123 @@ static unsigned char *stbi__load_main(stbi__context *s, int *x, int *y, int *com #ifndef STBI_NO_TGA // test tga last because it's a crappy test! if (stbi__tga_test(s)) - return stbi__tga_load(s,x,y,comp,req_comp); + return stbi__tga_load(s,x,y,comp,req_comp, ri); #endif return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt"); } -static unsigned char *stbi__load_flip(stbi__context *s, int *x, int *y, int *comp, int req_comp) +static stbi_uc *stbi__convert_16_to_8(stbi__uint16 *orig, int w, int h, int channels) { - unsigned char *result = stbi__load_main(s, x, y, comp, req_comp); + int i; + int img_len = w * h * channels; + stbi_uc *reduced; - if (stbi__vertically_flip_on_load && result != NULL) { - int w = *x, h = *y; - int depth = req_comp ? req_comp : *comp; - int row,col,z; - stbi_uc temp; + reduced = (stbi_uc *) stbi__malloc(img_len); + if (reduced == NULL) return stbi__errpuc("outofmem", "Out of memory"); - // @OPTIMIZE: use a bigger temp buffer and memcpy multiple pixels at once - for (row = 0; row < (h>>1); row++) { - for (col = 0; col < w; col++) { - for (z = 0; z < depth; z++) { - temp = result[(row * w + col) * depth + z]; - result[(row * w + col) * depth + z] = result[((h - row - 1) * w + col) * depth + z]; - result[((h - row - 1) * w + col) * depth + z] = temp; - } - } + for (i = 0; i < img_len; ++i) + reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling + + STBI_FREE(orig); + return reduced; +} + +static stbi__uint16 *stbi__convert_8_to_16(stbi_uc *orig, int w, int h, int channels) +{ + int i; + int img_len = w * h * channels; + stbi__uint16 *enlarged; + + enlarged = (stbi__uint16 *) stbi__malloc(img_len*2); + if (enlarged == NULL) return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); + + for (i = 0; i < img_len; ++i) + enlarged[i] = (stbi__uint16)((orig[i] << 8) + orig[i]); // replicate to high and low byte, maps 0->0, 255->0xffff + + STBI_FREE(orig); + return enlarged; +} + +static void stbi__vertical_flip(void *image, int w, int h, int bytes_per_pixel) +{ + int row; + size_t bytes_per_row = (size_t)w * bytes_per_pixel; + stbi_uc temp[2048]; + stbi_uc *bytes = (stbi_uc *)image; + + for (row = 0; row < (h>>1); row++) { + stbi_uc *row0 = bytes + row*bytes_per_row; + stbi_uc *row1 = bytes + (h - row - 1)*bytes_per_row; + // swap row0 with row1 + size_t bytes_left = bytes_per_row; + while (bytes_left) { + size_t bytes_copy = (bytes_left < sizeof(temp)) ? bytes_left : sizeof(temp); + memcpy(temp, row0, bytes_copy); + memcpy(row0, row1, bytes_copy); + memcpy(row1, temp, bytes_copy); + row0 += bytes_copy; + row1 += bytes_copy; + bytes_left -= bytes_copy; } } +} - return result; +static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi__result_info ri; + void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 8); + + if (result == NULL) + return NULL; + + if (ri.bits_per_channel != 8) { + STBI_ASSERT(ri.bits_per_channel == 16); + result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp); + ri.bits_per_channel = 8; + } + + // @TODO: move stbi__convert_format to here + + if (stbi__vertically_flip_on_load) { + int channels = req_comp ? req_comp : *comp; + stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi_uc)); + } + + return (unsigned char *) result; +} + +static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi__result_info ri; + void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 16); + + if (result == NULL) + return NULL; + + if (ri.bits_per_channel != 16) { + STBI_ASSERT(ri.bits_per_channel == 8); + result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp); + ri.bits_per_channel = 16; + } + + // @TODO: move stbi__convert_format16 to here + // @TODO: special case RGB-to-Y (and RGBA-to-YA) for 8-bit-to-16-bit case to keep more precision + + if (stbi__vertically_flip_on_load) { + int channels = req_comp ? req_comp : *comp; + stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi__uint16)); + } + + return (stbi__uint16 *) result; } #ifndef STBI_NO_HDR static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp) { if (stbi__vertically_flip_on_load && result != NULL) { - int w = *x, h = *y; - int depth = req_comp ? req_comp : *comp; - int row,col,z; - float temp; - - // @OPTIMIZE: use a bigger temp buffer and memcpy multiple pixels at once - for (row = 0; row < (h>>1); row++) { - for (col = 0; col < w; col++) { - for (z = 0; z < depth; z++) { - temp = result[(row * w + col) * depth + z]; - result[(row * w + col) * depth + z] = result[((h - row - 1) * w + col) * depth + z]; - result[((h - row - 1) * w + col) * depth + z] = temp; - } - } - } + int channels = req_comp ? req_comp : *comp; + stbi__vertical_flip(result, *x, *y, channels * sizeof(float)); } } #endif @@ -1059,27 +1143,66 @@ STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req unsigned char *result; stbi__context s; stbi__start_file(&s,f); - result = stbi__load_flip(&s,x,y,comp,req_comp); + result = stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); if (result) { // need to 'unget' all the characters in the IO buffer fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR); } return result; } + +STBIDEF stbi__uint16 *stbi_load_from_file_16(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + stbi__uint16 *result; + stbi__context s; + stbi__start_file(&s,f); + result = stbi__load_and_postprocess_16bit(&s,x,y,comp,req_comp); + if (result) { + // need to 'unget' all the characters in the IO buffer + fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR); + } + return result; +} + +STBIDEF stbi_us *stbi_load_16(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + FILE *f = stbi__fopen(filename, "rb"); + stbi__uint16 *result; + if (!f) return (stbi_us *) stbi__errpuc("can't fopen", "Unable to open file"); + result = stbi_load_from_file_16(f,x,y,comp,req_comp); + fclose(f); + return result; +} + + #endif //!STBI_NO_STDIO +STBIDEF stbi_us *stbi_load_16_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels); +} + +STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *)clbk, user); + return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels); +} + STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) { stbi__context s; stbi__start_mem(&s,buffer,len); - return stbi__load_flip(&s,x,y,comp,req_comp); + return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); } STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) { stbi__context s; stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); - return stbi__load_flip(&s,x,y,comp,req_comp); + return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); } #ifndef STBI_NO_LINEAR @@ -1088,13 +1211,14 @@ static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int unsigned char *data; #ifndef STBI_NO_HDR if (stbi__hdr_test(s)) { - float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp); + stbi__result_info ri; + float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp, &ri); if (hdr_data) stbi__float_postprocess(hdr_data,x,y,comp,req_comp); return hdr_data; } #endif - data = stbi__load_flip(s, x, y, comp, req_comp); + data = stbi__load_and_postprocess_8bit(s, x, y, comp, req_comp); if (data) return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); return stbi__errpf("unknown image type", "Image not of any known type, or corrupt"); @@ -1301,15 +1425,11 @@ static int stbi__get16be(stbi__context *s) return (z << 8) + stbi__get8(s); } -#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) -// nothing -#else static stbi__uint32 stbi__get32be(stbi__context *s) { stbi__uint32 z = stbi__get16be(s); return (z << 16) + stbi__get16be(s); } -#endif #if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) // nothing @@ -1356,7 +1476,7 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r if (req_comp == img_n) return data; STBI_ASSERT(req_comp >= 1 && req_comp <= 4); - good = (unsigned char *) stbi__malloc(req_comp * x * y); + good = (unsigned char *) stbi__malloc_mad3(req_comp, x, y, 0); if (good == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); @@ -1366,26 +1486,75 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r unsigned char *src = data + j * x * img_n ; unsigned char *dest = good + j * x * req_comp; - #define COMBO(a,b) ((a)*8+(b)) - #define CASE(a,b) case COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) + #define STBI__COMBO(a,b) ((a)*8+(b)) + #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) // convert source image with img_n components to one with req_comp components; // avoid switch per pixel, so use switch per scanline and massive macros - switch (COMBO(img_n, req_comp)) { - CASE(1,2) dest[0]=src[0], dest[1]=255; break; - CASE(1,3) dest[0]=dest[1]=dest[2]=src[0]; break; - CASE(1,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=255; break; - CASE(2,1) dest[0]=src[0]; break; - CASE(2,3) dest[0]=dest[1]=dest[2]=src[0]; break; - CASE(2,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; break; - CASE(3,4) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; break; - CASE(3,1) dest[0]=stbi__compute_y(src[0],src[1],src[2]); break; - CASE(3,2) dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = 255; break; - CASE(4,1) dest[0]=stbi__compute_y(src[0],src[1],src[2]); break; - CASE(4,2) dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = src[3]; break; - CASE(4,3) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; break; + switch (STBI__COMBO(img_n, req_comp)) { + STBI__CASE(1,2) { dest[0]=src[0], dest[1]=255; } break; + STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=255; } break; + STBI__CASE(2,1) { dest[0]=src[0]; } break; + STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; } break; + STBI__CASE(3,4) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; } break; + STBI__CASE(3,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; + STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = 255; } break; + STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; + STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = src[3]; } break; + STBI__CASE(4,3) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; } break; default: STBI_ASSERT(0); } - #undef CASE + #undef STBI__CASE + } + + STBI_FREE(data); + return good; +} + +static stbi__uint16 stbi__compute_y_16(int r, int g, int b) +{ + return (stbi__uint16) (((r*77) + (g*150) + (29*b)) >> 8); +} + +static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int req_comp, unsigned int x, unsigned int y) +{ + int i,j; + stbi__uint16 *good; + + if (req_comp == img_n) return data; + STBI_ASSERT(req_comp >= 1 && req_comp <= 4); + + good = (stbi__uint16 *) stbi__malloc(req_comp * x * y * 2); + if (good == NULL) { + STBI_FREE(data); + return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); + } + + for (j=0; j < (int) y; ++j) { + stbi__uint16 *src = data + j * x * img_n ; + stbi__uint16 *dest = good + j * x * req_comp; + + #define STBI__COMBO(a,b) ((a)*8+(b)) + #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) + // convert source image with img_n components to one with req_comp components; + // avoid switch per pixel, so use switch per scanline and massive macros + switch (STBI__COMBO(img_n, req_comp)) { + STBI__CASE(1,2) { dest[0]=src[0], dest[1]=0xffff; } break; + STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=0xffff; } break; + STBI__CASE(2,1) { dest[0]=src[0]; } break; + STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; } break; + STBI__CASE(3,4) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=0xffff; } break; + STBI__CASE(3,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; + STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]), dest[1] = 0xffff; } break; + STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; + STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]), dest[1] = src[3]; } break; + STBI__CASE(4,3) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; } break; + default: STBI_ASSERT(0); + } + #undef STBI__CASE } STBI_FREE(data); @@ -1396,7 +1565,9 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp) { int i,k,n; - float *output = (float *) stbi__malloc(x * y * comp * sizeof(float)); + float *output; + if (!data) return NULL; + output = (float *) stbi__malloc_mad4(x, y, comp, sizeof(float), 0); if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } // compute number of non-alpha components if (comp & 1) n = comp; else n = comp-1; @@ -1416,7 +1587,9 @@ static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp) static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp) { int i,k,n; - stbi_uc *output = (stbi_uc *) stbi__malloc(x * y * comp); + stbi_uc *output; + if (!data) return NULL; + output = (stbi_uc *) stbi__malloc_mad3(x, y, comp, 0); if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } // compute number of non-alpha components if (comp & 1) n = comp; else n = comp-1; @@ -1481,7 +1654,7 @@ typedef struct stbi__context *s; stbi__huffman huff_dc[4]; stbi__huffman huff_ac[4]; - stbi_uc dequant[4][64]; + stbi__uint16 dequant[4][64]; stbi__int16 fast_ac[4][1 << FAST_BITS]; // sizes for components, interleaved MCUs @@ -1517,6 +1690,8 @@ typedef struct int succ_high; int succ_low; int eob_run; + int jfif; + int app14_color_transform; // Adobe APP14 tag int rgb; int scan_n, order[4]; @@ -1587,7 +1762,7 @@ static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h) // magnitude code followed by receive_extend code int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); int m = 1 << (magbits - 1); - if (k < m) k += (-1 << magbits) + 1; + if (k < m) k += (~0U << magbits) + 1; // if the result is small enough, we can fit it in fast_ac table if (k >= -128 && k <= 127) fast_ac[i] = (stbi__int16) ((k << 8) + (run << 4) + (len + magbits)); @@ -1602,6 +1777,7 @@ static void stbi__grow_buffer_unsafe(stbi__jpeg *j) int b = j->nomore ? 0 : stbi__get8(j->s); if (b == 0xff) { int c = stbi__get8(j->s); + while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes if (c != 0) { j->marker = (unsigned char) c; j->nomore = 1; @@ -1726,7 +1902,7 @@ static stbi_uc stbi__jpeg_dezigzag[64+15] = }; // decode one 64-entry block-- -static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi_uc *dequant) +static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi__uint16 *dequant) { int diff,dc,k; int t; @@ -2435,7 +2611,7 @@ static stbi_uc stbi__get_marker(stbi__jpeg *j) x = stbi__get8(j->s); if (x != 0xff) return STBI__MARKER_none; while (x == 0xff) - x = stbi__get8(j->s); + x = stbi__get8(j->s); // consume repeated 0xff fill bytes return x; } @@ -2450,7 +2626,7 @@ static void stbi__jpeg_reset(stbi__jpeg *j) j->code_bits = 0; j->code_buffer = 0; j->nomore = 0; - j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = 0; + j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; j->marker = STBI__MARKER_none; j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; j->eob_run = 0; @@ -2582,7 +2758,7 @@ static int stbi__parse_entropy_coded_data(stbi__jpeg *z) } } -static void stbi__jpeg_dequantize(short *data, stbi_uc *dequant) +static void stbi__jpeg_dequantize(short *data, stbi__uint16 *dequant) { int i; for (i=0; i < 64; ++i) @@ -2624,13 +2800,14 @@ static int stbi__process_marker(stbi__jpeg *z, int m) L = stbi__get16be(z->s)-2; while (L > 0) { int q = stbi__get8(z->s); - int p = q >> 4; + int p = q >> 4, sixteen = (p != 0); int t = q & 15,i; - if (p != 0) return stbi__err("bad DQT type","Corrupt JPEG"); + if (p != 0 && p != 1) return stbi__err("bad DQT type","Corrupt JPEG"); if (t > 3) return stbi__err("bad DQT table","Corrupt JPEG"); + for (i=0; i < 64; ++i) - z->dequant[t][stbi__jpeg_dezigzag[i]] = stbi__get8(z->s); - L -= 65; + z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); + L -= (sixteen ? 129 : 65); } return L==0; @@ -2663,12 +2840,50 @@ static int stbi__process_marker(stbi__jpeg *z, int m) } return L==0; } + // check for comment block or APP blocks if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { - stbi__skip(z->s, stbi__get16be(z->s)-2); + L = stbi__get16be(z->s); + if (L < 2) { + if (m == 0xFE) + return stbi__err("bad COM len","Corrupt JPEG"); + else + return stbi__err("bad APP len","Corrupt JPEG"); + } + L -= 2; + + if (m == 0xE0 && L >= 5) { // JFIF APP0 segment + static const unsigned char tag[5] = {'J','F','I','F','\0'}; + int ok = 1; + int i; + for (i=0; i < 5; ++i) + if (stbi__get8(z->s) != tag[i]) + ok = 0; + L -= 5; + if (ok) + z->jfif = 1; + } else if (m == 0xEE && L >= 12) { // Adobe APP14 segment + static const unsigned char tag[6] = {'A','d','o','b','e','\0'}; + int ok = 1; + int i; + for (i=0; i < 6; ++i) + if (stbi__get8(z->s) != tag[i]) + ok = 0; + L -= 6; + if (ok) { + stbi__get8(z->s); // version + stbi__get16be(z->s); // flags0 + stbi__get16be(z->s); // flags1 + z->app14_color_transform = stbi__get8(z->s); // color transform + L -= 6; + } + } + + stbi__skip(z->s, L); return 1; } - return 0; + + return stbi__err("unknown marker","Corrupt JPEG"); } // after we see SOS @@ -2711,6 +2926,28 @@ static int stbi__process_scan_header(stbi__jpeg *z) return 1; } +static int stbi__free_jpeg_components(stbi__jpeg *z, int ncomp, int why) +{ + int i; + for (i=0; i < ncomp; ++i) { + if (z->img_comp[i].raw_data) { + STBI_FREE(z->img_comp[i].raw_data); + z->img_comp[i].raw_data = NULL; + z->img_comp[i].data = NULL; + } + if (z->img_comp[i].raw_coeff) { + STBI_FREE(z->img_comp[i].raw_coeff); + z->img_comp[i].raw_coeff = 0; + z->img_comp[i].coeff = 0; + } + if (z->img_comp[i].linebuf) { + STBI_FREE(z->img_comp[i].linebuf); + z->img_comp[i].linebuf = NULL; + } + } + return why; +} + static int stbi__process_frame_header(stbi__jpeg *z, int scan) { stbi__context *s = z->s; @@ -2720,7 +2957,7 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan) s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires c = stbi__get8(s); - if (c != 3 && c != 1) return stbi__err("bad component count","Corrupt JPEG"); // JFIF requires + if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG"); s->img_n = c; for (i=0; i < c; ++i) { z->img_comp[i].data = NULL; @@ -2733,13 +2970,8 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan) for (i=0; i < s->img_n; ++i) { static unsigned char rgb[3] = { 'R', 'G', 'B' }; z->img_comp[i].id = stbi__get8(s); - if (z->img_comp[i].id != i+1) // JFIF requires - if (z->img_comp[i].id != i) { // some version of jpegtran outputs non-JFIF-compliant files! - // somethings output this (see http://fileformats.archiveteam.org/wiki/JPEG#Color_format) - if (z->img_comp[i].id != rgb[i]) - return stbi__err("bad component ID","Corrupt JPEG"); - ++z->rgb; - } + if (s->img_n == 3 && z->img_comp[i].id == rgb[i]) + ++z->rgb; q = stbi__get8(s); z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG"); z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG"); @@ -2748,7 +2980,7 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan) if (scan != STBI__SCAN_load) return 1; - if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); + if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); for (i=0; i < s->img_n; ++i) { if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; @@ -2760,6 +2992,7 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan) z->img_v_max = v_max; z->img_mcu_w = h_max * 8; z->img_mcu_h = v_max * 8; + // these sizes can't be more than 17 bits z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w; z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h; @@ -2771,28 +3004,27 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan) // the bogus oversized data from using interleaved MCUs and their // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't // discard the extra data until colorspace conversion + // + // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier) + // so these muls can't overflow with 32-bit ints (which we require) z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; - z->img_comp[i].raw_data = stbi__malloc(z->img_comp[i].w2 * z->img_comp[i].h2+15); - - if (z->img_comp[i].raw_data == NULL) { - for(--i; i >= 0; --i) { - STBI_FREE(z->img_comp[i].raw_data); - z->img_comp[i].raw_data = NULL; - } - return stbi__err("outofmem", "Out of memory"); - } + z->img_comp[i].coeff = 0; + z->img_comp[i].raw_coeff = 0; + z->img_comp[i].linebuf = NULL; + z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); + if (z->img_comp[i].raw_data == NULL) + return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory")); // align blocks for idct using mmx/sse z->img_comp[i].data = (stbi_uc*) (((size_t) z->img_comp[i].raw_data + 15) & ~15); - z->img_comp[i].linebuf = NULL; if (z->progressive) { - z->img_comp[i].coeff_w = (z->img_comp[i].w2 + 7) >> 3; - z->img_comp[i].coeff_h = (z->img_comp[i].h2 + 7) >> 3; - z->img_comp[i].raw_coeff = STBI_MALLOC(z->img_comp[i].coeff_w * z->img_comp[i].coeff_h * 64 * sizeof(short) + 15); + // w2, h2 are multiples of 8 (see above) + z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; + z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; + z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); + if (z->img_comp[i].raw_coeff == NULL) + return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory")); z->img_comp[i].coeff = (short*) (((size_t) z->img_comp[i].raw_coeff + 15) & ~15); - } else { - z->img_comp[i].coeff = 0; - z->img_comp[i].raw_coeff = 0; } } @@ -2811,6 +3043,8 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan) static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan) { int m; + z->jfif = 0; + z->app14_color_transform = -1; // valid values are 0,1,2 z->marker = STBI__MARKER_none; // initialize cached marker to empty m = stbi__get_marker(z); if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG"); @@ -2852,12 +3086,15 @@ static int stbi__decode_jpeg_image(stbi__jpeg *j) if (x == 255) { j->marker = stbi__get8(j->s); break; - } else if (x != 0) { - return stbi__err("junk before marker", "Corrupt JPEG"); } } // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 } + } else if (stbi__DNL(m)) { + int Ld = stbi__get16be(j->s); + stbi__uint32 NL = stbi__get16be(j->s); + if (Ld != 4) stbi__err("bad DNL len", "Corrupt JPEG"); + if (NL != j->s->img_y) stbi__err("bad DNL height", "Corrupt JPEG"); } else { if (!stbi__process_marker(j, m)) return 0; } @@ -3076,38 +3313,9 @@ static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_ return out; } -#ifdef STBI_JPEG_OLD -// this is the same YCbCr-to-RGB calculation that stb_image has used -// historically before the algorithm changes in 1.49 -#define float2fixed(x) ((int) ((x) * 65536 + 0.5)) -static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step) -{ - int i; - for (i=0; i < count; ++i) { - int y_fixed = (y[i] << 16) + 32768; // rounding - int r,g,b; - int cr = pcr[i] - 128; - int cb = pcb[i] - 128; - r = y_fixed + cr*float2fixed(1.40200f); - g = y_fixed - cr*float2fixed(0.71414f) - cb*float2fixed(0.34414f); - b = y_fixed + cb*float2fixed(1.77200f); - r >>= 16; - g >>= 16; - b >>= 16; - if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } - if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } - if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } - out[0] = (stbi_uc)r; - out[1] = (stbi_uc)g; - out[2] = (stbi_uc)b; - out[3] = 255; - out += step; - } -} -#else // this is a reduced-precision calculation of YCbCr-to-RGB introduced // to make sure the code produces the same results in both SIMD and scalar -#define float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) +#define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step) { int i; @@ -3116,9 +3324,9 @@ static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc int r,g,b; int cr = pcr[i] - 128; int cb = pcb[i] - 128; - r = y_fixed + cr* float2fixed(1.40200f); - g = y_fixed + (cr*-float2fixed(0.71414f)) + ((cb*-float2fixed(0.34414f)) & 0xffff0000); - b = y_fixed + cb* float2fixed(1.77200f); + r = y_fixed + cr* stbi__float2fixed(1.40200f); + g = y_fixed + (cr*-stbi__float2fixed(0.71414f)) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb* stbi__float2fixed(1.77200f); r >>= 20; g >>= 20; b >>= 20; @@ -3132,7 +3340,6 @@ static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc out += step; } } -#endif #if defined(STBI_SSE2) || defined(STBI_NEON) static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc const *pcb, stbi_uc const *pcr, int count, int step) @@ -3251,9 +3458,9 @@ static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc cons int r,g,b; int cr = pcr[i] - 128; int cb = pcb[i] - 128; - r = y_fixed + cr* float2fixed(1.40200f); - g = y_fixed + cr*-float2fixed(0.71414f) + ((cb*-float2fixed(0.34414f)) & 0xffff0000); - b = y_fixed + cb* float2fixed(1.77200f); + r = y_fixed + cr* stbi__float2fixed(1.40200f); + g = y_fixed + cr*-stbi__float2fixed(0.71414f) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb* stbi__float2fixed(1.77200f); r >>= 20; g >>= 20; b >>= 20; @@ -3279,18 +3486,14 @@ static void stbi__setup_jpeg(stbi__jpeg *j) #ifdef STBI_SSE2 if (stbi__sse2_available()) { j->idct_block_kernel = stbi__idct_simd; - #ifndef STBI_JPEG_OLD j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; - #endif j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; } #endif #ifdef STBI_NEON j->idct_block_kernel = stbi__idct_simd; - #ifndef STBI_JPEG_OLD j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; - #endif j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; #endif } @@ -3298,23 +3501,7 @@ static void stbi__setup_jpeg(stbi__jpeg *j) // clean up the temporary component buffers static void stbi__cleanup_jpeg(stbi__jpeg *j) { - int i; - for (i=0; i < j->s->img_n; ++i) { - if (j->img_comp[i].raw_data) { - STBI_FREE(j->img_comp[i].raw_data); - j->img_comp[i].raw_data = NULL; - j->img_comp[i].data = NULL; - } - if (j->img_comp[i].raw_coeff) { - STBI_FREE(j->img_comp[i].raw_coeff); - j->img_comp[i].raw_coeff = 0; - j->img_comp[i].coeff = 0; - } - if (j->img_comp[i].linebuf) { - STBI_FREE(j->img_comp[i].linebuf); - j->img_comp[i].linebuf = NULL; - } - } + stbi__free_jpeg_components(j, j->s->img_n, 0); } typedef struct @@ -3327,9 +3514,16 @@ typedef struct int ypos; // which pre-expansion row we're on } stbi__resample; +// fast 0..255 * 0..255 => 0..255 rounded multiplication +static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y) +{ + unsigned int t = x*y + 128; + return (stbi_uc) ((t + (t >>8)) >> 8); +} + static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) { - int n, decode_n; + int n, decode_n, is_rgb; z->s->img_n = 0; // make stbi__cleanup_jpeg safe // validate req_comp @@ -3339,9 +3533,11 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } // determine actual number of components to generate - n = req_comp ? req_comp : z->s->img_n; + n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1; - if (z->s->img_n == 3 && n < 3) + is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif)); + + if (z->s->img_n == 3 && n < 3 && !is_rgb) decode_n = 1; else decode_n = z->s->img_n; @@ -3378,7 +3574,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp } // can't error after this so, this is safe - output = (stbi_uc *) stbi__malloc(n * z->s->img_x * z->s->img_y + 1); + output = (stbi_uc *) stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } // now go ahead and resample @@ -3401,7 +3597,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp if (n >= 3) { stbi_uc *y = coutput[0]; if (z->s->img_n == 3) { - if (z->rgb == 3) { + if (is_rgb) { for (i=0; i < z->s->img_x; ++i) { out[0] = y[i]; out[1] = coutput[1][i]; @@ -3412,6 +3608,28 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp } else { z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); } + } else if (z->s->img_n == 4) { + if (z->app14_color_transform == 0) { // CMYK + for (i=0; i < z->s->img_x; ++i) { + stbi_uc m = coutput[3][i]; + out[0] = stbi__blinn_8x8(coutput[0][i], m); + out[1] = stbi__blinn_8x8(coutput[1][i], m); + out[2] = stbi__blinn_8x8(coutput[2][i], m); + out[3] = 255; + out += n; + } + } else if (z->app14_color_transform == 2) { // YCCK + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + for (i=0; i < z->s->img_x; ++i) { + stbi_uc m = coutput[3][i]; + out[0] = stbi__blinn_8x8(255 - out[0], m); + out[1] = stbi__blinn_8x8(255 - out[1], m); + out[2] = stbi__blinn_8x8(255 - out[2], m); + out += n; + } + } else { // YCbCr + alpha? Ignore the fourth channel for now + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + } } else for (i=0; i < z->s->img_x; ++i) { out[0] = out[1] = out[2] = y[i]; @@ -3419,25 +3637,54 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp out += n; } } else { - stbi_uc *y = coutput[0]; - if (n == 1) - for (i=0; i < z->s->img_x; ++i) out[i] = y[i]; - else - for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255; + if (is_rgb) { + if (n == 1) + for (i=0; i < z->s->img_x; ++i) + *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); + else { + for (i=0; i < z->s->img_x; ++i, out += 2) { + out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); + out[1] = 255; + } + } + } else if (z->s->img_n == 4 && z->app14_color_transform == 0) { + for (i=0; i < z->s->img_x; ++i) { + stbi_uc m = coutput[3][i]; + stbi_uc r = stbi__blinn_8x8(coutput[0][i], m); + stbi_uc g = stbi__blinn_8x8(coutput[1][i], m); + stbi_uc b = stbi__blinn_8x8(coutput[2][i], m); + out[0] = stbi__compute_y(r, g, b); + out[1] = 255; + out += n; + } + } else if (z->s->img_n == 4 && z->app14_color_transform == 2) { + for (i=0; i < z->s->img_x; ++i) { + out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); + out[1] = 255; + out += n; + } + } else { + stbi_uc *y = coutput[0]; + if (n == 1) + for (i=0; i < z->s->img_x; ++i) out[i] = y[i]; + else + for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255; + } } } stbi__cleanup_jpeg(z); *out_x = z->s->img_x; *out_y = z->s->img_y; - if (comp) *comp = z->s->img_n; // report original components, not output + if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output return output; } } -static unsigned char *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { unsigned char* result; stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg)); + STBI_NOTUSED(ri); j->s = s; stbi__setup_jpeg(j); result = load_jpeg_image(j, x,y,comp,req_comp); @@ -3448,11 +3695,12 @@ static unsigned char *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *com static int stbi__jpeg_test(stbi__context *s) { int r; - stbi__jpeg j; - j.s = s; - stbi__setup_jpeg(&j); - r = stbi__decode_jpeg_header(&j, STBI__SCAN_type); + stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); + j->s = s; + stbi__setup_jpeg(j); + r = stbi__decode_jpeg_header(j, STBI__SCAN_type); stbi__rewind(s); + STBI_FREE(j); return r; } @@ -3464,7 +3712,7 @@ static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp) } if (x) *x = j->s->img_x; if (y) *y = j->s->img_y; - if (comp) *comp = j->s->img_n; + if (comp) *comp = j->s->img_n >= 3 ? 3 : 1; return 1; } @@ -3521,7 +3769,7 @@ stbi_inline static int stbi__bit_reverse(int v, int bits) return stbi__bitreverse16(v) >> (16-bits); } -static int stbi__zbuild_huffman(stbi__zhuffman *z, stbi_uc *sizelist, int num) +static int stbi__zbuild_huffman(stbi__zhuffman *z, const stbi_uc *sizelist, int num) { int i,k=0; int code, next_code[16], sizes[17]; @@ -3731,6 +3979,7 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a) int hlit = stbi__zreceive(a,5) + 257; int hdist = stbi__zreceive(a,5) + 1; int hclen = stbi__zreceive(a,4) + 4; + int ntot = hlit + hdist; memset(codelength_sizes, 0, sizeof(codelength_sizes)); for (i=0; i < hclen; ++i) { @@ -3740,27 +3989,29 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a) if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; n = 0; - while (n < hlit + hdist) { + while (n < ntot) { int c = stbi__zhuffman_decode(a, &z_codelength); if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); if (c < 16) lencodes[n++] = (stbi_uc) c; - else if (c == 16) { - c = stbi__zreceive(a,2)+3; - memset(lencodes+n, lencodes[n-1], c); - n += c; - } else if (c == 17) { - c = stbi__zreceive(a,3)+3; - memset(lencodes+n, 0, c); - n += c; - } else { - STBI_ASSERT(c == 18); - c = stbi__zreceive(a,7)+11; - memset(lencodes+n, 0, c); + else { + stbi_uc fill = 0; + if (c == 16) { + c = stbi__zreceive(a,2)+3; + if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); + fill = lencodes[n-1]; + } else if (c == 17) + c = stbi__zreceive(a,3)+3; + else { + STBI_ASSERT(c == 18); + c = stbi__zreceive(a,7)+11; + } + if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); + memset(lencodes+n, fill, c); n += c; } } - if (n != hlit+hdist) return stbi__err("bad codelengths","Corrupt PNG"); + if (n != ntot) return stbi__err("bad codelengths","Corrupt PNG"); if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; if (!stbi__zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0; return 1; @@ -3808,9 +4059,24 @@ static int stbi__parse_zlib_header(stbi__zbuf *a) return 1; } -// @TODO: should statically initialize these for optimal thread safety -static stbi_uc stbi__zdefault_length[288], stbi__zdefault_distance[32]; -static void stbi__init_zdefaults(void) +static const stbi_uc stbi__zdefault_length[288] = +{ + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8 +}; +static const stbi_uc stbi__zdefault_distance[32] = +{ + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 +}; +/* +Init algorithm: { int i; // use <= to match clearly with spec for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; @@ -3820,6 +4086,7 @@ static void stbi__init_zdefaults(void) for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; } +*/ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header) { @@ -3838,7 +4105,6 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header) } else { if (type == 1) { // use fixed code lengths - if (!stbi__zdefault_distance[31]) stbi__init_zdefaults(); if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , 288)) return 0; if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; } else { @@ -4026,20 +4292,19 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r int width = x; STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1); - a->out = (stbi_uc *) stbi__malloc(x * y * output_bytes); // extra bytes to write off the end into + a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into if (!a->out) return stbi__err("outofmem", "Out of memory"); img_width_bytes = (((img_n * x * depth) + 7) >> 3); img_len = (img_width_bytes + 1) * y; - if (s->img_x == x && s->img_y == y) { - if (raw_len != img_len) return stbi__err("not enough pixels","Corrupt PNG"); - } else { // interlaced: - if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG"); - } + // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, + // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), + // so just check for raw_len < img_len always. + if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG"); for (j=0; j < y; ++j) { stbi_uc *cur = a->out + stride*j; - stbi_uc *prior = cur - stride; + stbi_uc *prior; int filter = *raw++; if (filter > 4) @@ -4051,6 +4316,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r filter_bytes = 1; width = img_width_bytes; } + prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above // if first row, use special filter that doesn't sample previous row if (j == 0) filter = first_row_filter[filter]; @@ -4091,37 +4357,37 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r // this is a little gross, so that we don't switch per-pixel or per-component if (depth < 8 || img_n == out_n) { int nk = (width - 1)*filter_bytes; - #define CASE(f) \ + #define STBI__CASE(f) \ case f: \ for (k=0; k < nk; ++k) switch (filter) { // "none" filter turns into a memcpy here; make that explicit. case STBI__F_none: memcpy(cur, raw, nk); break; - CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); break; - CASE(STBI__F_up) cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; - CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); break; - CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); break; - CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); break; - CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); break; + STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); } break; + STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; + STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); } break; + STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); } break; + STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); } break; + STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); } break; } - #undef CASE + #undef STBI__CASE raw += nk; } else { STBI_ASSERT(img_n+1 == out_n); - #define CASE(f) \ + #define STBI__CASE(f) \ case f: \ for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ for (k=0; k < filter_bytes; ++k) switch (filter) { - CASE(STBI__F_none) cur[k] = raw[k]; break; - CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); break; - CASE(STBI__F_up) cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; - CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); break; - CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); break; - CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); break; - CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); break; + STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break; + STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); } break; + STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; + STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); } break; + STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); } break; + STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); } break; + STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); } break; } - #undef CASE + #undef STBI__CASE // the loop above sets the high byte of the pixels' alpha, but for // 16 bit png files we also need the low byte set. we'll do that here. @@ -4224,13 +4490,15 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) { + int bytes = (depth == 16 ? 2 : 1); + int out_bytes = out_n * bytes; stbi_uc *final; int p; if (!interlaced) return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); // de-interlacing - final = (stbi_uc *) stbi__malloc(a->s->img_x * a->s->img_y * out_n); + final = (stbi_uc *) stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); for (p=0; p < 7; ++p) { int xorig[] = { 0,4,0,2,0,1,0 }; int yorig[] = { 0,0,4,0,2,0,1 }; @@ -4250,8 +4518,8 @@ static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint3 for (i=0; i < x; ++i) { int out_y = j*yspc[p]+yorig[p]; int out_x = i*xspc[p]+xorig[p]; - memcpy(final + out_y*a->s->img_x*out_n + out_x*out_n, - a->out + (j*x+i)*out_n, out_n); + memcpy(final + out_y*a->s->img_x*out_bytes + out_x*out_bytes, + a->out + (j*x+i)*out_bytes, out_bytes); } } STBI_FREE(a->out); @@ -4319,7 +4587,7 @@ static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; stbi_uc *p, *temp_out, *orig = a->out; - p = (stbi_uc *) stbi__malloc(pixel_count * pal_img_n); + p = (stbi_uc *) stbi__malloc_mad2(pixel_count, pal_img_n, 0); if (p == NULL) return stbi__err("outofmem", "Out of memory"); // between here and free(out) below, exitting would leak @@ -4351,26 +4619,6 @@ static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int return 1; } -static int stbi__reduce_png(stbi__png *p) -{ - int i; - int img_len = p->s->img_x * p->s->img_y * p->s->img_out_n; - stbi_uc *reduced; - stbi__uint16 *orig = (stbi__uint16*)p->out; - - if (p->depth != 16) return 1; // don't need to do anything if not 16-bit data - - reduced = (stbi_uc *)stbi__malloc(img_len); - if (p == NULL) return stbi__err("outofmem", "Out of memory"); - - for (i = 0; i < img_len; ++i) reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is a decent approx of 16->8 bit scaling - - p->out = reduced; - STBI_FREE(orig); - - return 1; -} - static int stbi__unpremultiply_on_load = 0; static int stbi__de_iphone_flag = 0; @@ -4405,9 +4653,10 @@ static void stbi__de_iphone(stbi__png *z) stbi_uc a = p[3]; stbi_uc t = p[0]; if (a) { - p[0] = p[2] * 255 / a; - p[1] = p[1] * 255 / a; - p[2] = t * 255 / a; + stbi_uc half = a / 2; + p[0] = (p[2] * 255 + half) / a; + p[1] = (p[1] * 255 + half) / a; + p[2] = ( t * 255 + half) / a; } else { p[0] = p[2]; p[2] = t; @@ -4461,7 +4710,7 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)"); z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only"); color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG"); - if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG"); + if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG"); if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG"); comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG"); filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG"); @@ -4510,7 +4759,7 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG"); has_trans = 1; if (z->depth == 16) { - for (k = 0; k < s->img_n; ++k) tc16[k] = stbi__get16be(s); // copy the values as-is + for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is } else { for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger } @@ -4570,6 +4819,9 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) if (req_comp >= 3) s->img_out_n = req_comp; if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) return 0; + } else if (has_trans) { + // non-paletted image with tRNS -> source image has (constant) alpha + ++s->img_n; } STBI_FREE(z->expanded); z->expanded = NULL; return 1; @@ -4597,20 +4849,22 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) } } -static unsigned char *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp) +static void *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp, stbi__result_info *ri) { - unsigned char *result=NULL; + void *result=NULL; if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { - if (p->depth == 16) { - if (!stbi__reduce_png(p)) { - return result; - } - } + if (p->depth < 8) + ri->bits_per_channel = 8; + else + ri->bits_per_channel = p->depth; result = p->out; p->out = NULL; if (req_comp && req_comp != p->s->img_out_n) { - result = stbi__convert_format(result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); + if (ri->bits_per_channel == 8) + result = stbi__convert_format((unsigned char *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); + else + result = stbi__convert_format16((stbi__uint16 *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); p->s->img_out_n = req_comp; if (result == NULL) return result; } @@ -4625,11 +4879,11 @@ static unsigned char *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req return result; } -static unsigned char *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { stbi__png p; p.s = s; - return stbi__do_png(&p, x,y,comp,req_comp); + return stbi__do_png(&p, x,y,comp,req_comp, ri); } static int stbi__png_test(stbi__context *s) @@ -4742,7 +4996,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) info->offset = stbi__get32le(s); info->hsz = hsz = stbi__get32le(s); info->mr = info->mg = info->mb = info->ma = 0; - + if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); if (hsz == 12) { s->img_x = stbi__get16le(s); @@ -4817,7 +5071,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) } -static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { stbi_uc *out; unsigned int mr=0,mg=0,mb=0,ma=0, all_a; @@ -4825,8 +5079,9 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int int psize=0,i,j,width; int flip_vertically, pad, target; stbi__bmp_data info; + STBI_NOTUSED(ri); - info.all_a = 255; + info.all_a = 255; if (stbi__bmp_parse_header(s, &info) == NULL) return NULL; // error code already set @@ -4853,7 +5108,11 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int else target = s->img_n; // if they want monochrome, we'll post-convert - out = (stbi_uc *) stbi__malloc(target * s->img_x * s->img_y); + // sanity-check size + if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) + return stbi__errpuc("too large", "Corrupt BMP"); + + out = (stbi_uc *) stbi__malloc_mad3(target, s->img_x, s->img_y, 0); if (!out) return stbi__errpuc("outofmem", "Out of memory"); if (info.bpp < 16) { int z=0; @@ -4941,7 +5200,7 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int stbi__skip(s, pad); } } - + // if alpha channel is all 0s, replace with all 255s if (target == 4 && all_a == 0) for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4) @@ -5087,18 +5346,18 @@ errorEnd: } // read 16bit value and convert to 24bit RGB -void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out) +static void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out) { - stbi__uint16 px = stbi__get16le(s); + stbi__uint16 px = (stbi__uint16)stbi__get16le(s); stbi__uint16 fiveBitMask = 31; // we have 3 channels with 5bits each int r = (px >> 10) & fiveBitMask; int g = (px >> 5) & fiveBitMask; int b = px & fiveBitMask; // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later - out[0] = (r * 255)/31; - out[1] = (g * 255)/31; - out[2] = (b * 255)/31; + out[0] = (stbi_uc)((r * 255)/31); + out[1] = (stbi_uc)((g * 255)/31); + out[2] = (stbi_uc)((b * 255)/31); // some people claim that the most significant bit might be used for alpha // (possibly if an alpha-bit is set in the "image descriptor byte") @@ -5106,7 +5365,7 @@ void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out) // so let's treat all 15 and 16bit TGAs as RGB with no alpha. } -static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { // read in the TGA header stuff int tga_offset = stbi__get8(s); @@ -5128,10 +5387,11 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int unsigned char *tga_data; unsigned char *tga_palette = NULL; int i, j; - unsigned char raw_data[4]; + unsigned char raw_data[4] = {0}; int RLE_count = 0; int RLE_repeating = 0; int read_next_pixel = 1; + STBI_NOTUSED(ri); // do a tiny bit of precessing if ( tga_image_type >= 8 ) @@ -5153,7 +5413,10 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int *y = tga_height; if (comp) *comp = tga_comp; - tga_data = (unsigned char*)stbi__malloc( (size_t)tga_width * tga_height * tga_comp ); + if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) + return stbi__errpuc("too large", "Corrupt TGA"); + + tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); // skip to the data's starting position (offset usually = 0) @@ -5172,7 +5435,7 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int // any data to skip? (offset usually = 0) stbi__skip(s, tga_palette_start ); // load the palette - tga_palette = (unsigned char*)stbi__malloc( tga_palette_len * tga_comp ); + tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); if (!tga_palette) { STBI_FREE(tga_data); return stbi__errpuc("outofmem", "Out of memory"); @@ -5308,14 +5571,53 @@ static int stbi__psd_test(stbi__context *s) return r; } -static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +static int stbi__psd_decode_rle(stbi__context *s, stbi_uc *p, int pixelCount) { - int pixelCount; + int count, nleft, len; + + count = 0; + while ((nleft = pixelCount - count) > 0) { + len = stbi__get8(s); + if (len == 128) { + // No-op. + } else if (len < 128) { + // Copy next len+1 bytes literally. + len++; + if (len > nleft) return 0; // corrupt data + count += len; + while (len) { + *p = stbi__get8(s); + p += 4; + len--; + } + } else if (len > 128) { + stbi_uc val; + // Next -len+1 bytes in the dest are replicated from next source byte. + // (Interpret len as a negative 8-bit int.) + len = 257 - len; + if (len > nleft) return 0; // corrupt data + val = stbi__get8(s); + count += len; + while (len) { + *p = val; + p += 4; + len--; + } + } + } + + return 1; +} + +static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) +{ + int pixelCount; int channelCount, compression; - int channel, i, count, len; + int channel, i; int bitdepth; int w,h; stbi_uc *out; + STBI_NOTUSED(ri); // Check identifier if (stbi__get32be(s) != 0x38425053) // "8BPS" @@ -5372,8 +5674,18 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int if (compression > 1) return stbi__errpuc("bad compression", "PSD has an unknown compression format"); + // Check size + if (!stbi__mad3sizes_valid(4, w, h, 0)) + return stbi__errpuc("too large", "Corrupt PSD"); + // Create the destination image. - out = (stbi_uc *) stbi__malloc(4 * w*h); + + if (!compression && bitdepth == 16 && bpc == 16) { + out = (stbi_uc *) stbi__malloc_mad3(8, w, h, 0); + ri->bits_per_channel = 16; + } else + out = (stbi_uc *) stbi__malloc(4 * w*h); + if (!out) return stbi__errpuc("outofmem", "Out of memory"); pixelCount = w*h; @@ -5405,82 +5717,86 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int *p = (channel == 3 ? 255 : 0); } else { // Read the RLE data. - count = 0; - while (count < pixelCount) { - len = stbi__get8(s); - if (len == 128) { - // No-op. - } else if (len < 128) { - // Copy next len+1 bytes literally. - len++; - count += len; - while (len) { - *p = stbi__get8(s); - p += 4; - len--; - } - } else if (len > 128) { - stbi_uc val; - // Next -len+1 bytes in the dest are replicated from next source byte. - // (Interpret len as a negative 8-bit int.) - len ^= 0x0FF; - len += 2; - val = stbi__get8(s); - count += len; - while (len) { - *p = val; - p += 4; - len--; - } - } + if (!stbi__psd_decode_rle(s, p, pixelCount)) { + STBI_FREE(out); + return stbi__errpuc("corrupt", "bad RLE data"); } } } } else { // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) - // where each channel consists of an 8-bit value for each pixel in the image. + // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. // Read the data by channel. for (channel = 0; channel < 4; channel++) { - stbi_uc *p; - - p = out + channel; if (channel >= channelCount) { // Fill this channel with default data. - stbi_uc val = channel == 3 ? 255 : 0; - for (i = 0; i < pixelCount; i++, p += 4) - *p = val; - } else { - // Read the data. - if (bitdepth == 16) { - for (i = 0; i < pixelCount; i++, p += 4) - *p = (stbi_uc) (stbi__get16be(s) >> 8); + if (bitdepth == 16 && bpc == 16) { + stbi__uint16 *q = ((stbi__uint16 *) out) + channel; + stbi__uint16 val = channel == 3 ? 65535 : 0; + for (i = 0; i < pixelCount; i++, q += 4) + *q = val; } else { + stbi_uc *p = out+channel; + stbi_uc val = channel == 3 ? 255 : 0; for (i = 0; i < pixelCount; i++, p += 4) - *p = stbi__get8(s); + *p = val; + } + } else { + if (ri->bits_per_channel == 16) { // output bpc + stbi__uint16 *q = ((stbi__uint16 *) out) + channel; + for (i = 0; i < pixelCount; i++, q += 4) + *q = (stbi__uint16) stbi__get16be(s); + } else { + stbi_uc *p = out+channel; + if (bitdepth == 16) { // input bpc + for (i = 0; i < pixelCount; i++, p += 4) + *p = (stbi_uc) (stbi__get16be(s) >> 8); + } else { + for (i = 0; i < pixelCount; i++, p += 4) + *p = stbi__get8(s); + } } } } } + // remove weird white matte from PSD if (channelCount >= 4) { - for (i=0; i < w*h; ++i) { - unsigned char *pixel = out + 4*i; - if (pixel[3] != 0 && pixel[3] != 255) { - // remove weird white matte from PSD - float a = pixel[3] / 255.0f; - float ra = 1.0f / a; - float inv_a = 255.0f * (1 - ra); - pixel[0] = (unsigned char) (pixel[0]*ra + inv_a); - pixel[1] = (unsigned char) (pixel[1]*ra + inv_a); - pixel[2] = (unsigned char) (pixel[2]*ra + inv_a); + if (ri->bits_per_channel == 16) { + for (i=0; i < w*h; ++i) { + stbi__uint16 *pixel = (stbi__uint16 *) out + 4*i; + if (pixel[3] != 0 && pixel[3] != 65535) { + float a = pixel[3] / 65535.0f; + float ra = 1.0f / a; + float inv_a = 65535.0f * (1 - ra); + pixel[0] = (stbi__uint16) (pixel[0]*ra + inv_a); + pixel[1] = (stbi__uint16) (pixel[1]*ra + inv_a); + pixel[2] = (stbi__uint16) (pixel[2]*ra + inv_a); + } + } + } else { + for (i=0; i < w*h; ++i) { + unsigned char *pixel = out + 4*i; + if (pixel[3] != 0 && pixel[3] != 255) { + float a = pixel[3] / 255.0f; + float ra = 1.0f / a; + float inv_a = 255.0f * (1 - ra); + pixel[0] = (unsigned char) (pixel[0]*ra + inv_a); + pixel[1] = (unsigned char) (pixel[1]*ra + inv_a); + pixel[2] = (unsigned char) (pixel[2]*ra + inv_a); + } } } } + // convert to desired output format if (req_comp && req_comp != 4) { - out = stbi__convert_format(out, 4, req_comp, w, h); + if (ri->bits_per_channel == 16) + out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, 4, req_comp, w, h); + else + out = stbi__convert_format(out, 4, req_comp, w, h); if (out == NULL) return out; // stbi__convert_format frees input on failure } @@ -5664,10 +5980,13 @@ static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *c return result; } -static stbi_uc *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp) +static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp, stbi__result_info *ri) { stbi_uc *result; - int i, x,y; + int i, x,y, internal_comp; + STBI_NOTUSED(ri); + + if (!comp) comp = &internal_comp; for (i=0; i<92; ++i) stbi__get8(s); @@ -5675,14 +5994,14 @@ static stbi_uc *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int re x = stbi__get16be(s); y = stbi__get16be(s); if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)"); - if ((1 << 28) / x < y) return stbi__errpuc("too large", "Image too large to decode"); + if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode"); stbi__get32be(s); //skip `ratio' stbi__get16be(s); //skip `fields' stbi__get16be(s); //skip `pad' // intermediate buffer is RGBA - result = (stbi_uc *) stbi__malloc(x*y*4); + result = (stbi_uc *) stbi__malloc_mad3(x, y, 4, 0); memset(result, 0xff, x*y*4); if (!stbi__pic_load_core(s,x,y,comp, result)) { @@ -5941,8 +6260,11 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i if (g->out == 0 && !stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header + if (!stbi__mad3sizes_valid(g->w, g->h, 4, 0)) + return stbi__errpuc("too large", "GIF too large"); + prev_out = g->out; - g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h); + g->out = (stbi_uc *) stbi__malloc_mad3(4, g->w, g->h, 0); if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory"); switch ((g->eflags & 0x1C) >> 2) { @@ -6049,11 +6371,12 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i STBI_NOTUSED(req_comp); } -static stbi_uc *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { stbi_uc *u = 0; stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif)); memset(g, 0, sizeof(*g)); + STBI_NOTUSED(ri); u = stbi__gif_load_next(s, g, comp, req_comp); if (u == (stbi_uc *) s) u = 0; // end of animated gif marker @@ -6079,20 +6402,24 @@ static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp) // Radiance RGBE HDR loader // originally by Nicolas Schulz #ifndef STBI_NO_HDR -static int stbi__hdr_test_core(stbi__context *s) +static int stbi__hdr_test_core(stbi__context *s, const char *signature) { - const char *signature = "#?RADIANCE\n"; int i; for (i=0; signature[i]; ++i) if (stbi__get8(s) != signature[i]) - return 0; + return 0; + stbi__rewind(s); return 1; } static int stbi__hdr_test(stbi__context* s) { - int r = stbi__hdr_test_core(s); + int r = stbi__hdr_test_core(s, "#?RADIANCE\n"); stbi__rewind(s); + if(!r) { + r = stbi__hdr_test_core(s, "#?RGBE\n"); + stbi__rewind(s); + } return r; } @@ -6146,7 +6473,7 @@ static void stbi__hdr_convert(float *output, stbi_uc *input, int req_comp) } } -static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { char buffer[STBI__HDR_BUFLEN]; char *token; @@ -6157,10 +6484,12 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re int len; unsigned char count, value; int i, j, k, c1,c2, z; - + const char *headerToken; + STBI_NOTUSED(ri); // Check identifier - if (strcmp(stbi__hdr_gettoken(s,buffer), "#?RADIANCE") != 0) + headerToken = stbi__hdr_gettoken(s,buffer); + if (strcmp(headerToken, "#?RADIANCE") != 0 && strcmp(headerToken, "#?RGBE") != 0) return stbi__errpf("not HDR", "Corrupt HDR image"); // Parse header @@ -6189,8 +6518,13 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re if (comp) *comp = 3; if (req_comp == 0) req_comp = 3; + if (!stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0)) + return stbi__errpf("too large", "HDR image is too large"); + // Read data - hdr_data = (float *) stbi__malloc(height * width * req_comp * sizeof(float)); + hdr_data = (float *) stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0); + if (!hdr_data) + return stbi__errpf("outofmem", "Out of memory"); // Load image data // image data is stored as some number of sca @@ -6229,20 +6563,29 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re len <<= 8; len |= stbi__get8(s); if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); } - if (scanline == NULL) scanline = (stbi_uc *) stbi__malloc(width * 4); + if (scanline == NULL) { + scanline = (stbi_uc *) stbi__malloc_mad2(width, 4, 0); + if (!scanline) { + STBI_FREE(hdr_data); + return stbi__errpf("outofmem", "Out of memory"); + } + } for (k = 0; k < 4; ++k) { + int nleft; i = 0; - while (i < width) { + while ((nleft = width - i) > 0) { count = stbi__get8(s); if (count > 128) { // Run value = stbi__get8(s); count -= 128; + if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } for (z = 0; z < count; ++z) scanline[i++ * 4 + k] = value; } else { // Dump + if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } for (z = 0; z < count; ++z) scanline[i++ * 4 + k] = stbi__get8(s); } @@ -6251,7 +6594,8 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re for (i=0; i < width; ++i) stbi__hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp); } - STBI_FREE(scanline); + if (scanline) + STBI_FREE(scanline); } return hdr_data; @@ -6262,6 +6606,11 @@ static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp) char buffer[STBI__HDR_BUFLEN]; char *token; int valid = 0; + int dummy; + + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; if (stbi__hdr_test(s) == 0) { stbi__rewind( s ); @@ -6303,14 +6652,14 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp) void *p; stbi__bmp_data info; - info.all_a = 255; + info.all_a = 255; p = stbi__bmp_parse_header(s, &info); stbi__rewind( s ); if (p == NULL) return 0; - *x = s->img_x; - *y = s->img_y; - *comp = info.ma ? 4 : 3; + if (x) *x = s->img_x; + if (y) *y = s->img_y; + if (comp) *comp = info.ma ? 4 : 3; return 1; } #endif @@ -6318,7 +6667,10 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp) #ifndef STBI_NO_PSD static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp) { - int channelCount; + int channelCount, dummy; + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; if (stbi__get32be(s) != 0x38425053) { stbi__rewind( s ); return 0; @@ -6351,9 +6703,13 @@ static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp) #ifndef STBI_NO_PIC static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp) { - int act_comp=0,num_packets=0,chained; + int act_comp=0,num_packets=0,chained,dummy; stbi__pic_packet packets[10]; + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; + if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) { stbi__rewind(s); return 0; @@ -6429,16 +6785,22 @@ static int stbi__pnm_test(stbi__context *s) return 1; } -static stbi_uc *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp) +static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { stbi_uc *out; + STBI_NOTUSED(ri); + if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n)) return 0; + *x = s->img_x; *y = s->img_y; - *comp = s->img_n; + if (comp) *comp = s->img_n; - out = (stbi_uc *) stbi__malloc(s->img_n * s->img_x * s->img_y); + if (!stbi__mad3sizes_valid(s->img_n, s->img_x, s->img_y, 0)) + return stbi__errpuc("too large", "PNM too large"); + + out = (stbi_uc *) stbi__malloc_mad3(s->img_n, s->img_x, s->img_y, 0); if (!out) return stbi__errpuc("outofmem", "Out of memory"); stbi__getn(s, out, s->img_n * s->img_x * s->img_y); @@ -6487,16 +6849,20 @@ static int stbi__pnm_getinteger(stbi__context *s, char *c) static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp) { - int maxv; + int maxv, dummy; char c, p, t; - stbi__rewind( s ); + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; + + stbi__rewind(s); // Get identifier p = (char) stbi__get8(s); t = (char) stbi__get8(s); if (p != 'P' || (t != '5' && t != '6')) { - stbi__rewind( s ); + stbi__rewind(s); return 0; } @@ -6603,6 +6969,19 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int /* revision history: + 2.16 (2017-07-23) all functions have 16-bit variants; + STBI_NO_STDIO works again; + compilation fixes; + fix rounding in unpremultiply; + optimize vertical flip; + disable raw_len validation; + documentation fixes + 2.15 (2017-03-18) fix png-1,2,4 bug; now all Imagenet JPGs decode; + warning fixes; disable run-time SSE detection on gcc; + uniform handling of optional "return" values; + thread-safe initialization of zlib tables + 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs + 2.13 (2016-11-29) add 16-bit API, only supported for PNG right now 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes 2.11 (2016-04-02) allocate large structures on the stack remove white matting for transparent PSD @@ -6763,3 +7142,46 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int 0.50 (2006-11-19) first released version */ + + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +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. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +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 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. +------------------------------------------------------------------------------ +*/ diff --git a/love/src/jni/love/src/libraries/tinyexr/tinyexr.h b/love/src/jni/love/src/libraries/tinyexr/tinyexr.h new file mode 100755 index 00000000..606c1975 --- /dev/null +++ b/love/src/jni/love/src/libraries/tinyexr/tinyexr.h @@ -0,0 +1,12579 @@ +/* +Copyright (c) 2014 - 2017, Syoyo Fujita +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Syoyo Fujita nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +// TinyEXR contains some OpenEXR code, which is licensed under ------------ + +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Industrial Light & Magic nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////// + +// End of OpenEXR license ------------------------------------------------- + +#ifndef TINYEXR_H_ +#define TINYEXR_H_ + +// +// +// Do this: +// #define TINYEXR_IMPLEMENTATION +// before you include this file in *one* C or C++ file to create the +// implementation. +// +// // i.e. it should look like this: +// #include ... +// #include ... +// #include ... +// #define TINYEXR_IMPLEMENTATION +// #include "tinyexr.h" +// +// + +#include // for size_t +#include // guess stdint.h is available(C99) + +#ifdef __cplusplus +extern "C" { +#endif + +// Use embedded miniz or not to decode ZIP format pixel. Linking with zlib +// required if this flas is 0. +#ifndef TINYEXR_USE_MINIZ +#define TINYEXR_USE_MINIZ (1) +#endif + +// Disable PIZ comporession when applying cpplint. +#ifndef TINYEXR_USE_PIZ +#define TINYEXR_USE_PIZ (1) +#endif + +#ifndef TINYEXR_USE_ZFP +#define TINYEXR_USE_ZFP (0) // TinyEXR extension. +// http://computation.llnl.gov/projects/floating-point-compression +#endif + +#define TINYEXR_SUCCESS (0) +#define TINYEXR_ERROR_INVALID_MAGIC_NUMBER (-1) +#define TINYEXR_ERROR_INVALID_EXR_VERSION (-2) +#define TINYEXR_ERROR_INVALID_ARGUMENT (-3) +#define TINYEXR_ERROR_INVALID_DATA (-4) +#define TINYEXR_ERROR_INVALID_FILE (-5) +#define TINYEXR_ERROR_INVALID_PARAMETER (-5) +#define TINYEXR_ERROR_CANT_OPEN_FILE (-6) +#define TINYEXR_ERROR_UNSUPPORTED_FORMAT (-7) +#define TINYEXR_ERROR_INVALID_HEADER (-8) + +// @note { OpenEXR file format: http://www.openexr.com/openexrfilelayout.pdf } + +// pixel type: possible values are: UINT = 0 HALF = 1 FLOAT = 2 +#define TINYEXR_PIXELTYPE_UINT (0) +#define TINYEXR_PIXELTYPE_HALF (1) +#define TINYEXR_PIXELTYPE_FLOAT (2) + +#define TINYEXR_MAX_ATTRIBUTES (128) + +#define TINYEXR_COMPRESSIONTYPE_NONE (0) +#define TINYEXR_COMPRESSIONTYPE_RLE (1) +#define TINYEXR_COMPRESSIONTYPE_ZIPS (2) +#define TINYEXR_COMPRESSIONTYPE_ZIP (3) +#define TINYEXR_COMPRESSIONTYPE_PIZ (4) +#define TINYEXR_COMPRESSIONTYPE_ZFP (128) // TinyEXR extension + +#define TINYEXR_ZFP_COMPRESSIONTYPE_RATE (0) +#define TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION (1) +#define TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY (2) + +#define TINYEXR_TILE_ONE_LEVEL (0) +#define TINYEXR_TILE_MIPMAP_LEVELS (1) +#define TINYEXR_TILE_RIPMAP_LEVELS (2) + +#define TINYEXR_TILE_ROUND_DOWN (0) +#define TINYEXR_TILE_ROUND_UP (1) + +typedef struct _EXRVersion { + int version; // this must be 2 + int tiled; // tile format image + int long_name; // long name attribute + int non_image; // deep image(EXR 2.0) + int multipart; // multi-part(EXR 2.0) +} EXRVersion; + +typedef struct _EXRAttribute { + char name[256]; // name and type are up to 255 chars long. + char type[256]; + unsigned char *value; // uint8_t* + int size; + int pad0; +} EXRAttribute; + +typedef struct _EXRChannelInfo { + char name[256]; // less than 255 bytes long + int pixel_type; + int x_sampling; + int y_sampling; + unsigned char p_linear; + unsigned char pad[3]; +} EXRChannelInfo; + +typedef struct _EXRTile { + int offset_x; + int offset_y; + int level_x; + int level_y; + + int width; // actual width in a tile. + int height; // actual height int a tile. + + unsigned char **images; // image[channels][pixels] +} EXRTile; + +typedef struct _EXRHeader { + float pixel_aspect_ratio; + int line_order; + int data_window[4]; + int display_window[4]; + float screen_window_center[2]; + float screen_window_width; + + int chunk_count; + + // Properties for tiled format(`tiledesc`). + int tiled; + int tile_size_x; + int tile_size_y; + int tile_level_mode; + int tile_rounding_mode; + + int long_name; + int non_image; + int multipart; + unsigned int header_len; + + // Custom attributes(exludes required attributes(e.g. `channels`, + // `compression`, etc) + int num_custom_attributes; + EXRAttribute custom_attributes[TINYEXR_MAX_ATTRIBUTES]; + + EXRChannelInfo *channels; // [num_channels] + + int *pixel_types; // Loaded pixel type(TINYEXR_PIXELTYPE_*) of `images` for + // each channel. This is overwritten with `requested_pixel_types` when + // loading. + int num_channels; + + int compression_type; // compression type(TINYEXR_COMPRESSIONTYPE_*) + int *requested_pixel_types; // Filled initially by + // ParseEXRHeaderFrom(Meomory|File), then users + // can edit it(only valid for HALF pixel type + // channel) + +} EXRHeader; + +typedef struct _EXRMultiPartHeader { + int num_headers; + EXRHeader *headers; + +} EXRMultiPartHeader; + +typedef struct _EXRImage { + EXRTile *tiles; // Tiled pixel data. The application must reconstruct image + // from tiles manually. NULL if scanline format. + unsigned char **images; // image[channels][pixels]. NULL if tiled format. + + int width; + int height; + int num_channels; + + // Properties for tile format. + int num_tiles; + +} EXRImage; + +typedef struct _EXRMultiPartImage { + int num_images; + EXRImage *images; + +} EXRMultiPartImage; + +typedef struct _DeepImage { + const char **channel_names; + float ***image; // image[channels][scanlines][samples] + int **offset_table; // offset_table[scanline][offsets] + int num_channels; + int width; + int height; + int pad0; +} DeepImage; + +// @deprecated { to be removed. } +// Loads single-frame OpenEXR image. Assume EXR image contains A(single channel +// alpha) or RGB(A) channels. +// Application must free image data as returned by `out_rgba` +// Result image format is: float x RGBA x width x hight +// Returns negative value and may set error string in `err` when there's an +// error +extern int LoadEXR(float **out_rgba, int *width, int *height, + const char *filename, const char **err); + +// @deprecated { to be removed. } +// Saves single-frame OpenEXR image. Assume EXR image contains RGB(A) channels. +// components must be 1(Grayscale), 3(RGB) or 4(RGBA). +// Input image format is: `float x width x height`, or `float x RGB(A) x width x +// hight` +// Save image as fp16(HALF) format when `save_as_fp16` is positive non-zero +// value. +// Save image as fp32(FLOAT) format when `save_as_fp16` is 0. +extern int SaveEXR(const float *data, const int width, const int height, + const int components, const int save_as_fp16, + const char *filename); + +// Initialize EXRHeader struct +extern void InitEXRHeader(EXRHeader *exr_header); + +// Initialize EXRImage struct +extern void InitEXRImage(EXRImage *exr_image); + +// Free's internal data of EXRHeader struct +extern int FreeEXRHeader(EXRHeader *exr_header); + +// Free's internal data of EXRImage struct +extern int FreeEXRImage(EXRImage *exr_image); + +// Parse EXR version header of a file. +extern int ParseEXRVersionFromFile(EXRVersion *version, const char *filename); + +// Parse EXR version header from memory-mapped EXR data. +extern int ParseEXRVersionFromMemory(EXRVersion *version, + const unsigned char *memory, size_t size); + +// Parse single-part OpenEXR header from a file and initialize `EXRHeader`. +extern int ParseEXRHeaderFromFile(EXRHeader *header, const EXRVersion *version, + const char *filename, const char **err); + +// Parse single-part OpenEXR header from a memory and initialize `EXRHeader`. +extern int ParseEXRHeaderFromMemory(EXRHeader *header, + const EXRVersion *version, + const unsigned char *memory, size_t size, + const char **err); + +// Parse multi-part OpenEXR headers from a file and initialize `EXRHeader*` +// array. +extern int ParseEXRMultipartHeaderFromFile(EXRHeader ***headers, + int *num_headers, + const EXRVersion *version, + const char *filename, + const char **err); + +// Parse multi-part OpenEXR headers from a memory and initialize `EXRHeader*` +// array +extern int ParseEXRMultipartHeaderFromMemory(EXRHeader ***headers, + int *num_headers, + const EXRVersion *version, + const unsigned char *memory, + size_t size, const char **err); + +// Loads single-part OpenEXR image from a file. +// Application must setup `ParseEXRHeaderFromFile` before calling this function. +// Application can free EXRImage using `FreeEXRImage` +// Returns negative value and may set error string in `err` when there's an +// error +extern int LoadEXRImageFromFile(EXRImage *image, const EXRHeader *header, + const char *filename, const char **err); + +// Loads single-part OpenEXR image from a memory. +// Application must setup `EXRHeader` with +// `ParseEXRHeaderFromMemory` before calling this function. +// Application can free EXRImage using `FreeEXRImage` +// Returns negative value and may set error string in `err` when there's an +// error +extern int LoadEXRImageFromMemory(EXRImage *image, const EXRHeader *header, + const unsigned char *memory, + const size_t size, const char **err); + +// Loads multi-part OpenEXR image from a file. +// Application must setup `ParseEXRMultipartHeaderFromFile` before calling this +// function. +// Application can free EXRImage using `FreeEXRImage` +// Returns negative value and may set error string in `err` when there's an +// error +extern int LoadEXRMultipartImageFromFile(EXRImage *images, + const EXRHeader **headers, + unsigned int num_parts, + const char *filename, + const char **err); + +// Loads multi-part OpenEXR image from a memory. +// Application must setup `EXRHeader*` array with +// `ParseEXRMultipartHeaderFromMemory` before calling this function. +// Application can free EXRImage using `FreeEXRImage` +// Returns negative value and may set error string in `err` when there's an +// error +extern int LoadEXRMultipartImageFromMemory(EXRImage *images, + const EXRHeader **headers, + unsigned int num_parts, + const unsigned char *memory, + const size_t size, const char **err); + +// Saves multi-channel, single-frame OpenEXR image to a file. +// Returns negative value and may set error string in `err` when there's an +// error +extern int SaveEXRImageToFile(const EXRImage *image, + const EXRHeader *exr_header, const char *filename, + const char **err); + +// Saves multi-channel, single-frame OpenEXR image to a memory. +// Image is compressed using EXRImage.compression value. +// Return the number of bytes if succes. +// Returns negative value and may set error string in `err` when there's an +// error +extern size_t SaveEXRImageToMemory(const EXRImage *image, + const EXRHeader *exr_header, + unsigned char **memory, const char **err); + +// Loads single-frame OpenEXR deep image. +// Application must free memory of variables in DeepImage(image, offset_table) +// Returns negative value and may set error string in `err` when there's an +// error +extern int LoadDeepEXR(DeepImage *out_image, const char *filename, + const char **err); + +// NOT YET IMPLEMENTED: +// Saves single-frame OpenEXR deep image. +// Returns negative value and may set error string in `err` when there's an +// error +// extern int SaveDeepEXR(const DeepImage *in_image, const char *filename, +// const char **err); + +// NOT YET IMPLEMENTED: +// Loads multi-part OpenEXR deep image. +// Application must free memory of variables in DeepImage(image, offset_table) +// extern int LoadMultiPartDeepEXR(DeepImage **out_image, int num_parts, const +// char *filename, +// const char **err); + +// For emscripten. +// Loads single-frame OpenEXR image from memory. Assume EXR image contains +// RGB(A) channels. +// Returns negative value and may set error string in `err` when there's an +// error +extern int LoadEXRFromMemory(float **out_rgba, int *width, int *height, + const unsigned char *memory, size_t size, + const char **err); + +#ifdef __cplusplus +} +#endif + +#endif // TINYEXR_H_ + +#ifdef TINYEXR_IMPLEMENTATION +#ifndef TINYEXR_IMPLEMENTATION_DEIFNED +#define TINYEXR_IMPLEMENTATION_DEIFNED + +#include +#include +#include +#include +#include +#include + +#include +#include + +#if __cplusplus > 199711L +// C++11 +#include +#endif // __cplusplus > 199711L + +#ifdef _OPENMP +#include +#endif + +#if TINYEXR_USE_MINIZ +#else +// Issue #46. Please include your own zlib-compatible API header before including `tinyexr.h` +//#include "zlib.h" +#endif + +#if TINYEXR_USE_ZFP +#include "zfp.h" +#endif + +namespace tinyexr { + +#if __cplusplus > 199711L +// C++11 +typedef uint64_t tinyexr_uint64; +typedef int64_t tinyexr_int64; +#else +// Although `long long` is not a standard type pre C++11, assume it is defined +// as a compiler's extension. +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wc++11-long-long" +#endif +typedef unsigned long long tinyexr_uint64; +typedef long long tinyexr_int64; +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +#endif + +#if TINYEXR_USE_MINIZ + +namespace miniz { + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wc++11-long-long" +#pragma clang diagnostic ignored "-Wold-style-cast" +#pragma clang diagnostic ignored "-Wpadded" +#pragma clang diagnostic ignored "-Wsign-conversion" +#pragma clang diagnostic ignored "-Wc++11-extensions" +#pragma clang diagnostic ignored "-Wconversion" +#pragma clang diagnostic ignored "-Wunused-function" +#if __has_warning("-Wcomma") +#pragma clang diagnostic ignored "-Wcomma" +#endif +#endif + +/* miniz.c v1.15 - public domain deflate/inflate, zlib-subset, ZIP + reading/writing/appending, PNG writing + See "unlicense" statement at the end of this file. + Rich Geldreich , last updated Oct. 13, 2013 + Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: + http://www.ietf.org/rfc/rfc1951.txt + + Most API's defined in miniz.c are optional. For example, to disable the + archive related functions just define + MINIZ_NO_ARCHIVE_APIS, or to get rid of all stdio usage define MINIZ_NO_STDIO + (see the list below for more macros). + + * Change History + 10/13/13 v1.15 r4 - Interim bugfix release while I work on the next major + release with Zip64 support (almost there!): + - Critical fix for the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY bug + (thanks kahmyong.moon@hp.com) which could cause locate files to not find + files. This bug + would only have occured in earlier versions if you explicitly used this + flag, OR if you used mz_zip_extract_archive_file_to_heap() or + mz_zip_add_mem_to_archive_file_in_place() + (which used this flag). If you can't switch to v1.15 but want to fix + this bug, just remove the uses of this flag from both helper funcs (and of + course don't use the flag). + - Bugfix in mz_zip_reader_extract_to_mem_no_alloc() from kymoon when + pUser_read_buf is not NULL and compressed size is > uncompressed size + - Fixing mz_zip_reader_extract_*() funcs so they don't try to extract + compressed data from directory entries, to account for weird zipfiles which + contain zero-size compressed data on dir entries. + Hopefully this fix won't cause any issues on weird zip archives, + because it assumes the low 16-bits of zip external attributes are DOS + attributes (which I believe they always are in practice). + - Fixing mz_zip_reader_is_file_a_directory() so it doesn't check the + internal attributes, just the filename and external attributes + - mz_zip_reader_init_file() - missing MZ_FCLOSE() call if the seek failed + - Added cmake support for Linux builds which builds all the examples, + tested with clang v3.3 and gcc v4.6. + - Clang fix for tdefl_write_image_to_png_file_in_memory() from toffaletti + - Merged MZ_FORCEINLINE fix from hdeanclark + - Fix include before config #ifdef, thanks emil.brink + - Added tdefl_write_image_to_png_file_in_memory_ex(): supports Y flipping + (super useful for OpenGL apps), and explicit control over the compression + level (so you can + set it to 1 for real-time compression). + - Merged in some compiler fixes from paulharris's github repro. + - Retested this build under Windows (VS 2010, including static analysis), + tcc 0.9.26, gcc v4.6 and clang v3.3. + - Added example6.c, which dumps an image of the mandelbrot set to a PNG + file. + - Modified example2 to help test the + MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY flag more. + - In r3: Bugfix to mz_zip_writer_add_file() found during merge: Fix + possible src file fclose() leak if alignment bytes+local header file write + faiiled + - In r4: Minor bugfix to mz_zip_writer_add_from_zip_reader(): + Was pushing the wrong central dir header offset, appears harmless in this + release, but it became a problem in the zip64 branch + 5/20/12 v1.14 - MinGW32/64 GCC 4.6.1 compiler fixes: added MZ_FORCEINLINE, + #include (thanks fermtect). + 5/19/12 v1.13 - From jason@cornsyrup.org and kelwert@mtu.edu - Fix + mz_crc32() so it doesn't compute the wrong CRC-32's when mz_ulong is 64-bit. + - Temporarily/locally slammed in "typedef unsigned long mz_ulong" and + re-ran a randomized regression test on ~500k files. + - Eliminated a bunch of warnings when compiling with GCC 32-bit/64. + - Ran all examples, miniz.c, and tinfl.c through MSVC 2008's /analyze + (static analysis) option and fixed all warnings (except for the silly + "Use of the comma-operator in a tested expression.." analysis warning, + which I purposely use to work around a MSVC compiler warning). + - Created 32-bit and 64-bit Codeblocks projects/workspace. Built and + tested Linux executables. The codeblocks workspace is compatible with + Linux+Win32/x64. + - Added miniz_tester solution/project, which is a useful little app + derived from LZHAM's tester app that I use as part of the regression test. + - Ran miniz.c and tinfl.c through another series of regression testing on + ~500,000 files and archives. + - Modified example5.c so it purposely disables a bunch of high-level + functionality (MINIZ_NO_STDIO, etc.). (Thanks to corysama for the + MINIZ_NO_STDIO bug report.) + - Fix ftell() usage in examples so they exit with an error on files which + are too large (a limitation of the examples, not miniz itself). + 4/12/12 v1.12 - More comments, added low-level example5.c, fixed a couple + minor level_and_flags issues in the archive API's. + level_and_flags can now be set to MZ_DEFAULT_COMPRESSION. Thanks to Bruce + Dawson for the feedback/bug report. + 5/28/11 v1.11 - Added statement from unlicense.org + 5/27/11 v1.10 - Substantial compressor optimizations: + - Level 1 is now ~4x faster than before. The L1 compressor's throughput + now varies between 70-110MB/sec. on a + - Core i7 (actual throughput varies depending on the type of data, and x64 + vs. x86). + - Improved baseline L2-L9 compression perf. Also, greatly improved + compression perf. issues on some file types. + - Refactored the compression code for better readability and + maintainability. + - Added level 10 compression level (L10 has slightly better ratio than + level 9, but could have a potentially large + drop in throughput on some files). + 5/15/11 v1.09 - Initial stable release. + + * Low-level Deflate/Inflate implementation notes: + + Compression: Use the "tdefl" API's. The compressor supports raw, static, + and dynamic blocks, lazy or + greedy parsing, match length filtering, RLE-only, and Huffman-only streams. + It performs and compresses + approximately as well as zlib. + + Decompression: Use the "tinfl" API's. The entire decompressor is + implemented as a single function + coroutine: see tinfl_decompress(). It supports decompression into a 32KB + (or larger power of 2) wrapping buffer, or into a memory + block large enough to hold the entire file. + + The low-level tdefl/tinfl API's do not make any use of dynamic memory + allocation. + + * zlib-style API notes: + + miniz.c implements a fairly large subset of zlib. There's enough + functionality present for it to be a drop-in + zlib replacement in many apps: + The z_stream struct, optional memory allocation callbacks + deflateInit/deflateInit2/deflate/deflateReset/deflateEnd/deflateBound + inflateInit/inflateInit2/inflate/inflateEnd + compress, compress2, compressBound, uncompress + CRC-32, Adler-32 - Using modern, minimal code size, CPU cache friendly + routines. + Supports raw deflate streams or standard zlib streams with adler-32 + checking. + + Limitations: + The callback API's are not implemented yet. No support for gzip headers or + zlib static dictionaries. + I've tried to closely emulate zlib's various flavors of stream flushing + and return status codes, but + there are no guarantees that miniz.c pulls this off perfectly. + + * PNG writing: See the tdefl_write_image_to_png_file_in_memory() function, + originally written by + Alex Evans. Supports 1-4 bytes/pixel images. + + * ZIP archive API notes: + + The ZIP archive API's where designed with simplicity and efficiency in + mind, with just enough abstraction to + get the job done with minimal fuss. There are simple API's to retrieve file + information, read files from + existing archives, create new archives, append new files to existing + archives, or clone archive data from + one archive to another. It supports archives located in memory or the heap, + on disk (using stdio.h), + or you can specify custom file read/write callbacks. + + - Archive reading: Just call this function to read a single file from a + disk archive: + + void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const + char *pArchive_name, + size_t *pSize, mz_uint zip_flags); + + For more complex cases, use the "mz_zip_reader" functions. Upon opening an + archive, the entire central + directory is located and read as-is into memory, and subsequent file access + only occurs when reading individual files. + + - Archives file scanning: The simple way is to use this function to scan a + loaded archive for a specific file: + + int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, + const char *pComment, mz_uint flags); + + The locate operation can optionally check file comments too, which (as one + example) can be used to identify + multiple versions of the same file in an archive. This function uses a + simple linear search through the central + directory, so it's not very fast. + + Alternately, you can iterate through all the files in an archive (using + mz_zip_reader_get_num_files()) and + retrieve detailed info on each file by calling mz_zip_reader_file_stat(). + + - Archive creation: Use the "mz_zip_writer" functions. The ZIP writer + immediately writes compressed file data + to disk and builds an exact image of the central directory in memory. The + central directory image is written + all at once at the end of the archive file when the archive is finalized. + + The archive writer can optionally align each file's local header and file + data to any power of 2 alignment, + which can be useful when the archive will be read from optical media. Also, + the writer supports placing + arbitrary data blobs at the very beginning of ZIP archives. Archives + written using either feature are still + readable by any ZIP tool. + + - Archive appending: The simple way to add a single file to an archive is + to call this function: + + mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, + const char *pArchive_name, + const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 + comment_size, mz_uint level_and_flags); + + The archive will be created if it doesn't already exist, otherwise it'll be + appended to. + Note the appending is done in-place and is not an atomic operation, so if + something goes wrong + during the operation it's possible the archive could be left without a + central directory (although the local + file headers and file data will be fine, so the archive will be + recoverable). + + For more complex archive modification scenarios: + 1. The safest way is to use a mz_zip_reader to read the existing archive, + cloning only those bits you want to + preserve into a new archive using using the + mz_zip_writer_add_from_zip_reader() function (which compiles the + compressed file data as-is). When you're done, delete the old archive and + rename the newly written archive, and + you're done. This is safe but requires a bunch of temporary disk space or + heap memory. + + 2. Or, you can convert an mz_zip_reader in-place to an mz_zip_writer using + mz_zip_writer_init_from_reader(), + append new files as needed, then finalize the archive which will write an + updated central directory to the + original archive. (This is basically what + mz_zip_add_mem_to_archive_file_in_place() does.) There's a + possibility that the archive's central directory could be lost with this + method if anything goes wrong, though. + + - ZIP archive support limitations: + No zip64 or spanning support. Extraction functions can only handle + unencrypted, stored or deflated files. + Requires streams capable of seeking. + + * This is a header file library, like stb_image.c. To get only a header file, + either cut and paste the + below header, or create miniz.h, #define MINIZ_HEADER_FILE_ONLY, and then + include miniz.c from it. + + * Important: For best perf. be sure to customize the below macros for your + target platform: + #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1 + #define MINIZ_LITTLE_ENDIAN 1 + #define MINIZ_HAS_64BIT_REGISTERS 1 + + * On platforms using glibc, Be sure to "#define _LARGEFILE64_SOURCE 1" before + including miniz.c to ensure miniz + uses the 64-bit variants: fopen64(), stat64(), etc. Otherwise you won't be + able to process large files + (i.e. 32-bit stat() fails for me on files > 0x7FFFFFFF bytes). +*/ + +#ifndef MINIZ_HEADER_INCLUDED +#define MINIZ_HEADER_INCLUDED + +//#include + +// Defines to completely disable specific portions of miniz.c: +// If all macros here are defined the only functionality remaining will be +// CRC-32, adler-32, tinfl, and tdefl. + +// Define MINIZ_NO_STDIO to disable all usage and any functions which rely on +// stdio for file I/O. +//#define MINIZ_NO_STDIO + +// If MINIZ_NO_TIME is specified then the ZIP archive functions will not be able +// to get the current time, or +// get/set file times, and the C run-time funcs that get/set times won't be +// called. +// The current downside is the times written to your archives will be from 1979. +#define MINIZ_NO_TIME + +// Define MINIZ_NO_ARCHIVE_APIS to disable all ZIP archive API's. +#define MINIZ_NO_ARCHIVE_APIS + +// Define MINIZ_NO_ARCHIVE_APIS to disable all writing related ZIP archive +// API's. +//#define MINIZ_NO_ARCHIVE_WRITING_APIS + +// Define MINIZ_NO_ZLIB_APIS to remove all ZLIB-style compression/decompression +// API's. +//#define MINIZ_NO_ZLIB_APIS + +// Define MINIZ_NO_ZLIB_COMPATIBLE_NAME to disable zlib names, to prevent +// conflicts against stock zlib. +//#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES + +// Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc. +// Note if MINIZ_NO_MALLOC is defined then the user must always provide custom +// user alloc/free/realloc +// callbacks to the zlib and archive API's, and a few stand-alone helper API's +// which don't provide custom user +// functions (such as tdefl_compress_mem_to_heap() and +// tinfl_decompress_mem_to_heap()) won't work. +//#define MINIZ_NO_MALLOC + +#if defined(__TINYC__) && (defined(__linux) || defined(__linux__)) +// TODO: Work around "error: include file 'sys\utime.h' when compiling with tcc +// on Linux +#define MINIZ_NO_TIME +#endif + +#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_ARCHIVE_APIS) +//#include +#endif + +#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || \ + defined(__i386) || defined(__i486__) || defined(__i486) || \ + defined(i386) || defined(__ia64__) || defined(__x86_64__) +// MINIZ_X86_OR_X64_CPU is only used to help set the below macros. +#define MINIZ_X86_OR_X64_CPU 1 +#endif + +#if defined(__sparcv9) +// Big endian +#else +#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU +// Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. +#define MINIZ_LITTLE_ENDIAN 1 +#endif +#endif + +#if MINIZ_X86_OR_X64_CPU +// Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient +// integer loads and stores from unaligned addresses. +//#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1 +#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES \ + 0 // disable to suppress compiler warnings +#endif + +#if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || \ + defined(_LP64) || defined(__LP64__) || defined(__ia64__) || \ + defined(__x86_64__) +// Set MINIZ_HAS_64BIT_REGISTERS to 1 if operations on 64-bit integers are +// reasonably fast (and don't involve compiler generated calls to helper +// functions). +#define MINIZ_HAS_64BIT_REGISTERS 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +// ------------------- zlib-style API Definitions. + +// For more compatibility with zlib, miniz.c uses unsigned long for some +// parameters/struct members. Beware: mz_ulong can be either 32 or 64-bits! +typedef unsigned long mz_ulong; + +// mz_free() internally uses the MZ_FREE() macro (which by default calls free() +// unless you've modified the MZ_MALLOC macro) to release a block allocated from +// the heap. +void mz_free(void *p); + +#define MZ_ADLER32_INIT (1) +// mz_adler32() returns the initial adler-32 value to use when called with +// ptr==NULL. +mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len); + +#define MZ_CRC32_INIT (0) +// mz_crc32() returns the initial CRC-32 value to use when called with +// ptr==NULL. +mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len); + +// Compression strategies. +enum { + MZ_DEFAULT_STRATEGY = 0, + MZ_FILTERED = 1, + MZ_HUFFMAN_ONLY = 2, + MZ_RLE = 3, + MZ_FIXED = 4 +}; + +// Method +#define MZ_DEFLATED 8 + +#ifndef MINIZ_NO_ZLIB_APIS + +// Heap allocation callbacks. +// Note that mz_alloc_func parameter types purpsosely differ from zlib's: +// items/size is size_t, not unsigned long. +typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size); +typedef void (*mz_free_func)(void *opaque, void *address); +typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, + size_t size); + +#define MZ_VERSION "9.1.15" +#define MZ_VERNUM 0x91F0 +#define MZ_VER_MAJOR 9 +#define MZ_VER_MINOR 1 +#define MZ_VER_REVISION 15 +#define MZ_VER_SUBREVISION 0 + +// Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The +// other values are for advanced use (refer to the zlib docs). +enum { + MZ_NO_FLUSH = 0, + MZ_PARTIAL_FLUSH = 1, + MZ_SYNC_FLUSH = 2, + MZ_FULL_FLUSH = 3, + MZ_FINISH = 4, + MZ_BLOCK = 5 +}; + +// Return status codes. MZ_PARAM_ERROR is non-standard. +enum { + MZ_OK = 0, + MZ_STREAM_END = 1, + MZ_NEED_DICT = 2, + MZ_ERRNO = -1, + MZ_STREAM_ERROR = -2, + MZ_DATA_ERROR = -3, + MZ_MEM_ERROR = -4, + MZ_BUF_ERROR = -5, + MZ_VERSION_ERROR = -6, + MZ_PARAM_ERROR = -10000 +}; + +// Compression levels: 0-9 are the standard zlib-style levels, 10 is best +// possible compression (not zlib compatible, and may be very slow), +// MZ_DEFAULT_COMPRESSION=MZ_DEFAULT_LEVEL. +enum { + MZ_NO_COMPRESSION = 0, + MZ_BEST_SPEED = 1, + MZ_BEST_COMPRESSION = 9, + MZ_UBER_COMPRESSION = 10, + MZ_DEFAULT_LEVEL = 6, + MZ_DEFAULT_COMPRESSION = -1 +}; + +// Window bits +#define MZ_DEFAULT_WINDOW_BITS 15 + +struct mz_internal_state; + +// Compression/decompression stream struct. +typedef struct mz_stream_s { + const unsigned char *next_in; // pointer to next byte to read + unsigned int avail_in; // number of bytes available at next_in + mz_ulong total_in; // total number of bytes consumed so far + + unsigned char *next_out; // pointer to next byte to write + unsigned int avail_out; // number of bytes that can be written to next_out + mz_ulong total_out; // total number of bytes produced so far + + char *msg; // error msg (unused) + struct mz_internal_state *state; // internal state, allocated by zalloc/zfree + + mz_alloc_func + zalloc; // optional heap allocation function (defaults to malloc) + mz_free_func zfree; // optional heap free function (defaults to free) + void *opaque; // heap alloc function user pointer + + int data_type; // data_type (unused) + mz_ulong adler; // adler32 of the source or uncompressed data + mz_ulong reserved; // not used +} mz_stream; + +typedef mz_stream *mz_streamp; + +// Returns the version string of miniz.c. +const char *mz_version(void); + +// mz_deflateInit() initializes a compressor with default options: +// Parameters: +// pStream must point to an initialized mz_stream struct. +// level must be between [MZ_NO_COMPRESSION, MZ_BEST_COMPRESSION]. +// level 1 enables a specially optimized compression function that's been +// optimized purely for performance, not ratio. +// (This special func. is currently only enabled when +// MINIZ_USE_UNALIGNED_LOADS_AND_STORES and MINIZ_LITTLE_ENDIAN are defined.) +// Return values: +// MZ_OK on success. +// MZ_STREAM_ERROR if the stream is bogus. +// MZ_PARAM_ERROR if the input parameters are bogus. +// MZ_MEM_ERROR on out of memory. +int mz_deflateInit(mz_streamp pStream, int level); + +// mz_deflateInit2() is like mz_deflate(), except with more control: +// Additional parameters: +// method must be MZ_DEFLATED +// window_bits must be MZ_DEFAULT_WINDOW_BITS (to wrap the deflate stream with +// zlib header/adler-32 footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate/no +// header or footer) +// mem_level must be between [1, 9] (it's checked but ignored by miniz.c) +int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, + int mem_level, int strategy); + +// Quickly resets a compressor without having to reallocate anything. Same as +// calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2(). +int mz_deflateReset(mz_streamp pStream); + +// mz_deflate() compresses the input to output, consuming as much of the input +// and producing as much output as possible. +// Parameters: +// pStream is the stream to read from and write to. You must initialize/update +// the next_in, avail_in, next_out, and avail_out members. +// flush may be MZ_NO_FLUSH, MZ_PARTIAL_FLUSH/MZ_SYNC_FLUSH, MZ_FULL_FLUSH, or +// MZ_FINISH. +// Return values: +// MZ_OK on success (when flushing, or if more input is needed but not +// available, and/or there's more output to be written but the output buffer +// is full). +// MZ_STREAM_END if all input has been consumed and all output bytes have been +// written. Don't call mz_deflate() on the stream anymore. +// MZ_STREAM_ERROR if the stream is bogus. +// MZ_PARAM_ERROR if one of the parameters is invalid. +// MZ_BUF_ERROR if no forward progress is possible because the input and/or +// output buffers are empty. (Fill up the input buffer or free up some output +// space and try again.) +int mz_deflate(mz_streamp pStream, int flush); + +// mz_deflateEnd() deinitializes a compressor: +// Return values: +// MZ_OK on success. +// MZ_STREAM_ERROR if the stream is bogus. +int mz_deflateEnd(mz_streamp pStream); + +// mz_deflateBound() returns a (very) conservative upper bound on the amount of +// data that could be generated by deflate(), assuming flush is set to only +// MZ_NO_FLUSH or MZ_FINISH. +mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len); + +// Single-call compression functions mz_compress() and mz_compress2(): +// Returns MZ_OK on success, or one of the error codes from mz_deflate() on +// failure. +int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, + const unsigned char *pSource, mz_ulong source_len); +int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, + const unsigned char *pSource, mz_ulong source_len, int level); + +// mz_compressBound() returns a (very) conservative upper bound on the amount of +// data that could be generated by calling mz_compress(). +mz_ulong mz_compressBound(mz_ulong source_len); + +// Initializes a decompressor. +int mz_inflateInit(mz_streamp pStream); + +// mz_inflateInit2() is like mz_inflateInit() with an additional option that +// controls the window size and whether or not the stream has been wrapped with +// a zlib header/footer: +// window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or +// -MZ_DEFAULT_WINDOW_BITS (raw deflate). +int mz_inflateInit2(mz_streamp pStream, int window_bits); + +// Decompresses the input stream to the output, consuming only as much of the +// input as needed, and writing as much to the output as possible. +// Parameters: +// pStream is the stream to read from and write to. You must initialize/update +// the next_in, avail_in, next_out, and avail_out members. +// flush may be MZ_NO_FLUSH, MZ_SYNC_FLUSH, or MZ_FINISH. +// On the first call, if flush is MZ_FINISH it's assumed the input and output +// buffers are both sized large enough to decompress the entire stream in a +// single call (this is slightly faster). +// MZ_FINISH implies that there are no more source bytes available beside +// what's already in the input buffer, and that the output buffer is large +// enough to hold the rest of the decompressed data. +// Return values: +// MZ_OK on success. Either more input is needed but not available, and/or +// there's more output to be written but the output buffer is full. +// MZ_STREAM_END if all needed input has been consumed and all output bytes +// have been written. For zlib streams, the adler-32 of the decompressed data +// has also been verified. +// MZ_STREAM_ERROR if the stream is bogus. +// MZ_DATA_ERROR if the deflate stream is invalid. +// MZ_PARAM_ERROR if one of the parameters is invalid. +// MZ_BUF_ERROR if no forward progress is possible because the input buffer is +// empty but the inflater needs more input to continue, or if the output +// buffer is not large enough. Call mz_inflate() again +// with more input data, or with more room in the output buffer (except when +// using single call decompression, described above). +int mz_inflate(mz_streamp pStream, int flush); + +// Deinitializes a decompressor. +int mz_inflateEnd(mz_streamp pStream); + +// Single-call decompression. +// Returns MZ_OK on success, or one of the error codes from mz_inflate() on +// failure. +int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, + const unsigned char *pSource, mz_ulong source_len); + +// Returns a string description of the specified error code, or NULL if the +// error code is invalid. +const char *mz_error(int err); + +// Redefine zlib-compatible names to miniz equivalents, so miniz.c can be used +// as a drop-in replacement for the subset of zlib that miniz.c supports. +// Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you +// use zlib in the same project. +#ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES +typedef unsigned char Byte; +typedef unsigned int uInt; +typedef mz_ulong uLong; +typedef Byte Bytef; +typedef uInt uIntf; +typedef char charf; +typedef int intf; +typedef void *voidpf; +typedef uLong uLongf; +typedef void *voidp; +typedef void *const voidpc; +#define Z_NULL 0 +#define Z_NO_FLUSH MZ_NO_FLUSH +#define Z_PARTIAL_FLUSH MZ_PARTIAL_FLUSH +#define Z_SYNC_FLUSH MZ_SYNC_FLUSH +#define Z_FULL_FLUSH MZ_FULL_FLUSH +#define Z_FINISH MZ_FINISH +#define Z_BLOCK MZ_BLOCK +#define Z_OK MZ_OK +#define Z_STREAM_END MZ_STREAM_END +#define Z_NEED_DICT MZ_NEED_DICT +#define Z_ERRNO MZ_ERRNO +#define Z_STREAM_ERROR MZ_STREAM_ERROR +#define Z_DATA_ERROR MZ_DATA_ERROR +#define Z_MEM_ERROR MZ_MEM_ERROR +#define Z_BUF_ERROR MZ_BUF_ERROR +#define Z_VERSION_ERROR MZ_VERSION_ERROR +#define Z_PARAM_ERROR MZ_PARAM_ERROR +#define Z_NO_COMPRESSION MZ_NO_COMPRESSION +#define Z_BEST_SPEED MZ_BEST_SPEED +#define Z_BEST_COMPRESSION MZ_BEST_COMPRESSION +#define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION +#define Z_DEFAULT_STRATEGY MZ_DEFAULT_STRATEGY +#define Z_FILTERED MZ_FILTERED +#define Z_HUFFMAN_ONLY MZ_HUFFMAN_ONLY +#define Z_RLE MZ_RLE +#define Z_FIXED MZ_FIXED +#define Z_DEFLATED MZ_DEFLATED +#define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS +#define alloc_func mz_alloc_func +#define free_func mz_free_func +#define internal_state mz_internal_state +#define z_stream mz_stream +#define deflateInit mz_deflateInit +#define deflateInit2 mz_deflateInit2 +#define deflateReset mz_deflateReset +#define deflate mz_deflate +#define deflateEnd mz_deflateEnd +#define deflateBound mz_deflateBound +#define compress mz_compress +#define compress2 mz_compress2 +#define compressBound mz_compressBound +#define inflateInit mz_inflateInit +#define inflateInit2 mz_inflateInit2 +#define inflate mz_inflate +#define inflateEnd mz_inflateEnd +#define uncompress mz_uncompress +#define crc32 mz_crc32 +#define adler32 mz_adler32 +#define MAX_WBITS 15 +#define MAX_MEM_LEVEL 9 +#define zError mz_error +#define ZLIB_VERSION MZ_VERSION +#define ZLIB_VERNUM MZ_VERNUM +#define ZLIB_VER_MAJOR MZ_VER_MAJOR +#define ZLIB_VER_MINOR MZ_VER_MINOR +#define ZLIB_VER_REVISION MZ_VER_REVISION +#define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION +#define zlibVersion mz_version +#define zlib_version mz_version() +#endif // #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES + +#endif // MINIZ_NO_ZLIB_APIS + +// ------------------- Types and macros + +typedef unsigned char mz_uint8; +typedef signed short mz_int16; +typedef unsigned short mz_uint16; +typedef unsigned int mz_uint32; +typedef unsigned int mz_uint; +typedef long long mz_int64; +typedef unsigned long long mz_uint64; +typedef int mz_bool; + +#define MZ_FALSE (0) +#define MZ_TRUE (1) + +// An attempt to work around MSVC's spammy "warning C4127: conditional +// expression is constant" message. +#ifdef _MSC_VER +#define MZ_MACRO_END while (0, 0) +#else +#define MZ_MACRO_END while (0) +#endif + +// ------------------- ZIP archive reading/writing + +#ifndef MINIZ_NO_ARCHIVE_APIS + +enum { + MZ_ZIP_MAX_IO_BUF_SIZE = 64 * 1024, + MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE = 260, + MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE = 256 +}; + +typedef struct { + mz_uint32 m_file_index; + mz_uint32 m_central_dir_ofs; + mz_uint16 m_version_made_by; + mz_uint16 m_version_needed; + mz_uint16 m_bit_flag; + mz_uint16 m_method; +#ifndef MINIZ_NO_TIME + time_t m_time; +#endif + mz_uint32 m_crc32; + mz_uint64 m_comp_size; + mz_uint64 m_uncomp_size; + mz_uint16 m_internal_attr; + mz_uint32 m_external_attr; + mz_uint64 m_local_header_ofs; + mz_uint32 m_comment_size; + char m_filename[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE]; + char m_comment[MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE]; +} mz_zip_archive_file_stat; + +typedef size_t (*mz_file_read_func)(void *pOpaque, mz_uint64 file_ofs, + void *pBuf, size_t n); +typedef size_t (*mz_file_write_func)(void *pOpaque, mz_uint64 file_ofs, + const void *pBuf, size_t n); + +struct mz_zip_internal_state_tag; +typedef struct mz_zip_internal_state_tag mz_zip_internal_state; + +typedef enum { + MZ_ZIP_MODE_INVALID = 0, + MZ_ZIP_MODE_READING = 1, + MZ_ZIP_MODE_WRITING = 2, + MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3 +} mz_zip_mode; + +typedef struct mz_zip_archive_tag { + mz_uint64 m_archive_size; + mz_uint64 m_central_directory_file_ofs; + mz_uint m_total_files; + mz_zip_mode m_zip_mode; + + mz_uint m_file_offset_alignment; + + mz_alloc_func m_pAlloc; + mz_free_func m_pFree; + mz_realloc_func m_pRealloc; + void *m_pAlloc_opaque; + + mz_file_read_func m_pRead; + mz_file_write_func m_pWrite; + void *m_pIO_opaque; + + mz_zip_internal_state *m_pState; + +} mz_zip_archive; + +typedef enum { + MZ_ZIP_FLAG_CASE_SENSITIVE = 0x0100, + MZ_ZIP_FLAG_IGNORE_PATH = 0x0200, + MZ_ZIP_FLAG_COMPRESSED_DATA = 0x0400, + MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY = 0x0800 +} mz_zip_flags; + +// ZIP archive reading + +// Inits a ZIP archive reader. +// These functions read and validate the archive's central directory. +mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, + mz_uint32 flags); +mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, + size_t size, mz_uint32 flags); + +#ifndef MINIZ_NO_STDIO +mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, + mz_uint32 flags); +#endif + +// Returns the total number of files in the archive. +mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip); + +// Returns detailed information about an archive file entry. +mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, + mz_zip_archive_file_stat *pStat); + +// Determines if an archive file entry is a directory entry. +mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, + mz_uint file_index); +mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, + mz_uint file_index); + +// Retrieves the filename of an archive file entry. +// Returns the number of bytes written to pFilename, or if filename_buf_size is +// 0 this function returns the number of bytes needed to fully store the +// filename. +mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, + char *pFilename, mz_uint filename_buf_size); + +// Attempts to locates a file in the archive's central directory. +// Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH +// Returns -1 if the file cannot be found. +int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, + const char *pComment, mz_uint flags); + +// Extracts a archive file to a memory buffer using no memory allocation. +mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, + mz_uint file_index, void *pBuf, + size_t buf_size, mz_uint flags, + void *pUser_read_buf, + size_t user_read_buf_size); +mz_bool mz_zip_reader_extract_file_to_mem_no_alloc( + mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, + mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size); + +// Extracts a archive file to a memory buffer. +mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, + void *pBuf, size_t buf_size, + mz_uint flags); +mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, + const char *pFilename, void *pBuf, + size_t buf_size, mz_uint flags); + +// Extracts a archive file to a dynamically allocated heap buffer. +void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, + size_t *pSize, mz_uint flags); +void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, + const char *pFilename, size_t *pSize, + mz_uint flags); + +// Extracts a archive file using a callback function to output the file's data. +mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, + mz_uint file_index, + mz_file_write_func pCallback, + void *pOpaque, mz_uint flags); +mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, + const char *pFilename, + mz_file_write_func pCallback, + void *pOpaque, mz_uint flags); + +#ifndef MINIZ_NO_STDIO +// Extracts a archive file to a disk file and sets its last accessed and +// modified times. +// This function only extracts files, not archive directory records. +mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, + const char *pDst_filename, mz_uint flags); +mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, + const char *pArchive_filename, + const char *pDst_filename, + mz_uint flags); +#endif + +// Ends archive reading, freeing all allocations, and closing the input archive +// file if mz_zip_reader_init_file() was used. +mz_bool mz_zip_reader_end(mz_zip_archive *pZip); + +// ZIP archive writing + +#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS + +// Inits a ZIP archive writer. +mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size); +mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, + size_t size_to_reserve_at_beginning, + size_t initial_allocation_size); + +#ifndef MINIZ_NO_STDIO +mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, + mz_uint64 size_to_reserve_at_beginning); +#endif + +// Converts a ZIP archive reader object into a writer object, to allow efficient +// in-place file appends to occur on an existing archive. +// For archives opened using mz_zip_reader_init_file, pFilename must be the +// archive's filename so it can be reopened for writing. If the file can't be +// reopened, mz_zip_reader_end() will be called. +// For archives opened using mz_zip_reader_init_mem, the memory block must be +// growable using the realloc callback (which defaults to realloc unless you've +// overridden it). +// Finally, for archives opened using mz_zip_reader_init, the mz_zip_archive's +// user provided m_pWrite function cannot be NULL. +// Note: In-place archive modification is not recommended unless you know what +// you're doing, because if execution stops or something goes wrong before +// the archive is finalized the file's central directory will be hosed. +mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, + const char *pFilename); + +// Adds the contents of a memory buffer to an archive. These functions record +// the current local time into the archive. +// To add a directory entry, call this method with an archive name ending in a +// forwardslash with empty buffer. +// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, +// MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or +// just set to MZ_DEFAULT_COMPRESSION. +mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, + const void *pBuf, size_t buf_size, + mz_uint level_and_flags); +mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, + const char *pArchive_name, const void *pBuf, + size_t buf_size, const void *pComment, + mz_uint16 comment_size, + mz_uint level_and_flags, mz_uint64 uncomp_size, + mz_uint32 uncomp_crc32); + +#ifndef MINIZ_NO_STDIO +// Adds the contents of a disk file to an archive. This function also records +// the disk file's modified time into the archive. +// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, +// MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or +// just set to MZ_DEFAULT_COMPRESSION. +mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, + const char *pSrc_filename, const void *pComment, + mz_uint16 comment_size, mz_uint level_and_flags); +#endif + +// Adds a file to an archive by fully cloning the data from another archive. +// This function fully clones the source file's compressed data (no +// recompression), along with its full filename, extra data, and comment fields. +mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, + mz_zip_archive *pSource_zip, + mz_uint file_index); + +// Finalizes the archive by writing the central directory records followed by +// the end of central directory record. +// After an archive is finalized, the only valid call on the mz_zip_archive +// struct is mz_zip_writer_end(). +// An archive must be manually finalized by calling this function for it to be +// valid. +mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip); +mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **pBuf, + size_t *pSize); + +// Ends archive writing, freeing all allocations, and closing the output file if +// mz_zip_writer_init_file() was used. +// Note for the archive to be valid, it must have been finalized before ending. +mz_bool mz_zip_writer_end(mz_zip_archive *pZip); + +// Misc. high-level helper functions: + +// mz_zip_add_mem_to_archive_file_in_place() efficiently (but not atomically) +// appends a memory blob to a ZIP archive. +// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, +// MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or +// just set to MZ_DEFAULT_COMPRESSION. +mz_bool mz_zip_add_mem_to_archive_file_in_place( + const char *pZip_filename, const char *pArchive_name, const void *pBuf, + size_t buf_size, const void *pComment, mz_uint16 comment_size, + mz_uint level_and_flags); + +// Reads a single file from an archive into a heap block. +// Returns NULL on failure. +void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, + const char *pArchive_name, + size_t *pSize, mz_uint zip_flags); + +#endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS + +#endif // #ifndef MINIZ_NO_ARCHIVE_APIS + +// ------------------- Low-level Decompression API Definitions + +// Decompression flags used by tinfl_decompress(). +// TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and +// ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the +// input is a raw deflate stream. +// TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available +// beyond the end of the supplied input buffer. If clear, the input buffer +// contains all remaining input. +// TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large +// enough to hold the entire decompressed stream. If clear, the output buffer is +// at least the size of the dictionary (typically 32KB). +// TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the +// decompressed bytes. +enum { + TINFL_FLAG_PARSE_ZLIB_HEADER = 1, + TINFL_FLAG_HAS_MORE_INPUT = 2, + TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4, + TINFL_FLAG_COMPUTE_ADLER32 = 8 +}; + +// High level decompression functions: +// tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block +// allocated via malloc(). +// On entry: +// pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data +// to decompress. +// On return: +// Function returns a pointer to the decompressed data, or NULL on failure. +// *pOut_len will be set to the decompressed data's size, which could be larger +// than src_buf_len on uncompressible data. +// The caller must call mz_free() on the returned block when it's no longer +// needed. +void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, + size_t *pOut_len, int flags); + +// tinfl_decompress_mem_to_mem() decompresses a block in memory to another block +// in memory. +// Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes +// written on success. +#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1)) +size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, + const void *pSrc_buf, size_t src_buf_len, + int flags); + +// tinfl_decompress_mem_to_callback() decompresses a block in memory to an +// internal 32KB buffer, and a user provided callback function will be called to +// flush the buffer. +// Returns 1 on success or 0 on failure. +typedef int (*tinfl_put_buf_func_ptr)(const void *pBuf, int len, void *pUser); +int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, + tinfl_put_buf_func_ptr pPut_buf_func, + void *pPut_buf_user, int flags); + +struct tinfl_decompressor_tag; +typedef struct tinfl_decompressor_tag tinfl_decompressor; + +// Max size of LZ dictionary. +#define TINFL_LZ_DICT_SIZE 32768 + +// Return status. +typedef enum { + TINFL_STATUS_BAD_PARAM = -3, + TINFL_STATUS_ADLER32_MISMATCH = -2, + TINFL_STATUS_FAILED = -1, + TINFL_STATUS_DONE = 0, + TINFL_STATUS_NEEDS_MORE_INPUT = 1, + TINFL_STATUS_HAS_MORE_OUTPUT = 2 +} tinfl_status; + +// Initializes the decompressor to its initial state. +#define tinfl_init(r) \ + do { \ + (r)->m_state = 0; \ + } \ + MZ_MACRO_END +#define tinfl_get_adler32(r) (r)->m_check_adler32 + +// Main low-level decompressor coroutine function. This is the only function +// actually needed for decompression. All the other functions are just +// high-level helpers for improved usability. +// This is a universal API, i.e. it can be used as a building block to build any +// desired higher level decompression API. In the limit case, it can be called +// once per every byte input or output. +tinfl_status tinfl_decompress(tinfl_decompressor *r, + const mz_uint8 *pIn_buf_next, + size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, + mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, + const mz_uint32 decomp_flags); + +// Internal/private bits follow. +enum { + TINFL_MAX_HUFF_TABLES = 3, + TINFL_MAX_HUFF_SYMBOLS_0 = 288, + TINFL_MAX_HUFF_SYMBOLS_1 = 32, + TINFL_MAX_HUFF_SYMBOLS_2 = 19, + TINFL_FAST_LOOKUP_BITS = 10, + TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS +}; + +typedef struct { + mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0]; + mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], + m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2]; +} tinfl_huff_table; + +#if MINIZ_HAS_64BIT_REGISTERS +#define TINFL_USE_64BIT_BITBUF 1 +#endif + +#if TINFL_USE_64BIT_BITBUF +typedef mz_uint64 tinfl_bit_buf_t; +#define TINFL_BITBUF_SIZE (64) +#else +typedef mz_uint32 tinfl_bit_buf_t; +#define TINFL_BITBUF_SIZE (32) +#endif + +struct tinfl_decompressor_tag { + mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, + m_check_adler32, m_dist, m_counter, m_num_extra, + m_table_sizes[TINFL_MAX_HUFF_TABLES]; + tinfl_bit_buf_t m_bit_buf; + size_t m_dist_from_out_buf_start; + tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES]; + mz_uint8 m_raw_header[4], + m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137]; +}; + +// ------------------- Low-level Compression API Definitions + +// Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly +// slower, and raw/dynamic blocks will be output more frequently). +#define TDEFL_LESS_MEMORY 0 + +// tdefl_init() compression flags logically OR'd together (low 12 bits contain +// the max. number of probes per dictionary search): +// TDEFL_DEFAULT_MAX_PROBES: The compressor defaults to 128 dictionary probes +// per dictionary search. 0=Huffman only, 1=Huffman+LZ (fastest/crap +// compression), 4095=Huffman+LZ (slowest/best compression). +enum { + TDEFL_HUFFMAN_ONLY = 0, + TDEFL_DEFAULT_MAX_PROBES = 128, + TDEFL_MAX_PROBES_MASK = 0xFFF +}; + +// TDEFL_WRITE_ZLIB_HEADER: If set, the compressor outputs a zlib header before +// the deflate data, and the Adler-32 of the source data at the end. Otherwise, +// you'll get raw deflate data. +// TDEFL_COMPUTE_ADLER32: Always compute the adler-32 of the input data (even +// when not writing zlib headers). +// TDEFL_GREEDY_PARSING_FLAG: Set to use faster greedy parsing, instead of more +// efficient lazy parsing. +// TDEFL_NONDETERMINISTIC_PARSING_FLAG: Enable to decrease the compressor's +// initialization time to the minimum, but the output may vary from run to run +// given the same input (depending on the contents of memory). +// TDEFL_RLE_MATCHES: Only look for RLE matches (matches with a distance of 1) +// TDEFL_FILTER_MATCHES: Discards matches <= 5 chars if enabled. +// TDEFL_FORCE_ALL_STATIC_BLOCKS: Disable usage of optimized Huffman tables. +// TDEFL_FORCE_ALL_RAW_BLOCKS: Only use raw (uncompressed) deflate blocks. +// The low 12 bits are reserved to control the max # of hash probes per +// dictionary lookup (see TDEFL_MAX_PROBES_MASK). +enum { + TDEFL_WRITE_ZLIB_HEADER = 0x01000, + TDEFL_COMPUTE_ADLER32 = 0x02000, + TDEFL_GREEDY_PARSING_FLAG = 0x04000, + TDEFL_NONDETERMINISTIC_PARSING_FLAG = 0x08000, + TDEFL_RLE_MATCHES = 0x10000, + TDEFL_FILTER_MATCHES = 0x20000, + TDEFL_FORCE_ALL_STATIC_BLOCKS = 0x40000, + TDEFL_FORCE_ALL_RAW_BLOCKS = 0x80000 +}; + +// High level compression functions: +// tdefl_compress_mem_to_heap() compresses a block in memory to a heap block +// allocated via malloc(). +// On entry: +// pSrc_buf, src_buf_len: Pointer and size of source block to compress. +// flags: The max match finder probes (default is 128) logically OR'd against +// the above flags. Higher probes are slower but improve compression. +// On return: +// Function returns a pointer to the compressed data, or NULL on failure. +// *pOut_len will be set to the compressed data's size, which could be larger +// than src_buf_len on uncompressible data. +// The caller must free() the returned block when it's no longer needed. +void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, + size_t *pOut_len, int flags); + +// tdefl_compress_mem_to_mem() compresses a block in memory to another block in +// memory. +// Returns 0 on failure. +size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, + const void *pSrc_buf, size_t src_buf_len, + int flags); + +// Compresses an image to a compressed PNG file in memory. +// On entry: +// pImage, w, h, and num_chans describe the image to compress. num_chans may be +// 1, 2, 3, or 4. +// The image pitch in bytes per scanline will be w*num_chans. The leftmost +// pixel on the top scanline is stored first in memory. +// level may range from [0,10], use MZ_NO_COMPRESSION, MZ_BEST_SPEED, +// MZ_BEST_COMPRESSION, etc. or a decent default is MZ_DEFAULT_LEVEL +// If flip is true, the image will be flipped on the Y axis (useful for OpenGL +// apps). +// On return: +// Function returns a pointer to the compressed data, or NULL on failure. +// *pLen_out will be set to the size of the PNG image file. +// The caller must mz_free() the returned heap block (which will typically be +// larger than *pLen_out) when it's no longer needed. +void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, + int h, int num_chans, + size_t *pLen_out, + mz_uint level, mz_bool flip); +void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, + int num_chans, size_t *pLen_out); + +// Output stream interface. The compressor uses this interface to write +// compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time. +typedef mz_bool (*tdefl_put_buf_func_ptr)(const void *pBuf, int len, + void *pUser); + +// tdefl_compress_mem_to_output() compresses a block to an output stream. The +// above helpers use this function internally. +mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, + tdefl_put_buf_func_ptr pPut_buf_func, + void *pPut_buf_user, int flags); + +enum { + TDEFL_MAX_HUFF_TABLES = 3, + TDEFL_MAX_HUFF_SYMBOLS_0 = 288, + TDEFL_MAX_HUFF_SYMBOLS_1 = 32, + TDEFL_MAX_HUFF_SYMBOLS_2 = 19, + TDEFL_LZ_DICT_SIZE = 32768, + TDEFL_LZ_DICT_SIZE_MASK = TDEFL_LZ_DICT_SIZE - 1, + TDEFL_MIN_MATCH_LEN = 3, + TDEFL_MAX_MATCH_LEN = 258 +}; + +// TDEFL_OUT_BUF_SIZE MUST be large enough to hold a single entire compressed +// output block (using static/fixed Huffman codes). +#if TDEFL_LESS_MEMORY +enum { + TDEFL_LZ_CODE_BUF_SIZE = 24 * 1024, + TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10, + TDEFL_MAX_HUFF_SYMBOLS = 288, + TDEFL_LZ_HASH_BITS = 12, + TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, + TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, + TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS +}; +#else +enum { + TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024, + TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10, + TDEFL_MAX_HUFF_SYMBOLS = 288, + TDEFL_LZ_HASH_BITS = 15, + TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, + TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, + TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS +}; +#endif + +// The low-level tdefl functions below may be used directly if the above helper +// functions aren't flexible enough. The low-level functions don't make any heap +// allocations, unlike the above helper functions. +typedef enum { + TDEFL_STATUS_BAD_PARAM = -2, + TDEFL_STATUS_PUT_BUF_FAILED = -1, + TDEFL_STATUS_OKAY = 0, + TDEFL_STATUS_DONE = 1 +} tdefl_status; + +// Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums +typedef enum { + TDEFL_NO_FLUSH = 0, + TDEFL_SYNC_FLUSH = 2, + TDEFL_FULL_FLUSH = 3, + TDEFL_FINISH = 4 +} tdefl_flush; + +// tdefl's compression state structure. +typedef struct { + tdefl_put_buf_func_ptr m_pPut_buf_func; + void *m_pPut_buf_user; + mz_uint m_flags, m_max_probes[2]; + int m_greedy_parsing; + mz_uint m_adler32, m_lookahead_pos, m_lookahead_size, m_dict_size; + mz_uint8 *m_pLZ_code_buf, *m_pLZ_flags, *m_pOutput_buf, *m_pOutput_buf_end; + mz_uint m_num_flags_left, m_total_lz_bytes, m_lz_code_buf_dict_pos, m_bits_in, + m_bit_buffer; + mz_uint m_saved_match_dist, m_saved_match_len, m_saved_lit, + m_output_flush_ofs, m_output_flush_remaining, m_finished, m_block_index, + m_wants_to_finish; + tdefl_status m_prev_return_status; + const void *m_pIn_buf; + void *m_pOut_buf; + size_t *m_pIn_buf_size, *m_pOut_buf_size; + tdefl_flush m_flush; + const mz_uint8 *m_pSrc; + size_t m_src_buf_left, m_out_buf_ofs; + mz_uint8 m_dict[TDEFL_LZ_DICT_SIZE + TDEFL_MAX_MATCH_LEN - 1]; + mz_uint16 m_huff_count[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; + mz_uint16 m_huff_codes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; + mz_uint8 m_huff_code_sizes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; + mz_uint8 m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE]; + mz_uint16 m_next[TDEFL_LZ_DICT_SIZE]; + mz_uint16 m_hash[TDEFL_LZ_HASH_SIZE]; + mz_uint8 m_output_buf[TDEFL_OUT_BUF_SIZE]; +} tdefl_compressor; + +// Initializes the compressor. +// There is no corresponding deinit() function because the tdefl API's do not +// dynamically allocate memory. +// pBut_buf_func: If NULL, output data will be supplied to the specified +// callback. In this case, the user should call the tdefl_compress_buffer() API +// for compression. +// If pBut_buf_func is NULL the user should always call the tdefl_compress() +// API. +// flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER, +// etc.) +tdefl_status tdefl_init(tdefl_compressor *d, + tdefl_put_buf_func_ptr pPut_buf_func, + void *pPut_buf_user, int flags); + +// Compresses a block of data, consuming as much of the specified input buffer +// as possible, and writing as much compressed data to the specified output +// buffer as possible. +tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, + size_t *pIn_buf_size, void *pOut_buf, + size_t *pOut_buf_size, tdefl_flush flush); + +// tdefl_compress_buffer() is only usable when the tdefl_init() is called with a +// non-NULL tdefl_put_buf_func_ptr. +// tdefl_compress_buffer() always consumes the entire input buffer. +tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, + size_t in_buf_size, tdefl_flush flush); + +tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d); +mz_uint32 tdefl_get_adler32(tdefl_compressor *d); + +// Can't use tdefl_create_comp_flags_from_zip_params if MINIZ_NO_ZLIB_APIS isn't +// defined, because it uses some of its macros. +#ifndef MINIZ_NO_ZLIB_APIS +// Create tdefl_compress() flags given zlib-style compression parameters. +// level may range from [0,10] (where 10 is absolute max compression, but may be +// much slower on some files) +// window_bits may be -15 (raw deflate) or 15 (zlib) +// strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, +// MZ_RLE, or MZ_FIXED +mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, + int strategy); +#endif // #ifndef MINIZ_NO_ZLIB_APIS + +#ifdef __cplusplus +} +#endif + +#endif // MINIZ_HEADER_INCLUDED + +// ------------------- End of Header: Implementation follows. (If you only want +// the header, define MINIZ_HEADER_FILE_ONLY.) + +#ifndef MINIZ_HEADER_FILE_ONLY + +typedef unsigned char mz_validate_uint16[sizeof(mz_uint16) == 2 ? 1 : -1]; +typedef unsigned char mz_validate_uint32[sizeof(mz_uint32) == 4 ? 1 : -1]; +typedef unsigned char mz_validate_uint64[sizeof(mz_uint64) == 8 ? 1 : -1]; + +//#include +//#include + +#define MZ_ASSERT(x) assert(x) + +#ifdef MINIZ_NO_MALLOC +#define MZ_MALLOC(x) NULL +#define MZ_FREE(x) (void)x, ((void)0) +#define MZ_REALLOC(p, x) NULL +#else +#define MZ_MALLOC(x) malloc(x) +#define MZ_FREE(x) free(x) +#define MZ_REALLOC(p, x) realloc(p, x) +#endif + +#define MZ_MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define MZ_MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj)) + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN +#define MZ_READ_LE16(p) *((const mz_uint16 *)(p)) +#define MZ_READ_LE32(p) *((const mz_uint32 *)(p)) +#else +#define MZ_READ_LE16(p) \ + ((mz_uint32)(((const mz_uint8 *)(p))[0]) | \ + ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U)) +#define MZ_READ_LE32(p) \ + ((mz_uint32)(((const mz_uint8 *)(p))[0]) | \ + ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | \ + ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | \ + ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U)) +#endif + +#ifdef _MSC_VER +#define MZ_FORCEINLINE __forceinline +#elif defined(__GNUC__) +#define MZ_FORCEINLINE inline __attribute__((__always_inline__)) +#else +#define MZ_FORCEINLINE inline +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +// ------------------- zlib-style API's + +mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len) { + mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16); + size_t block_len = buf_len % 5552; + if (!ptr) return MZ_ADLER32_INIT; + while (buf_len) { + for (i = 0; i + 7 < block_len; i += 8, ptr += 8) { + s1 += ptr[0], s2 += s1; + s1 += ptr[1], s2 += s1; + s1 += ptr[2], s2 += s1; + s1 += ptr[3], s2 += s1; + s1 += ptr[4], s2 += s1; + s1 += ptr[5], s2 += s1; + s1 += ptr[6], s2 += s1; + s1 += ptr[7], s2 += s1; + } + for (; i < block_len; ++i) s1 += *ptr++, s2 += s1; + s1 %= 65521U, s2 %= 65521U; + buf_len -= block_len; + block_len = 5552; + } + return (s2 << 16) + s1; +} + +// Karl Malbrain's compact CRC-32. See "A compact CCITT crc16 and crc32 C +// implementation that balances processor cache usage against speed": +// http://www.geocities.com/malbrain/ +mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len) { + static const mz_uint32 s_crc32[16] = { + 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, + 0x4db26158, 0x5005713c, 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, + 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c}; + mz_uint32 crcu32 = (mz_uint32)crc; + if (!ptr) return MZ_CRC32_INIT; + crcu32 = ~crcu32; + while (buf_len--) { + mz_uint8 b = *ptr++; + crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)]; + crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)]; + } + return ~crcu32; +} + +void mz_free(void *p) { MZ_FREE(p); } + +#ifndef MINIZ_NO_ZLIB_APIS + +static void *def_alloc_func(void *opaque, size_t items, size_t size) { + (void)opaque, (void)items, (void)size; + return MZ_MALLOC(items * size); +} +static void def_free_func(void *opaque, void *address) { + (void)opaque, (void)address; + MZ_FREE(address); +} +// static void *def_realloc_func(void *opaque, void *address, size_t items, +// size_t size) { +// (void)opaque, (void)address, (void)items, (void)size; +// return MZ_REALLOC(address, items * size); +//} + +const char *mz_version(void) { return MZ_VERSION; } + +int mz_deflateInit(mz_streamp pStream, int level) { + return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9, + MZ_DEFAULT_STRATEGY); +} + +int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, + int mem_level, int strategy) { + tdefl_compressor *pComp; + mz_uint comp_flags = + TDEFL_COMPUTE_ADLER32 | + tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy); + + if (!pStream) return MZ_STREAM_ERROR; + if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) || + ((window_bits != MZ_DEFAULT_WINDOW_BITS) && + (-window_bits != MZ_DEFAULT_WINDOW_BITS))) + return MZ_PARAM_ERROR; + + pStream->data_type = 0; + pStream->adler = MZ_ADLER32_INIT; + pStream->msg = NULL; + pStream->reserved = 0; + pStream->total_in = 0; + pStream->total_out = 0; + if (!pStream->zalloc) pStream->zalloc = def_alloc_func; + if (!pStream->zfree) pStream->zfree = def_free_func; + + pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, + sizeof(tdefl_compressor)); + if (!pComp) return MZ_MEM_ERROR; + + pStream->state = (struct mz_internal_state *)pComp; + + if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY) { + mz_deflateEnd(pStream); + return MZ_PARAM_ERROR; + } + + return MZ_OK; +} + +int mz_deflateReset(mz_streamp pStream) { + if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || + (!pStream->zfree)) + return MZ_STREAM_ERROR; + pStream->total_in = pStream->total_out = 0; + tdefl_init((tdefl_compressor *)pStream->state, NULL, NULL, + ((tdefl_compressor *)pStream->state)->m_flags); + return MZ_OK; +} + +int mz_deflate(mz_streamp pStream, int flush) { + size_t in_bytes, out_bytes; + mz_ulong orig_total_in, orig_total_out; + int mz_status = MZ_OK; + + if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || + (!pStream->next_out)) + return MZ_STREAM_ERROR; + if (!pStream->avail_out) return MZ_BUF_ERROR; + + if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH; + + if (((tdefl_compressor *)pStream->state)->m_prev_return_status == + TDEFL_STATUS_DONE) + return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR; + + orig_total_in = pStream->total_in; + orig_total_out = pStream->total_out; + for (;;) { + tdefl_status defl_status; + in_bytes = pStream->avail_in; + out_bytes = pStream->avail_out; + + defl_status = tdefl_compress((tdefl_compressor *)pStream->state, + pStream->next_in, &in_bytes, pStream->next_out, + &out_bytes, (tdefl_flush)flush); + pStream->next_in += (mz_uint)in_bytes; + pStream->avail_in -= (mz_uint)in_bytes; + pStream->total_in += (mz_uint)in_bytes; + pStream->adler = tdefl_get_adler32((tdefl_compressor *)pStream->state); + + pStream->next_out += (mz_uint)out_bytes; + pStream->avail_out -= (mz_uint)out_bytes; + pStream->total_out += (mz_uint)out_bytes; + + if (defl_status < 0) { + mz_status = MZ_STREAM_ERROR; + break; + } else if (defl_status == TDEFL_STATUS_DONE) { + mz_status = MZ_STREAM_END; + break; + } else if (!pStream->avail_out) + break; + else if ((!pStream->avail_in) && (flush != MZ_FINISH)) { + if ((flush) || (pStream->total_in != orig_total_in) || + (pStream->total_out != orig_total_out)) + break; + return MZ_BUF_ERROR; // Can't make forward progress without some input. + } + } + return mz_status; +} + +int mz_deflateEnd(mz_streamp pStream) { + if (!pStream) return MZ_STREAM_ERROR; + if (pStream->state) { + pStream->zfree(pStream->opaque, pStream->state); + pStream->state = NULL; + } + return MZ_OK; +} + +mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len) { + (void)pStream; + // This is really over conservative. (And lame, but it's actually pretty + // tricky to compute a true upper bound given the way tdefl's blocking works.) + return MZ_MAX(128 + (source_len * 110) / 100, + 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5); +} + +int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, + const unsigned char *pSource, mz_ulong source_len, int level) { + int status; + mz_stream stream; + memset(&stream, 0, sizeof(stream)); + + // In case mz_ulong is 64-bits (argh I hate longs). + if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR; + + stream.next_in = pSource; + stream.avail_in = (mz_uint32)source_len; + stream.next_out = pDest; + stream.avail_out = (mz_uint32)*pDest_len; + + status = mz_deflateInit(&stream, level); + if (status != MZ_OK) return status; + + status = mz_deflate(&stream, MZ_FINISH); + if (status != MZ_STREAM_END) { + mz_deflateEnd(&stream); + return (status == MZ_OK) ? MZ_BUF_ERROR : status; + } + + *pDest_len = stream.total_out; + return mz_deflateEnd(&stream); +} + +int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, + const unsigned char *pSource, mz_ulong source_len) { + return mz_compress2(pDest, pDest_len, pSource, source_len, + MZ_DEFAULT_COMPRESSION); +} + +mz_ulong mz_compressBound(mz_ulong source_len) { + return mz_deflateBound(NULL, source_len); +} + +typedef struct { + tinfl_decompressor m_decomp; + mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed; + int m_window_bits; + mz_uint8 m_dict[TINFL_LZ_DICT_SIZE]; + tinfl_status m_last_status; +} inflate_state; + +int mz_inflateInit2(mz_streamp pStream, int window_bits) { + inflate_state *pDecomp; + if (!pStream) return MZ_STREAM_ERROR; + if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && + (-window_bits != MZ_DEFAULT_WINDOW_BITS)) + return MZ_PARAM_ERROR; + + pStream->data_type = 0; + pStream->adler = 0; + pStream->msg = NULL; + pStream->total_in = 0; + pStream->total_out = 0; + pStream->reserved = 0; + if (!pStream->zalloc) pStream->zalloc = def_alloc_func; + if (!pStream->zfree) pStream->zfree = def_free_func; + + pDecomp = (inflate_state *)pStream->zalloc(pStream->opaque, 1, + sizeof(inflate_state)); + if (!pDecomp) return MZ_MEM_ERROR; + + pStream->state = (struct mz_internal_state *)pDecomp; + + tinfl_init(&pDecomp->m_decomp); + pDecomp->m_dict_ofs = 0; + pDecomp->m_dict_avail = 0; + pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT; + pDecomp->m_first_call = 1; + pDecomp->m_has_flushed = 0; + pDecomp->m_window_bits = window_bits; + + return MZ_OK; +} + +int mz_inflateInit(mz_streamp pStream) { + return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS); +} + +int mz_inflate(mz_streamp pStream, int flush) { + inflate_state *pState; + mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32; + size_t in_bytes, out_bytes, orig_avail_in; + tinfl_status status; + + if ((!pStream) || (!pStream->state)) return MZ_STREAM_ERROR; + if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH; + if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH)) + return MZ_STREAM_ERROR; + + pState = (inflate_state *)pStream->state; + if (pState->m_window_bits > 0) decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER; + orig_avail_in = pStream->avail_in; + + first_call = pState->m_first_call; + pState->m_first_call = 0; + if (pState->m_last_status < 0) return MZ_DATA_ERROR; + + if (pState->m_has_flushed && (flush != MZ_FINISH)) return MZ_STREAM_ERROR; + pState->m_has_flushed |= (flush == MZ_FINISH); + + if ((flush == MZ_FINISH) && (first_call)) { + // MZ_FINISH on the first call implies that the input and output buffers are + // large enough to hold the entire compressed/decompressed file. + decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF; + in_bytes = pStream->avail_in; + out_bytes = pStream->avail_out; + status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, + pStream->next_out, pStream->next_out, &out_bytes, + decomp_flags); + pState->m_last_status = status; + pStream->next_in += (mz_uint)in_bytes; + pStream->avail_in -= (mz_uint)in_bytes; + pStream->total_in += (mz_uint)in_bytes; + pStream->adler = tinfl_get_adler32(&pState->m_decomp); + pStream->next_out += (mz_uint)out_bytes; + pStream->avail_out -= (mz_uint)out_bytes; + pStream->total_out += (mz_uint)out_bytes; + + if (status < 0) + return MZ_DATA_ERROR; + else if (status != TINFL_STATUS_DONE) { + pState->m_last_status = TINFL_STATUS_FAILED; + return MZ_BUF_ERROR; + } + return MZ_STREAM_END; + } + // flush != MZ_FINISH then we must assume there's more input. + if (flush != MZ_FINISH) decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT; + + if (pState->m_dict_avail) { + n = MZ_MIN(pState->m_dict_avail, pStream->avail_out); + memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n); + pStream->next_out += n; + pStream->avail_out -= n; + pStream->total_out += n; + pState->m_dict_avail -= n; + pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1); + return ((pState->m_last_status == TINFL_STATUS_DONE) && + (!pState->m_dict_avail)) + ? MZ_STREAM_END + : MZ_OK; + } + + for (;;) { + in_bytes = pStream->avail_in; + out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs; + + status = tinfl_decompress( + &pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict, + pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags); + pState->m_last_status = status; + + pStream->next_in += (mz_uint)in_bytes; + pStream->avail_in -= (mz_uint)in_bytes; + pStream->total_in += (mz_uint)in_bytes; + pStream->adler = tinfl_get_adler32(&pState->m_decomp); + + pState->m_dict_avail = (mz_uint)out_bytes; + + n = MZ_MIN(pState->m_dict_avail, pStream->avail_out); + memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n); + pStream->next_out += n; + pStream->avail_out -= n; + pStream->total_out += n; + pState->m_dict_avail -= n; + pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1); + + if (status < 0) + return MZ_DATA_ERROR; // Stream is corrupted (there could be some + // uncompressed data left in the output dictionary - + // oh well). + else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in)) + return MZ_BUF_ERROR; // Signal caller that we can't make forward progress + // without supplying more input or by setting flush + // to MZ_FINISH. + else if (flush == MZ_FINISH) { + // The output buffer MUST be large to hold the remaining uncompressed data + // when flush==MZ_FINISH. + if (status == TINFL_STATUS_DONE) + return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END; + // status here must be TINFL_STATUS_HAS_MORE_OUTPUT, which means there's + // at least 1 more byte on the way. If there's no more room left in the + // output buffer then something is wrong. + else if (!pStream->avail_out) + return MZ_BUF_ERROR; + } else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || + (!pStream->avail_out) || (pState->m_dict_avail)) + break; + } + + return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) + ? MZ_STREAM_END + : MZ_OK; +} + +int mz_inflateEnd(mz_streamp pStream) { + if (!pStream) return MZ_STREAM_ERROR; + if (pStream->state) { + pStream->zfree(pStream->opaque, pStream->state); + pStream->state = NULL; + } + return MZ_OK; +} + +int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, + const unsigned char *pSource, mz_ulong source_len) { + mz_stream stream; + int status; + memset(&stream, 0, sizeof(stream)); + + // In case mz_ulong is 64-bits (argh I hate longs). + if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR; + + stream.next_in = pSource; + stream.avail_in = (mz_uint32)source_len; + stream.next_out = pDest; + stream.avail_out = (mz_uint32)*pDest_len; + + status = mz_inflateInit(&stream); + if (status != MZ_OK) return status; + + status = mz_inflate(&stream, MZ_FINISH); + if (status != MZ_STREAM_END) { + mz_inflateEnd(&stream); + return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR + : status; + } + *pDest_len = stream.total_out; + + return mz_inflateEnd(&stream); +} + +const char *mz_error(int err) { + static struct { + int m_err; + const char *m_pDesc; + } s_error_descs[] = {{MZ_OK, ""}, + {MZ_STREAM_END, "stream end"}, + {MZ_NEED_DICT, "need dictionary"}, + {MZ_ERRNO, "file error"}, + {MZ_STREAM_ERROR, "stream error"}, + {MZ_DATA_ERROR, "data error"}, + {MZ_MEM_ERROR, "out of memory"}, + {MZ_BUF_ERROR, "buf error"}, + {MZ_VERSION_ERROR, "version error"}, + {MZ_PARAM_ERROR, "parameter error"}}; + mz_uint i; + for (i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i) + if (s_error_descs[i].m_err == err) return s_error_descs[i].m_pDesc; + return NULL; +} + +#endif // MINIZ_NO_ZLIB_APIS + +// ------------------- Low-level Decompression (completely independent from all +// compression API's) + +#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l) +#define TINFL_MEMSET(p, c, l) memset(p, c, l) + +#define TINFL_CR_BEGIN \ + switch (r->m_state) { \ + case 0: +#define TINFL_CR_RETURN(state_index, result) \ + do { \ + status = result; \ + r->m_state = state_index; \ + goto common_exit; \ + case state_index:; \ + } \ + MZ_MACRO_END +#define TINFL_CR_RETURN_FOREVER(state_index, result) \ + do { \ + for (;;) { \ + TINFL_CR_RETURN(state_index, result); \ + } \ + } \ + MZ_MACRO_END +#define TINFL_CR_FINISH } + +// TODO: If the caller has indicated that there's no more input, and we attempt +// to read beyond the input buf, then something is wrong with the input because +// the inflator never +// reads ahead more than it needs to. Currently TINFL_GET_BYTE() pads the end of +// the stream with 0's in this scenario. +#define TINFL_GET_BYTE(state_index, c) \ + do { \ + if (pIn_buf_cur >= pIn_buf_end) { \ + for (;;) { \ + if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \ + TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \ + if (pIn_buf_cur < pIn_buf_end) { \ + c = *pIn_buf_cur++; \ + break; \ + } \ + } else { \ + c = 0; \ + break; \ + } \ + } \ + } else \ + c = *pIn_buf_cur++; \ + } \ + MZ_MACRO_END + +#define TINFL_NEED_BITS(state_index, n) \ + do { \ + mz_uint c; \ + TINFL_GET_BYTE(state_index, c); \ + bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \ + num_bits += 8; \ + } while (num_bits < (mz_uint)(n)) +#define TINFL_SKIP_BITS(state_index, n) \ + do { \ + if (num_bits < (mz_uint)(n)) { \ + TINFL_NEED_BITS(state_index, n); \ + } \ + bit_buf >>= (n); \ + num_bits -= (n); \ + } \ + MZ_MACRO_END +#define TINFL_GET_BITS(state_index, b, n) \ + do { \ + if (num_bits < (mz_uint)(n)) { \ + TINFL_NEED_BITS(state_index, n); \ + } \ + b = bit_buf & ((1 << (n)) - 1); \ + bit_buf >>= (n); \ + num_bits -= (n); \ + } \ + MZ_MACRO_END + +// TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes +// remaining in the input buffer falls below 2. +// It reads just enough bytes from the input stream that are needed to decode +// the next Huffman code (and absolutely no more). It works by trying to fully +// decode a +// Huffman code by using whatever bits are currently present in the bit buffer. +// If this fails, it reads another byte, and tries again until it succeeds or +// until the +// bit buffer contains >=15 bits (deflate's max. Huffman code size). +#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \ + do { \ + temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \ + if (temp >= 0) { \ + code_len = temp >> 9; \ + if ((code_len) && (num_bits >= code_len)) break; \ + } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \ + code_len = TINFL_FAST_LOOKUP_BITS; \ + do { \ + temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \ + } while ((temp < 0) && (num_bits >= (code_len + 1))); \ + if (temp >= 0) break; \ + } \ + TINFL_GET_BYTE(state_index, c); \ + bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \ + num_bits += 8; \ + } while (num_bits < 15); + +// TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex +// than you would initially expect because the zlib API expects the decompressor +// to never read +// beyond the final byte of the deflate stream. (In other words, when this macro +// wants to read another byte from the input, it REALLY needs another byte in +// order to fully +// decode the next Huffman code.) Handling this properly is particularly +// important on raw deflate (non-zlib) streams, which aren't followed by a byte +// aligned adler-32. +// The slow path is only executed at the very end of the input buffer. +#define TINFL_HUFF_DECODE(state_index, sym, pHuff) \ + do { \ + int temp; \ + mz_uint code_len, c; \ + if (num_bits < 15) { \ + if ((pIn_buf_end - pIn_buf_cur) < 2) { \ + TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \ + } else { \ + bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | \ + (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); \ + pIn_buf_cur += 2; \ + num_bits += 16; \ + } \ + } \ + if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= \ + 0) \ + code_len = temp >> 9, temp &= 511; \ + else { \ + code_len = TINFL_FAST_LOOKUP_BITS; \ + do { \ + temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \ + } while (temp < 0); \ + } \ + sym = temp; \ + bit_buf >>= code_len; \ + num_bits -= code_len; \ + } \ + MZ_MACRO_END + +tinfl_status tinfl_decompress(tinfl_decompressor *r, + const mz_uint8 *pIn_buf_next, + size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, + mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, + const mz_uint32 decomp_flags) { + static const int s_length_base[31] = { + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const int s_length_extra[31] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, + 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, + 4, 4, 5, 5, 5, 5, 0, 0, 0}; + static const int s_dist_base[32] = { + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, + 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, + 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0}; + static const int s_dist_extra[32] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, + 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; + static const mz_uint8 s_length_dezigzag[19] = { + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + static const int s_min_table_sizes[3] = {257, 1, 4}; + + tinfl_status status = TINFL_STATUS_FAILED; + mz_uint32 num_bits, dist, counter, num_extra; + tinfl_bit_buf_t bit_buf; + const mz_uint8 *pIn_buf_cur = pIn_buf_next, + *const pIn_buf_end = pIn_buf_next + *pIn_buf_size; + mz_uint8 *pOut_buf_cur = pOut_buf_next, + *const pOut_buf_end = pOut_buf_next + *pOut_buf_size; + size_t out_buf_size_mask = + (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) + ? (size_t)-1 + : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, + dist_from_out_buf_start; + + // Ensure the output buffer's size is a power of 2, unless the output buffer + // is large enough to hold the entire output file (in which case it doesn't + // matter). + if (((out_buf_size_mask + 1) & out_buf_size_mask) || + (pOut_buf_next < pOut_buf_start)) { + *pIn_buf_size = *pOut_buf_size = 0; + return TINFL_STATUS_BAD_PARAM; + } + + num_bits = r->m_num_bits; + bit_buf = r->m_bit_buf; + dist = r->m_dist; + counter = r->m_counter; + num_extra = r->m_num_extra; + dist_from_out_buf_start = r->m_dist_from_out_buf_start; + TINFL_CR_BEGIN + + bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0; + r->m_z_adler32 = r->m_check_adler32 = 1; + if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) { + TINFL_GET_BYTE(1, r->m_zhdr0); + TINFL_GET_BYTE(2, r->m_zhdr1); + counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || + (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8)); + if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) + counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || + ((out_buf_size_mask + 1) < + (size_t)(1ULL << (8U + (r->m_zhdr0 >> 4))))); + if (counter) { + TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); + } + } + + do { + TINFL_GET_BITS(3, r->m_final, 3); + r->m_type = r->m_final >> 1; + if (r->m_type == 0) { + TINFL_SKIP_BITS(5, num_bits & 7); + for (counter = 0; counter < 4; ++counter) { + if (num_bits) + TINFL_GET_BITS(6, r->m_raw_header[counter], 8); + else + TINFL_GET_BYTE(7, r->m_raw_header[counter]); + } + if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) != + (mz_uint)(0xFFFF ^ + (r->m_raw_header[2] | (r->m_raw_header[3] << 8)))) { + TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED); + } + while ((counter) && (num_bits)) { + TINFL_GET_BITS(51, dist, 8); + while (pOut_buf_cur >= pOut_buf_end) { + TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT); + } + *pOut_buf_cur++ = (mz_uint8)dist; + counter--; + } + while (counter) { + size_t n; + while (pOut_buf_cur >= pOut_buf_end) { + TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); + } + while (pIn_buf_cur >= pIn_buf_end) { + if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { + TINFL_CR_RETURN(38, TINFL_STATUS_NEEDS_MORE_INPUT); + } else { + TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED); + } + } + n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), + (size_t)(pIn_buf_end - pIn_buf_cur)), + counter); + TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); + pIn_buf_cur += n; + pOut_buf_cur += n; + counter -= (mz_uint)n; + } + } else if (r->m_type == 3) { + TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED); + } else { + if (r->m_type == 1) { + mz_uint8 *p = r->m_tables[0].m_code_size; + mz_uint i; + r->m_table_sizes[0] = 288; + r->m_table_sizes[1] = 32; + TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32); + for (i = 0; i <= 143; ++i) *p++ = 8; + for (; i <= 255; ++i) *p++ = 9; + for (; i <= 279; ++i) *p++ = 7; + for (; i <= 287; ++i) *p++ = 8; + } else { + for (counter = 0; counter < 3; counter++) { + TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); + r->m_table_sizes[counter] += s_min_table_sizes[counter]; + } + MZ_CLEAR_OBJ(r->m_tables[2].m_code_size); + for (counter = 0; counter < r->m_table_sizes[2]; counter++) { + mz_uint s; + TINFL_GET_BITS(14, s, 3); + r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; + } + r->m_table_sizes[2] = 19; + } + for (; (int)r->m_type >= 0; r->m_type--) { + int tree_next, tree_cur; + tinfl_huff_table *pTable; + mz_uint i, j, used_syms, total, sym_index, next_code[17], + total_syms[16]; + pTable = &r->m_tables[r->m_type]; + MZ_CLEAR_OBJ(total_syms); + MZ_CLEAR_OBJ(pTable->m_look_up); + MZ_CLEAR_OBJ(pTable->m_tree); + for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) + total_syms[pTable->m_code_size[i]]++; + used_syms = 0, total = 0; + next_code[0] = next_code[1] = 0; + for (i = 1; i <= 15; ++i) { + used_syms += total_syms[i]; + next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); + } + if ((65536 != total) && (used_syms > 1)) { + TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED); + } + for (tree_next = -1, sym_index = 0; + sym_index < r->m_table_sizes[r->m_type]; ++sym_index) { + mz_uint rev_code = 0, l, cur_code, + code_size = pTable->m_code_size[sym_index]; + if (!code_size) continue; + cur_code = next_code[code_size]++; + for (l = code_size; l > 0; l--, cur_code >>= 1) + rev_code = (rev_code << 1) | (cur_code & 1); + if (code_size <= TINFL_FAST_LOOKUP_BITS) { + mz_int16 k = (mz_int16)((code_size << 9) | sym_index); + while (rev_code < TINFL_FAST_LOOKUP_SIZE) { + pTable->m_look_up[rev_code] = k; + rev_code += (1 << code_size); + } + continue; + } + if (0 == + (tree_cur = pTable->m_look_up[rev_code & + (TINFL_FAST_LOOKUP_SIZE - 1)])) { + pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = + (mz_int16)tree_next; + tree_cur = tree_next; + tree_next -= 2; + } + rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1); + for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--) { + tree_cur -= ((rev_code >>= 1) & 1); + if (!pTable->m_tree[-tree_cur - 1]) { + pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next; + tree_cur = tree_next; + tree_next -= 2; + } else + tree_cur = pTable->m_tree[-tree_cur - 1]; + } + tree_cur -= ((rev_code >>= 1) & 1); + pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index; + } + if (r->m_type == 2) { + for (counter = 0; + counter < (r->m_table_sizes[0] + r->m_table_sizes[1]);) { + mz_uint s; + TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]); + if (dist < 16) { + r->m_len_codes[counter++] = (mz_uint8)dist; + continue; + } + if ((dist == 16) && (!counter)) { + TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED); + } + num_extra = "\02\03\07"[dist - 16]; + TINFL_GET_BITS(18, s, num_extra); + s += "\03\03\013"[dist - 16]; + TINFL_MEMSET(r->m_len_codes + counter, + (dist == 16) ? r->m_len_codes[counter - 1] : 0, s); + counter += s; + } + if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter) { + TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED); + } + TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, + r->m_table_sizes[0]); + TINFL_MEMCPY(r->m_tables[1].m_code_size, + r->m_len_codes + r->m_table_sizes[0], + r->m_table_sizes[1]); + } + } + for (;;) { + mz_uint8 *pSrc; + for (;;) { + if (((pIn_buf_end - pIn_buf_cur) < 4) || + ((pOut_buf_end - pOut_buf_cur) < 2)) { + TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]); + if (counter >= 256) break; + while (pOut_buf_cur >= pOut_buf_end) { + TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT); + } + *pOut_buf_cur++ = (mz_uint8)counter; + } else { + int sym2; + mz_uint code_len; +#if TINFL_USE_64BIT_BITBUF + if (num_bits < 30) { + bit_buf |= + (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits); + pIn_buf_cur += 4; + num_bits += 32; + } +#else + if (num_bits < 15) { + bit_buf |= + (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); + pIn_buf_cur += 2; + num_bits += 16; + } +#endif + if ((sym2 = + r->m_tables[0] + .m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= + 0) + code_len = sym2 >> 9; + else { + code_len = TINFL_FAST_LOOKUP_BITS; + do { + sym2 = r->m_tables[0] + .m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; + } while (sym2 < 0); + } + counter = sym2; + bit_buf >>= code_len; + num_bits -= code_len; + if (counter & 256) break; + +#if !TINFL_USE_64BIT_BITBUF + if (num_bits < 15) { + bit_buf |= + (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); + pIn_buf_cur += 2; + num_bits += 16; + } +#endif + if ((sym2 = + r->m_tables[0] + .m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= + 0) + code_len = sym2 >> 9; + else { + code_len = TINFL_FAST_LOOKUP_BITS; + do { + sym2 = r->m_tables[0] + .m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; + } while (sym2 < 0); + } + bit_buf >>= code_len; + num_bits -= code_len; + + pOut_buf_cur[0] = (mz_uint8)counter; + if (sym2 & 256) { + pOut_buf_cur++; + counter = sym2; + break; + } + pOut_buf_cur[1] = (mz_uint8)sym2; + pOut_buf_cur += 2; + } + } + if ((counter &= 511) == 256) break; + + num_extra = s_length_extra[counter - 257]; + counter = s_length_base[counter - 257]; + if (num_extra) { + mz_uint extra_bits; + TINFL_GET_BITS(25, extra_bits, num_extra); + counter += extra_bits; + } + + TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]); + num_extra = s_dist_extra[dist]; + dist = s_dist_base[dist]; + if (num_extra) { + mz_uint extra_bits; + TINFL_GET_BITS(27, extra_bits, num_extra); + dist += extra_bits; + } + + dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start; + if ((dist > dist_from_out_buf_start) && + (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) { + TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED); + } + + pSrc = pOut_buf_start + + ((dist_from_out_buf_start - dist) & out_buf_size_mask); + + if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end) { + while (counter--) { + while (pOut_buf_cur >= pOut_buf_end) { + TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT); + } + *pOut_buf_cur++ = + pOut_buf_start[(dist_from_out_buf_start++ - dist) & + out_buf_size_mask]; + } + continue; + } +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES + else if ((counter >= 9) && (counter <= dist)) { + const mz_uint8 *pSrc_end = pSrc + (counter & ~7); + do { + ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0]; + ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1]; + pOut_buf_cur += 8; + } while ((pSrc += 8) < pSrc_end); + if ((counter &= 7) < 3) { + if (counter) { + pOut_buf_cur[0] = pSrc[0]; + if (counter > 1) pOut_buf_cur[1] = pSrc[1]; + pOut_buf_cur += counter; + } + continue; + } + } +#endif + do { + pOut_buf_cur[0] = pSrc[0]; + pOut_buf_cur[1] = pSrc[1]; + pOut_buf_cur[2] = pSrc[2]; + pOut_buf_cur += 3; + pSrc += 3; + } while ((int)(counter -= 3) > 2); + if ((int)counter > 0) { + pOut_buf_cur[0] = pSrc[0]; + if ((int)counter > 1) pOut_buf_cur[1] = pSrc[1]; + pOut_buf_cur += counter; + } + } + } + } while (!(r->m_final & 1)); + if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) { + TINFL_SKIP_BITS(32, num_bits & 7); + for (counter = 0; counter < 4; ++counter) { + mz_uint s; + if (num_bits) + TINFL_GET_BITS(41, s, 8); + else + TINFL_GET_BYTE(42, s); + r->m_z_adler32 = (r->m_z_adler32 << 8) | s; + } + } + TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE); + TINFL_CR_FINISH + +common_exit: + r->m_num_bits = num_bits; + r->m_bit_buf = bit_buf; + r->m_dist = dist; + r->m_counter = counter; + r->m_num_extra = num_extra; + r->m_dist_from_out_buf_start = dist_from_out_buf_start; + *pIn_buf_size = pIn_buf_cur - pIn_buf_next; + *pOut_buf_size = pOut_buf_cur - pOut_buf_next; + if ((decomp_flags & + (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && + (status >= 0)) { + const mz_uint8 *ptr = pOut_buf_next; + size_t buf_len = *pOut_buf_size; + mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, + s2 = r->m_check_adler32 >> 16; + size_t block_len = buf_len % 5552; + while (buf_len) { + for (i = 0; i + 7 < block_len; i += 8, ptr += 8) { + s1 += ptr[0], s2 += s1; + s1 += ptr[1], s2 += s1; + s1 += ptr[2], s2 += s1; + s1 += ptr[3], s2 += s1; + s1 += ptr[4], s2 += s1; + s1 += ptr[5], s2 += s1; + s1 += ptr[6], s2 += s1; + s1 += ptr[7], s2 += s1; + } + for (; i < block_len; ++i) s1 += *ptr++, s2 += s1; + s1 %= 65521U, s2 %= 65521U; + buf_len -= block_len; + block_len = 5552; + } + r->m_check_adler32 = (s2 << 16) + s1; + if ((status == TINFL_STATUS_DONE) && + (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && + (r->m_check_adler32 != r->m_z_adler32)) + status = TINFL_STATUS_ADLER32_MISMATCH; + } + return status; +} + +// Higher level helper functions. +void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, + size_t *pOut_len, int flags) { + tinfl_decompressor decomp; + void *pBuf = NULL, *pNew_buf; + size_t src_buf_ofs = 0, out_buf_capacity = 0; + *pOut_len = 0; + tinfl_init(&decomp); + for (;;) { + size_t src_buf_size = src_buf_len - src_buf_ofs, + dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity; + tinfl_status status = tinfl_decompress( + &decomp, (const mz_uint8 *)pSrc_buf + src_buf_ofs, &src_buf_size, + (mz_uint8 *)pBuf, pBuf ? (mz_uint8 *)pBuf + *pOut_len : NULL, + &dst_buf_size, + (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | + TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); + if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT)) { + MZ_FREE(pBuf); + *pOut_len = 0; + return NULL; + } + src_buf_ofs += src_buf_size; + *pOut_len += dst_buf_size; + if (status == TINFL_STATUS_DONE) break; + new_out_buf_capacity = out_buf_capacity * 2; + if (new_out_buf_capacity < 128) new_out_buf_capacity = 128; + pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity); + if (!pNew_buf) { + MZ_FREE(pBuf); + *pOut_len = 0; + return NULL; + } + pBuf = pNew_buf; + out_buf_capacity = new_out_buf_capacity; + } + return pBuf; +} + +size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, + const void *pSrc_buf, size_t src_buf_len, + int flags) { + tinfl_decompressor decomp; + tinfl_status status; + tinfl_init(&decomp); + status = + tinfl_decompress(&decomp, (const mz_uint8 *)pSrc_buf, &src_buf_len, + (mz_uint8 *)pOut_buf, (mz_uint8 *)pOut_buf, &out_buf_len, + (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | + TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); + return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED + : out_buf_len; +} + +int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, + tinfl_put_buf_func_ptr pPut_buf_func, + void *pPut_buf_user, int flags) { + int result = 0; + tinfl_decompressor decomp; + mz_uint8 *pDict = (mz_uint8 *)MZ_MALLOC(TINFL_LZ_DICT_SIZE); + size_t in_buf_ofs = 0, dict_ofs = 0; + if (!pDict) return TINFL_STATUS_FAILED; + tinfl_init(&decomp); + for (;;) { + size_t in_buf_size = *pIn_buf_size - in_buf_ofs, + dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs; + tinfl_status status = + tinfl_decompress(&decomp, (const mz_uint8 *)pIn_buf + in_buf_ofs, + &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size, + (flags & + ~(TINFL_FLAG_HAS_MORE_INPUT | + TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))); + in_buf_ofs += in_buf_size; + if ((dst_buf_size) && + (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user))) + break; + if (status != TINFL_STATUS_HAS_MORE_OUTPUT) { + result = (status == TINFL_STATUS_DONE); + break; + } + dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1); + } + MZ_FREE(pDict); + *pIn_buf_size = in_buf_ofs; + return result; +} + +// ------------------- Low-level Compression (independent from all decompression +// API's) + +// Purposely making these tables static for faster init and thread safety. +static const mz_uint16 s_tdefl_len_sym[256] = { + 257, 258, 259, 260, 261, 262, 263, 264, 265, 265, 266, 266, 267, 267, 268, + 268, 269, 269, 269, 269, 270, 270, 270, 270, 271, 271, 271, 271, 272, 272, + 272, 272, 273, 273, 273, 273, 273, 273, 273, 273, 274, 274, 274, 274, 274, + 274, 274, 274, 275, 275, 275, 275, 275, 275, 275, 275, 276, 276, 276, 276, + 276, 276, 276, 276, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 282, 282, 282, 282, 282, + 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, + 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 283, 283, 283, + 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, + 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 284, + 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + 285}; + +static const mz_uint8 s_tdefl_len_extra[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 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, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0}; + +static const mz_uint8 s_tdefl_small_dist_sym[512] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, + 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17}; + +static const mz_uint8 s_tdefl_small_dist_extra[512] = { + 0, 0, 0, 0, 1, 1, 1, 1, 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, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7}; + +static const mz_uint8 s_tdefl_large_dist_sym[128] = { + 0, 0, 18, 19, 20, 20, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, + 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29}; + +static const mz_uint8 s_tdefl_large_dist_extra[128] = { + 0, 0, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13}; + +// Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted +// values. +typedef struct { mz_uint16 m_key, m_sym_index; } tdefl_sym_freq; +static tdefl_sym_freq *tdefl_radix_sort_syms(mz_uint num_syms, + tdefl_sym_freq *pSyms0, + tdefl_sym_freq *pSyms1) { + mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2]; + tdefl_sym_freq *pCur_syms = pSyms0, *pNew_syms = pSyms1; + MZ_CLEAR_OBJ(hist); + for (i = 0; i < num_syms; i++) { + mz_uint freq = pSyms0[i].m_key; + hist[freq & 0xFF]++; + hist[256 + ((freq >> 8) & 0xFF)]++; + } + while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256])) + total_passes--; + for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8) { + const mz_uint32 *pHist = &hist[pass << 8]; + mz_uint offsets[256], cur_ofs = 0; + for (i = 0; i < 256; i++) { + offsets[i] = cur_ofs; + cur_ofs += pHist[i]; + } + for (i = 0; i < num_syms; i++) + pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] = + pCur_syms[i]; + { + tdefl_sym_freq *t = pCur_syms; + pCur_syms = pNew_syms; + pNew_syms = t; + } + } + return pCur_syms; +} + +// tdefl_calculate_minimum_redundancy() originally written by: Alistair Moffat, +// alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996. +static void tdefl_calculate_minimum_redundancy(tdefl_sym_freq *A, int n) { + int root, leaf, next, avbl, used, dpth; + if (n == 0) + return; + else if (n == 1) { + A[0].m_key = 1; + return; + } + A[0].m_key += A[1].m_key; + root = 0; + leaf = 2; + for (next = 1; next < n - 1; next++) { + if (leaf >= n || A[root].m_key < A[leaf].m_key) { + A[next].m_key = A[root].m_key; + A[root++].m_key = (mz_uint16)next; + } else + A[next].m_key = A[leaf++].m_key; + if (leaf >= n || (root < next && A[root].m_key < A[leaf].m_key)) { + A[next].m_key = (mz_uint16)(A[next].m_key + A[root].m_key); + A[root++].m_key = (mz_uint16)next; + } else + A[next].m_key = (mz_uint16)(A[next].m_key + A[leaf++].m_key); + } + A[n - 2].m_key = 0; + for (next = n - 3; next >= 0; next--) + A[next].m_key = A[A[next].m_key].m_key + 1; + avbl = 1; + used = dpth = 0; + root = n - 2; + next = n - 1; + while (avbl > 0) { + while (root >= 0 && (int)A[root].m_key == dpth) { + used++; + root--; + } + while (avbl > used) { + A[next--].m_key = (mz_uint16)(dpth); + avbl--; + } + avbl = 2 * used; + dpth++; + used = 0; + } +} + +// Limits canonical Huffman code table's max code size. +enum { TDEFL_MAX_SUPPORTED_HUFF_CODESIZE = 32 }; +static void tdefl_huffman_enforce_max_code_size(int *pNum_codes, + int code_list_len, + int max_code_size) { + int i; + mz_uint32 total = 0; + if (code_list_len <= 1) return; + for (i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++) + pNum_codes[max_code_size] += pNum_codes[i]; + for (i = max_code_size; i > 0; i--) + total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i)); + while (total != (1UL << max_code_size)) { + pNum_codes[max_code_size]--; + for (i = max_code_size - 1; i > 0; i--) + if (pNum_codes[i]) { + pNum_codes[i]--; + pNum_codes[i + 1] += 2; + break; + } + total--; + } +} + +static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, + int table_len, int code_size_limit, + int static_table) { + int i, j, l, num_codes[1 + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE]; + mz_uint next_code[TDEFL_MAX_SUPPORTED_HUFF_CODESIZE + 1]; + MZ_CLEAR_OBJ(num_codes); + if (static_table) { + for (i = 0; i < table_len; i++) + num_codes[d->m_huff_code_sizes[table_num][i]]++; + } else { + tdefl_sym_freq syms0[TDEFL_MAX_HUFF_SYMBOLS], syms1[TDEFL_MAX_HUFF_SYMBOLS], + *pSyms; + int num_used_syms = 0; + const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0]; + for (i = 0; i < table_len; i++) + if (pSym_count[i]) { + syms0[num_used_syms].m_key = (mz_uint16)pSym_count[i]; + syms0[num_used_syms++].m_sym_index = (mz_uint16)i; + } + + pSyms = tdefl_radix_sort_syms(num_used_syms, syms0, syms1); + tdefl_calculate_minimum_redundancy(pSyms, num_used_syms); + + for (i = 0; i < num_used_syms; i++) num_codes[pSyms[i].m_key]++; + + tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms, + code_size_limit); + + MZ_CLEAR_OBJ(d->m_huff_code_sizes[table_num]); + MZ_CLEAR_OBJ(d->m_huff_codes[table_num]); + for (i = 1, j = num_used_syms; i <= code_size_limit; i++) + for (l = num_codes[i]; l > 0; l--) + d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i); + } + + next_code[1] = 0; + for (j = 0, i = 2; i <= code_size_limit; i++) + next_code[i] = j = ((j + num_codes[i - 1]) << 1); + + for (i = 0; i < table_len; i++) { + mz_uint rev_code = 0, code, code_size; + if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0) continue; + code = next_code[code_size]++; + for (l = code_size; l > 0; l--, code >>= 1) + rev_code = (rev_code << 1) | (code & 1); + d->m_huff_codes[table_num][i] = (mz_uint16)rev_code; + } +} + +#define TDEFL_PUT_BITS(b, l) \ + do { \ + mz_uint bits = b; \ + mz_uint len = l; \ + MZ_ASSERT(bits <= ((1U << len) - 1U)); \ + d->m_bit_buffer |= (bits << d->m_bits_in); \ + d->m_bits_in += len; \ + while (d->m_bits_in >= 8) { \ + if (d->m_pOutput_buf < d->m_pOutput_buf_end) \ + *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \ + d->m_bit_buffer >>= 8; \ + d->m_bits_in -= 8; \ + } \ + } \ + MZ_MACRO_END + +#define TDEFL_RLE_PREV_CODE_SIZE() \ + { \ + if (rle_repeat_count) { \ + if (rle_repeat_count < 3) { \ + d->m_huff_count[2][prev_code_size] = (mz_uint16)( \ + d->m_huff_count[2][prev_code_size] + rle_repeat_count); \ + while (rle_repeat_count--) \ + packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \ + } else { \ + d->m_huff_count[2][16] = (mz_uint16)(d->m_huff_count[2][16] + 1); \ + packed_code_sizes[num_packed_code_sizes++] = 16; \ + packed_code_sizes[num_packed_code_sizes++] = \ + (mz_uint8)(rle_repeat_count - 3); \ + } \ + rle_repeat_count = 0; \ + } \ + } + +#define TDEFL_RLE_ZERO_CODE_SIZE() \ + { \ + if (rle_z_count) { \ + if (rle_z_count < 3) { \ + d->m_huff_count[2][0] = \ + (mz_uint16)(d->m_huff_count[2][0] + rle_z_count); \ + while (rle_z_count--) packed_code_sizes[num_packed_code_sizes++] = 0; \ + } else if (rle_z_count <= 10) { \ + d->m_huff_count[2][17] = (mz_uint16)(d->m_huff_count[2][17] + 1); \ + packed_code_sizes[num_packed_code_sizes++] = 17; \ + packed_code_sizes[num_packed_code_sizes++] = \ + (mz_uint8)(rle_z_count - 3); \ + } else { \ + d->m_huff_count[2][18] = (mz_uint16)(d->m_huff_count[2][18] + 1); \ + packed_code_sizes[num_packed_code_sizes++] = 18; \ + packed_code_sizes[num_packed_code_sizes++] = \ + (mz_uint8)(rle_z_count - 11); \ + } \ + rle_z_count = 0; \ + } \ + } + +static mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = { + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +static void tdefl_start_dynamic_block(tdefl_compressor *d) { + int num_lit_codes, num_dist_codes, num_bit_lengths; + mz_uint i, total_code_sizes_to_pack, num_packed_code_sizes, rle_z_count, + rle_repeat_count, packed_code_sizes_index; + mz_uint8 + code_sizes_to_pack[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], + packed_code_sizes[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], + prev_code_size = 0xFF; + + d->m_huff_count[0][256] = 1; + + tdefl_optimize_huffman_table(d, 0, TDEFL_MAX_HUFF_SYMBOLS_0, 15, MZ_FALSE); + tdefl_optimize_huffman_table(d, 1, TDEFL_MAX_HUFF_SYMBOLS_1, 15, MZ_FALSE); + + for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--) + if (d->m_huff_code_sizes[0][num_lit_codes - 1]) break; + for (num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--) + if (d->m_huff_code_sizes[1][num_dist_codes - 1]) break; + + memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes); + memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0], + num_dist_codes); + total_code_sizes_to_pack = num_lit_codes + num_dist_codes; + num_packed_code_sizes = 0; + rle_z_count = 0; + rle_repeat_count = 0; + + memset(&d->m_huff_count[2][0], 0, + sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2); + for (i = 0; i < total_code_sizes_to_pack; i++) { + mz_uint8 code_size = code_sizes_to_pack[i]; + if (!code_size) { + TDEFL_RLE_PREV_CODE_SIZE(); + if (++rle_z_count == 138) { + TDEFL_RLE_ZERO_CODE_SIZE(); + } + } else { + TDEFL_RLE_ZERO_CODE_SIZE(); + if (code_size != prev_code_size) { + TDEFL_RLE_PREV_CODE_SIZE(); + d->m_huff_count[2][code_size] = + (mz_uint16)(d->m_huff_count[2][code_size] + 1); + packed_code_sizes[num_packed_code_sizes++] = code_size; + } else if (++rle_repeat_count == 6) { + TDEFL_RLE_PREV_CODE_SIZE(); + } + } + prev_code_size = code_size; + } + if (rle_repeat_count) { + TDEFL_RLE_PREV_CODE_SIZE(); + } else { + TDEFL_RLE_ZERO_CODE_SIZE(); + } + + tdefl_optimize_huffman_table(d, 2, TDEFL_MAX_HUFF_SYMBOLS_2, 7, MZ_FALSE); + + TDEFL_PUT_BITS(2, 2); + + TDEFL_PUT_BITS(num_lit_codes - 257, 5); + TDEFL_PUT_BITS(num_dist_codes - 1, 5); + + for (num_bit_lengths = 18; num_bit_lengths >= 0; num_bit_lengths--) + if (d->m_huff_code_sizes + [2][s_tdefl_packed_code_size_syms_swizzle[num_bit_lengths]]) + break; + num_bit_lengths = MZ_MAX(4, (num_bit_lengths + 1)); + TDEFL_PUT_BITS(num_bit_lengths - 4, 4); + for (i = 0; (int)i < num_bit_lengths; i++) + TDEFL_PUT_BITS( + d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[i]], 3); + + for (packed_code_sizes_index = 0; + packed_code_sizes_index < num_packed_code_sizes;) { + mz_uint code = packed_code_sizes[packed_code_sizes_index++]; + MZ_ASSERT(code < TDEFL_MAX_HUFF_SYMBOLS_2); + TDEFL_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]); + if (code >= 16) + TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++], + "\02\03\07"[code - 16]); + } +} + +static void tdefl_start_static_block(tdefl_compressor *d) { + mz_uint i; + mz_uint8 *p = &d->m_huff_code_sizes[0][0]; + + for (i = 0; i <= 143; ++i) *p++ = 8; + for (; i <= 255; ++i) *p++ = 9; + for (; i <= 279; ++i) *p++ = 7; + for (; i <= 287; ++i) *p++ = 8; + + memset(d->m_huff_code_sizes[1], 5, 32); + + tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE); + tdefl_optimize_huffman_table(d, 1, 32, 15, MZ_TRUE); + + TDEFL_PUT_BITS(1, 2); +} + +static const mz_uint mz_bitmasks[17] = { + 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, + 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF}; + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && \ + MINIZ_HAS_64BIT_REGISTERS +static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d) { + mz_uint flags; + mz_uint8 *pLZ_codes; + mz_uint8 *pOutput_buf = d->m_pOutput_buf; + mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf; + mz_uint64 bit_buffer = d->m_bit_buffer; + mz_uint bits_in = d->m_bits_in; + +#define TDEFL_PUT_BITS_FAST(b, l) \ + { \ + bit_buffer |= (((mz_uint64)(b)) << bits_in); \ + bits_in += (l); \ + } + + flags = 1; + for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end; + flags >>= 1) { + if (flags == 1) flags = *pLZ_codes++ | 0x100; + + if (flags & 1) { + mz_uint s0, s1, n0, n1, sym, num_extra_bits; + mz_uint match_len = pLZ_codes[0], + match_dist = *(const mz_uint16 *)(pLZ_codes + 1); + pLZ_codes += 3; + + MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], + d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); + TDEFL_PUT_BITS_FAST(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], + s_tdefl_len_extra[match_len]); + + // This sequence coaxes MSVC into using cmov's vs. jmp's. + s0 = s_tdefl_small_dist_sym[match_dist & 511]; + n0 = s_tdefl_small_dist_extra[match_dist & 511]; + s1 = s_tdefl_large_dist_sym[match_dist >> 8]; + n1 = s_tdefl_large_dist_extra[match_dist >> 8]; + sym = (match_dist < 512) ? s0 : s1; + num_extra_bits = (match_dist < 512) ? n0 : n1; + + MZ_ASSERT(d->m_huff_code_sizes[1][sym]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym], + d->m_huff_code_sizes[1][sym]); + TDEFL_PUT_BITS_FAST(match_dist & mz_bitmasks[num_extra_bits], + num_extra_bits); + } else { + mz_uint lit = *pLZ_codes++; + MZ_ASSERT(d->m_huff_code_sizes[0][lit]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], + d->m_huff_code_sizes[0][lit]); + + if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) { + flags >>= 1; + lit = *pLZ_codes++; + MZ_ASSERT(d->m_huff_code_sizes[0][lit]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], + d->m_huff_code_sizes[0][lit]); + + if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) { + flags >>= 1; + lit = *pLZ_codes++; + MZ_ASSERT(d->m_huff_code_sizes[0][lit]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], + d->m_huff_code_sizes[0][lit]); + } + } + } + + if (pOutput_buf >= d->m_pOutput_buf_end) return MZ_FALSE; + + *(mz_uint64 *)pOutput_buf = bit_buffer; + pOutput_buf += (bits_in >> 3); + bit_buffer >>= (bits_in & ~7); + bits_in &= 7; + } + +#undef TDEFL_PUT_BITS_FAST + + d->m_pOutput_buf = pOutput_buf; + d->m_bits_in = 0; + d->m_bit_buffer = 0; + + while (bits_in) { + mz_uint32 n = MZ_MIN(bits_in, 16); + TDEFL_PUT_BITS((mz_uint)bit_buffer & mz_bitmasks[n], n); + bit_buffer >>= n; + bits_in -= n; + } + + TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]); + + return (d->m_pOutput_buf < d->m_pOutput_buf_end); +} +#else +static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d) { + mz_uint flags; + mz_uint8 *pLZ_codes; + + flags = 1; + for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf; + flags >>= 1) { + if (flags == 1) flags = *pLZ_codes++ | 0x100; + if (flags & 1) { + mz_uint sym, num_extra_bits; + mz_uint match_len = pLZ_codes[0], + match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8)); + pLZ_codes += 3; + + MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); + TDEFL_PUT_BITS(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], + d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); + TDEFL_PUT_BITS(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], + s_tdefl_len_extra[match_len]); + + if (match_dist < 512) { + sym = s_tdefl_small_dist_sym[match_dist]; + num_extra_bits = s_tdefl_small_dist_extra[match_dist]; + } else { + sym = s_tdefl_large_dist_sym[match_dist >> 8]; + num_extra_bits = s_tdefl_large_dist_extra[match_dist >> 8]; + } + MZ_ASSERT(d->m_huff_code_sizes[1][sym]); + TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]); + TDEFL_PUT_BITS(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits); + } else { + mz_uint lit = *pLZ_codes++; + MZ_ASSERT(d->m_huff_code_sizes[0][lit]); + TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); + } + } + + TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]); + + return (d->m_pOutput_buf < d->m_pOutput_buf_end); +} +#endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && + // MINIZ_HAS_64BIT_REGISTERS + +static mz_bool tdefl_compress_block(tdefl_compressor *d, mz_bool static_block) { + if (static_block) + tdefl_start_static_block(d); + else + tdefl_start_dynamic_block(d); + return tdefl_compress_lz_codes(d); +} + +static int tdefl_flush_block(tdefl_compressor *d, int flush) { + mz_uint saved_bit_buf, saved_bits_in; + mz_uint8 *pSaved_output_buf; + mz_bool comp_block_succeeded = MZ_FALSE; + int n, + use_raw_block = + ((d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS) != 0) && + (d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size; + mz_uint8 *pOutput_buf_start = + ((d->m_pPut_buf_func == NULL) && + ((*d->m_pOut_buf_size - d->m_out_buf_ofs) >= TDEFL_OUT_BUF_SIZE)) + ? ((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs) + : d->m_output_buf; + + d->m_pOutput_buf = pOutput_buf_start; + d->m_pOutput_buf_end = d->m_pOutput_buf + TDEFL_OUT_BUF_SIZE - 16; + + MZ_ASSERT(!d->m_output_flush_remaining); + d->m_output_flush_ofs = 0; + d->m_output_flush_remaining = 0; + + *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left); + d->m_pLZ_code_buf -= (d->m_num_flags_left == 8); + + if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index)) { + TDEFL_PUT_BITS(0x78, 8); + TDEFL_PUT_BITS(0x01, 8); + } + + TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1); + + pSaved_output_buf = d->m_pOutput_buf; + saved_bit_buf = d->m_bit_buffer; + saved_bits_in = d->m_bits_in; + + if (!use_raw_block) + comp_block_succeeded = + tdefl_compress_block(d, + (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) || + (d->m_total_lz_bytes < 48)); + + // If the block gets expanded, forget the current contents of the output + // buffer and send a raw block instead. + if (((use_raw_block) || + ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >= + d->m_total_lz_bytes))) && + ((d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size)) { + mz_uint i; + d->m_pOutput_buf = pSaved_output_buf; + d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in; + TDEFL_PUT_BITS(0, 2); + if (d->m_bits_in) { + TDEFL_PUT_BITS(0, 8 - d->m_bits_in); + } + for (i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF) { + TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16); + } + for (i = 0; i < d->m_total_lz_bytes; ++i) { + TDEFL_PUT_BITS( + d->m_dict[(d->m_lz_code_buf_dict_pos + i) & TDEFL_LZ_DICT_SIZE_MASK], + 8); + } + } + // Check for the extremely unlikely (if not impossible) case of the compressed + // block not fitting into the output buffer when using dynamic codes. + else if (!comp_block_succeeded) { + d->m_pOutput_buf = pSaved_output_buf; + d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in; + tdefl_compress_block(d, MZ_TRUE); + } + + if (flush) { + if (flush == TDEFL_FINISH) { + if (d->m_bits_in) { + TDEFL_PUT_BITS(0, 8 - d->m_bits_in); + } + if (d->m_flags & TDEFL_WRITE_ZLIB_HEADER) { + mz_uint i, a = d->m_adler32; + for (i = 0; i < 4; i++) { + TDEFL_PUT_BITS((a >> 24) & 0xFF, 8); + a <<= 8; + } + } + } else { + mz_uint i, z = 0; + TDEFL_PUT_BITS(0, 3); + if (d->m_bits_in) { + TDEFL_PUT_BITS(0, 8 - d->m_bits_in); + } + for (i = 2; i; --i, z ^= 0xFFFF) { + TDEFL_PUT_BITS(z & 0xFFFF, 16); + } + } + } + + MZ_ASSERT(d->m_pOutput_buf < d->m_pOutput_buf_end); + + memset(&d->m_huff_count[0][0], 0, + sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0); + memset(&d->m_huff_count[1][0], 0, + sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1); + + d->m_pLZ_code_buf = d->m_lz_code_buf + 1; + d->m_pLZ_flags = d->m_lz_code_buf; + d->m_num_flags_left = 8; + d->m_lz_code_buf_dict_pos += d->m_total_lz_bytes; + d->m_total_lz_bytes = 0; + d->m_block_index++; + + if ((n = (int)(d->m_pOutput_buf - pOutput_buf_start)) != 0) { + if (d->m_pPut_buf_func) { + *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf; + if (!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user)) + return (d->m_prev_return_status = TDEFL_STATUS_PUT_BUF_FAILED); + } else if (pOutput_buf_start == d->m_output_buf) { + int bytes_to_copy = (int)MZ_MIN( + (size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs)); + memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf, + bytes_to_copy); + d->m_out_buf_ofs += bytes_to_copy; + if ((n -= bytes_to_copy) != 0) { + d->m_output_flush_ofs = bytes_to_copy; + d->m_output_flush_remaining = n; + } + } else { + d->m_out_buf_ofs += n; + } + } + + return d->m_output_flush_remaining; +} + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES +#define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16 *)(p) +static MZ_FORCEINLINE void tdefl_find_match( + tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, + mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len) { + mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, + match_len = *pMatch_len, probe_pos = pos, next_probe_pos, + probe_len; + mz_uint num_probes_left = d->m_max_probes[match_len >= 32]; + const mz_uint16 *s = (const mz_uint16 *)(d->m_dict + pos), *p, *q; + mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]), + s01 = TDEFL_READ_UNALIGNED_WORD(s); + MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); + if (max_match_len <= match_len) return; + for (;;) { + for (;;) { + if (--num_probes_left == 0) return; +#define TDEFL_PROBE \ + next_probe_pos = d->m_next[probe_pos]; \ + if ((!next_probe_pos) || \ + ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \ + return; \ + probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \ + if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) \ + break; + TDEFL_PROBE; + TDEFL_PROBE; + TDEFL_PROBE; + } + if (!dist) break; + q = (const mz_uint16 *)(d->m_dict + probe_pos); + if (TDEFL_READ_UNALIGNED_WORD(q) != s01) continue; + p = s; + probe_len = 32; + do { + } while ( + (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && + (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && + (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && + (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && + (--probe_len > 0)); + if (!probe_len) { + *pMatch_dist = dist; + *pMatch_len = MZ_MIN(max_match_len, TDEFL_MAX_MATCH_LEN); + break; + } else if ((probe_len = ((mz_uint)(p - s) * 2) + + (mz_uint)(*(const mz_uint8 *)p == + *(const mz_uint8 *)q)) > match_len) { + *pMatch_dist = dist; + if ((*pMatch_len = match_len = MZ_MIN(max_match_len, probe_len)) == + max_match_len) + break; + c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]); + } + } +} +#else +static MZ_FORCEINLINE void tdefl_find_match( + tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, + mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len) { + mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, + match_len = *pMatch_len, probe_pos = pos, next_probe_pos, + probe_len; + mz_uint num_probes_left = d->m_max_probes[match_len >= 32]; + const mz_uint8 *s = d->m_dict + pos, *p, *q; + mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1]; + MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); + if (max_match_len <= match_len) return; + for (;;) { + for (;;) { + if (--num_probes_left == 0) return; +#define TDEFL_PROBE \ + next_probe_pos = d->m_next[probe_pos]; \ + if ((!next_probe_pos) || \ + ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \ + return; \ + probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \ + if ((d->m_dict[probe_pos + match_len] == c0) && \ + (d->m_dict[probe_pos + match_len - 1] == c1)) \ + break; + TDEFL_PROBE; + TDEFL_PROBE; + TDEFL_PROBE; + } + if (!dist) break; + p = s; + q = d->m_dict + probe_pos; + for (probe_len = 0; probe_len < max_match_len; probe_len++) + if (*p++ != *q++) break; + if (probe_len > match_len) { + *pMatch_dist = dist; + if ((*pMatch_len = match_len = probe_len) == max_match_len) return; + c0 = d->m_dict[pos + match_len]; + c1 = d->m_dict[pos + match_len - 1]; + } + } +} +#endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN +static mz_bool tdefl_compress_fast(tdefl_compressor *d) { + // Faster, minimally featured LZRW1-style match+parse loop with better + // register utilization. Intended for applications where raw throughput is + // valued more highly than ratio. + mz_uint lookahead_pos = d->m_lookahead_pos, + lookahead_size = d->m_lookahead_size, dict_size = d->m_dict_size, + total_lz_bytes = d->m_total_lz_bytes, + num_flags_left = d->m_num_flags_left; + mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags; + mz_uint cur_pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK; + + while ((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size))) { + const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE = 4096; + mz_uint dst_pos = + (lookahead_pos + lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK; + mz_uint num_bytes_to_process = (mz_uint)MZ_MIN( + d->m_src_buf_left, TDEFL_COMP_FAST_LOOKAHEAD_SIZE - lookahead_size); + d->m_src_buf_left -= num_bytes_to_process; + lookahead_size += num_bytes_to_process; + + while (num_bytes_to_process) { + mz_uint32 n = MZ_MIN(TDEFL_LZ_DICT_SIZE - dst_pos, num_bytes_to_process); + memcpy(d->m_dict + dst_pos, d->m_pSrc, n); + if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) + memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc, + MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos)); + d->m_pSrc += n; + dst_pos = (dst_pos + n) & TDEFL_LZ_DICT_SIZE_MASK; + num_bytes_to_process -= n; + } + + dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - lookahead_size, dict_size); + if ((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE)) + break; + + while (lookahead_size >= 4) { + mz_uint cur_match_dist, cur_match_len = 1; + mz_uint8 *pCur_dict = d->m_dict + cur_pos; + mz_uint first_trigram = (*(const mz_uint32 *)pCur_dict) & 0xFFFFFF; + mz_uint hash = + (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) & + TDEFL_LEVEL1_HASH_SIZE_MASK; + mz_uint probe_pos = d->m_hash[hash]; + d->m_hash[hash] = (mz_uint16)lookahead_pos; + + if (((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <= + dict_size) && + ((*(const mz_uint32 *)(d->m_dict + + (probe_pos &= TDEFL_LZ_DICT_SIZE_MASK)) & + 0xFFFFFF) == first_trigram)) { + const mz_uint16 *p = (const mz_uint16 *)pCur_dict; + const mz_uint16 *q = (const mz_uint16 *)(d->m_dict + probe_pos); + mz_uint32 probe_len = 32; + do { + } while ((TDEFL_READ_UNALIGNED_WORD(++p) == + TDEFL_READ_UNALIGNED_WORD(++q)) && + (TDEFL_READ_UNALIGNED_WORD(++p) == + TDEFL_READ_UNALIGNED_WORD(++q)) && + (TDEFL_READ_UNALIGNED_WORD(++p) == + TDEFL_READ_UNALIGNED_WORD(++q)) && + (TDEFL_READ_UNALIGNED_WORD(++p) == + TDEFL_READ_UNALIGNED_WORD(++q)) && + (--probe_len > 0)); + cur_match_len = ((mz_uint)(p - (const mz_uint16 *)pCur_dict) * 2) + + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q); + if (!probe_len) + cur_match_len = cur_match_dist ? TDEFL_MAX_MATCH_LEN : 0; + + if ((cur_match_len < TDEFL_MIN_MATCH_LEN) || + ((cur_match_len == TDEFL_MIN_MATCH_LEN) && + (cur_match_dist >= 8U * 1024U))) { + cur_match_len = 1; + *pLZ_code_buf++ = (mz_uint8)first_trigram; + *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); + d->m_huff_count[0][(mz_uint8)first_trigram]++; + } else { + mz_uint32 s0, s1; + cur_match_len = MZ_MIN(cur_match_len, lookahead_size); + + MZ_ASSERT((cur_match_len >= TDEFL_MIN_MATCH_LEN) && + (cur_match_dist >= 1) && + (cur_match_dist <= TDEFL_LZ_DICT_SIZE)); + + cur_match_dist--; + + pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN); + *(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist; + pLZ_code_buf += 3; + *pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80); + + s0 = s_tdefl_small_dist_sym[cur_match_dist & 511]; + s1 = s_tdefl_large_dist_sym[cur_match_dist >> 8]; + d->m_huff_count[1][(cur_match_dist < 512) ? s0 : s1]++; + + d->m_huff_count[0][s_tdefl_len_sym[cur_match_len - + TDEFL_MIN_MATCH_LEN]]++; + } + } else { + *pLZ_code_buf++ = (mz_uint8)first_trigram; + *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); + d->m_huff_count[0][(mz_uint8)first_trigram]++; + } + + if (--num_flags_left == 0) { + num_flags_left = 8; + pLZ_flags = pLZ_code_buf++; + } + + total_lz_bytes += cur_match_len; + lookahead_pos += cur_match_len; + dict_size = MZ_MIN(dict_size + cur_match_len, TDEFL_LZ_DICT_SIZE); + cur_pos = (cur_pos + cur_match_len) & TDEFL_LZ_DICT_SIZE_MASK; + MZ_ASSERT(lookahead_size >= cur_match_len); + lookahead_size -= cur_match_len; + + if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) { + int n; + d->m_lookahead_pos = lookahead_pos; + d->m_lookahead_size = lookahead_size; + d->m_dict_size = dict_size; + d->m_total_lz_bytes = total_lz_bytes; + d->m_pLZ_code_buf = pLZ_code_buf; + d->m_pLZ_flags = pLZ_flags; + d->m_num_flags_left = num_flags_left; + if ((n = tdefl_flush_block(d, 0)) != 0) + return (n < 0) ? MZ_FALSE : MZ_TRUE; + total_lz_bytes = d->m_total_lz_bytes; + pLZ_code_buf = d->m_pLZ_code_buf; + pLZ_flags = d->m_pLZ_flags; + num_flags_left = d->m_num_flags_left; + } + } + + while (lookahead_size) { + mz_uint8 lit = d->m_dict[cur_pos]; + + total_lz_bytes++; + *pLZ_code_buf++ = lit; + *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); + if (--num_flags_left == 0) { + num_flags_left = 8; + pLZ_flags = pLZ_code_buf++; + } + + d->m_huff_count[0][lit]++; + + lookahead_pos++; + dict_size = MZ_MIN(dict_size + 1, TDEFL_LZ_DICT_SIZE); + cur_pos = (cur_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; + lookahead_size--; + + if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) { + int n; + d->m_lookahead_pos = lookahead_pos; + d->m_lookahead_size = lookahead_size; + d->m_dict_size = dict_size; + d->m_total_lz_bytes = total_lz_bytes; + d->m_pLZ_code_buf = pLZ_code_buf; + d->m_pLZ_flags = pLZ_flags; + d->m_num_flags_left = num_flags_left; + if ((n = tdefl_flush_block(d, 0)) != 0) + return (n < 0) ? MZ_FALSE : MZ_TRUE; + total_lz_bytes = d->m_total_lz_bytes; + pLZ_code_buf = d->m_pLZ_code_buf; + pLZ_flags = d->m_pLZ_flags; + num_flags_left = d->m_num_flags_left; + } + } + } + + d->m_lookahead_pos = lookahead_pos; + d->m_lookahead_size = lookahead_size; + d->m_dict_size = dict_size; + d->m_total_lz_bytes = total_lz_bytes; + d->m_pLZ_code_buf = pLZ_code_buf; + d->m_pLZ_flags = pLZ_flags; + d->m_num_flags_left = num_flags_left; + return MZ_TRUE; +} +#endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN + +static MZ_FORCEINLINE void tdefl_record_literal(tdefl_compressor *d, + mz_uint8 lit) { + d->m_total_lz_bytes++; + *d->m_pLZ_code_buf++ = lit; + *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1); + if (--d->m_num_flags_left == 0) { + d->m_num_flags_left = 8; + d->m_pLZ_flags = d->m_pLZ_code_buf++; + } + d->m_huff_count[0][lit]++; +} + +static MZ_FORCEINLINE void tdefl_record_match(tdefl_compressor *d, + mz_uint match_len, + mz_uint match_dist) { + mz_uint32 s0, s1; + + MZ_ASSERT((match_len >= TDEFL_MIN_MATCH_LEN) && (match_dist >= 1) && + (match_dist <= TDEFL_LZ_DICT_SIZE)); + + d->m_total_lz_bytes += match_len; + + d->m_pLZ_code_buf[0] = (mz_uint8)(match_len - TDEFL_MIN_MATCH_LEN); + + match_dist -= 1; + d->m_pLZ_code_buf[1] = (mz_uint8)(match_dist & 0xFF); + d->m_pLZ_code_buf[2] = (mz_uint8)(match_dist >> 8); + d->m_pLZ_code_buf += 3; + + *d->m_pLZ_flags = (mz_uint8)((*d->m_pLZ_flags >> 1) | 0x80); + if (--d->m_num_flags_left == 0) { + d->m_num_flags_left = 8; + d->m_pLZ_flags = d->m_pLZ_code_buf++; + } + + s0 = s_tdefl_small_dist_sym[match_dist & 511]; + s1 = s_tdefl_large_dist_sym[(match_dist >> 8) & 127]; + d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++; + + if (match_len >= TDEFL_MIN_MATCH_LEN) + d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++; +} + +static mz_bool tdefl_compress_normal(tdefl_compressor *d) { + const mz_uint8 *pSrc = d->m_pSrc; + size_t src_buf_left = d->m_src_buf_left; + tdefl_flush flush = d->m_flush; + + while ((src_buf_left) || ((flush) && (d->m_lookahead_size))) { + mz_uint len_to_move, cur_match_dist, cur_match_len, cur_pos; + // Update dictionary and hash chains. Keeps the lookahead size equal to + // TDEFL_MAX_MATCH_LEN. + if ((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1)) { + mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & + TDEFL_LZ_DICT_SIZE_MASK, + ins_pos = d->m_lookahead_pos + d->m_lookahead_size - 2; + mz_uint hash = (d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] + << TDEFL_LZ_HASH_SHIFT) ^ + d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK]; + mz_uint num_bytes_to_process = (mz_uint)MZ_MIN( + src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size); + const mz_uint8 *pSrc_end = pSrc + num_bytes_to_process; + src_buf_left -= num_bytes_to_process; + d->m_lookahead_size += num_bytes_to_process; + while (pSrc != pSrc_end) { + mz_uint8 c = *pSrc++; + d->m_dict[dst_pos] = c; + if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) + d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c; + hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1); + d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; + d->m_hash[hash] = (mz_uint16)(ins_pos); + dst_pos = (dst_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; + ins_pos++; + } + } else { + while ((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) { + mz_uint8 c = *pSrc++; + mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & + TDEFL_LZ_DICT_SIZE_MASK; + src_buf_left--; + d->m_dict[dst_pos] = c; + if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) + d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c; + if ((++d->m_lookahead_size + d->m_dict_size) >= TDEFL_MIN_MATCH_LEN) { + mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2; + mz_uint hash = ((d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] + << (TDEFL_LZ_HASH_SHIFT * 2)) ^ + (d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK] + << TDEFL_LZ_HASH_SHIFT) ^ + c) & + (TDEFL_LZ_HASH_SIZE - 1); + d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; + d->m_hash[hash] = (mz_uint16)(ins_pos); + } + } + } + d->m_dict_size = + MZ_MIN(TDEFL_LZ_DICT_SIZE - d->m_lookahead_size, d->m_dict_size); + if ((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) break; + + // Simple lazy/greedy parsing state machine. + len_to_move = 1; + cur_match_dist = 0; + cur_match_len = + d->m_saved_match_len ? d->m_saved_match_len : (TDEFL_MIN_MATCH_LEN - 1); + cur_pos = d->m_lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK; + if (d->m_flags & (TDEFL_RLE_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS)) { + if ((d->m_dict_size) && (!(d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))) { + mz_uint8 c = d->m_dict[(cur_pos - 1) & TDEFL_LZ_DICT_SIZE_MASK]; + cur_match_len = 0; + while (cur_match_len < d->m_lookahead_size) { + if (d->m_dict[cur_pos + cur_match_len] != c) break; + cur_match_len++; + } + if (cur_match_len < TDEFL_MIN_MATCH_LEN) + cur_match_len = 0; + else + cur_match_dist = 1; + } + } else { + tdefl_find_match(d, d->m_lookahead_pos, d->m_dict_size, + d->m_lookahead_size, &cur_match_dist, &cur_match_len); + } + if (((cur_match_len == TDEFL_MIN_MATCH_LEN) && + (cur_match_dist >= 8U * 1024U)) || + (cur_pos == cur_match_dist) || + ((d->m_flags & TDEFL_FILTER_MATCHES) && (cur_match_len <= 5))) { + cur_match_dist = cur_match_len = 0; + } + if (d->m_saved_match_len) { + if (cur_match_len > d->m_saved_match_len) { + tdefl_record_literal(d, (mz_uint8)d->m_saved_lit); + if (cur_match_len >= 128) { + tdefl_record_match(d, cur_match_len, cur_match_dist); + d->m_saved_match_len = 0; + len_to_move = cur_match_len; + } else { + d->m_saved_lit = d->m_dict[cur_pos]; + d->m_saved_match_dist = cur_match_dist; + d->m_saved_match_len = cur_match_len; + } + } else { + tdefl_record_match(d, d->m_saved_match_len, d->m_saved_match_dist); + len_to_move = d->m_saved_match_len - 1; + d->m_saved_match_len = 0; + } + } else if (!cur_match_dist) + tdefl_record_literal(d, + d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]); + else if ((d->m_greedy_parsing) || (d->m_flags & TDEFL_RLE_MATCHES) || + (cur_match_len >= 128)) { + tdefl_record_match(d, cur_match_len, cur_match_dist); + len_to_move = cur_match_len; + } else { + d->m_saved_lit = d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]; + d->m_saved_match_dist = cur_match_dist; + d->m_saved_match_len = cur_match_len; + } + // Move the lookahead forward by len_to_move bytes. + d->m_lookahead_pos += len_to_move; + MZ_ASSERT(d->m_lookahead_size >= len_to_move); + d->m_lookahead_size -= len_to_move; + d->m_dict_size = + MZ_MIN(d->m_dict_size + len_to_move, (mz_uint)TDEFL_LZ_DICT_SIZE); + // Check if it's time to flush the current LZ codes to the internal output + // buffer. + if ((d->m_pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) || + ((d->m_total_lz_bytes > 31 * 1024) && + (((((mz_uint)(d->m_pLZ_code_buf - d->m_lz_code_buf) * 115) >> 7) >= + d->m_total_lz_bytes) || + (d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS)))) { + int n; + d->m_pSrc = pSrc; + d->m_src_buf_left = src_buf_left; + if ((n = tdefl_flush_block(d, 0)) != 0) + return (n < 0) ? MZ_FALSE : MZ_TRUE; + } + } + + d->m_pSrc = pSrc; + d->m_src_buf_left = src_buf_left; + return MZ_TRUE; +} + +static tdefl_status tdefl_flush_output_buffer(tdefl_compressor *d) { + if (d->m_pIn_buf_size) { + *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf; + } + + if (d->m_pOut_buf_size) { + size_t n = MZ_MIN(*d->m_pOut_buf_size - d->m_out_buf_ofs, + d->m_output_flush_remaining); + memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, + d->m_output_buf + d->m_output_flush_ofs, n); + d->m_output_flush_ofs += (mz_uint)n; + d->m_output_flush_remaining -= (mz_uint)n; + d->m_out_buf_ofs += n; + + *d->m_pOut_buf_size = d->m_out_buf_ofs; + } + + return (d->m_finished && !d->m_output_flush_remaining) ? TDEFL_STATUS_DONE + : TDEFL_STATUS_OKAY; +} + +tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, + size_t *pIn_buf_size, void *pOut_buf, + size_t *pOut_buf_size, tdefl_flush flush) { + if (!d) { + if (pIn_buf_size) *pIn_buf_size = 0; + if (pOut_buf_size) *pOut_buf_size = 0; + return TDEFL_STATUS_BAD_PARAM; + } + + d->m_pIn_buf = pIn_buf; + d->m_pIn_buf_size = pIn_buf_size; + d->m_pOut_buf = pOut_buf; + d->m_pOut_buf_size = pOut_buf_size; + d->m_pSrc = (const mz_uint8 *)(pIn_buf); + d->m_src_buf_left = pIn_buf_size ? *pIn_buf_size : 0; + d->m_out_buf_ofs = 0; + d->m_flush = flush; + + if (((d->m_pPut_buf_func != NULL) == + ((pOut_buf != NULL) || (pOut_buf_size != NULL))) || + (d->m_prev_return_status != TDEFL_STATUS_OKAY) || + (d->m_wants_to_finish && (flush != TDEFL_FINISH)) || + (pIn_buf_size && *pIn_buf_size && !pIn_buf) || + (pOut_buf_size && *pOut_buf_size && !pOut_buf)) { + if (pIn_buf_size) *pIn_buf_size = 0; + if (pOut_buf_size) *pOut_buf_size = 0; + return (d->m_prev_return_status = TDEFL_STATUS_BAD_PARAM); + } + d->m_wants_to_finish |= (flush == TDEFL_FINISH); + + if ((d->m_output_flush_remaining) || (d->m_finished)) + return (d->m_prev_return_status = tdefl_flush_output_buffer(d)); + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN + if (((d->m_flags & TDEFL_MAX_PROBES_MASK) == 1) && + ((d->m_flags & TDEFL_GREEDY_PARSING_FLAG) != 0) && + ((d->m_flags & (TDEFL_FILTER_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS | + TDEFL_RLE_MATCHES)) == 0)) { + if (!tdefl_compress_fast(d)) return d->m_prev_return_status; + } else +#endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN + { + if (!tdefl_compress_normal(d)) return d->m_prev_return_status; + } + + if ((d->m_flags & (TDEFL_WRITE_ZLIB_HEADER | TDEFL_COMPUTE_ADLER32)) && + (pIn_buf)) + d->m_adler32 = + (mz_uint32)mz_adler32(d->m_adler32, (const mz_uint8 *)pIn_buf, + d->m_pSrc - (const mz_uint8 *)pIn_buf); + + if ((flush) && (!d->m_lookahead_size) && (!d->m_src_buf_left) && + (!d->m_output_flush_remaining)) { + if (tdefl_flush_block(d, flush) < 0) return d->m_prev_return_status; + d->m_finished = (flush == TDEFL_FINISH); + if (flush == TDEFL_FULL_FLUSH) { + MZ_CLEAR_OBJ(d->m_hash); + MZ_CLEAR_OBJ(d->m_next); + d->m_dict_size = 0; + } + } + + return (d->m_prev_return_status = tdefl_flush_output_buffer(d)); +} + +tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, + size_t in_buf_size, tdefl_flush flush) { + MZ_ASSERT(d->m_pPut_buf_func); + return tdefl_compress(d, pIn_buf, &in_buf_size, NULL, NULL, flush); +} + +tdefl_status tdefl_init(tdefl_compressor *d, + tdefl_put_buf_func_ptr pPut_buf_func, + void *pPut_buf_user, int flags) { + d->m_pPut_buf_func = pPut_buf_func; + d->m_pPut_buf_user = pPut_buf_user; + d->m_flags = (mz_uint)(flags); + d->m_max_probes[0] = 1 + ((flags & 0xFFF) + 2) / 3; + d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0; + d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3; + if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG)) MZ_CLEAR_OBJ(d->m_hash); + d->m_lookahead_pos = d->m_lookahead_size = d->m_dict_size = + d->m_total_lz_bytes = d->m_lz_code_buf_dict_pos = d->m_bits_in = 0; + d->m_output_flush_ofs = d->m_output_flush_remaining = d->m_finished = + d->m_block_index = d->m_bit_buffer = d->m_wants_to_finish = 0; + d->m_pLZ_code_buf = d->m_lz_code_buf + 1; + d->m_pLZ_flags = d->m_lz_code_buf; + d->m_num_flags_left = 8; + d->m_pOutput_buf = d->m_output_buf; + d->m_pOutput_buf_end = d->m_output_buf; + d->m_prev_return_status = TDEFL_STATUS_OKAY; + d->m_saved_match_dist = d->m_saved_match_len = d->m_saved_lit = 0; + d->m_adler32 = 1; + d->m_pIn_buf = NULL; + d->m_pOut_buf = NULL; + d->m_pIn_buf_size = NULL; + d->m_pOut_buf_size = NULL; + d->m_flush = TDEFL_NO_FLUSH; + d->m_pSrc = NULL; + d->m_src_buf_left = 0; + d->m_out_buf_ofs = 0; + memset(&d->m_huff_count[0][0], 0, + sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0); + memset(&d->m_huff_count[1][0], 0, + sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1); + return TDEFL_STATUS_OKAY; +} + +tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d) { + return d->m_prev_return_status; +} + +mz_uint32 tdefl_get_adler32(tdefl_compressor *d) { return d->m_adler32; } + +mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, + tdefl_put_buf_func_ptr pPut_buf_func, + void *pPut_buf_user, int flags) { + tdefl_compressor *pComp; + mz_bool succeeded; + if (((buf_len) && (!pBuf)) || (!pPut_buf_func)) return MZ_FALSE; + pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor)); + if (!pComp) return MZ_FALSE; + succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags) == + TDEFL_STATUS_OKAY); + succeeded = + succeeded && (tdefl_compress_buffer(pComp, pBuf, buf_len, TDEFL_FINISH) == + TDEFL_STATUS_DONE); + MZ_FREE(pComp); + return succeeded; +} + +typedef struct { + size_t m_size, m_capacity; + mz_uint8 *m_pBuf; + mz_bool m_expandable; +} tdefl_output_buffer; + +static mz_bool tdefl_output_buffer_putter(const void *pBuf, int len, + void *pUser) { + tdefl_output_buffer *p = (tdefl_output_buffer *)pUser; + size_t new_size = p->m_size + len; + if (new_size > p->m_capacity) { + size_t new_capacity = p->m_capacity; + mz_uint8 *pNew_buf; + if (!p->m_expandable) return MZ_FALSE; + do { + new_capacity = MZ_MAX(128U, new_capacity << 1U); + } while (new_size > new_capacity); + pNew_buf = (mz_uint8 *)MZ_REALLOC(p->m_pBuf, new_capacity); + if (!pNew_buf) return MZ_FALSE; + p->m_pBuf = pNew_buf; + p->m_capacity = new_capacity; + } + memcpy((mz_uint8 *)p->m_pBuf + p->m_size, pBuf, len); + p->m_size = new_size; + return MZ_TRUE; +} + +void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, + size_t *pOut_len, int flags) { + tdefl_output_buffer out_buf; + MZ_CLEAR_OBJ(out_buf); + if (!pOut_len) + return MZ_FALSE; + else + *pOut_len = 0; + out_buf.m_expandable = MZ_TRUE; + if (!tdefl_compress_mem_to_output( + pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) + return NULL; + *pOut_len = out_buf.m_size; + return out_buf.m_pBuf; +} + +size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, + const void *pSrc_buf, size_t src_buf_len, + int flags) { + tdefl_output_buffer out_buf; + MZ_CLEAR_OBJ(out_buf); + if (!pOut_buf) return 0; + out_buf.m_pBuf = (mz_uint8 *)pOut_buf; + out_buf.m_capacity = out_buf_len; + if (!tdefl_compress_mem_to_output( + pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) + return 0; + return out_buf.m_size; +} + +#ifndef MINIZ_NO_ZLIB_APIS +static const mz_uint s_tdefl_num_probes[11] = {0, 1, 6, 32, 16, 32, + 128, 256, 512, 768, 1500}; + +// level may actually range from [0,10] (10 is a "hidden" max level, where we +// want a bit more compression and it's fine if throughput to fall off a cliff +// on some files). +mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, + int strategy) { + mz_uint comp_flags = + s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : MZ_DEFAULT_LEVEL] | + ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0); + if (window_bits > 0) comp_flags |= TDEFL_WRITE_ZLIB_HEADER; + + if (!level) + comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS; + else if (strategy == MZ_FILTERED) + comp_flags |= TDEFL_FILTER_MATCHES; + else if (strategy == MZ_HUFFMAN_ONLY) + comp_flags &= ~TDEFL_MAX_PROBES_MASK; + else if (strategy == MZ_FIXED) + comp_flags |= TDEFL_FORCE_ALL_STATIC_BLOCKS; + else if (strategy == MZ_RLE) + comp_flags |= TDEFL_RLE_MATCHES; + + return comp_flags; +} +#endif // MINIZ_NO_ZLIB_APIS + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4204) // nonstandard extension used : non-constant + // aggregate initializer (also supported by GNU + // C and C99, so no big deal) +#pragma warning(disable : 4244) // 'initializing': conversion from '__int64' to + // 'int', possible loss of data +#pragma warning( \ + disable : 4267) // 'argument': conversion from '__int64' to 'int', + // possible loss of data +#pragma warning(disable : 4996) // 'strdup': The POSIX name for this item is + // deprecated. Instead, use the ISO C and C++ + // conformant name: _strdup. +#endif + +// Simple PNG writer function by Alex Evans, 2011. Released into the public +// domain: https://gist.github.com/908299, more context at +// http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/. +// This is actually a modification of Alex's original code so PNG files +// generated by this function pass pngcheck. +void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, + int h, int num_chans, + size_t *pLen_out, + mz_uint level, mz_bool flip) { + // Using a local copy of this array here in case MINIZ_NO_ZLIB_APIS was + // defined. + static const mz_uint s_tdefl_png_num_probes[11] = { + 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500}; + tdefl_compressor *pComp = + (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor)); + tdefl_output_buffer out_buf; + int i, bpl = w * num_chans, y, z; + mz_uint32 c; + *pLen_out = 0; + if (!pComp) return NULL; + MZ_CLEAR_OBJ(out_buf); + out_buf.m_expandable = MZ_TRUE; + out_buf.m_capacity = 57 + MZ_MAX(64, (1 + bpl) * h); + if (NULL == (out_buf.m_pBuf = (mz_uint8 *)MZ_MALLOC(out_buf.m_capacity))) { + MZ_FREE(pComp); + return NULL; + } + // write dummy header + for (z = 41; z; --z) tdefl_output_buffer_putter(&z, 1, &out_buf); + // compress image data + tdefl_init( + pComp, tdefl_output_buffer_putter, &out_buf, + s_tdefl_png_num_probes[MZ_MIN(10, level)] | TDEFL_WRITE_ZLIB_HEADER); + for (y = 0; y < h; ++y) { + tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH); + tdefl_compress_buffer(pComp, + (mz_uint8 *)pImage + (flip ? (h - 1 - y) : y) * bpl, + bpl, TDEFL_NO_FLUSH); + } + if (tdefl_compress_buffer(pComp, NULL, 0, TDEFL_FINISH) != + TDEFL_STATUS_DONE) { + MZ_FREE(pComp); + MZ_FREE(out_buf.m_pBuf); + return NULL; + } + // write real header + *pLen_out = out_buf.m_size - 41; + { + static const mz_uint8 chans[] = {0x00, 0x00, 0x04, 0x02, 0x06}; + mz_uint8 pnghdr[41] = {0x89, + 0x50, + 0x4e, + 0x47, + 0x0d, + 0x0a, + 0x1a, + 0x0a, + 0x00, + 0x00, + 0x00, + 0x0d, + 0x49, + 0x48, + 0x44, + 0x52, + 0, + 0, + (mz_uint8)(w >> 8), + (mz_uint8)w, + 0, + 0, + (mz_uint8)(h >> 8), + (mz_uint8)h, + 8, + chans[num_chans], + 0, + 0, + 0, + 0, + 0, + 0, + 0, + (mz_uint8)(*pLen_out >> 24), + (mz_uint8)(*pLen_out >> 16), + (mz_uint8)(*pLen_out >> 8), + (mz_uint8)*pLen_out, + 0x49, + 0x44, + 0x41, + 0x54}; + c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, pnghdr + 12, 17); + for (i = 0; i < 4; ++i, c <<= 8) + ((mz_uint8 *)(pnghdr + 29))[i] = (mz_uint8)(c >> 24); + memcpy(out_buf.m_pBuf, pnghdr, 41); + } + // write footer (IDAT CRC-32, followed by IEND chunk) + if (!tdefl_output_buffer_putter( + "\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf)) { + *pLen_out = 0; + MZ_FREE(pComp); + MZ_FREE(out_buf.m_pBuf); + return NULL; + } + c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, out_buf.m_pBuf + 41 - 4, + *pLen_out + 4); + for (i = 0; i < 4; ++i, c <<= 8) + (out_buf.m_pBuf + out_buf.m_size - 16)[i] = (mz_uint8)(c >> 24); + // compute final size of file, grab compressed data buffer and return + *pLen_out += 57; + MZ_FREE(pComp); + return out_buf.m_pBuf; +} +void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, + int num_chans, size_t *pLen_out) { + // Level 6 corresponds to TDEFL_DEFAULT_MAX_PROBES or MZ_DEFAULT_LEVEL (but we + // can't depend on MZ_DEFAULT_LEVEL being available in case the zlib API's + // where #defined out) + return tdefl_write_image_to_png_file_in_memory_ex(pImage, w, h, num_chans, + pLen_out, 6, MZ_FALSE); +} + +// ------------------- .ZIP archive reading + +#ifndef MINIZ_NO_ARCHIVE_APIS +#error "No arvhive APIs" + +#ifdef MINIZ_NO_STDIO +#define MZ_FILE void * +#else +#include +#include + +#if defined(_MSC_VER) || defined(__MINGW64__) +static FILE *mz_fopen(const char *pFilename, const char *pMode) { + FILE *pFile = NULL; + fopen_s(&pFile, pFilename, pMode); + return pFile; +} +static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) { + FILE *pFile = NULL; + if (freopen_s(&pFile, pPath, pMode, pStream)) return NULL; + return pFile; +} +#ifndef MINIZ_NO_TIME +#include +#endif +#define MZ_FILE FILE +#define MZ_FOPEN mz_fopen +#define MZ_FCLOSE fclose +#define MZ_FREAD fread +#define MZ_FWRITE fwrite +#define MZ_FTELL64 _ftelli64 +#define MZ_FSEEK64 _fseeki64 +#define MZ_FILE_STAT_STRUCT _stat +#define MZ_FILE_STAT _stat +#define MZ_FFLUSH fflush +#define MZ_FREOPEN mz_freopen +#define MZ_DELETE_FILE remove +#elif defined(__MINGW32__) +#ifndef MINIZ_NO_TIME +#include +#endif +#define MZ_FILE FILE +#define MZ_FOPEN(f, m) fopen(f, m) +#define MZ_FCLOSE fclose +#define MZ_FREAD fread +#define MZ_FWRITE fwrite +#define MZ_FTELL64 ftello64 +#define MZ_FSEEK64 fseeko64 +#define MZ_FILE_STAT_STRUCT _stat +#define MZ_FILE_STAT _stat +#define MZ_FFLUSH fflush +#define MZ_FREOPEN(f, m, s) freopen(f, m, s) +#define MZ_DELETE_FILE remove +#elif defined(__TINYC__) +#ifndef MINIZ_NO_TIME +#include +#endif +#define MZ_FILE FILE +#define MZ_FOPEN(f, m) fopen(f, m) +#define MZ_FCLOSE fclose +#define MZ_FREAD fread +#define MZ_FWRITE fwrite +#define MZ_FTELL64 ftell +#define MZ_FSEEK64 fseek +#define MZ_FILE_STAT_STRUCT stat +#define MZ_FILE_STAT stat +#define MZ_FFLUSH fflush +#define MZ_FREOPEN(f, m, s) freopen(f, m, s) +#define MZ_DELETE_FILE remove +#elif defined(__GNUC__) && defined(_LARGEFILE64_SOURCE) && _LARGEFILE64_SOURCE +#ifndef MINIZ_NO_TIME +#include +#endif +#define MZ_FILE FILE +#define MZ_FOPEN(f, m) fopen64(f, m) +#define MZ_FCLOSE fclose +#define MZ_FREAD fread +#define MZ_FWRITE fwrite +#define MZ_FTELL64 ftello64 +#define MZ_FSEEK64 fseeko64 +#define MZ_FILE_STAT_STRUCT stat64 +#define MZ_FILE_STAT stat64 +#define MZ_FFLUSH fflush +#define MZ_FREOPEN(p, m, s) freopen64(p, m, s) +#define MZ_DELETE_FILE remove +#else +#ifndef MINIZ_NO_TIME +#include +#endif +#define MZ_FILE FILE +#define MZ_FOPEN(f, m) fopen(f, m) +#define MZ_FCLOSE fclose +#define MZ_FREAD fread +#define MZ_FWRITE fwrite +#define MZ_FTELL64 ftello +#define MZ_FSEEK64 fseeko +#define MZ_FILE_STAT_STRUCT stat +#define MZ_FILE_STAT stat +#define MZ_FFLUSH fflush +#define MZ_FREOPEN(f, m, s) freopen(f, m, s) +#define MZ_DELETE_FILE remove +#endif // #ifdef _MSC_VER +#endif // #ifdef MINIZ_NO_STDIO + +#define MZ_TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c)) + +// Various ZIP archive enums. To completely avoid cross platform compiler +// alignment and platform endian issues, miniz.c doesn't use structs for any of +// this stuff. +enum { + // ZIP archive identifiers and record sizes + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06054b50, + MZ_ZIP_CENTRAL_DIR_HEADER_SIG = 0x02014b50, + MZ_ZIP_LOCAL_DIR_HEADER_SIG = 0x04034b50, + MZ_ZIP_LOCAL_DIR_HEADER_SIZE = 30, + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE = 46, + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE = 22, + // Central directory header record offsets + MZ_ZIP_CDH_SIG_OFS = 0, + MZ_ZIP_CDH_VERSION_MADE_BY_OFS = 4, + MZ_ZIP_CDH_VERSION_NEEDED_OFS = 6, + MZ_ZIP_CDH_BIT_FLAG_OFS = 8, + MZ_ZIP_CDH_METHOD_OFS = 10, + MZ_ZIP_CDH_FILE_TIME_OFS = 12, + MZ_ZIP_CDH_FILE_DATE_OFS = 14, + MZ_ZIP_CDH_CRC32_OFS = 16, + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS = 20, + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS = 24, + MZ_ZIP_CDH_FILENAME_LEN_OFS = 28, + MZ_ZIP_CDH_EXTRA_LEN_OFS = 30, + MZ_ZIP_CDH_COMMENT_LEN_OFS = 32, + MZ_ZIP_CDH_DISK_START_OFS = 34, + MZ_ZIP_CDH_INTERNAL_ATTR_OFS = 36, + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS = 38, + MZ_ZIP_CDH_LOCAL_HEADER_OFS = 42, + // Local directory header offsets + MZ_ZIP_LDH_SIG_OFS = 0, + MZ_ZIP_LDH_VERSION_NEEDED_OFS = 4, + MZ_ZIP_LDH_BIT_FLAG_OFS = 6, + MZ_ZIP_LDH_METHOD_OFS = 8, + MZ_ZIP_LDH_FILE_TIME_OFS = 10, + MZ_ZIP_LDH_FILE_DATE_OFS = 12, + MZ_ZIP_LDH_CRC32_OFS = 14, + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS = 18, + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS = 22, + MZ_ZIP_LDH_FILENAME_LEN_OFS = 26, + MZ_ZIP_LDH_EXTRA_LEN_OFS = 28, + // End of central directory offsets + MZ_ZIP_ECDH_SIG_OFS = 0, + MZ_ZIP_ECDH_NUM_THIS_DISK_OFS = 4, + MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS = 6, + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 8, + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS = 10, + MZ_ZIP_ECDH_CDIR_SIZE_OFS = 12, + MZ_ZIP_ECDH_CDIR_OFS_OFS = 16, + MZ_ZIP_ECDH_COMMENT_SIZE_OFS = 20, +}; + +typedef struct { + void *m_p; + size_t m_size, m_capacity; + mz_uint m_element_size; +} mz_zip_array; + +struct mz_zip_internal_state_tag { + mz_zip_array m_central_dir; + mz_zip_array m_central_dir_offsets; + mz_zip_array m_sorted_central_dir_offsets; + MZ_FILE *m_pFile; + void *m_pMem; + size_t m_mem_size; + size_t m_mem_capacity; +}; + +#define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size) \ + (array_ptr)->m_element_size = element_size +#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) \ + ((element_type *)((array_ptr)->m_p))[index] + +static MZ_FORCEINLINE void mz_zip_array_clear(mz_zip_archive *pZip, + mz_zip_array *pArray) { + pZip->m_pFree(pZip->m_pAlloc_opaque, pArray->m_p); + memset(pArray, 0, sizeof(mz_zip_array)); +} + +static mz_bool mz_zip_array_ensure_capacity(mz_zip_archive *pZip, + mz_zip_array *pArray, + size_t min_new_capacity, + mz_uint growing) { + void *pNew_p; + size_t new_capacity = min_new_capacity; + MZ_ASSERT(pArray->m_element_size); + if (pArray->m_capacity >= min_new_capacity) return MZ_TRUE; + if (growing) { + new_capacity = MZ_MAX(1, pArray->m_capacity); + while (new_capacity < min_new_capacity) new_capacity *= 2; + } + if (NULL == (pNew_p = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pArray->m_p, + pArray->m_element_size, new_capacity))) + return MZ_FALSE; + pArray->m_p = pNew_p; + pArray->m_capacity = new_capacity; + return MZ_TRUE; +} + +static MZ_FORCEINLINE mz_bool mz_zip_array_reserve(mz_zip_archive *pZip, + mz_zip_array *pArray, + size_t new_capacity, + mz_uint growing) { + if (new_capacity > pArray->m_capacity) { + if (!mz_zip_array_ensure_capacity(pZip, pArray, new_capacity, growing)) + return MZ_FALSE; + } + return MZ_TRUE; +} + +static MZ_FORCEINLINE mz_bool mz_zip_array_resize(mz_zip_archive *pZip, + mz_zip_array *pArray, + size_t new_size, + mz_uint growing) { + if (new_size > pArray->m_capacity) { + if (!mz_zip_array_ensure_capacity(pZip, pArray, new_size, growing)) + return MZ_FALSE; + } + pArray->m_size = new_size; + return MZ_TRUE; +} + +static MZ_FORCEINLINE mz_bool mz_zip_array_ensure_room(mz_zip_archive *pZip, + mz_zip_array *pArray, + size_t n) { + return mz_zip_array_reserve(pZip, pArray, pArray->m_size + n, MZ_TRUE); +} + +static MZ_FORCEINLINE mz_bool mz_zip_array_push_back(mz_zip_archive *pZip, + mz_zip_array *pArray, + const void *pElements, + size_t n) { + size_t orig_size = pArray->m_size; + if (!mz_zip_array_resize(pZip, pArray, orig_size + n, MZ_TRUE)) + return MZ_FALSE; + memcpy((mz_uint8 *)pArray->m_p + orig_size * pArray->m_element_size, + pElements, n * pArray->m_element_size); + return MZ_TRUE; +} + +#ifndef MINIZ_NO_TIME +static time_t mz_zip_dos_to_time_t(int dos_time, int dos_date) { + struct tm tm; + memset(&tm, 0, sizeof(tm)); + tm.tm_isdst = -1; + tm.tm_year = ((dos_date >> 9) & 127) + 1980 - 1900; + tm.tm_mon = ((dos_date >> 5) & 15) - 1; + tm.tm_mday = dos_date & 31; + tm.tm_hour = (dos_time >> 11) & 31; + tm.tm_min = (dos_time >> 5) & 63; + tm.tm_sec = (dos_time << 1) & 62; + return mktime(&tm); +} + +static void mz_zip_time_to_dos_time(time_t time, mz_uint16 *pDOS_time, + mz_uint16 *pDOS_date) { +#ifdef _MSC_VER + struct tm tm_struct; + struct tm *tm = &tm_struct; + errno_t err = localtime_s(tm, &time); + if (err) { + *pDOS_date = 0; + *pDOS_time = 0; + return; + } +#else + struct tm *tm = localtime(&time); +#endif + *pDOS_time = (mz_uint16)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) + + ((tm->tm_sec) >> 1)); + *pDOS_date = (mz_uint16)(((tm->tm_year + 1900 - 1980) << 9) + + ((tm->tm_mon + 1) << 5) + tm->tm_mday); +} +#endif + +#ifndef MINIZ_NO_STDIO +static mz_bool mz_zip_get_file_modified_time(const char *pFilename, + mz_uint16 *pDOS_time, + mz_uint16 *pDOS_date) { +#ifdef MINIZ_NO_TIME + (void)pFilename; + *pDOS_date = *pDOS_time = 0; +#else + struct MZ_FILE_STAT_STRUCT file_stat; + // On Linux with x86 glibc, this call will fail on large files (>= 0x80000000 + // bytes) unless you compiled with _LARGEFILE64_SOURCE. Argh. + if (MZ_FILE_STAT(pFilename, &file_stat) != 0) return MZ_FALSE; + mz_zip_time_to_dos_time(file_stat.st_mtime, pDOS_time, pDOS_date); +#endif // #ifdef MINIZ_NO_TIME + return MZ_TRUE; +} + +#ifndef MINIZ_NO_TIME +static mz_bool mz_zip_set_file_times(const char *pFilename, time_t access_time, + time_t modified_time) { + struct utimbuf t; + t.actime = access_time; + t.modtime = modified_time; + return !utime(pFilename, &t); +} +#endif // #ifndef MINIZ_NO_TIME +#endif // #ifndef MINIZ_NO_STDIO + +static mz_bool mz_zip_reader_init_internal(mz_zip_archive *pZip, + mz_uint32 flags) { + (void)flags; + if ((!pZip) || (pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID)) + return MZ_FALSE; + + if (!pZip->m_pAlloc) pZip->m_pAlloc = def_alloc_func; + if (!pZip->m_pFree) pZip->m_pFree = def_free_func; + if (!pZip->m_pRealloc) pZip->m_pRealloc = def_realloc_func; + + pZip->m_zip_mode = MZ_ZIP_MODE_READING; + pZip->m_archive_size = 0; + pZip->m_central_directory_file_ofs = 0; + pZip->m_total_files = 0; + + if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc( + pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state)))) + return MZ_FALSE; + memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state)); + MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, + sizeof(mz_uint8)); + MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, + sizeof(mz_uint32)); + MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets, + sizeof(mz_uint32)); + return MZ_TRUE; +} + +static MZ_FORCEINLINE mz_bool +mz_zip_reader_filename_less(const mz_zip_array *pCentral_dir_array, + const mz_zip_array *pCentral_dir_offsets, + mz_uint l_index, mz_uint r_index) { + const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT( + pCentral_dir_array, mz_uint8, + MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, + l_index)), + *pE; + const mz_uint8 *pR = &MZ_ZIP_ARRAY_ELEMENT( + pCentral_dir_array, mz_uint8, + MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, r_index)); + mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS), + r_len = MZ_READ_LE16(pR + MZ_ZIP_CDH_FILENAME_LEN_OFS); + mz_uint8 l = 0, r = 0; + pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; + pR += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; + pE = pL + MZ_MIN(l_len, r_len); + while (pL < pE) { + if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR))) break; + pL++; + pR++; + } + return (pL == pE) ? (l_len < r_len) : (l < r); +} + +#define MZ_SWAP_UINT32(a, b) \ + do { \ + mz_uint32 t = a; \ + a = b; \ + b = t; \ + } \ + MZ_MACRO_END + +// Heap sort of lowercased filenames, used to help accelerate plain central +// directory searches by mz_zip_reader_locate_file(). (Could also use qsort(), +// but it could allocate memory.) +static void mz_zip_reader_sort_central_dir_offsets_by_filename( + mz_zip_archive *pZip) { + mz_zip_internal_state *pState = pZip->m_pState; + const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets; + const mz_zip_array *pCentral_dir = &pState->m_central_dir; + mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT( + &pState->m_sorted_central_dir_offsets, mz_uint32, 0); + const int size = pZip->m_total_files; + int start = (size - 2) >> 1, end; + while (start >= 0) { + int child, root = start; + for (;;) { + if ((child = (root << 1) + 1) >= size) break; + child += + (((child + 1) < size) && + (mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, + pIndices[child], pIndices[child + 1]))); + if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, + pIndices[root], pIndices[child])) + break; + MZ_SWAP_UINT32(pIndices[root], pIndices[child]); + root = child; + } + start--; + } + + end = size - 1; + while (end > 0) { + int child, root = 0; + MZ_SWAP_UINT32(pIndices[end], pIndices[0]); + for (;;) { + if ((child = (root << 1) + 1) >= end) break; + child += + (((child + 1) < end) && + mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, + pIndices[child], pIndices[child + 1])); + if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, + pIndices[root], pIndices[child])) + break; + MZ_SWAP_UINT32(pIndices[root], pIndices[child]); + root = child; + } + end--; + } +} + +static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, + mz_uint32 flags) { + mz_uint cdir_size, num_this_disk, cdir_disk_index; + mz_uint64 cdir_ofs; + mz_int64 cur_file_ofs; + const mz_uint8 *p; + mz_uint32 buf_u32[4096 / sizeof(mz_uint32)]; + mz_uint8 *pBuf = (mz_uint8 *)buf_u32; + mz_bool sort_central_dir = + ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0); + // Basic sanity checks - reject files which are too small, and check the first + // 4 bytes of the file to make sure a local header is there. + if (pZip->m_archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) + return MZ_FALSE; + // Find the end of central directory record by scanning the file from the end + // towards the beginning. + cur_file_ofs = + MZ_MAX((mz_int64)pZip->m_archive_size - (mz_int64)sizeof(buf_u32), 0); + for (;;) { + int i, + n = (int)MZ_MIN(sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs); + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n) + return MZ_FALSE; + for (i = n - 4; i >= 0; --i) + if (MZ_READ_LE32(pBuf + i) == MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) break; + if (i >= 0) { + cur_file_ofs += i; + break; + } + if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >= + (0xFFFF + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE))) + return MZ_FALSE; + cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0); + } + // Read and verify the end of central directory record. + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) + return MZ_FALSE; + if ((MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) != + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) || + ((pZip->m_total_files = + MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS)) != + MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS))) + return MZ_FALSE; + + num_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_THIS_DISK_OFS); + cdir_disk_index = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS); + if (((num_this_disk | cdir_disk_index) != 0) && + ((num_this_disk != 1) || (cdir_disk_index != 1))) + return MZ_FALSE; + + if ((cdir_size = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_SIZE_OFS)) < + pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) + return MZ_FALSE; + + cdir_ofs = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS); + if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size) return MZ_FALSE; + + pZip->m_central_directory_file_ofs = cdir_ofs; + + if (pZip->m_total_files) { + mz_uint i, n; + + // Read the entire central directory into a heap block, and allocate another + // heap block to hold the unsorted central dir file record offsets, and + // another to hold the sorted indices. + if ((!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir, cdir_size, + MZ_FALSE)) || + (!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir_offsets, + pZip->m_total_files, MZ_FALSE))) + return MZ_FALSE; + + if (sort_central_dir) { + if (!mz_zip_array_resize(pZip, + &pZip->m_pState->m_sorted_central_dir_offsets, + pZip->m_total_files, MZ_FALSE)) + return MZ_FALSE; + } + + if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs, + pZip->m_pState->m_central_dir.m_p, + cdir_size) != cdir_size) + return MZ_FALSE; + + // Now create an index into the central directory file records, do some + // basic sanity checking on each record, and check for zip64 entries (which + // are not yet supported). + p = (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p; + for (n = cdir_size, i = 0; i < pZip->m_total_files; ++i) { + mz_uint total_header_size, comp_size, decomp_size, disk_index; + if ((n < MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) || + (MZ_READ_LE32(p) != MZ_ZIP_CENTRAL_DIR_HEADER_SIG)) + return MZ_FALSE; + MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, + i) = + (mz_uint32)(p - (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p); + if (sort_central_dir) + MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_sorted_central_dir_offsets, + mz_uint32, i) = i; + comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); + decomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS); + if (((!MZ_READ_LE32(p + MZ_ZIP_CDH_METHOD_OFS)) && + (decomp_size != comp_size)) || + (decomp_size && !comp_size) || (decomp_size == 0xFFFFFFFF) || + (comp_size == 0xFFFFFFFF)) + return MZ_FALSE; + disk_index = MZ_READ_LE16(p + MZ_ZIP_CDH_DISK_START_OFS); + if ((disk_index != num_this_disk) && (disk_index != 1)) return MZ_FALSE; + if (((mz_uint64)MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS) + + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + comp_size) > pZip->m_archive_size) + return MZ_FALSE; + if ((total_header_size = MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS) + + MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS)) > + n) + return MZ_FALSE; + n -= total_header_size; + p += total_header_size; + } + } + + if (sort_central_dir) + mz_zip_reader_sort_central_dir_offsets_by_filename(pZip); + + return MZ_TRUE; +} + +mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, + mz_uint32 flags) { + if ((!pZip) || (!pZip->m_pRead)) return MZ_FALSE; + if (!mz_zip_reader_init_internal(pZip, flags)) return MZ_FALSE; + pZip->m_archive_size = size; + if (!mz_zip_reader_read_central_dir(pZip, flags)) { + mz_zip_reader_end(pZip); + return MZ_FALSE; + } + return MZ_TRUE; +} + +static size_t mz_zip_mem_read_func(void *pOpaque, mz_uint64 file_ofs, + void *pBuf, size_t n) { + mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; + size_t s = (file_ofs >= pZip->m_archive_size) + ? 0 + : (size_t)MZ_MIN(pZip->m_archive_size - file_ofs, n); + memcpy(pBuf, (const mz_uint8 *)pZip->m_pState->m_pMem + file_ofs, s); + return s; +} + +mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, + size_t size, mz_uint32 flags) { + if (!mz_zip_reader_init_internal(pZip, flags)) return MZ_FALSE; + pZip->m_archive_size = size; + pZip->m_pRead = mz_zip_mem_read_func; + pZip->m_pIO_opaque = pZip; +#ifdef __cplusplus + pZip->m_pState->m_pMem = const_cast(pMem); +#else + pZip->m_pState->m_pMem = (void *)pMem; +#endif + pZip->m_pState->m_mem_size = size; + if (!mz_zip_reader_read_central_dir(pZip, flags)) { + mz_zip_reader_end(pZip); + return MZ_FALSE; + } + return MZ_TRUE; +} + +#ifndef MINIZ_NO_STDIO +static size_t mz_zip_file_read_func(void *pOpaque, mz_uint64 file_ofs, + void *pBuf, size_t n) { + mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; + mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile); + if (((mz_int64)file_ofs < 0) || + (((cur_ofs != (mz_int64)file_ofs)) && + (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET)))) + return 0; + return MZ_FREAD(pBuf, 1, n, pZip->m_pState->m_pFile); +} + +mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, + mz_uint32 flags) { + mz_uint64 file_size; + MZ_FILE *pFile = MZ_FOPEN(pFilename, "rb"); + if (!pFile) return MZ_FALSE; + if (MZ_FSEEK64(pFile, 0, SEEK_END)) { + MZ_FCLOSE(pFile); + return MZ_FALSE; + } + file_size = MZ_FTELL64(pFile); + if (!mz_zip_reader_init_internal(pZip, flags)) { + MZ_FCLOSE(pFile); + return MZ_FALSE; + } + pZip->m_pRead = mz_zip_file_read_func; + pZip->m_pIO_opaque = pZip; + pZip->m_pState->m_pFile = pFile; + pZip->m_archive_size = file_size; + if (!mz_zip_reader_read_central_dir(pZip, flags)) { + mz_zip_reader_end(pZip); + return MZ_FALSE; + } + return MZ_TRUE; +} +#endif // #ifndef MINIZ_NO_STDIO + +mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip) { + return pZip ? pZip->m_total_files : 0; +} + +static MZ_FORCEINLINE const mz_uint8 *mz_zip_reader_get_cdh( + mz_zip_archive *pZip, mz_uint file_index) { + if ((!pZip) || (!pZip->m_pState) || (file_index >= pZip->m_total_files) || + (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) + return NULL; + return &MZ_ZIP_ARRAY_ELEMENT( + &pZip->m_pState->m_central_dir, mz_uint8, + MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, + file_index)); +} + +mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, + mz_uint file_index) { + mz_uint m_bit_flag; + const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index); + if (!p) return MZ_FALSE; + m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS); + return (m_bit_flag & 1); +} + +mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, + mz_uint file_index) { + mz_uint filename_len, external_attr; + const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index); + if (!p) return MZ_FALSE; + + // First see if the filename ends with a '/' character. + filename_len = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); + if (filename_len) { + if (*(p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_len - 1) == '/') + return MZ_TRUE; + } + + // Bugfix: This code was also checking if the internal attribute was non-zero, + // which wasn't correct. + // Most/all zip writers (hopefully) set DOS file/directory attributes in the + // low 16-bits, so check for the DOS directory flag and ignore the source OS + // ID in the created by field. + // FIXME: Remove this check? Is it necessary - we already check the filename. + external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS); + if ((external_attr & 0x10) != 0) return MZ_TRUE; + + return MZ_FALSE; +} + +mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, + mz_zip_archive_file_stat *pStat) { + mz_uint n; + const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index); + if ((!p) || (!pStat)) return MZ_FALSE; + + // Unpack the central directory record. + pStat->m_file_index = file_index; + pStat->m_central_dir_ofs = MZ_ZIP_ARRAY_ELEMENT( + &pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index); + pStat->m_version_made_by = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS); + pStat->m_version_needed = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_NEEDED_OFS); + pStat->m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS); + pStat->m_method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS); +#ifndef MINIZ_NO_TIME + pStat->m_time = + mz_zip_dos_to_time_t(MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_TIME_OFS), + MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_DATE_OFS)); +#endif + pStat->m_crc32 = MZ_READ_LE32(p + MZ_ZIP_CDH_CRC32_OFS); + pStat->m_comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); + pStat->m_uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS); + pStat->m_internal_attr = MZ_READ_LE16(p + MZ_ZIP_CDH_INTERNAL_ATTR_OFS); + pStat->m_external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS); + pStat->m_local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS); + + // Copy as much of the filename and comment as possible. + n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); + n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE - 1); + memcpy(pStat->m_filename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n); + pStat->m_filename[n] = '\0'; + + n = MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS); + n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE - 1); + pStat->m_comment_size = n; + memcpy(pStat->m_comment, + p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS), + n); + pStat->m_comment[n] = '\0'; + + return MZ_TRUE; +} + +mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, + char *pFilename, mz_uint filename_buf_size) { + mz_uint n; + const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index); + if (!p) { + if (filename_buf_size) pFilename[0] = '\0'; + return 0; + } + n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); + if (filename_buf_size) { + n = MZ_MIN(n, filename_buf_size - 1); + memcpy(pFilename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n); + pFilename[n] = '\0'; + } + return n + 1; +} + +static MZ_FORCEINLINE mz_bool mz_zip_reader_string_equal(const char *pA, + const char *pB, + mz_uint len, + mz_uint flags) { + mz_uint i; + if (flags & MZ_ZIP_FLAG_CASE_SENSITIVE) return 0 == memcmp(pA, pB, len); + for (i = 0; i < len; ++i) + if (MZ_TOLOWER(pA[i]) != MZ_TOLOWER(pB[i])) return MZ_FALSE; + return MZ_TRUE; +} + +static MZ_FORCEINLINE int mz_zip_reader_filename_compare( + const mz_zip_array *pCentral_dir_array, + const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, const char *pR, + mz_uint r_len) { + const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT( + pCentral_dir_array, mz_uint8, + MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, + l_index)), + *pE; + mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS); + mz_uint8 l = 0, r = 0; + pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; + pE = pL + MZ_MIN(l_len, r_len); + while (pL < pE) { + if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR))) break; + pL++; + pR++; + } + return (pL == pE) ? (int)(l_len - r_len) : (l - r); +} + +static int mz_zip_reader_locate_file_binary_search(mz_zip_archive *pZip, + const char *pFilename) { + mz_zip_internal_state *pState = pZip->m_pState; + const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets; + const mz_zip_array *pCentral_dir = &pState->m_central_dir; + mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT( + &pState->m_sorted_central_dir_offsets, mz_uint32, 0); + const int size = pZip->m_total_files; + const mz_uint filename_len = (mz_uint)strlen(pFilename); + int l = 0, h = size - 1; + while (l <= h) { + int m = (l + h) >> 1, file_index = pIndices[m], + comp = + mz_zip_reader_filename_compare(pCentral_dir, pCentral_dir_offsets, + file_index, pFilename, filename_len); + if (!comp) + return file_index; + else if (comp < 0) + l = m + 1; + else + h = m - 1; + } + return -1; +} + +int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, + const char *pComment, mz_uint flags) { + mz_uint file_index; + size_t name_len, comment_len; + if ((!pZip) || (!pZip->m_pState) || (!pName) || + (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) + return -1; + if (((flags & (MZ_ZIP_FLAG_IGNORE_PATH | MZ_ZIP_FLAG_CASE_SENSITIVE)) == 0) && + (!pComment) && (pZip->m_pState->m_sorted_central_dir_offsets.m_size)) + return mz_zip_reader_locate_file_binary_search(pZip, pName); + name_len = strlen(pName); + if (name_len > 0xFFFF) return -1; + comment_len = pComment ? strlen(pComment) : 0; + if (comment_len > 0xFFFF) return -1; + for (file_index = 0; file_index < pZip->m_total_files; file_index++) { + const mz_uint8 *pHeader = &MZ_ZIP_ARRAY_ELEMENT( + &pZip->m_pState->m_central_dir, mz_uint8, + MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, + file_index)); + mz_uint filename_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_FILENAME_LEN_OFS); + const char *pFilename = + (const char *)pHeader + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; + if (filename_len < name_len) continue; + if (comment_len) { + mz_uint file_extra_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_EXTRA_LEN_OFS), + file_comment_len = + MZ_READ_LE16(pHeader + MZ_ZIP_CDH_COMMENT_LEN_OFS); + const char *pFile_comment = pFilename + filename_len + file_extra_len; + if ((file_comment_len != comment_len) || + (!mz_zip_reader_string_equal(pComment, pFile_comment, + file_comment_len, flags))) + continue; + } + if ((flags & MZ_ZIP_FLAG_IGNORE_PATH) && (filename_len)) { + int ofs = filename_len - 1; + do { + if ((pFilename[ofs] == '/') || (pFilename[ofs] == '\\') || + (pFilename[ofs] == ':')) + break; + } while (--ofs >= 0); + ofs++; + pFilename += ofs; + filename_len -= ofs; + } + if ((filename_len == name_len) && + (mz_zip_reader_string_equal(pName, pFilename, filename_len, flags))) + return file_index; + } + return -1; +} + +mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, + mz_uint file_index, void *pBuf, + size_t buf_size, mz_uint flags, + void *pUser_read_buf, + size_t user_read_buf_size) { + int status = TINFL_STATUS_DONE; + mz_uint64 needed_size, cur_file_ofs, comp_remaining, + out_buf_ofs = 0, read_buf_size, read_buf_ofs = 0, read_buf_avail; + mz_zip_archive_file_stat file_stat; + void *pRead_buf; + mz_uint32 + local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / + sizeof(mz_uint32)]; + mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; + tinfl_decompressor inflator; + + if ((buf_size) && (!pBuf)) return MZ_FALSE; + + if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) return MZ_FALSE; + + // Empty file, or a directory (but not always a directory - I've seen odd zips + // with directories that have compressed data which inflates to 0 bytes) + if (!file_stat.m_comp_size) return MZ_TRUE; + + // Entry is a subdirectory (I've seen old zips with dir entries which have + // compressed deflate data which inflates to 0 bytes, but these entries claim + // to uncompress to 512 bytes in the headers). + // I'm torn how to handle this case - should it fail instead? + if (mz_zip_reader_is_file_a_directory(pZip, file_index)) return MZ_TRUE; + + // Encryption and patch files are not supported. + if (file_stat.m_bit_flag & (1 | 32)) return MZ_FALSE; + + // This function only supports stored and deflate. + if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && + (file_stat.m_method != MZ_DEFLATED)) + return MZ_FALSE; + + // Ensure supplied output buffer is large enough. + needed_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size + : file_stat.m_uncomp_size; + if (buf_size < needed_size) return MZ_FALSE; + + // Read and parse the local directory entry. + cur_file_ofs = file_stat.m_local_header_ofs; + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, + MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != + MZ_ZIP_LOCAL_DIR_HEADER_SIZE) + return MZ_FALSE; + if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) + return MZ_FALSE; + + cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); + if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size) + return MZ_FALSE; + + if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) { + // The file is stored or the caller has requested the compressed data. + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, + (size_t)needed_size) != needed_size) + return MZ_FALSE; + return ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) != 0) || + (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, + (size_t)file_stat.m_uncomp_size) == file_stat.m_crc32); + } + + // Decompress the file either directly from memory or from a file input + // buffer. + tinfl_init(&inflator); + + if (pZip->m_pState->m_pMem) { + // Read directly from the archive in memory. + pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs; + read_buf_size = read_buf_avail = file_stat.m_comp_size; + comp_remaining = 0; + } else if (pUser_read_buf) { + // Use a user provided read buffer. + if (!user_read_buf_size) return MZ_FALSE; + pRead_buf = (mz_uint8 *)pUser_read_buf; + read_buf_size = user_read_buf_size; + read_buf_avail = 0; + comp_remaining = file_stat.m_comp_size; + } else { + // Temporarily allocate a read buffer. + read_buf_size = + MZ_MIN(file_stat.m_comp_size, (mz_uint)MZ_ZIP_MAX_IO_BUF_SIZE); +#ifdef _MSC_VER + if (((0, sizeof(size_t) == sizeof(mz_uint32))) && + (read_buf_size > 0x7FFFFFFF)) +#else + if (((sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF)) +#endif + return MZ_FALSE; + if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, + (size_t)read_buf_size))) + return MZ_FALSE; + read_buf_avail = 0; + comp_remaining = file_stat.m_comp_size; + } + + do { + size_t in_buf_size, + out_buf_size = (size_t)(file_stat.m_uncomp_size - out_buf_ofs); + if ((!read_buf_avail) && (!pZip->m_pState->m_pMem)) { + read_buf_avail = MZ_MIN(read_buf_size, comp_remaining); + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, + (size_t)read_buf_avail) != read_buf_avail) { + status = TINFL_STATUS_FAILED; + break; + } + cur_file_ofs += read_buf_avail; + comp_remaining -= read_buf_avail; + read_buf_ofs = 0; + } + in_buf_size = (size_t)read_buf_avail; + status = tinfl_decompress( + &inflator, (mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, + (mz_uint8 *)pBuf, (mz_uint8 *)pBuf + out_buf_ofs, &out_buf_size, + TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF | + (comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0)); + read_buf_avail -= in_buf_size; + read_buf_ofs += in_buf_size; + out_buf_ofs += out_buf_size; + } while (status == TINFL_STATUS_NEEDS_MORE_INPUT); + + if (status == TINFL_STATUS_DONE) { + // Make sure the entire file was decompressed, and check its CRC. + if ((out_buf_ofs != file_stat.m_uncomp_size) || + (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, + (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32)) + status = TINFL_STATUS_FAILED; + } + + if ((!pZip->m_pState->m_pMem) && (!pUser_read_buf)) + pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); + + return status == TINFL_STATUS_DONE; +} + +mz_bool mz_zip_reader_extract_file_to_mem_no_alloc( + mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, + mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size) { + int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags); + if (file_index < 0) return MZ_FALSE; + return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, + flags, pUser_read_buf, + user_read_buf_size); +} + +mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, + void *pBuf, size_t buf_size, + mz_uint flags) { + return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, + flags, NULL, 0); +} + +mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, + const char *pFilename, void *pBuf, + size_t buf_size, mz_uint flags) { + return mz_zip_reader_extract_file_to_mem_no_alloc(pZip, pFilename, pBuf, + buf_size, flags, NULL, 0); +} + +void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, + size_t *pSize, mz_uint flags) { + mz_uint64 comp_size, uncomp_size, alloc_size; + const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index); + void *pBuf; + + if (pSize) *pSize = 0; + if (!p) return NULL; + + comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); + uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS); + + alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? comp_size : uncomp_size; +#ifdef _MSC_VER + if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF)) +#else + if (((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF)) +#endif + return NULL; + if (NULL == + (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)alloc_size))) + return NULL; + + if (!mz_zip_reader_extract_to_mem(pZip, file_index, pBuf, (size_t)alloc_size, + flags)) { + pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); + return NULL; + } + + if (pSize) *pSize = (size_t)alloc_size; + return pBuf; +} + +void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, + const char *pFilename, size_t *pSize, + mz_uint flags) { + int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags); + if (file_index < 0) { + if (pSize) *pSize = 0; + return MZ_FALSE; + } + return mz_zip_reader_extract_to_heap(pZip, file_index, pSize, flags); +} + +mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, + mz_uint file_index, + mz_file_write_func pCallback, + void *pOpaque, mz_uint flags) { + int status = TINFL_STATUS_DONE; + mz_uint file_crc32 = MZ_CRC32_INIT; + mz_uint64 read_buf_size, read_buf_ofs = 0, read_buf_avail, comp_remaining, + out_buf_ofs = 0, cur_file_ofs; + mz_zip_archive_file_stat file_stat; + void *pRead_buf = NULL; + void *pWrite_buf = NULL; + mz_uint32 + local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / + sizeof(mz_uint32)]; + mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; + + if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) return MZ_FALSE; + + // Empty file, or a directory (but not always a directory - I've seen odd zips + // with directories that have compressed data which inflates to 0 bytes) + if (!file_stat.m_comp_size) return MZ_TRUE; + + // Entry is a subdirectory (I've seen old zips with dir entries which have + // compressed deflate data which inflates to 0 bytes, but these entries claim + // to uncompress to 512 bytes in the headers). + // I'm torn how to handle this case - should it fail instead? + if (mz_zip_reader_is_file_a_directory(pZip, file_index)) return MZ_TRUE; + + // Encryption and patch files are not supported. + if (file_stat.m_bit_flag & (1 | 32)) return MZ_FALSE; + + // This function only supports stored and deflate. + if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && + (file_stat.m_method != MZ_DEFLATED)) + return MZ_FALSE; + + // Read and parse the local directory entry. + cur_file_ofs = file_stat.m_local_header_ofs; + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, + MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != + MZ_ZIP_LOCAL_DIR_HEADER_SIZE) + return MZ_FALSE; + if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) + return MZ_FALSE; + + cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); + if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size) + return MZ_FALSE; + + // Decompress the file either directly from memory or from a file input + // buffer. + if (pZip->m_pState->m_pMem) { + pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs; + read_buf_size = read_buf_avail = file_stat.m_comp_size; + comp_remaining = 0; + } else { + read_buf_size = + MZ_MIN(file_stat.m_comp_size, (mz_uint)MZ_ZIP_MAX_IO_BUF_SIZE); + if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, + (size_t)read_buf_size))) + return MZ_FALSE; + read_buf_avail = 0; + comp_remaining = file_stat.m_comp_size; + } + + if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) { + // The file is stored or the caller has requested the compressed data. + if (pZip->m_pState->m_pMem) { +#ifdef _MSC_VER + if (((0, sizeof(size_t) == sizeof(mz_uint32))) && + (file_stat.m_comp_size > 0xFFFFFFFF)) +#else + if (((sizeof(size_t) == sizeof(mz_uint32))) && + (file_stat.m_comp_size > 0xFFFFFFFF)) +#endif + return MZ_FALSE; + if (pCallback(pOpaque, out_buf_ofs, pRead_buf, + (size_t)file_stat.m_comp_size) != file_stat.m_comp_size) + status = TINFL_STATUS_FAILED; + else if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) + file_crc32 = + (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, + (size_t)file_stat.m_comp_size); + cur_file_ofs += file_stat.m_comp_size; + out_buf_ofs += file_stat.m_comp_size; + comp_remaining = 0; + } else { + while (comp_remaining) { + read_buf_avail = MZ_MIN(read_buf_size, comp_remaining); + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, + (size_t)read_buf_avail) != read_buf_avail) { + status = TINFL_STATUS_FAILED; + break; + } + + if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) + file_crc32 = (mz_uint32)mz_crc32( + file_crc32, (const mz_uint8 *)pRead_buf, (size_t)read_buf_avail); + + if (pCallback(pOpaque, out_buf_ofs, pRead_buf, + (size_t)read_buf_avail) != read_buf_avail) { + status = TINFL_STATUS_FAILED; + break; + } + cur_file_ofs += read_buf_avail; + out_buf_ofs += read_buf_avail; + comp_remaining -= read_buf_avail; + } + } + } else { + tinfl_decompressor inflator; + tinfl_init(&inflator); + + if (NULL == (pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, + TINFL_LZ_DICT_SIZE))) + status = TINFL_STATUS_FAILED; + else { + do { + mz_uint8 *pWrite_buf_cur = + (mz_uint8 *)pWrite_buf + (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1)); + size_t in_buf_size, + out_buf_size = + TINFL_LZ_DICT_SIZE - (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1)); + if ((!read_buf_avail) && (!pZip->m_pState->m_pMem)) { + read_buf_avail = MZ_MIN(read_buf_size, comp_remaining); + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, + (size_t)read_buf_avail) != read_buf_avail) { + status = TINFL_STATUS_FAILED; + break; + } + cur_file_ofs += read_buf_avail; + comp_remaining -= read_buf_avail; + read_buf_ofs = 0; + } + + in_buf_size = (size_t)read_buf_avail; + status = tinfl_decompress( + &inflator, (const mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, + (mz_uint8 *)pWrite_buf, pWrite_buf_cur, &out_buf_size, + comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0); + read_buf_avail -= in_buf_size; + read_buf_ofs += in_buf_size; + + if (out_buf_size) { + if (pCallback(pOpaque, out_buf_ofs, pWrite_buf_cur, out_buf_size) != + out_buf_size) { + status = TINFL_STATUS_FAILED; + break; + } + file_crc32 = + (mz_uint32)mz_crc32(file_crc32, pWrite_buf_cur, out_buf_size); + if ((out_buf_ofs += out_buf_size) > file_stat.m_uncomp_size) { + status = TINFL_STATUS_FAILED; + break; + } + } + } while ((status == TINFL_STATUS_NEEDS_MORE_INPUT) || + (status == TINFL_STATUS_HAS_MORE_OUTPUT)); + } + } + + if ((status == TINFL_STATUS_DONE) && + (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))) { + // Make sure the entire file was decompressed, and check its CRC. + if ((out_buf_ofs != file_stat.m_uncomp_size) || + (file_crc32 != file_stat.m_crc32)) + status = TINFL_STATUS_FAILED; + } + + if (!pZip->m_pState->m_pMem) pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); + if (pWrite_buf) pZip->m_pFree(pZip->m_pAlloc_opaque, pWrite_buf); + + return status == TINFL_STATUS_DONE; +} + +mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, + const char *pFilename, + mz_file_write_func pCallback, + void *pOpaque, mz_uint flags) { + int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags); + if (file_index < 0) return MZ_FALSE; + return mz_zip_reader_extract_to_callback(pZip, file_index, pCallback, pOpaque, + flags); +} + +#ifndef MINIZ_NO_STDIO +static size_t mz_zip_file_write_callback(void *pOpaque, mz_uint64 ofs, + const void *pBuf, size_t n) { + (void)ofs; + return MZ_FWRITE(pBuf, 1, n, (MZ_FILE *)pOpaque); +} + +mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, + const char *pDst_filename, + mz_uint flags) { + mz_bool status; + mz_zip_archive_file_stat file_stat; + MZ_FILE *pFile; + if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) return MZ_FALSE; + pFile = MZ_FOPEN(pDst_filename, "wb"); + if (!pFile) return MZ_FALSE; + status = mz_zip_reader_extract_to_callback( + pZip, file_index, mz_zip_file_write_callback, pFile, flags); + if (MZ_FCLOSE(pFile) == EOF) return MZ_FALSE; +#ifndef MINIZ_NO_TIME + if (status) + mz_zip_set_file_times(pDst_filename, file_stat.m_time, file_stat.m_time); +#endif + return status; +} +#endif // #ifndef MINIZ_NO_STDIO + +mz_bool mz_zip_reader_end(mz_zip_archive *pZip) { + if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || + (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) + return MZ_FALSE; + + if (pZip->m_pState) { + mz_zip_internal_state *pState = pZip->m_pState; + pZip->m_pState = NULL; + mz_zip_array_clear(pZip, &pState->m_central_dir); + mz_zip_array_clear(pZip, &pState->m_central_dir_offsets); + mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets); + +#ifndef MINIZ_NO_STDIO + if (pState->m_pFile) { + MZ_FCLOSE(pState->m_pFile); + pState->m_pFile = NULL; + } +#endif // #ifndef MINIZ_NO_STDIO + + pZip->m_pFree(pZip->m_pAlloc_opaque, pState); + } + pZip->m_zip_mode = MZ_ZIP_MODE_INVALID; + + return MZ_TRUE; +} + +#ifndef MINIZ_NO_STDIO +mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, + const char *pArchive_filename, + const char *pDst_filename, + mz_uint flags) { + int file_index = + mz_zip_reader_locate_file(pZip, pArchive_filename, NULL, flags); + if (file_index < 0) return MZ_FALSE; + return mz_zip_reader_extract_to_file(pZip, file_index, pDst_filename, flags); +} +#endif + +// ------------------- .ZIP archive writing + +#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS + +static void mz_write_le16(mz_uint8 *p, mz_uint16 v) { + p[0] = (mz_uint8)v; + p[1] = (mz_uint8)(v >> 8); +} +static void mz_write_le32(mz_uint8 *p, mz_uint32 v) { + p[0] = (mz_uint8)v; + p[1] = (mz_uint8)(v >> 8); + p[2] = (mz_uint8)(v >> 16); + p[3] = (mz_uint8)(v >> 24); +} +#define MZ_WRITE_LE16(p, v) mz_write_le16((mz_uint8 *)(p), (mz_uint16)(v)) +#define MZ_WRITE_LE32(p, v) mz_write_le32((mz_uint8 *)(p), (mz_uint32)(v)) + +mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size) { + if ((!pZip) || (pZip->m_pState) || (!pZip->m_pWrite) || + (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID)) + return MZ_FALSE; + + if (pZip->m_file_offset_alignment) { + // Ensure user specified file offset alignment is a power of 2. + if (pZip->m_file_offset_alignment & (pZip->m_file_offset_alignment - 1)) + return MZ_FALSE; + } + + if (!pZip->m_pAlloc) pZip->m_pAlloc = def_alloc_func; + if (!pZip->m_pFree) pZip->m_pFree = def_free_func; + if (!pZip->m_pRealloc) pZip->m_pRealloc = def_realloc_func; + + pZip->m_zip_mode = MZ_ZIP_MODE_WRITING; + pZip->m_archive_size = existing_size; + pZip->m_central_directory_file_ofs = 0; + pZip->m_total_files = 0; + + if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc( + pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state)))) + return MZ_FALSE; + memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state)); + MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, + sizeof(mz_uint8)); + MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, + sizeof(mz_uint32)); + MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets, + sizeof(mz_uint32)); + return MZ_TRUE; +} + +static size_t mz_zip_heap_write_func(void *pOpaque, mz_uint64 file_ofs, + const void *pBuf, size_t n) { + mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; + mz_zip_internal_state *pState = pZip->m_pState; + mz_uint64 new_size = MZ_MAX(file_ofs + n, pState->m_mem_size); +#ifdef _MSC_VER + if ((!n) || + ((0, sizeof(size_t) == sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF))) +#else + if ((!n) || + ((sizeof(size_t) == sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF))) +#endif + return 0; + if (new_size > pState->m_mem_capacity) { + void *pNew_block; + size_t new_capacity = MZ_MAX(64, pState->m_mem_capacity); + while (new_capacity < new_size) new_capacity *= 2; + if (NULL == (pNew_block = pZip->m_pRealloc( + pZip->m_pAlloc_opaque, pState->m_pMem, 1, new_capacity))) + return 0; + pState->m_pMem = pNew_block; + pState->m_mem_capacity = new_capacity; + } + memcpy((mz_uint8 *)pState->m_pMem + file_ofs, pBuf, n); + pState->m_mem_size = (size_t)new_size; + return n; +} + +mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, + size_t size_to_reserve_at_beginning, + size_t initial_allocation_size) { + pZip->m_pWrite = mz_zip_heap_write_func; + pZip->m_pIO_opaque = pZip; + if (!mz_zip_writer_init(pZip, size_to_reserve_at_beginning)) return MZ_FALSE; + if (0 != (initial_allocation_size = MZ_MAX(initial_allocation_size, + size_to_reserve_at_beginning))) { + if (NULL == (pZip->m_pState->m_pMem = pZip->m_pAlloc( + pZip->m_pAlloc_opaque, 1, initial_allocation_size))) { + mz_zip_writer_end(pZip); + return MZ_FALSE; + } + pZip->m_pState->m_mem_capacity = initial_allocation_size; + } + return MZ_TRUE; +} + +#ifndef MINIZ_NO_STDIO +static size_t mz_zip_file_write_func(void *pOpaque, mz_uint64 file_ofs, + const void *pBuf, size_t n) { + mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; + mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile); + if (((mz_int64)file_ofs < 0) || + (((cur_ofs != (mz_int64)file_ofs)) && + (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET)))) + return 0; + return MZ_FWRITE(pBuf, 1, n, pZip->m_pState->m_pFile); +} + +mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, + mz_uint64 size_to_reserve_at_beginning) { + MZ_FILE *pFile; + pZip->m_pWrite = mz_zip_file_write_func; + pZip->m_pIO_opaque = pZip; + if (!mz_zip_writer_init(pZip, size_to_reserve_at_beginning)) return MZ_FALSE; + if (NULL == (pFile = MZ_FOPEN(pFilename, "wb"))) { + mz_zip_writer_end(pZip); + return MZ_FALSE; + } + pZip->m_pState->m_pFile = pFile; + if (size_to_reserve_at_beginning) { + mz_uint64 cur_ofs = 0; + char buf[4096]; + MZ_CLEAR_OBJ(buf); + do { + size_t n = (size_t)MZ_MIN(sizeof(buf), size_to_reserve_at_beginning); + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_ofs, buf, n) != n) { + mz_zip_writer_end(pZip); + return MZ_FALSE; + } + cur_ofs += n; + size_to_reserve_at_beginning -= n; + } while (size_to_reserve_at_beginning); + } + return MZ_TRUE; +} +#endif // #ifndef MINIZ_NO_STDIO + +mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, + const char *pFilename) { + mz_zip_internal_state *pState; + if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) + return MZ_FALSE; + // No sense in trying to write to an archive that's already at the support max + // size + if ((pZip->m_total_files == 0xFFFF) || + ((pZip->m_archive_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + + MZ_ZIP_LOCAL_DIR_HEADER_SIZE) > 0xFFFFFFFF)) + return MZ_FALSE; + + pState = pZip->m_pState; + + if (pState->m_pFile) { +#ifdef MINIZ_NO_STDIO + pFilename; + return MZ_FALSE; +#else + // Archive is being read from stdio - try to reopen as writable. + if (pZip->m_pIO_opaque != pZip) return MZ_FALSE; + if (!pFilename) return MZ_FALSE; + pZip->m_pWrite = mz_zip_file_write_func; + if (NULL == + (pState->m_pFile = MZ_FREOPEN(pFilename, "r+b", pState->m_pFile))) { + // The mz_zip_archive is now in a bogus state because pState->m_pFile is + // NULL, so just close it. + mz_zip_reader_end(pZip); + return MZ_FALSE; + } +#endif // #ifdef MINIZ_NO_STDIO + } else if (pState->m_pMem) { + // Archive lives in a memory block. Assume it's from the heap that we can + // resize using the realloc callback. + if (pZip->m_pIO_opaque != pZip) return MZ_FALSE; + pState->m_mem_capacity = pState->m_mem_size; + pZip->m_pWrite = mz_zip_heap_write_func; + } + // Archive is being read via a user provided read function - make sure the + // user has specified a write function too. + else if (!pZip->m_pWrite) + return MZ_FALSE; + + // Start writing new files at the archive's current central directory + // location. + pZip->m_archive_size = pZip->m_central_directory_file_ofs; + pZip->m_zip_mode = MZ_ZIP_MODE_WRITING; + pZip->m_central_directory_file_ofs = 0; + + return MZ_TRUE; +} + +mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, + const void *pBuf, size_t buf_size, + mz_uint level_and_flags) { + return mz_zip_writer_add_mem_ex(pZip, pArchive_name, pBuf, buf_size, NULL, 0, + level_and_flags, 0, 0); +} + +typedef struct { + mz_zip_archive *m_pZip; + mz_uint64 m_cur_archive_file_ofs; + mz_uint64 m_comp_size; +} mz_zip_writer_add_state; + +static mz_bool mz_zip_writer_add_put_buf_callback(const void *pBuf, int len, + void *pUser) { + mz_zip_writer_add_state *pState = (mz_zip_writer_add_state *)pUser; + if ((int)pState->m_pZip->m_pWrite(pState->m_pZip->m_pIO_opaque, + pState->m_cur_archive_file_ofs, pBuf, + len) != len) + return MZ_FALSE; + pState->m_cur_archive_file_ofs += len; + pState->m_comp_size += len; + return MZ_TRUE; +} + +static mz_bool mz_zip_writer_create_local_dir_header( + mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, + mz_uint16 extra_size, mz_uint64 uncomp_size, mz_uint64 comp_size, + mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, + mz_uint16 dos_time, mz_uint16 dos_date) { + (void)pZip; + memset(pDst, 0, MZ_ZIP_LOCAL_DIR_HEADER_SIZE); + MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_SIG_OFS, MZ_ZIP_LOCAL_DIR_HEADER_SIG); + MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_VERSION_NEEDED_OFS, method ? 20 : 0); + MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_BIT_FLAG_OFS, bit_flags); + MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_METHOD_OFS, method); + MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_TIME_OFS, dos_time); + MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_DATE_OFS, dos_date); + MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_CRC32_OFS, uncomp_crc32); + MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS, comp_size); + MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS, uncomp_size); + MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILENAME_LEN_OFS, filename_size); + MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_EXTRA_LEN_OFS, extra_size); + return MZ_TRUE; +} + +static mz_bool mz_zip_writer_create_central_dir_header( + mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, + mz_uint16 extra_size, mz_uint16 comment_size, mz_uint64 uncomp_size, + mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, + mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, + mz_uint64 local_header_ofs, mz_uint32 ext_attributes) { + (void)pZip; + memset(pDst, 0, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE); + MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_SIG_OFS, MZ_ZIP_CENTRAL_DIR_HEADER_SIG); + MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_VERSION_NEEDED_OFS, method ? 20 : 0); + MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_BIT_FLAG_OFS, bit_flags); + MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_METHOD_OFS, method); + MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_TIME_OFS, dos_time); + MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_DATE_OFS, dos_date); + MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_CRC32_OFS, uncomp_crc32); + MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS, comp_size); + MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS, uncomp_size); + MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILENAME_LEN_OFS, filename_size); + MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_EXTRA_LEN_OFS, extra_size); + MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_COMMENT_LEN_OFS, comment_size); + MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS, ext_attributes); + MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_LOCAL_HEADER_OFS, local_header_ofs); + return MZ_TRUE; +} + +static mz_bool mz_zip_writer_add_to_central_dir( + mz_zip_archive *pZip, const char *pFilename, mz_uint16 filename_size, + const void *pExtra, mz_uint16 extra_size, const void *pComment, + mz_uint16 comment_size, mz_uint64 uncomp_size, mz_uint64 comp_size, + mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, + mz_uint16 dos_time, mz_uint16 dos_date, mz_uint64 local_header_ofs, + mz_uint32 ext_attributes) { + mz_zip_internal_state *pState = pZip->m_pState; + mz_uint32 central_dir_ofs = (mz_uint32)pState->m_central_dir.m_size; + size_t orig_central_dir_size = pState->m_central_dir.m_size; + mz_uint8 central_dir_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE]; + + // No zip64 support yet + if ((local_header_ofs > 0xFFFFFFFF) || + (((mz_uint64)pState->m_central_dir.m_size + + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + extra_size + + comment_size) > 0xFFFFFFFF)) + return MZ_FALSE; + + if (!mz_zip_writer_create_central_dir_header( + pZip, central_dir_header, filename_size, extra_size, comment_size, + uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, + dos_date, local_header_ofs, ext_attributes)) + return MZ_FALSE; + + if ((!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_dir_header, + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) || + (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pFilename, + filename_size)) || + (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pExtra, + extra_size)) || + (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pComment, + comment_size)) || + (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, + ¢ral_dir_ofs, 1))) { + // Try to push the central directory array back into its original state. + mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, + MZ_FALSE); + return MZ_FALSE; + } + + return MZ_TRUE; +} + +static mz_bool mz_zip_writer_validate_archive_name(const char *pArchive_name) { + // Basic ZIP archive filename validity checks: Valid filenames cannot start + // with a forward slash, cannot contain a drive letter, and cannot use + // DOS-style backward slashes. + if (*pArchive_name == '/') return MZ_FALSE; + while (*pArchive_name) { + if ((*pArchive_name == '\\') || (*pArchive_name == ':')) return MZ_FALSE; + pArchive_name++; + } + return MZ_TRUE; +} + +static mz_uint mz_zip_writer_compute_padding_needed_for_file_alignment( + mz_zip_archive *pZip) { + mz_uint32 n; + if (!pZip->m_file_offset_alignment) return 0; + n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1)); + return (pZip->m_file_offset_alignment - n) & + (pZip->m_file_offset_alignment - 1); +} + +static mz_bool mz_zip_writer_write_zeros(mz_zip_archive *pZip, + mz_uint64 cur_file_ofs, mz_uint32 n) { + char buf[4096]; + memset(buf, 0, MZ_MIN(sizeof(buf), n)); + while (n) { + mz_uint32 s = MZ_MIN(sizeof(buf), n); + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_file_ofs, buf, s) != s) + return MZ_FALSE; + cur_file_ofs += s; + n -= s; + } + return MZ_TRUE; +} + +mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, + const char *pArchive_name, const void *pBuf, + size_t buf_size, const void *pComment, + mz_uint16 comment_size, + mz_uint level_and_flags, mz_uint64 uncomp_size, + mz_uint32 uncomp_crc32) { + mz_uint16 method = 0, dos_time = 0, dos_date = 0; + mz_uint level, ext_attributes = 0, num_alignment_padding_bytes; + mz_uint64 local_dir_header_ofs = pZip->m_archive_size, + cur_archive_file_ofs = pZip->m_archive_size, comp_size = 0; + size_t archive_name_size; + mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; + tdefl_compressor *pComp = NULL; + mz_bool store_data_uncompressed; + mz_zip_internal_state *pState; + + if ((int)level_and_flags < 0) level_and_flags = MZ_DEFAULT_LEVEL; + level = level_and_flags & 0xF; + store_data_uncompressed = + ((!level) || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)); + + if ((!pZip) || (!pZip->m_pState) || + (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || ((buf_size) && (!pBuf)) || + (!pArchive_name) || ((comment_size) && (!pComment)) || + (pZip->m_total_files == 0xFFFF) || (level > MZ_UBER_COMPRESSION)) + return MZ_FALSE; + + pState = pZip->m_pState; + + if ((!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (uncomp_size)) + return MZ_FALSE; + // No zip64 support yet + if ((buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF)) return MZ_FALSE; + if (!mz_zip_writer_validate_archive_name(pArchive_name)) return MZ_FALSE; + +#ifndef MINIZ_NO_TIME + { + time_t cur_time; + time(&cur_time); + mz_zip_time_to_dos_time(cur_time, &dos_time, &dos_date); + } +#endif // #ifndef MINIZ_NO_TIME + + archive_name_size = strlen(pArchive_name); + if (archive_name_size > 0xFFFF) return MZ_FALSE; + + num_alignment_padding_bytes = + mz_zip_writer_compute_padding_needed_for_file_alignment(pZip); + + // no zip64 support yet + if ((pZip->m_total_files == 0xFFFF) || + ((pZip->m_archive_size + num_alignment_padding_bytes + + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + + comment_size + archive_name_size) > 0xFFFFFFFF)) + return MZ_FALSE; + + if ((archive_name_size) && (pArchive_name[archive_name_size - 1] == '/')) { + // Set DOS Subdirectory attribute bit. + ext_attributes |= 0x10; + // Subdirectories cannot contain data. + if ((buf_size) || (uncomp_size)) return MZ_FALSE; + } + + // Try to do any allocations before writing to the archive, so if an + // allocation fails the file remains unmodified. (A good idea if we're doing + // an in-place modification.) + if ((!mz_zip_array_ensure_room( + pZip, &pState->m_central_dir, + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size)) || + (!mz_zip_array_ensure_room(pZip, &pState->m_central_dir_offsets, 1))) + return MZ_FALSE; + + if ((!store_data_uncompressed) && (buf_size)) { + if (NULL == (pComp = (tdefl_compressor *)pZip->m_pAlloc( + pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor)))) + return MZ_FALSE; + } + + if (!mz_zip_writer_write_zeros( + pZip, cur_archive_file_ofs, + num_alignment_padding_bytes + sizeof(local_dir_header))) { + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + return MZ_FALSE; + } + local_dir_header_ofs += num_alignment_padding_bytes; + if (pZip->m_file_offset_alignment) { + MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == + 0); + } + cur_archive_file_ofs += + num_alignment_padding_bytes + sizeof(local_dir_header); + + MZ_CLEAR_OBJ(local_dir_header); + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, + archive_name_size) != archive_name_size) { + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + return MZ_FALSE; + } + cur_archive_file_ofs += archive_name_size; + + if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) { + uncomp_crc32 = + (mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, buf_size); + uncomp_size = buf_size; + if (uncomp_size <= 3) { + level = 0; + store_data_uncompressed = MZ_TRUE; + } + } + + if (store_data_uncompressed) { + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pBuf, + buf_size) != buf_size) { + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + return MZ_FALSE; + } + + cur_archive_file_ofs += buf_size; + comp_size = buf_size; + + if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA) method = MZ_DEFLATED; + } else if (buf_size) { + mz_zip_writer_add_state state; + + state.m_pZip = pZip; + state.m_cur_archive_file_ofs = cur_archive_file_ofs; + state.m_comp_size = 0; + + if ((tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, + tdefl_create_comp_flags_from_zip_params( + level, -15, MZ_DEFAULT_STRATEGY)) != + TDEFL_STATUS_OKAY) || + (tdefl_compress_buffer(pComp, pBuf, buf_size, TDEFL_FINISH) != + TDEFL_STATUS_DONE)) { + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + return MZ_FALSE; + } + + comp_size = state.m_comp_size; + cur_archive_file_ofs = state.m_cur_archive_file_ofs; + + method = MZ_DEFLATED; + } + + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + pComp = NULL; + + // no zip64 support yet + if ((comp_size > 0xFFFFFFFF) || (cur_archive_file_ofs > 0xFFFFFFFF)) + return MZ_FALSE; + + if (!mz_zip_writer_create_local_dir_header( + pZip, local_dir_header, (mz_uint16)archive_name_size, 0, uncomp_size, + comp_size, uncomp_crc32, method, 0, dos_time, dos_date)) + return MZ_FALSE; + + if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, + sizeof(local_dir_header)) != sizeof(local_dir_header)) + return MZ_FALSE; + + if (!mz_zip_writer_add_to_central_dir( + pZip, pArchive_name, (mz_uint16)archive_name_size, NULL, 0, pComment, + comment_size, uncomp_size, comp_size, uncomp_crc32, method, 0, + dos_time, dos_date, local_dir_header_ofs, ext_attributes)) + return MZ_FALSE; + + pZip->m_total_files++; + pZip->m_archive_size = cur_archive_file_ofs; + + return MZ_TRUE; +} + +#ifndef MINIZ_NO_STDIO +mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, + const char *pSrc_filename, const void *pComment, + mz_uint16 comment_size, + mz_uint level_and_flags) { + mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes; + mz_uint16 method = 0, dos_time = 0, dos_date = 0, ext_attributes = 0; + mz_uint64 local_dir_header_ofs = pZip->m_archive_size, + cur_archive_file_ofs = pZip->m_archive_size, uncomp_size = 0, + comp_size = 0; + size_t archive_name_size; + mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; + MZ_FILE *pSrc_file = NULL; + + if ((int)level_and_flags < 0) level_and_flags = MZ_DEFAULT_LEVEL; + level = level_and_flags & 0xF; + + if ((!pZip) || (!pZip->m_pState) || + (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) || + ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION)) + return MZ_FALSE; + if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA) return MZ_FALSE; + if (!mz_zip_writer_validate_archive_name(pArchive_name)) return MZ_FALSE; + + archive_name_size = strlen(pArchive_name); + if (archive_name_size > 0xFFFF) return MZ_FALSE; + + num_alignment_padding_bytes = + mz_zip_writer_compute_padding_needed_for_file_alignment(pZip); + + // no zip64 support yet + if ((pZip->m_total_files == 0xFFFF) || + ((pZip->m_archive_size + num_alignment_padding_bytes + + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + + comment_size + archive_name_size) > 0xFFFFFFFF)) + return MZ_FALSE; + + if (!mz_zip_get_file_modified_time(pSrc_filename, &dos_time, &dos_date)) + return MZ_FALSE; + + pSrc_file = MZ_FOPEN(pSrc_filename, "rb"); + if (!pSrc_file) return MZ_FALSE; + MZ_FSEEK64(pSrc_file, 0, SEEK_END); + uncomp_size = MZ_FTELL64(pSrc_file); + MZ_FSEEK64(pSrc_file, 0, SEEK_SET); + + if (uncomp_size > 0xFFFFFFFF) { + // No zip64 support yet + MZ_FCLOSE(pSrc_file); + return MZ_FALSE; + } + if (uncomp_size <= 3) level = 0; + + if (!mz_zip_writer_write_zeros( + pZip, cur_archive_file_ofs, + num_alignment_padding_bytes + sizeof(local_dir_header))) { + MZ_FCLOSE(pSrc_file); + return MZ_FALSE; + } + local_dir_header_ofs += num_alignment_padding_bytes; + if (pZip->m_file_offset_alignment) { + MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == + 0); + } + cur_archive_file_ofs += + num_alignment_padding_bytes + sizeof(local_dir_header); + + MZ_CLEAR_OBJ(local_dir_header); + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, + archive_name_size) != archive_name_size) { + MZ_FCLOSE(pSrc_file); + return MZ_FALSE; + } + cur_archive_file_ofs += archive_name_size; + + if (uncomp_size) { + mz_uint64 uncomp_remaining = uncomp_size; + void *pRead_buf = + pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, MZ_ZIP_MAX_IO_BUF_SIZE); + if (!pRead_buf) { + MZ_FCLOSE(pSrc_file); + return MZ_FALSE; + } + + if (!level) { + while (uncomp_remaining) { + mz_uint n = + (mz_uint)MZ_MIN((mz_uint)MZ_ZIP_MAX_IO_BUF_SIZE, uncomp_remaining); + if ((MZ_FREAD(pRead_buf, 1, n, pSrc_file) != n) || + (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pRead_buf, + n) != n)) { + pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); + MZ_FCLOSE(pSrc_file); + return MZ_FALSE; + } + uncomp_crc32 = + (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n); + uncomp_remaining -= n; + cur_archive_file_ofs += n; + } + comp_size = uncomp_size; + } else { + mz_bool result = MZ_FALSE; + mz_zip_writer_add_state state; + tdefl_compressor *pComp = (tdefl_compressor *)pZip->m_pAlloc( + pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor)); + if (!pComp) { + pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); + MZ_FCLOSE(pSrc_file); + return MZ_FALSE; + } + + state.m_pZip = pZip; + state.m_cur_archive_file_ofs = cur_archive_file_ofs; + state.m_comp_size = 0; + + if (tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, + tdefl_create_comp_flags_from_zip_params( + level, -15, MZ_DEFAULT_STRATEGY)) != + TDEFL_STATUS_OKAY) { + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); + MZ_FCLOSE(pSrc_file); + return MZ_FALSE; + } + + for (;;) { + size_t in_buf_size = (mz_uint32)MZ_MIN(uncomp_remaining, + (mz_uint)MZ_ZIP_MAX_IO_BUF_SIZE); + tdefl_status status; + + if (MZ_FREAD(pRead_buf, 1, in_buf_size, pSrc_file) != in_buf_size) + break; + + uncomp_crc32 = (mz_uint32)mz_crc32( + uncomp_crc32, (const mz_uint8 *)pRead_buf, in_buf_size); + uncomp_remaining -= in_buf_size; + + status = tdefl_compress_buffer( + pComp, pRead_buf, in_buf_size, + uncomp_remaining ? TDEFL_NO_FLUSH : TDEFL_FINISH); + if (status == TDEFL_STATUS_DONE) { + result = MZ_TRUE; + break; + } else if (status != TDEFL_STATUS_OKAY) + break; + } + + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + + if (!result) { + pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); + MZ_FCLOSE(pSrc_file); + return MZ_FALSE; + } + + comp_size = state.m_comp_size; + cur_archive_file_ofs = state.m_cur_archive_file_ofs; + + method = MZ_DEFLATED; + } + + pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); + } + + MZ_FCLOSE(pSrc_file); + pSrc_file = NULL; + + // no zip64 support yet + if ((comp_size > 0xFFFFFFFF) || (cur_archive_file_ofs > 0xFFFFFFFF)) + return MZ_FALSE; + + if (!mz_zip_writer_create_local_dir_header( + pZip, local_dir_header, (mz_uint16)archive_name_size, 0, uncomp_size, + comp_size, uncomp_crc32, method, 0, dos_time, dos_date)) + return MZ_FALSE; + + if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, + sizeof(local_dir_header)) != sizeof(local_dir_header)) + return MZ_FALSE; + + if (!mz_zip_writer_add_to_central_dir( + pZip, pArchive_name, (mz_uint16)archive_name_size, NULL, 0, pComment, + comment_size, uncomp_size, comp_size, uncomp_crc32, method, 0, + dos_time, dos_date, local_dir_header_ofs, ext_attributes)) + return MZ_FALSE; + + pZip->m_total_files++; + pZip->m_archive_size = cur_archive_file_ofs; + + return MZ_TRUE; +} +#endif // #ifndef MINIZ_NO_STDIO + +mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, + mz_zip_archive *pSource_zip, + mz_uint file_index) { + mz_uint n, bit_flags, num_alignment_padding_bytes; + mz_uint64 comp_bytes_remaining, local_dir_header_ofs; + mz_uint64 cur_src_file_ofs, cur_dst_file_ofs; + mz_uint32 + local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / + sizeof(mz_uint32)]; + mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; + mz_uint8 central_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE]; + size_t orig_central_dir_size; + mz_zip_internal_state *pState; + void *pBuf; + const mz_uint8 *pSrc_central_header; + + if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING)) + return MZ_FALSE; + if (NULL == + (pSrc_central_header = mz_zip_reader_get_cdh(pSource_zip, file_index))) + return MZ_FALSE; + pState = pZip->m_pState; + + num_alignment_padding_bytes = + mz_zip_writer_compute_padding_needed_for_file_alignment(pZip); + + // no zip64 support yet + if ((pZip->m_total_files == 0xFFFF) || + ((pZip->m_archive_size + num_alignment_padding_bytes + + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) > + 0xFFFFFFFF)) + return MZ_FALSE; + + cur_src_file_ofs = + MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS); + cur_dst_file_ofs = pZip->m_archive_size; + + if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, + pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != + MZ_ZIP_LOCAL_DIR_HEADER_SIZE) + return MZ_FALSE; + if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) + return MZ_FALSE; + cur_src_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE; + + if (!mz_zip_writer_write_zeros(pZip, cur_dst_file_ofs, + num_alignment_padding_bytes)) + return MZ_FALSE; + cur_dst_file_ofs += num_alignment_padding_bytes; + local_dir_header_ofs = cur_dst_file_ofs; + if (pZip->m_file_offset_alignment) { + MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == + 0); + } + + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pLocal_header, + MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != + MZ_ZIP_LOCAL_DIR_HEADER_SIZE) + return MZ_FALSE; + cur_dst_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE; + + n = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); + comp_bytes_remaining = + n + MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); + + if (NULL == (pBuf = pZip->m_pAlloc( + pZip->m_pAlloc_opaque, 1, + (size_t)MZ_MAX(sizeof(mz_uint32) * 4, + MZ_MIN((mz_uint)MZ_ZIP_MAX_IO_BUF_SIZE, + comp_bytes_remaining))))) + return MZ_FALSE; + + while (comp_bytes_remaining) { + n = (mz_uint)MZ_MIN((mz_uint)MZ_ZIP_MAX_IO_BUF_SIZE, comp_bytes_remaining); + if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, + n) != n) { + pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); + return MZ_FALSE; + } + cur_src_file_ofs += n; + + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n) { + pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); + return MZ_FALSE; + } + cur_dst_file_ofs += n; + + comp_bytes_remaining -= n; + } + + bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS); + if (bit_flags & 8) { + // Copy data descriptor + if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, + sizeof(mz_uint32) * 4) != sizeof(mz_uint32) * 4) { + pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); + return MZ_FALSE; + } + + n = sizeof(mz_uint32) * ((MZ_READ_LE32(pBuf) == 0x08074b50) ? 4 : 3); + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n) { + pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); + return MZ_FALSE; + } + + cur_src_file_ofs += n; + cur_dst_file_ofs += n; + } + pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); + + // no zip64 support yet + if (cur_dst_file_ofs > 0xFFFFFFFF) return MZ_FALSE; + + orig_central_dir_size = pState->m_central_dir.m_size; + + memcpy(central_header, pSrc_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE); + MZ_WRITE_LE32(central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS, + local_dir_header_ofs); + if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_header, + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) + return MZ_FALSE; + + n = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_FILENAME_LEN_OFS) + + MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS) + + MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_COMMENT_LEN_OFS); + if (!mz_zip_array_push_back( + pZip, &pState->m_central_dir, + pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n)) { + mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, + MZ_FALSE); + return MZ_FALSE; + } + + if (pState->m_central_dir.m_size > 0xFFFFFFFF) return MZ_FALSE; + n = (mz_uint32)orig_central_dir_size; + if (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &n, 1)) { + mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, + MZ_FALSE); + return MZ_FALSE; + } + + pZip->m_total_files++; + pZip->m_archive_size = cur_dst_file_ofs; + + return MZ_TRUE; +} + +mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip) { + mz_zip_internal_state *pState; + mz_uint64 central_dir_ofs, central_dir_size; + mz_uint8 hdr[MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE]; + + if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING)) + return MZ_FALSE; + + pState = pZip->m_pState; + + // no zip64 support yet + if ((pZip->m_total_files > 0xFFFF) || + ((pZip->m_archive_size + pState->m_central_dir.m_size + + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) > 0xFFFFFFFF)) + return MZ_FALSE; + + central_dir_ofs = 0; + central_dir_size = 0; + if (pZip->m_total_files) { + // Write central directory + central_dir_ofs = pZip->m_archive_size; + central_dir_size = pState->m_central_dir.m_size; + pZip->m_central_directory_file_ofs = central_dir_ofs; + if (pZip->m_pWrite(pZip->m_pIO_opaque, central_dir_ofs, + pState->m_central_dir.m_p, + (size_t)central_dir_size) != central_dir_size) + return MZ_FALSE; + pZip->m_archive_size += central_dir_size; + } + + // Write end of central directory record + MZ_CLEAR_OBJ(hdr); + MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_SIG_OFS, + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG); + MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS, + pZip->m_total_files); + MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS, pZip->m_total_files); + MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_SIZE_OFS, central_dir_size); + MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_OFS_OFS, central_dir_ofs); + + if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr, + sizeof(hdr)) != sizeof(hdr)) + return MZ_FALSE; +#ifndef MINIZ_NO_STDIO + if ((pState->m_pFile) && (MZ_FFLUSH(pState->m_pFile) == EOF)) return MZ_FALSE; +#endif // #ifndef MINIZ_NO_STDIO + + pZip->m_archive_size += sizeof(hdr); + + pZip->m_zip_mode = MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED; + return MZ_TRUE; +} + +mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **pBuf, + size_t *pSize) { + if ((!pZip) || (!pZip->m_pState) || (!pBuf) || (!pSize)) return MZ_FALSE; + if (pZip->m_pWrite != mz_zip_heap_write_func) return MZ_FALSE; + if (!mz_zip_writer_finalize_archive(pZip)) return MZ_FALSE; + + *pBuf = pZip->m_pState->m_pMem; + *pSize = pZip->m_pState->m_mem_size; + pZip->m_pState->m_pMem = NULL; + pZip->m_pState->m_mem_size = pZip->m_pState->m_mem_capacity = 0; + return MZ_TRUE; +} + +mz_bool mz_zip_writer_end(mz_zip_archive *pZip) { + mz_zip_internal_state *pState; + mz_bool status = MZ_TRUE; + if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || + ((pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) && + (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED))) + return MZ_FALSE; + + pState = pZip->m_pState; + pZip->m_pState = NULL; + mz_zip_array_clear(pZip, &pState->m_central_dir); + mz_zip_array_clear(pZip, &pState->m_central_dir_offsets); + mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets); + +#ifndef MINIZ_NO_STDIO + if (pState->m_pFile) { + MZ_FCLOSE(pState->m_pFile); + pState->m_pFile = NULL; + } +#endif // #ifndef MINIZ_NO_STDIO + + if ((pZip->m_pWrite == mz_zip_heap_write_func) && (pState->m_pMem)) { + pZip->m_pFree(pZip->m_pAlloc_opaque, pState->m_pMem); + pState->m_pMem = NULL; + } + + pZip->m_pFree(pZip->m_pAlloc_opaque, pState); + pZip->m_zip_mode = MZ_ZIP_MODE_INVALID; + return status; +} + +#ifndef MINIZ_NO_STDIO +mz_bool mz_zip_add_mem_to_archive_file_in_place( + const char *pZip_filename, const char *pArchive_name, const void *pBuf, + size_t buf_size, const void *pComment, mz_uint16 comment_size, + mz_uint level_and_flags) { + mz_bool status, created_new_archive = MZ_FALSE; + mz_zip_archive zip_archive; + struct MZ_FILE_STAT_STRUCT file_stat; + MZ_CLEAR_OBJ(zip_archive); + if ((int)level_and_flags < 0) level_and_flags = MZ_DEFAULT_LEVEL; + if ((!pZip_filename) || (!pArchive_name) || ((buf_size) && (!pBuf)) || + ((comment_size) && (!pComment)) || + ((level_and_flags & 0xF) > MZ_UBER_COMPRESSION)) + return MZ_FALSE; + if (!mz_zip_writer_validate_archive_name(pArchive_name)) return MZ_FALSE; + if (MZ_FILE_STAT(pZip_filename, &file_stat) != 0) { + // Create a new archive. + if (!mz_zip_writer_init_file(&zip_archive, pZip_filename, 0)) + return MZ_FALSE; + created_new_archive = MZ_TRUE; + } else { + // Append to an existing archive. + if (!mz_zip_reader_init_file( + &zip_archive, pZip_filename, + level_and_flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY)) + return MZ_FALSE; + if (!mz_zip_writer_init_from_reader(&zip_archive, pZip_filename)) { + mz_zip_reader_end(&zip_archive); + return MZ_FALSE; + } + } + status = + mz_zip_writer_add_mem_ex(&zip_archive, pArchive_name, pBuf, buf_size, + pComment, comment_size, level_and_flags, 0, 0); + // Always finalize, even if adding failed for some reason, so we have a valid + // central directory. (This may not always succeed, but we can try.) + if (!mz_zip_writer_finalize_archive(&zip_archive)) status = MZ_FALSE; + if (!mz_zip_writer_end(&zip_archive)) status = MZ_FALSE; + if ((!status) && (created_new_archive)) { + // It's a new archive and something went wrong, so just delete it. + int ignoredStatus = MZ_DELETE_FILE(pZip_filename); + (void)ignoredStatus; + } + return status; +} + +void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, + const char *pArchive_name, + size_t *pSize, mz_uint flags) { + int file_index; + mz_zip_archive zip_archive; + void *p = NULL; + + if (pSize) *pSize = 0; + + if ((!pZip_filename) || (!pArchive_name)) return NULL; + + MZ_CLEAR_OBJ(zip_archive); + if (!mz_zip_reader_init_file( + &zip_archive, pZip_filename, + flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY)) + return NULL; + + if ((file_index = mz_zip_reader_locate_file(&zip_archive, pArchive_name, NULL, + flags)) >= 0) + p = mz_zip_reader_extract_to_heap(&zip_archive, file_index, pSize, flags); + + mz_zip_reader_end(&zip_archive); + return p; +} + +#endif // #ifndef MINIZ_NO_STDIO + +#endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS + +#endif // #ifndef MINIZ_NO_ARCHIVE_APIS + +#ifdef __cplusplus +} +#endif + +#endif // MINIZ_HEADER_FILE_ONLY + +/* + This is free and unencumbered software released into the public domain. + + Anyone is free to copy, modify, publish, use, compile, sell, or + distribute this software, either in source code form or as a compiled + binary, for any purpose, commercial or non-commercial, and by any + means. + + In jurisdictions that recognize copyright laws, the author or authors + of this software dedicate any and all copyright interest in the + software to the public domain. We make this dedication for the benefit + of the public at large and to the detriment of our heirs and + successors. We intend this dedication to be an overt act of + relinquishment in perpetuity of all present and future rights to this + software under copyright law. + + 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 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. + + For more information, please refer to +*/ + +// ---------------------- end of miniz ---------------------------------------- + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + +} +#else + +// Reuse MINIZ_LITTE_ENDIAN macro + +#if defined(__sparcv9) +// Big endian +#else +#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU +// Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. +#define MINIZ_LITTLE_ENDIAN 1 +#endif +#endif + +#endif // TINYEXR_USE_MINIZ + +// static bool IsBigEndian(void) { +// union { +// unsigned int i; +// char c[4]; +// } bint = {0x01020304}; +// +// return bint.c[0] == 1; +//} + +static const int kEXRVersionSize = 8; + +static void swap2(unsigned short *val) { +#ifdef MINIZ_LITTLE_ENDIAN + (void)val; +#else + unsigned short tmp = *val; + unsigned char *dst = reinterpret_cast(val); + unsigned char *src = reinterpret_cast(&tmp); + + dst[0] = src[1]; + dst[1] = src[0]; +#endif +} + +static void swap4(unsigned int *val) { +#ifdef MINIZ_LITTLE_ENDIAN + (void)val; +#else + unsigned int tmp = *val; + unsigned char *dst = reinterpret_cast(val); + unsigned char *src = reinterpret_cast(&tmp); + + dst[0] = src[3]; + dst[1] = src[2]; + dst[2] = src[1]; + dst[3] = src[0]; +#endif +} + +static void swap8(tinyexr::tinyexr_uint64 *val) { +#ifdef MINIZ_LITTLE_ENDIAN + (void)val; +#else + tinyexr::tinyexr_uint64 tmp = (*val); + unsigned char *dst = reinterpret_cast(val); + unsigned char *src = reinterpret_cast(&tmp); + + dst[0] = src[7]; + dst[1] = src[6]; + dst[2] = src[5]; + dst[3] = src[4]; + dst[4] = src[3]; + dst[5] = src[2]; + dst[6] = src[1]; + dst[7] = src[0]; +#endif +} + +// https://gist.github.com/rygorous/2156668 +// Reuse MINIZ_LITTLE_ENDIAN flag from miniz. +union FP32 { + unsigned int u; + float f; + struct { +#if MINIZ_LITTLE_ENDIAN + unsigned int Mantissa : 23; + unsigned int Exponent : 8; + unsigned int Sign : 1; +#else + unsigned int Sign : 1; + unsigned int Exponent : 8; + unsigned int Mantissa : 23; +#endif + } s; +}; + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +union FP16 { + unsigned short u; + struct { +#if MINIZ_LITTLE_ENDIAN + unsigned int Mantissa : 10; + unsigned int Exponent : 5; + unsigned int Sign : 1; +#else + unsigned int Sign : 1; + unsigned int Exponent : 5; + unsigned int Mantissa : 10; +#endif + } s; +}; + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +static FP32 half_to_float(FP16 h) { + static const FP32 magic = {113 << 23}; + static const unsigned int shifted_exp = 0x7c00 + << 13; // exponent mask after shift + FP32 o; + + o.u = (h.u & 0x7fffU) << 13U; // exponent/mantissa bits + unsigned int exp_ = shifted_exp & o.u; // just the exponent + o.u += (127 - 15) << 23; // exponent adjust + + // handle exponent special cases + if (exp_ == shifted_exp) // Inf/NaN? + o.u += (128 - 16) << 23; // extra exp adjust + else if (exp_ == 0) // Zero/Denormal? + { + o.u += 1 << 23; // extra exp adjust + o.f -= magic.f; // renormalize + } + + o.u |= (h.u & 0x8000U) << 16U; // sign bit + return o; +} + +static FP16 float_to_half_full(FP32 f) { + FP16 o = {0}; + + // Based on ISPC reference code (with minor modifications) + if (f.s.Exponent == 0) // Signed zero/denormal (which will underflow) + o.s.Exponent = 0; + else if (f.s.Exponent == 255) // Inf or NaN (all exponent bits set) + { + o.s.Exponent = 31; + o.s.Mantissa = f.s.Mantissa ? 0x200 : 0; // NaN->qNaN and Inf->Inf + } else // Normalized number + { + // Exponent unbias the single, then bias the halfp + int newexp = f.s.Exponent - 127 + 15; + if (newexp >= 31) // Overflow, return signed infinity + o.s.Exponent = 31; + else if (newexp <= 0) // Underflow + { + if ((14 - newexp) <= 24) // Mantissa might be non-zero + { + unsigned int mant = f.s.Mantissa | 0x800000; // Hidden 1 bit + o.s.Mantissa = mant >> (14 - newexp); + if ((mant >> (13 - newexp)) & 1) // Check for rounding + o.u++; // Round, might overflow into exp bit, but this is OK + } + } else { + o.s.Exponent = static_cast(newexp); + o.s.Mantissa = f.s.Mantissa >> 13; + if (f.s.Mantissa & 0x1000) // Check for rounding + o.u++; // Round, might overflow to inf, this is OK + } + } + + o.s.Sign = f.s.Sign; + return o; +} + +// NOTE: From OpenEXR code +// #define IMF_INCREASING_Y 0 +// #define IMF_DECREASING_Y 1 +// #define IMF_RAMDOM_Y 2 +// +// #define IMF_NO_COMPRESSION 0 +// #define IMF_RLE_COMPRESSION 1 +// #define IMF_ZIPS_COMPRESSION 2 +// #define IMF_ZIP_COMPRESSION 3 +// #define IMF_PIZ_COMPRESSION 4 +// #define IMF_PXR24_COMPRESSION 5 +// #define IMF_B44_COMPRESSION 6 +// #define IMF_B44A_COMPRESSION 7 + +static const char *ReadString(std::string *s, const char *ptr) { + // Read untile NULL(\0). + const char *p = ptr; + const char *q = ptr; + while ((*q) != 0) q++; + + (*s) = std::string(p, q); + + return q + 1; // skip '\0' +} + +static bool ReadAttribute(std::string *name, std::string *type, + std::vector *data, size_t *marker_size, + const char *marker, size_t size) { + size_t name_len = strnlen(marker, size); + if (name_len == size) { + // String does not have a terminating character. + return false; + } + *name = std::string(marker, name_len); + + marker += name_len + 1; + size -= name_len + 1; + + size_t type_len = strnlen(marker, size); + if (type_len == size) { + return false; + } + *type = std::string(marker, type_len); + + marker += type_len + 1; + size -= type_len + 1; + + if (size < sizeof(uint32_t)) { + return false; + } + + uint32_t data_len; + memcpy(&data_len, marker, sizeof(uint32_t)); + tinyexr::swap4(reinterpret_cast(&data_len)); + + marker += sizeof(uint32_t); + size -= sizeof(uint32_t); + + if (size < data_len) { + return false; + } + + data->resize(static_cast(data_len)); + memcpy(&data->at(0), marker, static_cast(data_len)); + + *marker_size = name_len + 1 + type_len + 1 + sizeof(uint32_t) + data_len; + return true; +} + +static void WriteAttributeToMemory(std::vector *out, + const char *name, const char *type, + const unsigned char *data, int len) { + out->insert(out->end(), name, name + strlen(name) + 1); + out->insert(out->end(), type, type + strlen(type) + 1); + + int outLen = len; + tinyexr::swap4(reinterpret_cast(&outLen)); + out->insert(out->end(), reinterpret_cast(&outLen), + reinterpret_cast(&outLen) + sizeof(int)); + out->insert(out->end(), data, data + len); +} + +typedef struct { + std::string name; // less than 255 bytes long + int pixel_type; + int x_sampling; + int y_sampling; + unsigned char p_linear; + unsigned char pad[3]; +} ChannelInfo; + +typedef struct { + std::vector channels; + std::vector attributes; + + int data_window[4]; + int line_order; + int display_window[4]; + float screen_window_center[2]; + float screen_window_width; + float pixel_aspect_ratio; + + int chunk_count; + + // Tiled format + int tile_size_x; + int tile_size_y; + int tile_level_mode; + int tile_rounding_mode; + + unsigned int header_len; + + int compression_type; + + void clear() { + channels.clear(); + attributes.clear(); + + data_window[0] = 0; + data_window[1] = 0; + data_window[2] = 0; + data_window[3] = 0; + line_order = 0; + display_window[0] = 0; + display_window[1] = 0; + display_window[2] = 0; + display_window[3] = 0; + screen_window_center[0] = 0.0f; + screen_window_center[1] = 0.0f; + screen_window_width = 0.0f; + pixel_aspect_ratio = 0.0f; + + chunk_count = 0; + + // Tiled format + tile_size_x = 0; + tile_size_y = 0; + tile_level_mode = 0; + tile_rounding_mode = 0; + + header_len = 0; + compression_type = 0; + } +} HeaderInfo; + +static void ReadChannelInfo(std::vector &channels, + const std::vector &data) { + const char *p = reinterpret_cast(&data.at(0)); + + for (;;) { + if ((*p) == 0) { + break; + } + ChannelInfo info; + p = ReadString(&info.name, p); + + memcpy(&info.pixel_type, p, sizeof(int)); + p += 4; + info.p_linear = static_cast(p[0]); // uchar + p += 1 + 3; // reserved: uchar[3] + memcpy(&info.x_sampling, p, sizeof(int)); // int + p += 4; + memcpy(&info.y_sampling, p, sizeof(int)); // int + p += 4; + + tinyexr::swap4(reinterpret_cast(&info.pixel_type)); + tinyexr::swap4(reinterpret_cast(&info.x_sampling)); + tinyexr::swap4(reinterpret_cast(&info.y_sampling)); + + channels.push_back(info); + } +} + +static void WriteChannelInfo(std::vector &data, + const std::vector &channels) { + size_t sz = 0; + + // Calculate total size. + for (size_t c = 0; c < channels.size(); c++) { + sz += strlen(channels[c].name.c_str()) + 1; // +1 for \0 + sz += 16; // 4 * int + } + data.resize(sz + 1); + + unsigned char *p = &data.at(0); + + for (size_t c = 0; c < channels.size(); c++) { + memcpy(p, channels[c].name.c_str(), strlen(channels[c].name.c_str())); + p += strlen(channels[c].name.c_str()); + (*p) = '\0'; + p++; + + int pixel_type = channels[c].pixel_type; + int x_sampling = channels[c].x_sampling; + int y_sampling = channels[c].y_sampling; + tinyexr::swap4(reinterpret_cast(&pixel_type)); + tinyexr::swap4(reinterpret_cast(&x_sampling)); + tinyexr::swap4(reinterpret_cast(&y_sampling)); + + memcpy(p, &pixel_type, sizeof(int)); + p += sizeof(int); + + (*p) = channels[c].p_linear; + p += 4; + + memcpy(p, &x_sampling, sizeof(int)); + p += sizeof(int); + + memcpy(p, &y_sampling, sizeof(int)); + p += sizeof(int); + } + + (*p) = '\0'; +} + +static void CompressZip(unsigned char *dst, + tinyexr::tinyexr_uint64 &compressedSize, + const unsigned char *src, unsigned long src_size) { + std::vector tmpBuf(src_size); + + // + // Apply EXR-specific? postprocess. Grabbed from OpenEXR's + // ImfZipCompressor.cpp + // + + // + // Reorder the pixel data. + // + + const char *srcPtr = reinterpret_cast(src); + + { + char *t1 = reinterpret_cast(&tmpBuf.at(0)); + char *t2 = reinterpret_cast(&tmpBuf.at(0)) + (src_size + 1) / 2; + const char *stop = srcPtr + src_size; + + for (;;) { + if (srcPtr < stop) + *(t1++) = *(srcPtr++); + else + break; + + if (srcPtr < stop) + *(t2++) = *(srcPtr++); + else + break; + } + } + + // + // Predictor. + // + + { + unsigned char *t = &tmpBuf.at(0) + 1; + unsigned char *stop = &tmpBuf.at(0) + src_size; + int p = t[-1]; + + while (t < stop) { + int d = int(t[0]) - p + (128 + 256); + p = t[0]; + t[0] = static_cast(d); + ++t; + } + } + +#if TINYEXR_USE_MINIZ + // + // Compress the data using miniz + // + + miniz::mz_ulong outSize = miniz::mz_compressBound(src_size); + int ret = miniz::mz_compress( + dst, &outSize, static_cast(&tmpBuf.at(0)), + src_size); + assert(ret == miniz::MZ_OK); + (void)ret; + + compressedSize = outSize; +#else + uLong outSize = compressBound(static_cast(src_size)); + int ret = compress(dst, &outSize, static_cast(&tmpBuf.at(0)), + src_size); + assert(ret == Z_OK); + + compressedSize = outSize; +#endif + + // Use uncompressed data when compressed data is larger than uncompressed. + // (Issue 40) + if (compressedSize >= src_size) { + compressedSize = src_size; + memcpy(dst, src, src_size); + } +} + +static void DecompressZip(unsigned char *dst, + unsigned long *uncompressed_size /* inout */, + const unsigned char *src, unsigned long src_size) { + if ((*uncompressed_size) == src_size) { + // Data is not compressed(Issue 40). + memcpy(dst, src, src_size); + return; + } + std::vector tmpBuf(*uncompressed_size); + +#if TINYEXR_USE_MINIZ + int ret = + miniz::mz_uncompress(&tmpBuf.at(0), uncompressed_size, src, src_size); + assert(ret == miniz::MZ_OK); + (void)ret; +#else + int ret = uncompress(&tmpBuf.at(0), uncompressed_size, src, src_size); + assert(ret == Z_OK); + (void)ret; +#endif + + // + // Apply EXR-specific? postprocess. Grabbed from OpenEXR's + // ImfZipCompressor.cpp + // + + // Predictor. + { + unsigned char *t = &tmpBuf.at(0) + 1; + unsigned char *stop = &tmpBuf.at(0) + (*uncompressed_size); + + while (t < stop) { + int d = int(t[-1]) + int(t[0]) - 128; + t[0] = static_cast(d); + ++t; + } + } + + // Reorder the pixel data. + { + const char *t1 = reinterpret_cast(&tmpBuf.at(0)); + const char *t2 = reinterpret_cast(&tmpBuf.at(0)) + + (*uncompressed_size + 1) / 2; + char *s = reinterpret_cast(dst); + char *stop = s + (*uncompressed_size); + + for (;;) { + if (s < stop) + *(s++) = *(t1++); + else + break; + + if (s < stop) + *(s++) = *(t2++); + else + break; + } + } +} + +// RLE code from OpenEXR -------------------------------------- + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wsign-conversion" +#endif + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4204) // nonstandard extension used : non-constant + // aggregate initializer (also supported by GNU + // C and C99, so no big deal) +#pragma warning(disable : 4244) // 'initializing': conversion from '__int64' to + // 'int', possible loss of data +#pragma warning( \ + disable : 4267) // 'argument': conversion from '__int64' to 'int', + // possible loss of data +#pragma warning(disable : 4996) // 'strdup': The POSIX name for this item is + // deprecated. Instead, use the ISO C and C++ + // conformant name: _strdup. +#endif + + +const int MIN_RUN_LENGTH = 3; +const int MAX_RUN_LENGTH = 127; + +// +// Compress an array of bytes, using run-length encoding, +// and return the length of the compressed data. +// + +static int rleCompress(int inLength, const char in[], signed char out[]) { + const char *inEnd = in + inLength; + const char *runStart = in; + const char *runEnd = in + 1; + signed char *outWrite = out; + + while (runStart < inEnd) { + while (runEnd < inEnd && *runStart == *runEnd && + runEnd - runStart - 1 < MAX_RUN_LENGTH) { + ++runEnd; + } + + if (runEnd - runStart >= MIN_RUN_LENGTH) { + // + // Compressable run + // + + *outWrite++ = static_cast(runEnd - runStart) - 1; + *outWrite++ = *(reinterpret_cast(runStart)); + runStart = runEnd; + } else { + // + // Uncompressable run + // + + while (runEnd < inEnd && + ((runEnd + 1 >= inEnd || *runEnd != *(runEnd + 1)) || + (runEnd + 2 >= inEnd || *(runEnd + 1) != *(runEnd + 2))) && + runEnd - runStart < MAX_RUN_LENGTH) { + ++runEnd; + } + + *outWrite++ = static_cast(runStart - runEnd); + + while (runStart < runEnd) { + *outWrite++ = *(reinterpret_cast(runStart++)); + } + } + + ++runEnd; + } + + return static_cast(outWrite - out); +} + +// +// Uncompress an array of bytes compressed with rleCompress(). +// Returns the length of the oncompressed data, or 0 if the +// length of the uncompressed data would be more than maxLength. +// + +static int rleUncompress(int inLength, int maxLength, const signed char in[], + char out[]) { + char *outStart = out; + + while (inLength > 0) { + if (*in < 0) { + int count = -(static_cast(*in++)); + inLength -= count + 1; + + if (0 > (maxLength -= count)) return 0; + + memcpy(out, in, count); + out += count; + in += count; + } else { + int count = *in++; + inLength -= 2; + + if (0 > (maxLength -= count + 1)) return 0; + + memset(out, *reinterpret_cast(in), count + 1); + out += count + 1; + + in++; + } + } + + return static_cast(out - outStart); +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// End of RLE code from OpenEXR ----------------------------------- + +static void CompressRle(unsigned char *dst, + tinyexr::tinyexr_uint64 &compressedSize, + const unsigned char *src, unsigned long src_size) { + std::vector tmpBuf(src_size); + + // + // Apply EXR-specific? postprocess. Grabbed from OpenEXR's + // ImfRleCompressor.cpp + // + + // + // Reorder the pixel data. + // + + const char *srcPtr = reinterpret_cast(src); + + { + char *t1 = reinterpret_cast(&tmpBuf.at(0)); + char *t2 = reinterpret_cast(&tmpBuf.at(0)) + (src_size + 1) / 2; + const char *stop = srcPtr + src_size; + + for (;;) { + if (srcPtr < stop) + *(t1++) = *(srcPtr++); + else + break; + + if (srcPtr < stop) + *(t2++) = *(srcPtr++); + else + break; + } + } + + // + // Predictor. + // + + { + unsigned char *t = &tmpBuf.at(0) + 1; + unsigned char *stop = &tmpBuf.at(0) + src_size; + int p = t[-1]; + + while (t < stop) { + int d = int(t[0]) - p + (128 + 256); + p = t[0]; + t[0] = static_cast(d); + ++t; + } + } + + // outSize will be (srcSiz * 3) / 2 at max. + int outSize = rleCompress(static_cast(src_size), + reinterpret_cast(&tmpBuf.at(0)), + reinterpret_cast(dst)); + assert(outSize > 0); + + compressedSize = static_cast(outSize); + + // Use uncompressed data when compressed data is larger than uncompressed. + // (Issue 40) + if (compressedSize >= src_size) { + compressedSize = src_size; + memcpy(dst, src, src_size); + } +} + +static void DecompressRle(unsigned char *dst, + const unsigned long uncompressed_size, + const unsigned char *src, unsigned long src_size) { + if (uncompressed_size == src_size) { + // Data is not compressed(Issue 40). + memcpy(dst, src, src_size); + return; + } + + std::vector tmpBuf(uncompressed_size); + + int ret = rleUncompress(static_cast(src_size), + static_cast(uncompressed_size), + reinterpret_cast(src), + reinterpret_cast(&tmpBuf.at(0))); + assert(ret == static_cast(uncompressed_size)); + (void)ret; + + // + // Apply EXR-specific? postprocess. Grabbed from OpenEXR's + // ImfRleCompressor.cpp + // + + // Predictor. + { + unsigned char *t = &tmpBuf.at(0) + 1; + unsigned char *stop = &tmpBuf.at(0) + uncompressed_size; + + while (t < stop) { + int d = int(t[-1]) + int(t[0]) - 128; + t[0] = static_cast(d); + ++t; + } + } + + // Reorder the pixel data. + { + const char *t1 = reinterpret_cast(&tmpBuf.at(0)); + const char *t2 = reinterpret_cast(&tmpBuf.at(0)) + + (uncompressed_size + 1) / 2; + char *s = reinterpret_cast(dst); + char *stop = s + uncompressed_size; + + for (;;) { + if (s < stop) + *(s++) = *(t1++); + else + break; + + if (s < stop) + *(s++) = *(t2++); + else + break; + } + } +} + +#if TINYEXR_USE_PIZ + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wc++11-long-long" +#pragma clang diagnostic ignored "-Wold-style-cast" +#pragma clang diagnostic ignored "-Wpadded" +#pragma clang diagnostic ignored "-Wsign-conversion" +#pragma clang diagnostic ignored "-Wc++11-extensions" +#pragma clang diagnostic ignored "-Wconversion" +#endif + +// +// PIZ compress/uncompress, based on OpenEXR's ImfPizCompressor.cpp +// +// ----------------------------------------------------------------- +// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas +// Digital Ltd. LLC) +// (3 clause BSD license) +// + +struct PIZChannelData { + unsigned short *start; + unsigned short *end; + int nx; + int ny; + int ys; + int size; +}; + +//----------------------------------------------------------------------------- +// +// 16-bit Haar Wavelet encoding and decoding +// +// The source code in this file is derived from the encoding +// and decoding routines written by Christian Rouet for his +// PIZ image file format. +// +//----------------------------------------------------------------------------- + +// +// Wavelet basis functions without modulo arithmetic; they produce +// the best compression ratios when the wavelet-transformed data are +// Huffman-encoded, but the wavelet transform works only for 14-bit +// data (untransformed data values must be less than (1 << 14)). +// + +inline void wenc14(unsigned short a, unsigned short b, unsigned short &l, + unsigned short &h) { + short as = static_cast(a); + short bs = static_cast(b); + + short ms = (as + bs) >> 1; + short ds = as - bs; + + l = static_cast(ms); + h = static_cast(ds); +} + +inline void wdec14(unsigned short l, unsigned short h, unsigned short &a, + unsigned short &b) { + short ls = static_cast(l); + short hs = static_cast(h); + + int hi = hs; + int ai = ls + (hi & 1) + (hi >> 1); + + short as = static_cast(ai); + short bs = static_cast(ai - hi); + + a = static_cast(as); + b = static_cast(bs); +} + +// +// Wavelet basis functions with modulo arithmetic; they work with full +// 16-bit data, but Huffman-encoding the wavelet-transformed data doesn't +// compress the data quite as well. +// + +const int NBITS = 16; +const int A_OFFSET = 1 << (NBITS - 1); +const int M_OFFSET = 1 << (NBITS - 1); +const int MOD_MASK = (1 << NBITS) - 1; + +inline void wenc16(unsigned short a, unsigned short b, unsigned short &l, + unsigned short &h) { + int ao = (a + A_OFFSET) & MOD_MASK; + int m = ((ao + b) >> 1); + int d = ao - b; + + if (d < 0) m = (m + M_OFFSET) & MOD_MASK; + + d &= MOD_MASK; + + l = static_cast(m); + h = static_cast(d); +} + +inline void wdec16(unsigned short l, unsigned short h, unsigned short &a, + unsigned short &b) { + int m = l; + int d = h; + int bb = (m - (d >> 1)) & MOD_MASK; + int aa = (d + bb - A_OFFSET) & MOD_MASK; + b = static_cast(bb); + a = static_cast(aa); +} + +// +// 2D Wavelet encoding: +// + +static void wav2Encode( + unsigned short *in, // io: values are transformed in place + int nx, // i : x size + int ox, // i : x offset + int ny, // i : y size + int oy, // i : y offset + unsigned short mx) // i : maximum in[x][y] value +{ + bool w14 = (mx < (1 << 14)); + int n = (nx > ny) ? ny : nx; + int p = 1; // == 1 << level + int p2 = 2; // == 1 << (level+1) + + // + // Hierachical loop on smaller dimension n + // + + while (p2 <= n) { + unsigned short *py = in; + unsigned short *ey = in + oy * (ny - p2); + int oy1 = oy * p; + int oy2 = oy * p2; + int ox1 = ox * p; + int ox2 = ox * p2; + unsigned short i00, i01, i10, i11; + + // + // Y loop + // + + for (; py <= ey; py += oy2) { + unsigned short *px = py; + unsigned short *ex = py + ox * (nx - p2); + + // + // X loop + // + + for (; px <= ex; px += ox2) { + unsigned short *p01 = px + ox1; + unsigned short *p10 = px + oy1; + unsigned short *p11 = p10 + ox1; + + // + // 2D wavelet encoding + // + + if (w14) { + wenc14(*px, *p01, i00, i01); + wenc14(*p10, *p11, i10, i11); + wenc14(i00, i10, *px, *p10); + wenc14(i01, i11, *p01, *p11); + } else { + wenc16(*px, *p01, i00, i01); + wenc16(*p10, *p11, i10, i11); + wenc16(i00, i10, *px, *p10); + wenc16(i01, i11, *p01, *p11); + } + } + + // + // Encode (1D) odd column (still in Y loop) + // + + if (nx & p) { + unsigned short *p10 = px + oy1; + + if (w14) + wenc14(*px, *p10, i00, *p10); + else + wenc16(*px, *p10, i00, *p10); + + *px = i00; + } + } + + // + // Encode (1D) odd line (must loop in X) + // + + if (ny & p) { + unsigned short *px = py; + unsigned short *ex = py + ox * (nx - p2); + + for (; px <= ex; px += ox2) { + unsigned short *p01 = px + ox1; + + if (w14) + wenc14(*px, *p01, i00, *p01); + else + wenc16(*px, *p01, i00, *p01); + + *px = i00; + } + } + + // + // Next level + // + + p = p2; + p2 <<= 1; + } +} + +// +// 2D Wavelet decoding: +// + +static void wav2Decode( + unsigned short *in, // io: values are transformed in place + int nx, // i : x size + int ox, // i : x offset + int ny, // i : y size + int oy, // i : y offset + unsigned short mx) // i : maximum in[x][y] value +{ + bool w14 = (mx < (1 << 14)); + int n = (nx > ny) ? ny : nx; + int p = 1; + int p2; + + // + // Search max level + // + + while (p <= n) p <<= 1; + + p >>= 1; + p2 = p; + p >>= 1; + + // + // Hierarchical loop on smaller dimension n + // + + while (p >= 1) { + unsigned short *py = in; + unsigned short *ey = in + oy * (ny - p2); + int oy1 = oy * p; + int oy2 = oy * p2; + int ox1 = ox * p; + int ox2 = ox * p2; + unsigned short i00, i01, i10, i11; + + // + // Y loop + // + + for (; py <= ey; py += oy2) { + unsigned short *px = py; + unsigned short *ex = py + ox * (nx - p2); + + // + // X loop + // + + for (; px <= ex; px += ox2) { + unsigned short *p01 = px + ox1; + unsigned short *p10 = px + oy1; + unsigned short *p11 = p10 + ox1; + + // + // 2D wavelet decoding + // + + if (w14) { + wdec14(*px, *p10, i00, i10); + wdec14(*p01, *p11, i01, i11); + wdec14(i00, i01, *px, *p01); + wdec14(i10, i11, *p10, *p11); + } else { + wdec16(*px, *p10, i00, i10); + wdec16(*p01, *p11, i01, i11); + wdec16(i00, i01, *px, *p01); + wdec16(i10, i11, *p10, *p11); + } + } + + // + // Decode (1D) odd column (still in Y loop) + // + + if (nx & p) { + unsigned short *p10 = px + oy1; + + if (w14) + wdec14(*px, *p10, i00, *p10); + else + wdec16(*px, *p10, i00, *p10); + + *px = i00; + } + } + + // + // Decode (1D) odd line (must loop in X) + // + + if (ny & p) { + unsigned short *px = py; + unsigned short *ex = py + ox * (nx - p2); + + for (; px <= ex; px += ox2) { + unsigned short *p01 = px + ox1; + + if (w14) + wdec14(*px, *p01, i00, *p01); + else + wdec16(*px, *p01, i00, *p01); + + *px = i00; + } + } + + // + // Next level + // + + p2 = p; + p >>= 1; + } +} + +//----------------------------------------------------------------------------- +// +// 16-bit Huffman compression and decompression. +// +// The source code in this file is derived from the 8-bit +// Huffman compression and decompression routines written +// by Christian Rouet for his PIZ image file format. +// +//----------------------------------------------------------------------------- + +// Adds some modification for tinyexr. + +const int HUF_ENCBITS = 16; // literal (value) bit length +const int HUF_DECBITS = 14; // decoding bit size (>= 8) + +const int HUF_ENCSIZE = (1 << HUF_ENCBITS) + 1; // encoding table size +const int HUF_DECSIZE = 1 << HUF_DECBITS; // decoding table size +const int HUF_DECMASK = HUF_DECSIZE - 1; + +struct HufDec { // short code long code + //------------------------------- + int len : 8; // code length 0 + int lit : 24; // lit p size + int *p; // 0 lits +}; + +inline long long hufLength(long long code) { return code & 63; } + +inline long long hufCode(long long code) { return code >> 6; } + +inline void outputBits(int nBits, long long bits, long long &c, int &lc, + char *&out) { + c <<= nBits; + lc += nBits; + + c |= bits; + + while (lc >= 8) *out++ = static_cast((c >> (lc -= 8))); +} + +inline long long getBits(int nBits, long long &c, int &lc, const char *&in) { + while (lc < nBits) { + c = (c << 8) | *(reinterpret_cast(in++)); + lc += 8; + } + + lc -= nBits; + return (c >> lc) & ((1 << nBits) - 1); +} + +// +// ENCODING TABLE BUILDING & (UN)PACKING +// + +// +// Build a "canonical" Huffman code table: +// - for each (uncompressed) symbol, hcode contains the length +// of the corresponding code (in the compressed data) +// - canonical codes are computed and stored in hcode +// - the rules for constructing canonical codes are as follows: +// * shorter codes (if filled with zeroes to the right) +// have a numerically higher value than longer codes +// * for codes with the same length, numerical values +// increase with numerical symbol values +// - because the canonical code table can be constructed from +// symbol lengths alone, the code table can be transmitted +// without sending the actual code values +// - see http://www.compressconsult.com/huffman/ +// + +static void hufCanonicalCodeTable(long long hcode[HUF_ENCSIZE]) { + long long n[59]; + + // + // For each i from 0 through 58, count the + // number of different codes of length i, and + // store the count in n[i]. + // + + for (int i = 0; i <= 58; ++i) n[i] = 0; + + for (int i = 0; i < HUF_ENCSIZE; ++i) n[hcode[i]] += 1; + + // + // For each i from 58 through 1, compute the + // numerically lowest code with length i, and + // store that code in n[i]. + // + + long long c = 0; + + for (int i = 58; i > 0; --i) { + long long nc = ((c + n[i]) >> 1); + n[i] = c; + c = nc; + } + + // + // hcode[i] contains the length, l, of the + // code for symbol i. Assign the next available + // code of length l to the symbol and store both + // l and the code in hcode[i]. + // + + for (int i = 0; i < HUF_ENCSIZE; ++i) { + int l = static_cast(hcode[i]); + + if (l > 0) hcode[i] = l | (n[l]++ << 6); + } +} + +// +// Compute Huffman codes (based on frq input) and store them in frq: +// - code structure is : [63:lsb - 6:msb] | [5-0: bit length]; +// - max code length is 58 bits; +// - codes outside the range [im-iM] have a null length (unused values); +// - original frequencies are destroyed; +// - encoding tables are used by hufEncode() and hufBuildDecTable(); +// + +struct FHeapCompare { + bool operator()(long long *a, long long *b) { return *a > *b; } +}; + +static void hufBuildEncTable( + long long *frq, // io: input frequencies [HUF_ENCSIZE], output table + int *im, // o: min frq index + int *iM) // o: max frq index +{ + // + // This function assumes that when it is called, array frq + // indicates the frequency of all possible symbols in the data + // that are to be Huffman-encoded. (frq[i] contains the number + // of occurrences of symbol i in the data.) + // + // The loop below does three things: + // + // 1) Finds the minimum and maximum indices that point + // to non-zero entries in frq: + // + // frq[im] != 0, and frq[i] == 0 for all i < im + // frq[iM] != 0, and frq[i] == 0 for all i > iM + // + // 2) Fills array fHeap with pointers to all non-zero + // entries in frq. + // + // 3) Initializes array hlink such that hlink[i] == i + // for all array entries. + // + + int hlink[HUF_ENCSIZE]; + long long *fHeap[HUF_ENCSIZE]; + + *im = 0; + + while (!frq[*im]) (*im)++; + + int nf = 0; + + for (int i = *im; i < HUF_ENCSIZE; i++) { + hlink[i] = i; + + if (frq[i]) { + fHeap[nf] = &frq[i]; + nf++; + *iM = i; + } + } + + // + // Add a pseudo-symbol, with a frequency count of 1, to frq; + // adjust the fHeap and hlink array accordingly. Function + // hufEncode() uses the pseudo-symbol for run-length encoding. + // + + (*iM)++; + frq[*iM] = 1; + fHeap[nf] = &frq[*iM]; + nf++; + + // + // Build an array, scode, such that scode[i] contains the number + // of bits assigned to symbol i. Conceptually this is done by + // constructing a tree whose leaves are the symbols with non-zero + // frequency: + // + // Make a heap that contains all symbols with a non-zero frequency, + // with the least frequent symbol on top. + // + // Repeat until only one symbol is left on the heap: + // + // Take the two least frequent symbols off the top of the heap. + // Create a new node that has first two nodes as children, and + // whose frequency is the sum of the frequencies of the first + // two nodes. Put the new node back into the heap. + // + // The last node left on the heap is the root of the tree. For each + // leaf node, the distance between the root and the leaf is the length + // of the code for the corresponding symbol. + // + // The loop below doesn't actually build the tree; instead we compute + // the distances of the leaves from the root on the fly. When a new + // node is added to the heap, then that node's descendants are linked + // into a single linear list that starts at the new node, and the code + // lengths of the descendants (that is, their distance from the root + // of the tree) are incremented by one. + // + + std::make_heap(&fHeap[0], &fHeap[nf], FHeapCompare()); + + long long scode[HUF_ENCSIZE]; + memset(scode, 0, sizeof(long long) * HUF_ENCSIZE); + + while (nf > 1) { + // + // Find the indices, mm and m, of the two smallest non-zero frq + // values in fHeap, add the smallest frq to the second-smallest + // frq, and remove the smallest frq value from fHeap. + // + + int mm = fHeap[0] - frq; + std::pop_heap(&fHeap[0], &fHeap[nf], FHeapCompare()); + --nf; + + int m = fHeap[0] - frq; + std::pop_heap(&fHeap[0], &fHeap[nf], FHeapCompare()); + + frq[m] += frq[mm]; + std::push_heap(&fHeap[0], &fHeap[nf], FHeapCompare()); + + // + // The entries in scode are linked into lists with the + // entries in hlink serving as "next" pointers and with + // the end of a list marked by hlink[j] == j. + // + // Traverse the lists that start at scode[m] and scode[mm]. + // For each element visited, increment the length of the + // corresponding code by one bit. (If we visit scode[j] + // during the traversal, then the code for symbol j becomes + // one bit longer.) + // + // Merge the lists that start at scode[m] and scode[mm] + // into a single list that starts at scode[m]. + // + + // + // Add a bit to all codes in the first list. + // + + for (int j = m;; j = hlink[j]) { + scode[j]++; + + assert(scode[j] <= 58); + + if (hlink[j] == j) { + // + // Merge the two lists. + // + + hlink[j] = mm; + break; + } + } + + // + // Add a bit to all codes in the second list + // + + for (int j = mm;; j = hlink[j]) { + scode[j]++; + + assert(scode[j] <= 58); + + if (hlink[j] == j) break; + } + } + + // + // Build a canonical Huffman code table, replacing the code + // lengths in scode with (code, code length) pairs. Copy the + // code table from scode into frq. + // + + hufCanonicalCodeTable(scode); + memcpy(frq, scode, sizeof(long long) * HUF_ENCSIZE); +} + +// +// Pack an encoding table: +// - only code lengths, not actual codes, are stored +// - runs of zeroes are compressed as follows: +// +// unpacked packed +// -------------------------------- +// 1 zero 0 (6 bits) +// 2 zeroes 59 +// 3 zeroes 60 +// 4 zeroes 61 +// 5 zeroes 62 +// n zeroes (6 or more) 63 n-6 (6 + 8 bits) +// + +const int SHORT_ZEROCODE_RUN = 59; +const int LONG_ZEROCODE_RUN = 63; +const int SHORTEST_LONG_RUN = 2 + LONG_ZEROCODE_RUN - SHORT_ZEROCODE_RUN; +const int LONGEST_LONG_RUN = 255 + SHORTEST_LONG_RUN; + +static void hufPackEncTable( + const long long *hcode, // i : encoding table [HUF_ENCSIZE] + int im, // i : min hcode index + int iM, // i : max hcode index + char **pcode) // o: ptr to packed table (updated) +{ + char *p = *pcode; + long long c = 0; + int lc = 0; + + for (; im <= iM; im++) { + int l = hufLength(hcode[im]); + + if (l == 0) { + int zerun = 1; + + while ((im < iM) && (zerun < LONGEST_LONG_RUN)) { + if (hufLength(hcode[im + 1]) > 0) break; + im++; + zerun++; + } + + if (zerun >= 2) { + if (zerun >= SHORTEST_LONG_RUN) { + outputBits(6, LONG_ZEROCODE_RUN, c, lc, p); + outputBits(8, zerun - SHORTEST_LONG_RUN, c, lc, p); + } else { + outputBits(6, SHORT_ZEROCODE_RUN + zerun - 2, c, lc, p); + } + continue; + } + } + + outputBits(6, l, c, lc, p); + } + + if (lc > 0) *p++ = (unsigned char)(c << (8 - lc)); + + *pcode = p; +} + +// +// Unpack an encoding table packed by hufPackEncTable(): +// + +static bool hufUnpackEncTable( + const char **pcode, // io: ptr to packed table (updated) + int ni, // i : input size (in bytes) + int im, // i : min hcode index + int iM, // i : max hcode index + long long *hcode) // o: encoding table [HUF_ENCSIZE] +{ + memset(hcode, 0, sizeof(long long) * HUF_ENCSIZE); + + const char *p = *pcode; + long long c = 0; + int lc = 0; + + for (; im <= iM; im++) { + if (p - *pcode > ni) { + return false; + } + + long long l = hcode[im] = getBits(6, c, lc, p); // code length + + if (l == (long long)LONG_ZEROCODE_RUN) { + if (p - *pcode > ni) { + return false; + } + + int zerun = getBits(8, c, lc, p) + SHORTEST_LONG_RUN; + + if (im + zerun > iM + 1) { + return false; + } + + while (zerun--) hcode[im++] = 0; + + im--; + } else if (l >= (long long)SHORT_ZEROCODE_RUN) { + int zerun = l - SHORT_ZEROCODE_RUN + 2; + + if (im + zerun > iM + 1) { + return false; + } + + while (zerun--) hcode[im++] = 0; + + im--; + } + } + + *pcode = const_cast(p); + + hufCanonicalCodeTable(hcode); + + return true; +} + +// +// DECODING TABLE BUILDING +// + +// +// Clear a newly allocated decoding table so that it contains only zeroes. +// + +static void hufClearDecTable(HufDec *hdecod) // io: (allocated by caller) +// decoding table [HUF_DECSIZE] +{ + for (int i = 0; i < HUF_DECSIZE; i++) { + hdecod[i].len = 0; + hdecod[i].lit = 0; + hdecod[i].p = NULL; + } + // memset(hdecod, 0, sizeof(HufDec) * HUF_DECSIZE); +} + +// +// Build a decoding hash table based on the encoding table hcode: +// - short codes (<= HUF_DECBITS) are resolved with a single table access; +// - long code entry allocations are not optimized, because long codes are +// unfrequent; +// - decoding tables are used by hufDecode(); +// + +static bool hufBuildDecTable(const long long *hcode, // i : encoding table + int im, // i : min index in hcode + int iM, // i : max index in hcode + HufDec *hdecod) // o: (allocated by caller) +// decoding table [HUF_DECSIZE] +{ + // + // Init hashtable & loop on all codes. + // Assumes that hufClearDecTable(hdecod) has already been called. + // + + for (; im <= iM; im++) { + long long c = hufCode(hcode[im]); + int l = hufLength(hcode[im]); + + if (c >> l) { + // + // Error: c is supposed to be an l-bit code, + // but c contains a value that is greater + // than the largest l-bit number. + // + + // invalidTableEntry(); + return false; + } + + if (l > HUF_DECBITS) { + // + // Long code: add a secondary entry + // + + HufDec *pl = hdecod + (c >> (l - HUF_DECBITS)); + + if (pl->len) { + // + // Error: a short code has already + // been stored in table entry *pl. + // + + // invalidTableEntry(); + return false; + } + + pl->lit++; + + if (pl->p) { + int *p = pl->p; + pl->p = new int[pl->lit]; + + for (int i = 0; i < pl->lit - 1; ++i) pl->p[i] = p[i]; + + delete[] p; + } else { + pl->p = new int[1]; + } + + pl->p[pl->lit - 1] = im; + } else if (l) { + // + // Short code: init all primary entries + // + + HufDec *pl = hdecod + (c << (HUF_DECBITS - l)); + + for (long long i = 1ULL << (HUF_DECBITS - l); i > 0; i--, pl++) { + if (pl->len || pl->p) { + // + // Error: a short code or a long code has + // already been stored in table entry *pl. + // + + // invalidTableEntry(); + return false; + } + + pl->len = l; + pl->lit = im; + } + } + } + + return true; +} + +// +// Free the long code entries of a decoding table built by hufBuildDecTable() +// + +static void hufFreeDecTable(HufDec *hdecod) // io: Decoding table +{ + for (int i = 0; i < HUF_DECSIZE; i++) { + if (hdecod[i].p) { + delete[] hdecod[i].p; + hdecod[i].p = 0; + } + } +} + +// +// ENCODING +// + +inline void outputCode(long long code, long long &c, int &lc, char *&out) { + outputBits(hufLength(code), hufCode(code), c, lc, out); +} + +inline void sendCode(long long sCode, int runCount, long long runCode, + long long &c, int &lc, char *&out) { + // + // Output a run of runCount instances of the symbol sCount. + // Output the symbols explicitly, or if that is shorter, output + // the sCode symbol once followed by a runCode symbol and runCount + // expressed as an 8-bit number. + // + + if (hufLength(sCode) + hufLength(runCode) + 8 < hufLength(sCode) * runCount) { + outputCode(sCode, c, lc, out); + outputCode(runCode, c, lc, out); + outputBits(8, runCount, c, lc, out); + } else { + while (runCount-- >= 0) outputCode(sCode, c, lc, out); + } +} + +// +// Encode (compress) ni values based on the Huffman encoding table hcode: +// + +static int hufEncode // return: output size (in bits) + (const long long *hcode, // i : encoding table + const unsigned short *in, // i : uncompressed input buffer + const int ni, // i : input buffer size (in bytes) + int rlc, // i : rl code + char *out) // o: compressed output buffer +{ + char *outStart = out; + long long c = 0; // bits not yet written to out + int lc = 0; // number of valid bits in c (LSB) + int s = in[0]; + int cs = 0; + + // + // Loop on input values + // + + for (int i = 1; i < ni; i++) { + // + // Count same values or send code + // + + if (s == in[i] && cs < 255) { + cs++; + } else { + sendCode(hcode[s], cs, hcode[rlc], c, lc, out); + cs = 0; + } + + s = in[i]; + } + + // + // Send remaining code + // + + sendCode(hcode[s], cs, hcode[rlc], c, lc, out); + + if (lc) *out = (c << (8 - lc)) & 0xff; + + return (out - outStart) * 8 + lc; +} + +// +// DECODING +// + +// +// In order to force the compiler to inline them, +// getChar() and getCode() are implemented as macros +// instead of "inline" functions. +// + +#define getChar(c, lc, in) \ + { \ + c = (c << 8) | *(unsigned char *)(in++); \ + lc += 8; \ + } + +#define getCode(po, rlc, c, lc, in, out, oe) \ + { \ + if (po == rlc) { \ + if (lc < 8) getChar(c, lc, in); \ + \ + lc -= 8; \ + \ + unsigned char cs = (c >> lc); \ + \ + if (out + cs > oe) return false; \ + \ + unsigned short s = out[-1]; \ + \ + while (cs-- > 0) *out++ = s; \ + } else if (out < oe) { \ + *out++ = po; \ + } else { \ + return false; \ + } \ + } + +// +// Decode (uncompress) ni bits based on encoding & decoding tables: +// + +static bool hufDecode(const long long *hcode, // i : encoding table + const HufDec *hdecod, // i : decoding table + const char *in, // i : compressed input buffer + int ni, // i : input size (in bits) + int rlc, // i : run-length code + int no, // i : expected output size (in bytes) + unsigned short *out) // o: uncompressed output buffer +{ + long long c = 0; + int lc = 0; + unsigned short *outb = out; + unsigned short *oe = out + no; + const char *ie = in + (ni + 7) / 8; // input byte size + + // + // Loop on input bytes + // + + while (in < ie) { + getChar(c, lc, in); + + // + // Access decoding table + // + + while (lc >= HUF_DECBITS) { + const HufDec pl = hdecod[(c >> (lc - HUF_DECBITS)) & HUF_DECMASK]; + + if (pl.len) { + // + // Get short code + // + + lc -= pl.len; + getCode(pl.lit, rlc, c, lc, in, out, oe); + } else { + if (!pl.p) { + return false; + } + // invalidCode(); // wrong code + + // + // Search long code + // + + int j; + + for (j = 0; j < pl.lit; j++) { + int l = hufLength(hcode[pl.p[j]]); + + while (lc < l && in < ie) // get more bits + getChar(c, lc, in); + + if (lc >= l) { + if (hufCode(hcode[pl.p[j]]) == + ((c >> (lc - l)) & (((long long)(1) << l) - 1))) { + // + // Found : get long code + // + + lc -= l; + getCode(pl.p[j], rlc, c, lc, in, out, oe); + break; + } + } + } + + if (j == pl.lit) { + return false; + // invalidCode(); // Not found + } + } + } + } + + // + // Get remaining (short) codes + // + + int i = (8 - ni) & 7; + c >>= i; + lc -= i; + + while (lc > 0) { + const HufDec pl = hdecod[(c << (HUF_DECBITS - lc)) & HUF_DECMASK]; + + if (pl.len) { + lc -= pl.len; + getCode(pl.lit, rlc, c, lc, in, out, oe); + } else { + return false; + // invalidCode(); // wrong (long) code + } + } + + if (out - outb != no) { + return false; + } + // notEnoughData (); + + return true; +} + +static void countFrequencies(long long freq[HUF_ENCSIZE], + const unsigned short data[/*n*/], int n) { + for (int i = 0; i < HUF_ENCSIZE; ++i) freq[i] = 0; + + for (int i = 0; i < n; ++i) ++freq[data[i]]; +} + +static void writeUInt(char buf[4], unsigned int i) { + unsigned char *b = (unsigned char *)buf; + + b[0] = i; + b[1] = i >> 8; + b[2] = i >> 16; + b[3] = i >> 24; +} + +static unsigned int readUInt(const char buf[4]) { + const unsigned char *b = (const unsigned char *)buf; + + return (b[0] & 0x000000ff) | ((b[1] << 8) & 0x0000ff00) | + ((b[2] << 16) & 0x00ff0000) | ((b[3] << 24) & 0xff000000); +} + +// +// EXTERNAL INTERFACE +// + +static int hufCompress(const unsigned short raw[], int nRaw, + char compressed[]) { + if (nRaw == 0) return 0; + + long long freq[HUF_ENCSIZE]; + + countFrequencies(freq, raw, nRaw); + + int im = 0; + int iM = 0; + hufBuildEncTable(freq, &im, &iM); + + char *tableStart = compressed + 20; + char *tableEnd = tableStart; + hufPackEncTable(freq, im, iM, &tableEnd); + int tableLength = tableEnd - tableStart; + + char *dataStart = tableEnd; + int nBits = hufEncode(freq, raw, nRaw, iM, dataStart); + int data_length = (nBits + 7) / 8; + + writeUInt(compressed, im); + writeUInt(compressed + 4, iM); + writeUInt(compressed + 8, tableLength); + writeUInt(compressed + 12, nBits); + writeUInt(compressed + 16, 0); // room for future extensions + + return dataStart + data_length - compressed; +} + +static bool hufUncompress(const char compressed[], int nCompressed, + unsigned short raw[], int nRaw) { + if (nCompressed == 0) { + if (nRaw != 0) return false; + + return false; + } + + int im = readUInt(compressed); + int iM = readUInt(compressed + 4); + // int tableLength = readUInt (compressed + 8); + int nBits = readUInt(compressed + 12); + + if (im < 0 || im >= HUF_ENCSIZE || iM < 0 || iM >= HUF_ENCSIZE) return false; + + const char *ptr = compressed + 20; + + // + // Fast decoder needs at least 2x64-bits of compressed data, and + // needs to be run-able on this platform. Otherwise, fall back + // to the original decoder + // + + // if (FastHufDecoder::enabled() && nBits > 128) + //{ + // FastHufDecoder fhd (ptr, nCompressed - (ptr - compressed), im, iM, iM); + // fhd.decode ((unsigned char*)ptr, nBits, raw, nRaw); + //} + // else + { + std::vector freq(HUF_ENCSIZE); + std::vector hdec(HUF_DECSIZE); + + hufClearDecTable(&hdec.at(0)); + + hufUnpackEncTable(&ptr, nCompressed - (ptr - compressed), im, iM, + &freq.at(0)); + + { + if (nBits > 8 * (nCompressed - (ptr - compressed))) { + return false; + } + + hufBuildDecTable(&freq.at(0), im, iM, &hdec.at(0)); + hufDecode(&freq.at(0), &hdec.at(0), ptr, nBits, iM, nRaw, raw); + } + // catch (...) + //{ + // hufFreeDecTable (hdec); + // throw; + //} + + hufFreeDecTable(&hdec.at(0)); + } + + return true; +} + +// +// Functions to compress the range of values in the pixel data +// + +const int USHORT_RANGE = (1 << 16); +const int BITMAP_SIZE = (USHORT_RANGE >> 3); + +static void bitmapFromData(const unsigned short data[/*nData*/], int nData, + unsigned char bitmap[BITMAP_SIZE], + unsigned short &minNonZero, + unsigned short &maxNonZero) { + for (int i = 0; i < BITMAP_SIZE; ++i) bitmap[i] = 0; + + for (int i = 0; i < nData; ++i) bitmap[data[i] >> 3] |= (1 << (data[i] & 7)); + + bitmap[0] &= ~1; // zero is not explicitly stored in + // the bitmap; we assume that the + // data always contain zeroes + minNonZero = BITMAP_SIZE - 1; + maxNonZero = 0; + + for (int i = 0; i < BITMAP_SIZE; ++i) { + if (bitmap[i]) { + if (minNonZero > i) minNonZero = i; + if (maxNonZero < i) maxNonZero = i; + } + } +} + +static unsigned short forwardLutFromBitmap( + const unsigned char bitmap[BITMAP_SIZE], unsigned short lut[USHORT_RANGE]) { + int k = 0; + + for (int i = 0; i < USHORT_RANGE; ++i) { + if ((i == 0) || (bitmap[i >> 3] & (1 << (i & 7)))) + lut[i] = k++; + else + lut[i] = 0; + } + + return k - 1; // maximum value stored in lut[], +} // i.e. number of ones in bitmap minus 1 + +static unsigned short reverseLutFromBitmap( + const unsigned char bitmap[BITMAP_SIZE], unsigned short lut[USHORT_RANGE]) { + int k = 0; + + for (int i = 0; i < USHORT_RANGE; ++i) { + if ((i == 0) || (bitmap[i >> 3] & (1 << (i & 7)))) lut[k++] = i; + } + + int n = k - 1; + + while (k < USHORT_RANGE) lut[k++] = 0; + + return n; // maximum k where lut[k] is non-zero, +} // i.e. number of ones in bitmap minus 1 + +static void applyLut(const unsigned short lut[USHORT_RANGE], + unsigned short data[/*nData*/], int nData) { + for (int i = 0; i < nData; ++i) data[i] = lut[data[i]]; +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif // __clang__ + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + +static bool CompressPiz(unsigned char *outPtr, unsigned int *outSize, + const unsigned char *inPtr, size_t inSize, + const std::vector &channelInfo, + int data_width, int num_lines) { + unsigned char bitmap[BITMAP_SIZE]; + unsigned short minNonZero; + unsigned short maxNonZero; + +#if !MINIZ_LITTLE_ENDIAN + // @todo { PIZ compression on BigEndian architecture. } + assert(0); + return false; +#endif + + // Assume `inSize` is multiple of 2 or 4. + std::vector tmpBuffer(inSize / sizeof(unsigned short)); + + std::vector channelData(channelInfo.size()); + unsigned short *tmpBufferEnd = &tmpBuffer.at(0); + + for (size_t c = 0; c < channelData.size(); c++) { + PIZChannelData &cd = channelData[c]; + + cd.start = tmpBufferEnd; + cd.end = cd.start; + + cd.nx = data_width; + cd.ny = num_lines; + // cd.ys = c.channel().ySampling; + + size_t pixelSize = sizeof(int); // UINT and FLOAT + if (channelInfo[c].pixel_type == TINYEXR_PIXELTYPE_HALF) { + pixelSize = sizeof(short); + } + + cd.size = static_cast(pixelSize / sizeof(short)); + + tmpBufferEnd += cd.nx * cd.ny * cd.size; + } + + const unsigned char *ptr = inPtr; + for (int y = 0; y < num_lines; ++y) { + for (size_t i = 0; i < channelData.size(); ++i) { + PIZChannelData &cd = channelData[i]; + + // if (modp (y, cd.ys) != 0) + // continue; + + size_t n = static_cast(cd.nx * cd.size); + memcpy(cd.end, ptr, n * sizeof(unsigned short)); + ptr += n * sizeof(unsigned short); + cd.end += n; + } + } + + bitmapFromData(&tmpBuffer.at(0), static_cast(tmpBuffer.size()), bitmap, + minNonZero, maxNonZero); + + unsigned short lut[USHORT_RANGE]; + unsigned short maxValue = forwardLutFromBitmap(bitmap, lut); + applyLut(lut, &tmpBuffer.at(0), static_cast(tmpBuffer.size())); + + // + // Store range compression info in _outBuffer + // + + char *buf = reinterpret_cast(outPtr); + + memcpy(buf, &minNonZero, sizeof(unsigned short)); + buf += sizeof(unsigned short); + memcpy(buf, &maxNonZero, sizeof(unsigned short)); + buf += sizeof(unsigned short); + + if (minNonZero <= maxNonZero) { + memcpy(buf, reinterpret_cast(&bitmap[0] + minNonZero), + maxNonZero - minNonZero + 1); + buf += maxNonZero - minNonZero + 1; + } + + // + // Apply wavelet encoding + // + + for (size_t i = 0; i < channelData.size(); ++i) { + PIZChannelData &cd = channelData[i]; + + for (int j = 0; j < cd.size; ++j) { + wav2Encode(cd.start + j, cd.nx, cd.size, cd.ny, cd.nx * cd.size, + maxValue); + } + } + + // + // Apply Huffman encoding; append the result to _outBuffer + // + + // length header(4byte), then huff data. Initialize length header with zero, + // then later fill it by `length`. + char *lengthPtr = buf; + int zero = 0; + memcpy(buf, &zero, sizeof(int)); + buf += sizeof(int); + + int length = + hufCompress(&tmpBuffer.at(0), static_cast(tmpBuffer.size()), buf); + memcpy(lengthPtr, &length, sizeof(int)); + + (*outSize) = static_cast( + (reinterpret_cast(buf) - outPtr) + + static_cast(length)); + + // Use uncompressed data when compressed data is larger than uncompressed. + // (Issue 40) + if ((*outSize) >= inSize) { + (*outSize) = static_cast(inSize); + memcpy(outPtr, inPtr, inSize); + } + return true; +} + +static bool DecompressPiz(unsigned char *outPtr, const unsigned char *inPtr, + size_t tmpBufSize, size_t inLen, int num_channels, + const EXRChannelInfo *channels, int data_width, + int num_lines) { + if (inLen == tmpBufSize) { + // Data is not compressed(Issue 40). + memcpy(outPtr, inPtr, inLen); + return true; + } + + unsigned char bitmap[BITMAP_SIZE]; + unsigned short minNonZero; + unsigned short maxNonZero; + +#if !MINIZ_LITTLE_ENDIAN + // @todo { PIZ compression on BigEndian architecture. } + assert(0); + return false; +#endif + + memset(bitmap, 0, BITMAP_SIZE); + + const unsigned char *ptr = inPtr; + minNonZero = *(reinterpret_cast(ptr)); + maxNonZero = *(reinterpret_cast(ptr + 2)); + ptr += 4; + + if (maxNonZero >= BITMAP_SIZE) { + return false; + } + + if (minNonZero <= maxNonZero) { + memcpy(reinterpret_cast(&bitmap[0] + minNonZero), ptr, + maxNonZero - minNonZero + 1); + ptr += maxNonZero - minNonZero + 1; + } + + unsigned short lut[USHORT_RANGE]; + memset(lut, 0, sizeof(unsigned short) * USHORT_RANGE); + unsigned short maxValue = reverseLutFromBitmap(bitmap, lut); + + // + // Huffman decoding + // + + int length; + + length = *(reinterpret_cast(ptr)); + ptr += sizeof(int); + + std::vector tmpBuffer(tmpBufSize); + hufUncompress(reinterpret_cast(ptr), length, &tmpBuffer.at(0), + static_cast(tmpBufSize)); + + // + // Wavelet decoding + // + + std::vector channelData(static_cast(num_channels)); + + unsigned short *tmpBufferEnd = &tmpBuffer.at(0); + + for (size_t i = 0; i < static_cast(num_channels); ++i) { + const EXRChannelInfo &chan = channels[i]; + + size_t pixelSize = sizeof(int); // UINT and FLOAT + if (chan.pixel_type == TINYEXR_PIXELTYPE_HALF) { + pixelSize = sizeof(short); + } + + channelData[i].start = tmpBufferEnd; + channelData[i].end = channelData[i].start; + channelData[i].nx = data_width; + channelData[i].ny = num_lines; + // channelData[i].ys = 1; + channelData[i].size = static_cast(pixelSize / sizeof(short)); + + tmpBufferEnd += channelData[i].nx * channelData[i].ny * channelData[i].size; + } + + for (size_t i = 0; i < channelData.size(); ++i) { + PIZChannelData &cd = channelData[i]; + + for (int j = 0; j < cd.size; ++j) { + wav2Decode(cd.start + j, cd.nx, cd.size, cd.ny, cd.nx * cd.size, + maxValue); + } + } + + // + // Expand the pixel data to their original range + // + + applyLut(lut, &tmpBuffer.at(0), static_cast(tmpBufSize)); + + for (int y = 0; y < num_lines; y++) { + for (size_t i = 0; i < channelData.size(); ++i) { + PIZChannelData &cd = channelData[i]; + + // if (modp (y, cd.ys) != 0) + // continue; + + size_t n = static_cast(cd.nx * cd.size); + memcpy(outPtr, cd.end, static_cast(n * sizeof(unsigned short))); + outPtr += n * sizeof(unsigned short); + cd.end += n; + } + } + + return true; +} +#endif // TINYEXR_USE_PIZ + +#if TINYEXR_USE_ZFP +struct ZFPCompressionParam { + double rate; + int precision; + double tolerance; + int type; // TINYEXR_ZFP_COMPRESSIONTYPE_* + + ZFPCompressionParam() { + type = TINYEXR_ZFP_COMPRESSIONTYPE_RATE; + rate = 2.0; + precision = 0; + tolerance = 0.0f; + } +}; + +bool FindZFPCompressionParam(ZFPCompressionParam *param, + const EXRAttribute *attributes, + int num_attributes) { + bool foundType = false; + + for (int i = 0; i < num_attributes; i++) { + if ((strcmp(attributes[i].name, "zfpCompressionType") == 0) && + (attributes[i].size == 1)) { + param->type = static_cast(attributes[i].value[0]); + + foundType = true; + } + } + + if (!foundType) { + return false; + } + + if (param->type == TINYEXR_ZFP_COMPRESSIONTYPE_RATE) { + for (int i = 0; i < num_attributes; i++) { + if ((strcmp(attributes[i].name, "zfpCompressionRate") == 0) && + (attributes[i].size == 8)) { + param->rate = *(reinterpret_cast(attributes[i].value)); + return true; + } + } + } else if (param->type == TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION) { + for (int i = 0; i < num_attributes; i++) { + if ((strcmp(attributes[i].name, "zfpCompressionPrecision") == 0) && + (attributes[i].size == 4)) { + param->rate = *(reinterpret_cast(attributes[i].value)); + return true; + } + } + } else if (param->type == TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY) { + for (int i = 0; i < num_attributes; i++) { + if ((strcmp(attributes[i].name, "zfpCompressionTolerance") == 0) && + (attributes[i].size == 8)) { + param->tolerance = *(reinterpret_cast(attributes[i].value)); + return true; + } + } + } else { + assert(0); + } + + return false; +} + +// Assume pixel format is FLOAT for all channels. +static bool DecompressZfp(float *dst, int dst_width, int dst_num_lines, + int num_channels, const unsigned char *src, + unsigned long src_size, + const ZFPCompressionParam ¶m) { + size_t uncompressed_size = dst_width * dst_num_lines * num_channels; + + if (uncompressed_size == src_size) { + // Data is not compressed(Issue 40). + memcpy(dst, src, src_size); + } + + zfp_stream *zfp = NULL; + zfp_field *field = NULL; + + assert((dst_width % 4) == 0); + assert((dst_num_lines % 4) == 0); + + if ((dst_width & 3U) || (dst_num_lines & 3U)) { + return false; + } + + field = + zfp_field_2d(reinterpret_cast(const_cast(src)), + zfp_type_float, dst_width, dst_num_lines * num_channels); + zfp = zfp_stream_open(NULL); + + if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_RATE) { + zfp_stream_set_rate(zfp, param.rate, zfp_type_float, /* dimention */ 2, + /* write random access */ 0); + } else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION) { + zfp_stream_set_precision(zfp, param.precision, zfp_type_float); + } else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY) { + zfp_stream_set_accuracy(zfp, param.tolerance, zfp_type_float); + } else { + assert(0); + } + + size_t buf_size = zfp_stream_maximum_size(zfp, field); + std::vector buf(buf_size); + memcpy(&buf.at(0), src, src_size); + + bitstream *stream = stream_open(&buf.at(0), buf_size); + zfp_stream_set_bit_stream(zfp, stream); + zfp_stream_rewind(zfp); + + size_t image_size = dst_width * dst_num_lines; + + for (int c = 0; c < num_channels; c++) { + // decompress 4x4 pixel block. + for (int y = 0; y < dst_num_lines; y += 4) { + for (int x = 0; x < dst_width; x += 4) { + float fblock[16]; + zfp_decode_block_float_2(zfp, fblock); + for (int j = 0; j < 4; j++) { + for (int i = 0; i < 4; i++) { + dst[c * image_size + ((y + j) * dst_width + (x + i))] = + fblock[j * 4 + i]; + } + } + } + } + } + + zfp_field_free(field); + zfp_stream_close(zfp); + stream_close(stream); + + return true; +} + +// Assume pixel format is FLOAT for all channels. +bool CompressZfp(std::vector *outBuf, unsigned int *outSize, + const float *inPtr, int width, int num_lines, int num_channels, + const ZFPCompressionParam ¶m) { + zfp_stream *zfp = NULL; + zfp_field *field = NULL; + + assert((width % 4) == 0); + assert((num_lines % 4) == 0); + + if ((width & 3U) || (num_lines & 3U)) { + return false; + } + + // create input array. + field = zfp_field_2d(reinterpret_cast(const_cast(inPtr)), + zfp_type_float, width, num_lines * num_channels); + + zfp = zfp_stream_open(NULL); + + if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_RATE) { + zfp_stream_set_rate(zfp, param.rate, zfp_type_float, 2, 0); + } else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION) { + zfp_stream_set_precision(zfp, param.precision, zfp_type_float); + } else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY) { + zfp_stream_set_accuracy(zfp, param.tolerance, zfp_type_float); + } else { + assert(0); + } + + size_t buf_size = zfp_stream_maximum_size(zfp, field); + + outBuf->resize(buf_size); + + bitstream *stream = stream_open(&outBuf->at(0), buf_size); + zfp_stream_set_bit_stream(zfp, stream); + zfp_field_free(field); + + size_t image_size = width * num_lines; + + for (int c = 0; c < num_channels; c++) { + // compress 4x4 pixel block. + for (int y = 0; y < num_lines; y += 4) { + for (int x = 0; x < width; x += 4) { + float fblock[16]; + for (int j = 0; j < 4; j++) { + for (int i = 0; i < 4; i++) { + fblock[j * 4 + i] = + inPtr[c * image_size + ((y + j) * width + (x + i))]; + } + } + zfp_encode_block_float_2(zfp, fblock); + } + } + } + + zfp_stream_flush(zfp); + (*outSize) = zfp_stream_compressed_size(zfp); + + zfp_stream_close(zfp); + + return true; +} + +#endif + +// +// ----------------------------------------------------------------- +// + +static void DecodePixelData(/* out */ unsigned char **out_images, + const int *requested_pixel_types, + const unsigned char *data_ptr, size_t data_len, + int compression_type, int line_order, int width, + int height, int x_stride, int y, int line_no, + int num_lines, size_t pixel_data_size, + size_t num_attributes, + const EXRAttribute *attributes, size_t num_channels, + const EXRChannelInfo *channels, + const std::vector &channel_offset_list) { + if (compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) { // PIZ +#if TINYEXR_USE_PIZ + // Allocate original data size. + std::vector outBuf(static_cast( + static_cast(width * num_lines) * pixel_data_size)); + size_t tmpBufLen = outBuf.size(); + + bool ret = tinyexr::DecompressPiz( + reinterpret_cast(&outBuf.at(0)), data_ptr, tmpBufLen, + data_len, static_cast(num_channels), channels, width, num_lines); + + assert(ret); + (void)ret; + + // For PIZ_COMPRESSION: + // pixel sample data for channel 0 for scanline 0 + // pixel sample data for channel 1 for scanline 0 + // pixel sample data for channel ... for scanline 0 + // pixel sample data for channel n for scanline 0 + // pixel sample data for channel 0 for scanline 1 + // pixel sample data for channel 1 for scanline 1 + // pixel sample data for channel ... for scanline 1 + // pixel sample data for channel n for scanline 1 + // ... + for (size_t c = 0; c < static_cast(num_channels); c++) { + if (channels[c].pixel_type == TINYEXR_PIXELTYPE_HALF) { + for (size_t v = 0; v < static_cast(num_lines); v++) { + const unsigned short *line_ptr = reinterpret_cast( + &outBuf.at(v * pixel_data_size * static_cast(width) + + channel_offset_list[c] * static_cast(width))); + for (size_t u = 0; u < static_cast(width); u++) { + FP16 hf; + + hf.u = line_ptr[u]; + + tinyexr::swap2(reinterpret_cast(&hf.u)); + + if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_HALF) { + unsigned short *image = + reinterpret_cast(out_images)[c]; + if (line_order == 0) { + image += (static_cast(line_no) + v) * + static_cast(x_stride) + + u; + } else { + image += static_cast( + (height - 1 - (line_no + static_cast(v)))) * + static_cast(x_stride) + + u; + } + *image = hf.u; + } else { // HALF -> FLOAT + FP32 f32 = half_to_float(hf); + float *image = reinterpret_cast(out_images)[c]; + if (line_order == 0) { + image += (static_cast(line_no) + v) * + static_cast(x_stride) + + u; + } else { + image += static_cast( + (height - 1 - (line_no + static_cast(v)))) * + static_cast(x_stride) + + u; + } + *image = f32.f; + } + } + } + } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_UINT) { + assert(requested_pixel_types[c] == TINYEXR_PIXELTYPE_UINT); + + for (size_t v = 0; v < static_cast(num_lines); v++) { + const unsigned int *line_ptr = reinterpret_cast( + &outBuf.at(v * pixel_data_size * static_cast(width) + + channel_offset_list[c] * static_cast(width))); + for (size_t u = 0; u < static_cast(width); u++) { + unsigned int val = line_ptr[u]; + + tinyexr::swap4(&val); + + unsigned int *image = + reinterpret_cast(out_images)[c]; + if (line_order == 0) { + image += (static_cast(line_no) + v) * + static_cast(x_stride) + + u; + } else { + image += static_cast( + (height - 1 - (line_no + static_cast(v)))) * + static_cast(x_stride) + + u; + } + *image = val; + } + } + } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT) { + assert(requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT); + for (size_t v = 0; v < static_cast(num_lines); v++) { + const float *line_ptr = reinterpret_cast(&outBuf.at( + v * pixel_data_size * static_cast(x_stride) + + channel_offset_list[c] * static_cast(x_stride))); + for (size_t u = 0; u < static_cast(width); u++) { + float val = line_ptr[u]; + + tinyexr::swap4(reinterpret_cast(&val)); + + float *image = reinterpret_cast(out_images)[c]; + if (line_order == 0) { + image += (static_cast(line_no) + v) * + static_cast(x_stride) + + u; + } else { + image += static_cast( + (height - 1 - (line_no + static_cast(v)))) * + static_cast(x_stride) + + u; + } + *image = val; + } + } + } else { + assert(0); + } + } +#else + assert(0 && "PIZ is enabled in this build"); +#endif + + } else if (compression_type == TINYEXR_COMPRESSIONTYPE_ZIPS || + compression_type == TINYEXR_COMPRESSIONTYPE_ZIP) { + // Allocate original data size. + std::vector outBuf(static_cast(width) * + static_cast(num_lines) * + pixel_data_size); + + unsigned long dstLen = static_cast(outBuf.size()); + assert(dstLen > 0); + tinyexr::DecompressZip(reinterpret_cast(&outBuf.at(0)), + &dstLen, data_ptr, + static_cast(data_len)); + + // For ZIP_COMPRESSION: + // pixel sample data for channel 0 for scanline 0 + // pixel sample data for channel 1 for scanline 0 + // pixel sample data for channel ... for scanline 0 + // pixel sample data for channel n for scanline 0 + // pixel sample data for channel 0 for scanline 1 + // pixel sample data for channel 1 for scanline 1 + // pixel sample data for channel ... for scanline 1 + // pixel sample data for channel n for scanline 1 + // ... + for (size_t c = 0; c < static_cast(num_channels); c++) { + if (channels[c].pixel_type == TINYEXR_PIXELTYPE_HALF) { + for (size_t v = 0; v < static_cast(num_lines); v++) { + const unsigned short *line_ptr = reinterpret_cast( + &outBuf.at(v * static_cast(pixel_data_size) * + static_cast(width) + + channel_offset_list[c] * static_cast(width))); + for (size_t u = 0; u < static_cast(width); u++) { + tinyexr::FP16 hf; + + hf.u = line_ptr[u]; + + tinyexr::swap2(reinterpret_cast(&hf.u)); + + if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_HALF) { + unsigned short *image = + reinterpret_cast(out_images)[c]; + if (line_order == 0) { + image += (static_cast(line_no) + v) * + static_cast(x_stride) + + u; + } else { + image += (static_cast(height) - 1U - + (static_cast(line_no) + v)) * + static_cast(x_stride) + + u; + } + *image = hf.u; + } else { // HALF -> FLOAT + tinyexr::FP32 f32 = half_to_float(hf); + float *image = reinterpret_cast(out_images)[c]; + if (line_order == 0) { + image += (static_cast(line_no) + v) * + static_cast(x_stride) + + u; + } else { + image += (static_cast(height) - 1U - + (static_cast(line_no) + v)) * + static_cast(x_stride) + + u; + } + *image = f32.f; + } + } + } + } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_UINT) { + assert(requested_pixel_types[c] == TINYEXR_PIXELTYPE_UINT); + + for (size_t v = 0; v < static_cast(num_lines); v++) { + const unsigned int *line_ptr = reinterpret_cast( + &outBuf.at(v * pixel_data_size * static_cast(width) + + channel_offset_list[c] * static_cast(width))); + for (size_t u = 0; u < static_cast(width); u++) { + unsigned int val = line_ptr[u]; + + tinyexr::swap4(&val); + + unsigned int *image = + reinterpret_cast(out_images)[c]; + if (line_order == 0) { + image += (static_cast(line_no) + v) * + static_cast(x_stride) + + u; + } else { + image += (static_cast(height) - 1U - + (static_cast(line_no) + v)) * + static_cast(x_stride) + + u; + } + *image = val; + } + } + } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT) { + assert(requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT); + for (size_t v = 0; v < static_cast(num_lines); v++) { + const float *line_ptr = reinterpret_cast( + &outBuf.at(v * pixel_data_size * static_cast(width) + + channel_offset_list[c] * static_cast(width))); + for (size_t u = 0; u < static_cast(width); u++) { + float val = line_ptr[u]; + + tinyexr::swap4(reinterpret_cast(&val)); + + float *image = reinterpret_cast(out_images)[c]; + if (line_order == 0) { + image += (static_cast(line_no) + v) * + static_cast(x_stride) + + u; + } else { + image += (static_cast(height) - 1U - + (static_cast(line_no) + v)) * + static_cast(x_stride) + + u; + } + *image = val; + } + } + } else { + assert(0); + } + } + } else if (compression_type == TINYEXR_COMPRESSIONTYPE_RLE) { + // Allocate original data size. + std::vector outBuf(static_cast(width) * + static_cast(num_lines) * + pixel_data_size); + + unsigned long dstLen = static_cast(outBuf.size()); + assert(dstLen > 0); + tinyexr::DecompressRle(reinterpret_cast(&outBuf.at(0)), + dstLen, data_ptr, + static_cast(data_len)); + + // For RLE_COMPRESSION: + // pixel sample data for channel 0 for scanline 0 + // pixel sample data for channel 1 for scanline 0 + // pixel sample data for channel ... for scanline 0 + // pixel sample data for channel n for scanline 0 + // pixel sample data for channel 0 for scanline 1 + // pixel sample data for channel 1 for scanline 1 + // pixel sample data for channel ... for scanline 1 + // pixel sample data for channel n for scanline 1 + // ... + for (size_t c = 0; c < static_cast(num_channels); c++) { + if (channels[c].pixel_type == TINYEXR_PIXELTYPE_HALF) { + for (size_t v = 0; v < static_cast(num_lines); v++) { + const unsigned short *line_ptr = reinterpret_cast( + &outBuf.at(v * static_cast(pixel_data_size) * + static_cast(width) + + channel_offset_list[c] * static_cast(width))); + for (size_t u = 0; u < static_cast(width); u++) { + tinyexr::FP16 hf; + + hf.u = line_ptr[u]; + + tinyexr::swap2(reinterpret_cast(&hf.u)); + + if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_HALF) { + unsigned short *image = + reinterpret_cast(out_images)[c]; + if (line_order == 0) { + image += (static_cast(line_no) + v) * + static_cast(x_stride) + + u; + } else { + image += (static_cast(height) - 1U - + (static_cast(line_no) + v)) * + static_cast(x_stride) + + u; + } + *image = hf.u; + } else { // HALF -> FLOAT + tinyexr::FP32 f32 = half_to_float(hf); + float *image = reinterpret_cast(out_images)[c]; + if (line_order == 0) { + image += (static_cast(line_no) + v) * + static_cast(x_stride) + + u; + } else { + image += (static_cast(height) - 1U - + (static_cast(line_no) + v)) * + static_cast(x_stride) + + u; + } + *image = f32.f; + } + } + } + } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_UINT) { + assert(requested_pixel_types[c] == TINYEXR_PIXELTYPE_UINT); + + for (size_t v = 0; v < static_cast(num_lines); v++) { + const unsigned int *line_ptr = reinterpret_cast( + &outBuf.at(v * pixel_data_size * static_cast(width) + + channel_offset_list[c] * static_cast(width))); + for (size_t u = 0; u < static_cast(width); u++) { + unsigned int val = line_ptr[u]; + + tinyexr::swap4(&val); + + unsigned int *image = + reinterpret_cast(out_images)[c]; + if (line_order == 0) { + image += (static_cast(line_no) + v) * + static_cast(x_stride) + + u; + } else { + image += (static_cast(height) - 1U - + (static_cast(line_no) + v)) * + static_cast(x_stride) + + u; + } + *image = val; + } + } + } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT) { + assert(requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT); + for (size_t v = 0; v < static_cast(num_lines); v++) { + const float *line_ptr = reinterpret_cast( + &outBuf.at(v * pixel_data_size * static_cast(width) + + channel_offset_list[c] * static_cast(width))); + for (size_t u = 0; u < static_cast(width); u++) { + float val = line_ptr[u]; + + tinyexr::swap4(reinterpret_cast(&val)); + + float *image = reinterpret_cast(out_images)[c]; + if (line_order == 0) { + image += (static_cast(line_no) + v) * + static_cast(x_stride) + + u; + } else { + image += (static_cast(height) - 1U - + (static_cast(line_no) + v)) * + static_cast(x_stride) + + u; + } + *image = val; + } + } + } else { + assert(0); + } + } + } else if (compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) { +#if TINYEXR_USE_ZFP + tinyexr::ZFPCompressionParam zfp_compression_param; + if (!FindZFPCompressionParam(&zfp_compression_param, attributes, + num_attributes)) { + assert(0); + return; + } + + // Allocate original data size. + std::vector outBuf(static_cast(width) * + static_cast(num_lines) * + pixel_data_size); + + unsigned long dstLen = outBuf.size(); + assert(dstLen > 0); + tinyexr::DecompressZfp(reinterpret_cast(&outBuf.at(0)), width, + num_lines, num_channels, data_ptr, + static_cast(data_len), + zfp_compression_param); + + // For ZFP_COMPRESSION: + // pixel sample data for channel 0 for scanline 0 + // pixel sample data for channel 1 for scanline 0 + // pixel sample data for channel ... for scanline 0 + // pixel sample data for channel n for scanline 0 + // pixel sample data for channel 0 for scanline 1 + // pixel sample data for channel 1 for scanline 1 + // pixel sample data for channel ... for scanline 1 + // pixel sample data for channel n for scanline 1 + // ... + for (size_t c = 0; c < static_cast(num_channels); c++) { + assert(channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT); + if (channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT) { + assert(requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT); + for (size_t v = 0; v < static_cast(num_lines); v++) { + const float *line_ptr = reinterpret_cast( + &outBuf.at(v * pixel_data_size * static_cast(width) + + channel_offset_list[c] * static_cast(width))); + for (size_t u = 0; u < static_cast(width); u++) { + float val = line_ptr[u]; + + tinyexr::swap4(reinterpret_cast(&val)); + + float *image = reinterpret_cast(out_images)[c]; + if (line_order == 0) { + image += (static_cast(line_no) + v) * + static_cast(x_stride) + + u; + } else { + image += (static_cast(height) - 1U - + (static_cast(line_no) + v)) * + static_cast(x_stride) + + u; + } + *image = val; + } + } + } else { + assert(0); + } + } +#else + (void)attributes; + (void)num_attributes; + (void)num_channels; + assert(0); +#endif + } else if (compression_type == TINYEXR_COMPRESSIONTYPE_NONE) { + for (size_t c = 0; c < num_channels; c++) { + if (channels[c].pixel_type == TINYEXR_PIXELTYPE_HALF) { + const unsigned short *line_ptr = + reinterpret_cast( + data_ptr + + c * static_cast(width) * sizeof(unsigned short)); + + if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_HALF) { + unsigned short *outLine = + reinterpret_cast(out_images[c]); + if (line_order == 0) { + outLine += y * x_stride; + } else { + outLine += (height - 1 - y) * x_stride; + } + + for (int u = 0; u < width; u++) { + tinyexr::FP16 hf; + + hf.u = line_ptr[u]; + + tinyexr::swap2(reinterpret_cast(&hf.u)); + + outLine[u] = hf.u; + } + } else if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT) { + float *outLine = reinterpret_cast(out_images[c]); + if (line_order == 0) { + outLine += y * x_stride; + } else { + outLine += (height - 1 - y) * x_stride; + } + + for (int u = 0; u < width; u++) { + tinyexr::FP16 hf; + + hf.u = line_ptr[u]; + + tinyexr::swap2(reinterpret_cast(&hf.u)); + + tinyexr::FP32 f32 = half_to_float(hf); + + outLine[u] = f32.f; + } + } else { + assert(0); + } + } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT) { + const float *line_ptr = reinterpret_cast( + data_ptr + c * static_cast(width) * sizeof(float)); + + float *outLine = reinterpret_cast(out_images[c]); + if (line_order == 0) { + outLine += y * x_stride; + } else { + outLine += (height - 1 - y) * x_stride; + } + + for (int u = 0; u < width; u++) { + float val = line_ptr[u]; + + tinyexr::swap4(reinterpret_cast(&val)); + + outLine[u] = val; + } + } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_UINT) { + const unsigned int *line_ptr = reinterpret_cast( + data_ptr + c * static_cast(width) * sizeof(unsigned int)); + + unsigned int *outLine = reinterpret_cast(out_images[c]); + if (line_order == 0) { + outLine += y * x_stride; + } else { + outLine += (height - 1 - y) * x_stride; + } + + for (int u = 0; u < width; u++) { + unsigned int val = line_ptr[u]; + + tinyexr::swap4(reinterpret_cast(&val)); + + outLine[u] = val; + } + } + } + } +} + +static void DecodeTiledPixelData( + unsigned char **out_images, int *width, int *height, + const int *requested_pixel_types, const unsigned char *data_ptr, + size_t data_len, int compression_type, int line_order, int data_width, + int data_height, int tile_offset_x, int tile_offset_y, int tile_size_x, + int tile_size_y, size_t pixel_data_size, size_t num_attributes, + const EXRAttribute *attributes, size_t num_channels, + const EXRChannelInfo *channels, + const std::vector &channel_offset_list) { + assert(tile_offset_x * tile_size_x < data_width); + assert(tile_offset_y * tile_size_y < data_height); + + // Compute actual image size in a tile. + if ((tile_offset_x + 1) * tile_size_x >= data_width) { + (*width) = data_width - (tile_offset_x * tile_size_x); + } else { + (*width) = tile_size_x; + } + + if ((tile_offset_y + 1) * tile_size_y >= data_height) { + (*height) = data_height - (tile_offset_y * tile_size_y); + } else { + (*height) = tile_size_y; + } + + // Image size = tile size. + DecodePixelData(out_images, requested_pixel_types, data_ptr, data_len, + compression_type, line_order, (*width), tile_size_y, + /* stride */ tile_size_x, /* y */ 0, /* line_no */ 0, + (*height), pixel_data_size, num_attributes, attributes, + num_channels, channels, channel_offset_list); +} + +static void ComputeChannelLayout(std::vector *channel_offset_list, + int *pixel_data_size, size_t *channel_offset, + int num_channels, + const EXRChannelInfo *channels) { + channel_offset_list->resize(static_cast(num_channels)); + + (*pixel_data_size) = 0; + (*channel_offset) = 0; + + for (size_t c = 0; c < static_cast(num_channels); c++) { + (*channel_offset_list)[c] = (*channel_offset); + if (channels[c].pixel_type == TINYEXR_PIXELTYPE_HALF) { + (*pixel_data_size) += sizeof(unsigned short); + (*channel_offset) += sizeof(unsigned short); + } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT) { + (*pixel_data_size) += sizeof(float); + (*channel_offset) += sizeof(float); + } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_UINT) { + (*pixel_data_size) += sizeof(unsigned int); + (*channel_offset) += sizeof(unsigned int); + } else { + assert(0); + } + } +} + +static unsigned char **AllocateImage(int num_channels, + const EXRChannelInfo *channels, + const int *requested_pixel_types, + int data_width, int data_height) { + unsigned char **images = + reinterpret_cast(static_cast( + malloc(sizeof(float *) * static_cast(num_channels)))); + + for (size_t c = 0; c < static_cast(num_channels); c++) { + size_t data_len = + static_cast(data_width) * static_cast(data_height); + if (channels[c].pixel_type == TINYEXR_PIXELTYPE_HALF) { + // pixel_data_size += sizeof(unsigned short); + // channel_offset += sizeof(unsigned short); + // Alloc internal image for half type. + if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_HALF) { + images[c] = + reinterpret_cast(static_cast( + malloc(sizeof(unsigned short) * data_len))); + } else if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT) { + images[c] = reinterpret_cast( + static_cast(malloc(sizeof(float) * data_len))); + } else { + assert(0); + } + } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT) { + // pixel_data_size += sizeof(float); + // channel_offset += sizeof(float); + images[c] = reinterpret_cast( + static_cast(malloc(sizeof(float) * data_len))); + } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_UINT) { + // pixel_data_size += sizeof(unsigned int); + // channel_offset += sizeof(unsigned int); + images[c] = reinterpret_cast( + static_cast(malloc(sizeof(unsigned int) * data_len))); + } else { + assert(0); + } + } + + return images; +} + +static int ParseEXRHeader(HeaderInfo *info, bool *empty_header, + const EXRVersion *version, std::string *err, + const unsigned char *buf, size_t size) { + const char *marker = reinterpret_cast(&buf[0]); + + if (empty_header) { + (*empty_header) = false; + } + + if (version->multipart) { + if (size > 0 && marker[0] == '\0') { + // End of header list. + if (empty_header) { + (*empty_header) = true; + } + return TINYEXR_SUCCESS; + } + } + + // According to the spec, the header of every OpenEXR file must contain at + // least the following attributes: + // + // channels chlist + // compression compression + // dataWindow box2i + // displayWindow box2i + // lineOrder lineOrder + // pixelAspectRatio float + // screenWindowCenter v2f + // screenWindowWidth float + bool has_channels = false; + bool has_compression = false; + bool has_data_window = false; + bool has_display_window = false; + bool has_line_order = false; + bool has_pixel_aspect_ratio = false; + bool has_screen_window_center = false; + bool has_screen_window_width = false; + + info->data_window[0] = 0; + info->data_window[1] = 0; + info->data_window[2] = 0; + info->data_window[3] = 0; + info->line_order = 0; // @fixme + info->display_window[0] = 0; + info->display_window[1] = 0; + info->display_window[2] = 0; + info->display_window[3] = 0; + info->screen_window_center[0] = 0.0f; + info->screen_window_center[1] = 0.0f; + info->screen_window_width = -1.0f; + info->pixel_aspect_ratio = -1.0f; + + info->tile_size_x = -1; + info->tile_size_y = -1; + info->tile_level_mode = -1; + info->tile_rounding_mode = -1; + + info->attributes.clear(); + + // Read attributes + size_t orig_size = size; + for (;;) { + if (0 == size) { + return TINYEXR_ERROR_INVALID_DATA; + } else if (marker[0] == '\0') { + size--; + break; + } + + std::string attr_name; + std::string attr_type; + std::vector data; + size_t marker_size; + if (!tinyexr::ReadAttribute(&attr_name, &attr_type, &data, &marker_size, + marker, size)) { + return TINYEXR_ERROR_INVALID_DATA; + } + marker += marker_size; + size -= marker_size; + + if (version->tiled && attr_name.compare("tiles") == 0) { + unsigned int x_size, y_size; + unsigned char tile_mode; + assert(data.size() == 9); + memcpy(&x_size, &data.at(0), sizeof(int)); + memcpy(&y_size, &data.at(4), sizeof(int)); + tile_mode = data[8]; + tinyexr::swap4(&x_size); + tinyexr::swap4(&y_size); + + info->tile_size_x = static_cast(x_size); + info->tile_size_y = static_cast(y_size); + + // mode = levelMode + roundingMode * 16 + info->tile_level_mode = tile_mode & 0x3; + info->tile_rounding_mode = (tile_mode >> 4) & 0x1; + + } else if (attr_name.compare("compression") == 0) { + bool ok = false; + if (data[0] < TINYEXR_COMPRESSIONTYPE_PIZ) { + ok = true; + } + + if (data[0] == TINYEXR_COMPRESSIONTYPE_PIZ) { +#if TINYEXR_USE_PIZ + ok = true; +#else + if (err) { + (*err) = "PIZ compression is not supported."; + } + return TINYEXR_ERROR_UNSUPPORTED_FORMAT; +#endif + } + + if (data[0] == TINYEXR_COMPRESSIONTYPE_ZFP) { +#if TINYEXR_USE_ZFP + ok = true; +#else + if (err) { + (*err) = "ZFP compression is not supported."; + } + return TINYEXR_ERROR_UNSUPPORTED_FORMAT; +#endif + } + + if (!ok) { + if (err) { + (*err) = "Unknown compression type."; + } + return TINYEXR_ERROR_UNSUPPORTED_FORMAT; + } + + info->compression_type = static_cast(data[0]); + has_compression = true; + + } else if (attr_name.compare("channels") == 0) { + // name: zero-terminated string, from 1 to 255 bytes long + // pixel type: int, possible values are: UINT = 0 HALF = 1 FLOAT = 2 + // pLinear: unsigned char, possible values are 0 and 1 + // reserved: three chars, should be zero + // xSampling: int + // ySampling: int + + ReadChannelInfo(info->channels, data); + + if (info->channels.size() < 1) { + if (err) { + (*err) = "# of channels is zero."; + } + return TINYEXR_ERROR_INVALID_DATA; + } + + has_channels = true; + + } else if (attr_name.compare("dataWindow") == 0) { + memcpy(&info->data_window[0], &data.at(0), sizeof(int)); + memcpy(&info->data_window[1], &data.at(4), sizeof(int)); + memcpy(&info->data_window[2], &data.at(8), sizeof(int)); + memcpy(&info->data_window[3], &data.at(12), sizeof(int)); + tinyexr::swap4(reinterpret_cast(&info->data_window[0])); + tinyexr::swap4(reinterpret_cast(&info->data_window[1])); + tinyexr::swap4(reinterpret_cast(&info->data_window[2])); + tinyexr::swap4(reinterpret_cast(&info->data_window[3])); + + has_data_window = true; + } else if (attr_name.compare("displayWindow") == 0) { + memcpy(&info->display_window[0], &data.at(0), sizeof(int)); + memcpy(&info->display_window[1], &data.at(4), sizeof(int)); + memcpy(&info->display_window[2], &data.at(8), sizeof(int)); + memcpy(&info->display_window[3], &data.at(12), sizeof(int)); + tinyexr::swap4( + reinterpret_cast(&info->display_window[0])); + tinyexr::swap4( + reinterpret_cast(&info->display_window[1])); + tinyexr::swap4( + reinterpret_cast(&info->display_window[2])); + tinyexr::swap4( + reinterpret_cast(&info->display_window[3])); + + has_display_window = true; + } else if (attr_name.compare("lineOrder") == 0) { + info->line_order = static_cast(data[0]); + has_line_order = true; + } else if (attr_name.compare("pixelAspectRatio") == 0) { + memcpy(&info->pixel_aspect_ratio, &data.at(0), sizeof(float)); + tinyexr::swap4( + reinterpret_cast(&info->pixel_aspect_ratio)); + has_pixel_aspect_ratio = true; + } else if (attr_name.compare("screenWindowCenter") == 0) { + memcpy(&info->screen_window_center[0], &data.at(0), sizeof(float)); + memcpy(&info->screen_window_center[1], &data.at(4), sizeof(float)); + tinyexr::swap4( + reinterpret_cast(&info->screen_window_center[0])); + tinyexr::swap4( + reinterpret_cast(&info->screen_window_center[1])); + has_screen_window_center = true; + } else if (attr_name.compare("screenWindowWidth") == 0) { + memcpy(&info->screen_window_width, &data.at(0), sizeof(float)); + tinyexr::swap4( + reinterpret_cast(&info->screen_window_width)); + + has_screen_window_width = true; + } else if (attr_name.compare("chunkCount") == 0) { + memcpy(&info->chunk_count, &data.at(0), sizeof(int)); + tinyexr::swap4(reinterpret_cast(&info->chunk_count)); + } else { + // Custom attribute(up to TINYEXR_MAX_ATTRIBUTES) + if (info->attributes.size() < TINYEXR_MAX_ATTRIBUTES) { + EXRAttribute attrib; +#ifdef _MSC_VER + strncpy_s(attrib.name, attr_name.c_str(), 255); + strncpy_s(attrib.type, attr_type.c_str(), 255); +#else + strncpy(attrib.name, attr_name.c_str(), 255); + strncpy(attrib.type, attr_type.c_str(), 255); +#endif + attrib.name[255] = '\0'; + attrib.type[255] = '\0'; + attrib.size = static_cast(data.size()); + attrib.value = static_cast(malloc(data.size())); + memcpy(reinterpret_cast(attrib.value), &data.at(0), + data.size()); + info->attributes.push_back(attrib); + } + } + } + + // Check if required attributes exist + { + std::stringstream ss_err; + + if (!has_compression) { + ss_err << "\"compression\" attribute not found in the header." + << std::endl; + } + + if (!has_channels) { + ss_err << "\"channels\" attribute not found in the header." << std::endl; + } + + if (!has_line_order) { + ss_err << "\"lineOrder\" attribute not found in the header." << std::endl; + } + + if (!has_display_window) { + ss_err << "\"displayWindow\" attribute not found in the header." + << std::endl; + } + + if (!has_data_window) { + ss_err << "\"dataWindow\" attribute not found in the header." + << std::endl; + } + + if (!has_pixel_aspect_ratio) { + ss_err << "\"pixelAspectRatio\" attribute not found in the header." + << std::endl; + } + + if (!has_screen_window_width) { + ss_err << "\"screenWindowWidth\" attribute not found in the header." + << std::endl; + } + + if (!has_screen_window_center) { + ss_err << "\"screenWindowCenter\" attribute not found in the header." + << std::endl; + } + + if (!(ss_err.str().empty())) { + if (err) { + (*err) += ss_err.str(); + } + return TINYEXR_ERROR_INVALID_HEADER; + } + } + + info->header_len = static_cast(orig_size - size); + + return TINYEXR_SUCCESS; +} + +// C++ HeaderInfo to C EXRHeader conversion. +static void ConvertHeader(EXRHeader *exr_header, const HeaderInfo &info) { + exr_header->pixel_aspect_ratio = info.pixel_aspect_ratio; + exr_header->screen_window_center[0] = info.screen_window_center[0]; + exr_header->screen_window_center[1] = info.screen_window_center[1]; + exr_header->screen_window_width = info.screen_window_width; + exr_header->chunk_count = info.chunk_count; + exr_header->display_window[0] = info.display_window[0]; + exr_header->display_window[1] = info.display_window[1]; + exr_header->display_window[2] = info.display_window[2]; + exr_header->display_window[3] = info.display_window[3]; + exr_header->data_window[0] = info.data_window[0]; + exr_header->data_window[1] = info.data_window[1]; + exr_header->data_window[2] = info.data_window[2]; + exr_header->data_window[3] = info.data_window[3]; + exr_header->line_order = info.line_order; + exr_header->compression_type = info.compression_type; + + exr_header->tile_size_x = info.tile_size_x; + exr_header->tile_size_y = info.tile_size_y; + exr_header->tile_level_mode = info.tile_level_mode; + exr_header->tile_rounding_mode = info.tile_rounding_mode; + + exr_header->num_channels = static_cast(info.channels.size()); + + exr_header->channels = static_cast(malloc( + sizeof(EXRChannelInfo) * static_cast(exr_header->num_channels))); + for (size_t c = 0; c < static_cast(exr_header->num_channels); c++) { +#ifdef _MSC_VER + strncpy_s(exr_header->channels[c].name, info.channels[c].name.c_str(), 255); +#else + strncpy(exr_header->channels[c].name, info.channels[c].name.c_str(), 255); +#endif + // manually add '\0' for safety. + exr_header->channels[c].name[255] = '\0'; + + exr_header->channels[c].pixel_type = info.channels[c].pixel_type; + exr_header->channels[c].p_linear = info.channels[c].p_linear; + exr_header->channels[c].x_sampling = info.channels[c].x_sampling; + exr_header->channels[c].y_sampling = info.channels[c].y_sampling; + } + + exr_header->pixel_types = static_cast( + malloc(sizeof(int) * static_cast(exr_header->num_channels))); + for (size_t c = 0; c < static_cast(exr_header->num_channels); c++) { + exr_header->pixel_types[c] = info.channels[c].pixel_type; + } + + // Initially fill with values of `pixel_types` + exr_header->requested_pixel_types = static_cast( + malloc(sizeof(int) * static_cast(exr_header->num_channels))); + for (size_t c = 0; c < static_cast(exr_header->num_channels); c++) { + exr_header->requested_pixel_types[c] = info.channels[c].pixel_type; + } + + assert(info.attributes.size() < TINYEXR_MAX_ATTRIBUTES); + exr_header->num_custom_attributes = static_cast(info.attributes.size()); + + for (size_t i = 0; i < info.attributes.size(); i++) { + memcpy(exr_header->custom_attributes[i].name, info.attributes[i].name, 256); + memcpy(exr_header->custom_attributes[i].type, info.attributes[i].type, 256); + exr_header->custom_attributes[i].size = info.attributes[i].size; + // Just copy poiner + exr_header->custom_attributes[i].value = info.attributes[i].value; + } + + exr_header->header_len = info.header_len; +} + +static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header, + const std::vector &offsets, + const unsigned char *head) { + int num_channels = exr_header->num_channels; + + int num_scanline_blocks = 1; + if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZIP) { + num_scanline_blocks = 16; + } else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) { + num_scanline_blocks = 32; + } else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) { + num_scanline_blocks = 16; + } + + int data_width = exr_header->data_window[2] - exr_header->data_window[0] + 1; + int data_height = exr_header->data_window[3] - exr_header->data_window[1] + 1; + + size_t num_blocks = offsets.size(); + + std::vector channel_offset_list; + int pixel_data_size = 0; + size_t channel_offset = 0; + tinyexr::ComputeChannelLayout(&channel_offset_list, &pixel_data_size, + &channel_offset, num_channels, + exr_header->channels); + + bool invalid_data = false; + + if (exr_header->tiled) { + size_t num_tiles = offsets.size(); // = # of blocks + + exr_image->tiles = static_cast( + malloc(sizeof(EXRTile) * static_cast(num_tiles))); + + for (size_t tile_idx = 0; tile_idx < num_tiles; tile_idx++) { + // Allocate memory for each tile. + exr_image->tiles[tile_idx].images = tinyexr::AllocateImage( + num_channels, exr_header->channels, exr_header->requested_pixel_types, + data_width, data_height); + + // 16 byte: tile coordinates + // 4 byte : data size + // ~ : data(uncompressed or compressed) + const unsigned char *data_ptr = + reinterpret_cast(head + offsets[tile_idx]); + + int tile_coordinates[4]; + memcpy(tile_coordinates, data_ptr, sizeof(int) * 4); + tinyexr::swap4(reinterpret_cast(&tile_coordinates[0])); + tinyexr::swap4(reinterpret_cast(&tile_coordinates[1])); + tinyexr::swap4(reinterpret_cast(&tile_coordinates[2])); + tinyexr::swap4(reinterpret_cast(&tile_coordinates[3])); + + // @todo{ LoD } + assert(tile_coordinates[2] == 0); + assert(tile_coordinates[3] == 0); + + int data_len; + memcpy(&data_len, data_ptr + 16, + sizeof(int)); // 16 = sizeof(tile_coordinates) + tinyexr::swap4(reinterpret_cast(&data_len)); + assert(data_len >= 4); + + // Move to data addr: 20 = 16 + 4; + data_ptr += 20; + + tinyexr::DecodeTiledPixelData( + exr_image->tiles[tile_idx].images, + &(exr_image->tiles[tile_idx].width), + &(exr_image->tiles[tile_idx].height), + exr_header->requested_pixel_types, data_ptr, + static_cast(data_len), exr_header->compression_type, + exr_header->line_order, data_width, data_height, tile_coordinates[0], + tile_coordinates[1], exr_header->tile_size_x, exr_header->tile_size_y, + static_cast(pixel_data_size), + static_cast(exr_header->num_custom_attributes), + exr_header->custom_attributes, + static_cast(exr_header->num_channels), exr_header->channels, + channel_offset_list); + + exr_image->tiles[tile_idx].offset_x = tile_coordinates[0]; + exr_image->tiles[tile_idx].offset_y = tile_coordinates[1]; + exr_image->tiles[tile_idx].level_x = tile_coordinates[2]; + exr_image->tiles[tile_idx].level_y = tile_coordinates[3]; + + exr_image->num_tiles = static_cast(num_tiles); + } + } else { // scanline format + + exr_image->images = tinyexr::AllocateImage( + num_channels, exr_header->channels, exr_header->requested_pixel_types, + data_width, data_height); + +#ifdef _OPENMP +#pragma omp parallel for +#endif + for (int y = 0; y < static_cast(num_blocks); y++) { + size_t y_idx = static_cast(y); + const unsigned char *data_ptr = + reinterpret_cast(head + offsets[y_idx]); + // 4 byte: scan line + // 4 byte: data size + // ~ : pixel data(uncompressed or compressed) + int line_no; + memcpy(&line_no, data_ptr, sizeof(int)); + int data_len; + memcpy(&data_len, data_ptr + 4, sizeof(int)); + tinyexr::swap4(reinterpret_cast(&line_no)); + tinyexr::swap4(reinterpret_cast(&data_len)); + + int end_line_no = (std::min)(line_no + num_scanline_blocks, + (exr_header->data_window[3] + 1)); + + int num_lines = end_line_no - line_no; + assert(num_lines > 0); + + // Move to data addr: 8 = 4 + 4; + data_ptr += 8; + + // Adjust line_no with data_window.bmin.y + line_no -= exr_header->data_window[1]; + + if (line_no < 0) { + invalid_data = true; + } else { + tinyexr::DecodePixelData( + exr_image->images, exr_header->requested_pixel_types, data_ptr, + static_cast(data_len), exr_header->compression_type, + exr_header->line_order, data_width, data_height, data_width, y, + line_no, num_lines, static_cast(pixel_data_size), + static_cast(exr_header->num_custom_attributes), + exr_header->custom_attributes, + static_cast(exr_header->num_channels), exr_header->channels, + channel_offset_list); + } + } // omp parallel + } + + if (invalid_data) { + return TINYEXR_ERROR_INVALID_DATA; + } + + // Overwrite `pixel_type` with `requested_pixel_type`. + { + for (int c = 0; c < exr_header->num_channels; c++) { + exr_header->pixel_types[c] = exr_header->requested_pixel_types[c]; + } + } + + { + exr_image->num_channels = num_channels; + + exr_image->width = data_width; + exr_image->height = data_height; + } + + return TINYEXR_SUCCESS; +} + +static bool ReconstructLineOffsets( + std::vector *offsets, size_t n, + const unsigned char *head, const unsigned char *marker, const size_t size) { + assert(head < marker); + assert(offsets->size() == n); + + for (size_t i = 0; i < n; i++) { + size_t offset = static_cast(marker - head); + // Offset should not exceed whole EXR file/data size. + if (offset >= size) { + return false; + } + + int y; + unsigned int data_len; + + memcpy(&y, marker, sizeof(int)); + memcpy(&data_len, marker + 4, sizeof(unsigned int)); + + if (data_len >= size) { + return false; + } + + tinyexr::swap4(reinterpret_cast(&y)); + tinyexr::swap4(reinterpret_cast(&data_len)); + + (*offsets)[i] = offset; + + marker += data_len + 8; // 8 = 4 bytes(y) + 4 bytes(data_len) + } + + return true; +} + +static int DecodeEXRImage(EXRImage *exr_image, const EXRHeader *exr_header, + const unsigned char *head, + const unsigned char *marker, const size_t size, + const char **err) { + if (exr_image == NULL || exr_header == NULL || head == NULL || + marker == NULL || (size <= tinyexr::kEXRVersionSize)) { + if (err) { + (*err) = "Invalid argument."; + } + return TINYEXR_ERROR_INVALID_ARGUMENT; + } + + int num_scanline_blocks = 1; + if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZIP) { + num_scanline_blocks = 16; + } else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) { + num_scanline_blocks = 32; + } else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) { + num_scanline_blocks = 16; + } + + int data_width = exr_header->data_window[2] - exr_header->data_window[0] + 1; + int data_height = exr_header->data_window[3] - exr_header->data_window[1] + 1; + + // Read offset tables. + size_t num_blocks; + + if (exr_header->chunk_count > 0) { + // Use `chunkCount` attribute. + num_blocks = static_cast(exr_header->chunk_count); + } else if (exr_header->tiled) { + // @todo { LoD } + size_t num_x_tiles = static_cast(data_width) / + static_cast(exr_header->tile_size_x); + if (num_x_tiles * static_cast(exr_header->tile_size_x) < + static_cast(data_width)) { + num_x_tiles++; + } + size_t num_y_tiles = static_cast(data_height) / + static_cast(exr_header->tile_size_y); + if (num_y_tiles * static_cast(exr_header->tile_size_y) < + static_cast(data_height)) { + num_y_tiles++; + } + + num_blocks = num_x_tiles * num_y_tiles; + } else { + num_blocks = static_cast(data_height) / + static_cast(num_scanline_blocks); + if (num_blocks * static_cast(num_scanline_blocks) < + static_cast(data_height)) { + num_blocks++; + } + } + + std::vector offsets(num_blocks); + + for (size_t y = 0; y < num_blocks; y++) { + tinyexr::tinyexr_uint64 offset; + memcpy(&offset, marker, sizeof(tinyexr::tinyexr_uint64)); + tinyexr::swap8(&offset); + if (offset >= size) { + if (err) { + (*err) = "Invalid offset value."; + } + return TINYEXR_ERROR_INVALID_DATA; + } + marker += sizeof(tinyexr::tinyexr_uint64); // = 8 + offsets[y] = offset; + } + + // If line offsets are invalid, we try to reconstruct it. + // See OpenEXR/IlmImf/ImfScanLineInputFile.cpp::readLineOffsets() for details. + for (size_t y = 0; y < num_blocks; y++) { + if (offsets[y] <= 0) { + // TODO(syoyo) Report as warning? + // if (err) { + // stringstream ss; + // ss << "Incomplete lineOffsets." << std::endl; + // (*err) += ss.str(); + //} + bool ret = + ReconstructLineOffsets(&offsets, num_blocks, head, marker, size); + if (ret) { + // OK + break; + } else { + if (err) { + (*err) = "Cannot reconstruct lineOffset table."; + } + return TINYEXR_ERROR_INVALID_DATA; + } + } + } + + return DecodeChunk(exr_image, exr_header, offsets, head); +} + +} // namespace tinyexr + +int LoadEXR(float **out_rgba, int *width, int *height, const char *filename, + const char **err) { + if (out_rgba == NULL) { + if (err) { + (*err) = "Invalid argument.\n"; + } + return TINYEXR_ERROR_INVALID_ARGUMENT; + } + + EXRVersion exr_version; + EXRImage exr_image; + EXRHeader exr_header; + InitEXRHeader(&exr_header); + InitEXRImage(&exr_image); + + { + int ret = ParseEXRVersionFromFile(&exr_version, filename); + if (ret != TINYEXR_SUCCESS) { + return ret; + } + + if (exr_version.multipart || exr_version.non_image) { + if (err) { + (*err) = "Loading multipart or DeepImage is not supported yet.\n"; + } + return TINYEXR_ERROR_INVALID_DATA; // @fixme. + } + } + + { + int ret = ParseEXRHeaderFromFile(&exr_header, &exr_version, filename, err); + if (ret != TINYEXR_SUCCESS) { + return ret; + } + } + + // Read HALF channel as FLOAT. + for (int i = 0; i < exr_header.num_channels; i++) { + if (exr_header.pixel_types[i] == TINYEXR_PIXELTYPE_HALF) { + exr_header.requested_pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT; + } + } + + { + int ret = LoadEXRImageFromFile(&exr_image, &exr_header, filename, err); + if (ret != TINYEXR_SUCCESS) { + return ret; + } + } + + // RGBA + int idxR = -1; + int idxG = -1; + int idxB = -1; + int idxA = -1; + for (int c = 0; c < exr_header.num_channels; c++) { + if (strcmp(exr_header.channels[c].name, "R") == 0) { + idxR = c; + } else if (strcmp(exr_header.channels[c].name, "G") == 0) { + idxG = c; + } else if (strcmp(exr_header.channels[c].name, "B") == 0) { + idxB = c; + } else if (strcmp(exr_header.channels[c].name, "A") == 0) { + idxA = c; + } + } + + if ((idxA == 0) && (idxR == -1) && (idxG == -1) && (idxB == -1)) { + // Alpha channel only. + + (*out_rgba) = reinterpret_cast( + malloc(4 * sizeof(float) * static_cast(exr_image.width) * + static_cast(exr_image.height))); + for (int i = 0; i < exr_image.width * exr_image.height; i++) { + const float val = reinterpret_cast(exr_image.images)[0][i]; + (*out_rgba)[4 * i + 0] = val; + (*out_rgba)[4 * i + 1] = val; + (*out_rgba)[4 * i + 2] = val; + (*out_rgba)[4 * i + 3] = val; + } + } else { + // Assume RGB(A) + + if (idxR == -1) { + if (err) { + (*err) = "R channel not found\n"; + } + + // @todo { free exr_image } + return TINYEXR_ERROR_INVALID_DATA; + } + + if (idxG == -1) { + if (err) { + (*err) = "G channel not found\n"; + } + // @todo { free exr_image } + return TINYEXR_ERROR_INVALID_DATA; + } + + if (idxB == -1) { + if (err) { + (*err) = "B channel not found\n"; + } + // @todo { free exr_image } + return TINYEXR_ERROR_INVALID_DATA; + } + + (*out_rgba) = reinterpret_cast( + malloc(4 * sizeof(float) * static_cast(exr_image.width) * + static_cast(exr_image.height))); + for (int i = 0; i < exr_image.width * exr_image.height; i++) { + (*out_rgba)[4 * i + 0] = + reinterpret_cast(exr_image.images)[idxR][i]; + (*out_rgba)[4 * i + 1] = + reinterpret_cast(exr_image.images)[idxG][i]; + (*out_rgba)[4 * i + 2] = + reinterpret_cast(exr_image.images)[idxB][i]; + if (idxA != -1) { + (*out_rgba)[4 * i + 3] = + reinterpret_cast(exr_image.images)[idxA][i]; + } else { + (*out_rgba)[4 * i + 3] = 1.0; + } + } + } + + (*width) = exr_image.width; + (*height) = exr_image.height; + + FreeEXRHeader(&exr_header); + FreeEXRImage(&exr_image); + + return TINYEXR_SUCCESS; +} + +int ParseEXRHeaderFromMemory(EXRHeader *exr_header, const EXRVersion *version, + const unsigned char *memory, size_t size, + const char **err) { + if (memory == NULL || exr_header == NULL) { + if (err) { + (*err) = "Invalid argument.\n"; + } + + // Invalid argument + return TINYEXR_ERROR_INVALID_ARGUMENT; + } + + if (size < tinyexr::kEXRVersionSize) { + return TINYEXR_ERROR_INVALID_DATA; + } + + const unsigned char *marker = memory + tinyexr::kEXRVersionSize; + size_t marker_size = size - tinyexr::kEXRVersionSize; + + tinyexr::HeaderInfo info; + info.clear(); + + std::string err_str; + int ret = ParseEXRHeader(&info, NULL, version, &err_str, marker, marker_size); + + if (ret != TINYEXR_SUCCESS) { + if (err && !err_str.empty()) { +#ifdef _WIN32 + (*err) = _strdup(err_str.c_str()); // May leak +#else + (*err) = strdup(err_str.c_str()); // May leak +#endif + } + } + + ConvertHeader(exr_header, info); + + // transfoer `tiled` from version. + exr_header->tiled = version->tiled; + + return ret; +} + +int LoadEXRFromMemory(float **out_rgba, int *width, int *height, + const unsigned char *memory, size_t size, + const char **err) { + if (out_rgba == NULL || memory == NULL) { + if (err) { + (*err) = "Invalid argument.\n"; + } + return TINYEXR_ERROR_INVALID_ARGUMENT; + } + + EXRVersion exr_version; + EXRImage exr_image; + EXRHeader exr_header; + + InitEXRHeader(&exr_header); + + int ret = ParseEXRVersionFromMemory(&exr_version, memory, size); + if (ret != TINYEXR_SUCCESS) { + return ret; + } + + ret = ParseEXRHeaderFromMemory(&exr_header, &exr_version, memory, size, err); + if (ret != TINYEXR_SUCCESS) { + return ret; + } + + // Read HALF channel as FLOAT. + for (int i = 0; i < exr_header.num_channels; i++) { + if (exr_header.pixel_types[i] == TINYEXR_PIXELTYPE_HALF) { + exr_header.requested_pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT; + } + } + + InitEXRImage(&exr_image); + ret = LoadEXRImageFromMemory(&exr_image, &exr_header, memory, size, err); + if (ret != TINYEXR_SUCCESS) { + return ret; + } + + // RGBA + int idxR = -1; + int idxG = -1; + int idxB = -1; + int idxA = -1; + for (int c = 0; c < exr_header.num_channels; c++) { + if (strcmp(exr_header.channels[c].name, "R") == 0) { + idxR = c; + } else if (strcmp(exr_header.channels[c].name, "G") == 0) { + idxG = c; + } else if (strcmp(exr_header.channels[c].name, "B") == 0) { + idxB = c; + } else if (strcmp(exr_header.channels[c].name, "A") == 0) { + idxA = c; + } + } + + if (idxR == -1) { + if (err) { + (*err) = "R channel not found\n"; + } + + // @todo { free exr_image } + return TINYEXR_ERROR_INVALID_DATA; + } + + if (idxG == -1) { + if (err) { + (*err) = "G channel not found\n"; + } + // @todo { free exr_image } + return TINYEXR_ERROR_INVALID_DATA; + } + + if (idxB == -1) { + if (err) { + (*err) = "B channel not found\n"; + } + // @todo { free exr_image } + return TINYEXR_ERROR_INVALID_DATA; + } + + (*out_rgba) = reinterpret_cast( + malloc(4 * sizeof(float) * static_cast(exr_image.width) * + static_cast(exr_image.height))); + + for (int i = 0; i < exr_image.width * exr_image.height; i++) { + (*out_rgba)[4 * i + 0] = + reinterpret_cast(exr_image.images)[idxR][i]; + (*out_rgba)[4 * i + 1] = + reinterpret_cast(exr_image.images)[idxG][i]; + (*out_rgba)[4 * i + 2] = + reinterpret_cast(exr_image.images)[idxB][i]; + if (idxA != -1) { + (*out_rgba)[4 * i + 3] = + reinterpret_cast(exr_image.images)[idxA][i]; + } + else { + (*out_rgba)[4 * i + 3] = 1.0; + } + } + + (*width) = exr_image.width; + (*height) = exr_image.height; + + FreeEXRHeader(&exr_header); + FreeEXRImage(&exr_image); + + return TINYEXR_SUCCESS; +} + +int LoadEXRImageFromFile(EXRImage *exr_image, const EXRHeader *exr_header, + const char *filename, const char **err) { + if (exr_image == NULL) { + if (err) { + (*err) = "Invalid argument."; + } + return TINYEXR_ERROR_INVALID_ARGUMENT; + } + +#ifdef _WIN32 + FILE *fp = NULL; + fopen_s(&fp, filename, "rb"); +#else + FILE *fp = fopen(filename, "rb"); +#endif + if (!fp) { + if (err) { + (*err) = "Cannot read file."; + } + return TINYEXR_ERROR_CANT_OPEN_FILE; + } + + size_t filesize; + // Compute size + fseek(fp, 0, SEEK_END); + filesize = static_cast(ftell(fp)); + fseek(fp, 0, SEEK_SET); + + std::vector buf(filesize); // @todo { use mmap } + { + size_t ret; + ret = fread(&buf[0], 1, filesize, fp); + assert(ret == filesize); + fclose(fp); + (void)ret; + } + + return LoadEXRImageFromMemory(exr_image, exr_header, &buf.at(0), filesize, + err); +} + +int LoadEXRImageFromMemory(EXRImage *exr_image, const EXRHeader *exr_header, + const unsigned char *memory, const size_t size, + const char **err) { + if (exr_image == NULL || memory == NULL || + (size < tinyexr::kEXRVersionSize)) { + if (err) { + (*err) = "Invalid argument."; + } + return TINYEXR_ERROR_INVALID_ARGUMENT; + } + + if (exr_header->header_len == 0) { + if (err) { + (*err) = "EXRHeader is not initialized."; + } + return TINYEXR_ERROR_INVALID_ARGUMENT; + } + + const unsigned char *head = memory; + const unsigned char *marker = reinterpret_cast( + memory + exr_header->header_len + + 8); // +8 for magic number + version header. + return tinyexr::DecodeEXRImage(exr_image, exr_header, head, marker, size, + err); +} + +size_t SaveEXRImageToMemory(const EXRImage *exr_image, + const EXRHeader *exr_header, + unsigned char **memory_out, const char **err) { + if (exr_image == NULL || memory_out == NULL || + exr_header->compression_type < 0) { + if (err) { + (*err) = "Invalid argument."; + } + return 0; // @fixme + } + +#if !TINYEXR_USE_PIZ + if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) { + if (err) { + (*err) = "PIZ compression is not supported in this build."; + } + return 0; + } +#endif + +#if !TINYEXR_USE_ZFP + if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) { + if (err) { + (*err) = "ZFP compression is not supported in this build."; + } + return 0; + } +#endif + +#if TINYEXR_USE_ZFP + for (size_t i = 0; i < static_cast(exr_header->num_channels); i++) { + if (exr_header->requested_pixel_types[i] != TINYEXR_PIXELTYPE_FLOAT) { + if (err) { + (*err) = "Pixel type must be FLOAT for ZFP compression."; + } + return 0; + } + } +#endif + + std::vector memory; + + // Header + { + const char header[] = {0x76, 0x2f, 0x31, 0x01}; + memory.insert(memory.end(), header, header + 4); + } + + // Version, scanline. + { + char marker[] = {2, 0, 0, 0}; + /* @todo + if (exr_header->tiled) { + marker[1] |= 0x2; + } + if (exr_header->long_name) { + marker[1] |= 0x4; + } + if (exr_header->non_image) { + marker[1] |= 0x8; + } + if (exr_header->multipart) { + marker[1] |= 0x10; + } + */ + memory.insert(memory.end(), marker, marker + 4); + } + + int num_scanlines = 1; + if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZIP) { + num_scanlines = 16; + } else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) { + num_scanlines = 32; + } else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) { + num_scanlines = 16; + } + + // Write attributes. + std::vector channels; + { + std::vector data; + + for (int c = 0; c < exr_header->num_channels; c++) { + tinyexr::ChannelInfo info; + info.p_linear = 0; + info.pixel_type = exr_header->requested_pixel_types[c]; + info.x_sampling = 1; + info.y_sampling = 1; + info.name = std::string(exr_header->channels[c].name); + channels.push_back(info); + } + + tinyexr::WriteChannelInfo(data, channels); + + tinyexr::WriteAttributeToMemory(&memory, "channels", "chlist", &data.at(0), + static_cast(data.size())); + } + + { + int comp = exr_header->compression_type; + tinyexr::swap4(reinterpret_cast(&comp)); + tinyexr::WriteAttributeToMemory( + &memory, "compression", "compression", + reinterpret_cast(&comp), 1); + } + + { + int data[4] = {0, 0, exr_image->width - 1, exr_image->height - 1}; + tinyexr::swap4(reinterpret_cast(&data[0])); + tinyexr::swap4(reinterpret_cast(&data[1])); + tinyexr::swap4(reinterpret_cast(&data[2])); + tinyexr::swap4(reinterpret_cast(&data[3])); + tinyexr::WriteAttributeToMemory( + &memory, "dataWindow", "box2i", + reinterpret_cast(data), sizeof(int) * 4); + tinyexr::WriteAttributeToMemory( + &memory, "displayWindow", "box2i", + reinterpret_cast(data), sizeof(int) * 4); + } + + { + unsigned char line_order = 0; // @fixme { read line_order from EXRHeader } + tinyexr::WriteAttributeToMemory(&memory, "lineOrder", "lineOrder", + &line_order, 1); + } + + { + float aspectRatio = 1.0f; + tinyexr::swap4(reinterpret_cast(&aspectRatio)); + tinyexr::WriteAttributeToMemory( + &memory, "pixelAspectRatio", "float", + reinterpret_cast(&aspectRatio), sizeof(float)); + } + + { + float center[2] = {0.0f, 0.0f}; + tinyexr::swap4(reinterpret_cast(¢er[0])); + tinyexr::swap4(reinterpret_cast(¢er[1])); + tinyexr::WriteAttributeToMemory( + &memory, "screenWindowCenter", "v2f", + reinterpret_cast(center), 2 * sizeof(float)); + } + + { + float w = static_cast(exr_image->width); + tinyexr::swap4(reinterpret_cast(&w)); + tinyexr::WriteAttributeToMemory(&memory, "screenWindowWidth", "float", + reinterpret_cast(&w), + sizeof(float)); + } + + // Custom attributes + if (exr_header->num_custom_attributes > 0) { + for (int i = 0; i < exr_header->num_custom_attributes; i++) { + tinyexr::WriteAttributeToMemory( + &memory, exr_header->custom_attributes[i].name, + exr_header->custom_attributes[i].type, + reinterpret_cast( + exr_header->custom_attributes[i].value), + exr_header->custom_attributes[i].size); + } + } + + { // end of header + unsigned char e = 0; + memory.push_back(e); + } + + int num_blocks = exr_image->height / num_scanlines; + if (num_blocks * num_scanlines < exr_image->height) { + num_blocks++; + } + + std::vector offsets(static_cast(num_blocks)); + + size_t headerSize = memory.size(); + tinyexr::tinyexr_uint64 offset = + headerSize + + static_cast(num_blocks) * + sizeof( + tinyexr::tinyexr_int64); // sizeof(header) + sizeof(offsetTable) + + std::vector data; + + std::vector > data_list( + static_cast(num_blocks)); + std::vector channel_offset_list( + static_cast(exr_header->num_channels)); + + int pixel_data_size = 0; + size_t channel_offset = 0; + for (size_t c = 0; c < static_cast(exr_header->num_channels); c++) { + channel_offset_list[c] = channel_offset; + if (exr_header->requested_pixel_types[c] == TINYEXR_PIXELTYPE_HALF) { + pixel_data_size += sizeof(unsigned short); + channel_offset += sizeof(unsigned short); + } else if (exr_header->requested_pixel_types[c] == + TINYEXR_PIXELTYPE_FLOAT) { + pixel_data_size += sizeof(float); + channel_offset += sizeof(float); + } else if (exr_header->requested_pixel_types[c] == TINYEXR_PIXELTYPE_UINT) { + pixel_data_size += sizeof(unsigned int); + channel_offset += sizeof(unsigned int); + } else { + assert(0); + } + } + +#if TINYEXR_USE_ZFP + tinyexr::ZFPCompressionParam zfp_compression_param; + + // Use ZFP compression parameter from custom attributes(if such a parameter + // exists) + { + bool ret = tinyexr::FindZFPCompressionParam( + &zfp_compression_param, exr_header->custom_attributes, + exr_header->num_custom_attributes); + + if (!ret) { + // Use predefined compression parameter. + zfp_compression_param.type = 0; + zfp_compression_param.rate = 2; + } + } +#endif + +// Use signed int since some OpenMP compiler doesn't allow unsigned type for +// `parallel for` +#ifdef _OPENMP +#pragma omp parallel for +#endif + for (int i = 0; i < num_blocks; i++) { + size_t ii = static_cast(i); + int start_y = num_scanlines * i; + int endY = (std::min)(num_scanlines * (i + 1), exr_image->height); + int h = endY - start_y; + + std::vector buf( + static_cast(exr_image->width * h * pixel_data_size)); + + for (size_t c = 0; c < static_cast(exr_header->num_channels); c++) { + if (exr_header->pixel_types[c] == TINYEXR_PIXELTYPE_HALF) { + if (exr_header->requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT) { + for (int y = 0; y < h; y++) { + for (int x = 0; x < exr_image->width; x++) { + tinyexr::FP16 h16; + h16.u = reinterpret_cast( + exr_image->images)[c][(y + start_y) * exr_image->width + x]; + + tinyexr::FP32 f32 = half_to_float(h16); + + tinyexr::swap4(reinterpret_cast(&f32.f)); + + // Assume increasing Y + float *line_ptr = reinterpret_cast(&buf.at( + static_cast(pixel_data_size * y * exr_image->width) + + channel_offset_list[c] * + static_cast(exr_image->width))); + line_ptr[x] = f32.f; + } + } + } else if (exr_header->requested_pixel_types[c] == + TINYEXR_PIXELTYPE_HALF) { + for (int y = 0; y < h; y++) { + for (int x = 0; x < exr_image->width; x++) { + unsigned short val = reinterpret_cast( + exr_image->images)[c][(y + start_y) * exr_image->width + x]; + + tinyexr::swap2(&val); + + // Assume increasing Y + unsigned short *line_ptr = reinterpret_cast( + &buf.at(static_cast(pixel_data_size * y * + exr_image->width) + + channel_offset_list[c] * + static_cast(exr_image->width))); + line_ptr[x] = val; + } + } + } else { + assert(0); + } + + } else if (exr_header->pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT) { + if (exr_header->requested_pixel_types[c] == TINYEXR_PIXELTYPE_HALF) { + for (int y = 0; y < h; y++) { + for (int x = 0; x < exr_image->width; x++) { + tinyexr::FP32 f32; + f32.f = reinterpret_cast( + exr_image->images)[c][(y + start_y) * exr_image->width + x]; + + tinyexr::FP16 h16; + h16 = float_to_half_full(f32); + + tinyexr::swap2(reinterpret_cast(&h16.u)); + + // Assume increasing Y + unsigned short *line_ptr = reinterpret_cast( + &buf.at(static_cast(pixel_data_size * y * + exr_image->width) + + channel_offset_list[c] * + static_cast(exr_image->width))); + line_ptr[x] = h16.u; + } + } + } else if (exr_header->requested_pixel_types[c] == + TINYEXR_PIXELTYPE_FLOAT) { + for (int y = 0; y < h; y++) { + for (int x = 0; x < exr_image->width; x++) { + float val = reinterpret_cast( + exr_image->images)[c][(y + start_y) * exr_image->width + x]; + + tinyexr::swap4(reinterpret_cast(&val)); + + // Assume increasing Y + float *line_ptr = reinterpret_cast(&buf.at( + static_cast(pixel_data_size * y * exr_image->width) + + channel_offset_list[c] * + static_cast(exr_image->width))); + line_ptr[x] = val; + } + } + } else { + assert(0); + } + } else if (exr_header->pixel_types[c] == TINYEXR_PIXELTYPE_UINT) { + for (int y = 0; y < h; y++) { + for (int x = 0; x < exr_image->width; x++) { + unsigned int val = reinterpret_cast( + exr_image->images)[c][(y + start_y) * exr_image->width + x]; + + tinyexr::swap4(&val); + + // Assume increasing Y + unsigned int *line_ptr = reinterpret_cast(&buf.at( + static_cast(pixel_data_size * y * exr_image->width) + + channel_offset_list[c] * + static_cast(exr_image->width))); + line_ptr[x] = val; + } + } + } + } + + if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_NONE) { + // 4 byte: scan line + // 4 byte: data size + // ~ : pixel data(uncompressed) + std::vector header(8); + unsigned int data_len = static_cast(buf.size()); + memcpy(&header.at(0), &start_y, sizeof(int)); + memcpy(&header.at(4), &data_len, sizeof(unsigned int)); + + tinyexr::swap4(reinterpret_cast(&header.at(0))); + tinyexr::swap4(reinterpret_cast(&header.at(4))); + + data_list[ii].insert(data_list[ii].end(), header.begin(), header.end()); + data_list[ii].insert(data_list[ii].end(), buf.begin(), + buf.begin() + data_len); + + } else if ((exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZIPS) || + (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZIP)) { +#if TINYEXR_USE_MINIZ + std::vector block(tinyexr::miniz::mz_compressBound( + static_cast(buf.size()))); +#else + std::vector block( + compressBound(static_cast(buf.size()))); +#endif + tinyexr::tinyexr_uint64 outSize = block.size(); + + tinyexr::CompressZip(&block.at(0), outSize, + reinterpret_cast(&buf.at(0)), + static_cast(buf.size())); + + // 4 byte: scan line + // 4 byte: data size + // ~ : pixel data(compressed) + std::vector header(8); + unsigned int data_len = static_cast(outSize); // truncate + memcpy(&header.at(0), &start_y, sizeof(int)); + memcpy(&header.at(4), &data_len, sizeof(unsigned int)); + + tinyexr::swap4(reinterpret_cast(&header.at(0))); + tinyexr::swap4(reinterpret_cast(&header.at(4))); + + data_list[ii].insert(data_list[ii].end(), header.begin(), header.end()); + data_list[ii].insert(data_list[ii].end(), block.begin(), + block.begin() + data_len); + + } else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_RLE) { + // (buf.size() * 3) / 2 would be enough. + std::vector block((buf.size() * 3) / 2); + + tinyexr::tinyexr_uint64 outSize = block.size(); + + tinyexr::CompressRle(&block.at(0), outSize, + reinterpret_cast(&buf.at(0)), + static_cast(buf.size())); + + // 4 byte: scan line + // 4 byte: data size + // ~ : pixel data(compressed) + std::vector header(8); + unsigned int data_len = static_cast(outSize); // truncate + memcpy(&header.at(0), &start_y, sizeof(int)); + memcpy(&header.at(4), &data_len, sizeof(unsigned int)); + + tinyexr::swap4(reinterpret_cast(&header.at(0))); + tinyexr::swap4(reinterpret_cast(&header.at(4))); + + data_list[ii].insert(data_list[ii].end(), header.begin(), header.end()); + data_list[ii].insert(data_list[ii].end(), block.begin(), + block.begin() + data_len); + + } else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) { +#if TINYEXR_USE_PIZ + unsigned int bufLen = + 1024 + static_cast( + 1.2 * static_cast( + buf.size())); // @fixme { compute good bound. } + std::vector block(bufLen); + unsigned int outSize = static_cast(block.size()); + + CompressPiz(&block.at(0), &outSize, + reinterpret_cast(&buf.at(0)), + buf.size(), channels, exr_image->width, h); + + // 4 byte: scan line + // 4 byte: data size + // ~ : pixel data(compressed) + std::vector header(8); + unsigned int data_len = outSize; + memcpy(&header.at(0), &start_y, sizeof(int)); + memcpy(&header.at(4), &data_len, sizeof(unsigned int)); + + tinyexr::swap4(reinterpret_cast(&header.at(0))); + tinyexr::swap4(reinterpret_cast(&header.at(4))); + + data_list[ii].insert(data_list[ii].end(), header.begin(), header.end()); + data_list[ii].insert(data_list[ii].end(), block.begin(), + block.begin() + data_len); + +#else + assert(0); +#endif + } else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) { +#if TINYEXR_USE_ZFP + std::vector block; + unsigned int outSize; + + tinyexr::CompressZfp( + &block, &outSize, reinterpret_cast(&buf.at(0)), + exr_image->width, h, exr_header->num_channels, zfp_compression_param); + + // 4 byte: scan line + // 4 byte: data size + // ~ : pixel data(compressed) + std::vector header(8); + unsigned int data_len = outSize; + memcpy(&header.at(0), &start_y, sizeof(int)); + memcpy(&header.at(4), &data_len, sizeof(unsigned int)); + + tinyexr::swap4(reinterpret_cast(&header.at(0))); + tinyexr::swap4(reinterpret_cast(&header.at(4))); + + data_list[ii].insert(data_list[ii].end(), header.begin(), header.end()); + data_list[ii].insert(data_list[ii].end(), block.begin(), + block.begin() + data_len); + +#else + assert(0); +#endif + } else { + assert(0); + } + } // omp parallel + + for (size_t i = 0; i < static_cast(num_blocks); i++) { + data.insert(data.end(), data_list[i].begin(), data_list[i].end()); + + offsets[i] = offset; + tinyexr::swap8(reinterpret_cast(&offsets[i])); + offset += data_list[i].size(); + } + + { + memory.insert( + memory.end(), reinterpret_cast(&offsets.at(0)), + reinterpret_cast(&offsets.at(0)) + + sizeof(tinyexr::tinyexr_uint64) * static_cast(num_blocks)); + } + + { memory.insert(memory.end(), data.begin(), data.end()); } + + assert(memory.size() > 0); + + (*memory_out) = static_cast(malloc(memory.size())); + memcpy((*memory_out), &memory.at(0), memory.size()); + + return memory.size(); // OK +} + +int SaveEXRImageToFile(const EXRImage *exr_image, const EXRHeader *exr_header, + const char *filename, const char **err) { + if (exr_image == NULL || filename == NULL || + exr_header->compression_type < 0) { + if (err) { + (*err) = "Invalid argument."; + } + return TINYEXR_ERROR_INVALID_ARGUMENT; + } + +#if !TINYEXR_USE_PIZ + if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) { + if (err) { + (*err) = "PIZ compression is not supported in this build."; + } + return 0; + } +#endif + +#if !TINYEXR_USE_ZFP + if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) { + if (err) { + (*err) = "ZFP compression is not supported in this build."; + } + return 0; + } +#endif + +#ifdef _WIN32 + FILE *fp = NULL; + fopen_s(&fp, filename, "wb"); +#else + FILE *fp = fopen(filename, "wb"); +#endif + if (!fp) { + if (err) { + (*err) = "Cannot write a file."; + } + return TINYEXR_ERROR_CANT_OPEN_FILE; + } + + unsigned char *mem = NULL; + size_t mem_size = SaveEXRImageToMemory(exr_image, exr_header, &mem, err); + + if ((mem_size > 0) && mem) { + fwrite(mem, 1, mem_size, fp); + } + free(mem); + + fclose(fp); + + return TINYEXR_SUCCESS; +} + +int LoadDeepEXR(DeepImage *deep_image, const char *filename, const char **err) { + if (deep_image == NULL) { + if (err) { + (*err) = "Invalid argument."; + } + return TINYEXR_ERROR_INVALID_ARGUMENT; + } + +#ifdef _MSC_VER + FILE *fp = NULL; + errno_t errcode = fopen_s(&fp, filename, "rb"); + if ((!errcode) || (!fp)) { + if (err) { + (*err) = "Cannot read file."; + } + return TINYEXR_ERROR_CANT_OPEN_FILE; + } +#else + FILE *fp = fopen(filename, "rb"); + if (!fp) { + if (err) { + (*err) = "Cannot read file."; + } + return TINYEXR_ERROR_CANT_OPEN_FILE; + } +#endif + + size_t filesize; + // Compute size + fseek(fp, 0, SEEK_END); + filesize = static_cast(ftell(fp)); + fseek(fp, 0, SEEK_SET); + + if (filesize == 0) { + fclose(fp); + if (err) { + (*err) = "File size is zero."; + } + return TINYEXR_ERROR_INVALID_FILE; + } + + std::vector buf(filesize); // @todo { use mmap } + { + size_t ret; + ret = fread(&buf[0], 1, filesize, fp); + assert(ret == filesize); + (void)ret; + } + fclose(fp); + + const char *head = &buf[0]; + const char *marker = &buf[0]; + + // Header check. + { + const char header[] = {0x76, 0x2f, 0x31, 0x01}; + + if (memcmp(marker, header, 4) != 0) { + if (err) { + (*err) = "Invalid magic number."; + } + return TINYEXR_ERROR_INVALID_MAGIC_NUMBER; + } + marker += 4; + } + + // Version, scanline. + { + // ver 2.0, scanline, deep bit on(0x800) + // must be [2, 0, 0, 0] + if (marker[0] != 2 || marker[1] != 8 || marker[2] != 0 || marker[3] != 0) { + if (err) { + (*err) = "Unsupported version or scanline."; + } + return TINYEXR_ERROR_UNSUPPORTED_FORMAT; + } + + marker += 4; + } + + int dx = -1; + int dy = -1; + int dw = -1; + int dh = -1; + int num_scanline_blocks = 1; // 16 for ZIP compression. + int compression_type = -1; + int num_channels = -1; + std::vector channels; + + // Read attributes + size_t size = filesize - tinyexr::kEXRVersionSize; + for (;;) { + if (0 == size) { + return TINYEXR_ERROR_INVALID_DATA; + } else if (marker[0] == '\0') { + marker++; + size--; + break; + } + + std::string attr_name; + std::string attr_type; + std::vector data; + size_t marker_size; + if (!tinyexr::ReadAttribute(&attr_name, &attr_type, &data, &marker_size, + marker, size)) { + return TINYEXR_ERROR_INVALID_DATA; + } + marker += marker_size; + size -= marker_size; + + if (attr_name.compare("compression") == 0) { + compression_type = data[0]; + if (compression_type > TINYEXR_COMPRESSIONTYPE_PIZ) { + if (err) { + (*err) = "Unsupported compression type."; + } + return TINYEXR_ERROR_UNSUPPORTED_FORMAT; + } + + if (compression_type == TINYEXR_COMPRESSIONTYPE_ZIP) { + num_scanline_blocks = 16; + } + + } else if (attr_name.compare("channels") == 0) { + // name: zero-terminated string, from 1 to 255 bytes long + // pixel type: int, possible values are: UINT = 0 HALF = 1 FLOAT = 2 + // pLinear: unsigned char, possible values are 0 and 1 + // reserved: three chars, should be zero + // xSampling: int + // ySampling: int + + tinyexr::ReadChannelInfo(channels, data); + + num_channels = static_cast(channels.size()); + + if (num_channels < 1) { + if (err) { + (*err) = "Invalid channels format."; + } + return TINYEXR_ERROR_INVALID_DATA; + } + + } else if (attr_name.compare("dataWindow") == 0) { + memcpy(&dx, &data.at(0), sizeof(int)); + memcpy(&dy, &data.at(4), sizeof(int)); + memcpy(&dw, &data.at(8), sizeof(int)); + memcpy(&dh, &data.at(12), sizeof(int)); + tinyexr::swap4(reinterpret_cast(&dx)); + tinyexr::swap4(reinterpret_cast(&dy)); + tinyexr::swap4(reinterpret_cast(&dw)); + tinyexr::swap4(reinterpret_cast(&dh)); + + } else if (attr_name.compare("displayWindow") == 0) { + int x; + int y; + int w; + int h; + memcpy(&x, &data.at(0), sizeof(int)); + memcpy(&y, &data.at(4), sizeof(int)); + memcpy(&w, &data.at(8), sizeof(int)); + memcpy(&h, &data.at(12), sizeof(int)); + tinyexr::swap4(reinterpret_cast(&x)); + tinyexr::swap4(reinterpret_cast(&y)); + tinyexr::swap4(reinterpret_cast(&w)); + tinyexr::swap4(reinterpret_cast(&h)); + } + } + + assert(dx >= 0); + assert(dy >= 0); + assert(dw >= 0); + assert(dh >= 0); + assert(num_channels >= 1); + + int data_width = dw - dx + 1; + int data_height = dh - dy + 1; + + std::vector image( + static_cast(data_width * data_height * 4)); // 4 = RGBA + + // Read offset tables. + int num_blocks = data_height / num_scanline_blocks; + if (num_blocks * num_scanline_blocks < data_height) { + num_blocks++; + } + + std::vector offsets(static_cast(num_blocks)); + + for (size_t y = 0; y < static_cast(num_blocks); y++) { + tinyexr::tinyexr_int64 offset; + memcpy(&offset, marker, sizeof(tinyexr::tinyexr_int64)); + tinyexr::swap8(reinterpret_cast(&offset)); + marker += sizeof(tinyexr::tinyexr_int64); // = 8 + offsets[y] = offset; + } + +#if TINYEXR_USE_PIZ + if ((compression_type == TINYEXR_COMPRESSIONTYPE_NONE) || + (compression_type == TINYEXR_COMPRESSIONTYPE_RLE) || + (compression_type == TINYEXR_COMPRESSIONTYPE_ZIPS) || + (compression_type == TINYEXR_COMPRESSIONTYPE_ZIP) || + (compression_type == TINYEXR_COMPRESSIONTYPE_PIZ)) { +#else + if ((compression_type == TINYEXR_COMPRESSIONTYPE_NONE) || + (compression_type == TINYEXR_COMPRESSIONTYPE_RLE) || + (compression_type == TINYEXR_COMPRESSIONTYPE_ZIPS) || + (compression_type == TINYEXR_COMPRESSIONTYPE_ZIP)) { +#endif + // OK + } else { + if (err) { + (*err) = "Unsupported format."; + } + return TINYEXR_ERROR_UNSUPPORTED_FORMAT; + } + + deep_image->image = static_cast( + malloc(sizeof(float **) * static_cast(num_channels))); + for (int c = 0; c < num_channels; c++) { + deep_image->image[c] = static_cast( + malloc(sizeof(float *) * static_cast(data_height))); + for (int y = 0; y < data_height; y++) { + } + } + + deep_image->offset_table = static_cast( + malloc(sizeof(int *) * static_cast(data_height))); + for (int y = 0; y < data_height; y++) { + deep_image->offset_table[y] = static_cast( + malloc(sizeof(int) * static_cast(data_width))); + } + + for (size_t y = 0; y < static_cast(num_blocks); y++) { + const unsigned char *data_ptr = + reinterpret_cast(head + offsets[y]); + + // int: y coordinate + // int64: packed size of pixel offset table + // int64: packed size of sample data + // int64: unpacked size of sample data + // compressed pixel offset table + // compressed sample data + int line_no; + tinyexr::tinyexr_int64 packedOffsetTableSize; + tinyexr::tinyexr_int64 packedSampleDataSize; + tinyexr::tinyexr_int64 unpackedSampleDataSize; + memcpy(&line_no, data_ptr, sizeof(int)); + memcpy(&packedOffsetTableSize, data_ptr + 4, + sizeof(tinyexr::tinyexr_int64)); + memcpy(&packedSampleDataSize, data_ptr + 12, + sizeof(tinyexr::tinyexr_int64)); + memcpy(&unpackedSampleDataSize, data_ptr + 20, + sizeof(tinyexr::tinyexr_int64)); + + tinyexr::swap4(reinterpret_cast(&line_no)); + tinyexr::swap8( + reinterpret_cast(&packedOffsetTableSize)); + tinyexr::swap8( + reinterpret_cast(&packedSampleDataSize)); + tinyexr::swap8( + reinterpret_cast(&unpackedSampleDataSize)); + + std::vector pixelOffsetTable(static_cast(data_width)); + + // decode pixel offset table. + { + unsigned long dstLen = + static_cast(pixelOffsetTable.size() * sizeof(int)); + tinyexr::DecompressZip( + reinterpret_cast(&pixelOffsetTable.at(0)), &dstLen, + data_ptr + 28, static_cast(packedOffsetTableSize)); + + assert(dstLen == pixelOffsetTable.size() * sizeof(int)); + for (size_t i = 0; i < static_cast(data_width); i++) { + deep_image->offset_table[y][i] = pixelOffsetTable[i]; + } + } + + std::vector sample_data( + static_cast(unpackedSampleDataSize)); + + // decode sample data. + { + unsigned long dstLen = static_cast(unpackedSampleDataSize); + if (dstLen) { + tinyexr::DecompressZip( + reinterpret_cast(&sample_data.at(0)), &dstLen, + data_ptr + 28 + packedOffsetTableSize, + static_cast(packedSampleDataSize)); + assert(dstLen == static_cast(unpackedSampleDataSize)); + } + } + + // decode sample + int sampleSize = -1; + std::vector channel_offset_list(static_cast(num_channels)); + { + int channel_offset = 0; + for (size_t i = 0; i < static_cast(num_channels); i++) { + channel_offset_list[i] = channel_offset; + if (channels[i].pixel_type == TINYEXR_PIXELTYPE_UINT) { // UINT + channel_offset += 4; + } else if (channels[i].pixel_type == TINYEXR_PIXELTYPE_HALF) { // half + channel_offset += 2; + } else if (channels[i].pixel_type == + TINYEXR_PIXELTYPE_FLOAT) { // float + channel_offset += 4; + } else { + assert(0); + } + } + sampleSize = channel_offset; + } + assert(sampleSize >= 2); + + assert(static_cast( + pixelOffsetTable[static_cast(data_width - 1)] * + sampleSize) == sample_data.size()); + int samples_per_line = static_cast(sample_data.size()) / sampleSize; + + // + // Alloc memory + // + + // + // pixel data is stored as image[channels][pixel_samples] + // + { + tinyexr::tinyexr_uint64 data_offset = 0; + for (size_t c = 0; c < static_cast(num_channels); c++) { + deep_image->image[c][y] = static_cast( + malloc(sizeof(float) * static_cast(samples_per_line))); + + if (channels[c].pixel_type == 0) { // UINT + for (size_t x = 0; x < static_cast(samples_per_line); x++) { + unsigned int ui = *reinterpret_cast( + &sample_data.at(size_t(data_offset) + x * sizeof(int))); + deep_image->image[c][y][x] = static_cast(ui); // @fixme + } + data_offset += + sizeof(unsigned int) * static_cast(samples_per_line); + } else if (channels[c].pixel_type == 1) { // half + for (size_t x = 0; x < static_cast(samples_per_line); x++) { + tinyexr::FP16 f16; + f16.u = *reinterpret_cast( + &sample_data.at(size_t(data_offset) + x * sizeof(short))); + tinyexr::FP32 f32 = half_to_float(f16); + deep_image->image[c][y][x] = f32.f; + } + data_offset += sizeof(short) * static_cast(samples_per_line); + } else { // float + for (size_t x = 0; x < static_cast(samples_per_line); x++) { + float f = *reinterpret_cast( + &sample_data.at(size_t(data_offset) + x * sizeof(float))); + deep_image->image[c][y][x] = f; + } + data_offset += sizeof(float) * static_cast(samples_per_line); + } + } + } + } // y + + deep_image->width = data_width; + deep_image->height = data_height; + + deep_image->channel_names = static_cast( + malloc(sizeof(const char *) * static_cast(num_channels))); + for (size_t c = 0; c < static_cast(num_channels); c++) { +#ifdef _WIN32 + deep_image->channel_names[c] = _strdup(channels[c].name.c_str()); +#else + deep_image->channel_names[c] = strdup(channels[c].name.c_str()); +#endif + } + deep_image->num_channels = num_channels; + + return TINYEXR_SUCCESS; +} + +void InitEXRImage(EXRImage *exr_image) { + if (exr_image == NULL) { + return; + } + + exr_image->width = 0; + exr_image->height = 0; + exr_image->num_channels = 0; + + exr_image->images = NULL; + exr_image->tiles = NULL; + + exr_image->num_tiles = 0; +} + +void InitEXRHeader(EXRHeader *exr_header) { + if (exr_header == NULL) { + return; + } + + memset(exr_header, 0, sizeof(EXRHeader)); +} + +int FreeEXRHeader(EXRHeader *exr_header) { + if (exr_header == NULL) { + return TINYEXR_ERROR_INVALID_ARGUMENT; + } + + if (exr_header->channels) { + free(exr_header->channels); + } + + if (exr_header->pixel_types) { + free(exr_header->pixel_types); + } + + if (exr_header->requested_pixel_types) { + free(exr_header->requested_pixel_types); + } + + for (int i = 0; i < exr_header->num_custom_attributes; i++) { + if (exr_header->custom_attributes[i].value) { + free(exr_header->custom_attributes[i].value); + } + } + + return TINYEXR_SUCCESS; +} + +int FreeEXRImage(EXRImage *exr_image) { + if (exr_image == NULL) { + return TINYEXR_ERROR_INVALID_ARGUMENT; + } + + for (int i = 0; i < exr_image->num_channels; i++) { + if (exr_image->images && exr_image->images[i]) { + free(exr_image->images[i]); + } + } + + if (exr_image->images) { + free(exr_image->images); + } + + if (exr_image->tiles) { + for (int tid = 0; tid < exr_image->num_tiles; tid++) { + for (int i = 0; i < exr_image->num_channels; i++) { + if (exr_image->tiles[tid].images && exr_image->tiles[tid].images[i]) { + free(exr_image->tiles[tid].images[i]); + } + } + if (exr_image->tiles[tid].images) { + free(exr_image->tiles[tid].images); + } + } + } + + return TINYEXR_SUCCESS; +} + +int ParseEXRHeaderFromFile(EXRHeader *exr_header, const EXRVersion *exr_version, + const char *filename, const char **err) { + if (exr_header == NULL || exr_version == NULL || filename == NULL) { + if (err) { + (*err) = "Invalid argument."; + } + return TINYEXR_ERROR_INVALID_ARGUMENT; + } + +#ifdef _WIN32 + FILE *fp = NULL; + fopen_s(&fp, filename, "rb"); +#else + FILE *fp = fopen(filename, "rb"); +#endif + if (!fp) { + if (err) { + (*err) = "Cannot read file."; + } + return TINYEXR_ERROR_CANT_OPEN_FILE; + } + + size_t filesize; + // Compute size + fseek(fp, 0, SEEK_END); + filesize = static_cast(ftell(fp)); + fseek(fp, 0, SEEK_SET); + + std::vector buf(filesize); // @todo { use mmap } + { + size_t ret; + ret = fread(&buf[0], 1, filesize, fp); + assert(ret == filesize); + fclose(fp); + + if (ret != filesize) { + if (err) { + (*err) = "fread error."; + } + return TINYEXR_ERROR_INVALID_FILE; + } + } + + return ParseEXRHeaderFromMemory(exr_header, exr_version, &buf.at(0), filesize, + err); +} + +int ParseEXRMultipartHeaderFromMemory(EXRHeader ***exr_headers, + int *num_headers, + const EXRVersion *exr_version, + const unsigned char *memory, size_t size, + const char **err) { + if (memory == NULL || exr_headers == NULL || num_headers == NULL || + exr_version == NULL) { + // Invalid argument + return TINYEXR_ERROR_INVALID_ARGUMENT; + } + + if (size < tinyexr::kEXRVersionSize) { + return TINYEXR_ERROR_INVALID_DATA; + } + + const unsigned char *marker = memory + tinyexr::kEXRVersionSize; + size_t marker_size = size - tinyexr::kEXRVersionSize; + + std::vector infos; + + for (;;) { + tinyexr::HeaderInfo info; + info.clear(); + + std::string err_str; + bool empty_header = false; + int ret = ParseEXRHeader(&info, &empty_header, exr_version, &err_str, + marker, marker_size); + + if (ret != TINYEXR_SUCCESS) { + if (err) { +#ifdef _WIN32 + (*err) = _strdup(err_str.c_str()); // may leak +#else + (*err) = strdup(err_str.c_str()); // may leak +#endif + } + return ret; + } + + if (empty_header) { + marker += 1; // skip '\0' + break; + } + + // `chunkCount` must exist in the header. + if (info.chunk_count == 0) { + if (err) { + (*err) = "`chunkCount' attribute is not found in the header."; + } + return TINYEXR_ERROR_INVALID_DATA; + } + + infos.push_back(info); + + // move to next header. + marker += info.header_len; + size -= info.header_len; + } + + // allocate memory for EXRHeader and create array of EXRHeader pointers. + (*exr_headers) = + static_cast(malloc(sizeof(EXRHeader *) * infos.size())); + for (size_t i = 0; i < infos.size(); i++) { + EXRHeader *exr_header = static_cast(malloc(sizeof(EXRHeader))); + + ConvertHeader(exr_header, infos[i]); + + // transfoer `tiled` from version. + exr_header->tiled = exr_version->tiled; + + (*exr_headers)[i] = exr_header; + } + + (*num_headers) = static_cast(infos.size()); + + return TINYEXR_SUCCESS; +} + +int ParseEXRMultipartHeaderFromFile(EXRHeader ***exr_headers, int *num_headers, + const EXRVersion *exr_version, + const char *filename, const char **err) { + if (exr_headers == NULL || num_headers == NULL || exr_version == NULL || + filename == NULL) { + if (err) { + (*err) = "Invalid argument."; + } + return TINYEXR_ERROR_INVALID_ARGUMENT; + } + +#ifdef _WIN32 + FILE *fp = NULL; + fopen_s(&fp, filename, "rb"); +#else + FILE *fp = fopen(filename, "rb"); +#endif + if (!fp) { + if (err) { + (*err) = "Cannot read file."; + } + return TINYEXR_ERROR_CANT_OPEN_FILE; + } + + size_t filesize; + // Compute size + fseek(fp, 0, SEEK_END); + filesize = static_cast(ftell(fp)); + fseek(fp, 0, SEEK_SET); + + std::vector buf(filesize); // @todo { use mmap } + { + size_t ret; + ret = fread(&buf[0], 1, filesize, fp); + assert(ret == filesize); + fclose(fp); + + if (ret != filesize) { + if (err) { + (*err) = "fread error."; + } + return TINYEXR_ERROR_INVALID_FILE; + } + } + + return ParseEXRMultipartHeaderFromMemory( + exr_headers, num_headers, exr_version, &buf.at(0), filesize, err); +} + +int ParseEXRVersionFromMemory(EXRVersion *version, const unsigned char *memory, + size_t size) { + if (version == NULL || memory == NULL) { + return TINYEXR_ERROR_INVALID_ARGUMENT; + } + + if (size < tinyexr::kEXRVersionSize) { + return TINYEXR_ERROR_INVALID_DATA; + } + + const unsigned char *marker = memory; + + // Header check. + { + const char header[] = {0x76, 0x2f, 0x31, 0x01}; + + if (memcmp(marker, header, 4) != 0) { + return TINYEXR_ERROR_INVALID_MAGIC_NUMBER; + } + marker += 4; + } + + version->tiled = false; + version->long_name = false; + version->non_image = false; + version->multipart = false; + + // Parse version header. + { + // must be 2 + if (marker[0] != 2) { + return TINYEXR_ERROR_INVALID_EXR_VERSION; + } + + if (version == NULL) { + return TINYEXR_SUCCESS; // May OK + } + + version->version = 2; + + if (marker[1] & 0x2) { // 9th bit + version->tiled = true; + } + if (marker[1] & 0x4) { // 10th bit + version->long_name = true; + } + if (marker[1] & 0x8) { // 11th bit + version->non_image = true; // (deep image) + } + if (marker[1] & 0x10) { // 12th bit + version->multipart = true; + } + } + + return TINYEXR_SUCCESS; +} + +int ParseEXRVersionFromFile(EXRVersion *version, const char *filename) { + if (filename == NULL) { + return TINYEXR_ERROR_INVALID_ARGUMENT; + } + +#ifdef _WIN32 + FILE *fp = NULL; + fopen_s(&fp, filename, "rb"); +#else + FILE *fp = fopen(filename, "rb"); +#endif + if (!fp) { + return TINYEXR_ERROR_CANT_OPEN_FILE; + } + + size_t file_size; + // Compute size + fseek(fp, 0, SEEK_END); + file_size = static_cast(ftell(fp)); + fseek(fp, 0, SEEK_SET); + + if (file_size < tinyexr::kEXRVersionSize) { + return TINYEXR_ERROR_INVALID_FILE; + } + + unsigned char buf[tinyexr::kEXRVersionSize]; + size_t ret = fread(&buf[0], 1, tinyexr::kEXRVersionSize, fp); + fclose(fp); + + if (ret != tinyexr::kEXRVersionSize) { + return TINYEXR_ERROR_INVALID_FILE; + } + + return ParseEXRVersionFromMemory(version, buf, tinyexr::kEXRVersionSize); +} + +int LoadEXRMultipartImageFromMemory(EXRImage *exr_images, + const EXRHeader **exr_headers, + unsigned int num_parts, + const unsigned char *memory, + const size_t size, const char **err) { + if (exr_images == NULL || exr_headers == NULL || num_parts == 0 || + memory == NULL || (size <= tinyexr::kEXRVersionSize)) { + if (err) { + (*err) = "Invalid argument."; + } + return TINYEXR_ERROR_INVALID_ARGUMENT; + } + + // compute total header size. + size_t total_header_size = 0; + for (unsigned int i = 0; i < num_parts; i++) { + if (exr_headers[i]->header_len == 0) { + if (err) { + (*err) = "EXRHeader is not initialized."; + } + return TINYEXR_ERROR_INVALID_ARGUMENT; + } + + total_header_size += exr_headers[i]->header_len; + } + + const char *marker = reinterpret_cast( + memory + total_header_size + 4 + + 4); // +8 for magic number and version header. + + marker += 1; // Skip empty header. + + // NOTE 1: + // In multipart image, There is 'part number' before chunk data. + // 4 byte : part number + // 4+ : chunk + // + // NOTE 2: + // EXR spec says 'part number' is 'unsigned long' but actually this is + // 'unsigned int(4 bytes)' in OpenEXR implementation... + // http://www.openexr.com/openexrfilelayout.pdf + + // Load chunk offset table. + std::vector > chunk_offset_table_list; + for (size_t i = 0; i < static_cast(num_parts); i++) { + std::vector offset_table( + static_cast(exr_headers[i]->chunk_count)); + + for (size_t c = 0; c < offset_table.size(); c++) { + tinyexr::tinyexr_uint64 offset; + memcpy(&offset, marker, 8); + tinyexr::swap8(&offset); + + if (offset >= size) { + if (err) { + (*err) = "Invalid offset size."; + } + return TINYEXR_ERROR_INVALID_DATA; + } + + offset_table[c] = offset + 4; // +4 to skip 'part number' + marker += 8; + } + + chunk_offset_table_list.push_back(offset_table); + } + + // Decode image. + for (size_t i = 0; i < static_cast(num_parts); i++) { + std::vector &offset_table = + chunk_offset_table_list[i]; + + // First check 'part number' is identitical to 'i' + for (size_t c = 0; c < offset_table.size(); c++) { + const unsigned char *part_number_addr = + memory + offset_table[c] - 4; // -4 to move to 'part number' field. + unsigned int part_no; + memcpy(&part_no, part_number_addr, sizeof(unsigned int)); // 4 + tinyexr::swap4(&part_no); + + if (part_no != i) { + assert(0); + return TINYEXR_ERROR_INVALID_DATA; + } + } + + int ret = tinyexr::DecodeChunk(&exr_images[i], exr_headers[i], offset_table, + memory); + if (ret != TINYEXR_SUCCESS) { + return ret; + } + } + + return TINYEXR_SUCCESS; +} + +int LoadEXRMultipartImageFromFile(EXRImage *exr_images, + const EXRHeader **exr_headers, + unsigned int num_parts, const char *filename, + const char **err) { + if (exr_images == NULL || exr_headers == NULL || num_parts == 0) { + if (err) { + (*err) = "Invalid argument."; + } + return TINYEXR_ERROR_INVALID_ARGUMENT; + } + +#ifdef _WIN32 + FILE *fp = NULL; + fopen_s(&fp, filename, "rb"); +#else + FILE *fp = fopen(filename, "rb"); +#endif + if (!fp) { + if (err) { + (*err) = "Cannot read file."; + } + return TINYEXR_ERROR_CANT_OPEN_FILE; + } + + size_t filesize; + // Compute size + fseek(fp, 0, SEEK_END); + filesize = static_cast(ftell(fp)); + fseek(fp, 0, SEEK_SET); + + std::vector buf(filesize); // @todo { use mmap } + { + size_t ret; + ret = fread(&buf[0], 1, filesize, fp); + assert(ret == filesize); + fclose(fp); + (void)ret; + } + + return LoadEXRMultipartImageFromMemory(exr_images, exr_headers, num_parts, + &buf.at(0), filesize, err); +} + +int SaveEXR(const float *data, int width, int height, int components, + const int save_as_fp16, const char *outfilename) { + if ((components == 1) || components == 3 || components == 4) { + // OK + } else { + return TINYEXR_ERROR_INVALID_ARGUMENT; + } + + // Assume at least 16x16 pixels. + if (width < 16) return TINYEXR_ERROR_INVALID_ARGUMENT; + if (height < 16) return TINYEXR_ERROR_INVALID_ARGUMENT; + + EXRHeader header; + InitEXRHeader(&header); + + EXRImage image; + InitEXRImage(&image); + + image.num_channels = components; + + std::vector images[4]; + + if (components == 1) { + images[0].resize(static_cast(width * height)); + memcpy(images[0].data(), data, sizeof(float) * size_t(width * height)); + } else { + images[0].resize(static_cast(width * height)); + images[1].resize(static_cast(width * height)); + images[2].resize(static_cast(width * height)); + images[3].resize(static_cast(width * height)); + + // Split RGB(A)RGB(A)RGB(A)... into R, G and B(and A) layers + for (size_t i = 0; i < static_cast(width * height); i++) { + images[0][i] = data[static_cast(components) * i + 0]; + images[1][i] = data[static_cast(components) * i + 1]; + images[2][i] = data[static_cast(components) * i + 2]; + if (components == 4) { + images[3][i] = data[static_cast(components) * i + 3]; + } + } + } + + float *image_ptr[4] = {0, 0, 0, 0}; + if (components == 4) { + image_ptr[0] = &(images[3].at(0)); // A + image_ptr[1] = &(images[2].at(0)); // B + image_ptr[2] = &(images[1].at(0)); // G + image_ptr[3] = &(images[0].at(0)); // R + } else if (components == 3) { + image_ptr[0] = &(images[2].at(0)); // B + image_ptr[1] = &(images[1].at(0)); // G + image_ptr[2] = &(images[0].at(0)); // R + } else if (components == 1) { + image_ptr[0] = &(images[0].at(0)); // A + } + + image.images = reinterpret_cast(image_ptr); + image.width = width; + image.height = height; + + header.num_channels = components; + header.channels = static_cast(malloc( + sizeof(EXRChannelInfo) * static_cast(header.num_channels))); + // Must be (A)BGR order, since most of EXR viewers expect this channel order. + if (components == 4) { +#ifdef _MSC_VER + strncpy_s(header.channels[0].name, "A", 255); + strncpy_s(header.channels[1].name, "B", 255); + strncpy_s(header.channels[2].name, "G", 255); + strncpy_s(header.channels[3].name, "R", 255); +#else + strncpy(header.channels[0].name, "A", 255); + strncpy(header.channels[1].name, "B", 255); + strncpy(header.channels[2].name, "G", 255); + strncpy(header.channels[3].name, "R", 255); +#endif + header.channels[0].name[strlen("A")] = '\0'; + header.channels[1].name[strlen("B")] = '\0'; + header.channels[2].name[strlen("G")] = '\0'; + header.channels[3].name[strlen("R")] = '\0'; + } else if (components == 3) { +#ifdef _MSC_VER + strncpy_s(header.channels[0].name, "B", 255); + strncpy_s(header.channels[1].name, "G", 255); + strncpy_s(header.channels[2].name, "R", 255); +#else + strncpy(header.channels[0].name, "B", 255); + strncpy(header.channels[1].name, "G", 255); + strncpy(header.channels[2].name, "R", 255); +#endif + header.channels[0].name[strlen("B")] = '\0'; + header.channels[1].name[strlen("G")] = '\0'; + header.channels[2].name[strlen("R")] = '\0'; + } else { +#ifdef _MSC_VER + strncpy_s(header.channels[0].name, "A", 255); +#else + strncpy(header.channels[0].name, "A", 255); +#endif + header.channels[0].name[strlen("A")] = '\0'; + } + + header.pixel_types = static_cast( + malloc(sizeof(int) * static_cast(header.num_channels))); + header.requested_pixel_types = static_cast( + malloc(sizeof(int) * static_cast(header.num_channels))); + for (int i = 0; i < header.num_channels; i++) { + header.pixel_types[i] = + TINYEXR_PIXELTYPE_FLOAT; // pixel type of input image + + if (save_as_fp16 > 0) { + header.requested_pixel_types[i] = + TINYEXR_PIXELTYPE_HALF; // save with half(fp16) pixel format + } else { + header.requested_pixel_types[i] = + TINYEXR_PIXELTYPE_FLOAT; // save with float(fp32) pixel format(i.e. + // no precision reduction) + } + } + + const char *err; + int ret = SaveEXRImageToFile(&image, &header, outfilename, &err); + if (ret != TINYEXR_SUCCESS) { + return ret; + } + + free(header.channels); + free(header.pixel_types); + free(header.requested_pixel_types); + + return ret; +} + +#endif // TINYEXR_IMPLEMENTATION_DEIFNED +#endif // TINYEXR_IMPLEMENTATION diff --git a/love/src/jni/love/src/libraries/xxHash/xxhash.c b/love/src/jni/love/src/libraries/xxHash/xxhash.c new file mode 100755 index 00000000..f74880b0 --- /dev/null +++ b/love/src/jni/love/src/libraries/xxHash/xxhash.c @@ -0,0 +1,889 @@ +/* +* xxHash - Fast Hash algorithm +* Copyright (C) 2012-2016, Yann Collet +* +* BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are +* met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above +* copyright notice, this list of conditions and the following disclaimer +* in the documentation and/or other materials provided with the +* distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* You can contact the author at : +* - xxHash homepage: http://www.xxhash.com +* - xxHash source repository : https://github.com/Cyan4973/xxHash +*/ + + +/* ************************************* +* Tuning parameters +***************************************/ +/*!XXH_FORCE_MEMORY_ACCESS : + * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. + * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. + * The below switch allow to select different access method for improved performance. + * Method 0 (default) : use `memcpy()`. Safe and portable. + * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). + * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. + * Method 2 : direct access. This method doesn't depend on compiler but violate C standard. + * It can generate buggy code on targets which do not support unaligned memory accesses. + * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) + * See http://stackoverflow.com/a/32095106/646947 for details. + * Prefer these methods in priority order (0 > 1 > 2) + */ +#ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ +# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) +# define XXH_FORCE_MEMORY_ACCESS 2 +# elif defined(__INTEL_COMPILER) || \ + (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) )) +# define XXH_FORCE_MEMORY_ACCESS 1 +# endif +#endif + +/*!XXH_ACCEPT_NULL_INPUT_POINTER : + * If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer. + * When this option is enabled, xxHash output for null input pointers will be the same as a null-length input. + * By default, this option is disabled. To enable it, uncomment below define : + */ +/* #define XXH_ACCEPT_NULL_INPUT_POINTER 1 */ + +/*!XXH_FORCE_NATIVE_FORMAT : + * By default, xxHash library provides endian-independent Hash values, based on little-endian convention. + * Results are therefore identical for little-endian and big-endian CPU. + * This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format. + * Should endian-independence be of no importance for your application, you may set the #define below to 1, + * to improve speed for Big-endian CPU. + * This option has no impact on Little_Endian CPU. + */ +#ifndef XXH_FORCE_NATIVE_FORMAT /* can be defined externally */ +# define XXH_FORCE_NATIVE_FORMAT 0 +#endif + +/*!XXH_FORCE_ALIGN_CHECK : + * This is a minor performance trick, only useful with lots of very small keys. + * It means : check for aligned/unaligned input. + * The check costs one initial branch per hash; set to 0 when the input data + * is guaranteed to be aligned. + */ +#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */ +# if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) +# define XXH_FORCE_ALIGN_CHECK 0 +# else +# define XXH_FORCE_ALIGN_CHECK 1 +# endif +#endif + + +/* ************************************* +* Includes & Memory related functions +***************************************/ +/*! Modify the local functions below should you wish to use some other memory routines +* for malloc(), free() */ +#include +static void* XXH_malloc(size_t s) { return malloc(s); } +static void XXH_free (void* p) { free(p); } +/*! and for memcpy() */ +#include +static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); } + +#define XXH_STATIC_LINKING_ONLY +#include "xxhash.h" + + +/* ************************************* +* Compiler Specific Options +***************************************/ +#ifdef _MSC_VER /* Visual Studio */ +# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ +# define FORCE_INLINE static __forceinline +#else +# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ +# ifdef __GNUC__ +# define FORCE_INLINE static inline __attribute__((always_inline)) +# else +# define FORCE_INLINE static inline +# endif +# else +# define FORCE_INLINE static +# endif /* __STDC_VERSION__ */ +#endif + + +/* ************************************* +* Basic Types +***************************************/ +#ifndef MEM_MODULE +# if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) +# include + typedef uint8_t BYTE; + typedef uint16_t U16; + typedef uint32_t U32; + typedef int32_t S32; +# else + typedef unsigned char BYTE; + typedef unsigned short U16; + typedef unsigned int U32; + typedef signed int S32; +# endif +#endif + +#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) + +/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ +static U32 XXH_read32(const void* memPtr) { return *(const U32*) memPtr; } + +#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) + +/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ +/* currently only defined for gcc and icc */ +typedef union { U32 u32; } __attribute__((packed)) unalign; +static U32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } + +#else + +/* portable and safe solution. Generally efficient. + * see : http://stackoverflow.com/a/32095106/646947 + */ +static U32 XXH_read32(const void* memPtr) +{ + U32 val; + memcpy(&val, memPtr, sizeof(val)); + return val; +} + +#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ + + +/* **************************************** +* Compiler-specific Functions and Macros +******************************************/ +#define XXH_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) + +/* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */ +#if defined(_MSC_VER) +# define XXH_rotl32(x,r) _rotl(x,r) +# define XXH_rotl64(x,r) _rotl64(x,r) +#else +# define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r))) +# define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r))) +#endif + +#if defined(_MSC_VER) /* Visual Studio */ +# define XXH_swap32 _byteswap_ulong +#elif XXH_GCC_VERSION >= 403 +# define XXH_swap32 __builtin_bswap32 +#else +static U32 XXH_swap32 (U32 x) +{ + return ((x << 24) & 0xff000000 ) | + ((x << 8) & 0x00ff0000 ) | + ((x >> 8) & 0x0000ff00 ) | + ((x >> 24) & 0x000000ff ); +} +#endif + + +/* ************************************* +* Architecture Macros +***************************************/ +typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess; + +/* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */ +#ifndef XXH_CPU_LITTLE_ENDIAN + static const int g_one = 1; +# define XXH_CPU_LITTLE_ENDIAN (*(const char*)(&g_one)) +#endif + + +/* *************************** +* Memory reads +*****************************/ +typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment; + +FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align) +{ + if (align==XXH_unaligned) + return endian==XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr)); + else + return endian==XXH_littleEndian ? *(const U32*)ptr : XXH_swap32(*(const U32*)ptr); +} + +FORCE_INLINE U32 XXH_readLE32(const void* ptr, XXH_endianess endian) +{ + return XXH_readLE32_align(ptr, endian, XXH_unaligned); +} + +static U32 XXH_readBE32(const void* ptr) +{ + return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr); +} + + +/* ************************************* +* Macros +***************************************/ +#define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */ +XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; } + + +/* ******************************************************************* +* 32-bits hash functions +*********************************************************************/ +static const U32 PRIME32_1 = 2654435761U; +static const U32 PRIME32_2 = 2246822519U; +static const U32 PRIME32_3 = 3266489917U; +static const U32 PRIME32_4 = 668265263U; +static const U32 PRIME32_5 = 374761393U; + +static U32 XXH32_round(U32 seed, U32 input) +{ + seed += input * PRIME32_2; + seed = XXH_rotl32(seed, 13); + seed *= PRIME32_1; + return seed; +} + +FORCE_INLINE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align) +{ + const BYTE* p = (const BYTE*)input; + const BYTE* bEnd = p + len; + U32 h32; +#define XXH_get32bits(p) XXH_readLE32_align(p, endian, align) + +#ifdef XXH_ACCEPT_NULL_INPUT_POINTER + if (p==NULL) { + len=0; + bEnd=p=(const BYTE*)(size_t)16; + } +#endif + + if (len>=16) { + const BYTE* const limit = bEnd - 16; + U32 v1 = seed + PRIME32_1 + PRIME32_2; + U32 v2 = seed + PRIME32_2; + U32 v3 = seed + 0; + U32 v4 = seed - PRIME32_1; + + do { + v1 = XXH32_round(v1, XXH_get32bits(p)); p+=4; + v2 = XXH32_round(v2, XXH_get32bits(p)); p+=4; + v3 = XXH32_round(v3, XXH_get32bits(p)); p+=4; + v4 = XXH32_round(v4, XXH_get32bits(p)); p+=4; + } while (p<=limit); + + h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); + } else { + h32 = seed + PRIME32_5; + } + + h32 += (U32) len; + + while (p+4<=bEnd) { + h32 += XXH_get32bits(p) * PRIME32_3; + h32 = XXH_rotl32(h32, 17) * PRIME32_4 ; + p+=4; + } + + while (p> 15; + h32 *= PRIME32_2; + h32 ^= h32 >> 13; + h32 *= PRIME32_3; + h32 ^= h32 >> 16; + + return h32; +} + + +XXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsigned int seed) +{ +#if 0 + /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ + XXH32_state_t state; + XXH32_reset(&state, seed); + XXH32_update(&state, input, len); + return XXH32_digest(&state); +#else + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if (XXH_FORCE_ALIGN_CHECK) { + if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */ + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); + else + return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); + } } + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); + else + return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); +#endif +} + + + +/*====== Hash streaming ======*/ + +XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void) +{ + return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t)); +} +XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr) +{ + XXH_free(statePtr); + return XXH_OK; +} + +XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32_state_t* srcState) +{ + memcpy(dstState, srcState, sizeof(*dstState)); +} + +XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsigned int seed) +{ + XXH32_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ + memset(&state, 0, sizeof(state)-4); /* do not write into reserved, for future removal */ + state.v1 = seed + PRIME32_1 + PRIME32_2; + state.v2 = seed + PRIME32_2; + state.v3 = seed + 0; + state.v4 = seed - PRIME32_1; + memcpy(statePtr, &state, sizeof(state)); + return XXH_OK; +} + + +FORCE_INLINE XXH_errorcode XXH32_update_endian (XXH32_state_t* state, const void* input, size_t len, XXH_endianess endian) +{ + const BYTE* p = (const BYTE*)input; + const BYTE* const bEnd = p + len; + +#ifdef XXH_ACCEPT_NULL_INPUT_POINTER + if (input==NULL) return XXH_ERROR; +#endif + + state->total_len_32 += (unsigned)len; + state->large_len |= (len>=16) | (state->total_len_32>=16); + + if (state->memsize + len < 16) { /* fill in tmp buffer */ + XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len); + state->memsize += (unsigned)len; + return XXH_OK; + } + + if (state->memsize) { /* some data left from previous update */ + XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize); + { const U32* p32 = state->mem32; + state->v1 = XXH32_round(state->v1, XXH_readLE32(p32, endian)); p32++; + state->v2 = XXH32_round(state->v2, XXH_readLE32(p32, endian)); p32++; + state->v3 = XXH32_round(state->v3, XXH_readLE32(p32, endian)); p32++; + state->v4 = XXH32_round(state->v4, XXH_readLE32(p32, endian)); p32++; + } + p += 16-state->memsize; + state->memsize = 0; + } + + if (p <= bEnd-16) { + const BYTE* const limit = bEnd - 16; + U32 v1 = state->v1; + U32 v2 = state->v2; + U32 v3 = state->v3; + U32 v4 = state->v4; + + do { + v1 = XXH32_round(v1, XXH_readLE32(p, endian)); p+=4; + v2 = XXH32_round(v2, XXH_readLE32(p, endian)); p+=4; + v3 = XXH32_round(v3, XXH_readLE32(p, endian)); p+=4; + v4 = XXH32_round(v4, XXH_readLE32(p, endian)); p+=4; + } while (p<=limit); + + state->v1 = v1; + state->v2 = v2; + state->v3 = v3; + state->v4 = v4; + } + + if (p < bEnd) { + XXH_memcpy(state->mem32, p, (size_t)(bEnd-p)); + state->memsize = (unsigned)(bEnd-p); + } + + return XXH_OK; +} + +XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len) +{ + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH32_update_endian(state_in, input, len, XXH_littleEndian); + else + return XXH32_update_endian(state_in, input, len, XXH_bigEndian); +} + + + +FORCE_INLINE U32 XXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian) +{ + const BYTE * p = (const BYTE*)state->mem32; + const BYTE* const bEnd = (const BYTE*)(state->mem32) + state->memsize; + U32 h32; + + if (state->large_len) { + h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18); + } else { + h32 = state->v3 /* == seed */ + PRIME32_5; + } + + h32 += state->total_len_32; + + while (p+4<=bEnd) { + h32 += XXH_readLE32(p, endian) * PRIME32_3; + h32 = XXH_rotl32(h32, 17) * PRIME32_4; + p+=4; + } + + while (p> 15; + h32 *= PRIME32_2; + h32 ^= h32 >> 13; + h32 *= PRIME32_3; + h32 ^= h32 >> 16; + + return h32; +} + + +XXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* state_in) +{ + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH32_digest_endian(state_in, XXH_littleEndian); + else + return XXH32_digest_endian(state_in, XXH_bigEndian); +} + + +/*====== Canonical representation ======*/ + +/*! Default XXH result types are basic unsigned 32 and 64 bits. +* The canonical representation follows human-readable write convention, aka big-endian (large digits first). +* These functions allow transformation of hash result into and from its canonical format. +* This way, hash values can be written into a file or buffer, and remain comparable across different systems and programs. +*/ + +XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash) +{ + XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); + if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash); + memcpy(dst, &hash, sizeof(*dst)); +} + +XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src) +{ + return XXH_readBE32(src); +} + + +#ifndef XXH_NO_LONG_LONG + +/* ******************************************************************* +* 64-bits hash functions +*********************************************************************/ + +/*====== Memory access ======*/ + +#ifndef MEM_MODULE +# define MEM_MODULE +# if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) +# include + typedef uint64_t U64; +# else + typedef unsigned long long U64; /* if your compiler doesn't support unsigned long long, replace by another 64-bit type here. Note that xxhash.h will also need to be updated. */ +# endif +#endif + + +#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) + +/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ +static U64 XXH_read64(const void* memPtr) { return *(const U64*) memPtr; } + +#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) + +/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ +/* currently only defined for gcc and icc */ +typedef union { U32 u32; U64 u64; } __attribute__((packed)) unalign64; +static U64 XXH_read64(const void* ptr) { return ((const unalign64*)ptr)->u64; } + +#else + +/* portable and safe solution. Generally efficient. + * see : http://stackoverflow.com/a/32095106/646947 + */ + +static U64 XXH_read64(const void* memPtr) +{ + U64 val; + memcpy(&val, memPtr, sizeof(val)); + return val; +} + +#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ + +#if defined(_MSC_VER) /* Visual Studio */ +# define XXH_swap64 _byteswap_uint64 +#elif XXH_GCC_VERSION >= 403 +# define XXH_swap64 __builtin_bswap64 +#else +static U64 XXH_swap64 (U64 x) +{ + return ((x << 56) & 0xff00000000000000ULL) | + ((x << 40) & 0x00ff000000000000ULL) | + ((x << 24) & 0x0000ff0000000000ULL) | + ((x << 8) & 0x000000ff00000000ULL) | + ((x >> 8) & 0x00000000ff000000ULL) | + ((x >> 24) & 0x0000000000ff0000ULL) | + ((x >> 40) & 0x000000000000ff00ULL) | + ((x >> 56) & 0x00000000000000ffULL); +} +#endif + +FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align) +{ + if (align==XXH_unaligned) + return endian==XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr)); + else + return endian==XXH_littleEndian ? *(const U64*)ptr : XXH_swap64(*(const U64*)ptr); +} + +FORCE_INLINE U64 XXH_readLE64(const void* ptr, XXH_endianess endian) +{ + return XXH_readLE64_align(ptr, endian, XXH_unaligned); +} + +static U64 XXH_readBE64(const void* ptr) +{ + return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr); +} + + +/*====== xxh64 ======*/ + +static const U64 PRIME64_1 = 11400714785074694791ULL; +static const U64 PRIME64_2 = 14029467366897019727ULL; +static const U64 PRIME64_3 = 1609587929392839161ULL; +static const U64 PRIME64_4 = 9650029242287828579ULL; +static const U64 PRIME64_5 = 2870177450012600261ULL; + +static U64 XXH64_round(U64 acc, U64 input) +{ + acc += input * PRIME64_2; + acc = XXH_rotl64(acc, 31); + acc *= PRIME64_1; + return acc; +} + +static U64 XXH64_mergeRound(U64 acc, U64 val) +{ + val = XXH64_round(0, val); + acc ^= val; + acc = acc * PRIME64_1 + PRIME64_4; + return acc; +} + +FORCE_INLINE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align) +{ + const BYTE* p = (const BYTE*)input; + const BYTE* bEnd = p + len; + U64 h64; +#define XXH_get64bits(p) XXH_readLE64_align(p, endian, align) + +#ifdef XXH_ACCEPT_NULL_INPUT_POINTER + if (p==NULL) { + len=0; + bEnd=p=(const BYTE*)(size_t)32; + } +#endif + + if (len>=32) { + const BYTE* const limit = bEnd - 32; + U64 v1 = seed + PRIME64_1 + PRIME64_2; + U64 v2 = seed + PRIME64_2; + U64 v3 = seed + 0; + U64 v4 = seed - PRIME64_1; + + do { + v1 = XXH64_round(v1, XXH_get64bits(p)); p+=8; + v2 = XXH64_round(v2, XXH_get64bits(p)); p+=8; + v3 = XXH64_round(v3, XXH_get64bits(p)); p+=8; + v4 = XXH64_round(v4, XXH_get64bits(p)); p+=8; + } while (p<=limit); + + h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); + h64 = XXH64_mergeRound(h64, v1); + h64 = XXH64_mergeRound(h64, v2); + h64 = XXH64_mergeRound(h64, v3); + h64 = XXH64_mergeRound(h64, v4); + + } else { + h64 = seed + PRIME64_5; + } + + h64 += (U64) len; + + while (p+8<=bEnd) { + U64 const k1 = XXH64_round(0, XXH_get64bits(p)); + h64 ^= k1; + h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; + p+=8; + } + + if (p+4<=bEnd) { + h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1; + h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; + p+=4; + } + + while (p> 33; + h64 *= PRIME64_2; + h64 ^= h64 >> 29; + h64 *= PRIME64_3; + h64 ^= h64 >> 32; + + return h64; +} + + +XXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed) +{ +#if 0 + /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ + XXH64_state_t state; + XXH64_reset(&state, seed); + XXH64_update(&state, input, len); + return XXH64_digest(&state); +#else + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if (XXH_FORCE_ALIGN_CHECK) { + if ((((size_t)input) & 7)==0) { /* Input is aligned, let's leverage the speed advantage */ + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); + else + return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); + } } + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); + else + return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); +#endif +} + +/*====== Hash Streaming ======*/ + +XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void) +{ + return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t)); +} +XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr) +{ + XXH_free(statePtr); + return XXH_OK; +} + +XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dstState, const XXH64_state_t* srcState) +{ + memcpy(dstState, srcState, sizeof(*dstState)); +} + +XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsigned long long seed) +{ + XXH64_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ + memset(&state, 0, sizeof(state)-8); /* do not write into reserved, for future removal */ + state.v1 = seed + PRIME64_1 + PRIME64_2; + state.v2 = seed + PRIME64_2; + state.v3 = seed + 0; + state.v4 = seed - PRIME64_1; + memcpy(statePtr, &state, sizeof(state)); + return XXH_OK; +} + +FORCE_INLINE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_endianess endian) +{ + const BYTE* p = (const BYTE*)input; + const BYTE* const bEnd = p + len; + +#ifdef XXH_ACCEPT_NULL_INPUT_POINTER + if (input==NULL) return XXH_ERROR; +#endif + + state->total_len += len; + + if (state->memsize + len < 32) { /* fill in tmp buffer */ + XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len); + state->memsize += (U32)len; + return XXH_OK; + } + + if (state->memsize) { /* tmp buffer is full */ + XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize); + state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64+0, endian)); + state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64+1, endian)); + state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64+2, endian)); + state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64+3, endian)); + p += 32-state->memsize; + state->memsize = 0; + } + + if (p+32 <= bEnd) { + const BYTE* const limit = bEnd - 32; + U64 v1 = state->v1; + U64 v2 = state->v2; + U64 v3 = state->v3; + U64 v4 = state->v4; + + do { + v1 = XXH64_round(v1, XXH_readLE64(p, endian)); p+=8; + v2 = XXH64_round(v2, XXH_readLE64(p, endian)); p+=8; + v3 = XXH64_round(v3, XXH_readLE64(p, endian)); p+=8; + v4 = XXH64_round(v4, XXH_readLE64(p, endian)); p+=8; + } while (p<=limit); + + state->v1 = v1; + state->v2 = v2; + state->v3 = v3; + state->v4 = v4; + } + + if (p < bEnd) { + XXH_memcpy(state->mem64, p, (size_t)(bEnd-p)); + state->memsize = (unsigned)(bEnd-p); + } + + return XXH_OK; +} + +XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len) +{ + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH64_update_endian(state_in, input, len, XXH_littleEndian); + else + return XXH64_update_endian(state_in, input, len, XXH_bigEndian); +} + +FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess endian) +{ + const BYTE * p = (const BYTE*)state->mem64; + const BYTE* const bEnd = (const BYTE*)state->mem64 + state->memsize; + U64 h64; + + if (state->total_len >= 32) { + U64 const v1 = state->v1; + U64 const v2 = state->v2; + U64 const v3 = state->v3; + U64 const v4 = state->v4; + + h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); + h64 = XXH64_mergeRound(h64, v1); + h64 = XXH64_mergeRound(h64, v2); + h64 = XXH64_mergeRound(h64, v3); + h64 = XXH64_mergeRound(h64, v4); + } else { + h64 = state->v3 + PRIME64_5; + } + + h64 += (U64) state->total_len; + + while (p+8<=bEnd) { + U64 const k1 = XXH64_round(0, XXH_readLE64(p, endian)); + h64 ^= k1; + h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; + p+=8; + } + + if (p+4<=bEnd) { + h64 ^= (U64)(XXH_readLE32(p, endian)) * PRIME64_1; + h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; + p+=4; + } + + while (p> 33; + h64 *= PRIME64_2; + h64 ^= h64 >> 29; + h64 *= PRIME64_3; + h64 ^= h64 >> 32; + + return h64; +} + +XXH_PUBLIC_API unsigned long long XXH64_digest (const XXH64_state_t* state_in) +{ + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH64_digest_endian(state_in, XXH_littleEndian); + else + return XXH64_digest_endian(state_in, XXH_bigEndian); +} + + +/*====== Canonical representation ======*/ + +XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash) +{ + XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t)); + if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash); + memcpy(dst, &hash, sizeof(*dst)); +} + +XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src) +{ + return XXH_readBE64(src); +} + +#endif /* XXH_NO_LONG_LONG */ diff --git a/love/src/jni/love/src/libraries/xxHash/xxhash.h b/love/src/jni/love/src/libraries/xxHash/xxhash.h new file mode 100755 index 00000000..9d831e03 --- /dev/null +++ b/love/src/jni/love/src/libraries/xxHash/xxhash.h @@ -0,0 +1,293 @@ +/* + xxHash - Extremely Fast Hash algorithm + Header File + Copyright (C) 2012-2016, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - xxHash source repository : https://github.com/Cyan4973/xxHash +*/ + +/* Notice extracted from xxHash homepage : + +xxHash is an extremely fast Hash algorithm, running at RAM speed limits. +It also successfully passes all tests from the SMHasher suite. + +Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz) + +Name Speed Q.Score Author +xxHash 5.4 GB/s 10 +CrapWow 3.2 GB/s 2 Andrew +MumurHash 3a 2.7 GB/s 10 Austin Appleby +SpookyHash 2.0 GB/s 10 Bob Jenkins +SBox 1.4 GB/s 9 Bret Mulvey +Lookup3 1.2 GB/s 9 Bob Jenkins +SuperFastHash 1.2 GB/s 1 Paul Hsieh +CityHash64 1.05 GB/s 10 Pike & Alakuijala +FNV 0.55 GB/s 5 Fowler, Noll, Vo +CRC32 0.43 GB/s 9 +MD5-32 0.33 GB/s 10 Ronald L. Rivest +SHA1-32 0.28 GB/s 10 + +Q.Score is a measure of quality of the hash function. +It depends on successfully passing SMHasher test set. +10 is a perfect score. + +A 64-bits version, named XXH64, is available since r35. +It offers much better speed, but for 64-bits applications only. +Name Speed on 64 bits Speed on 32 bits +XXH64 13.8 GB/s 1.9 GB/s +XXH32 6.8 GB/s 6.0 GB/s +*/ + +#ifndef XXHASH_H_5627135585666179 +#define XXHASH_H_5627135585666179 1 + +#if defined (__cplusplus) +extern "C" { +#endif + + +/* **************************** +* Definitions +******************************/ +#include /* size_t */ +typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; + + +/* **************************** +* API modifier +******************************/ +/** XXH_PRIVATE_API +* This is useful to include xxhash functions in `static` mode +* in order to inline them, and remove their symbol from the public list. +* Methodology : +* #define XXH_PRIVATE_API +* #include "xxhash.h" +* `xxhash.c` is automatically included. +* It's not useful to compile and link it as a separate module. +*/ +#ifdef XXH_PRIVATE_API +# ifndef XXH_STATIC_LINKING_ONLY +# define XXH_STATIC_LINKING_ONLY +# endif +# if defined(__GNUC__) +# define XXH_PUBLIC_API static __inline __attribute__((unused)) +# elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +# define XXH_PUBLIC_API static inline +# elif defined(_MSC_VER) +# define XXH_PUBLIC_API static __inline +# else +# define XXH_PUBLIC_API static /* this version may generate warnings for unused static functions; disable the relevant warning */ +# endif +#else +# define XXH_PUBLIC_API /* do nothing */ +#endif /* XXH_PRIVATE_API */ + +/*!XXH_NAMESPACE, aka Namespace Emulation : + +If you want to include _and expose_ xxHash functions from within your own library, +but also want to avoid symbol collisions with other libraries which may also include xxHash, + +you can use XXH_NAMESPACE, to automatically prefix any public symbol from xxhash library +with the value of XXH_NAMESPACE (therefore, avoid NULL and numeric values). + +Note that no change is required within the calling program as long as it includes `xxhash.h` : +regular symbol name will be automatically translated by this header. +*/ +#ifdef XXH_NAMESPACE +# define XXH_CAT(A,B) A##B +# define XXH_NAME2(A,B) XXH_CAT(A,B) +# define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber) +# define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32) +# define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState) +# define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState) +# define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset) +# define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update) +# define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest) +# define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState) +# define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash) +# define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical) +# define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64) +# define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState) +# define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState) +# define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset) +# define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update) +# define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest) +# define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState) +# define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash) +# define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical) +#endif + + +/* ************************************* +* Version +***************************************/ +#define XXH_VERSION_MAJOR 0 +#define XXH_VERSION_MINOR 6 +#define XXH_VERSION_RELEASE 2 +#define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE) +XXH_PUBLIC_API unsigned XXH_versionNumber (void); + + +/*-********************************************************************** +* 32-bits hash +************************************************************************/ +typedef unsigned int XXH32_hash_t; + +/*! XXH32() : + Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input". + The memory between input & input+length must be valid (allocated and read-accessible). + "seed" can be used to alter the result predictably. + Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s */ +XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, unsigned int seed); + +/*====== Streaming ======*/ +typedef struct XXH32_state_s XXH32_state_t; /* incomplete type */ +XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void); +XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr); +XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_t* src_state); + +XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned int seed); +XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length); +XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr); + +/* +These functions generate the xxHash of an input provided in multiple segments. +Note that, for small input, they are slower than single-call functions, due to state management. +For small input, prefer `XXH32()` and `XXH64()` . + +XXH state must first be allocated, using XXH*_createState() . + +Start a new hash by initializing state with a seed, using XXH*_reset(). + +Then, feed the hash state by calling XXH*_update() as many times as necessary. +Obviously, input must be allocated and read accessible. +The function returns an error code, with 0 meaning OK, and any other value meaning there is an error. + +Finally, a hash value can be produced anytime, by using XXH*_digest(). +This function returns the nn-bits hash as an int or long long. + +It's still possible to continue inserting input into the hash state after a digest, +and generate some new hashes later on, by calling again XXH*_digest(). + +When done, free XXH state space if it was allocated dynamically. +*/ + +/*====== Canonical representation ======*/ + +typedef struct { unsigned char digest[4]; } XXH32_canonical_t; +XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash); +XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src); + +/* Default result type for XXH functions are primitive unsigned 32 and 64 bits. +* The canonical representation uses human-readable write convention, aka big-endian (large digits first). +* These functions allow transformation of hash result into and from its canonical format. +* This way, hash values can be written into a file / memory, and remain comparable on different systems and programs. +*/ + + +#ifndef XXH_NO_LONG_LONG +/*-********************************************************************** +* 64-bits hash +************************************************************************/ +typedef unsigned long long XXH64_hash_t; + +/*! XXH64() : + Calculate the 64-bits hash of sequence of length "len" stored at memory address "input". + "seed" can be used to alter the result predictably. + This function runs faster on 64-bits systems, but slower on 32-bits systems (see benchmark). +*/ +XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t length, unsigned long long seed); + +/*====== Streaming ======*/ +typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */ +XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void); +XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); +XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dst_state, const XXH64_state_t* src_state); + +XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed); +XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length); +XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr); + +/*====== Canonical representation ======*/ +typedef struct { unsigned char digest[8]; } XXH64_canonical_t; +XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash); +XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src); +#endif /* XXH_NO_LONG_LONG */ + + +#ifdef XXH_STATIC_LINKING_ONLY + +/* ================================================================================================ + This section contains definitions which are not guaranteed to remain stable. + They may change in future versions, becoming incompatible with a different version of the library. + They shall only be used with static linking. + Never use these definitions in association with dynamic linking ! +=================================================================================================== */ + +/* These definitions are only meant to make possible + static allocation of XXH state, on stack or in a struct for example. + Never use members directly. */ + +struct XXH32_state_s { + unsigned total_len_32; + unsigned large_len; + unsigned v1; + unsigned v2; + unsigned v3; + unsigned v4; + unsigned mem32[4]; /* buffer defined as U32 for alignment */ + unsigned memsize; + unsigned reserved; /* never read nor write, will be removed in a future version */ +}; /* typedef'd to XXH32_state_t */ + +#ifndef XXH_NO_LONG_LONG /* remove 64-bits support */ +struct XXH64_state_s { + unsigned long long total_len; + unsigned long long v1; + unsigned long long v2; + unsigned long long v3; + unsigned long long v4; + unsigned long long mem64[4]; /* buffer defined as U64 for alignment */ + unsigned memsize; + unsigned reserved[2]; /* never read nor write, will be removed in a future version */ +}; /* typedef'd to XXH64_state_t */ +#endif + +#ifdef XXH_PRIVATE_API +# include "xxhash.c" /* include xxhash function bodies as `static`, for inlining */ +#endif + +#endif /* XXH_STATIC_LINKING_ONLY */ + + +#if defined (__cplusplus) +} +#endif + +#endif /* XXHASH_H_5627135585666179 */ diff --git a/love/src/jni/love/src/love.cpp b/love/src/jni/love/src/love.cpp index 00e8f36c..a4a2444c 100644 --- a/love/src/jni/love/src/love.cpp +++ b/love/src/jni/love/src/love.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -44,17 +44,10 @@ extern "C" { #include "common/ios.h" #endif -#ifdef LOVE_ANDROID -#include "common/android.h" -extern "C" -{ -#include "luajit.h" -} -#endif - #ifdef LOVE_WINDOWS extern "C" { + // Prefer the higher performance GPU on Windows systems that use nvidia Optimus. // http://developer.download.nvidia.com/devzone/devcenter/gamegraphics/files/OptimusRenderingPolicies.pdf // TODO: Re-evaluate in the future when the average integrated GPU in Optimus @@ -139,39 +132,6 @@ static int love_preload(lua_State *L, lua_CFunction f, const char *name) return 0; } -#ifdef LOVE_ANDROID -static int l_print_sdl_log(lua_State *L) -{ - int nargs = lua_gettop(L); - - lua_getglobal(L, "tostring"); - - std::string outstring; - - for (int i = 1; i <= nargs; i++) - { - // Call tostring(arg) and leave the result on the top of the stack. - lua_pushvalue(L, -1); - lua_pushvalue(L, i); - lua_call(L, 1, 1); - - const char *s = lua_tostring(L, -1); - if (s == nullptr) - return luaL_error(L, "'tostring' must return a string to 'print'"); - - if (i > 1) - outstring += "\t"; - - outstring += s; - - lua_pop(L, 1); // Pop the result of tostring(arg). - } - - SDL_Log("[LOVE] %s", outstring.c_str()); - return 0; -} -#endif - enum DoneAction { DONE_QUIT, @@ -191,6 +151,10 @@ static DoneAction runlove(int argc, char **argv, int &retval) // Oh, you just want the version? Okay! if (argc > 1 && strcmp(argv[1], "--version") == 0) { +#ifdef LOVE_LEGENDARY_CONSOLE_IO_HACK + const char *err = nullptr; + love_openConsole(err); +#endif printf("LOVE %s (%s)\n", love_version(), love_codename()); retval = 0; return DONE_QUIT; @@ -200,11 +164,6 @@ static DoneAction runlove(int argc, char **argv, int &retval) lua_State *L = luaL_newstate(); luaL_openlibs(L); -#ifdef LOVE_ANDROID - luaJIT_setmode(L, 0, LUAJIT_MODE_ENGINE| LUAJIT_MODE_OFF); - lua_register(L, "print", l_print_sdl_log); -#endif - // Add love to package.preload for easy requiring. love_preload(L, luaopen_love, "love"); @@ -251,8 +210,12 @@ static DoneAction runlove(int argc, char **argv, int &retval) lua_pushstring(L, "love.boot"); lua_call(L, 1, 1); - // Call the returned boot function. - lua_call(L, 0, 1); + // Turn the returned boot function into a coroutine and call it until done. + lua_newthread(L); + lua_pushvalue(L, -2); + int stackpos = lua_gettop(L); + while (lua_resume(L, 0) == LUA_YIELD) + lua_pop(L, lua_gettop(L) - stackpos); retval = 0; DoneAction done = DONE_QUIT; diff --git a/love/src/jni/love/src/modules/audio/Audio.cpp b/love/src/jni/love/src/modules/audio/Audio.cpp index 86d7b914..9092af8e 100644 --- a/love/src/jni/love/src/modules/audio/Audio.cpp +++ b/love/src/jni/love/src/modules/audio/Audio.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -13,18 +13,34 @@ * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. - * 2. Altered Audio versions must be plainly marked as such, and must not be + * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any Audio distribution. + * 3. This notice may not be removed or altered from any source distribution. **/ #include "Audio.h" +#include "common/config.h" + +#ifdef LOVE_IOS +#include "common/ios.h" +#endif namespace love { namespace audio { +bool Audio::setMixWithSystem(bool mix) +{ +#ifdef LOVE_IOS + love::ios::setAudioMixWithOthers(mix); + return true; +#else + LOVE_UNUSED(mix); + return false; +#endif +} + StringMap::Entry Audio::distanceModelEntries[] = { {"none", Audio::DISTANCE_NONE}, @@ -48,5 +64,10 @@ bool Audio::getConstant(DistanceModel in, const char *&out) return distanceModels.find(in, out); } +std::vector Audio::getConstants(DistanceModel) +{ + return distanceModels.getNames(); +} + } // audio } // love diff --git a/love/src/jni/love/src/modules/audio/Audio.h b/love/src/jni/love/src/modules/audio/Audio.h index 4cd59ced..2f3fe6e1 100644 --- a/love/src/jni/love/src/modules/audio/Audio.h +++ b/love/src/jni/love/src/modules/audio/Audio.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -9,7 +9,7 @@ * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * - * 1. The origin of this software must not be misrepresented = 0; you must not + * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. @@ -21,9 +21,15 @@ #ifndef LOVE_AUDIO_AUDIO_H #define LOVE_AUDIO_AUDIO_H +// STL +#include + +// LOVE #include "common/Module.h" #include "common/StringMap.h" #include "Source.h" +#include "Effect.h" +#include "RecordingDevice.h" namespace love { @@ -63,6 +69,7 @@ public: static bool getConstant(const char *in, DistanceModel &out); static bool getConstant(DistanceModel in, const char *&out); + static std::vector getConstants(DistanceModel); virtual ~Audio() {} @@ -71,12 +78,13 @@ public: virtual Source *newSource(love::sound::Decoder *decoder) = 0; virtual Source *newSource(love::sound::SoundData *soundData) = 0; + virtual Source *newSource(int sampleRate, int bitDepth, int channels, int buffers) = 0; /** * Gets the current number of simultaneous playing sources. * @return The current number of simultaneous playing sources. **/ - virtual int getSourceCount() const = 0; + virtual int getActiveSourceCount() const = 0; /** * Gets the maximum supported number of simultaneous playing sources. @@ -90,12 +98,24 @@ public: **/ virtual bool play(Source *source) = 0; + /** + * Play the specified Sources. + * @param sources The Sources to play. + **/ + virtual bool play(const std::vector &sources) = 0; + /** * Stops playback on the specified source. * @param source The source on which to stop the playback. **/ virtual void stop(Source *source) = 0; + /** + * Stops playback on the specified sources. + * @param sources The sources on which to stop the playback. + **/ + virtual void stop(const std::vector &sources) = 0; + /** * Stops all playing audio. **/ @@ -107,33 +127,16 @@ public: **/ virtual void pause(Source *source) = 0; + /** + * Pauses playback on the specified sources. + * @param sources The sources on which to pause the playback. + **/ + virtual void pause(const std::vector &sources) = 0; + /** * Pauses all audio. **/ - virtual void pause() = 0; - - /** - * Resumes playback on the specified source. - * @param source The source on which to resume the playback. - **/ - virtual void resume(Source *source) = 0; - - /** - * Resumes all audio. - **/ - virtual void resume() = 0; - - /** - * Rewinds the specified source. Whatever is playing on this - * source gets rewound to the start. - * @param source The source to rewind. - **/ - virtual void rewind(Source *source) = 0; - - /** - * Rewinds all playing audio. - **/ - virtual void rewind() = 0; + virtual std::vector pause() = 0; /** * Sets the master volume, where 0.0f is min (off) and 1.0f is max. @@ -187,36 +190,12 @@ public: virtual void setDopplerScale(float scale) = 0; virtual float getDopplerScale() const = 0; - + //virtual void setMeter(float scale) = 0; + //virtual float getMeter() const = 0; /** - * Begins recording audio input from the microphone. + * @return Reference to a vector of pointers to recording devices. May be empty. **/ - virtual void record() = 0; - - /** - * Gets a section of recorded audio. - * Per OpenAL, the measurement begins from the start of the - * audio data in memory, which is after the last time this function - * was called. If this function has not been called yet this recording - * session, it just grabs from the beginning. - * @return All the recorded SoundData thus far. - **/ - virtual love::sound::SoundData *getRecordedData() = 0; - - /** - * Stops recording and, if passed true, returns all the recorded audio - * not already gotten by getRecordedData. - * @param returnData Whether to return recorded audio. - * @return if returnData, all the recorded audio yet to be gotten, - * otherwise NULL. - **/ - virtual love::sound::SoundData *stopRecording(bool returnData) = 0; - - /** - * Checks whether LOVE is able to record audio input. - * @return hasMic Whether LOVE has a microphone enabled. - **/ - virtual bool canRecord() = 0; + virtual const std::vector &getRecordingDevices() = 0; /** * Gets the distance model used for attenuation. @@ -230,6 +209,60 @@ public: */ virtual void setDistanceModel(DistanceModel distanceModel) = 0; + /** + * Sets scene EFX effect. + * @param name Effect name to use. + * @param fxparams Effect description table. + * @return true if successful, false otherwise. + */ + virtual bool setEffect(const char *name, std::map ¶ms) = 0; + + /** + * Removes scene EFX effect. + * @param name Effect name to clear. + * @return true if successful, false otherwise. + */ + virtual bool unsetEffect(const char *name) = 0; + + /** + * Gets scene EFX effect. + * @param name Effect name to get data from. + * @param fxparams Effect description table. + * @return true if effect was present, false otherwise. + */ + virtual bool getEffect(const char *name, std::map ¶ms) = 0; + + /** + * Gets list of EFX effect names. + * @param list List of EFX names to fill. + * @return true if effect was present, false otherwise. + */ + virtual bool getActiveEffects(std::vector &list) const = 0; + + /** + * Gets maximum number of scene EFX effects. + * @return number of effects. + */ + virtual int getMaxSceneEffects() const = 0; + + /** + * Gets maximum number of source EFX effects. + * @return number of effects. + */ + virtual int getMaxSourceEffects() const = 0; + + /** + * Gets EFX (or analog) availability. + * @return true if supported. + */ + virtual bool isEFXsupported() const = 0; + + /** + * Sets whether audio from other apps mixes with love.audio or is muted, + * on supported platforms. + **/ + bool setMixWithSystem(bool mix); + private: static StringMap::Entry distanceModelEntries[]; diff --git a/love/src/jni/love/src/modules/audio/Effect.cpp b/love/src/jni/love/src/modules/audio/Effect.cpp new file mode 100644 index 00000000..30c2b176 --- /dev/null +++ b/love/src/jni/love/src/modules/audio/Effect.cpp @@ -0,0 +1,396 @@ +/** + * Copyright (c) 2006-2018 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#include "Effect.h" + +namespace love +{ +namespace audio +{ + +Effect::Effect() +{ +} + +Effect::~Effect() +{ +} + +Effect::Type Effect::getType() const +{ + return type; +} + +bool Effect::getConstant(const char *in, Type &out) +{ + return types.find(in, out); +} + +bool Effect::getConstant(Type in, const char *&out) +{ + return types.find(in, out); +} + +std::vector Effect::getConstants(Type) +{ + return types.getNames(); +} + +/* +bool Effect::getConstant(const char *in, Phoneme &out) +{ + return phonemes.find(in, out); +} + +bool Effect::getConstant(Phoneme in, const char *&out) +{ + return phonemes.find(in, out); +} +*/ +bool Effect::getConstant(const char *in, Waveform &out) +{ + return waveforms.find(in, out); +} + +bool Effect::getConstant(Waveform in, const char *&out) +{ + return waveforms.find(in, out); +} +/* +bool Effect::getConstant(const char *in, Direction &out) +{ + return directions.find(in, out); +} + +bool Effect::getConstant(Direction in, const char *&out) +{ + return directions.find(in, out); +} +*/ +bool Effect::getConstant(const char *in, Parameter &out, Type t) +{ + return parameterNames[t].find(in, out); +} + +bool Effect::getConstant(Parameter in, const char *&out, Type t) +{ + return parameterNames[t].find(in, out); +} + +Effect::ParameterType Effect::getParameterType(Effect::Parameter in) +{ + return parameterTypes[in]; +} + +StringMap::Entry Effect::typeEntries[] = +{ + {"reverb", Effect::TYPE_REVERB}, + {"chorus", Effect::TYPE_CHORUS}, + {"distortion", Effect::TYPE_DISTORTION}, + {"echo", Effect::TYPE_ECHO}, + {"flanger", Effect::TYPE_FLANGER}, + //{"frequencyshifter", Effect::TYPE_FREQSHIFTER}, + //{"vocalmorpher", Effect::TYPE_MORPHER}, + //{"pitchshifter", Effect::TYPE_PITCHSHIFTER}, + {"ringmodulator", Effect::TYPE_MODULATOR}, + //{"autowah", Effect::TYPE_AUTOWAH}, + {"compressor", Effect::TYPE_COMPRESSOR}, + {"equalizer", Effect::TYPE_EQUALIZER}, +}; + +StringMap Effect::types(Effect::typeEntries, sizeof(Effect::typeEntries)); + +StringMap::Entry Effect::waveformEntries[] = +{ + {"sine", Effect::WAVE_SINE}, + {"triangle", Effect::WAVE_TRIANGLE}, + {"sawtooth", Effect::WAVE_SAWTOOTH}, + {"square", Effect::WAVE_SQUARE}, +}; + +StringMap Effect::waveforms(Effect::waveformEntries, sizeof(Effect::waveformEntries)); + +/* +StringMap::Entry Effect::directionEntries[] = +{ + {"up", Effect::DIR_UP}, + {"down", Effect::DIR_DOWN}, + {"none", Effect::DIR_NONE}, +}; + +StringMap Effect::directions(Effect::directionEntries, sizeof(Effect::directionEntries)); + +StringMap::Entry Effect::phonemeEntries[] = +{ + {"a", Effect::PHONEME_A}, + {"e", Effect::PHONEME_E}, + {"i", Effect::PHONEME_I}, + {"o", Effect::PHONEME_O}, + {"u", Effect::PHONEME_U}, + {"aa", Effect::PHONEME_AA}, + {"ae", Effect::PHONEME_AE}, + {"ah", Effect::PHONEME_AH}, + {"ao", Effect::PHONEME_AO}, + {"eh", Effect::PHONEME_EH}, + {"er", Effect::PHONEME_ER}, + {"ih", Effect::PHONEME_IH}, + {"iy", Effect::PHONEME_IY}, + {"uh", Effect::PHONEME_UH}, + {"uw", Effect::PHONEME_UW}, + {"b", Effect::PHONEME_B}, + {"d", Effect::PHONEME_D}, + {"f", Effect::PHONEME_F}, + {"g", Effect::PHONEME_G}, + {"j", Effect::PHONEME_J}, + {"k", Effect::PHONEME_K}, + {"l", Effect::PHONEME_L}, + {"m", Effect::PHONEME_M}, + {"n", Effect::PHONEME_N}, + {"p", Effect::PHONEME_P}, + {"r", Effect::PHONEME_R}, + {"s", Effect::PHONEME_S}, + {"t", Effect::PHONEME_T}, + {"v", Effect::PHONEME_V}, + {"z", Effect::PHONEME_Z}, +}; + +StringMap Effect::phonemes(Effect::phonemeEntries, sizeof(Effect::phonemeEntries)); +*/ + +#define StringMap LazierAndSlowerButEasilyArrayableStringMap + +std::vector::Entry> Effect::basicParameters = +{ + {"type", Effect::EFFECT_TYPE}, + {"volume", Effect::EFFECT_VOLUME} +}; + +std::vector::Entry> Effect::reverbParameters = +{ + {"gain", Effect::REVERB_GAIN}, + {"highgain", Effect::REVERB_HFGAIN}, + {"density", Effect::REVERB_DENSITY}, + {"diffusion", Effect::REVERB_DIFFUSION}, + {"decaytime", Effect::REVERB_DECAY}, + {"decayhighratio", Effect::REVERB_HFDECAY}, + {"earlygain", Effect::REVERB_EARLYGAIN}, + {"earlydelay", Effect::REVERB_EARLYDELAY}, + {"lategain", Effect::REVERB_LATEGAIN}, + {"latedelay", Effect::REVERB_LATEDELAY}, + {"roomrolloff", Effect::REVERB_ROLLOFF}, + {"airabsorption", Effect::REVERB_AIRHFGAIN}, + {"highlimit", Effect::REVERB_HFLIMITER} +}; + +std::vector::Entry> Effect::chorusParameters = +{ + {"waveform", Effect::CHORUS_WAVEFORM}, + {"phase", Effect::CHORUS_PHASE}, + {"rate", Effect::CHORUS_RATE}, + {"depth", Effect::CHORUS_DEPTH}, + {"feedback", Effect::CHORUS_FEEDBACK}, + {"delay", Effect::CHORUS_DELAY} +}; + +std::vector::Entry> Effect::distortionParameters = +{ + {"gain", Effect::DISTORTION_GAIN}, + {"edge", Effect::DISTORTION_EDGE}, + {"lowcut", Effect::DISTORTION_LOWCUT}, + {"center", Effect::DISTORTION_EQCENTER}, + {"bandwidth", Effect::DISTORTION_EQBAND} +}; + +std::vector::Entry> Effect::echoParameters = +{ + {"delay", Effect::ECHO_DELAY}, + {"tapdelay", Effect::ECHO_LRDELAY}, + {"damping", Effect::ECHO_DAMPING}, + {"feedback", Effect::ECHO_FEEDBACK}, + {"spread", Effect::ECHO_SPREAD} +}; + +std::vector::Entry> Effect::flangerParameters = +{ + {"waveform", Effect::FLANGER_WAVEFORM}, + {"phase", Effect::FLANGER_PHASE}, + {"rate", Effect::FLANGER_RATE}, + {"depth", Effect::FLANGER_DEPTH}, + {"feedback", Effect::FLANGER_FEEDBACK}, + {"delay", Effect::FLANGER_DELAY} +}; +/* +std::vector::Entry> Effect::freqshifterParameters = +{ + {"frequency", Effect::FREQSHIFTER_FREQ}, + {"leftdirection", Effect::FREQSHIFTER_LEFTDIR}, + {"rightdirection", Effect::FREQSHIFTER_RIGHTDIR} +}; + +std::vector::Entry> Effect::morpherParameters = +{ + {"waveform", Effect::MORPHER_WAVEFORM}, + {"rate", Effect::MORPHER_RATE}, + {"phonemea", Effect::MORPHER_PHONEMEA}, + {"phonemeb", Effect::MORPHER_PHONEMEB}, + {"tunea", Effect::MORPHER_COARSEA}, + {"tuneb", Effect::MORPHER_COARSEB} +} +; +std::vector::Entry> Effect::pitchshifterParameters = +{ + {"pitch", Effect::PITCHSHIFTER_PITCH} +}; +*/ +std::vector::Entry> Effect::modulatorParameters = +{ + {"waveform", Effect::MODULATOR_WAVEFORM}, + {"frequency", Effect::MODULATOR_FREQ}, + {"highcut", Effect::MODULATOR_HIGHCUT} +}; +/* +std::vector::Entry> Effect::autowahParameters = +{ + {"attack", Effect::AUTOWAH_ATTACK}, + {"release", Effect::AUTOWAH_RELEASE}, + {"resonance", Effect::AUTOWAH_RESONANCE}, + {"peakgain", Effect::AUTOWAH_PEAKGAIN} +}; +*/ +std::vector::Entry> Effect::compressorParameters = +{ + {"enable", Effect::COMPRESSOR_ENABLE} +}; + +std::vector::Entry> Effect::equalizerParameters = +{ + {"lowgain", Effect::EQUALIZER_LOWGAIN}, + {"lowcut", Effect::EQUALIZER_LOWCUT}, + {"lowmidgain", Effect::EQUALIZER_MID1GAIN}, + {"lowmidfrequency", Effect::EQUALIZER_MID1FREQ}, + {"lowmidbandwidth", Effect::EQUALIZER_MID1BAND}, + {"highmidgain", Effect::EQUALIZER_MID2GAIN}, + {"highmidfrequency", Effect::EQUALIZER_MID2FREQ}, + {"highmidbandwidth", Effect::EQUALIZER_MID2BAND}, + {"highgain", Effect::EQUALIZER_HIGHGAIN}, + {"highcut", Effect::EQUALIZER_HIGHCUT} +}; + +std::map> Effect::parameterNames = +{ + {Effect::TYPE_BASIC, Effect::basicParameters}, + {Effect::TYPE_REVERB, Effect::reverbParameters}, + {Effect::TYPE_CHORUS, Effect::chorusParameters}, + {Effect::TYPE_DISTORTION, Effect::distortionParameters}, + {Effect::TYPE_ECHO, Effect::echoParameters}, + {Effect::TYPE_FLANGER, Effect::flangerParameters}, + //{Effect::TYPE_FREQSHIFTER, Effect::freqshifterParameters}, + //{Effect::TYPE_MORPHER, Effect::morpherbParameters}, + //{Effect::TYPE_PITCHSHIFTER, Effect::pitchshifterParameters}, + {Effect::TYPE_MODULATOR, Effect::modulatorParameters}, + //{Effect::TYPE_AUTOWAH, Effect::autowahParameters}, + {Effect::TYPE_COMPRESSOR, Effect::compressorParameters}, + {Effect::TYPE_EQUALIZER, Effect::equalizerParameters} +}; +#undef StringMap + +std::map Effect::parameterTypes = +{ + {Effect::EFFECT_TYPE, Effect::PARAM_TYPE}, + {Effect::EFFECT_VOLUME, Effect::PARAM_FLOAT}, + + {Effect::REVERB_GAIN, Effect::PARAM_FLOAT}, + {Effect::REVERB_HFGAIN, Effect::PARAM_FLOAT}, + {Effect::REVERB_DENSITY, Effect::PARAM_FLOAT}, + {Effect::REVERB_DIFFUSION, Effect::PARAM_FLOAT}, + {Effect::REVERB_DECAY, Effect::PARAM_FLOAT}, + {Effect::REVERB_HFDECAY, Effect::PARAM_FLOAT}, + {Effect::REVERB_EARLYGAIN, Effect::PARAM_FLOAT}, + {Effect::REVERB_EARLYDELAY, Effect::PARAM_FLOAT}, + {Effect::REVERB_LATEGAIN, Effect::PARAM_FLOAT}, + {Effect::REVERB_LATEDELAY, Effect::PARAM_FLOAT}, + {Effect::REVERB_ROLLOFF, Effect::PARAM_FLOAT}, + {Effect::REVERB_AIRHFGAIN, Effect::PARAM_FLOAT}, + {Effect::REVERB_HFLIMITER, Effect::PARAM_BOOL}, + + {Effect::CHORUS_WAVEFORM, Effect::PARAM_WAVEFORM}, + {Effect::CHORUS_PHASE, Effect::PARAM_FLOAT}, + {Effect::CHORUS_RATE, Effect::PARAM_FLOAT}, + {Effect::CHORUS_DEPTH, Effect::PARAM_FLOAT}, + {Effect::CHORUS_FEEDBACK, Effect::PARAM_FLOAT}, + {Effect::CHORUS_DELAY, Effect::PARAM_FLOAT}, + + {Effect::DISTORTION_GAIN, Effect::PARAM_FLOAT}, + {Effect::DISTORTION_EDGE, Effect::PARAM_FLOAT}, + {Effect::DISTORTION_LOWCUT, Effect::PARAM_FLOAT}, + {Effect::DISTORTION_EQCENTER, Effect::PARAM_FLOAT}, + {Effect::DISTORTION_EQBAND, Effect::PARAM_FLOAT}, + + {Effect::ECHO_DELAY, Effect::PARAM_FLOAT}, + {Effect::ECHO_LRDELAY, Effect::PARAM_FLOAT}, + {Effect::ECHO_DAMPING, Effect::PARAM_FLOAT}, + {Effect::ECHO_FEEDBACK, Effect::PARAM_FLOAT}, + {Effect::ECHO_SPREAD, Effect::PARAM_FLOAT}, + + {Effect::FLANGER_WAVEFORM, Effect::PARAM_WAVEFORM}, + {Effect::FLANGER_PHASE, Effect::PARAM_FLOAT}, + {Effect::FLANGER_RATE, Effect::PARAM_FLOAT}, + {Effect::FLANGER_DEPTH, Effect::PARAM_FLOAT}, + {Effect::FLANGER_FEEDBACK, Effect::PARAM_FLOAT}, + {Effect::FLANGER_DELAY, Effect::PARAM_FLOAT}, +/* + {Effect::FREQSHIFTER_FREQ, Effect::PARAM_FLOAT}, + {Effect::FREQSHIFTER_LEFTDIR, Effect::PARAM_DIRECTION}, + {Effect::FREQSHIFTER_RIGHTDIR, Effect::PARAM_DIRECTION}, + + {Effect::MORPHER_WAVEFORM, Effect::PARAM_WAVEFORM}, + {Effect::MORPHER_RATE, Effect::PARAM_FLOAT}, + {Effect::MORPHER_PHONEMEA, Effect::PARAM_PHONEME}, + {Effect::MORPHER_PHONEMEB, Effect::PARAM_PHONEME}, + {Effect::MORPHER_TUNEA, Effect::PARAM_FLOAT}, + {Effect::MORPHER_TUNEB, Effect::PARAM_FLOAT}, + + {Effect::PITCHSHIFTER_PITCH, Effect::PARAM_FLOAT}, +*/ + {Effect::MODULATOR_WAVEFORM, Effect::PARAM_WAVEFORM}, + {Effect::MODULATOR_FREQ, Effect::PARAM_FLOAT}, + {Effect::MODULATOR_HIGHCUT, Effect::PARAM_FLOAT}, +/* + {Effect::AUTOWAH_ATTACK, Effect::PARAM_FLOAT}, + {Effect::AUTOWAH_RELEASE, Effect::PARAM_FLOAT}, + {Effect::AUTOWAH_RESONANCE, Effect::PARAM_FLOAT}, + {Effect::AUTOWAH_PEAKGAIN, Effect::PARAM_FLOAT}, +*/ + {Effect::COMPRESSOR_ENABLE, Effect::PARAM_BOOL}, + + {Effect::EQUALIZER_LOWGAIN, Effect::PARAM_FLOAT}, + {Effect::EQUALIZER_LOWCUT, Effect::PARAM_FLOAT}, + {Effect::EQUALIZER_MID1GAIN, Effect::PARAM_FLOAT}, + {Effect::EQUALIZER_MID1FREQ, Effect::PARAM_FLOAT}, + {Effect::EQUALIZER_MID1BAND, Effect::PARAM_FLOAT}, + {Effect::EQUALIZER_MID2GAIN, Effect::PARAM_FLOAT}, + {Effect::EQUALIZER_MID2FREQ, Effect::PARAM_FLOAT}, + {Effect::EQUALIZER_MID2BAND, Effect::PARAM_FLOAT}, + {Effect::EQUALIZER_HIGHGAIN, Effect::PARAM_FLOAT}, + {Effect::EQUALIZER_HIGHCUT, Effect::PARAM_FLOAT} +}; + +} //audio +} //love diff --git a/love/src/jni/love/src/modules/audio/Effect.h b/love/src/jni/love/src/modules/audio/Effect.h new file mode 100644 index 00000000..2336a9d0 --- /dev/null +++ b/love/src/jni/love/src/modules/audio/Effect.h @@ -0,0 +1,297 @@ +/** + * Copyright (c) 2006-2018 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#ifndef LOVE_AUDIO_EFFECTS_H +#define LOVE_AUDIO_EFFECTS_H + +#include "common/Object.h" +#include "common/StringMap.h" +#include +#include + +template +class LazierAndSlowerButEasilyArrayableStringMap +{ +public: + struct Entry + { + const char *key; + T value; + }; + LazierAndSlowerButEasilyArrayableStringMap() + { + } + + LazierAndSlowerButEasilyArrayableStringMap(const std::vector &entries) + { + for (auto entry : entries) + { + forward[entry.key] = entry.value; + reverse[entry.value] = entry.key; + } + } + + bool find(const char *key, T &t) + { + if (forward.find(key) == forward.end()) + return false; + t = forward[key]; + return true; + } + + bool find(T key, const char *&str) + { + if (reverse.find(key) == reverse.end()) + return false; + str = reverse[key]; + return true; + } + +private: + std::map forward; + std::map reverse; +}; + +namespace love +{ +namespace audio +{ + +class Effect +{ +public: + enum Type + { + TYPE_BASIC, //not a real type + TYPE_REVERB, + TYPE_CHORUS, + TYPE_DISTORTION, + TYPE_ECHO, + TYPE_FLANGER, + //TYPE_FREQSHIFTER, + //TYPE_MORPHER, + //TYPE_PITCHSHIFTER, + TYPE_MODULATOR, + //TYPE_AUTOWAH, + TYPE_COMPRESSOR, + TYPE_EQUALIZER, + TYPE_MAX_ENUM + }; + + enum Parameter + { + EFFECT_TYPE, + EFFECT_VOLUME, + + REVERB_GAIN, + REVERB_HFGAIN, + REVERB_DENSITY, + REVERB_DIFFUSION, + REVERB_DECAY, + REVERB_HFDECAY, + REVERB_EARLYGAIN, + REVERB_EARLYDELAY, + REVERB_LATEGAIN, + REVERB_LATEDELAY, + REVERB_ROLLOFF, + REVERB_AIRHFGAIN, + REVERB_HFLIMITER, + + CHORUS_WAVEFORM, + CHORUS_PHASE, + CHORUS_RATE, + CHORUS_DEPTH, + CHORUS_FEEDBACK, + CHORUS_DELAY, + + DISTORTION_GAIN, + DISTORTION_EDGE, + DISTORTION_LOWCUT, + DISTORTION_EQCENTER, + DISTORTION_EQBAND, + + ECHO_DELAY, + ECHO_LRDELAY, + ECHO_DAMPING, + ECHO_FEEDBACK, + ECHO_SPREAD, + + FLANGER_WAVEFORM, + FLANGER_PHASE, + FLANGER_RATE, + FLANGER_DEPTH, + FLANGER_FEEDBACK, + FLANGER_DELAY, +/* + FREQSHIFTER_FREQ, + FREQSHIFTER_LEFTDIR, + FREQSHIFTER_RIGHTDIR, + + MORPHER_WAVEFORM, + MORPHER_RATE, + MORPHER_PHONEMEA, + MORPHER_PHONEMEB, + MORPHER_TUNEA, + MORPHER_TUNEB, + + PITCHSHIFTER_PITCH, +*/ + MODULATOR_WAVEFORM, + MODULATOR_FREQ, + MODULATOR_HIGHCUT, +/* + AUTOWAH_ATTACK, + AUTOWAH_RELEASE, + AUTOWAH_RESONANCE, + AUTOWAH_PEAKGAIN, +*/ + COMPRESSOR_ENABLE, + + EQUALIZER_LOWGAIN, + EQUALIZER_LOWCUT, + EQUALIZER_MID1GAIN, + EQUALIZER_MID1FREQ, + EQUALIZER_MID1BAND, + EQUALIZER_MID2GAIN, + EQUALIZER_MID2FREQ, + EQUALIZER_MID2BAND, + EQUALIZER_HIGHGAIN, + EQUALIZER_HIGHCUT, + + EFFECT_MAX_ENUM + }; + + enum ParameterType + { + PARAM_TYPE, + PARAM_FLOAT, + PARAM_BOOL, + PARAM_WAVEFORM, + //PARAM_DIRECTION, + //PARAM_PHONEME, + PARAM_MAX_ENUM + }; + + enum Waveform + { + WAVE_SINE, + WAVE_TRIANGLE, + WAVE_SAWTOOTH, + WAVE_SQUARE, + WAVE_MAX_ENUM + }; + /* + enum Direction + { + DIR_NONE, + DIR_UP, + DIR_DOWN, + DIR_MAX_ENUM + }; + + enum Phoneme + { + PHONEME_A, + PHONEME_E, + PHONEME_I, + PHONEME_O, + PHONEME_U, + PHONEME_AA, + PHONEME_AE, + PHONEME_AH, + PHONEME_AO, + PHONEME_EH, + PHONEME_ER, + PHONEME_IH, + PHONEME_IY, + PHONEME_UH, + PHONEME_UW, + PHONEME_B, + PHONEME_D, + PHONEME_F, + PHONEME_G, + PHONEME_J, + PHONEME_K, + PHONEME_L, + PHONEME_M, + PHONEME_N, + PHONEME_P, + PHONEME_R, + PHONEME_S, + PHONEME_T, + PHONEME_V, + PHONEME_Z, + PHONEME_MAX_ENUM + }; + */ + + Effect(); + virtual ~Effect(); + Type getType() const; + + static bool getConstant(const char *in, Type &out); + static bool getConstant(Type in, const char *&out); + static std::vector getConstants(Type); + static bool getConstant(const char *in, Waveform &out); + static bool getConstant(Waveform in, const char *&out); + //static bool getConstant(const char *in, Direction &out); + //static bool getConstant(Direction in, const char *&out); + //static bool getConstant(const char *in, Phoneme &out); + //static bool getConstant(Phoneme in, const char *&out); + static bool getConstant(const char *in, Parameter &out, Type t); + static bool getConstant(Parameter in, const char *&out, Type t); + static ParameterType getParameterType(Parameter in); + +protected: + Type type; + +private: + static StringMap::Entry typeEntries[]; + static StringMap types; + static StringMap::Entry waveformEntries[]; + static StringMap waveforms; + //static StringMap::Entry directionEntries[]; + //static StringMap directions; + //static StringMap::Entry phonemeEntries[]; + //static StringMap phonemes; +#define StringMap LazierAndSlowerButEasilyArrayableStringMap + static std::vector::Entry> basicParameters; + static std::vector::Entry> reverbParameters; + static std::vector::Entry> chorusParameters; + static std::vector::Entry> distortionParameters; + static std::vector::Entry> echoParameters; + static std::vector::Entry> flangerParameters; + //static std::vector::Entry> freqshifterParameters; + //static std::vector::Entry> morpherParameters; + //static std::vector::Entry> pitchshifterParameters; + static std::vector::Entry> modulatorParameters; + //static std::vector::Entry> autowahParameters; + static std::vector::Entry> compressorParameters; + static std::vector::Entry> equalizerParameters; + static std::map> parameterNames; +#undef StringMap + static std::map parameterTypes; + +}; + +} //audio +} //love + +#endif //LOVE_AUDIO_EFFECTS_H diff --git a/love/src/jni/love/src/modules/audio/Filter.cpp b/love/src/jni/love/src/modules/audio/Filter.cpp new file mode 100644 index 00000000..13608692 --- /dev/null +++ b/love/src/jni/love/src/modules/audio/Filter.cpp @@ -0,0 +1,121 @@ +/** + * Copyright (c) 2006-2018 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#include "Filter.h" + +namespace love +{ +namespace audio +{ + +Filter::Filter() +{ +} + +Filter::~Filter() +{ +} + +Filter::Type Filter::getType() const +{ + return type; +} + +bool Filter::getConstant(const char *in, Type &out) +{ + return types.find(in, out); +} + +bool Filter::getConstant(Type in, const char *&out) +{ + return types.find(in, out); +} + +std::vector Filter::getConstants(Type) +{ + return types.getNames(); +} + +bool Filter::getConstant(const char *in, Parameter &out, Type t) +{ + return parameterNames[t].find(in, out); +} + +bool Filter::getConstant(Parameter in, const char *&out, Type t) +{ + return parameterNames[t].find(in, out); +} + +Filter::ParameterType Filter::getParameterType(Parameter in) +{ + return parameterTypes[in]; +} + +StringMap::Entry Filter::typeEntries[] = +{ + {"lowpass", Filter::TYPE_LOWPASS}, + {"highpass", Filter::TYPE_HIGHPASS}, + {"bandpass", Filter::TYPE_BANDPASS}, +}; + +StringMap Filter::types(Filter::typeEntries, sizeof(Filter::typeEntries)); + +#define StringMap LazierAndSlowerButEasilyArrayableStringMap2 +std::vector::Entry> Filter::basicParameters = +{ + {"type", Filter::FILTER_TYPE}, + {"volume", Filter::FILTER_VOLUME} +}; + +std::vector::Entry> Filter::lowpassParameters = +{ + {"highgain", Filter::FILTER_HIGHGAIN} +}; + +std::vector::Entry> Filter::highpassParameters = +{ + {"lowgain", Filter::FILTER_LOWGAIN} +}; + +std::vector::Entry> Filter::bandpassParameters = +{ + {"lowgain", Filter::FILTER_LOWGAIN}, + {"highgain", Filter::FILTER_HIGHGAIN} +}; + +std::map> Filter::parameterNames = +{ + {Filter::TYPE_BASIC, Filter::basicParameters}, + {Filter::TYPE_LOWPASS, Filter::lowpassParameters}, + {Filter::TYPE_HIGHPASS, Filter::highpassParameters}, + {Filter::TYPE_BANDPASS, Filter::bandpassParameters}, +}; +#undef StringMap + +std::map Filter::parameterTypes = +{ + {Filter::FILTER_TYPE, Filter::PARAM_TYPE}, + {Filter::FILTER_VOLUME, Filter::PARAM_FLOAT}, + {Filter::FILTER_LOWGAIN, Filter::PARAM_FLOAT}, + {Filter::FILTER_HIGHGAIN, Filter::PARAM_FLOAT} +}; + +} //audio +} //love diff --git a/love/src/jni/love/src/modules/audio/Filter.h b/love/src/jni/love/src/modules/audio/Filter.h new file mode 100644 index 00000000..d4de4356 --- /dev/null +++ b/love/src/jni/love/src/modules/audio/Filter.h @@ -0,0 +1,136 @@ +/** + * Copyright (c) 2006-2018 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#ifndef LOVE_AUDIO_FILTERS_H +#define LOVE_AUDIO_FILTERS_H + +#include "common/Object.h" +#include "common/StringMap.h" +#include + +template +class LazierAndSlowerButEasilyArrayableStringMap2 +{ +public: + struct Entry + { + const char *key; + T value; + }; + LazierAndSlowerButEasilyArrayableStringMap2() + { + } + + LazierAndSlowerButEasilyArrayableStringMap2(const std::vector &entries) + { + for (auto entry : entries) + { + forward[entry.key] = entry.value; + reverse[entry.value] = entry.key; + } + } + + bool find(const char *key, T &t) + { + if (forward.find(key) == forward.end()) + return false; + t = forward[key]; + return true; + } + + bool find(T key, const char *&str) + { + if (reverse.find(key) == reverse.end()) + return false; + str = reverse[key]; + return true; + } + +private: + std::map forward; + std::map reverse; +}; + +namespace love +{ +namespace audio +{ + +class Filter +{ +public: + enum Type + { + TYPE_BASIC, + TYPE_LOWPASS, + TYPE_HIGHPASS, + TYPE_BANDPASS, + TYPE_MAX_ENUM + }; + + enum Parameter + { + FILTER_TYPE, + FILTER_VOLUME, + + FILTER_LOWGAIN, + FILTER_HIGHGAIN, + + FILTER_MAX_ENUM + }; + + enum ParameterType + { + PARAM_TYPE, + PARAM_FLOAT, + PARAM_MAX_ENUM + }; + + Filter(); + virtual ~Filter(); + Type getType() const; + + static bool getConstant(const char *in, Type &out); + static bool getConstant(Type in, const char *&out); + static std::vector getConstants(Type); + static bool getConstant(const char *in, Parameter &out, Type t); + static bool getConstant(Parameter in, const char *&out, Type t); + static ParameterType getParameterType(Parameter in); + +protected: + Type type; + +private: + static StringMap::Entry typeEntries[]; + static StringMap types; +#define StringMap LazierAndSlowerButEasilyArrayableStringMap2 + static std::vector::Entry> basicParameters; + static std::vector::Entry> lowpassParameters; + static std::vector::Entry> highpassParameters; + static std::vector::Entry> bandpassParameters; + static std::map> parameterNames; +#undef StringMap + static std::map parameterTypes; +}; + +} //audio +} //love + +#endif //LOVE_AUDIO_FILTERS_H diff --git a/love/src/jni/love/src/modules/audio/RecordingDevice.cpp b/love/src/jni/love/src/modules/audio/RecordingDevice.cpp new file mode 100644 index 00000000..3317692f --- /dev/null +++ b/love/src/jni/love/src/modules/audio/RecordingDevice.cpp @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2006-2018 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#include "RecordingDevice.h" + +namespace love +{ +namespace audio +{ + +love::Type RecordingDevice::type("RecordingDevice", &Object::type); + +RecordingDevice::RecordingDevice() +{ +} + +RecordingDevice::~RecordingDevice() +{ +} + +} //audio +} //love diff --git a/love/src/jni/love/src/modules/audio/RecordingDevice.h b/love/src/jni/love/src/modules/audio/RecordingDevice.h new file mode 100644 index 00000000..0a3ba2d9 --- /dev/null +++ b/love/src/jni/love/src/modules/audio/RecordingDevice.h @@ -0,0 +1,109 @@ +/** + * Copyright (c) 2006-2018 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#ifndef LOVE_AUDIO_RECORDING_DEVICE_H +#define LOVE_AUDIO_RECORDING_DEVICE_H + +#include "common/Object.h" +#include "sound/SoundData.h" + +#include + +namespace love +{ +namespace audio +{ + +class RecordingDevice : public love::Object +{ +public: + + static love::Type type; + + static const int DEFAULT_SAMPLES = 8192; + static const int DEFAULT_SAMPLE_RATE = 8000; + static const int DEFAULT_BIT_DEPTH = 16; + static const int DEFAULT_CHANNELS = 1; + + RecordingDevice(); + virtual ~RecordingDevice(); + + /** + * Begins audio input recording process. + * @param samples Number of samples to buffer. + * @param sampleRate Desired sample rate. + * @param bitDepth Desired bit depth (8 or 16). + * @param channels Desired number of channels. + * @return True if recording started successfully. + **/ + virtual bool start(int samples, int sampleRate, int bitDepth, int channels) = 0; + + /** + * Stops audio input recording. + **/ + virtual void stop() = 0; + + /** + * Retreives recorded data. + * @return SoundData containing data obtained from recording device. + **/ + virtual love::sound::SoundData *getData() = 0; + + /** + * @return C string device name. + **/ + virtual const char *getName() const = 0; + + /** + * @return Number of samples currently recorded. + **/ + virtual int getSampleCount() const = 0; + + /** + * Gets the maximum number of samples that will be buffered, as set by start(). + **/ + virtual int getMaxSamples() const = 0; + + /** + * @return Sample rate for recording. + **/ + virtual int getSampleRate() const = 0; + + /** + * @return Bit depth for recording. + **/ + virtual int getBitDepth() const = 0; + + /** + * @return Number of channels for recording. + **/ + virtual int getChannelCount() const = 0; + + /** + * @return True if currently recording. + **/ + virtual bool isRecording() const = 0; + +}; //RecordingDevice + +} //audio +} //love + +#endif //LOVE_AUDIO_RECORDING_DEVICE_H diff --git a/love/src/jni/love/src/modules/audio/Source.cpp b/love/src/jni/love/src/modules/audio/Source.cpp index d0356ec0..47f6c787 100644 --- a/love/src/jni/love/src/modules/audio/Source.cpp +++ b/love/src/jni/love/src/modules/audio/Source.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -25,8 +25,10 @@ namespace love namespace audio { -Source::Source(Type type) - : type(type) +love::Type Source::type("Source", &Object::type); + +Source::Source(Type sourceType) + : sourceType(sourceType) { } @@ -36,7 +38,7 @@ Source::~Source() Source::Type Source::getType() const { - return type; + return sourceType; } bool Source::getConstant(const char *in, Type &out) @@ -49,6 +51,11 @@ bool Source::getConstant(Type in, const char *&out) return types.find(in, out); } +std::vector Source::getConstants(Type) +{ + return types.getNames(); +} + bool Source::getConstant(const char *in, Unit &out) { return units.find(in, out); @@ -59,10 +66,16 @@ bool Source::getConstant(Unit in, const char *&out) return units.find(in, out); } +std::vector Source::getConstants(Unit) +{ + return units.getNames(); +} + StringMap::Entry Source::typeEntries[] = { {"static", Source::TYPE_STATIC}, {"stream", Source::TYPE_STREAM}, + {"queue", Source::TYPE_QUEUE}, }; StringMap Source::types(Source::typeEntries, sizeof(Source::typeEntries)); diff --git a/love/src/jni/love/src/modules/audio/Source.h b/love/src/jni/love/src/modules/audio/Source.h index a4c5d4d9..d234d59e 100644 --- a/love/src/jni/love/src/modules/audio/Source.h +++ b/love/src/jni/love/src/modules/audio/Source.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -24,6 +24,9 @@ // LOVE #include "common/Object.h" #include "common/StringMap.h" +#include "Filter.h" + +#include namespace love { @@ -34,10 +37,13 @@ class Source : public Object { public: + static love::Type type; + enum Type { TYPE_STATIC, TYPE_STREAM, + TYPE_QUEUE, TYPE_MAX_ENUM }; @@ -56,10 +62,7 @@ public: virtual bool play() = 0; virtual void stop() = 0; virtual void pause() = 0; - virtual void resume() = 0; - virtual void rewind() = 0; - virtual bool isStopped() const = 0; - virtual bool isPaused() const = 0; + virtual bool isPlaying() const = 0; virtual bool isFinished() const = 0; virtual bool update() = 0; @@ -81,8 +84,8 @@ public: virtual void setDirection(float *v) = 0; virtual void getDirection(float *v) const = 0; - virtual void setCone(float innerAngle, float outerAngle, float outerVolume) = 0; - virtual void getCone(float &innerAngle, float &outerAngle, float &outerVolume) const = 0; + virtual void setCone(float innerAngle, float outerAngle, float outerVolume, float outerHighGain) = 0; + virtual void getCone(float &innerAngle, float &outerAngle, float &outerVolume, float &outerHighGain) const = 0; virtual void setRelative(bool enable) = 0; virtual bool isRelative() const = 0; @@ -101,18 +104,36 @@ public: virtual float getRolloffFactor() const = 0; virtual void setMaxDistance(float distance) = 0; virtual float getMaxDistance() const = 0; + virtual void setAirAbsorptionFactor(float factor) = 0; + virtual float getAirAbsorptionFactor() const = 0; + + virtual int getChannelCount() const = 0; + + virtual bool setFilter(const std::map ¶ms) = 0; + virtual bool setFilter() = 0; + virtual bool getFilter(std::map ¶ms) = 0; + + virtual bool setEffect(const char *effect) = 0; + virtual bool setEffect(const char *effect, const std::map ¶ms) = 0; + virtual bool unsetEffect(const char *effect) = 0; + virtual bool getEffect(const char *effect, std::map ¶ms) = 0; + virtual bool getActiveEffects(std::vector &list) const = 0; + + virtual int getFreeBufferCount() const = 0; + virtual bool queue(void *data, size_t length, int dataSampleRate, int dataBitDepth, int dataChannels) = 0; - virtual int getChannels() const = 0; virtual Type getType() const; static bool getConstant(const char *in, Type &out); static bool getConstant(Type in, const char *&out); + static std::vector getConstants(Type); static bool getConstant(const char *in, Unit &out); static bool getConstant(Unit in, const char *&out); + static std::vector getConstants(Unit); protected: - Type type; + Type sourceType; private: diff --git a/love/src/jni/love/src/modules/audio/null/Audio.cpp b/love/src/jni/love/src/modules/audio/null/Audio.cpp index ea9ac5e0..4093ace0 100644 --- a/love/src/jni/love/src/modules/audio/null/Audio.cpp +++ b/love/src/jni/love/src/modules/audio/null/Audio.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -51,7 +51,12 @@ love::audio::Source *Audio::newSource(love::sound::SoundData *) return new Source(); } -int Audio::getSourceCount() const +love::audio::Source *Audio::newSource(int, int, int, int) +{ + return new Source(); +} + +int Audio::getActiveSourceCount() const { return 0; } @@ -66,10 +71,19 @@ bool Audio::play(love::audio::Source *) return false; } +bool Audio::play(const std::vector&) +{ + return false; +} + void Audio::stop(love::audio::Source *) { } +void Audio::stop(const std::vector&) +{ +} + void Audio::stop() { } @@ -78,24 +92,13 @@ void Audio::pause(love::audio::Source *) { } -void Audio::pause() +void Audio::pause(const std::vector&) { } -void Audio::resume(love::audio::Source *) -{ -} - -void Audio::resume() -{ -} - -void Audio::rewind(love::audio::Source *) -{ -} - -void Audio::rewind() +std::vector Audio::pause() { + return {}; } void Audio::setVolume(float volume) @@ -140,24 +143,19 @@ float Audio::getDopplerScale() const { return 1.0f; } - -void Audio::record() +/* +void setMeter(float) { } -love::sound::SoundData *Audio::getRecordedData() +float getMeter() const { - return NULL; + return 1.0f; } - -love::sound::SoundData *Audio::stopRecording(bool) +*/ +const std::vector &Audio::getRecordingDevices() { - return NULL; -} - -bool Audio::canRecord() -{ - return false; + return capture; } Audio::DistanceModel Audio::getDistanceModel() const @@ -170,6 +168,41 @@ void Audio::setDistanceModel(DistanceModel distanceModel) this->distanceModel = distanceModel; } +bool Audio::setEffect(const char *, std::map &) +{ + return false; +} + +bool Audio::unsetEffect(const char *) +{ + return false; +} + +bool Audio::getEffect(const char *, std::map &) +{ + return false; +} + +bool Audio::getActiveEffects(std::vector &) const +{ + return false; +} + +int Audio::getMaxSceneEffects() const +{ + return 0; +} + +int Audio::getMaxSourceEffects() const +{ + return 0; +} + +bool Audio::isEFXsupported() const +{ + return false; +} + } // null } // audio } // love diff --git a/love/src/jni/love/src/modules/audio/null/Audio.h b/love/src/jni/love/src/modules/audio/null/Audio.h index 0be0ecc6..690cc79c 100644 --- a/love/src/jni/love/src/modules/audio/null/Audio.h +++ b/love/src/jni/love/src/modules/audio/null/Audio.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -24,6 +24,7 @@ // LOVE #include "audio/Audio.h" +#include "RecordingDevice.h" #include "Source.h" namespace love @@ -46,17 +47,17 @@ public: // Implements Audio. love::audio::Source *newSource(love::sound::Decoder *decoder); love::audio::Source *newSource(love::sound::SoundData *soundData); - int getSourceCount() const; + love::audio::Source *newSource(int sampleRate, int bitDepth, int channels, int buffers); + int getActiveSourceCount() const; int getMaxSources() const; bool play(love::audio::Source *source); + bool play(const std::vector &sources); void stop(love::audio::Source *source); + void stop(const std::vector &sources); void stop(); void pause(love::audio::Source *source); - void pause(); - void resume(love::audio::Source *source); - void resume(); - void rewind(love::audio::Source *source); - void rewind(); + void pause(const std::vector &sources); + std::vector pause(); void setVolume(float volume); float getVolume() const; @@ -69,18 +70,26 @@ public: void setDopplerScale(float scale); float getDopplerScale() const; + //void setMeter(float scale); + //float getMeter() const; - void record(); - love::sound::SoundData *getRecordedData(); - love::sound::SoundData *stopRecording(bool returnData); - bool canRecord(); + const std::vector &getRecordingDevices(); DistanceModel getDistanceModel() const; void setDistanceModel(DistanceModel distanceModel); + bool setEffect(const char *, std::map ¶ms); + bool unsetEffect(const char *); + bool getEffect(const char *, std::map ¶ms); + bool getActiveEffects(std::vector &list) const; + int getMaxSceneEffects() const; + int getMaxSourceEffects() const; + bool isEFXsupported() const; + private: float volume; DistanceModel distanceModel; + std::vector capture; }; // Audio diff --git a/love/src/jni/love/src/modules/audio/null/RecordingDevice.cpp b/love/src/jni/love/src/modules/audio/null/RecordingDevice.cpp new file mode 100644 index 00000000..c423d2e2 --- /dev/null +++ b/love/src/jni/love/src/modules/audio/null/RecordingDevice.cpp @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2006-2018 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#include "RecordingDevice.h" +#include "Audio.h" + +namespace love +{ +namespace audio +{ +namespace null +{ + +const char *RecordingDevice::name = "null"; + +RecordingDevice::RecordingDevice(const char *) +{ +} + +RecordingDevice::~RecordingDevice() +{ +} + +bool RecordingDevice::start(int, int, int, int) +{ + return false; +} + +void RecordingDevice::stop() +{ +} + +love::sound::SoundData *RecordingDevice::getData() +{ + return nullptr; +} + +int RecordingDevice::getSampleCount() const +{ + return 0; +} + +int RecordingDevice::getMaxSamples() const +{ + return 0; +} + +int RecordingDevice::getSampleRate() const +{ + return 0; +} + +int RecordingDevice::getBitDepth() const +{ + return 0; +} + +int RecordingDevice::getChannelCount() const +{ + return 0; +} + +const char *RecordingDevice::getName() const +{ + return name; +} + +bool RecordingDevice::isRecording() const +{ + return false; +} + +} //null +} //audio +} //love diff --git a/love/src/jni/love/src/modules/audio/null/RecordingDevice.h b/love/src/jni/love/src/modules/audio/null/RecordingDevice.h new file mode 100644 index 00000000..03b69e20 --- /dev/null +++ b/love/src/jni/love/src/modules/audio/null/RecordingDevice.h @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2006-2018 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#ifndef LOVE_AUDIO_NULL_RECORDING_DEVICE_H +#define LOVE_AUDIO_NULL_RECORDING_DEVICE_H + +#include "audio/RecordingDevice.h" +#include "sound/SoundData.h" + +namespace love +{ +namespace audio +{ +namespace null +{ + +class RecordingDevice : public love::audio::RecordingDevice +{ +public: + RecordingDevice(const char *name); + virtual ~RecordingDevice(); + virtual bool start(int samples, int sampleRate, int bitDepth, int channels); + virtual void stop(); + virtual love::sound::SoundData *getData(); + virtual const char *getName() const; + virtual int getMaxSamples() const; + virtual int getSampleCount() const; + virtual int getSampleRate() const; + virtual int getBitDepth() const; + virtual int getChannelCount() const; + virtual bool isRecording() const; + +private: + static const char *name; +}; //RecordingDevice + +} //null +} //audio +} //love + +#endif //LOVE_AUDIO_NULL_RECORDING_DEVICE_H diff --git a/love/src/jni/love/src/modules/audio/null/Source.cpp b/love/src/jni/love/src/modules/audio/null/Source.cpp index bf79968f..21922394 100644 --- a/love/src/jni/love/src/modules/audio/null/Source.cpp +++ b/love/src/jni/love/src/modules/audio/null/Source.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -55,20 +55,7 @@ void Source::pause() { } -void Source::resume() -{ -} - -void Source::rewind() -{ -} - -bool Source::isStopped() const -{ - return true; -} - -bool Source::isPaused() const +bool Source::isPlaying() const { return false; } @@ -141,18 +128,20 @@ void Source::getDirection(float *) const { } -void Source::setCone(float innerAngle, float outerAngle, float outerVolume) +void Source::setCone(float innerAngle, float outerAngle, float outerVolume, float outerHighGain) { coneInnerAngle = innerAngle; coneOuterAngle = outerAngle; coneOuterVolume = outerVolume; + coneOuterHighGain = outerHighGain; } -void Source::getCone(float &innerAngle, float &outerAngle, float &outerVolume) const +void Source::getCone(float &innerAngle, float &outerAngle, float &outerVolume, float &outerHighGain) const { innerAngle = coneInnerAngle; outerAngle = coneOuterAngle; outerVolume = coneOuterVolume; + outerHighGain = coneOuterHighGain; } void Source::setRelative(bool enable) @@ -225,11 +214,71 @@ float Source::getMaxDistance() const return this->maxDistance; } -int Source::getChannels() const +void Source::setAirAbsorptionFactor(float factor) +{ + absorptionFactor = factor; +} + +float Source::getAirAbsorptionFactor() const +{ + return absorptionFactor; +} + +int Source::getChannelCount() const { return 2; } +int Source::getFreeBufferCount() const +{ + return 0; +} + +bool Source::queue(void *, size_t, int, int, int) +{ + return false; +} + +bool Source::setFilter(const std::map &) +{ + return false; +} + +bool Source::setFilter() +{ + return false; +} + +bool Source::getFilter(std::map &) +{ + return false; +} + +bool Source::setEffect(const char *) +{ + return false; +} + +bool Source::setEffect(const char *, const std::map &) +{ + return false; +} + +bool Source::unsetEffect(const char *) +{ + return false; +} + +bool Source::getEffect(const char *, std::map &) +{ + return false; +} + +bool Source::getActiveEffects(std::vector &) const +{ + return false; +} + } // null } // audio } // love diff --git a/love/src/jni/love/src/modules/audio/null/Source.h b/love/src/jni/love/src/modules/audio/null/Source.h index ec07d45a..002f2648 100644 --- a/love/src/jni/love/src/modules/audio/null/Source.h +++ b/love/src/jni/love/src/modules/audio/null/Source.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -24,6 +24,7 @@ // LOVE #include "common/Object.h" #include "audio/Source.h" +#include "audio/Filter.h" namespace love { @@ -42,10 +43,7 @@ public: virtual bool play(); virtual void stop(); virtual void pause(); - virtual void resume(); - virtual void rewind(); - virtual bool isStopped() const; - virtual bool isPaused() const; + virtual bool isPlaying() const; virtual bool isFinished() const; virtual bool update(); virtual void setPitch(float pitch); @@ -61,8 +59,8 @@ public: virtual void getVelocity(float *v) const; virtual void setDirection(float *v); virtual void getDirection(float *v) const; - virtual void setCone(float innerAngle, float outerAngle, float outerVolume); - virtual void getCone(float &innerAngle, float &outerAngle, float &outerVolume) const; + virtual void setCone(float innerAngle, float outerAngle, float outerVolume, float outerHighGain); + virtual void getCone(float &innerAngle, float &outerAngle, float &outerVolume, float &outerHighGain) const; virtual void setRelative(bool enable); virtual bool isRelative() const; void setLooping(bool looping); @@ -77,7 +75,22 @@ public: virtual float getRolloffFactor() const; virtual void setMaxDistance(float distance); virtual float getMaxDistance() const; - virtual int getChannels() const; + virtual void setAirAbsorptionFactor(float factor); + virtual float getAirAbsorptionFactor() const; + virtual int getChannelCount() const; + + virtual int getFreeBufferCount() const; + virtual bool queue(void *data, size_t length, int dataSampleRate, int dataBitDepth, int dataChannels); + + virtual bool setFilter(const std::map ¶ms); + virtual bool setFilter(); + virtual bool getFilter(std::map ¶ms); + + virtual bool setEffect(const char *effect); + virtual bool setEffect(const char *effect, const std::map ¶ms); + virtual bool unsetEffect(const char *effect); + virtual bool getEffect(const char *effect, std::map ¶ms); + virtual bool getActiveEffects(std::vector &list) const; private: @@ -86,6 +99,7 @@ private: float coneInnerAngle; float coneOuterAngle; float coneOuterVolume; + float coneOuterHighGain; bool relative; bool looping; float minVolume; @@ -93,6 +107,7 @@ private: float referenceDistance; float rolloffFactor; float maxDistance; + float absorptionFactor; }; // Source diff --git a/love/src/jni/love/src/modules/audio/openal/Audio.cpp b/love/src/jni/love/src/modules/audio/openal/Audio.cpp index 7df930f0..cb2eb2f8 100644 --- a/love/src/jni/love/src/modules/audio/openal/Audio.cpp +++ b/love/src/jni/love/src/modules/audio/openal/Audio.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -20,10 +20,11 @@ #include "Audio.h" #include "common/delay.h" - +#include "RecordingDevice.h" #include "sound/Decoder.h" #include +#include namespace love { @@ -67,21 +68,52 @@ void Audio::PoolThread::setFinish() finish = true; } +ALenum Audio::getFormat(int bitDepth, int channels) +{ + if (bitDepth != 8 && bitDepth != 16) + return AL_NONE; + + if (channels == 1) + return bitDepth == 8 ? AL_FORMAT_MONO8 : AL_FORMAT_MONO16; + else if (channels == 2) + return bitDepth == 8 ? AL_FORMAT_STEREO8 : AL_FORMAT_STEREO16; +#ifdef AL_EXT_MCFORMATS + else if (alIsExtensionPresent("AL_EXT_MCFORMATS")) + { + if (channels == 6) + return bitDepth == 8 ? AL_FORMAT_51CHN8 : AL_FORMAT_51CHN16; + else if (channels == 8) + return bitDepth == 8 ? AL_FORMAT_71CHN8 : AL_FORMAT_71CHN16; + } +#endif + return AL_NONE; +} + Audio::Audio() : device(nullptr) - , capture(nullptr) , context(nullptr) , pool(nullptr) , poolThread(nullptr) , distanceModel(DISTANCE_INVERSE_CLAMPED) { +#if defined(LOVE_LINUX) + // Temporarly block signals, as the thread inherits this mask + love::thread::disableSignals(); +#endif + // Passing null for default device. device = alcOpenDevice(nullptr); if (device == nullptr) throw love::Exception("Could not open device."); - context = alcCreateContext(device, nullptr); +#ifdef ALC_EXT_EFX + ALint attribs[4] = { ALC_MAX_AUXILIARY_SENDS, MAX_SOURCE_EFFECTS, 0, 0 }; +#else + ALint *attribs = nullptr; +#endif + + context = alcCreateContext(device, attribs); if (context == nullptr) throw love::Exception("Could not create context."); @@ -89,36 +121,59 @@ Audio::Audio() if (!alcMakeContextCurrent(context) || alcGetError(device) != ALC_NO_ERROR) throw love::Exception("Could not make context current."); - /*std::string captureName(alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER)); - const ALCchar * devices = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER); - while (*devices) +#if defined(LOVE_LINUX) + love::thread::reenableSignals(); +#endif + +#ifdef ALC_EXT_EFX + initializeEFX(); + + alcGetIntegerv(device, ALC_MAX_AUXILIARY_SENDS, 1, &MAX_SOURCE_EFFECTS); + + alGetError(); + if (alGenAuxiliaryEffectSlots) { - std::string device(devices); - devices += device.size() + 1; - if (device.find("Mic") != std::string::npos || device.find("mic") != std::string::npos) + for (int i = 0; i < MAX_SCENE_EFFECTS; i++) { - captureName = device; + ALuint slot; + alGenAuxiliaryEffectSlots(1, &slot); + if (alGetError() == AL_NO_ERROR) + slotlist.push(slot); + else + { + MAX_SCENE_EFFECTS = i; + break; + } } } + else + MAX_SCENE_EFFECTS = MAX_SOURCE_EFFECTS = 0; +#else + MAX_SCENE_EFFECTS = MAX_SOURCE_EFFECTS = 0; +#endif - capture = alcCaptureOpenDevice(captureName.c_str(), 8000, AL_FORMAT_MONO16, 262144); // about 32 seconds - - if (!capture) - { - // We're not going to prevent LOVE from running without a microphone, but we should warn, at least - std::cerr << "Warning, couldn't open capture device! No audio input!" << std::endl; - }*/ - - // pool must be allocated after AL context. try { pool = new Pool(); } catch (love::Exception &) { + for (auto c : capture) + delete c; + +#ifdef ALC_EXT_EFX + if (alDeleteAuxiliaryEffectSlots) + { + while (!slotlist.empty()) + { + alDeleteAuxiliaryEffectSlots(1, &slotlist.top()); + slotlist.pop(); + } + } +#endif + alcMakeContextCurrent(nullptr); alcDestroyContext(context); - //if (capture) alcCaptureCloseDevice(capture); alcCloseDevice(device); throw; } @@ -135,13 +190,30 @@ Audio::~Audio() delete poolThread; delete pool; + for (auto c : capture) + delete c; + +#ifdef ALC_EXT_EFX + for (auto e : effectmap) + { + delete e.second.effect; + slotlist.push(e.second.slot); + } + + if (alDeleteAuxiliaryEffectSlots) + { + while (!slotlist.empty()) + { + alDeleteAuxiliaryEffectSlots(1, &slotlist.top()); + slotlist.pop(); + } + } +#endif alcMakeContextCurrent(nullptr); alcDestroyContext(context); - //if (capture) alcCaptureCloseDevice(capture); alcCloseDevice(device); } - const char *Audio::getName() const { return "love.audio.openal"; @@ -157,9 +229,14 @@ love::audio::Source *Audio::newSource(love::sound::SoundData *soundData) return new Source(pool, soundData); } -int Audio::getSourceCount() const +love::audio::Source *Audio::newSource(int sampleRate, int bitDepth, int channels, int buffers) { - return pool->getSourceCount(); + return new Source(pool, sampleRate, bitDepth, channels, buffers); +} + +int Audio::getActiveSourceCount() const +{ + return pool->getActiveSourceCount(); } int Audio::getMaxSources() const @@ -172,14 +249,24 @@ bool Audio::play(love::audio::Source *source) return source->play(); } +bool Audio::play(const std::vector &sources) +{ + return Source::play(sources); +} + void Audio::stop(love::audio::Source *source) { source->stop(); } +void Audio::stop(const std::vector &sources) +{ + return Source::stop(sources); +} + void Audio::stop() { - pool->stop(); + return Source::stop(pool); } void Audio::pause(love::audio::Source *source) @@ -187,35 +274,14 @@ void Audio::pause(love::audio::Source *source) source->pause(); } -void Audio::pause() +void Audio::pause(const std::vector &sources) { - pool->pause(); -#ifdef LOVE_ANDROID - alcDevicePauseSOFT(device); -#endif + return Source::pause(sources); } -void Audio::resume(love::audio::Source *source) +std::vector Audio::pause() { - source->resume(); -} - -void Audio::resume() -{ -#ifdef LOVE_ANDROID - alcDeviceResumeSOFT(device); -#endif - pool->resume(); -} - -void Audio::rewind(love::audio::Source *source) -{ - source->rewind(); -} - -void Audio::rewind() -{ - pool->rewind(); + return Source::pause(pool); } void Audio::setVolume(float volume) @@ -270,45 +336,23 @@ float Audio::getDopplerScale() const { return alGetFloat(AL_DOPPLER_FACTOR); } - -void Audio::record() +/* +void Audio::setMeter(float scale) { - if (!canRecord()) return; - alcCaptureStart(capture); -} - -love::sound::SoundData *Audio::getRecordedData() -{ - if (!canRecord()) - return NULL; - int samplerate = 8000; - ALCint samples; - alcGetIntegerv(capture, ALC_CAPTURE_SAMPLES, 4, &samples); - void *data = malloc(samples * (2/sizeof(char))); - alcCaptureSamples(capture, data, samples); - love::sound::SoundData *sd = new love::sound::SoundData(data, samples, samplerate, 16, 1); - free(data); - return sd; -} - -love::sound::SoundData *Audio::stopRecording(bool returnData) -{ - if (!canRecord()) - return NULL; - love::sound::SoundData *sd = NULL; - if (returnData) + if (scale >= 0.0f) { - sd = getRecordedData(); + metersPerUnit = scale; +#ifdef ALC_EXT_EFX + alListenerf(AL_METERS_PER_UNIT, scale); +#endif } - alcCaptureStop(capture); - return sd; } -bool Audio::canRecord() +float Audio::getMeter() const { - return (capture != NULL); + return metersPerUnit; } - +*/ Audio::DistanceModel Audio::getDistanceModel() const { return distanceModel; @@ -353,6 +397,296 @@ void Audio::setDistanceModel(DistanceModel distanceModel) } } +const std::vector &Audio::getRecordingDevices() +{ + std::vector devnames; + std::vector devices; + + std::string defaultname(alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER)); + + //no device name obtained from AL, fallback to reading from device + if (defaultname.length() == 0) + { + //use some safe basic parameters - 8 kHz, 8 bits, 1 channel + ALCdevice *defaultdevice = alcCaptureOpenDevice(NULL, 8000, 8, 1); + if (alGetError() == AL_NO_ERROR) + { + defaultname = alcGetString(defaultdevice, ALC_CAPTURE_DEVICE_SPECIFIER); + alcCaptureCloseDevice(defaultdevice); + } + else + { + //failed to open default recording device - bail, return empty list + capture.clear(); + return capture; + } + } + + devnames.reserve(capture.size()); + devnames.push_back(defaultname); + + //find devices name list + const ALCchar *devstr = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER); + size_t offset = 0; + while (true) + { + if (devstr[offset] == '\0') + break; + std::string str((ALCchar*)&devstr[offset]); + if (str != defaultname) + devnames.push_back(str); + offset += str.length() + 1; + } + + devices.reserve(devnames.size()); + //build ordered list of devices + for (int i = 0; i < (int) devnames.size(); i++) + { + devices.push_back(nullptr); + auto d = devices.end() - 1; + + for (auto c : capture) + if (devnames[i] == c->getName()) + *d = c; + + if (*d == nullptr) + *d = new RecordingDevice(devnames[i].c_str()); + else + (*d)->retain(); + } + + for (auto c : capture) + c->release(); + capture.clear(); + capture.reserve(devices.size()); + + //this needs to be executed in specific order + for (unsigned int i = 0; i < devnames.size(); i++) + capture.push_back(devices[i]); + + return capture; +} + +bool Audio::setEffect(const char *name, std::map ¶ms) +{ + Effect *effect; + ALuint slot; + + auto iter = effectmap.find(name); + if (iter == effectmap.end()) + { + //new effect needed but no more slots + if (effectmap.size() >= (unsigned int)MAX_SCENE_EFFECTS) + return false; + + effect = new Effect(); + slot = slotlist.top(); + slotlist.pop(); + + effectmap[name] = {effect, slot}; + } + else + { + effect = iter->second.effect; + slot = iter->second.slot; + } + + bool result = effect->setParams(params); + +#ifdef ALC_EXT_EFX + if (alAuxiliaryEffectSloti) + { + if (result) + { + auto iter = params.find(Effect::EFFECT_VOLUME); + if (iter != params.end()) + alAuxiliaryEffectSlotf(slot, AL_EFFECTSLOT_GAIN, iter->second); + alAuxiliaryEffectSloti(slot, AL_EFFECTSLOT_EFFECT, effect->getEffect()); + } + else + alAuxiliaryEffectSloti(slot, AL_EFFECTSLOT_EFFECT, AL_EFFECT_NULL); + alGetError(); + } +#endif + + return result; +} + +bool Audio::unsetEffect(const char *name) +{ + auto iter = effectmap.find(name); + if (iter == effectmap.end()) + return false; + + Effect *effect = iter->second.effect; + ALuint slot = iter->second.slot; + +#ifdef ALC_EXT_EFX + if (alAuxiliaryEffectSloti) + alAuxiliaryEffectSloti(slot, AL_EFFECTSLOT_EFFECT, AL_EFFECT_NULL); +#endif + + delete effect; + effectmap.erase(iter); + slotlist.push(slot); + return true; +} + +bool Audio::getEffect(const char *name, std::map ¶ms) +{ + auto iter = effectmap.find(name); + if (iter == effectmap.end()) + return false; + + params = iter->second.effect->getParams(); + + return true; +} + +bool Audio::getActiveEffects(std::vector &list) const +{ + if (effectmap.empty()) + return false; + + list.reserve(effectmap.size()); + for (auto i : effectmap) + list.push_back(i.first); + + return true; +} + +int Audio::getMaxSceneEffects() const +{ + return MAX_SCENE_EFFECTS; +} + +int Audio::getMaxSourceEffects() const +{ + return MAX_SOURCE_EFFECTS; +} + +bool Audio::isEFXsupported() const +{ +#ifdef ALC_EXT_EFX + return (alGenEffects != nullptr); +#else + return false; +#endif +} + +bool Audio::getEffectID(const char *name, ALuint &id) +{ + auto iter = effectmap.find(name); + if (iter == effectmap.end()) + return false; + + id = iter->second.slot; + return true; +} + +#ifdef ALC_EXT_EFX +LPALGENEFFECTS alGenEffects = nullptr; +LPALDELETEEFFECTS alDeleteEffects = nullptr; +LPALISEFFECT alIsEffect = nullptr; +LPALEFFECTI alEffecti = nullptr; +LPALEFFECTIV alEffectiv = nullptr; +LPALEFFECTF alEffectf = nullptr; +LPALEFFECTFV alEffectfv = nullptr; +LPALGETEFFECTI alGetEffecti = nullptr; +LPALGETEFFECTIV alGetEffectiv = nullptr; +LPALGETEFFECTF alGetEffectf = nullptr; +LPALGETEFFECTFV alGetEffectfv = nullptr; +LPALGENFILTERS alGenFilters = nullptr; +LPALDELETEFILTERS alDeleteFilters = nullptr; +LPALISFILTER alIsFilter = nullptr; +LPALFILTERI alFilteri = nullptr; +LPALFILTERIV alFilteriv = nullptr; +LPALFILTERF alFilterf = nullptr; +LPALFILTERFV alFilterfv = nullptr; +LPALGETFILTERI alGetFilteri = nullptr; +LPALGETFILTERIV alGetFilteriv = nullptr; +LPALGETFILTERF alGetFilterf = nullptr; +LPALGETFILTERFV alGetFilterfv = nullptr; +LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots = nullptr; +LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots = nullptr; +LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot = nullptr; +LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti = nullptr; +LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv = nullptr; +LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf = nullptr; +LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv = nullptr; +LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti = nullptr; +LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv = nullptr; +LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf = nullptr; +LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv = nullptr; +#endif + +void Audio::initializeEFX() +{ +#ifdef ALC_EXT_EFX + if (alcIsExtensionPresent(device, "ALC_EXT_EFX") == AL_FALSE) + return; + + alGenEffects = (LPALGENEFFECTS)alGetProcAddress("alGenEffects"); + alDeleteEffects = (LPALDELETEEFFECTS)alGetProcAddress("alDeleteEffects"); + alIsEffect = (LPALISEFFECT)alGetProcAddress("alIsEffect"); + alEffecti = (LPALEFFECTI)alGetProcAddress("alEffecti"); + alEffectiv = (LPALEFFECTIV)alGetProcAddress("alEffectiv"); + alEffectf = (LPALEFFECTF)alGetProcAddress("alEffectf"); + alEffectfv = (LPALEFFECTFV)alGetProcAddress("alEffectfv"); + alGetEffecti = (LPALGETEFFECTI)alGetProcAddress("alGetEffecti"); + alGetEffectiv = (LPALGETEFFECTIV)alGetProcAddress("alGetEffectiv"); + alGetEffectf = (LPALGETEFFECTF)alGetProcAddress("alGetEffectf"); + alGetEffectfv = (LPALGETEFFECTFV)alGetProcAddress("alGetEffectfv"); + alGenFilters = (LPALGENFILTERS)alGetProcAddress("alGenFilters"); + alDeleteFilters = (LPALDELETEFILTERS)alGetProcAddress("alDeleteFilters"); + alIsFilter = (LPALISFILTER)alGetProcAddress("alIsFilter"); + alFilteri = (LPALFILTERI)alGetProcAddress("alFilteri"); + alFilteriv = (LPALFILTERIV)alGetProcAddress("alFilteriv"); + alFilterf = (LPALFILTERF)alGetProcAddress("alFilterf"); + alFilterfv = (LPALFILTERFV)alGetProcAddress("alFilterfv"); + alGetFilteri = (LPALGETFILTERI)alGetProcAddress("alGetFilteri"); + alGetFilteriv = (LPALGETFILTERIV)alGetProcAddress("alGetFilteriv"); + alGetFilterf = (LPALGETFILTERF)alGetProcAddress("alGetFilterf"); + alGetFilterfv = (LPALGETFILTERFV)alGetProcAddress("alGetFilterfv"); + alGenAuxiliaryEffectSlots = (LPALGENAUXILIARYEFFECTSLOTS)alGetProcAddress("alGenAuxiliaryEffectSlots"); + alDeleteAuxiliaryEffectSlots = (LPALDELETEAUXILIARYEFFECTSLOTS)alGetProcAddress("alDeleteAuxiliaryEffectSlots"); + alIsAuxiliaryEffectSlot = (LPALISAUXILIARYEFFECTSLOT)alGetProcAddress("alIsAuxiliaryEffectSlot"); + alAuxiliaryEffectSloti = (LPALAUXILIARYEFFECTSLOTI)alGetProcAddress("alAuxiliaryEffectSloti"); + alAuxiliaryEffectSlotiv = (LPALAUXILIARYEFFECTSLOTIV)alGetProcAddress("alAuxiliaryEffectSlotiv"); + alAuxiliaryEffectSlotf = (LPALAUXILIARYEFFECTSLOTF)alGetProcAddress("alAuxiliaryEffectSlotf"); + alAuxiliaryEffectSlotfv = (LPALAUXILIARYEFFECTSLOTFV)alGetProcAddress("alAuxiliaryEffectSlotfv"); + alGetAuxiliaryEffectSloti = (LPALGETAUXILIARYEFFECTSLOTI)alGetProcAddress("alGetAuxiliaryEffectSloti"); + alGetAuxiliaryEffectSlotiv = (LPALGETAUXILIARYEFFECTSLOTIV)alGetProcAddress("alGetAuxiliaryEffectSlotiv"); + alGetAuxiliaryEffectSlotf = (LPALGETAUXILIARYEFFECTSLOTF)alGetProcAddress("alGetAuxiliaryEffectSlotf"); + alGetAuxiliaryEffectSlotfv = (LPALGETAUXILIARYEFFECTSLOTFV)alGetProcAddress("alGetAuxiliaryEffectSlotfv"); + + //failed to initialize functions, revert to nullptr + if (!alGenEffects || !alDeleteEffects || !alIsEffect || + !alGenFilters || !alDeleteFilters || !alIsFilter || + !alGenAuxiliaryEffectSlots || !alDeleteAuxiliaryEffectSlots || !alIsAuxiliaryEffectSlot || + !alEffecti || !alEffectiv || !alEffectf || !alEffectfv || + !alGetEffecti || !alGetEffectiv || !alGetEffectf || !alGetEffectfv || + !alFilteri || !alFilteriv || !alFilterf || !alFilterfv || + !alGetFilteri || !alGetFilteriv || !alGetFilterf || !alGetFilterfv || + !alAuxiliaryEffectSloti || !alAuxiliaryEffectSlotiv || !alAuxiliaryEffectSlotf || !alAuxiliaryEffectSlotfv || + !alGetAuxiliaryEffectSloti || !alGetAuxiliaryEffectSlotiv || !alGetAuxiliaryEffectSlotf || !alGetAuxiliaryEffectSlotfv) + { + alGenEffects = nullptr; alDeleteEffects = nullptr; alIsEffect = nullptr; + alEffecti = nullptr; alEffectiv = nullptr; alEffectf = nullptr; alEffectfv = nullptr; + alGetEffecti = nullptr; alGetEffectiv = nullptr; alGetEffectf = nullptr; alGetEffectfv = nullptr; + alGenFilters = nullptr; alDeleteFilters = nullptr; alIsFilter = nullptr; + alFilteri = nullptr; alFilteriv = nullptr; alFilterf = nullptr; alFilterfv = nullptr; + alGetFilteri = nullptr; alGetFilteriv = nullptr; alGetFilterf = nullptr; alGetFilterfv = nullptr; + alGenAuxiliaryEffectSlots = nullptr; alDeleteAuxiliaryEffectSlots = nullptr; alIsAuxiliaryEffectSlot = nullptr; + alAuxiliaryEffectSloti = nullptr; alAuxiliaryEffectSlotiv = nullptr; + alAuxiliaryEffectSlotf = nullptr; alAuxiliaryEffectSlotfv = nullptr; + alGetAuxiliaryEffectSloti = nullptr; alGetAuxiliaryEffectSlotiv = nullptr; + alGetAuxiliaryEffectSlotf = nullptr; alGetAuxiliaryEffectSlotfv = nullptr; + } + +#endif +} + } // openal } // audio } // love diff --git a/love/src/jni/love/src/modules/audio/openal/Audio.h b/love/src/jni/love/src/modules/audio/openal/Audio.h index 4ec6d4d6..aa3918b0 100644 --- a/love/src/jni/love/src/modules/audio/openal/Audio.h +++ b/love/src/jni/love/src/modules/audio/openal/Audio.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -24,14 +24,19 @@ // STD #include #include +#include +#include #include // LOVE #include "audio/Audio.h" +#include "audio/RecordingDevice.h" +#include "audio/Filter.h" #include "common/config.h" #include "sound/SoundData.h" #include "Source.h" +#include "Effect.h" #include "Pool.h" #include "thread/threads.h" @@ -64,23 +69,32 @@ public: Audio(); ~Audio(); + /** + * Gets the OpenAL format identifier based on number of + * channels and bits. + * @param channels. + * @param bitDepth Either 8-bit samples, or 16-bit samples. + * @return One of AL_FORMAT_*, or AL_NONE if unsupported format. + **/ + static ALenum getFormat(int bitDepth, int channels); + // Implements Module. const char *getName() const; // Implements Audio. love::audio::Source *newSource(love::sound::Decoder *decoder); love::audio::Source *newSource(love::sound::SoundData *soundData); - int getSourceCount() const; + love::audio::Source *newSource(int sampleRate, int bitDepth, int channels, int buffers); + int getActiveSourceCount() const; int getMaxSources() const; bool play(love::audio::Source *source); + bool play(const std::vector &sources); void stop(love::audio::Source *source); + void stop(const std::vector &sources); void stop(); void pause(love::audio::Source *source); - void pause(); - void resume(love::audio::Source *source); - void resume(); - void rewind(love::audio::Source *source); - void rewind(); + void pause(const std::vector &sources); + std::vector pause(); void setVolume(float volume); float getVolume() const; @@ -93,26 +107,46 @@ public: void setDopplerScale(float scale); float getDopplerScale() const; + //void setMeter(float scale); + //float getMeter() const; - void record(); - love::sound::SoundData *getRecordedData(); - love::sound::SoundData *stopRecording(bool returnData); - bool canRecord(); + const std::vector &getRecordingDevices(); DistanceModel getDistanceModel() const; void setDistanceModel(DistanceModel distanceModel); -private: + bool setEffect(const char *name, std::map ¶ms); + bool unsetEffect(const char *name); + bool getEffect(const char *name, std::map ¶ms); + bool getActiveEffects(std::vector &list) const; + int getMaxSceneEffects() const; + int getMaxSourceEffects() const; + bool isEFXsupported() const; + bool getEffectID(const char *name, ALuint &id); + +private: + void initializeEFX(); // The OpenAL device. ALCdevice *device; - // The OpenAL capture device (microphone). - ALCdevice *capture; + // The OpenAL capture devices. + std::vector capture; // The OpenAL context. ALCcontext *context; + // The OpenAL effects + struct EffectMapStorage + { + Effect *effect; + ALuint slot; + }; + std::map effectmap; + std::stack slotlist; + int MAX_SCENE_EFFECTS = 64; + int MAX_SOURCE_EFFECTS = 64; + // The Pool. Pool *pool; @@ -139,9 +173,50 @@ private: PoolThread *poolThread; DistanceModel distanceModel; - + //float metersPerUnit = 1.0; }; // Audio +#ifdef ALC_EXT_EFX + // Effect objects +extern LPALGENEFFECTS alGenEffects; +extern LPALDELETEEFFECTS alDeleteEffects; +extern LPALISEFFECT alIsEffect; +extern LPALEFFECTI alEffecti; +extern LPALEFFECTIV alEffectiv; +extern LPALEFFECTF alEffectf; +extern LPALEFFECTFV alEffectfv; +extern LPALGETEFFECTI alGetEffecti; +extern LPALGETEFFECTIV alGetEffectiv; +extern LPALGETEFFECTF alGetEffectf; +extern LPALGETEFFECTFV alGetEffectfv; + +//Filter objects +extern LPALGENFILTERS alGenFilters; +extern LPALDELETEFILTERS alDeleteFilters; +extern LPALISFILTER alIsFilter; +extern LPALFILTERI alFilteri; +extern LPALFILTERIV alFilteriv; +extern LPALFILTERF alFilterf; +extern LPALFILTERFV alFilterfv; +extern LPALGETFILTERI alGetFilteri; +extern LPALGETFILTERIV alGetFilteriv; +extern LPALGETFILTERF alGetFilterf; +extern LPALGETFILTERFV alGetFilterfv; + +// Auxiliary slot object +extern LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots; +extern LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots; +extern LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot; +extern LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti; +extern LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv; +extern LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf; +extern LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv; +extern LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti; +extern LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv; +extern LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf; +extern LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv; +#endif + } // openal } // audio } // love diff --git a/love/src/jni/love/src/modules/audio/openal/Effect.cpp b/love/src/jni/love/src/modules/audio/openal/Effect.cpp new file mode 100644 index 00000000..2a8bccb3 --- /dev/null +++ b/love/src/jni/love/src/modules/audio/openal/Effect.cpp @@ -0,0 +1,417 @@ +/** + * Copyright (c) 2006-2016 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#include "Effect.h" +#include "common/Exception.h" + +#include +#include + +namespace love +{ +namespace audio +{ +namespace openal +{ + +//base class +Effect::Effect() +{ + generateEffect(); +} + +Effect::Effect(const Effect &s) + : Effect() +{ + setParams(s.getParams()); +} + +Effect::~Effect() +{ + deleteEffect(); +} + +Effect *Effect::clone() +{ + return new Effect(*this); +} + +bool Effect::generateEffect() +{ +#ifdef ALC_EXT_EFX + if (!alGenEffects) + return false; + + if (effect != AL_EFFECT_NULL) + return true; + + alGenEffects(1, &effect); + if (alGetError() != AL_NO_ERROR) + throw love::Exception("Failed to create sound Effect."); + + return true; +#else + return false; +#endif +} + +void Effect::deleteEffect() +{ +#ifdef ALC_EXT_EFX + if (effect != AL_EFFECT_NULL) + alDeleteEffects(1, &effect); +#endif + effect = AL_EFFECT_NULL; +} + +ALuint Effect::getEffect() const +{ + return effect; +} + +bool Effect::setParams(const std::map ¶ms) +{ + this->params = params; + type = (Type)(int) this->params[EFFECT_TYPE]; + + if (!generateEffect()) + return false; + +#ifdef ALC_EXT_EFX + //parameter table without EFFECT_TYPE entry is illegal + switch (type) + { + case TYPE_REVERB: + alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_REVERB); + break; + case TYPE_CHORUS: + alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_CHORUS); + break; + case TYPE_DISTORTION: + alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_DISTORTION); + break; + case TYPE_ECHO: + alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_ECHO); + break; + case TYPE_FLANGER: + alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_FLANGER); + break; +/* + case TYPE_FREQSHIFTER: + alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_FREQUENCY_SHIFTER); + break; + case TYPE_MORPHER: + alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_VOCAL_MORPHER); + break; + case TYPE_PITCHSHIFTER: + alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_PITCH_SHIFTER); + break; +*/ + case TYPE_MODULATOR: + alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_RING_MODULATOR); + break; +/* + case TYPE_AUTOWAH: + alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_AUTOWAH); + break; +*/ + case TYPE_COMPRESSOR: + alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_COMPRESSOR); + break; + case TYPE_EQUALIZER: + alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_EQUALIZER); + break; + case TYPE_BASIC: + case TYPE_MAX_ENUM: + break; + } + + //failed to make effect specific type - not supported etc. + if (alGetError() != AL_NO_ERROR) + { + deleteEffect(); + return false; + } + +#define clampf(v,l,h) fmax(fmin((v),(h)),(l)) +#define PARAMSTR(i,e,v) effect,AL_##e##_##v,clampf(getValue(i,AL_##e##_DEFAULT_##v),AL_##e##_MIN_##v,AL_##e##_MAX_##v) + switch (type) + { + case TYPE_REVERB: + { + alEffectf(PARAMSTR(REVERB_GAIN,REVERB,GAIN)); + alEffectf(PARAMSTR(REVERB_HFGAIN,REVERB,GAINHF)); + alEffectf(PARAMSTR(REVERB_DENSITY,REVERB,DENSITY)); + alEffectf(PARAMSTR(REVERB_DIFFUSION,REVERB,DIFFUSION)); + alEffectf(PARAMSTR(REVERB_DECAY,REVERB,DECAY_TIME)); + alEffectf(PARAMSTR(REVERB_HFDECAY,REVERB,DECAY_HFRATIO)); + alEffectf(PARAMSTR(REVERB_EARLYGAIN,REVERB,REFLECTIONS_GAIN)); + alEffectf(PARAMSTR(REVERB_EARLYDELAY,REVERB,REFLECTIONS_DELAY)); + alEffectf(PARAMSTR(REVERB_LATEGAIN,REVERB,LATE_REVERB_GAIN)); + alEffectf(PARAMSTR(REVERB_LATEDELAY,REVERB,LATE_REVERB_DELAY));; + alEffectf(PARAMSTR(REVERB_ROLLOFF,REVERB,ROOM_ROLLOFF_FACTOR)); + alEffectf(PARAMSTR(REVERB_AIRHFGAIN,REVERB,AIR_ABSORPTION_GAINHF)); + alEffecti(effect, AL_REVERB_DECAY_HFLIMIT, getValue(REVERB_HFLIMITER, 0)); + break; + } + case TYPE_CHORUS: + { + Waveform wave = static_cast(getValue(CHORUS_WAVEFORM, static_cast(WAVE_MAX_ENUM))); + if (wave == WAVE_SINE) + alEffecti(effect, AL_CHORUS_WAVEFORM, AL_CHORUS_WAVEFORM_SINUSOID); + else if (wave == WAVE_TRIANGLE) + alEffecti(effect, AL_CHORUS_WAVEFORM, AL_CHORUS_WAVEFORM_TRIANGLE); + else + alEffecti(effect, AL_CHORUS_WAVEFORM, AL_CHORUS_DEFAULT_WAVEFORM); + + alEffecti(PARAMSTR(CHORUS_PHASE,CHORUS,PHASE)); + alEffectf(PARAMSTR(CHORUS_RATE,CHORUS,RATE)); + alEffectf(PARAMSTR(CHORUS_DEPTH,CHORUS,DEPTH)); + alEffectf(PARAMSTR(CHORUS_FEEDBACK,CHORUS,FEEDBACK)); + alEffectf(PARAMSTR(CHORUS_DELAY,CHORUS,DELAY)); + break; + } + case TYPE_DISTORTION: + alEffectf(PARAMSTR(DISTORTION_GAIN,DISTORTION,GAIN)); + alEffectf(PARAMSTR(DISTORTION_EDGE,DISTORTION,EDGE)); + alEffectf(PARAMSTR(DISTORTION_LOWCUT,DISTORTION,LOWPASS_CUTOFF)); + alEffectf(PARAMSTR(DISTORTION_EQCENTER,DISTORTION,EQCENTER)); + alEffectf(PARAMSTR(DISTORTION_EQBAND,DISTORTION,EQBANDWIDTH)); + break; + + case TYPE_ECHO: + alEffectf(PARAMSTR(ECHO_DELAY,ECHO,DELAY)); + alEffectf(PARAMSTR(ECHO_LRDELAY,ECHO,LRDELAY)); + alEffectf(PARAMSTR(ECHO_DAMPING,ECHO,DAMPING)); + alEffectf(PARAMSTR(ECHO_FEEDBACK,ECHO,FEEDBACK)); + alEffectf(PARAMSTR(ECHO_SPREAD,ECHO,SPREAD)); + break; + + case TYPE_FLANGER: + { + Waveform wave = static_cast(getValue(FLANGER_WAVEFORM, static_cast(WAVE_MAX_ENUM))); + if (wave == WAVE_SINE) + alEffecti(effect, AL_FLANGER_WAVEFORM, AL_FLANGER_WAVEFORM_SINUSOID); + else if (wave == WAVE_TRIANGLE) + alEffecti(effect, AL_FLANGER_WAVEFORM, AL_FLANGER_WAVEFORM_TRIANGLE); + else + alEffecti(effect, AL_FLANGER_WAVEFORM, AL_FLANGER_DEFAULT_WAVEFORM); + + alEffecti(PARAMSTR(FLANGER_PHASE,FLANGER,PHASE)); + alEffectf(PARAMSTR(FLANGER_RATE,FLANGER,RATE)); + alEffectf(PARAMSTR(FLANGER_DEPTH,FLANGER,DEPTH)); + alEffectf(PARAMSTR(FLANGER_FEEDBACK,FLANGER,FEEDBACK)); + alEffectf(PARAMSTR(FLANGER_DELAY,FLANGER,DELAY)); + break; + } +/* + case TYPE_FREQSHIFTER: + { + alEffectf(PARAMSTR(FREQSHIFTER_FREQ,FREQUENCY_SHIFTER,FREQUENCY)); + + Direction dir = static_cast(getValue(FREQSHIFTER_LEFTDIR, static_cast(DIR_MAX_ENUM))); + if (dir == DIR_NONE) + alEffecti(effect, AL_FREQUENCY_SHIFTER_LEFT_DIRECTION, AL_FREQUENCY_SHIFTER_DIRECTION_OFF); + else if(dir == DIR_UP) + alEffecti(effect, AL_FREQUENCY_SHIFTER_LEFT_DIRECTION, AL_FREQUENCY_SHIFTER_DIRECTION_UP); + else if(dir == DIR_DOWN) + alEffecti(effect, AL_FREQUENCY_SHIFTER_LEFT_DIRECTION, AL_FREQUENCY_SHIFTER_DIRECTION_DOWN); + else + alEffecti(effect, AL_FREQUENCY_SHIFTER_LEFT_DIRECTION, AL_FREQUENCY_SHIFTER_DEFAULT_LEFT_DIRECTION); + + dir = static_cast(getValue(FREQSHIFTER_RIGHTDIR, static_cast(DIR_MAX_ENUM))); + if (dir == DIR_NONE) + alEffecti(effect, AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION, AL_FREQUENCY_SHIFTER_DIRECTION_OFF); + else if(dir == DIR_UP) + alEffecti(effect, AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION, AL_FREQUENCY_SHIFTER_DIRECTION_UP); + else if(dir == DIR_DOWN) + alEffecti(effect, AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION, AL_FREQUENCY_SHIFTER_DIRECTION_DOWN); + else + alEffecti(effect, AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION, AL_FREQUENCY_SHIFTER_DEFAULT_RIGHT_DIRECTION); + break; + } + case TYPE_MORPHER: + { + Waveform wave = static_cast(getValue(MORPHER_WAVEFORM, static_cast(WAVE_MAX_ENUM))); + if (wave == WAVE_SINE) + alEffecti(effect, AL_VOCAL_MORPHER_WAVEFORM, AL_VOCAL_MORPHER_WAVEFORM_SINUSOID); + else if (wave == WAVE_TRIANGLE) + alEffecti(effect, AL_VOCAL_MORPHER_WAVEFORM, AL_VOCAL_MORPHER_WAVEFORM_TRIANGLE); + else if (wave == WAVE_SAWTOOTH) + alEffecti(effect, AL_VOCAL_MORPHER_WAVEFORM, AL_VOCAL_MORPHER_WAVEFORM_SAWTOOTH); + else + alEffecti(effect, AL_VOCAL_MORPHER_WAVEFORM, AL_VOCAL_MORPHER_DEFAULT_WAVEFORM); + + Phoneme phoneme = static_cast(getValue(MORPHER_PHONEMEA, static_cast(PHONEME_MAX_ENUM))); + if (phoneme == PHONEME_MAX_ENUM) + alEffecti(effect, AL_VOCAL_MORPHER_PHONEMEA, AL_VOCAL_MORPHER_DEFAULT_PHONEMEA); + else + alEffecti(effect, AL_VOCAL_MORPHER_PHONEMEA, phonemeMap[phoneme]); + + phoneme = static_cast(getValue(MORPHER_PHONEMEB, static_cast(PHONEME_MAX_ENUM))); + if (phoneme == PHONEME_MAX_ENUM) + alEffecti(effect, AL_VOCAL_MORPHER_PHONEMEB, AL_VOCAL_MORPHER_DEFAULT_PHONEMEB); + else + alEffecti(effect, AL_VOCAL_MORPHER_PHONEMEB, phonemeMap[phoneme]); + + alEffectf(PARAMSTR(MORPHER_RATE,VOCAL_MORPHER,RATE)); + alEffecti(PARAMSTR(MORPHER_TUNEA,VOCAL_MORPHER,PHONEMEA_COARSE_TUNING)); + alEffecti(PARAMSTR(MORPHER_TUNEB,VOCAL_MORPHER,PHONEMEB_COARSE_TUNING)); + break; + } + case TYPE_PITCHSHIFTER: + { + float tune = getValue(PITCHSHIFTER_PITCH, (float)AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE + (float)(AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE - 50) / 100.0 ); + + int coarse = (int)floor(tune); + int fine = (int)(fmod(tune, 1.0)*100.0); + if (fine > 50) + { + fine -= 100; + coarse += 1; + } + else if (fine < -50) + { + fine += 100; + coarse -= 1; + } + if (coarse > AL_PITCH_SHIFTER_MAX_COARSE_TUNE) + { + coarse = AL_PITCH_SHIFTER_MAX_COARSE_TUNE; + fine = AL_PITCH_SHIFTER_MAX_FINE_TUNE; + } + else if (coarse < AL_PITCH_SHIFTER_MIN_COARSE_TUNE) + { + coarse = AL_PITCH_SHIFTER_MIN_COARSE_TUNE; + fine = AL_PITCH_SHIFTER_MIN_FINE_TUNE; + } + alEffecti(effect, AL_PITCH_SHIFTER_COARSE_TUNE, coarse); + alEffecti(effect, AL_PITCH_SHIFTER_FINE_TUNE, fine); + break; + } +*/ + case TYPE_MODULATOR: + { + Waveform wave = static_cast(getValue(MODULATOR_WAVEFORM,static_cast(WAVE_MAX_ENUM))); + if (wave == WAVE_SINE) + alEffecti(effect, AL_RING_MODULATOR_WAVEFORM, AL_RING_MODULATOR_SINUSOID); + else if (wave == WAVE_SAWTOOTH) + alEffecti(effect, AL_RING_MODULATOR_WAVEFORM, AL_RING_MODULATOR_SAWTOOTH); + else if (wave == WAVE_SQUARE) + alEffecti(effect, AL_RING_MODULATOR_WAVEFORM, AL_RING_MODULATOR_SQUARE); + else + alEffecti(effect, AL_RING_MODULATOR_WAVEFORM, AL_RING_MODULATOR_DEFAULT_WAVEFORM); + + alEffectf(PARAMSTR(MODULATOR_FREQ,RING_MODULATOR,FREQUENCY)); + alEffectf(PARAMSTR(MODULATOR_HIGHCUT,RING_MODULATOR,HIGHPASS_CUTOFF)); + break; + } +/* + case TYPE_AUTOWAH: + alEffectf(PARAMSTR(AUTOWAH_ATTACK,AUTOWAH,ATTACK_TIME)); + alEffectf(PARAMSTR(AUTOWAH_RELEASE,AUTOWAH,RELEASE_TIME)); + alEffectf(PARAMSTR(AUTOWAH_RESONANCE,AUTOWAH,RESONANCE)); + alEffectf(PARAMSTR(AUTOWAH_PEAKGAIN,AUTOWAH,PEAK_GAIN)); + break; +*/ + case TYPE_COMPRESSOR: + alEffecti(effect, AL_COMPRESSOR_ONOFF, getValue(COMPRESSOR_ENABLE,static_cast(AL_COMPRESSOR_DEFAULT_ONOFF))); + break; + + case TYPE_EQUALIZER: + alEffectf(PARAMSTR(EQUALIZER_LOWGAIN,EQUALIZER,LOW_GAIN)); + alEffectf(PARAMSTR(EQUALIZER_LOWCUT,EQUALIZER,LOW_CUTOFF)); + alEffectf(PARAMSTR(EQUALIZER_MID1GAIN,EQUALIZER,MID1_GAIN)); + alEffectf(PARAMSTR(EQUALIZER_MID1FREQ,EQUALIZER,MID1_CENTER)); + alEffectf(PARAMSTR(EQUALIZER_MID1BAND,EQUALIZER,MID1_WIDTH)); + alEffectf(PARAMSTR(EQUALIZER_MID2GAIN,EQUALIZER,MID2_GAIN)); + alEffectf(PARAMSTR(EQUALIZER_MID2FREQ,EQUALIZER,MID2_CENTER)); + alEffectf(PARAMSTR(EQUALIZER_MID2BAND,EQUALIZER,MID2_WIDTH)); + alEffectf(PARAMSTR(EQUALIZER_HIGHGAIN,EQUALIZER,HIGH_GAIN)); + alEffectf(PARAMSTR(EQUALIZER_HIGHCUT,EQUALIZER,HIGH_CUTOFF)); + break; + case TYPE_BASIC: + case TYPE_MAX_ENUM: + break; + } +#undef PARAMSTR +#undef clampf + //alGetError(); + + return true; +#else + return false; +#endif //ALC_EXT_EFX +} + +const std::map &Effect::getParams() const +{ + return params; +} + +float Effect::getValue(Parameter in, float def) const +{ + return params.find(in) == params.end() ? def : params.at(in); +} + +int Effect::getValue(Parameter in, int def) const +{ + return params.find(in) == params.end() ? def : static_cast(params.at(in)); +} + +/* +std::map Effect::phonemeMap = +{ + {Effect::PHONEME_A, AL_VOCAL_MORPHER_PHONEME_A}, + {Effect::PHONEME_E, AL_VOCAL_MORPHER_PHONEME_E}, + {Effect::PHONEME_I, AL_VOCAL_MORPHER_PHONEME_I}, + {Effect::PHONEME_O, AL_VOCAL_MORPHER_PHONEME_O}, + {Effect::PHONEME_U, AL_VOCAL_MORPHER_PHONEME_U}, + {Effect::PHONEME_AA, AL_VOCAL_MORPHER_PHONEME_AA}, + {Effect::PHONEME_AE, AL_VOCAL_MORPHER_PHONEME_AE}, + {Effect::PHONEME_AH, AL_VOCAL_MORPHER_PHONEME_AH}, + {Effect::PHONEME_AO, AL_VOCAL_MORPHER_PHONEME_AO}, + {Effect::PHONEME_EH, AL_VOCAL_MORPHER_PHONEME_EH}, + {Effect::PHONEME_ER, AL_VOCAL_MORPHER_PHONEME_ER}, + {Effect::PHONEME_IH, AL_VOCAL_MORPHER_PHONEME_IH}, + {Effect::PHONEME_IY, AL_VOCAL_MORPHER_PHONEME_IY}, + {Effect::PHONEME_UH, AL_VOCAL_MORPHER_PHONEME_UH}, + {Effect::PHONEME_UW, AL_VOCAL_MORPHER_PHONEME_UW}, + {Effect::PHONEME_B, AL_VOCAL_MORPHER_PHONEME_B}, + {Effect::PHONEME_D, AL_VOCAL_MORPHER_PHONEME_D}, + {Effect::PHONEME_F, AL_VOCAL_MORPHER_PHONEME_F}, + {Effect::PHONEME_G, AL_VOCAL_MORPHER_PHONEME_G}, + {Effect::PHONEME_J, AL_VOCAL_MORPHER_PHONEME_J}, + {Effect::PHONEME_K, AL_VOCAL_MORPHER_PHONEME_K}, + {Effect::PHONEME_L, AL_VOCAL_MORPHER_PHONEME_L}, + {Effect::PHONEME_M, AL_VOCAL_MORPHER_PHONEME_M}, + {Effect::PHONEME_N, AL_VOCAL_MORPHER_PHONEME_N}, + {Effect::PHONEME_P, AL_VOCAL_MORPHER_PHONEME_P}, + {Effect::PHONEME_R, AL_VOCAL_MORPHER_PHONEME_R}, + {Effect::PHONEME_S, AL_VOCAL_MORPHER_PHONEME_S}, + {Effect::PHONEME_T, AL_VOCAL_MORPHER_PHONEME_T}, + {Effect::PHONEME_V, AL_VOCAL_MORPHER_PHONEME_V}, + {Effect::PHONEME_Z, AL_VOCAL_MORPHER_PHONEME_Z} +}; +*/ + +} //openal +} //audio +} //love diff --git a/love/src/jni/love/src/modules/audio/openal/Effect.h b/love/src/jni/love/src/modules/audio/openal/Effect.h new file mode 100644 index 00000000..547db2e6 --- /dev/null +++ b/love/src/jni/love/src/modules/audio/openal/Effect.h @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2006-2016 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#ifndef LOVE_AUDIO_OPENAL_EFFECTS_H +#define LOVE_AUDIO_OPENAL_EFFECTS_H + +#include "common/config.h" + +// OpenAL +#ifdef LOVE_APPLE_USE_FRAMEWORKS // Frameworks have different include paths. +#ifdef LOVE_IOS +#include +#include +#else +#include +#include +#include +#endif +#else +#include +#include +#include +#endif + +#include +#include + +#include "audio/Effect.h" +#include "Audio.h" + +#ifndef AL_EFFECT_NULL +#define AL_EFFECT_NULL (0) +#endif + +#ifndef AL_EFFECTSLOT_NULL +#define AL_EFFECTSLOT_NULL (0) +#endif + +namespace love +{ +namespace audio +{ +namespace openal +{ + +class Effect : public love::audio::Effect +{ +public: + Effect(); + Effect(const Effect &s); + virtual ~Effect(); + virtual Effect *clone(); + ALuint getEffect() const; + virtual bool setParams(const std::map ¶ms); + virtual const std::map &getParams() const; + +private: + bool generateEffect(); + void deleteEffect(); + float getValue(Parameter in, float def) const; + int getValue(Parameter in, int def) const; + + ALuint effect = AL_EFFECT_NULL; + std::map params; + //static std::map phonemeMap; +}; + +} //openal +} //audio +} //love + +#endif //LOVE_AUDIO_OPENAL_EFFECTS_H diff --git a/love/src/jni/love/src/modules/audio/openal/Filter.cpp b/love/src/jni/love/src/modules/audio/openal/Filter.cpp new file mode 100644 index 00000000..ec2fb9b7 --- /dev/null +++ b/love/src/jni/love/src/modules/audio/openal/Filter.cpp @@ -0,0 +1,168 @@ +/** + * Copyright (c) 2006-2018 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#include "Filter.h" +#include "common/Exception.h" + +#include + +namespace love +{ +namespace audio +{ +namespace openal +{ + +//base class +Filter::Filter() +{ + generateFilter(); +} + +Filter::Filter(const Filter &s) + : Filter() +{ + setParams(s.getParams()); +} + +Filter::~Filter() +{ + deleteFilter(); +} + +Filter *Filter::clone() +{ + return new Filter(*this); +} + +bool Filter::generateFilter() +{ +#ifdef ALC_EXT_EFX + if (!alGenFilters) + return false; + + if (filter != AL_FILTER_NULL) + return true; + + alGenFilters(1, &filter); + if (alGetError() != AL_NO_ERROR) + throw love::Exception("Failed to create sound Filter."); + + return true; +#else + return false; +#endif +} + +void Filter::deleteFilter() +{ +#ifdef ALC_EXT_EFX + if (filter != AL_FILTER_NULL) + alDeleteFilters(1, &filter); +#endif + filter = AL_FILTER_NULL; +} + +ALuint Filter::getFilter() const +{ + return filter; +} + +bool Filter::setParams(const std::map ¶ms) +{ + this->params = params; + type = (Type)(int) this->params[FILTER_TYPE]; + + if (!generateFilter()) + return false; + +#ifdef ALC_EXT_EFX + switch (type) + { + case TYPE_LOWPASS: + alFilteri(filter, AL_FILTER_TYPE, AL_FILTER_LOWPASS); + break; + case TYPE_HIGHPASS: + alFilteri(filter, AL_FILTER_TYPE, AL_FILTER_HIGHPASS); + break; + case TYPE_BANDPASS: + alFilteri(filter, AL_FILTER_TYPE, AL_FILTER_BANDPASS); + break; + case TYPE_BASIC: + case TYPE_MAX_ENUM: + break; + } + + //failed to make filter specific type - not supported etc. + if (alGetError() != AL_NO_ERROR) + { + deleteFilter(); + return false; + } + +#define clampf(v,l,h) fmax(fmin((v),(h)),(l)) +#define PARAMSTR(i,e,v) filter,AL_##e##_##v,clampf(getValue(i,AL_##e##_DEFAULT_##v),AL_##e##_MIN_##v,AL_##e##_MAX_##v) + switch (type) + { + case TYPE_LOWPASS: + alFilterf(PARAMSTR(FILTER_VOLUME,LOWPASS,GAIN)); + alFilterf(PARAMSTR(FILTER_HIGHGAIN,LOWPASS,GAINHF)); + break; + case TYPE_HIGHPASS: + alFilterf(PARAMSTR(FILTER_VOLUME,HIGHPASS,GAIN)); + alFilterf(PARAMSTR(FILTER_LOWGAIN,HIGHPASS,GAINLF)); + break; + case TYPE_BANDPASS: + alFilterf(PARAMSTR(FILTER_VOLUME,BANDPASS,GAIN)); + alFilterf(PARAMSTR(FILTER_LOWGAIN,BANDPASS,GAINLF)); + alFilterf(PARAMSTR(FILTER_HIGHGAIN,BANDPASS,GAINHF)); + break; + case TYPE_BASIC: + case TYPE_MAX_ENUM: + break; + } +#undef clampf +#undef PARAMSTR + //alGetError(); + + return true; +#else + return false; +#endif +} + +const std::map &Filter::getParams() const +{ + return params; +} + +float Filter::getValue(Parameter in, float def) const +{ + return params.find(in) == params.end() ? def : params.at(in); +} + +int Filter::getValue(Parameter in, int def) const +{ + return params.find(in) == params.end() ? def : static_cast(params.at(in)); +} + +} //openal +} //audio +} //love diff --git a/love/src/jni/love/src/modules/audio/openal/Filter.h b/love/src/jni/love/src/modules/audio/openal/Filter.h new file mode 100644 index 00000000..6e3c6239 --- /dev/null +++ b/love/src/jni/love/src/modules/audio/openal/Filter.h @@ -0,0 +1,82 @@ +/** + * Copyright (c) 2006-2018 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#ifndef LOVE_AUDIO_OPENAL_FILTERS_H +#define LOVE_AUDIO_OPENAL_FILTERS_H + +#include "common/config.h" + +// OpenAL +#ifdef LOVE_APPLE_USE_FRAMEWORKS // Frameworks have different include paths. +#ifdef LOVE_IOS +#include +#include +#else +#include +#include +#include +#endif +#else +#include +#include +#include +#endif + +#include + +#include "audio/Filter.h" +#include "Audio.h" + +#ifndef AL_FILTER_NULL +#define AL_FILTER_NULL (0) +#endif + +namespace love +{ +namespace audio +{ +namespace openal +{ + +class Filter : public love::audio::Filter +{ +public: + Filter(); + Filter(const Filter &s); + virtual ~Filter(); + virtual Filter *clone(); + ALuint getFilter() const; + virtual bool setParams(const std::map ¶ms); + virtual const std::map &getParams() const; + +private: + bool generateFilter(); + void deleteFilter(); + float getValue(Parameter in, float def) const; + int getValue(Parameter in, int def) const; + ALuint filter = AL_FILTER_NULL; + std::map params; +}; + +} //openal +} //audio +} //love + +#endif //LOVE_AUDIO_OPENAL_FILTERS_H diff --git a/love/src/jni/love/src/modules/audio/openal/Pool.cpp b/love/src/jni/love/src/modules/audio/openal/Pool.cpp index 1e662640..565041bb 100644 --- a/love/src/jni/love/src/modules/audio/openal/Pool.cpp +++ b/love/src/jni/love/src/modules/audio/openal/Pool.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -73,7 +73,7 @@ Pool::Pool() Pool::~Pool() { - stop(); + Source::stop(this); // Free all sources. alDeleteSources(totalSources, sources); @@ -103,24 +103,19 @@ void Pool::update() { thread::Lock lock(mutex); - std::map::iterator i = playing.begin(); + std::vector torelease; - while (i != playing.end()) + for (const auto &i : playing) { - if (!i->first->update()) - { - i->first->stopAtomic(); - i->first->rewindAtomic(); - i->first->release(); - available.push(i->second); - playing.erase(i++); - } - else - i++; + if (!i.first->update()) + torelease.push_back(i.first); } + + for (Source *s : torelease) + releaseSource(s); } -int Pool::getSourceCount() const +int Pool::getActiveSourceCount() const { return (int) playing.size(); } @@ -130,183 +125,68 @@ int Pool::getMaxSources() const return totalSources; } -bool Pool::play(Source *source, ALuint &out) +bool Pool::assignSource(Source *source, ALuint &out, char &wasPlaying) { - thread::Lock lock(mutex); - - bool ok = true; out = 0; - bool alreadyPlaying = findSource(source, out); - - if (!alreadyPlaying) - { - // Try to play. - if (!available.empty()) - { - // Get the first available source. - out = available.front(); - - // Remove it. - available.pop(); - - // Insert into map of playing sources. - playing.insert(std::pair(source, out)); - - source->retain(); - - ok = source->playAtomic(); - } - else - { - ok = false; - } - } - else - { - ok = true; - } - - return ok; -} - -void Pool::stop() -{ - thread::Lock lock(mutex); - for (const auto &i : playing) - { - i.first->stopAtomic(); - i.first->rewindAtomic(); - i.first->release(); - available.push(i.second); - } - - playing.clear(); -} - -void Pool::stop(Source *source) -{ - thread::Lock lock(mutex); - removeSource(source); -} - -void Pool::pause() -{ - thread::Lock lock(mutex); - for (const auto &i : playing) - i.first->pauseAtomic(); -} - -void Pool::pause(Source *source) -{ - thread::Lock lock(mutex); - ALuint out; if (findSource(source, out)) - source->pauseAtomic(); + return wasPlaying = true; + + wasPlaying = false; + + if (available.empty()) + return false; + + out = available.front(); + available.pop(); + + playing.insert(std::make_pair(source, out)); + source->retain(); + return true; } -void Pool::resume() +bool Pool::releaseSource(Source *source, bool stop) { - thread::Lock lock(mutex); - for (const auto &i : playing) - i.first->resumeAtomic(); -} + ALuint s; -void Pool::resume(Source *source) -{ - thread::Lock lock(mutex); - ALuint out; - if (findSource(source, out)) - source->resumeAtomic(); -} - -void Pool::rewind() -{ - thread::Lock lock(mutex); - for (const auto &i : playing) - i.first->rewindAtomic(); -} - -// For those times we don't need it backed. -void Pool::softRewind(Source *source) -{ - thread::Lock lock(mutex); - source->rewindAtomic(); -} - -void Pool::rewind(Source *source) -{ - thread::Lock lock(mutex); - source->rewindAtomic(); -} - -void Pool::release(Source *source) -{ - ALuint s = findi(source); - - if (s != 0) + if (findSource(source, s)) { + if (stop) + source->stopAtomic(); + source->release(); available.push(s); playing.erase(source); - } -} - -void Pool::seek(Source *source, float offset, void *unit) -{ - thread::Lock lock(mutex); - return source->seekAtomic(offset, unit); -} - -float Pool::tell(Source *source, void *unit) -{ - thread::Lock lock(mutex); - return source->tellAtomic(unit); -} - -double Pool::getDuration(Source *source, void *unit) -{ - thread::Lock lock(mutex); - return source->getDurationAtomic(unit); -} - -ALuint Pool::findi(const Source *source) const -{ - std::map::const_iterator i = playing.find((Source *)source); - - if (i != playing.end()) - return i->second; - - return 0; -} - -bool Pool::findSource(Source *source, ALuint &out) -{ - std::map::const_iterator i = playing.find((Source *)source); - - bool found = i != playing.end(); - - if (found) - out = i->second; - - return found; -} - -bool Pool::removeSource(Source *source) -{ - std::map::iterator i = playing.find((Source *)source); - - if (i != playing.end()) - { - source->stopAtomic(); - available.push(i->second); - playing.erase(i++); - source->release(); return true; } return false; } +bool Pool::findSource(Source *source, ALuint &out) +{ + std::map::const_iterator i = playing.find(source); + + if (i == playing.end()) + return false; + + out = i->second; + return true; +} + +thread::Lock Pool::lock() +{ + return thread::Lock(mutex); +} + +std::vector Pool::getPlayingSources() +{ + std::vector sources; + sources.reserve(playing.size()); + for (auto &i : playing) + sources.push_back(i.first); + return sources; +} + } // openal } // audio } // love diff --git a/love/src/jni/love/src/modules/audio/openal/Pool.h b/love/src/jni/love/src/modules/audio/openal/Pool.h index b4417b4d..fe57382e 100644 --- a/love/src/jni/love/src/modules/audio/openal/Pool.h +++ b/love/src/jni/love/src/modules/audio/openal/Pool.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -24,12 +24,14 @@ // STD #include #include +#include #include // LOVE #include "common/config.h" #include "common/Exception.h" #include "thread/threads.h" +#include "audio/Source.h" // OpenAL #ifdef LOVE_APPLE_USE_FRAMEWORKS @@ -78,35 +80,23 @@ public: void update(); - int getSourceCount() const; + int getActiveSourceCount() const; int getMaxSources() const; - bool play(Source *source, ALuint &out); - void stop(); - void stop(Source *source); - void pause(); - void pause(Source *source); - void resume(); - void resume(Source *source); - void rewind(); - void rewind(Source *source); - void softRewind(Source *source); - void seek(Source *source, float offset, void *unit); - float tell(Source *source, void *unit); - double getDuration(Source *source, void *unit); - private: + friend class Source; + LOVE_WARN_UNUSED thread::Lock lock(); + std::vector getPlayingSources(); + /** * Makes the specified OpenAL source available for use. * @param source The OpenAL source. **/ - void release(Source *source); - - ALuint findi(const Source *source) const; + bool releaseSource(Source *source, bool stop = true); + bool assignSource(Source *source, ALuint &out, char &wasPlaying); bool findSource(Source *source, ALuint &out); - bool removeSource(Source *source); // Maximum possible number of OpenAL sources the pool attempts to generate. static const int MAX_SOURCES = 64; diff --git a/love/src/jni/love/src/modules/audio/openal/RecordingDevice.cpp b/love/src/jni/love/src/modules/audio/openal/RecordingDevice.cpp new file mode 100644 index 00000000..26a2fb29 --- /dev/null +++ b/love/src/jni/love/src/modules/audio/openal/RecordingDevice.cpp @@ -0,0 +1,152 @@ +/** + * Copyright (c) 2006-2018 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#include "RecordingDevice.h" +#include "Audio.h" +#include "sound/Sound.h" + +namespace love +{ +namespace audio +{ +namespace openal +{ + +#define soundInstance() (Module::getInstance(Module::M_SOUND)) + +class InvalidFormatException : public love::Exception +{ +public: + + InvalidFormatException(int channels, int bitdepth) + : Exception("Recording %d channels with %d bits per sample is not supported.", channels, bitdepth) + { + } + +}; + +RecordingDevice::RecordingDevice(const char *name) + : name(name) +{ +} + +RecordingDevice::~RecordingDevice() +{ + stop(); +} + +bool RecordingDevice::start(int samples, int sampleRate, int bitDepth, int channels) +{ + ALenum format = Audio::getFormat(bitDepth, channels); + if (format == AL_NONE) + throw InvalidFormatException(channels, bitDepth); + + if (samples <= 0) + throw love::Exception("Invalid number of samples."); + + if (sampleRate <= 0) + throw love::Exception("Invalid sample rate."); + + if (isRecording()) + stop(); + + device = alcCaptureOpenDevice(name.c_str(), sampleRate, format, samples); + if (device == nullptr) + return false; + + alcCaptureStart(device); + + this->samples = samples; + this->sampleRate = sampleRate; + this->bitDepth = bitDepth; + this->channels = channels; + + return true; +} + +void RecordingDevice::stop() +{ + if (!isRecording()) + return; + + alcCaptureStop(device); + alcCaptureCloseDevice(device); + device = nullptr; +} + +love::sound::SoundData *RecordingDevice::getData() +{ + if (!isRecording()) + return nullptr; + + int samples = getSampleCount(); + if (samples == 0) + return nullptr; + + love::sound::SoundData *soundData = soundInstance()->newSoundData(samples, sampleRate, bitDepth, channels); + + alcCaptureSamples(device, soundData->getData(), samples); + + return soundData; +} + +int RecordingDevice::getSampleCount() const +{ + if (!isRecording()) + return 0; + + ALCint samples; + alcGetIntegerv(device, ALC_CAPTURE_SAMPLES, sizeof(ALCint), &samples); + return (int)samples; +} + +int RecordingDevice::getMaxSamples() const +{ + return samples; +} + +int RecordingDevice::getSampleRate() const +{ + return sampleRate; +} + +int RecordingDevice::getBitDepth() const +{ + return bitDepth; +} + +int RecordingDevice::getChannelCount() const +{ + return channels; +} + +const char *RecordingDevice::getName() const +{ + return name.c_str(); +} + +bool RecordingDevice::isRecording() const +{ + return device != nullptr; +} + +} //openal +} //audio +} //love diff --git a/love/src/jni/love/src/modules/audio/openal/RecordingDevice.h b/love/src/jni/love/src/modules/audio/openal/RecordingDevice.h new file mode 100644 index 00000000..19ed6a2c --- /dev/null +++ b/love/src/jni/love/src/modules/audio/openal/RecordingDevice.h @@ -0,0 +1,82 @@ +/** + * Copyright (c) 2006-2018 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#ifndef LOVE_AUDIO_OPENAL_RECORDING_DEVICE_H +#define LOVE_AUDIO_OPENAL_RECORDING_DEVICE_H + +#include "common/config.h" + +#ifdef LOVE_APPLE_USE_FRAMEWORKS +#ifdef LOVE_IOS +#include +#include +#else +#include +#include +#endif +#else +#include +#include +#endif + +#include "audio/RecordingDevice.h" +#include "sound/SoundData.h" + +namespace love +{ +namespace audio +{ +namespace openal +{ + +class RecordingDevice : public love::audio::RecordingDevice +{ +public: + + RecordingDevice(const char *name); + virtual ~RecordingDevice(); + virtual bool start(int samples, int sampleRate, int bitDepth, int channels); + virtual void stop(); + virtual love::sound::SoundData *getData(); + virtual const char *getName() const; + virtual int getSampleCount() const; + virtual int getMaxSamples() const; + virtual int getSampleRate() const; + virtual int getBitDepth() const; + virtual int getChannelCount() const; + virtual bool isRecording() const; + +private: + + int samples = DEFAULT_SAMPLES; + int sampleRate = DEFAULT_SAMPLE_RATE; + int bitDepth = DEFAULT_BIT_DEPTH; + int channels = DEFAULT_CHANNELS; + + std::string name; + ALCdevice *device = nullptr; + +}; //RecordingDevice + +} //openal +} //audio +} //love + +#endif //LOVE_AUDIO_OPENAL_RECORDING_DEVICE_H diff --git a/love/src/jni/love/src/modules/audio/openal/Source.cpp b/love/src/jni/love/src/modules/audio/openal/Source.cpp index 99f3b792..f8caddf9 100644 --- a/love/src/jni/love/src/modules/audio/openal/Source.cpp +++ b/love/src/jni/love/src/modules/audio/openal/Source.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2016 LOVE Development Team + * Copyright (c) 2006-2018 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -19,14 +19,19 @@ **/ #include "Source.h" +#include "Filter.h" #include "Pool.h" +#include "Audio.h" #include "common/math.h" // STD #include -#include #include +#define audiomodule() (Module::getInstance