diff options
author | Campbell Barton <ideasman42@gmail.com> | 2017-04-24 15:11:05 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2017-04-24 15:11:05 +0300 |
commit | 2010dbe8a59e80775219fb5162f3c2f5dfd24e04 (patch) | |
tree | c816bd1504d011b3afac38922bc67e88b76a9505 | |
parent | f93f4169cbfb2e3d5583d1bca5aa8466f37393dc (diff) | |
parent | aff30aaf2dddeb30ae43ec45ff12073a73ffcdc0 (diff) |
Merge branch 'master' into blender2.8
29 files changed, 780 insertions, 553 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index c7209ed4819..e1c1a5eccbb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -561,113 +561,7 @@ endif() # Apple if(APPLE) - # require newer cmake on osx because of version handling, - # older cmake cannot handle 2 digit subversion! - cmake_minimum_required(VERSION 3.0.0) - - if(NOT CMAKE_OSX_ARCHITECTURES) - set(CMAKE_OSX_ARCHITECTURES x86_64 CACHE STRING - "Choose the architecture you want to build Blender for: i386, x86_64 or ppc" - FORCE) - endif() - - if(NOT DEFINED OSX_SYSTEM) - execute_process( - COMMAND xcodebuild -version -sdk macosx SDKVersion - OUTPUT_VARIABLE OSX_SYSTEM - OUTPUT_STRIP_TRAILING_WHITESPACE) - endif() - - # workaround for incorrect cmake xcode lookup for developer previews - XCODE_VERSION does not - # take xcode-select path into account but would always look into /Applications/Xcode.app - # while dev versions are named Xcode<version>-DP<preview_number> - execute_process( - COMMAND xcode-select --print-path - OUTPUT_VARIABLE XCODE_CHECK OUTPUT_STRIP_TRAILING_WHITESPACE) - string(REPLACE "/Contents/Developer" "" XCODE_BUNDLE ${XCODE_CHECK}) # truncate to bundlepath in any case - - if(${CMAKE_GENERATOR} MATCHES "Xcode") - - # earlier xcode has no bundled developer dir, no sense in getting xcode path from - if(${XCODE_VERSION} VERSION_GREATER 4.2) - # reduce to XCode name without dp extension - string(SUBSTRING "${XCODE_CHECK}" 14 6 DP_NAME) - if(${DP_NAME} MATCHES Xcode5) - set(XCODE_VERSION 5) - endif() - endif() - - ##### cmake incompatibility with xcode 4.3 and higher ##### - if(${XCODE_VERSION} MATCHES '') # cmake fails due looking for xcode in the wrong path, thus will be empty var - message(FATAL_ERROR "Xcode 4.3 and higher must be used with cmake 2.8-8 or higher") - endif() - ### end cmake incompatibility with xcode 4.3 and higher ### - - if(${XCODE_VERSION} VERSION_EQUAL 4 OR ${XCODE_VERSION} VERSION_GREATER 4 AND ${XCODE_VERSION} VERSION_LESS 4.3) - # Xcode 4 defaults to the Apple LLVM Compiler. - # Override the default compiler selection because Blender only compiles with gcc up to xcode 4.2 - set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvmgcc42") - message(STATUS "Setting compiler to: " ${CMAKE_XCODE_ATTRIBUTE_GCC_VERSION}) - endif() - else() # unix makefile generator does not fill XCODE_VERSION var, so we get it with a command - execute_process(COMMAND xcodebuild -version OUTPUT_VARIABLE XCODE_VERS_BUILD_NR) - string(SUBSTRING "${XCODE_VERS_BUILD_NR}" 6 3 XCODE_VERSION) # truncate away build-nr - unset(XCODE_VERS_BUILD_NR) - endif() - - message(STATUS "Detected OS X ${OSX_SYSTEM} and Xcode ${XCODE_VERSION} at ${XCODE_BUNDLE}") - - if(${XCODE_VERSION} VERSION_LESS 4.3) - # use guaranteed existing sdk - set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX${OSX_SYSTEM}.sdk CACHE PATH "" FORCE) - else() - # note: xcode-select path could be ambigous, - # cause /Applications/Xcode.app/Contents/Developer or /Applications/Xcode.app would be allowed - # so i use a selfcomposed bundlepath here - set(OSX_SYSROOT_PREFIX ${XCODE_BUNDLE}/Contents/Developer/Platforms/MacOSX.platform) - message(STATUS "OSX_SYSROOT_PREFIX: " ${OSX_SYSROOT_PREFIX}) - set(OSX_DEVELOPER_PREFIX /Developer/SDKs/MacOSX${OSX_SYSTEM}.sdk) # use guaranteed existing sdk - set(CMAKE_OSX_SYSROOT ${OSX_SYSROOT_PREFIX}/${OSX_DEVELOPER_PREFIX} CACHE PATH "" FORCE) - if(${CMAKE_GENERATOR} MATCHES "Xcode") - # to silence sdk not found warning, just overrides CMAKE_OSX_SYSROOT - set(CMAKE_XCODE_ATTRIBUTE_SDKROOT macosx${OSX_SYSTEM}) - endif() - - # QuickTime framework is no longer available in SDK 10.12+ - if(WITH_CODEC_QUICKTIME AND ${OSX_SYSTEM} VERSION_GREATER 10.11) - set(WITH_CODEC_QUICKTIME OFF) - message(STATUS "QuickTime not supported by SDK ${OSX_SYSTEM}, disabling WITH_CODEC_QUICKTIME") - endif() - endif() - - if(OSX_SYSTEM MATCHES 10.9) - # make sure syslibs and headers are looked up in sdk ( expecially for 10.9 openGL atm. ) - set(CMAKE_FIND_ROOT_PATH ${CMAKE_OSX_SYSROOT}) - endif() - - if(WITH_CXX11) - # 10.9 is our min. target, if you use higher sdk, weak linking happens - if(CMAKE_OSX_DEPLOYMENT_TARGET) - if(${CMAKE_OSX_DEPLOYMENT_TARGET} VERSION_LESS 10.9) - message(STATUS "Setting deployment target to 10.9, lower versions are incompatible with WITH_CXX11") - set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "" FORCE) - endif() - else() - set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "" FORCE) - endif() - else() - if(NOT CMAKE_OSX_DEPLOYMENT_TARGET) - # 10.6 is our min. target, if you use higher sdk, weak linking happens - set(CMAKE_OSX_DEPLOYMENT_TARGET "10.6" CACHE STRING "" FORCE) - endif() - endif() - - if(NOT ${CMAKE_GENERATOR} MATCHES "Xcode") - # force CMAKE_OSX_DEPLOYMENT_TARGET for makefiles, will not work else ( cmake bug ? ) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") - add_definitions("-DMACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}") - endif() + include(platform_apple_xcode) endif() @@ -841,6 +735,10 @@ if(WITH_AUDASPACE) endif() endif() +if(APPLE) + apple_check_quicktime() +endif() + #----------------------------------------------------------------------------- # Check for valid directories # ... a partial checkout may cause this. diff --git a/build_files/cmake/config/blender_full.cmake b/build_files/cmake/config/blender_full.cmake index cb18500c7ca..bd8a2dbaf2c 100644 --- a/build_files/cmake/config/blender_full.cmake +++ b/build_files/cmake/config/blender_full.cmake @@ -75,4 +75,8 @@ elseif(APPLE) set(WITH_JACK ON CACHE BOOL "" FORCE) set(WITH_CODEC_QUICKTIME ON CACHE BOOL "" FORCE) set(WITH_OPENSUBDIV OFF CACHE BOOL "" FORCE) + set(WITH_CODEC_QUICKTIME ON CACHE BOOL "" FORCE) + + include("${CMAKE_SOURCE_DIR}/build_files/cmake/platform/platform_apple_xcode.cmake") + apple_check_quicktime() endif() diff --git a/build_files/cmake/config/blender_release.cmake b/build_files/cmake/config/blender_release.cmake index 050db91e75e..42e8c111714 100644 --- a/build_files/cmake/config/blender_release.cmake +++ b/build_files/cmake/config/blender_release.cmake @@ -76,4 +76,8 @@ elseif(APPLE) set(WITH_JACK ON CACHE BOOL "" FORCE) set(WITH_CODEC_QUICKTIME ON CACHE BOOL "" FORCE) set(WITH_OPENSUBDIV OFF CACHE BOOL "" FORCE) + set(WITH_CODEC_QUICKTIME ON CACHE BOOL "" FORCE) + + include("${CMAKE_SOURCE_DIR}/build_files/cmake/platform/platform_apple_xcode.cmake") + apple_check_quicktime() endif() diff --git a/build_files/cmake/platform/platform_apple_xcode.cmake b/build_files/cmake/platform/platform_apple_xcode.cmake new file mode 100644 index 00000000000..e76a7783939 --- /dev/null +++ b/build_files/cmake/platform/platform_apple_xcode.cmake @@ -0,0 +1,135 @@ +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2016, Blender Foundation +# All rights reserved. +# +# Contributor(s): Jacques Beaurain. +# +# ***** END GPL LICENSE BLOCK ***** + +# Xcode and system configuration for Apple. + +# require newer cmake on osx because of version handling, +# older cmake cannot handle 2 digit subversion! +cmake_minimum_required(VERSION 3.0.0) + +if(NOT CMAKE_OSX_ARCHITECTURES) + set(CMAKE_OSX_ARCHITECTURES x86_64 CACHE STRING + "Choose the architecture you want to build Blender for: i386, x86_64 or ppc" + FORCE) +endif() + +if(NOT DEFINED OSX_SYSTEM) + execute_process( + COMMAND xcodebuild -version -sdk macosx SDKVersion + OUTPUT_VARIABLE OSX_SYSTEM + OUTPUT_STRIP_TRAILING_WHITESPACE) +endif() + +# workaround for incorrect cmake xcode lookup for developer previews - XCODE_VERSION does not +# take xcode-select path into account but would always look into /Applications/Xcode.app +# while dev versions are named Xcode<version>-DP<preview_number> +execute_process( + COMMAND xcode-select --print-path + OUTPUT_VARIABLE XCODE_CHECK OUTPUT_STRIP_TRAILING_WHITESPACE) +string(REPLACE "/Contents/Developer" "" XCODE_BUNDLE ${XCODE_CHECK}) # truncate to bundlepath in any case + +if(${CMAKE_GENERATOR} MATCHES "Xcode") + + # earlier xcode has no bundled developer dir, no sense in getting xcode path from + if(${XCODE_VERSION} VERSION_GREATER 4.2) + # reduce to XCode name without dp extension + string(SUBSTRING "${XCODE_CHECK}" 14 6 DP_NAME) + if(${DP_NAME} MATCHES Xcode5) + set(XCODE_VERSION 5) + endif() + endif() + + ##### cmake incompatibility with xcode 4.3 and higher ##### + if(${XCODE_VERSION} MATCHES '') # cmake fails due looking for xcode in the wrong path, thus will be empty var + message(FATAL_ERROR "Xcode 4.3 and higher must be used with cmake 2.8-8 or higher") + endif() + ### end cmake incompatibility with xcode 4.3 and higher ### + + if(${XCODE_VERSION} VERSION_EQUAL 4 OR ${XCODE_VERSION} VERSION_GREATER 4 AND ${XCODE_VERSION} VERSION_LESS 4.3) + # Xcode 4 defaults to the Apple LLVM Compiler. + # Override the default compiler selection because Blender only compiles with gcc up to xcode 4.2 + set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvmgcc42") + message(STATUS "Setting compiler to: " ${CMAKE_XCODE_ATTRIBUTE_GCC_VERSION}) + endif() +else() # unix makefile generator does not fill XCODE_VERSION var, so we get it with a command + execute_process(COMMAND xcodebuild -version OUTPUT_VARIABLE XCODE_VERS_BUILD_NR) + string(SUBSTRING "${XCODE_VERS_BUILD_NR}" 6 3 XCODE_VERSION) # truncate away build-nr + unset(XCODE_VERS_BUILD_NR) +endif() + +message(STATUS "Detected OS X ${OSX_SYSTEM} and Xcode ${XCODE_VERSION} at ${XCODE_BUNDLE}") + +if(${XCODE_VERSION} VERSION_LESS 4.3) + # use guaranteed existing sdk + set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX${OSX_SYSTEM}.sdk CACHE PATH "" FORCE) +else() + # note: xcode-select path could be ambigous, + # cause /Applications/Xcode.app/Contents/Developer or /Applications/Xcode.app would be allowed + # so i use a selfcomposed bundlepath here + set(OSX_SYSROOT_PREFIX ${XCODE_BUNDLE}/Contents/Developer/Platforms/MacOSX.platform) + message(STATUS "OSX_SYSROOT_PREFIX: " ${OSX_SYSROOT_PREFIX}) + set(OSX_DEVELOPER_PREFIX /Developer/SDKs/MacOSX${OSX_SYSTEM}.sdk) # use guaranteed existing sdk + set(CMAKE_OSX_SYSROOT ${OSX_SYSROOT_PREFIX}/${OSX_DEVELOPER_PREFIX} CACHE PATH "" FORCE) + if(${CMAKE_GENERATOR} MATCHES "Xcode") + # to silence sdk not found warning, just overrides CMAKE_OSX_SYSROOT + set(CMAKE_XCODE_ATTRIBUTE_SDKROOT macosx${OSX_SYSTEM}) + endif() +endif() + +if(OSX_SYSTEM MATCHES 10.9) + # make sure syslibs and headers are looked up in sdk ( expecially for 10.9 openGL atm. ) + set(CMAKE_FIND_ROOT_PATH ${CMAKE_OSX_SYSROOT}) +endif() + +if(WITH_CXX11) + # 10.9 is our min. target, if you use higher sdk, weak linking happens + if(CMAKE_OSX_DEPLOYMENT_TARGET) + if(${CMAKE_OSX_DEPLOYMENT_TARGET} VERSION_LESS 10.9) + message(STATUS "Setting deployment target to 10.9, lower versions are incompatible with WITH_CXX11") + set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "" FORCE) + endif() + else() + set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "" FORCE) + endif() +else() + if(NOT CMAKE_OSX_DEPLOYMENT_TARGET) + # 10.6 is our min. target, if you use higher sdk, weak linking happens + set(CMAKE_OSX_DEPLOYMENT_TARGET "10.6" CACHE STRING "" FORCE) + endif() +endif() + +if(NOT ${CMAKE_GENERATOR} MATCHES "Xcode") + # force CMAKE_OSX_DEPLOYMENT_TARGET for makefiles, will not work else ( cmake bug ? ) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") + add_definitions("-DMACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}") +endif() + +macro(apple_check_quicktime) + # QuickTime framework is no longer available in SDK 10.12+ + if(WITH_CODEC_QUICKTIME AND ${OSX_SYSTEM} VERSION_GREATER 10.11) + set(WITH_CODEC_QUICKTIME OFF CACHE BOOL "" FORCE) + message(STATUS "QuickTime not supported by SDK ${OSX_SYSTEM}, disabling WITH_CODEC_QUICKTIME") + endif() +endmacro() + diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index 58f6140970d..3fe7572e4ce 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -258,7 +258,7 @@ ccl_device_forceinline float3 reflection_color(const MicrofacetBsdf *bsdf, float ccl_device_forceinline float D_GTR1(float NdotH, float alpha) { - if (alpha >= 1.0f) return M_1_PI_F; + if(alpha >= 1.0f) return M_1_PI_F; float alpha2 = alpha*alpha; float t = 1.0f + (alpha2 - 1.0f) * NdotH*NdotH; return (alpha2 - 1.0f) / (M_PI_F * logf(alpha2) * t); diff --git a/intern/locale/CMakeLists.txt b/intern/locale/CMakeLists.txt index 6896702fcbf..cbc75d1ab1f 100644 --- a/intern/locale/CMakeLists.txt +++ b/intern/locale/CMakeLists.txt @@ -60,22 +60,3 @@ if(WITH_INTERNATIONAL) endif() blender_add_lib(bf_intern_locale "${SRC}" "${INC}" "${INC_SYS}") - -# ----------------------------------------------------------------------------- -# Build msgfmt executable - -if(CMAKE_COMPILER_IS_GNUCC) - # workaroud ld.gold linker bug - string(REPLACE "-fuse-ld=gold" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") -endif() - -set(MSFFMT_SRC - msgfmt.cc -) -add_executable(msgfmt ${MSFFMT_SRC}) - -if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND (NOT (CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4))) - # needed for clang 3.4+ - target_link_libraries(msgfmt ${PLATFORM_LINKLIBS}) -endif() - diff --git a/intern/locale/msgfmt.cc b/intern/locale/msgfmt.cc deleted file mode 100644 index 02c58ebc5bc..00000000000 --- a/intern/locale/msgfmt.cc +++ /dev/null @@ -1,374 +0,0 @@ -// Written by Sergey Sharybin <sergey.vfx@gmail.com> -// Added support for contexts -// -// Based on Python script msgfmt.py from Python source -// code tree, which was written by Written by -// Martin v. Löwis <loewis@informatik.hu-berlin.de> -// -// Generate binary message catalog from textual translation description. -// -// This program converts a textual Uniforum-style message catalog (.po file) into -// a binary GNU catalog (.mo file). This is essentially the same function as the -// GNU msgfmt program, however, it is a simpler implementation. -// -// Usage: msgfmt input.po output.po - -#include <algorithm> -#include <cctype> -#include <fstream> -#include <functional> -#include <iostream> -#include <map> -#include <stdlib.h> -#include <string> -#include <vector> - -namespace { - -std::map<std::string, std::string> MESSAGES; - -bool starts_with(const std::string &str, - const std::string &prefix) { - const size_t prefix_length = prefix.length(); - if (prefix_length == 0) { - return true; - } - // TODO(sergey): Could be optimized if we calculate str.length() - // to maximum of prefix_length characters. - if (prefix_length > str.length()) { - return false; - } else { - return str.compare(0, prefix_length, prefix) == 0; - } -} - -std::string trim(const std::string &str) { - std::string result = str; - result.erase(0, result.find_first_not_of(" \t\r\n")); - result.erase(result.find_last_not_of(" \t\r\n") + 1); - return result; -} - -std::string unescape(const std::string &str) { - std::string result; - const size_t str_length = str.length(); - size_t i = 0; - while (i < str_length) { - char current_char = str[i++]; - if (current_char == '\\' && i < str_length - 1) { - char next_char = str[i++]; - if (next_char == '\\') { - current_char = '\\'; - } else if (next_char == 'n') { - current_char = '\n'; - } else if (next_char == 't') { - current_char = '\t'; - } else { - current_char = next_char; - } - } - result += current_char; - } - - const size_t result_length = result.length(); - if (result[0] == '"' && result[result_length - 1] == '"') { - result = result.substr(1, result_length - 2); - } - - return result; -} - -// Add a non-fuzzy translation to the dictionary. -void add(const std::string &msgctxt, - const std::string &msgid, - const std::string &msgstr, - bool fuzzy) { - if (fuzzy == false && msgstr.empty() == false) { - if (msgctxt.empty()) { - MESSAGES[msgid] = msgstr; - } else { - MESSAGES[msgctxt + (char)0x04 + msgid] = msgstr; - } - } -} - -template<typename TKey, typename TValue> -void get_keys(std::map<TKey, TValue> map, - std::vector<TKey> *keys) { - keys->reserve(map.size()); - for (typename std::map<TKey, TValue>::iterator it = map.begin(); - it != map.end(); - it++) { - keys->push_back(it->first); - } -} - -std::string intToBytes(int value) { - std::string result; - for (unsigned int i = 0; i < sizeof(value); i++) { - result += (unsigned char) ((value >> (i * 8)) & 0xff); - } - return result; -} - -typedef enum { - SECTION_NONE = 0, - SECTION_CTX = 1, - SECTION_ID = 2, - SECTION_STR = 3 -} eSectionType; - -struct Offset { - unsigned int o1, l1, o2, l2; -}; - -// Return the generated output. -std::string generate(void) { - // The keys are sorted in the .mo file - std::vector<std::string> keys; - - // Get list of sorted keys. - get_keys(MESSAGES, &keys); - std::sort(keys.begin(), keys.end()); - - std::vector<Offset> offsets; - offsets.reserve(keys.size()); - std::string ids = "", strs = ""; - for (std::vector<std::string>::iterator it = keys.begin(); - it != keys.end(); - it++) { - std::string &id = *it; - // For each string, we need size and file offset. Each string is NUL - // terminated; the NUL does not count into the size. - Offset offset = {(unsigned int) ids.size(), - (unsigned int) id.size(), - (unsigned int) strs.size(), - (unsigned int) MESSAGES[id].size()}; - offsets.push_back(offset); - ids += id + '\0'; - strs += MESSAGES[id] + '\0'; - } - - // The header is 7 32-bit unsigned integers. We don't use hash tables, so - // the keys start right after the index tables. - // translated string. - int keystart = 7 * 4 + 16 * keys.size(); - // and the values start after the keys - int valuestart = keystart + ids.size(); - std::vector<int> koffsets; - std::vector<int> voffsets; - koffsets.reserve(offsets.size() * 2); - voffsets.reserve(offsets.size() * 2); - // The string table first has the list of keys, then the list of values. - // Each entry has first the size of the string, then the file offset. - for (std::vector<Offset>::iterator it = offsets.begin(); - it != offsets.end(); - it++) { - Offset &offset = *it; - koffsets.push_back(offset.l1); - koffsets.push_back(offset.o1 + keystart); - voffsets.push_back(offset.l2); - voffsets.push_back(offset.o2 + valuestart); - } - - std::vector<int> all_offsets; - all_offsets.reserve(koffsets.size() + voffsets.size()); - all_offsets.insert(all_offsets.end(), koffsets.begin(), koffsets.end()); - all_offsets.insert(all_offsets.end(), voffsets.begin(), voffsets.end()); - - std::string output = ""; - output += intToBytes(0x950412de); // Magic - output += intToBytes(0x0); // Version - output += intToBytes(keys.size()); // # of entries - output += intToBytes(7 * 4); // start of key index - output += intToBytes(7 * 4 + keys.size() * 8); // start of value index - output += intToBytes(0); // Size of hash table - output += intToBytes(0); // Offset of hash table - - for (std::vector<int>::iterator it = all_offsets.begin(); - it != all_offsets.end(); - it++) { - int offset = *it; - output += intToBytes(offset); - } - - output += ids; - output += strs; - - return output; -} - -void make(const char *input_file_name, - const char *output_file_name) { - std::map<std::string, std::string> messages; - - // Start off assuming Latin-1, so everything decodes without failure, - // until we know the exact encoding. - // TODO(sergey): Support encoding. - // const char *encoding = "latin-1"; - - eSectionType section = SECTION_NONE; - bool fuzzy = false; - bool is_plural = false; - std::string msgctxt, msgid, msgstr; - - std::ifstream input_file_stream(input_file_name); - - // Parse the catalog. - int lno = 0; - for (std::string l; getline(input_file_stream, l); ) { - lno++; - // If we get a comment line after a msgstr, this is a new entry. - if (l[0] == '#' && section == SECTION_STR) { - add(msgctxt, msgid, msgstr, fuzzy); - section = SECTION_NONE; - msgctxt = ""; - fuzzy = false; - } - // Record a fuzzy mark. - if (starts_with(l, "#,") && l.find("fuzzy") != std::string::npos) { - fuzzy = true; - } - // Skip comments - if (l[0] == '#') { - continue; - } - // Now we are in a msgid section, output previous section. - if (starts_with(l, "msgctxt")) { - if (section == SECTION_STR) { - add(msgctxt, msgid, msgstr, fuzzy); - } - section = SECTION_CTX; - l = l.substr(7, l.size() - 7); - msgctxt = msgid = msgstr = ""; - } - else if (starts_with(l, "msgid") && !starts_with(l, "msgid_plural")) { - if (section == SECTION_STR) { - add(msgctxt, msgid, msgstr, fuzzy); - msgctxt = ""; - if (msgid == "") { -#if 0 - // See whether there is an encoding declaration. - p = HeaderParser(); - charset = p.parsestr(msgstr.decode(encoding)).get_content_charset(); - if (charset) { - encoding = charset; - } -#else - // Not ported to C++ yet. - std::cerr << "Encoding declarations are not supported yet.\n" - << std::endl; - abort(); -#endif - } - } - section = SECTION_ID; - l = l.substr(5, l.size() - 5); - msgid = msgstr = ""; - is_plural = false; - } else if (starts_with(l, "msgid_plural")) { - // This is a message with plural forms. - if (section != SECTION_ID) { - std::cerr << "msgid_plural not preceeded by msgid on" - << input_file_name << ":" - << lno - << std::endl; - abort(); - } - l = l.substr(12, l.size() - 12); - msgid += '\0'; // separator of singular and plural - is_plural = true; - } else if (starts_with(l, "msgstr")) { - // Now we are in a msgstr section - section = SECTION_STR; - if (starts_with(l, "msgstr[")) { - if (is_plural == false) { - std::cerr << "plural without msgid_plural on " - << input_file_name << ":" - << lno - << std::endl; - abort(); - } - int bracket_position = l.find(']'); - if (bracket_position == std::string::npos) { - std::cerr << "Syntax error on " - << input_file_name << ":" - << lno - << std::endl; - abort(); - } - l = l.substr(bracket_position, l.size() - bracket_position); - if (msgstr != "") { - msgstr += '\0'; // Separator of the various plural forms; - } - } else { - if (is_plural) { - std::cerr << "indexed msgstr required for plural on " - << input_file_name << ":" - << lno - << std::endl; - abort(); - } - l = l.substr(6, l.size() - 6); - } - } - // Skip empty lines. - l = trim(l); - if (l.empty()) { - if (section == SECTION_STR) { - add(msgctxt, msgid, msgstr, fuzzy); - msgctxt = msgid = msgstr = ""; - section = SECTION_NONE; - fuzzy = false; - } - continue; - } - l = unescape(l); - if (section == SECTION_CTX) { - // TODO(sergey): Support encoding. - // msgid += l.encode(encoding); - msgctxt += l; - } - else if (section == SECTION_ID) { - // TODO(sergey): Support encoding. - // msgid += l.encode(encoding); - msgid += l; - } else if (section == SECTION_STR) { - // TODO(sergey): Support encoding. - // msgstr += l.encode(encoding) - msgstr += l; - } else { - std::cerr << "Syntax error on " - << input_file_name << ":" - << lno - << std::endl; - abort(); - } - // Add last entry - if (section == SECTION_STR) { - add(msgctxt, msgid, msgstr, fuzzy); - } - } - - // Compute output - std::string output = generate(); - - std::ofstream output_file_stream(output_file_name, - std::ios::out | std::ios::binary); - output_file_stream << output; -} - -} // namespace - -int main(int argc, char **argv) { - if (argc != 3) { - printf("Usage: %s <input.po> <output.mo>\n", argv[0]); - return EXIT_FAILURE; - } - const char *input_file = argv[1]; - const char *output_file = argv[2]; - - make(input_file, output_file); - - return EXIT_SUCCESS; -} @@ -1,7 +1,7 @@ @echo off REM This batch file does an out-of-source CMake build in ../build_windows REM This is for users who like to configure & build Blender with a single command. - +setlocal EnableDelayedExpansion setlocal ENABLEEXTENSIONS set BLENDER_DIR=%~dp0 set BLENDER_DIR_NOSPACES=%BLENDER_DIR: =% @@ -12,10 +12,12 @@ if not "%BLENDER_DIR%"=="%BLENDER_DIR_NOSPACES%" ( set BUILD_DIR=%BLENDER_DIR%..\build_windows set BUILD_TYPE=Release rem reset all variables so they do not get accidentally get carried over from previous builds +set BUILD_DIR_OVERRRIDE= set BUILD_CMAKE_ARGS= set BUILD_ARCH= set BUILD_VS_VER= set BUILD_VS_YEAR= +set BUILD_NGE= set KEY_NAME= set MSBUILD_PLATFORM= set MUST_CLEAN= @@ -35,6 +37,12 @@ if NOT "%1" == "" ( if "%1" == "debug" ( set BUILD_TYPE=Debug REM Build Configurations + ) else if "%1" == "noge" ( + set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -DWITH_GAMEENGINE=OFF -DWITH_PLAYER=OFF + set BUILD_NGE=_noge + ) else if "%1" == "builddir" ( + set BUILD_DIR_OVERRRIDE="%BLENDER_DIR%..\%2" + shift /1 ) else if "%1" == "with_tests" ( set TESTS_CMAKE_ARGS=-DWITH_GTESTS=On ) else if "%1" == "full" ( @@ -185,8 +193,10 @@ if %ERRORLEVEL% NEQ 0 ( ) -set BUILD_DIR=%BUILD_DIR%_%TARGET%_%BUILD_ARCH%_vc%BUILD_VS_VER%_%BUILD_TYPE% - +set BUILD_DIR=%BUILD_DIR%_%TARGET%%BUILD_NGE%_%BUILD_ARCH%_vc%BUILD_VS_VER%_%BUILD_TYPE% +if NOT "%BUILD_DIR_OVERRRIDE%"=="" ( + set BUILD_DIR=%BUILD_DIR_OVERRRIDE% +) where /Q cmake if %ERRORLEVEL% NEQ 0 ( @@ -287,8 +297,10 @@ goto EOF echo. echo Configuration options echo - with_tests ^(enable building unit tests^) + echo - noge ^(disable building game enginge and player^) echo - debug ^(Build an unoptimized debuggable build^) echo - packagename [newname] ^(override default cpack package name^) + echo - buildir [newdir] ^(override default build folder^) echo - x86 ^(override host auto-detect and build 32 bit code^) echo - x64 ^(override host auto-detect and build 64 bit code^) echo - 2013 ^(build with visual studio 2013^) diff --git a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py index 949678b2fc0..316415555ab 100644 --- a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py +++ b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py @@ -357,6 +357,7 @@ class SpellChecker: "bezier", "beziers", "bicubic", "bilinear", + "bindpose", "binormal", "blackpoint", "whitepoint", "blinn", @@ -364,6 +365,7 @@ class SpellChecker: "catadioptric", "centroid", "chrominance", + "clearcoat", "codec", "codecs", "collada", "compositing", diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c index eadeeb2d86a..27f7cac2a8e 100644 --- a/source/blender/blenkernel/intern/idprop.c +++ b/source/blender/blenkernel/intern/idprop.c @@ -979,7 +979,7 @@ IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char * prop->len = prop->totallen = val->array.len; break; } - printf("%s: bad array type.\n",__func__); + printf("%s: bad array type.\n", __func__); return NULL; } case IDP_STRING: diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c index 4e17e04dcb3..24ddf67a815 100644 --- a/source/blender/blenkernel/intern/library_query.c +++ b/source/blender/blenkernel/intern/library_query.c @@ -998,6 +998,7 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call for (bGPDlayer *gp_layer = gpencil->layers.first; gp_layer; gp_layer = gp_layer->next) { CALLBACK_INVOKE(gp_layer->parent, IDWALK_CB_NOP); } + break; } /* Nothing needed for those... */ diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index 0d0055113b7..c725e884b58 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -1026,7 +1026,7 @@ static bool loop_split_generator_check_cyclic_smooth_fan( BLI_assert(!BLI_BITMAP_TEST(skip_loops, mlfan_vert_index)); BLI_BITMAP_ENABLE(skip_loops, mlfan_vert_index); - while(true) { + while (true) { /* Find next loop of the smooth fan. */ loop_manifold_fan_around_vert_next( mloops, mpolys, loop_to_poly, e2lfan_curr, mv_pivot_index, diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c index 9a70c42418f..844edd87c37 100644 --- a/source/blender/blenkernel/intern/object_dupli.c +++ b/source/blender/blenkernel/intern/object_dupli.c @@ -186,8 +186,9 @@ static DupliObject *make_dupli(const DupliContext *ctx, dob->random_id = BLI_hash_string(dob->ob->id.name + 2); if (dob->persistent_id[0] != INT_MAX) { - for(i = 0; i < MAX_DUPLI_RECUR*2; i++) + for (i = 0; i < MAX_DUPLI_RECUR * 2; i++) { dob->random_id = BLI_hash_int_2d(dob->random_id, (unsigned int)dob->persistent_id[i]); + } } else { dob->random_id = BLI_hash_int_2d(dob->random_id, 0); diff --git a/source/blender/blenlib/BLI_dynstr.h b/source/blender/blenlib/BLI_dynstr.h index 7aa1c30e449..b26accc7f78 100644 --- a/source/blender/blenlib/BLI_dynstr.h +++ b/source/blender/blenlib/BLI_dynstr.h @@ -43,11 +43,14 @@ #include "BLI_compiler_attrs.h" struct DynStr; +struct MemArena; /** The abstract DynStr type */ typedef struct DynStr DynStr; DynStr *BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; +DynStr *BLI_dynstr_new_memarena(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT; + void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) ATTR_NONNULL(); void BLI_dynstr_nappend(DynStr *__restrict ds, const char *cstr, int len) ATTR_NONNULL(); @@ -56,8 +59,9 @@ void BLI_dynstr_vappendf(DynStr *__restrict ds, const char *__restrict format int BLI_dynstr_get_len(DynStr *ds) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); char *BLI_dynstr_get_cstring(DynStr *ds) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); - void BLI_dynstr_get_cstring_ex(DynStr *__restrict ds, char *__restrict str) ATTR_NONNULL(); + +void BLI_dynstr_clear(DynStr *ds) ATTR_NONNULL(); void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL(); #endif /* __BLI_DYNSTR_H__ */ diff --git a/source/blender/blenlib/BLI_hash.h b/source/blender/blenlib/BLI_hash.h index 50c7a7f9f0f..e849e5f8f61 100644 --- a/source/blender/blenlib/BLI_hash.h +++ b/source/blender/blenlib/BLI_hash.h @@ -27,7 +27,7 @@ BLI_INLINE unsigned int BLI_hash_int_2d(unsigned int kx, unsigned int ky) { -#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) +#define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k)))) unsigned int a, b, c; @@ -35,13 +35,13 @@ BLI_INLINE unsigned int BLI_hash_int_2d(unsigned int kx, unsigned int ky) a += kx; b += ky; - c ^= b; c -= rot(b,14); - a ^= c; a -= rot(c,11); - b ^= a; b -= rot(a,25); - c ^= b; c -= rot(b,16); - a ^= c; a -= rot(c,4); - b ^= a; b -= rot(a,14); - c ^= b; c -= rot(b,24); + c ^= b; c -= rot(b, 14); + a ^= c; a -= rot(c, 11); + b ^= a; b -= rot(a, 25); + c ^= b; c -= rot(b, 16); + a ^= c; a -= rot(c, 4); + b ^= a; b -= rot(a, 14); + c ^= b; c -= rot(b, 24); return c; @@ -52,9 +52,9 @@ BLI_INLINE unsigned int BLI_hash_string(const char *str) { unsigned int i = 0, c; - while((c = *str++)) + while ((c = *str++)) { i = i * 37 + c; - + } return i; } diff --git a/source/blender/blenlib/intern/BLI_dynstr.c b/source/blender/blenlib/intern/BLI_dynstr.c index ecd4a6e6b09..bce6614beb5 100644 --- a/source/blender/blenlib/intern/BLI_dynstr.c +++ b/source/blender/blenlib/intern/BLI_dynstr.c @@ -35,6 +35,7 @@ #include "MEM_guardedalloc.h" #include "BLI_utildefines.h" +#include "BLI_memarena.h" #include "BLI_string.h" #include "BLI_dynstr.h" @@ -64,6 +65,7 @@ struct DynStrElem { struct DynStr { DynStrElem *elems, *last; int curlen; + MemArena *memarena; }; /***/ @@ -78,11 +80,32 @@ DynStr *BLI_dynstr_new(void) DynStr *ds = MEM_mallocN(sizeof(*ds), "DynStr"); ds->elems = ds->last = NULL; ds->curlen = 0; + ds->memarena = NULL; return ds; } /** + * Create a new DynStr. + * + * \return Pointer to a new DynStr. + */ +DynStr *BLI_dynstr_new_memarena(void) +{ + DynStr *ds = MEM_mallocN(sizeof(*ds), "DynStr"); + ds->elems = ds->last = NULL; + ds->curlen = 0; + ds->memarena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); + + return ds; +} + +BLI_INLINE void *dynstr_alloc(DynStr *__restrict ds, size_t size) +{ + return ds->memarena ? BLI_memarena_alloc(ds->memarena, size) : malloc(size); +} + +/** * Append a c-string to a DynStr. * * \param ds The DynStr to append to. @@ -90,10 +113,10 @@ DynStr *BLI_dynstr_new(void) */ void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) { - DynStrElem *dse = malloc(sizeof(*dse)); + DynStrElem *dse = dynstr_alloc(ds, sizeof(*dse)); int cstrlen = strlen(cstr); - dse->str = malloc(cstrlen + 1); + dse->str = dynstr_alloc(ds, cstrlen + 1); memcpy(dse->str, cstr, cstrlen + 1); dse->next = NULL; @@ -114,10 +137,10 @@ void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) */ void BLI_dynstr_nappend(DynStr *__restrict ds, const char *cstr, int len) { - DynStrElem *dse = malloc(sizeof(*dse)); + DynStrElem *dse = dynstr_alloc(ds, sizeof(*dse)); int cstrlen = BLI_strnlen(cstr, len); - dse->str = malloc(cstrlen + 1); + dse->str = dynstr_alloc(ds, cstrlen + 1); memcpy(dse->str, cstr, cstrlen); dse->str[cstrlen] = '\0'; dse->next = NULL; @@ -296,22 +319,41 @@ char *BLI_dynstr_get_cstring(DynStr *ds) } /** + * Clear the DynStr + * + * \param ds The DynStr to clear. + */ +void BLI_dynstr_clear(DynStr *ds) +{ + if (ds->memarena) { + BLI_memarena_clear(ds->memarena); + } + else { + for (DynStrElem *dse_next, *dse = ds->elems; dse; dse = dse_next) { + dse_next = dse->next; + + free(dse->str); + free(dse); + } + } + + ds->elems = ds->last = NULL; + ds->curlen = 0; +} + +/** * Free the DynStr * * \param ds The DynStr to free. */ void BLI_dynstr_free(DynStr *ds) { - DynStrElem *dse; - - for (dse = ds->elems; dse; ) { - DynStrElem *n = dse->next; - - free(dse->str); - free(dse); - - dse = n; + if (ds->memarena) { + BLI_memarena_free(ds->memarena); } - + else { + BLI_dynstr_clear(ds); + } + MEM_freeN(ds); } diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index be15070d0cc..0b6be6ab08d 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -1259,7 +1259,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) for (Camera *camera = main->camera.first; camera != NULL; camera = camera->id.next) { if (camera->stereo.pole_merge_angle_from == 0.0f && - camera->stereo.pole_merge_angle_to == 0.0f) + camera->stereo.pole_merge_angle_to == 0.0f) { camera->stereo.pole_merge_angle_from = DEG2RADF(60.0f); camera->stereo.pole_merge_angle_to = DEG2RADF(75.0f); diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 6550ad9a2fd..dae8e180282 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1318,8 +1318,8 @@ static void write_particlesettings(WriteData *wd, ParticleSettings *part) dw->index = 0; if (part->dup_group) { /* can be NULL if lining fails or set to None */ for (GroupObject *go = part->dup_group->gobject.first; - go && go->ob != dw->ob; - go = go->next, dw->index++); + go && go->ob != dw->ob; + go = go->next, dw->index++); } } writestruct(wd, DATA, ParticleDupliWeight, 1, dw); @@ -2682,8 +2682,8 @@ static void write_scene(WriteData *wd, Scene *sce) } if (seq->type == SEQ_TYPE_IMAGE) { writestruct(wd, DATA, StripElem, - MEM_allocN_len(strip->stripdata) / sizeof(struct StripElem), - strip->stripdata); + MEM_allocN_len(strip->stripdata) / sizeof(struct StripElem), + strip->stripdata); } else if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) { writestruct(wd, DATA, StripElem, 1, strip->stripdata); @@ -3403,13 +3403,13 @@ static void write_mask(WriteData *wd, Mask *mask) } for (masklay_shape = masklay->splines_shapes.first; - masklay_shape; - masklay_shape = masklay_shape->next) + masklay_shape; + masklay_shape = masklay_shape->next) { writestruct(wd, DATA, MaskLayerShape, 1, masklay_shape); writedata(wd, DATA, - masklay_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, - masklay_shape->data); + masklay_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, + masklay_shape->data); } } } @@ -3895,7 +3895,7 @@ static bool write_file_handle( write_scene(wd, (Scene *)id); break; case ID_CU: - write_curve(wd,(Curve *)id); + write_curve(wd, (Curve *)id); break; case ID_MB: write_mball(wd, (MetaBall *)id); diff --git a/source/blender/blentranslation/CMakeLists.txt b/source/blender/blentranslation/CMakeLists.txt index a3e85344027..c0dce5b4f0d 100644 --- a/source/blender/blentranslation/CMakeLists.txt +++ b/source/blender/blentranslation/CMakeLists.txt @@ -60,3 +60,5 @@ if(WIN32) endif() blender_add_lib(bf_blentranslation "${SRC}" "${INC}" "${INC_SYS}") + +add_subdirectory(msgfmt) diff --git a/source/blender/blentranslation/msgfmt/CMakeLists.txt b/source/blender/blentranslation/msgfmt/CMakeLists.txt new file mode 100644 index 00000000000..d2cb6f5a03b --- /dev/null +++ b/source/blender/blentranslation/msgfmt/CMakeLists.txt @@ -0,0 +1,50 @@ +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2017, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Bastien Montagne. +# +# ***** END GPL LICENSE BLOCK ***** + +# ----------------------------------------------------------------------------- +# Build msgfmt executable + +blender_include_dirs( + ../../../../intern/guardedalloc + ../../blenlib +) + +set(SRC + msgfmt.c +) + +add_cc_flags_custom_test(msgfmt) + +add_executable(msgfmt ${SRC}) + +target_link_libraries(msgfmt bf_blenlib) +target_link_libraries(msgfmt bf_intern_guardedalloc) + +if(WIN32) + target_link_libraries(msgfmt bf_intern_utfconv) +endif() + +target_link_libraries(msgfmt ${ZLIB_LIBRARIES}) +target_link_libraries(msgfmt ${PLATFORM_LINKLIBS}) diff --git a/source/blender/blentranslation/msgfmt/msgfmt.c b/source/blender/blentranslation/msgfmt/msgfmt.c new file mode 100644 index 00000000000..487d9fee7b4 --- /dev/null +++ b/source/blender/blentranslation/msgfmt/msgfmt.c @@ -0,0 +1,464 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2017 by Blender Foundation. + * All rights reserved. + * + * Contributor(s): Bastien Montagne + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/* + * Based on C++ version by Sergey Sharybin <sergey.vfx@gmail.com>. + * Based on Python script msgfmt.py from Python source code tree, which was written by + * Martin v. Löwis <loewis@informatik.hu-berlin.de> + * + * Generate binary message catalog from textual translation description. + * + * This program converts a textual Uniforum-style message catalog (.po file) into a binary GNU catalog (.mo file). + * This is essentially the same function as the GNU msgfmt program, however, it is a simpler implementation. + * + * Usage: msgfmt input.po output.po + */ + +#include <string.h> +#include <stdlib.h> + +#include "BLI_utildefines.h" +#include "BLI_dynstr.h" +#include "BLI_fileops.h" +#include "BLI_ghash.h" +#include "BLI_linklist.h" +#include "BLI_memarena.h" + +#include "MEM_guardedalloc.h" + + +/* Stupid stub necessary because some BLI files includes winstuff.h, which uses G a bit... */ +#ifdef WIN32 + typedef struct Global { + void *dummy; + } Global; + + Global G; +#endif + + +/* We cannot use NULL char until ultimate step, would give nightmare to our C string processing... + * Using one of the UTF-8 invalid bytes (as per our BLI string_utf8.c) */ +#define NULLSEP_STR "\xff" +#define NULLSEP_CHR '\xff' + +typedef enum { + SECTION_NONE = 0, + SECTION_CTX = 1, + SECTION_ID = 2, + SECTION_STR = 3, +} eSectionType; + +typedef struct Message { + DynStr *ctxt; + DynStr *id; + DynStr *str; + + bool is_fuzzy; +} Message; + +static char *trim(char *str) +{ + const size_t len = strlen(str); + size_t i; + + if (len == 0) { + return str; + } + + for (i = 0; i < len && ELEM(str[0], ' ', '\t', '\n'); str++, i++); + + char *end = &str[len - 1 - i]; + for (i = len; i > 0 && ELEM(end[0], ' ', '\t', '\n'); end--, i--); + end[1] = '\0'; + + return str; +} + +static char *unescape(char *str) +{ + char *curr, *next; + for (curr = next = str; next[0] != '\0'; curr++, next++) { + if (next[0] == '\\') { + switch (next[1]) { + case '\0': + /* Get rid of trailing escape char... */ + curr--; + break; + case '\\': + *curr = '\\'; + next++; + break; + case 'n': + *curr = '\n'; + next++; + break; + case 't': + *curr = '\t'; + next++; + break; + default: + /* Get rid of useless escape char. */ + next++; + *curr = *next; + } + } + else if (curr != next) { + *curr = *next; + } + } + *curr = '\0'; + + if (str[0] == '"' && *(curr - 1) == '"') { + *(curr - 1) = '\0'; + return str + 1; + } + return str; +} + +static int qsort_str_cmp(const void *a, const void *b) +{ + return strcmp(*(const char **)a, *(const char **)b); +} + +static char **get_keys_sorted(GHash *messages, const uint32_t num_keys) +{ + GHashIterator iter; + + char **keys = MEM_mallocN(sizeof(*keys) * num_keys, __func__); + char **k = keys; + + GHASH_ITER(iter, messages) { + *k = BLI_ghashIterator_getKey(&iter); + k++; + } + + qsort(keys, num_keys, sizeof(*keys), qsort_str_cmp); + + return keys; +} + +BLI_INLINE size_t uint32_to_bytes(const int value, char *bytes) { + size_t i; + for (i = 0; i < sizeof(value); i++) { + bytes[i] = (char) ((value >> ((int)i * 8)) & 0xff); + } + return i; +} + +BLI_INLINE size_t msg_to_bytes(char *msg, char *bytes, uint32_t size) { + /* Note that we also perform replacing of our NULLSEP placeholder by real NULL char... */ + size_t i; + for (i = 0; i < size; i++, msg++, bytes++) { + *bytes = (*msg == NULLSEP_CHR) ? '\0' : *msg; + } + return i; +} + +typedef struct Offset { + uint32_t key_offset, key_len, val_offset, val_len; +} Offset; + +/* Return the generated binary output. */ +static char *generate(GHash *messages, size_t *r_output_size) { + const uint32_t num_keys = BLI_ghash_size(messages); + + /* Get list of sorted keys. */ + char **keys = get_keys_sorted(messages, num_keys); + char **vals = MEM_mallocN(sizeof(*vals) * num_keys, __func__); + uint32_t tot_keys_len = 0; + uint32_t tot_vals_len = 0; + + Offset *offsets = MEM_mallocN(sizeof(*offsets) * num_keys, __func__); + + for (int i = 0; i < num_keys; i++) { + Offset *off = &offsets[i]; + + vals[i] = BLI_ghash_lookup(messages, keys[i]); + + /* For each string, we need size and file offset. + * Each string is NULL terminated; the NULL does not count into the size. */ + off->key_offset = tot_keys_len; + off->key_len = (uint32_t)strlen(keys[i]); + tot_keys_len += off->key_len + 1; + + off->val_offset = tot_vals_len; + off->val_len = (uint32_t)strlen(vals[i]); + tot_vals_len += off->val_len + 1; + } + + /* The header is 7 32-bit unsigned integers. then comes the keys index table, then the values index table. */ + const uint32_t idx_keystart = 7 * 4; + const uint32_t idx_valstart = idx_keystart + 8 * num_keys; + /* We don't use hash tables, so the keys start right after the index tables. */ + const uint32_t keystart = idx_valstart + 8 * num_keys; + /* and the values start after the keys */ + const uint32_t valstart = keystart + tot_keys_len; + + /* Final buffer representing the binary MO file. */ + *r_output_size = valstart + tot_vals_len; + char *output = MEM_mallocN(*r_output_size, __func__); + char *h = output; + char *ik = output + idx_keystart; + char *iv = output + idx_valstart; + char *k = output + keystart; + char *v = output + valstart; + + h += uint32_to_bytes(0x950412de, h); /* Magic */ + h += uint32_to_bytes(0x0, h); /* Version */ + h += uint32_to_bytes(num_keys, h); /* Number of entries */ + h += uint32_to_bytes(idx_keystart, h); /* Start of key index */ + h += uint32_to_bytes(idx_valstart, h); /* Start of value index */ + h += uint32_to_bytes(0, h); /* Size of hash table */ + h += uint32_to_bytes(0, h); /* Offset of hash table */ + + BLI_assert(h == ik); + + for (int i = 0; i < num_keys; i++) { + Offset *off = &offsets[i]; + + /* The index table first has the list of keys, then the list of values. + * Each entry has first the size of the string, then the file offset. */ + ik += uint32_to_bytes(off->key_len, ik); + ik += uint32_to_bytes(off->key_offset + keystart, ik); + iv += uint32_to_bytes(off->val_len, iv); + iv += uint32_to_bytes(off->val_offset + valstart, iv); + + k += msg_to_bytes(keys[i], k, off->key_len + 1); + v += msg_to_bytes(vals[i], v, off->val_len + 1); + } + + BLI_assert(ik == output + idx_valstart); + BLI_assert(iv == output + keystart); + BLI_assert(k == output + valstart); + + MEM_freeN(keys); + MEM_freeN(vals); + MEM_freeN(offsets); + + return output; +} + +/* Add a non-fuzzy translation to the dictionary. */ +static void add(GHash *messages, MemArena *memarena, const Message *msg) +{ + const size_t msgctxt_len = (size_t)BLI_dynstr_get_len(msg->ctxt); + const size_t msgid_len = (size_t)BLI_dynstr_get_len(msg->id); + const size_t msgstr_len = (size_t)BLI_dynstr_get_len(msg->str); + const size_t msgkey_len = msgid_len + ((msgctxt_len == 0) ? 0 : msgctxt_len + 1); + + if (!msg->is_fuzzy && msgstr_len != 0) { + char *msgkey = BLI_memarena_alloc(memarena, sizeof(*msgkey) * (msgkey_len + 1)); + char *msgstr = BLI_memarena_alloc(memarena, sizeof(*msgstr) * (msgstr_len + 1)); + + if (msgctxt_len != 0) { + BLI_dynstr_get_cstring_ex(msg->ctxt, msgkey); + msgkey[msgctxt_len] = '\x04'; /* Context/msgid separator */ + BLI_dynstr_get_cstring_ex(msg->id, &msgkey[msgctxt_len + 1]); + } + else { + BLI_dynstr_get_cstring_ex(msg->id, msgkey); + } + + BLI_dynstr_get_cstring_ex(msg->str, msgstr); + + BLI_ghash_insert(messages, msgkey, msgstr); + } +} + + +static void clear(Message *msg) +{ + BLI_dynstr_clear(msg->ctxt); + BLI_dynstr_clear(msg->id); + BLI_dynstr_clear(msg->str); + msg->is_fuzzy = false; +} + +static int make(const char *input_file_name, const char *output_file_name) +{ + GHash *messages = BLI_ghash_new(BLI_ghashutil_strhash_p_murmur, BLI_ghashutil_strcmp, __func__); + MemArena *msgs_memarena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); + + const char *msgctxt_kw = "msgctxt"; + const char *msgid_kw = "msgid"; + const char *msgid_plural_kw = "msgid_plural"; + const char *msgstr_kw = "msgstr"; + const size_t msgctxt_len = strlen(msgctxt_kw); + const size_t msgid_len = strlen(msgid_kw); + const size_t msgid_plural_len = strlen(msgid_plural_kw); + const size_t msgstr_len = strlen(msgstr_kw); + + /* Note: For now, we assume file encoding is always utf-8. */ + + eSectionType section = SECTION_NONE; + bool is_plural = false; + + Message msg = { + .ctxt = BLI_dynstr_new_memarena(), + .id = BLI_dynstr_new_memarena(), + .str = BLI_dynstr_new_memarena(), + .is_fuzzy = false, + }; + + LinkNode *input_file_lines = BLI_file_read_as_lines(input_file_name); + LinkNode *ifl = input_file_lines; + + /* Parse the catalog. */ + for (int lno = 1; ifl; ifl = ifl->next, lno++) { + char *l = ifl->link; + const bool is_comment = (l[0] == '#'); + /* If we get a comment line after a msgstr, this is a new entry. */ + if (is_comment) { + if (section == SECTION_STR) { + add(messages, msgs_memarena, &msg); + clear(&msg); + section = SECTION_NONE; + } + /* Record a fuzzy mark. */ + if (l[1] == ',' && strstr(l, "fuzzy") != NULL) { + msg.is_fuzzy = true; + } + /* Skip comments */ + continue; + } + if (strstr(l, msgctxt_kw) == l) { + if (section == SECTION_STR) { + /* New message, output previous section. */ + add(messages, msgs_memarena, &msg); + } + if (!ELEM(section, SECTION_NONE, SECTION_STR)) { + printf("msgctxt not at start of new message on %s:%d\n", input_file_name, lno); + return EXIT_FAILURE; + } + section = SECTION_CTX; + l = l + msgctxt_len; + clear(&msg); + } + else if (strstr(l, msgid_plural_kw) == l) { + /* This is a message with plural forms. */ + if (section != SECTION_ID) { + printf("msgid_plural not preceeded by msgid on %s:%d\n", input_file_name, lno); + return EXIT_FAILURE; + } + l = l + msgid_plural_len; + BLI_dynstr_append(msg.id, NULLSEP_STR); /* separator of singular and plural */ + is_plural = true; + } + else if (strstr(l, msgid_kw) == l) { + if (section == SECTION_STR) { + add(messages, msgs_memarena, &msg); + } + if (section != SECTION_CTX) { + clear(&msg); + } + section = SECTION_ID; + l = l + msgid_len; + is_plural = false; + } + else if (strstr(l, msgstr_kw) == l) { + l = l + msgstr_len; + // Now we are in a msgstr section + section = SECTION_STR; + if (l[0] == '[') { + if (!is_plural) { + printf("plural without msgid_plural on %s:%d\n", input_file_name, lno); + return EXIT_FAILURE; + } + if ((l = strchr(l, ']')) == NULL) { + printf("Syntax error on %s:%d\n", input_file_name, lno); + return EXIT_FAILURE; + } + if (BLI_dynstr_get_len(msg.str) != 0) { + BLI_dynstr_append(msg.str, NULLSEP_STR); /* Separator of the various plural forms. */ + } + } + else { + if (is_plural) { + printf("indexed msgstr required for plural on %s:%d\n", input_file_name, lno); + return EXIT_FAILURE; + } + } + } + /* Skip empty lines. */ + l = trim(l); + if (l[0] == '\0') { + if (section == SECTION_STR) { + add(messages, msgs_memarena, &msg); + clear(&msg); + } + section = SECTION_NONE; + continue; + } + l = unescape(l); + if (section == SECTION_CTX) { + BLI_dynstr_append(msg.ctxt, l); + } + else if (section == SECTION_ID) { + BLI_dynstr_append(msg.id, l); + } + else if (section == SECTION_STR) { + BLI_dynstr_append(msg.str, l); + } + else { + printf("Syntax error on %s:%d\n", input_file_name, lno); + return EXIT_FAILURE; + } + } + /* Add last entry */ + if (section == SECTION_STR) { + add(messages, msgs_memarena, &msg); + } + + BLI_dynstr_free(msg.ctxt); + BLI_dynstr_free(msg.id); + BLI_dynstr_free(msg.str); + BLI_file_free_lines(input_file_lines); + + /* Compute output */ + size_t output_size; + char *output = generate(messages, &output_size); + + FILE *fp = BLI_fopen(output_file_name, "wb"); + fwrite(output, 1, output_size, fp); + fclose(fp); + + MEM_freeN(output); + BLI_ghash_free(messages, NULL, NULL); + BLI_memarena_free(msgs_memarena); + + return EXIT_SUCCESS; +} + +int main(int argc, char **argv) { + if (argc != 3) { + printf("Usage: %s <input.po> <output.mo>\n", argv[0]); + return EXIT_FAILURE; + } + const char *input_file = argv[1]; + const char *output_file = argv[2]; + + return make(input_file, output_file); +} diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c index d2360fea672..6947ca6b376 100644 --- a/source/blender/editors/gpencil/gpencil_interpolate.c +++ b/source/blender/editors/gpencil/gpencil_interpolate.c @@ -77,7 +77,6 @@ #include "ED_object.h" #include "ED_screen.h" #include "ED_view3d.h" -#include "ED_screen.h" #include "ED_space_api.h" #include "gpencil_intern.h" diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c index 45dbde80284..2912a1ac4eb 100644 --- a/source/blender/editors/gpencil/gpencil_select.c +++ b/source/blender/editors/gpencil/gpencil_select.c @@ -1012,7 +1012,7 @@ static int gpencil_lasso_select_exec(bContext *C, wmOperator *op) } /* test if in lasso boundbox + within the lasso noose */ if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(&rect, x0, y0) && - BLI_lasso_is_point_inside(mcords, mcords_tot, x0, y0, INT_MAX)) + BLI_lasso_is_point_inside(mcords, mcords_tot, x0, y0, INT_MAX)) { if (select) { pt->flag |= GP_SPOINT_SELECT; diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index ff62e5f2f37..7ae2f78e91d 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -2013,7 +2013,7 @@ void ED_object_single_users(Main *bmain, Scene *scene, const bool full, const bo for (Base *base = scene->base.first; base; base = base->next) { Object *ob = base->object; if (!ID_IS_LINKED_DATABLOCK(ob)) { - IDP_RelinkProperty(ob->id.properties); + IDP_RelinkProperty(ob->id.properties); } } diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index a213d8dd911..01759338744 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -1897,7 +1897,7 @@ static void GPU_get_object_info(float oi[3], Material *mat) else { random = BLI_hash_int_2d(BLI_hash_string(GMS.gob->id.name + 2), 0); } - oi[2] = random * (1.0f/(float)0xFFFFFFFF); + oi[2] = random * (1.0f / (float)0xFFFFFFFF); } int GPU_object_material_bind(int nr, void *attribs) diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c index 97145d9be7b..f6288dc9be0 100644 --- a/source/blender/modifiers/intern/MOD_surfacedeform.c +++ b/source/blender/modifiers/intern/MOD_surfacedeform.c @@ -1135,9 +1135,11 @@ static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], un } /* Actual vertex location update starts here */ - SDefDeformData data = {.bind_verts = smd->verts, - .targetCos = MEM_mallocN(sizeof(float[3]) * tnumverts, "SDefTargetVertArray"), - .vertexCos = vertexCos}; + SDefDeformData data = { + .bind_verts = smd->verts, + .targetCos = MEM_mallocN(sizeof(float[3]) * tnumverts, "SDefTargetVertArray"), + .vertexCos = vertexCos, + }; if (data.targetCos != NULL) { bool tdm_vert_alloc; diff --git a/source/blender/nodes/shader/nodes/node_shader_object_info.c b/source/blender/nodes/shader/nodes/node_shader_object_info.c index 165d565a5b4..63d3bac88a0 100644 --- a/source/blender/nodes/shader/nodes/node_shader_object_info.c +++ b/source/blender/nodes/shader/nodes/node_shader_object_info.c @@ -48,7 +48,7 @@ static void node_shader_exec_object_info(void *data, int UNUSED(thread), bNode * copy_v4_v4(out[0]->vec, RE_object_instance_get_matrix(scd->shi->obi, RE_OBJECT_INSTANCE_MATRIX_OB)[3]); out[1]->vec[0] = RE_object_instance_get_object_pass_index(scd->shi->obi); out[2]->vec[0] = scd->shi->mat->index; - out[3]->vec[0] = RE_object_instance_get_random_id(scd->shi->obi) * (1.0f/(float)0xFFFFFFFF);; + out[3]->vec[0] = RE_object_instance_get_random_id(scd->shi->obi) * (1.0f / (float)0xFFFFFFFF); } /* node type definition */ diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 00627030db3..dc247f28539 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -7107,8 +7107,8 @@ static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item RNA_struct_idprops_contains_datablock(type_srna)) { PyErr_Format(PyExc_ValueError, - "bpy_struct \"%.200s\" doesn't support datablock properties \n", - RNA_struct_identifier(srna)); + "bpy_struct \"%.200s\" doesn't support datablock properties \n", + RNA_struct_identifier(srna)); return -1; } } diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt index 9a89ddd6fbc..9042b804be9 100644 --- a/tests/python/CMakeLists.txt +++ b/tests/python/CMakeLists.txt @@ -458,7 +458,7 @@ if(WITH_ALEMBIC) ) if(MSVC) - add_test(NAME cycles_${subject}_test + add_test(NAME alembic_tests COMMAND "$<TARGET_FILE_DIR:blender>/${BLENDER_VERSION_MAJOR}.${BLENDER_VERSION_MINOR}/python/bin/python$<$<CONFIG:Debug>:_d>" ${CMAKE_CURRENT_LIST_DIR}/alembic_tests.py |